ここでも,「商品データ」「顧客データ」「評価データ」の3つのデータを読み込んで行列形式に集計する方法を確認します.前のページとの違いは3つのテーブルを一気に結合するところです.
まず,必要なライブラリをインポートします.
import pandas as pd
import numpy as np
商品のCSVデータを GitHub のリポジトリからデータフレームに読み込みます.
url_items = "https://github.com/rinsaka/sample-data-sets/blob/master/collaborative_filtering_items.csv?raw=true"
df_items = pd.read_csv(url_items)
print(df_items)
id item 0 0 A 1 1 B 2 2 C 3 3 D 4 4 E
顧客のCSVデータを読み込みます.
url_customers = "https://github.com/rinsaka/sample-data-sets/blob/master/collaborative_filtering_customers.csv?raw=true"
df_customers = pd.read_csv(url_customers )
print(df_customers)
id name 0 0 Eto 1 1 Sato 2 2 Kato 3 3 Muto 4 4 Kito 5 5 Goto 6 6 Bito 7 7 Saito 8 8 Naito 9 9 Koto
次に,評価のCSVデータを読み込みます.例えば先頭行は,顧客ID = 8 の Naito さんが,商品ID = 3 の商品「D」について「2」という評価を行ったことを意味しています.
url_ratings = "https://github.com/rinsaka/sample-data-sets/blob/master/collaborative_filtering_ratings.csv?raw=true"
df_ratings = pd.read_csv(url_ratings)
print(df_ratings)
customer item rating
0 8 3 2
1 1 1 2
2 6 1 3
3 9 2 2
4 6 0 3
5 2 2 4
6 1 2 4
7 4 2 3
8 3 2 2
9 8 0 5
10 0 0 5
11 2 1 3
12 4 0 4
13 5 4 3
14 7 2 5
15 8 4 1
16 5 3 2
17 6 4 1
18 0 1 4
19 1 3 2
20 5 0 2
21 7 1 4
22 0 2 3
23 5 1 5
24 3 1 3
25 8 1 5
26 3 4 2
27 8 2 4
28 9 3 2
29 1 4 3
30 6 2 2
31 2 0 2
32 3 0 2
33 9 4 2
34 7 4 5
35 7 0 4
36 9 0 3
37 4 3 4
38 4 1 3
3つのテーブル(表のこと)を一気に結合します.なお,テーブルの結合に関する詳細はここやここで確認してください.
tbl_3 = pd.merge(
pd.merge(
df_ratings, df_items,
left_on = 'item',
right_on = 'id',
),
df_customers,
left_on = 'customer', right_on = 'id'
)
print(tbl_3)
customer item_x rating id_x item_y id_y name
0 8 3 2 3 D 8 Naito
1 8 1 5 1 B 8 Naito
2 8 2 4 2 C 8 Naito
3 8 0 5 0 A 8 Naito
4 8 4 1 4 E 8 Naito
5 5 3 2 3 D 5 Goto
6 5 1 5 1 B 5 Goto
...(中略)...
33 7 0 4 0 A 7 Saito
34 7 4 5 4 E 7 Saito
35 3 1 3 1 B 3 Muto
36 3 2 2 2 C 3 Muto
37 3 0 2 0 A 3 Muto
38 3 4 2 4 E 3 Muto
列名を変更します.
tbl_3 = tbl_3.rename(columns={'item_y': 'item', 'id_y': 'id'})
print(tbl_3)
customer item_x rating id_x item id name
0 8 3 2 3 D 8 Naito
1 8 1 5 1 B 8 Naito
2 8 2 4 2 C 8 Naito
...(省略)...
必要な列だけ残し,更に順序も変更します.
tbl_3 = tbl_3.loc[:,['id', 'name','item','rating']]
print(tbl_3)
id name item rating 0 8 Naito D 2 1 8 Naito B 5 2 8 Naito C 4 3 8 Naito A 5 4 8 Naito E 1 5 5 Goto D 2 6 5 Goto B 5 7 5 Goto A 2 8 5 Goto E 3 9 1 Sato D 2 10 1 Sato B 2 11 1 Sato C 4 12 1 Sato E 3 13 9 Koto D 2 14 9 Koto C 2 15 9 Koto A 3 16 9 Koto E 2 17 4 Kito D 4 18 4 Kito B 3 19 4 Kito C 3 20 4 Kito A 4 21 6 Bito B 3 22 6 Bito C 2 23 6 Bito A 3 24 6 Bito E 1 25 2 Kato B 3 26 2 Kato C 4 27 2 Kato A 2 28 0 Eto B 4 29 0 Eto C 3 30 0 Eto A 5 31 7 Saito B 4 32 7 Saito C 5 33 7 Saito A 4 34 7 Saito E 5 35 3 Muto B 3 36 3 Muto C 2 37 3 Muto A 2 38 3 Muto E 2
評価の生データをピボットテーブルを利用して行列形式にまとめます.まず,念の為に顧客と商品ごとの評価数を確認します.つまり,同一顧客が同じ商品に複数回評価していないかを確認しておきます.この結果,1.0 より大きなデータがない,つまり,同じ商品を複数回評価しているデータはないことがわかりました.
df = tbl_3.pivot_table('rating', index=['id', 'name'], columns='item', aggfunc='count')
print(df)
item A B C D E id name 0 Eto 1.0 1.0 1.0 NaN NaN 1 Sato NaN 1.0 1.0 1.0 1.0 2 Kato 1.0 1.0 1.0 NaN NaN 3 Muto 1.0 1.0 1.0 NaN 1.0 4 Kito 1.0 1.0 1.0 1.0 NaN 5 Goto 1.0 1.0 NaN 1.0 1.0 6 Bito 1.0 1.0 1.0 NaN 1.0 7 Saito 1.0 1.0 1.0 NaN 1.0 8 Naito 1.0 1.0 1.0 1.0 1.0 9 Koto 1.0 NaN 1.0 1.0 1.0
重複した評価がないことが確認できたので,合計を計算すると簡単に集計できます.
df = tbl_3.pivot_table('rating', index=['id', 'name'], columns='item', aggfunc='sum')
print(df)
item A B C D E id name 0 Eto 5.0 4.0 3.0 NaN NaN 1 Sato NaN 2.0 4.0 2.0 3.0 2 Kato 2.0 3.0 4.0 NaN NaN 3 Muto 2.0 3.0 2.0 NaN 2.0 4 Kito 4.0 3.0 3.0 4.0 NaN 5 Goto 2.0 5.0 NaN 2.0 3.0 6 Bito 3.0 3.0 2.0 NaN 1.0 7 Saito 4.0 4.0 5.0 NaN 5.0 8 Naito 5.0 5.0 4.0 2.0 1.0 9 Koto 3.0 NaN 2.0 2.0 2.0
これで行列形式のデータフレームが完成したので,NumPy 配列に格納し,レイティング行列 y
を生成します.
y = df.values
print(y)
[[ 5. 4. 3. nan nan] [nan 2. 4. 2. 3.] [ 2. 3. 4. nan nan] [ 2. 3. 2. nan 2.] [ 4. 3. 3. 4. nan] [ 2. 5. nan 2. 3.] [ 3. 3. 2. nan 1.] [ 4. 4. 5. nan 5.] [ 5. 5. 4. 2. 1.] [ 3. nan 2. 2. 2.]]
これも以前のページの行列 y
と全く同じ形式です.ここまでできれば,類似度の計算やスコアの計算は前のページと同じ方法で可能です.
これまでコードを断片的に示してきたので,次のページではコードの全体像を示します.