/var/log/messages

Jul 28, 2018 - 3 minute read - Comments - Recommendation Python

映画の推薦システムを作る

以下な ipynb を確認しつつ控えを取ってみます。

ここ、7.4 をさらっている、という理解で良いのかな。

fastFMの動作確認

ここ、テキスト 131p のあたり。

  • DictVectorizer#fit_transform によって入力データの値が文字列になっている列をカテゴリカル変数にしている
  • ALS アルゴリズムで回帰する FM モデルを作って fit で学習
  • fit には入力データとそれに対応する評価値な配列を渡しています

この前処理を行なっておいて

  • {"user": "5", "item": "10", "age": 24} なデータをカテゴリカル変数にする
  • それを predict という手続きに渡して予測

という流れになっているようです。

データの探索的分析

このあたり、少々戻って 124p のあたりになっていますね。データを読み込んだ後、集計を行なっています。

movie_stats = lens.groupby('title').agg({'rating': [np.size, np.mean]})
movie_stats.sort_values(by=[('rating', 'mean')], ascending=False).head()
  • title 列で groupby して {'ratine': [np.size, np.mean]} な形式で aggregate したものが movie_stats に格納されてます
  • 平均値を sort key にして降順で sort しています

で、size が 100 以上のものがデータ的に妥当だろうということでさらに以下のフィルタをかけています。

atleast_100 = movie_stats['rating']['size'] >=100
movie_stats[atleast_100].sort_values(by=[('rating', 'mean')], ascending=False)[:15]

色々と便利ですね。

MovieLensデータの予測モデルの構築

この節は 132p あたり以降になるのかどうか。Factorization Machineを使った予測モデルの構築と、FMの特徴である、自由な特徴量の追加についての効果を確認 という記述があります。

データのロード

  • ua.base が開発データ、ua.test がテストデータ
  • タブ区切りで user, movieid, rating, ts の並びな行
  • data は {"user_id": str(user), "movie_id": str(movie)} な辞書の配列
  • y は rating を float にキャストした値が格納されている配列
  • users は user の値が格納されているセット
  • items は movieid の値が格納されているセット

ということで ua.base を渡した戻りは dev が付いた変数、ua.test を渡した戻りは test が付いた変数に格納されているようです。

あと、loadData の戻りがテキストと微妙に違いますね。最後のブロックが不慣れなので若干謎。

  • 開発データの data をカテゴリカル変数に変換して X_dev 格納
  • テストデータは transform して X_test 格納
  • テストデータの y の標準偏差を取得
  • 訓練データと評価値を取得

イテレーション回数の影響

もう少し。テキストによれば イテレーションの回数に対する平均二乗誤差と MCMC のハイパーパラメータ (alpha, lambda_w, mu_w) の推移を見て みるとのこと。

とりあえず、以下なあたり確認? なんですが

hyper_param = np.zeros((n_iter -1, 3 + 2 * rank), dtype=np.float64)

for nr, i in enumerate(range(1, n_iter)):
    fm.random_state = i * seed
    y_pred = fm.fit_predict(X_train, y_train, X_dev_test, n_more_iter=step_size)
    rmse_test.append(np.sqrt(mean_squared_error(y_pred, y_dev_test)))
    hyper_param[nr, :] = fm.hyper_param_

なんとなく時間切れになりそう。

  • np.zeros に渡す shape は二次元、ってことでいいのか。なので hyper_param は二次元配列?

別途

以下を確認してみようと思います。

pdb で云々しつつ、という形ですかね。。

トレーニング スマホ回線乗り換え検討

comments powered by Disqus