[データ マイニングとビジネス インテリジェンスの意思決定] 第 15 章 インテリジェント レコメンデーション システム - 協調フィルタリング アルゴリズム

序文

私のCSDNブログは「バイオニックプログラマーは電子羊の夢を見るか」です。この記事はマークダウンに基づいて書かれており、プラットフォームとソフトウェアはCSDNとTyporaであり、記事内の画像の保存アドレスはCSDNであるため、一部の画像には「」が含まれている可能性があります。 CSDN@维红者计划会「電気羊の夢」の透かしは私自身のオリジナルであり、「データマイニングとビジネスインテリジェンスの意思決定」の日常業務と主要業務に使用されています。

この記事の内容は、第 15 章「インテリジェント レコメンデーション システム - 協調フィルタリング アルゴリズム」です。
読みやすいように、記事の内容を次のセクションに分けました。

  1. 基本知識
  2. 実験内容
  3. 拡張研究
  4. 経験

その中で、各セクションの紹介は次のとおりです。

  • 基本知識
    • この章のトピックに関する個人的な学習と理解、要約された知識ポイント、記録する価値のあるコードと操作の結果が含まれています。
  • 実験内容
    • これはこの記事の主題実験部分であり、教師から送信された実験内容でもあり、コンピューター (jupyter Notebook) 上で正常に実行された後、マークダウン形式にエクスポートされます。
    • このうち、メインタイトルは各章の小節の内容です
      ここに画像の説明を挿入
    • 上の図に示すように、メイン タイトルは PCA 主成分分析とコード実装、サブタイトルはファイル内のサブモジュールです。各メイン タイトルの内容は互いに異なります。つまり、同じ Python ライブラリ参照が 2 つのメイン タイトルで見つかる場合があります。コードの整合性を確保するために、ここでは予約されています。
    • 授業の課題が確実に完了していることを示すために、教師が与えたコードとほぼ同じですが、マークダウンテキストの部分は私なりの理解を加えていますが、データソースが必ずしも正しいものであるとは限らないため、同様に、実行結果や描画もチュートリアルとは異なりますが、実験自体は正しく完了しています。
    • さらに、教師から送信されたいくつかの関連ケース (コース センターではなく、航空会社の顧客価値分析のケース) もこの部分に添付されます。
  • 拡張研究
    • この部分は、コードやナレッジポイントを含め、この主題の実験以外で試した拡張コンテンツであり、私自身の実験も含まれています
  • 経験

基本知識

実験内容

15.2 類似性計算の 3 つの一般的な方法

15.2.1 ユークリッド距離

import pandas as pd
df = pd.DataFrame([[5, 1, 5], [4, 2, 2], [4, 2, 1]], columns=['用户1', '用户2', '用户3'], index=['物品A', '物品B', '物品C'])
df
ユーザー1 ユーザー2 ユーザー3
アイテムA 5 1 5
アイテムB 4 2 2
アイテムC 4 2 1
import numpy as np
dist = np.linalg.norm(df.iloc[0] - df.iloc[1])
dist
3.3166247903554

15.2.2 コサイン組み込み関数

import pandas as pd
df = pd.DataFrame([[5, 1, 5], [4, 2, 2], [4, 2, 1]], columns=['用户1', '用户2', '用户3'], index=['物品A', '物品B', '物品C'])
df
ユーザー1 ユーザー2 ユーザー3
アイテムA 5 1 5
アイテムB 4 2 2
アイテムC 4 2 1
from sklearn.metrics.pairwise import cosine_similarity
user_similarity = cosine_similarity(df)
pd.DataFrame(user_similarity, columns=['物品A', '物品B', '物品C'], index=['物品A', '物品B', '物品C'])
アイテムA アイテムB アイテムC
アイテムA 1.000000 0.914659 0.825029
アイテムB 0.914659 1.000000 0.979958
アイテムC 0.825029 0.979958 1.000000

15.2.3 ピアソン相関係数の簡易版

from scipy.stats import pearsonr
X = [1, 3, 5, 7, 9]
Y = [9, 8, 6, 4, 2]
corr = pearsonr(X, Y)
print('相关系数r值为' + str(corr[0]) + ',显著性水平P值为' + str(corr[1]))
相关系数r值为-0.9938837346736188,显著性水平P值为0.0005736731093322215

