協調フィルタリングを使用した推奨エンジンの構築

協調フィルタリングを使用した推奨エンジンの構築

協調フィルタリングは、ユーザーに関するより多くの情報が収集されるにつれて、より良い推奨事項を提供することを学ぶことができるインテリジェントな推奨システムを構築する際に使用される最も一般的な手法です。

Amazon、YouTube、NetflixなどのほとんどのWebサイトは、高度な推奨システムの一部として協調フィルタリングを使用しています。 この手法を使用して、類似ユーザーの好き嫌いに基づいてユーザーに提案を行うレコメンダーを構築できます。

この記事では、以下について学習します:

  • 協調フィルタリングとそのタイプ

  • レコメンダーを構築するために必要なデータ

  • レコメンダーを作成するためにPythonで使用可能なライブラリー

  • 共同フィルタリングのユースケースと課題

*無料ボーナス:*リンク:[Python Tricks:The Book]の章にアクセスするには、ここをクリックして、Pythonのベストプラクティスを簡単な例とともに示します。すぐに適用して、より美しい+ Pythonコードを記述できます。

協調フィルタリングとは何ですか?

協調フィルタリングは、類似したユーザーの反応に基づいて、ユーザーが好む可能性のあるアイテムをフィルターで除外できる手法です。

多数の人々を検索し、特定のユーザーに似た好みを持つ少数のユーザーを見つけることで機能します。 好きなアイテムを見て、それらを組み合わせて、ランク付けされた候補リストを作成します。

どのユーザーが似ているかを判断し、選択肢を組み合わせて推奨事項のリストを作成する方法は多数あります。 この記事では、Pythonでそれを行う方法を示します。

データセット

推奨アルゴリズムを試すには、*アイテムのセット*および一部のアイテムに反応した*ユーザーのセット*を含むデータが必要です。

反応は、明示的(1から5の評価、好きまたは嫌い)または*暗黙的*(アイテムの表示、ウィッシュリストへの追加、記事に費やした時間)です。

このようなデータを操作している間は、ほとんどの場合、ユーザーが一連のアイテムの一部のアイテムに対して行った反応で構成される*マトリックス*の形式で表示されます。 各行にはユーザーが指定した評価が含まれ、各列にはアイテムが受け取った評価が含まれます。 5人のユーザーと5つのアイテムを持つマトリックスは次のようになります。

マトリックスには、一部のアイテムを1〜5のスケールで評価した5人のユーザーが表示されます。 たとえば、最初のユーザーが3番目のアイテムに評価4を与えました。

ほとんどの場合、マトリックス内のセルは空です。これは、ユーザーがいくつかのアイテムのみを評価するためです。 すべてのユーザーが利用可能なすべてのアイテムを評価または反応することはほとんどありません。 ほとんどが空のセルを持つマトリックスは sparse と呼ばれ、その反対(ほとんどが塗りつぶされたマトリックス)は dense と呼ばれます。

多くのデータセットが収集され、研究とベンチマークのために公開されています。 以下に、選択可能なhttps://github.com/caserec/Datasets-for-Recommneder-Systems [高品質データソースのリスト]を示します。

始めるのに最適なのは、GroupLens Researchによって収集されたhttps://grouplens.org/datasets/movielens/[MovieLens]データセットです。 特に、https://grouplens.org/datasets/movielens/100k/[MovieLens 100kデータセット]は、安定したベンチマークデータセットであり、1683の映画に対して943人のユーザーによって100,000の評価が与えられ、各ユーザーは少なくとも20の映画を評価しました。

このデータセットは、映画、ユーザー、およびユーザーが視聴した映画に対してユーザーから与えられた評価に関する情報を含む多くのファイルで構成されています。 興味深いのは次のとおりです。

  • * + u.item +:*映画のリスト

  • * + u.data +:*ユーザーが指定した評価のリスト

評価を含むファイル「+ u.data +」は、ユーザーID、アイテムID、評価、およびタイムスタンプのタブ区切りリストです。 ファイルの最初の数行は次のようになります。

上記のように、このファイルは、ユーザーが特定の映画に付けた評価を示します。 このファイルには、100,000件のこのような評価が含まれており、ユーザーが視聴していない映画の評価を予測するために使用されます。

協調フィルタリングに含まれるステップ

他のユーザーの好みに基づいてユーザーにアイテムを自動的に推奨できるシステムを構築するには、最初のステップは類似したユーザーまたはアイテムを見つけることです。 2番目のステップは、ユーザーがまだ評価していないアイテムの評価を予測することです。 したがって、これらの質問に対する答えが必要になります。

  • どのユーザーまたはアイテムが互いに似ているかをどのように判断しますか?

  • どのユーザーが似ているかがわかっている場合、似たようなユーザーの評価に基づいて、ユーザーがアイテムに与える評価をどのように決定しますか?

  • 計算した評価の精度をどのように測定しますか?

