fastai動かしてみたLesson4③ 協調フィルタリング

公開日:2019-05-19
最終更新:2019-05-25

今回はLesson4 https://course.fast.ai/videos/?lesson=4

notebookはこちら https://github.com/fastai/course-v3/tree/master/nbs/dl1

自然言語処理、協調フィルタリング、テーブルデータの機械学習について学んでいく

協調フィルタリング

協調フィルタリングの参考:https://www.albert2005.co.jp/knowledge/marketing/recommendation_basics/collaborative_filtering

Amazonとかショッピングサイトのおすすめ商品を求めるのとかに使われている

協調フィルタリングの構造は2つの方法で表すことができる
1つ目はユーザと映画の列を持つ表(左図)
2つ目はユーザーごとに映画の評価を持つ表(右図)

右図のような方法だと空欄が多くできてしまうため、ここでは左図のような形式のデータを扱う

実際に動かしてみると以下のようになる
今までやってきたことと大体やり方はおんなじ

サンプルデータのダウンロードとそのPathを得る

user,item,title = 'userId','movieId','title'  
path = untar_data(URLs.ML_SAMPLE)  
path  

PosixPath('/root/.fastai/data/movie_lens_sample')

ユーザーの映画に対する評価をいつ行ったかのcsvを読み込む

ratings = pd.read_csv(path/'ratings.csv')  
ratings.head()  

読み込んだDataframeからdatabunchを作る
また、ここでは実際のrateは0~5であるが、y_rangeを0~5.5としている、説明は後にする
今回はcollab_learnerを使いfitさせる

data = CollabDataBunch.from_df(ratings, seed=42)  
y_range = [0,5.5]  
learn = collab_learner(data, n_factors=50, y_range=y_range)  
learn.fit_one_cycle(3, 5e-3)  

協調フィルタの問題点

この映画の例でいうと、新しい映画のレビューができたときに、他に似たようなレビューが存在しないため、推薦することが難しいということがあげられる

そういう場合は協調フィルタリングを使ったモデルでないものを用意しておくとよい

ヒンディー語などを英語で書いたものや、絵文字の含まれる文を使うこともできるのか

絵文字などが使われる文章を訓練データに使っておけば問題ない

fastaiではRNNモデルをTabular dataで扱うことができるのか

できない
代わりに曜日や何月であるか週末であるか祝日であるかなどのデータを加えたりする

Excelで協調フィルタを行ってみよう

Excelファイルはhttps://github.com/fastai/course-v3/blob/master/files/xl/collab_filter.xlsx
このファイルはソルバーで最適化されたものです
適当に重みの部分の数字を変えてソルバーを動かしてみてください

上の表の行はユーザーID、列は映画のIDを表している
要は上のratingのuserID,movieID,rating,を表している


この表の左の5列と上の5行の数字は(はじめはランダム)重みである

表のセルはもしそのユーザーが映画に対するレビューを行っていた場合には赤枠と紫枠の行列の積、行っていない場合には0を表す

ここで得られた数字と実際の値を使ってLossを求めてみよう

ここではMean Squared Errorを求めてみよう

実際の評価は3、予測した値は3.25なので、計算してみると0.06が求められる

ソルバーを使って、MSEを求めることができる
変数セルに重みのセルを指定し、目的セルを黄色のセルを指定する
黄色のセルには数式を入れておく

=SQRT(SUMXMY2(H2:V16,H25:V39)/COUNT(H2:V16))

実行すると解が求まる

ノートブックに戻る

collab_learnerを見てみる

Fastaiの中身はPytorchで書かれている
Pytorchのモデルはnn.Moduleといわれる

モデルを作成するときにinitで色々定義する
forwardには実際にどのようにモデルを動かすかを描く

実際にコードを見てみると、モデルの勾配を計算していないが、それはPytorchがやってくれるからである、したがって、実際にするのはどのようにoutputを計算するかを書けばよい

ここでは、このモデルは
・ユーザーの重み
・アイテム(映画)の重み
・ユーザーのバイアス
・アイテム(映画)のバイアス
が含まれている

そして、これらの値はembeddingからきている

trunc_normal_はランダムに値を決めるということである

つまり、Embeddingというのは、Weight(重み)の行列のことである
基本的にEmbedding行列というのは重み行列のことで、行列としてあるものを番号付けするために設定し、1ベクトルを得るためのものである
今回の例では要は赤と紫のWeightをランダムに設定するということである

しかし、これだけでは不十分である
実際には特定の映画に対して皆がもっと好きかもしれないからである
例えばどれくらいその映画は人気があるとか、見た人が一般的にどれくらいの評価をつけるかなどを加えたい
これらの数値をバイアスという


再びコードを見に戻る
モデルを作り、Embeddingを準備したので、バイアスを準備する
そしてモデルを計算する
ここで行うことはdotを計算し、dotに2つのバイアスを加える

そして限りなく0に近い数から限りなくある正の数までの数を加える
その数を与える関数をシグモイドといい、ここでは5と0に漸近する

こうすることでdotがどんな形になっても0~5の範囲に収まるようになる

return torch.sigmoid(res) * (self.y_range[1]-self.y_range[0]) + self.y_range[0]  

最後に、torch.sigmoid(res)ではweightにバイアスを加えたresをシグモイドで計算しself.y_range[1]-self.y_range[0]をかけて、self.y_range[0]を加えることで、self.y_range[0]~self.y_range[1]の範囲に値を収めることができる

記事が少しでもいいなと思ったらクラップを送ってみよう!
0
+1
大学生の書きなぐりブログ 間違ってる事も書いてるので自己責任で勉強しましょう

よく一緒に読まれている記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう
目次をみる

技術ブログをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

技術ブログを開設する

Qrunchでアウトプットをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

Markdownで書ける

ログ機能でアウトプットを加速

デザインのカスタマイズが可能

技術ブログ開設

ここから先はアカウント(ブログ)開設が必要です

英数字4文字以上
.qrunch.io
英数字6文字以上
ログインする