ピアソン相関係数が小さい場合

import pandas as pd
df = pd.DataFrame([[5, 4, 4], [1, 2, 2], [5, 2, 1]], columns=['物品A', '物品B', '物品C'], index=['用户1', '用户2', '用户3'])  
df
アイテムA アイテムB アイテムC
ユーザー1 5 4 4
ユーザー2 1 2 2
ユーザー3 5 2 1
# 物品A与其他物品的皮尔逊相关系数
A = df['物品A']
corr_A = df.corrwith(A)
corr_A
物品A    1.000000
物品B    0.500000
物品C    0.188982
dtype: float64
# 皮尔逊系数表,获取各物品相关性
df.corr()
アイテムA アイテムB アイテムC
アイテムA 1.000000 0.500000 0.188982
アイテムB 0.500000 1.000000 0.944911
アイテムC 0.188982 0.944911 1.000000

15.3 ケーススタディ - 映画インテリジェント レコメンダー システム

1. データの読み取り

import pandas as pd 
movies = pd.read_excel('电影.xlsx')
movies.head()
映画番号 名前 カテゴリー
0 1 トイ・ストーリー (1995) アドベンチャー | アニメーション | キッズ | コメディ | ファンタジー
1 2 ジュマンジ (1995) アドベンチャー|子供|ファンタジー
2 3 ファイティング・オールド・ウニ 2 (1995) コメディ|ロマンス
3 4 目覚める時まで待ってください (1995) コメディ|ドラマ|ロマンス
4 5 花嫁の父 2 (1995) コメディ
score = pd.read_excel('评分.xlsx')
score.head()
ユーザーID 映画番号 スコア
0 1 1 4.0
1 1 3 4.0
2 1 6 4.0
3 1 47 5.0
4 1 50 5.0
df = pd.merge(movies, score, on='电影编号')
df.head()
映画番号 名前 カテゴリー ユーザーID スコア
0 1 トイ・ストーリー (1995) アドベンチャー | アニメーション | キッズ | コメディ | ファンタジー 1 4.0
1 1 トイ・ストーリー (1995) アドベンチャー | アニメーション | キッズ | コメディ | ファンタジー 5 4.0
2 1 トイ・ストーリー (1995) アドベンチャー | アニメーション | キッズ | コメディ | ファンタジー 7 4.5
3 1 トイ・ストーリー (1995) アドベンチャー | アニメーション | キッズ | コメディ | ファンタジー 15 2.5
4 1 トイ・ストーリー (1995) アドベンチャー | アニメーション | キッズ | コメディ | ファンタジー 17 4.5
df.to_excel('电影推荐系统.xlsx')
df['评分'].value_counts()  # 查看各个评分的出现的次数
4.0    26794
3.0    20017
5.0    13180
3.5    13129
4.5     8544
2.0     7545
2.5     5544
1.0     2808
1.5     1791
0.5     1369
Name: 评分, dtype: int64
%matplotlib inline
import matplotlib.pyplot as plt
df['评分'].hist(bins=20)  # hist()函数绘制直方图,竖轴为各评分出现的次数
<AxesSubplot:>

ここに画像の説明を挿入

2. データ分析

ratings = pd.DataFrame(df.groupby('名称')['评分'].mean())
ratings.sort_values('评分', ascending=False).head()
スコア
名前
お転婆 (1997) 5.0
シャーロック ホームズとワトソン博士の冒険: 恐喝の王 (1980) 5.0
ロボット (2016) 5.0
オスカー (1967) 5.0
人間の条件III (1961) 5.0
ratings['评分次数'] = df.groupby('名称')['评分'].count()
ratings.sort_values('评分次数', ascending=False).head()
スコア 評価数
名前
フォレスト・ガンプ (1994) 4.164134 329
ショーシャンクの空に (1994) 4.429022 317
パルプ フィクション (1994) 4.197068 307
羊たちの沈黙 (1991) 4.161290 279
マトリックス (1999) 4.192446 278

3. データ処理