最初の2つの質問には単一の答えはありません。 協調フィルタリングは、類似したユーザーまたはアイテムを見つける複数の方法と、類似したユーザーの評価に基づいて評価を計算する複数の方法があるアルゴリズムのファミリーです。 選択した内容に応じて、最終的には協調的なフィルタリングアプローチのタイプになります。 この記事では、類似性を見つけて評価を予測するためのさまざまなアプローチを紹介します。

留意すべき重要な点は、純粋に協調フィルタリングに基づくアプローチでは、ユーザーの年齢、映画のジャンル、またはユーザーやアイテムに関するその他のデータなどの要因を使用して類似性が計算されないことです。 ユーザーがアイテムに与える評価(明示的または暗黙的)に基づいてのみ計算されます。 たとえば、2人のユーザーは、年齢に大きな違いがあるにもかかわらず、10本の映画に同じ評価を与えた場合、類似していると見なすことができます。

予測の精度を測定する方法に関する3番目の質問には、複数の回答があります。これには、協調フィルタリングに基づくレコメンダーだけでなく、多くの場所で使用できるエラー計算手法が含まれます。

結果の精度を測定する方法の1つは、二乗平均誤差(RMSE)です。この方法では、評価値が既知のユーザーとアイテムのペアのテストデータセットの評価を予測します。 既知の値と予測値の差がエラーになります。 テストセットのすべてのエラー値を平方し、平均(または平均)を求め、その平均の平方根を取得してRMSEを取得します。

精度を測定するもう1つのメトリックは平均絶対誤差(MAE)で、絶対値を見つけてすべての誤差値の平均を取ることで誤差の大きさを見つけます。

Pythonのさまざまなパッケージの一部としてすぐに利用できるため、この時点でRMSEまたはMAEの詳細を心配する必要はありません。詳細は記事の後半で説明します。

次に、協調フィルタリングのファミリーのさまざまなタイプのアルゴリズムを見てみましょう。

メモリベース

最初のカテゴリには、メモリベースのアルゴリズムが含まれます。このアルゴリズムでは、統計的手法がデータセット全体に適用され、予測が計算されます。

ユーザー U がアイテム I に与える評価 R を見つけるために、アプローチには以下が含まれます。

  • アイテムを評価した U に類似したユーザーを検索 I

  • 前のステップで見つかったユーザーの評価に基づく評価 R の計算

次のセクションで、それらのそれぞれについて詳しく説明します。

評価に基づいて同様のユーザーを見つける方法

類似性の概念を理解するために、最初に簡単なデータセットを作成しましょう。

データには、2つの映画を評価した4人のユーザー ABC 、および D が含まれます。 評価はリストに保存され、各リストには各映画の評価を示す2つの数字が含まれています。

  • A による評価は `+ [1.0、2.0] +`です。

  • B による評価は `+ [2.0、4.0] +`です。

  • C による評価は `+ [2.5、4.0] +`です。

  • D による評価は `+ [4.5、5.0] +`です。

視覚的な手がかりから始めるには、ユーザーが指定した2つの映画の評価をグラフにプロットし、パターンを探します。 グラフは次のようになります。

上記のグラフでは、各ポイントはユーザーを表し、2つの映画に与えた評価に対してプロットされています。

点間の距離を調べることは、類似性を推定するための良い方法のようですよね? 2点間のユークリッド距離の式を使用して、距離を見つけることができます。 次のプログラムに示すように、 `+ scipy +`で利用可能な関数を使用できます。

>>>

>>> from scipy import spatial

>>> a = [1, 2]
>>> b = [2, 4]
>>> c = [2.5, 4]
>>> d = [4.5, 5]

>>> spatial.distance.euclidean(c, a)
2.5
>>> spatial.distance.euclidean(c, b)
0.5
>>> spatial.distance.euclidean(c, d)
2.23606797749979

上記のように、 `+ scipy.spatial.distance.euclidean +`を使用して2点間の距離を計算できます。 これを使用して、 AB 、および D の評価と C の評価との距離を計算すると、距離の観点から、 C の評価が B の評価に最も近いことがわかります。 。

グラフを見ても、ユーザー CB に最も近いことがわかります。 しかし、 AD のうち、 C に近いのは誰ですか?

*C* は距離の点で *D* に近いと言えます。 しかし、ランキングを見ると、 *C* の選択は *D* よりも *A* の選択と一致すると思われます。これは、 *A* と *C* の両方が、2番目の映画がほぼ2倍好きなので、最初の映画ですが、 *D* は両方の映画が等しく好きです。

それで、ユークリッド距離ができないようなパターンを識別するために何を使用できますか? 点を原点に結合する線の間の角度を使用して決定を下すことができますか? 以下に示すように、グラフの原点とそれぞれのポイントを結ぶ線の間の角度を見ることができます。

グラフには、各ポイントを原点に結合する4本の線が表示されます。 AB の線は一致しており、それらの間の角度はゼロになっています。

