【R】recosystemでレコメンデーション

1. はじめに

まだ、よくわかってないのですが、推薦システム(のベース)をRでやってみることに。これを実現するパッケージはすでに多くあるようなのですが、今回は、Yu-Chin Juan, Wei-Sheng Chin, Yong Zhuang, Bo-Wen Yuan, Meng-Yuan Yang, and Chih-Jen LinによるLIMBFライブラリーのWrapperであるrecosystemというパッケージを使ってみます。

LIMBFは、C++でかかれた高パフォーマンスのライブラリーで並列処理により効率よく大規模データを処理できます。また、CPUのみならずGPUにも対応しています。

推薦システムは、ECサイトなどで関連商品をレコメンドするものです。何らかのユーザー行動やアイテム情報などから、ユーザーが関心がありそうなアイテムを提示することが目的です。ユーザーが大量の商品から好みの商品を見つけやすくしたり、自分でも気づかなかった意外な商品を気に入るなどの意外性もあったりします。

2. インストール

CRANからインストールします。

install.packages("recosystem")

3. つかってみる

サンプルにあるデータを使ってみます。まずは、データの読み込み。

library(recosystem)
set.seed(123) # This is a randomized algorithm
train_set = data_file(system.file("dat", "smalltrain.txt", package = "recosystem"))
test_set  = data_file(system.file("dat", "smalltest.txt",  package = "recosystem"))

Reco()関数により、オブジェクトを作ります。

r = Reco()

$tuneメソッドにより最適なパラメータを選択します。

opts = r$tune(train_set, opts = list(dim = c(10, 20, 30), lrate = c(0.1, 0.2),
                                     costp_l1 = 0, costq_l1 = 0,
                                     nthread = 1, niter = 10))
opts
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
> opts
$min
$min$dim
[1] 10

$min$costp_l1
[1] 0

$min$costp_l2
[1] 0.1

$min$costq_l1
[1] 0

$min$costq_l2
[1] 0.1

$min$lrate
[1] 0.1

$min$loss_fun
[1] 0.9743264


$res
   dim costp_l1 costp_l2 costq_l1 costq_l2 lrate  loss_fun
1   10        0     0.01        0     0.01   0.1 1.0158789
2   20        0     0.01        0     0.01   0.1 0.9981966
3   30        0     0.01        0     0.01   0.1 0.9991761
4   10        0     0.10        0     0.01   0.1 1.0056670
5   20        0     0.10        0     0.01   0.1 0.9851703
6   30        0     0.10        0     0.01   0.1 0.9838365
7   10        0     0.01        0     0.10   0.1 0.9908790
8   20        0     0.01        0     0.10   0.1 0.9978197
9   30        0     0.01        0     0.10   0.1 0.9831165
10  10        0     0.10        0     0.10   0.1 0.9743264
11  20        0     0.10        0     0.10   0.1 0.9878893
12  30        0     0.10        0     0.10   0.1 0.9887035
13  10        0     0.01        0     0.01   0.2 1.0945747
14  20        0     0.01        0     0.01   0.2 1.0289115
15  30        0     0.01        0     0.01   0.2 1.0166264
16  10        0     0.10        0     0.01   0.2 1.0657177
17  20        0     0.10        0     0.01   0.2 1.0316208
18  30        0     0.10        0     0.01   0.2 1.0082243
19  10        0     0.01        0     0.10   0.2 1.0782190
20  20        0     0.01        0     0.10   0.2 1.0268844
21  30        0     0.01        0     0.10   0.2 1.0054406
22  10        0     0.10        0     0.10   0.2 1.0599895
23  20        0     0.10        0     0.10   0.2 1.0323456
24  30        0     0.10        0     0.10   0.2 1.0064500

$tuneの結果得られたパラメータを使って、$trainにより学習します。

r$train(train_set, opts = c(opts$min, nthread = 1, niter = 20))
> r$train(train_set, opts = c(opts$min, nthread = 1, niter = 20))
iter      tr_rmse          obj
   0       2.1027   4.8998e+04
   1       0.9744   1.5287e+04
   2       0.8348   1.2881e+04
   3       0.8047   1.2434e+04
   4       0.7883   1.2222e+04
   5       0.7736   1.2030e+04
   6       0.7592   1.1861e+04
   7       0.7431   1.1673e+04
   8       0.7263   1.1504e+04
   9       0.7073   1.1305e+04
  10       0.6891   1.1140e+04
  11       0.6692   1.0943e+04
  12       0.6519   1.0786e+04
  13       0.6362   1.0654e+04
  14       0.6214   1.0531e+04
  15       0.6081   1.0420e+04
  16       0.5967   1.0334e+04
  17       0.5855   1.0241e+04
  18       0.5761   1.0168e+04
  19       0.5682   1.0117e+04

次にモデルで予測してみます。ファイルに保存する場合には、以下のようにします。

pred_file = tempfile()
r$predict(test_set, out_file(pred_file))

print(scan(pred_file, n = 10))

メモリ上で行うには、次のようにします。

pred_rvec = r$predict(test_set, out_memory())
head(pred_rvec, 10)
> head(pred_rvec, 10)
 [1] 3.851235 3.435712 2.890148 3.185432 2.307347 3.497945 2.890176 3.001640 1.998869
[10] 3.327145

モデルの性能を学習データを使ってみてみます。

library(caret)
pred_rvec = r$predict(train_set, out_memory())
dat <- read.csv("smalltrain.txt", sep=" ", header = FALSE)

MAE(round(pred_rvec,0), dat[,3])
RMSE(round(pred_rvec,0), dat[,3])
R2(round(pred_rvec,0), dat[,3], form = "traditional")
> MAE(round(pred_rvec,0), dat[,3])
[1] 0.3471
> RMSE(round(pred_rvec,0), dat[,3])
[1] 0.5990826
> R2(round(pred_rvec,0), dat[,3], form = "traditional")
[1] 0.4890019

どうなんでしょう?あまりよくないような。。。

4. さいごに

まだまだよくわからないので、これから勉強します。

Add a Comment

メールアドレスが公開されることはありません。