user_movie = df.pivot_table(index='用户编号', columns='名称', values='评分')
user_movie.tail()
名前 007 ゴールデンアイ (1995) 100人の女の子 (2000) 100 ストリート (2016) 101 匹の犬: ロンドンの冒険 (2003) の続編 101忠狗(1961) 101 レイキャビク (2000) 102 ダルメシアン (2000) 10個以下(2006年) 10(1979) 11:14(2003) ... ドラゴンボール ミステリーアドベンチャー (1988) ドラゴンボール 呪いの血ルビー (1986) ドラゴンボール 魔神城のねむり姫 (1987) ドラゴンシード (1944) ドラゴン・タトゥーの女 (2011) テキーラ サンライズ (1988) ロブスター (2015) ドラゴンズ: 夜の怒りの贈り物 (2011) ドラゴン: ブルース・リー物語 (1993) タートル・ダイアリーズ (1985)
ユーザーID
606 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
607 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
608 4.0 NaN NaN NaN NaN NaN NaN 3.5 NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
609 4.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
610 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN 4.0 NaN 4.5 NaN NaN NaN

5行×9687列

user_movie.describe()  # 因为数据量较大,这个耗时可能会有1分钟左右
名前 007 ゴールデンアイ (1995) 100人の女の子 (2000) 100 ストリート (2016) 101 匹の犬: ロンドンの冒険 (2003) の続編 101忠狗(1961) 101 レイキャビク (2000) 102 ダルメシアン (2000) 10個以下(2006年) 10(1979) 11:14(2003) ... ドラゴンボール ミステリーアドベンチャー (1988) ドラゴンボール 呪いの血ルビー (1986) ドラゴンボール 魔神城のねむり姫 (1987) ドラゴンシード (1944) ドラゴン・タトゥーの女 (2011) テキーラ サンライズ (1988) ロブスター (2015) ドラゴンズ: 夜の怒りの贈り物 (2011) ドラゴン: ブルース・リー物語 (1993) タートル・ダイアリーズ (1985)
カウント 132.000000 4.00 1.0 1.0 44.000000 1.0 9.000000 3.000000 4.000000 4.00 ... 1.0 1.0 2.000000 1.0 42.000000 13.000000 7.000000 1.0 8.00000 2.0
平均 3.496212 3.25 2.5 2.5 3.431818 3.5 2.777778 2.666667 3.375000 3.75 ... 3.5 3.5 3.250000 3.5 3.488095 3.038462 4.000000 5.0 2.81250 4.0
標準 0.859381 0.50 NaN NaN 0.751672 NaN 0.833333 1.040833 1.030776 0.50 ... NaN NaN 0.353553 NaN 1.327422 0.431158 0.707107 NaN 1.03294 0.0
0.500000 2.50 2.5 2.5 1.500000 3.5 2.000000 1.500000 2.000000 3.00 ... 3.5 3.5 3.000000 3.5 0.500000 2.000000 3.000000 5.0 0.50000 4.0
25% 3.000000 3.25 2.5 2.5 3.000000 3.5 2.000000 2.250000 3.125000 3.75 ... 3.5 3.5 3.125000 3.5 2.625000 3.000000 3.500000 5.0 2.87500 4.0
50% 3.500000 3.50 2.5 2.5 3.500000 3.5 2.500000 3.000000 3.500000 4.00 ... 3.5 3.5 3.250000 3.5 4.000000 3.000000 4.000000 5.0 3.00000 4.0
75% 4.000000 3.50 2.5 2.5 4.000000 3.5 3.000000 3.250000 3.750000 4.00 ... 3.5 3.5 3.375000 3.5 4.000000 3.000000 4.500000 5.0 3.12500 4.0
最大 5.000000 3.50 2.5 2.5 5.000000 3.5 4.500000 3.500000 4.500000 4.00 ... 3.5 3.5 3.500000 3.5 5.000000 4.000000 5.000000 5.0 4.00000 4.0

8行×9687列

4. 賢いおすすめ

FG = user_movie['阿甘正传(1994)']  # FG是Forrest Gump(),阿甘英文名称的缩写
pd.DataFrame(FG).head()
フォレスト・ガンプ (1994)
ユーザーID
1 4.0
2 NaN
3 NaN
4 NaN
5 NaN
import numpy as np
np.seterr(divide='ignore',invalid='ignore')
# axis默认为0,计算user_movie各列与FG的相关系数
corr_FG = user_movie.corrwith(FG)
similarity = pd.DataFrame(corr_FG, columns=['相关系数'])
similarity.head()
D:\coder\randomnumbers\venv\lib\site-packages\numpy\lib\function_base.py:2845: RuntimeWarning: Degrees of freedom <= 0 for slice
  c = cov(x, y, rowvar, dtype=dtype)