線間の角度が大きくなると類似性が低下し、角度がゼロの場合はユーザーが非常に似ていると考えることができます。

角度を使用して類似度を計算するには、低角度の場合は*高類似度*または*短距離*を、高角度の場合は*低類似度*または*長距離*を返す関数が必要です。 角度の余弦は、角度が0から180に増加するにつれて1から-1に減少する関数です。

角度のコサインを使用して、2人のユーザー間の類似性を見つけることができます。 角度が大きいほど、余弦は低くなり、したがって、ユーザーの類似度は低くなります。 角度のコサインの値を逆にして、1から減算することにより、ユーザー間のコサイン距離を取得することもできます。

`+ scipy +`には、ベクトルの*コサイン距離*を計算する機能があります。 角度が大きいほど高い値を返します。

>>>

>>> from scipy import spatial
>>> a = [1, 2]
>>> b = [2, 4]
>>> c = [2.5, 4]
>>> d = [4.5, 5]

>>> spatial.distance.cosine(c,a)
0.004504527406047898

>>> spatial.distance.cosine(c,b)
0.004504527406047898

>>> spatial.distance.cosine(c,d)
0.015137225946083022

>>> spatial.distance.cosine(a,b)
0.0
*C* と *A* のベクトル間の角度が小さいほど、コサイン距離の値は小さくなります。 この方法でユーザーの類似性をランク付けする場合は、コサイン距離を使用します。

*注意:*上記の例では、2つの映画のみが考慮されているため、評価ベクトルを2次元で視覚化することが容易になります。 これは、説明を簡単にするためだけに行われます。

複数のアイテムを使用する実際のユースケースでは、評価ベクトルにより多くのディメンションが含まれます。 https://en.wikipedia.org/wiki/Cosine_similarity [コサイン類似度]の数学にも行きたいかもしれません。

ユーザー AB は、評価が異なるにもかかわらず、コサイン類似度メトリックで完全に類似していると見なされることに注意してください。 これは実際には現実の世界でよく見られる現象であり、ユーザー A のようなユーザーは*タフな評価者*と呼ぶことができます。 例は、常に平均より低い評価を与える映画評論家ですが、リスト内のアイテムのランキングは B のような*平均評価者*に似ています。

このような個々のユーザー設定を考慮するには、バイアスを削除してすべてのユーザーを同じレベルにする必要があります。 これを行うには、そのユーザーが評価した各アイテムから、そのユーザーがすべてのアイテムに与えた平均評価を減算します。 これは次のようになります。

  • ユーザー A の場合、評価ベクトル `+ [1、2] `の平均は ` 1.5 `です。 すべての評価から「+1.5」を引くと、ベクトル「+ [-0.5、0.5] +」が得られます。

  • ユーザー B の場合、評価ベクトル `+ [2、4] `は平均 ` 3 `を持ちます。 すべての評価から「+3」を引くと、ベクトル「+ [-1、1] +」が得られます。

これにより、すべてのユーザーが指定する平均評価の値を0に変更しました。 ユーザー CD についても同じことを試してください。すべてのユーザーの評価が平均0になるように調整されていることがわかります。これにより、すべてのユーザーが同じレベルになり、偏りがなくなります。

調整されたベクトル間の角度のコサインは、*中央コサイン*と呼ばれます。 このアプローチは通常、ベクトルに多くの欠損値があり、欠損値を埋めるために共通の値を配置する必要がある場合に使用されます。

評価マトリックスの欠損値をランダムな値で埋めると、不正確になる可能性があります。 欠損値を埋めるのに適した選択肢は、各ユーザーの平均評価ですが、ユーザー AB の元の平均はそれぞれ「1.5」と「3」であり、すべての空を埋めます「1.5」を使用した A と「3」を使用した B の値は、異なるユーザーになります。

しかし、値を調整した後、両方のユーザーの*中央*平均は「0」であり、両方のユーザーのベクトルのすべての欠損値を持つ両方のユーザーの平均より上または下のアイテムのアイデアをより正確にキャプチャできます同じ値「0」。

ユークリッド距離とコサイン類似度は、互いに類似したユーザー、さらには類似したアイテムを見つけるために使用できるアプローチの一部です。 (上記で使用される関数は、コサイン距離を計算します。 コサインの類似度を計算するには、1から距離を引きます)

*注:*中央コサインの式は、ピアソン相関係数の式と同じです。 レコメンダーの多くのリソースとライブラリーは、中心コサインの実装をピアソン相関と呼んでいることがわかります。

評価の計算方法

ユーザー U に類似したユーザーのリストを決定したら、 U が特定のアイテム I に与える評価 R を計算する必要があります。 繰り返しますが、類似性と同様に、複数の方法でこれを行うことができます。

アイテム I に対するユーザーの評価 R は、 U に最も類似した上位5ユーザーまたは上位10ユーザーが I に与えた評価の平均に近いと予測できます。 _n_ユーザーが指定する平均評価の数式は次のようになります。

