Хорошее общее руководство по оптимизации гиперпараметров можно найти в документации sklearn.
Одним из простых, но эффективных способов оптимизации модели LightFM является случайный поиск. Грубо говоря, он состоит из следующих шагов:
- Разделите данные на обучающий набор, проверочный набор и тестовый набор.
- Определите распределение для каждого гиперпараметра, который вы хотите оптимизировать. Например, если вы оптимизируете скорость обучения, вы можете использовать экспоненциальное распределение со средним значением 0,05; если вы оптимизируете функцию потерь, вы можете выбрать однородную выборку из
['warp', 'bpr', 'warp-kos']
.
- В каждой итерации оптимизации отбирайте все свои гиперпараметры и используйте их, чтобы подогнать модель к обучающим данным. Оцените производительность модели на проверочном наборе.
- После выполнения ряда шагов оптимизации выберите тот, который обеспечивает наилучшую производительность проверки.
Чтобы оценить производительность окончательной модели, вы должны использовать тестовый набор: просто оцените лучшую модель проверки в тестовом наборе.
Следующий сценарий иллюстрирует это:
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))
person
Maciej Kula
schedule
23.04.2018