D:\coder\randomnumbers\venv\lib\site-packages\numpy\lib\function_base.py:518: RuntimeWarning: Mean of empty slice.
  avg = a.mean(axis, **keepdims_kw)
相関係数
007 ゴールデンアイ (1995) 0.217441
100人の女の子 (2000) NaN
100 ストリート (2016) NaN
101 匹の犬: ロンドンの冒険 (2003) の続編 NaN
101忠狗(1961) 0.141023
similarity.dropna(inplace=True)  # 或写成similarity=similarity.dropna()
similarity.head()
相関係数
007 ゴールデンアイ (1995) 0.217441
101忠狗(1961) 0.141023
102 ダルメシアン (2000) -0.857589
10個以下(2006年) -1.000000
11:14(2003) 0.500000
similarity_new = pd.merge(similarity, ratings['评分次数'], left_index=True, right_index=True)
similarity_new.head()
相関係数 評価数
007 ゴールデンアイ (1995) 0.217441 132
101忠狗(1961) 0.141023 44
102 ダルメシアン (2000) -0.857589 9
10個以下(2006年) -1.000000 3
11:14(2003) 0.500000 4
# 第二种合并方式
similarity_new = similarity.join(ratings['评分次数'])
similarity_new.head()
相関係数 評価数
007 ゴールデンアイ (1995) 0.217441 132
101忠狗(1961) 0.141023 44
102 ダルメシアン (2000) -0.857589 9
10個以下(2006年) -1.000000 3
11:14(2003) 0.500000 4
similarity_new[similarity_new['评分次数'] > 20].sort_values(by='相关系数', ascending=False).head()  # 选取阈值
相関係数 評価数
フォレスト・ガンプ (1994) 1.000000 329
クレイジー・ツインズ (1996) 0.723238 31
マイティ・ソー: ダーク・ワールド (2013) 0.715809 21
フェイタル・アトラクション (1987) 0.701856 36
X-MEN: デイズ・オブ・フューチャー・パスト (2014) 0.682284 30

補足知識: groupby() 関数の使用

import pandas as pd
data = pd.DataFrame([['战狼2', '丁一', 6, 8], ['攀登者', '王二', 8, 6], ['攀登者', '张三', 10, 8], ['卧虎藏龙', '李四', 8, 8], ['卧虎藏龙', '赵五', 8, 10]], columns=['电影名称', '影评师', '观前评分', '观后评分'])
data
映画のタイトル 映画評論家 プレビュー評価 視聴後の評価
0 狼の戦士2 ディン・イー 6 8
1 クライマー ワン・アー 8 6
2 クライマー 張三 10 8
3 クラウチング・タイガー、ヒドゥン・ドラゴン 李思 8 8
4 クラウチング・タイガー、ヒドゥン・ドラゴン 趙武 8 10
means = data.groupby('电影名称')[['观后评分']].mean()
means
視聴後の評価
映画のタイトル
クラウチング・タイガー、ヒドゥン・ドラゴン 9.0
狼の戦士2 8.0
クライマー 7.0
means = data.groupby('电影名称')[['观前评分', '观后评分']].mean()
means
プレビュー評価 視聴後の評価
映画のタイトル
クラウチング・タイガー、ヒドゥン・ドラゴン 8.0 9.0
狼の戦士2 6.0 8.0
クライマー 9.0 7.0
means = data.groupby(['电影名称', '影评师'])[['观后评分']].mean()
means
視聴後の評価
映画のタイトル 映画評論家
クラウチング・タイガー、ヒドゥン・ドラゴン 李思 8.0
趙武 10.0
狼の戦士2 ディン・イー 8.0
クライマー 張三 8.0
ワン・アー 6.0
count = data.groupby('电影名称')[['观后评分']].count()
count
視聴後の評価
映画のタイトル
クラウチング・タイガー、ヒドゥン・ドラゴン 2
狼の戦士2 1
クライマー 2
count = count.rename(columns={
    
    '观后评分':'评分次数'})
count
評価数
映画のタイトル
クラウチング・タイガー、ヒドゥン・ドラゴン 2
狼の戦士2 1
クライマー 2

拡張研究

経験

おすすめ

転載: blog.csdn.net/Algernon98/article/details/130571749