この式は、_n_類似ユーザーによって与えられる平均評価が、それらによって与えられる評価の合計を類似ユーザーの数で割ったものである_n_に等しいことを示しています。

見つかった_n_類似ユーザーがターゲットユーザー U と等しく似ていない場合があります。 それらの上位3つは非常に似ている場合があり、残りは上位3ほど U に似ていない場合があります。 その場合、最も類似したユーザーの評価が2番目に類似したユーザーよりも重要であるというアプローチを検討できます。 加重平均は、それを達成するのに役立ちます。

加重平均アプローチでは、各評価に類似度係数(ユーザーの類似度を示す)を掛けます。 類似性係数を掛けることにより、評価に重みを追加します。 重量が重ければ重いほど、評価は重要になります。

重みとして機能する類似性係数は、距離が短いほど類似性が高いことを意味するため、前述の距離の逆数である必要があります。 たとえば、1からコサイン距離を減算して、コサイン類似度を取得できます。

ターゲットユーザー U と類似する各ユーザーの類似度係数 S を使用すると、次の式を使用して加重平均を計算できます。

上記の式では、すべての評価に評価を与えたユーザーの類似度係数が乗算されます。 ユーザーによる最終的な予測評価 U は、加重評価の合計を重みの合計で割った値に等しくなります。

*注:*加重評価の合計が_n_ではなく、重みの合計で除算される理由を疑問に思っている場合は、これを考慮してください。前の平均の式では、重量は1でした。

分母は常に平均値を求める際の重みの合計であり、通常の平均の場合、重みが1の場合は分母が_n_に等しいことを意味します。

加重平均を使用すると、類似ユーザーの評価を類似度の順にさらに考慮することができます。

これで、同様のユーザーを見つける方法と、評価に基づいて評価を計算する方法がわかりました。 また、ユーザーの代わりに互いに類似したアイテムを見つけて評価を計算することで評価を予測する、協調フィルタリングのバリエーションもあります。 このバリエーションについては、次のセクションで説明します。

ユーザーベースのコラボレーションフィルタリングとアイテムベースのコラボレーションフィルタリング

上記の例で、評価マトリックスを使用して、評価に基づいて類似のユーザーを見つける手法は、ユーザーベースまたはユーザー間協調フィルタリングと呼ばれます。 評価マトリックスを使用して、ユーザーから与えられた評価に基づいて類似のアイテムを検索する場合、このアプローチはアイテムベースまたはアイテムアイテム協調フィルタリングと呼ばれます。

2つのアプローチは数学的に非常に似ていますが、2つのアプローチには概念的な違いがあります。 この2つの比較方法は次のとおりです。

  • ユーザーベース:*ユーザー *U の場合、特定のアイテム評価で構成される評価ベクトルに基づいて決定される類似ユーザーのセットで、アイテムの評価は未評価の I を選択することで検出されます。類似リストから、アイテム I を評価し、これらのN個の評価に基づいて評価を計算したN人のユーザーを除外します。

  • アイテムベース:*アイテムの場合 *I 、受信したユーザー評価で構成される評価ベクトルに基づいて決定された類似アイテムのセットでは、ユーザーによる評価は、評価していない U がピッキングによって検出されます U によって評価された類似リストからN個のアイテムを取り出し、これらのN個の評価に基づいて評価を計算します。

アイテムベースの協調フィルタリングは、Amazonによって開発されました。 アイテムよりもユーザーが多いシステムでは、アイテムベースのフィルタリングはユーザーベースよりも高速で安定しています。 通常、アイテムが受け取る平均評価は、ユーザーがさまざまなアイテムに与える平均評価ほど迅速に変化しないため、効果的です。 評価マトリックスがまばらな場合、ユーザーベースのアプローチよりもパフォーマンスが高いことも知られています。

ただし、アイテムベースのアプローチは、MovieLensなどのブラウジングやエンターテイメント関連のアイテムを含むデータセットではパフォーマンスが低下します。 このようなデータセットは、次のセクションで説明するマトリックスファクタリング手法、またはhttps://en.wikipedia.org/wikiを使用してジャンルなどのデータの内容も考慮に入れるハイブリッドレコメンダーでより良い結果が得られます/Recommender_system#Content-based_filtering [コンテンツベースのフィルタリング]。

ライブラリhttps://github.com/NicolasHug/Surprise[Surprise]を使用して、さまざまな推奨アルゴリズムをすばやく実験できます。 (これについては記事の後半で詳しく説明します。)

モデルベース

2番目のカテゴリは、モデルベースのアプローチをカバーします。これは、大きくても疎なユーザーアイテムマトリックスを削減または圧縮するステップを含みます。 このステップを理解するには、次元削減の基本的な理解が非常に役立ちます。

次元削減

