Как мне оптимизировать гиперпараметры LightFM?

Я использую библиотеку рекомендателей LightFM в моем наборе данных, которая дает мне результаты на изображении ниже.

Плохие результаты после нескольких эпох

NUM_THREADS = 4
NUM_COMPONENTS = 30
NUM_EPOCHS = 5
ITEM_ALPHA = 1e-6
LEARNING_RATE = 0.005
LEARNING_SCHEDULE = 'adagrad'
RANDOM_SEED = 29031994    

warp_model = LightFM(loss='warp',
                    learning_rate=LEARNING_RATE,
                    learning_schedule=LEARNING_SCHEDULE,
                    item_alpha=ITEM_ALPHA,
                    no_components=NUM_COMPONENTS,
                    random_state=RANDOM_SEED)

bpr_model = LightFM(loss='bpr',
                    learning_rate=LEARNING_RATE,
                    learning_schedule=LEARNING_SCHEDULE,
                    item_alpha=ITEM_ALPHA,
                    no_components=NUM_COMPONENTS,
                    random_state=RANDOM_SEED)

Формы моих особенностей следующие:

Предметы и пользовательские особенности фигур

Как я могу оптимизировать свои гиперпараметры, чтобы улучшить баллы по площади под кривой (AUC)?

1 ответ

Решение

Вы можете найти хорошее общее руководство по оптимизации гиперпараметров в документации по sklearn.

Одним простым, но эффективным методом, который вы можете применить для оптимизации модели LightFM, является случайный поиск. Грубо говоря, он состоит из следующих шагов:

  1. Разделите ваши данные на обучающий набор, набор проверки и набор тестов.
  2. Определите распределение для каждого гиперпараметра, который вы хотите оптимизировать. Например, если вы оптимизируете свою скорость обучения, вы можете использовать экспоненциальное распределение со средним значением 0,05; если вы оптимизируете функцию потерь, вы можете выбрать равномерно из ['warp', 'bpr', 'warp-kos'],
  3. На каждой итерации оптимизации делайте выборку всех ваших гиперпараметров и используйте их для подгонки модели к тренировочным данным. Оцените производительность модели на наборе валидации.
  4. После выполнения ряда шагов по оптимизации выберите один из них с наилучшей производительностью проверки.

Чтобы измерить производительность окончательной модели, вы должны использовать набор тестов: просто оцените лучшую модель проверки на тестовом наборе.

Следующий скрипт иллюстрирует это:

import itertools

import numpy as np

from lightfm import LightFM
from lightfm.evaluation import auc_score


def sample_hyperparameters():
    """
    Yield possible hyperparameter choices.
    """

    while True:
        yield {
            "no_components": np.random.randint(16, 64),
            "learning_schedule": np.random.choice(["adagrad", "adadelta"]),
            "loss": np.random.choice(["bpr", "warp", "warp-kos"]),
            "learning_rate": np.random.exponential(0.05),
            "item_alpha": np.random.exponential(1e-8),
            "user_alpha": np.random.exponential(1e-8),
            "max_sampled": np.random.randint(5, 15),
            "num_epochs": np.random.randint(5, 50),
        }


def random_search(train, test, num_samples=10, num_threads=1):
    """
    Sample random hyperparameters, fit a LightFM model, and evaluate it
    on the test set.

    Parameters
    ----------

    train: np.float32 coo_matrix of shape [n_users, n_items]
        Training data.
    test: np.float32 coo_matrix of shape [n_users, n_items]
        Test data.
    num_samples: int, optional
        Number of hyperparameter choices to evaluate.


    Returns
    -------

    generator of (auc_score, hyperparameter dict, fitted model)

    """

    for hyperparams in itertools.islice(sample_hyperparameters(), num_samples):
        num_epochs = hyperparams.pop("num_epochs")

        model = LightFM(**hyperparams)
        model.fit(train, epochs=num_epochs, num_threads=num_threads)

        score = auc_score(model, test, train_interactions=train, num_threads=num_threads).mean()

        hyperparams["num_epochs"] = num_epochs

        yield (score, hyperparams, model)


if __name__ == "__main__":
    from lightfm.datasets import fetch_movielens

    data = fetch_movielens()
    train = data["train"]
    test = data["test"]

    (score, hyperparams, model) = max(random_search(train, test, num_threads=2), key=lambda x: x[0])

    print("Best score {} at {}".format(score, hyperparams))
Другие вопросы по тегам