簡単な推薦システムを作ってみた
ある人の使用しているプログラミング言語から、次に学習すべきプログラミング言語の推薦システムを簡単に作った。
Python3.5でかいた。 参考書籍はこれ。
データサイエンティスト養成読本 機械学習入門編 (Software Design plus)
- 作者: 比戸将平,馬場雪乃,里洋平,戸嶋龍哉,得居誠也,福島真太朗,加藤公一,関喜史,阿部厳,熊崎宏樹
- 出版社/メーカー: 技術評論社
- 発売日: 2015/09/10
- メディア: 大型本
- この商品を含むブログ (7件) を見る
データ
データはこれ。
Ruby,Python,HTML/CSS/JS,C,C++,Java,PHP,C# 0,5,2,0,3,4,1,0 4,0,0,0,0,0,5,0 0,0,0,5,4,0,0,0 0,3,2,0,5,4,0,0 0,5,4,0,0,2,0,0 3,0,2,0,5,4,0,0 0,0,0,0,4,3,0,5 0,1,2,5,4,0,0,3 0,4,0,5,0,0,0,0 0,4,0,0,5,0,0,0 0,0,0,0,4,5,0,0 3,4,1,0,0,5,2,0 5,4,2,0,0,0,0,3 4,5,0,0,0,0,0,0 3,0,4,0,0,5,0,0 5,0,4,0,3,0,0,0 3,0,0,0,0,5,4,0 0,0,3,5,4,0,0,0 0,0,0,5,4,0,0,3 0,4,0,5,0,3,0,0 4,0,3,0,0,0,0,5 0,4,0,0,5,0,0,0
Twitterのフォロワーさんのプロフィールを元にデータを作りました。 プロフィールの一番左に書いてあるプログラミング言語を評価値を5として、右にいくにつれてデクリメント。
例えば、 C/C++/Ruby/JS なら Cの評価値を5、C++の評価値を4、Rubyの評価値を3、そしてJSの評価値を2みたいな感じで、最大5個まで評価値をつけていった。
書いていない言語は触ったことがないものとして、評価値を0にした。
コード
処理としては、推薦したい人が習得している言語と、似たような傾向を持った人が習得している言語を推薦している。
似てるか似てないかは、コサイン距離を用いて表現している。
# coding:utf-8 import numpy as np import scipy as sp from scipy.spatial.distance import cosine def calc_item_score(target_user_index, user_rating_matrix): """ 指定したアイテムの評価値を計算する :param target_user_index: int: ユーザのIndex :param user_rating_matrix: numpy.ndarray: ユーザアイテムの評価値行列 :return: float: 指定したアイテムの評価値 """ target_user_ratings = user_rating_matrix[target_user_index] item_similarity = np.zeros(len(target_user_ratings)) for compare_user_index in np.arange(len(user_rating_matrix)): compare_user_ratings = user_rating_matrix[compare_user_index] if compare_user_index == target_user_index: # 同一ユーザのときは類似度計算はしない continue # ユーザの類似度をコサイン距離から求める user_similarity = 1.0 - cosine(target_user_ratings, compare_user_ratings) # 求めたコサイン距離をそのユーザの評価値に乗じて足しあわせる item_similarity += user_similarity * compare_user_ratings return item_similarity # データ読み込み data = sp.loadtxt("data.csv",delimiter=",",skiprows=1) # 推薦計算 predict_ratings = calc_item_score(0,data) # 推薦したい言語の取得 header = ['Ruby','Python','HTML/CSS/JS','C','C++','Java','PHP','C\#'] zero_index = np.nonzero(data[0,:] != 0) for i in zero_index: predict_ratings[i] = 0.0 max_index = np.where(predict_ratings == predict_ratings.max()) print("次は ",end="") print(header[max_index[0][0]],end="") print(" をやるんやで")
実行結果
% python main.py 次は Ruby をやるんやで
となる。