ユーザーアイテムマトリックスには、2つの次元があります。

  1. ユーザー数

  2. アイテム数

行列の大部分が空の場合、次元を減らすと、空間と時間の両方の点でアルゴリズムのパフォーマンスが向上します。 これを行うには、行列因数分解やオートエンコーダーなどのさまざまな方法を使用できます。

行列分解*は、大きな行列を小さな行列の積に分解するものと見なすことができます。 これは整数の因数分解に似ており、「+ 12+」は「6 x 2」または「4 x 3」と記述できます。 行列の場合、寸法「+ m x n 」の行列 *A* は、それぞれ寸法「 m x p 」および「 p x n +」の2つの行列 *X および Y の積に縮小できます。

注意:*行列乗算では、 *X の列数が Y の行数と等しい場合にのみ、行列 XY を乗算できます。 したがって、2つの縮小行列は共通の次元 p を持ちます。

次元削減に使用されるアルゴリズムに応じて、削減された行列の数も3つ以上になる可能性があります。

縮小されたマトリックスは、実際にはユーザーとアイテムを個別に表します。 最初のマトリックスの m 行は m ユーザーを表し、 p 列はユーザ​​ーの機能または特性を示します。 同じことが、 n 個のアイテムと p 特性を持つアイテムマトリックスにも当てはまります。 マトリックス分解がどのように見えるかの例を次に示します。

上の画像では、マトリックスは2つのマトリックスに縮小されています。 左側の1つは_m_個のユーザーを持つユーザーマトリックスであり、上部の1つは_n_個のアイテムを持つアイテムマトリックスです。 評価「4」は次のように削減または因数分解されます。

  1. ユーザーベクトル (2、-1)

  2. アイテムベクトル (2.5、1)

ユーザーマトリックスの2列とアイテムマトリックスの2行は潜在因子と呼ばれ、ユーザーまたはアイテムに関する隠された特性を示します。 因数分解の可能な解釈は次のようになります。

  • ユーザーベクトル「(u、v)」において、「+ u 」はユーザーがホラージャンルをどれだけ気に入っているかを表し、「 v +」はロマンスジャンルをどれだけ気に入っているかを表します。

  • したがって、ユーザーベクトル「(2、-1)」は、ホラー映画が好きで、それらを肯定的に評価し、ロマンスのある映画を嫌い、否定的に評価するユーザーを表します。

  • アイテムベクトル「(i、j)」で、「+ i 」は映画がホラージャンルに属する量を表し、「 j 」はその映画がロマンスジャンルに属する量を表すと仮定します。 *映画「(2.5、1)」のホラー評価は「+2.5」、ロマンス評価は「1」です。 行列乗算ルールを使用してユーザーベクトルで乗算すると、 `(2* 2.5)(-1 * 1)= 4 +`が得られます。

  • そのため、映画はホラージャンルに属し、ユーザーは「5」と評価できましたが、ロマンスをわずかに含めると、最終評価は「4」に低下しました。

因子マトリックスは、ユーザーやアイテムに関するそのような洞察を提供できますが、実際には、通常、上記の説明よりもはるかに複雑です。 そのような要因の数は、1から数百、さらには数千にまで及ぶことがあります。 この数は、モデルのトレーニング中に最適化する必要があるものの1つです。

この例では、映画のジャンルに2つの潜在的要因がありましたが、実際のシナリオでは、これらの潜在的要因をあまり分析する必要はありません。 これらは、データのパターンであり、その意味を解読するかどうかにかかわらず、自動的に役割を果たします。

潜在的要因の数は、要因の数が多いほど推奨がよりパーソナライズされるように推奨に影響します。 ただし、要素が多すぎると、モデルが過剰適合する可能性があります。

注: *オーバーフィット*は、モデルがトレーニングデータに適合するようにトレーニングすると、新しいデータでうまく機能しない場合に発生します。

行列分解のアルゴリズム

行列を因数分解する一般的なアルゴリズムの1つは、https://en.wikipedia.org/wiki/Singular_value_decomposition [特異値分解](SVD)アルゴリズムです。 SVDは、Netflix賞コンペティションで行列因子分解がうまく機能していることが確認されたときに脚光を浴びました。 その他のアルゴリズムには、https://en.wikipedia.org/wiki/Principal_component_analysis [PCA]とそのバリエーション、https://en.wikipedia.org/wiki/Non-negative_matrix_factorization [NMF]などがあります。 Autoencodersは、ニューラルネットワークを使用する場合の次元削減にも使用できます。

Pythonのさまざまなライブラリでこれらのアルゴリズムの実装を見つけることができるため、この時点で詳細について心配する必要はありません。 しかし、さらに読みたい場合は、本http://www.mmds.org/[Mining of Massive Datasets]の次元削減に関する章を読む価値があります。

Pythonを使用してレコメンダーを作成する

