今回は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件のコメント