ピアソン相関係数とk-means法を使って嗜好の似ている人を特定するプログラムをpythonでやりたい

映画サイトとかでレビューってあるじゃない? あれのユーザーごとのレビューの評価データを集めて、自分と似てる人にオススメの映画紹介して欲しくない? それをpythonでやれたら素敵じゃない? という事でpythonでピアソン相関係数を用いて類似度を計算し、自分と似てる人を特定するというプログラムを作ってみた。

やることの概要としては以下。
・レビューデータをベクトル化
・レビューデータのベクトルをk-means法でグループ分け(クラスタリング)
・誰と誰が似てるかをグループで明示
例えば、人間とウサギにアンケートし、好きな食べ物を5段階評価でアンケートしてもらった。アンケートデータは以下。

人間はハンバーグとか麻婆豆腐とかの好き嫌いを入れているのに対して、アイドルウサギのモキュ様などはペレットやチモシーなどの好みを入れている。人間が見れば、これがウサギだ、これが人間だと判断できるが、プログラムは判別できない。それを判断できるとかっこいい。
まずはこのデータをベクトル化する。ベクトル化する関数は下記。

testdataをこの関数に入れてやれば、「vectorData.csv」という形で保存される。エクセルで見ると人の名前とその人の食べ物の嗜好がテーブルになっているのがわかる。こんな感じ。小梅ちゃんがActiveEしか食べないのが心配される。

このファイルから、以下の関数で名前のリスト(colNames)、食べ物のリスト(rowNames)、食べ物の評価値のリスト(data)を作る。

createVector()を実行した後でreadFile()を実行すれば良い。さっきのcsvファイルを元に各データがreturnされる。こんな感じ。

>>> colNames
[‘\xe3\x82\xa8\xe3\x83\xb3\xe3\x83\x8f\xe3\x83\xb3\xe3\x82\xb5\xe3\x83\xbc’, ‘\xe3\x83\x9a\xe3\x83\xac\xe3\x83\x83\xe3\x83\x88’, ‘\xe3\x83\x81\xe3\x83\xa2\xe3\x82\xb7\xe3\x83\xbc’, ‘\xe3\x83\x93\xe3\x83\xbc\xe3\x83\xab’, ‘\xe7\xb4\x8d\xe8\xb1\x86’, ‘ActiveE’, ‘\xe9\xba\xbb\xe5\xa9\x86\xe8\xb1\x86\xe8\x85\x90’, ‘\xe3\x83\x8f\xe3\x83\xb3\xe3\x83\x90\xe3\x83\xbc\xe3\x82\xb0’]
>>>
>>>
>>> rowNames
[‘mocu’, ‘sota’, ‘yhei’, ‘chataro’, ‘koume’, ‘tanaka’, ‘karupati’]
>>>
>>>
>>>
>>> data
[[2.0, 3.0, 2.0, 0.0, 0.0, 3.0, 0.0, 0.0], [5.0, 5.0, 5.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 4.0, 1.0, 0.0, 3.0, 5.0], [5.0, 4.0, 3.0, 0.0, 0.0, 5.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 5.0, 0.0, 0.0], [0.0, 0.0, 0.0, 1.0, 5.0, 0.0, 5.0, 2.0], [0.0, 0.0, 0.0, 3.0, 1.0, 0.0, 2.0, 3.0]]

例えばdata[0]にモキュ様の食べ物の評価値のリスト([2.0, 3.0, 2.0, 0.0, 0.0, 3.0, 0.0, 0.0])が入る。このdataというリストが入ったリスト(ややこしい)を

>>> kclust, clusters = pearson.kcluster(data)

上記のようにk-means法でクラスタリングする関数、kcluster()に入れるとデフォルト二つのグループに分けてくれる。k-means法を簡単に示した例は下記。k-means法の理論はここが参考になる。k個の点をランダムな位置にとって、各ベクトルがどこに近いかでグループ化する手法である。
関数は下記。kの引数を変えることで何グループに分けるか指定できる。

kclustにグループ分けされたリストが出てくる。下記の感じ。

>>> kclust
[[0, 1, 3, 4], [2, 5, 6]]

1要素がグループを示しており、数字は誰かを示すid。id0はmocuさまを示す。rowNamesを使って、名前を特定できる。

[[0, 1, 3, 4], [2, 5, 6]]
>>> [rowNames[r] for r in kclust[0]]
[‘mocu’, ‘sota’, ‘chataro’, ‘koume’]
>>> [rowNames[r] for r in kclust[1]]
[‘yhei’, ‘tanaka’, ‘karupati’]

上記の通り、モキュ様そうた君、うちの茶太郎小梅ちゃんとウサギのグループを示すkclust[0]。
yhei、tanakaさん、karupati(俺のニコニコ動画のHN)さんが人間グループを示すkclust[1]のように、嗜好アンケートからグループ分けができた。今後、ウサギか人間のどちらかにアンケートを取った時に、どちらのグループに似ているかをみることにより、その人がウサギなのか人間なのか推測することができる。データが多ければ多いほど精度は高くなる。こう言う学習して精度が良くなっていく感じが機械学習の楽しいところ。
今回使ったpythonプログラムは下記の通り。一番下にReadMe的なものを書いてるので流用する場合はご参照をば。