Pythonには、レコメンダーを構築するために使用できるさまざまなアルゴリズムの実装を提供するライブラリとツールキットがかなりあります。 しかし、推奨システムを理解しながら試してみるべきものはhttps://github.com/NicolasHug/Surprise[Surprise]です。

サプライズはPython SciKitであり、さまざまなレコメンダーアルゴリズムと類似度メトリックが付属しており、レコメンダーの構築と分析が容易になります。

pipを使用してインストールする方法は次のとおりです。

$ pip install numpy
$ pip install scikit-surprise

condaを使用してインストールする方法は次のとおりです。

$ conda install -c conda-forge scikit-surprise

*注意:*例に従う場合は、https://realpython.com/courses/introduction-pandas-and-vincent/[Pandas]をインストールすることもお勧めします。

サプライズを使用するには、まず基本的なhttps://realpython.com/python-modules-packages/[modules]およびhttps://realpython.com/lessons/classes-python/[classes]で利用可能なものを知っている必要があります:

  • `+ Dataset +`モジュールは、ファイル、https://realpython.com/courses/pandas-dataframes-101/[Pandas dataframes]、または実験に利用可能な組み込みデータセットからデータをロードするために使用されます。 (MovieLens 100kはSurpriseの組み込みデータセットの1つです。)データセットをロードするには、次のメソッドを使用できます。

  • + Dataset.load_builtin()+

  • + Dataset.load_from_file()+

  • + Dataset.load_from_df()+

  • 評価を含むファイルを解析するには、 `+ Reader `クラスを使用します。 データを受け入れるデフォルトの形式は、各評価が ` user item rating +`の順序で別々の行に保存されることです。 この順序と区切り文字は、パラメーターを使用して構成できます。

  • + line_format + はhttps://realpython.com/python-strings/[string]で、 `" item user rating "`のように、フィールド名をスペースで区切ったデータの順序を格納します。

  • + sep + は、 `+ '、' +`などのフィールド間の区切り文字を指定するために使用されます。

  • + rating_scale + は評価尺度を指定するために使用されます。 デフォルトは `(1、5)`です。

  • + skip_lines + は、ファイルの先頭でスキップする行数を示すために使用されます。 デフォルトは `+ 0 +`です。

Pandasデータフレームまたは組み込みのMovieLens 100kデータセットからデータをロードするために使用できるプログラムは次のとおりです。

# load_data.py

import pandas as pd
from surprise import Dataset
from surprise import Reader

# This is the same data that was plotted for similarity earlier
# with one new user "E" who has rated only movie 1
ratings_dict = {
    "item": [1, 2, 1, 2, 1, 2, 1, 2, 1],
    "user": ['A', 'A', 'B', 'B', 'C', 'C', 'D', 'D', 'E'],
    "rating": [1, 2, 2, 4, 2.5, 4, 4.5, 5, 3],
}

df = pd.DataFrame(ratings_dict)
reader = Reader(rating_scale=(1, 5))

