【Python】教師あり機械学習で映画を推薦するモデルを作成する【LightFM】

LightFM
この記事は約8分で読めます。
https://github.com/lyst/lightfm

Pythonのライブラリ、LightFMを利用してサンプルデータセットの映画データを利用して推薦するモデルを作成します。

プラグインのインストール

lyst/lightfm
A Python implementation of LightFM, a hybrid recommendation algorithm. - lyst/lightfm

pipでインストール

pip install lightfm

Anaconda環境

conda install -c conda-forge lightfm

クイックスタート

Quickstart — LightFM 1.15 documentation
import numpy as np

from lightfm import LightFM
from lightfm.datasets import fetch_movielens
from lightfm.evaluation import precision_at_k
from lightfm.evaluation import auc_score

# Load the MovieLens 100k dataset. Only five
# star ratings are treated as positive.
data = fetch_movielens(min_rating=5.0)

# Instantiate and train the model
model = LightFM(loss='warp')
model.fit(data['train'], epochs=30, num_threads=2)

# Evaluate the trained model
train_precision = precision_at_k(model, data['train'], k=5).mean()
test_precision = precision_at_k(model, data['test'], k=5).mean()

train_auc = auc_score(model, data['train']).mean()
test_auc = auc_score(model, data['test']).mean()

print('Precision: train %.2f, test %.2f.' % (train_precision, test_precision))
print('AUC: train %.2f, test %.2f.' % (train_auc, test_auc))

def sample_recommendation(model, data, user_ids):


    n_users, n_items = data['train'].shape

    for user_id in user_ids:
        known_positives = data['item_labels'][data['train'].tocsr()[user_id].indices]

        scores = model.predict(user_id, np.arange(n_items))
        top_items = data['item_labels'][np.argsort(-scores)]

        print("User %s" % user_id)
        print("     Known positives:")

        for x in known_positives[:3]:
            print("        %s" % x)

        print("     Recommended:")

        for x in top_items[:3]:
            print("        %s" % x)

sample_recommendation(model, data, [3, 25, 450])

Movielensデータセット取得

from lightfm.datasets import fetch_movielens

trainとtestという2つの行列があります。
どちらも約1000人のユーザーと1700のアイテムを持っています。
訓練用の行列でモデルを学習しますが、検証用の行列で学習結果の検証をします。

print(repr(data['train']))
print(repr(data['test']))
<943x1682 sparse matrix of type '<type 'numpy.int32'>'
    with 19048 stored elements in COOrdinate format>
<943x1682 sparse matrix of type '<type 'numpy.int32'>'
    with 2153 stored elements in COOrdinate format>

min_ratingに5を指定すると、星の評価が5のデータを抽出することができます。
指定しない場合は、全データを利用できます。

モデルを作成する

# Instantiate and train the model
model = LightFM(loss='warp')
model.fit(data['train'], epochs=30, num_threads=2)

WARP(Weighted Approximate-Rank Pairwise)モデルを使用します。
WARPは暗黙的なフィードバックモデルです。

この実装では、非同期確率勾配降下を使用してトレーニングを行います。これは、相互作用行列が非常に密であり、多数のスレッドが使用されている場合、精度が低下する可能性があります。しかし、実際には、30スレッドのデータセットでトレーニングを行っても、測定可能な精度の低下はありません。

モデルの目標は、低スコアを暗黙のネガティブに割り当てながら、これらの暗黙のポジティブを高度にスコアリングすることです。

訓練用データで学習させる

# Evaluate the trained model
train_precision = precision_at_k(model, data['train'], k=5).mean()
test_precision = precision_at_k(model, data['test'], k=5).mean()

テストデータで訓練結果のスコアを確認する

train_auc = auc_score(model, data['train']).mean()
test_auc = auc_score(model, data['test']).mean()

print('Precision: train %.2f, test %.2f.' % (train_precision, test_precision))
print('AUC: train %.2f, test %.2f.' % (train_auc, test_auc))
Precision: train 0.41, test 0.06.
AUC: train 0.97, test 0.92.

アウトプット

def sample_recommendation(model, data, user_ids):


    n_users, n_items = data['train'].shape

    for user_id in user_ids:
        known_positives = data['item_labels'][data['train'].tocsr()[user_id].indices]

        scores = model.predict(user_id, np.arange(n_items))
        top_items = data['item_labels'][np.argsort(-scores)]

        print("User %s" % user_id)
        print("     Known positives:")

        for x in known_positives[:3]:
            print("        %s" % x)

        print("     Recommended:")

        for x in top_items[:3]:
            print("        %s" % x)

sample_recommendation(model, data, [3, 25, 450])
User 3
     Known positives:
        Contact (1997)
        Air Force One (1997)
        In & Out (1997)
     Recommended:
        Air Force One (1997)
        Assignment, The (1997)
        Kiss the Girls (1997)
User 25
     Known positives:
        Fargo (1996)
        Godfather, The (1972)
        L.A. Confidential (1997)
     Recommended:
        L.A. Confidential (1997)
        Titanic (1997)
        Fargo (1996)
User 450
     Known positives:
        Event Horizon (1997)
        Scream (1996)
        Conspiracy Theory (1997)
     Recommended:
        Independence Day (ID4) (1996)
        Scream (1996)
        Ransom (1996)

各ユーザーに対しておすすめの映画を提示することができました。

タイトルとURLをコピーしました