# Loads Pandas dataframe
data = Dataset.load_from_df(df[[user", "item", "rating"]], reader)
# Loads the builtin Movielens-100k data
movielens = Dataset.load_builtin('ml-100k')

上記のプログラムでは、データは、Pandasデータフレームにロードされたディクショナリに格納され、その後サプライズのDatasetオブジェクトにロードされます。

K-Nearest Neighbors(k-NN)に基づくアルゴリズム

レコメンダー機能のアルゴリズムの選択は、使用する手法によって異なります。 上記のメモリベースのアプローチの場合、法案に適合するアルゴリズムはhttps://surprise.readthedocs.io/en/stable/knn_inspired.html#surprise.prediction_algorithms.knns.KNNWithMeans[Centered k-NN]であるため、アルゴリズムは、上で説明した中央化コサイン類似度式に非常に近いです。 サプライズでは「+ KNNWithMeans +」として利用できます。

類似性を見つけるには、辞書を引数としてリコメンダー関数に渡すことで、関数を構成するだけです。 辞書には、次のような必要なキーが必要です。

  • + name + には、使用する類似性メトリックが含まれます。 オプションは、「+ cosine 」、「 msd 」、「 pearson 」、または「 pearson_baseline 」です。 デフォルトはhttps://surprise.readthedocs.io/en/stable/similarities.html#surprise.similarities.msd [` msd +`]です。

  • + user_based + は、アプローチがユーザーベースかアイテムベースかを示す `+ boolean `です。 デフォルトは「 True +」で、ユーザーベースのアプローチが使用されることを意味します。

  • + min_support + は、類似性を考慮するためにユーザー間で必要な共通アイテムの最小数です。 アイテムベースのアプローチの場合、これは2つのアイテムの最小共通ユーザー数に対応します。

次のプログラムは、 `+ KNNWithMeans +`関数を設定します:

# recommender.py

from surprise import KNNWithMeans

# To use item-based cosine similarity
sim_options = {
    "name": "cosine",
    "user_based": False,  # Compute  similarities between items
}
algo = KNNWithMeans(sim_options=sim_options)

上記のプログラムのリコメンダー機能は、コサイン類似度を使用し、アイテムベースのアプローチを使用して類似アイテムを検索するように構成されています。

このリコメンダーを試すには、「+ data 」から「 Trainset 」を作成する必要があります。 ` Trainset `は同じデータを使用して構築されますが、アルゴリズムで使用されるユーザーとアイテム( ` n_users `、 ` n_items +`)の数など、データに関する詳細情報が含まれます。 データ全体またはデータの一部を使用して作成できます。 また、データの一部をトレーニングに使用し、一部をテストに使用するフォールドに分割することもできます。

*注意:*通常、トレーニングデータとテストデータのペアを1つだけ使用するだけでは十分ではありません。 元のデータセットをトレーニングデータとテストデータに分割するときは、テストデータのトレーニングにバリエーションがある複数の観測を可能にするために、複数のペアを作成する必要があります。

アルゴリズムは、複数のフォールドを使用してhttps://en.wikipedia.org/wiki/Cross-validation_(statistics)[cross-validated]にする必要があります。 異なるペアを使用することで、レコメンダーからの異なる結果が表示されます。 MovieLens 100kは、5つの異なる交差検証のために、u1.base、u1.test、u2.base、u2.test…u5.base、u5.testの5種類のトレーニングデータとテストデータを提供します。

ユーザー E が映画2をどのように評価するかを調べる例は次のとおりです。

>>>

>>> from load_data import data
>>> from recommender import algo

>>> trainingSet = data.build_full_trainset()

>>> algo.fit(trainingSet)
Computing the cosine similarity matrix...
Done computing similarity matrix.
<surprise.prediction_algorithms.knns.KNNWithMeans object at 0x7f04fec56898>

>>> prediction = algo.predict('E', 2)
>>> prediction.est
4.15

アルゴリズムは、ユーザー E が映画4.15を評価すると予測しました。これは、推奨として表示するのに十分高い可能性があります。

さまざまなhttps://surprise.readthedocs.io/en/stable/knn_inspired.html[k-NNベースのアルゴリズム]をさまざまな類似性オプションとhttps://surprise.readthedocs.io/en/stable/とともに試してみてください。 matrix_factorization.html [matrix factorization algorithm]はSurpriseライブラリで利用可能です。 MovieLensデータセットでそれらを試して、ベンチマークを上回ることができるかどうかを確認してください。 次のセクションでは、サプライズを使用してデータに最適なパラメータを確認する方法について説明します。

アルゴリズムパラメーターの調整

サプライズは、https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.html [GridSearchCV]の `+ scikit-learn `に類似した ` GridSearchCV +`クラスを提供します。

すべてのパラメーターの「+ dict 」を使用して、「 GridSearchCV +」はパラメーターのすべての組み合わせを試行し、精度測定に最適なパラメーターをレポートします

たとえば、メモリベースのアプローチで、どの類似性メトリックがデータに最適かを確認できます。

from surprise import KNNWithMeans
from surprise import Dataset
from surprise.model_selection import GridSearchCV

data = Dataset.load_builtin("ml-100k")
sim_options = {
    "name": ["msd", "cosine"],
    "min_support": [3, 4, 5],
    "user_based": [False, True],
}

param_grid = {"sim_options": sim_options}

gs = GridSearchCV(KNNWithMeans, param_grid, measures=["rmse", "mae"], cv=3)
gs.fit(data)

print(gs.best_score["rmse"])
print(gs.best_params["rmse"])

上記のプログラムの出力は次のとおりです。

0.9434791128171457
{'sim_options': {'name': 'msd', 'min_support': 3, 'user_based': False}}

そのため、MovieLens 100kデータセットの場合、アイテムベースのアプローチを採用し、最小サポート3の類似性メトリックとしてmsdを使用すると、Centered-KNNアルゴリズムが最適に機能します。

同様に、モデルベースのアプローチの場合、 `+ Surprise +`を使用して、次の要素のどの値が最適に機能するかを確認できます。

  • + n_epochs + は、SGDの反復回数です。これは基本的に、関数を最小化するために統計で使用される反復法です。

  • + lr_all + は、すべてのパラメーターの学習率です。これは、各反復でパラメーターを調整する量を決定するパラメーターです。

  • + reg_all + はすべてのパラメーターの正規化用語であり、過適合を防ぐために追加されるペナルティ用語です。

*注:*潜在的な要因がユーザーまたはアイテム間の類似性を処理するため、マトリックス分解アルゴリズムには類似性メトリックが存在しないことに注意してください。

次のプログラムは、マトリックス分解アルゴリズムであるhttps://surprise.readthedocs.io/en/stable/matrix_factorization.html#surprise.prediction_algorithms.matrix_factorization.SVDpp[SVD]アルゴリズムの最適値をチェックします。

from surprise import SVD
from surprise import Dataset
from surprise.model_selection import GridSearchCV

data = Dataset.load_builtin("ml-100k")

param_grid = {
    "n_epochs": [5, 10],
    "lr_all": [0.002, 0.005],
    "reg_all": [0.4, 0.6]
}
gs = GridSearchCV(SVD, param_grid, measures=["rmse", "mae"], cv=3)

gs.fit(data)

print(gs.best_score["rmse"])
print(gs.best_params["rmse"])

上記のプログラムの出力は次のとおりです。

0.9642278631521038
{'n_epochs': 10, 'lr_all': 0.005, 'reg_all': 0.4}

したがって、MovieLens 100kデータセットの場合、10エポックに進み、0.005および0.4正則化の学習率を使用すると、「+ SVD +」アルゴリズムが最適に機能します。

`+ Surprise `で利用可能な他のマトリックス分解ベースのアルゴリズムは、https://surprise.readthedocs.io/en/stable/matrix_factorization.html#surprise.prediction_algorithms.matrix_factorization.SVDpp [SVD +]およびhttps://surprise.readthedocs.ioです。/en/stable/matrix_factorization.html#surprise.prediction_algorithms.matrix_factorization.SVDpp[NMF]。

これらの例に従って、これらのアルゴリズムで使用できるすべてのパラメーターを深く掘り下げることができます。 あなたは間違いなくそれらの背後にある数学をチェックアウトする必要があります。 最初にアルゴリズムの実装について心配する必要はないため、リコメンダーは機械学習の分野に移行し、それに基づいてアプリケーションを構築するのに最適な方法です。

協調フィルタリングはいつ使用できますか?

協調フィルタリングは、ユーザーがアイテムに対して行う対話を回避します。 これらの相互作用は、アイテムやユーザーに関するデータではできないパターンを見つけるのに役立ちます。 協調フィルタリングを使用できるかどうかを判断するのに役立ついくつかのポイントを次に示します。

  • 協調フィルタリングでは、アイテムやユーザーに関する機能を知る必要はありません。 さまざまな種類のアイテムのセットに適しています。たとえば、さまざまなカテゴリのアイテムを追加できるスーパーマーケットの在庫などです。 しかし、書店のような類似のアイテムのセットでは、作家やジャンルなどの既知の機能が有用である可能性があり、コンテンツベースまたはハイブリッドのアプローチの恩恵を受ける可能性があります。

  • 協調フィルタリングは、レコメンダーがユーザーのプロファイルを過度に専門化せず、以前に見たものとは完全に異なるアイテムを推奨するのに役立ちます。 同様のスニーカーを購入したばかりの人に推奨者がスニーカーを提案しないようにしたい場合は、推奨スペルに協調フィルタリングを追加してみてください。

コラボレーティブフィルタリングはレコメンダーで非常に一般的に使用されていますが、使用中に直面する課題のいくつかは次のとおりです。

  • 協調フィルタリングは、リストに追加された新しいアイテムのコールドスタートなどの問題を引き起こす可能性があります。 誰かがそれらを評価するまで、推奨されません。

  • データのスパース性は、ユーザーベースのレコメンダーの品質に影響を与え、上記のコールドスタートの問題に追加される可能性があります。

  • 複雑さは大きくなりすぎる可能性があるため、スケーリングはデータセットの成長にとって困難な場合があります。 データセットが大きい場合、アイテムベースのレコメンダーはユーザーベースのレコメンダーよりも高速です。

  • 簡単な実装では、推奨事項がすでに人気があり、https://en.wikipedia.org/wiki/Long_tail [long tail]セクションの項目が無視される可能性があることに気付くかもしれません。

長所と短所の独自のリストを持つすべてのタイプのリコメンダーアルゴリズムでは、通常、救助に来るのはハイブリッドレコメンダーです。 一緒にまたはパイプラインで動作する複数のアルゴリズムの利点は、より正確なレコメンダーのセットアップに役立ちます。 実際、Netflix賞の受賞者のソリューションは、複数のアルゴリズムの複雑な組み合わせでもありました。

結論

これで、協調フィルタリングタイプレコメンダーの計算と、データセットでさまざまなタイプのアルゴリズムをすばやく試して、協調フィルタリングが有効かどうかを確認する方法がわかりました。 高い精度でデータに適合していないように思われる場合でも、説明したユースケースのいくつかは、長期的にハイブリッドな方法で物事を計画するのに役立つ場合があります。

実装のほか、協調フィルタリングやその他の推奨アルゴリズムの詳細を読むためのリソースを次に示します。

図書館:

研究論文:

  • * http://files.grouplens.org/papers/www10_sarwar.pdf [アイテムベースの協調フィルタリング推奨アルゴリズム]:*アイテムベースの推奨者に関する最初の論文

  • * https://scinapse.io/papers/1966553486 [協調フィルタリングを使用して情報タペストリーを織り込む]:*協調フィルタリングという用語の最初の使用

本: