Regurarized Greedy Forest

最近、決定木ベースの手法ではxgboost が主流となってきています。実際、xgboost やrandomForest は手軽に結構良い精度が出るので、まずはじめに試すとしたらこのあたりの手法かなと思います。
 Regurarized Greedy Forest (以下、RGF と略す)は、C++ で書かれていることとトレーニングに時間がかかるため、あまり普及はしていないように感じます。ただ精度に関してはxgboost より良いことも多い印象があります。
Regularized greedy forest (RGF) in C++
こちらからダウンロードすることができます。RGF の使い方やアルゴリズムについては付属のpdf に詳しく書かれています。アルゴリズムについては時間があるときに追記しようと思います。

  • コンペでの使用状況
  • metric とloss の目安
  • 使用上の注意点
  • パラメータ
  • python のwrapper
  • R のwrapper

コンペでの使用状況

  • 実際に、kaggle のコンペでもときどき使用されていて、2 値分類ではWest Nile Virus Prediction のコンペで2 位の方がRGF を用いていました。

GitHub - diefimov/west_nile_virus_2015: the 2nd place solution for West Nile Virus Prediction challenge on Kaggle

  • またHiggsBoson のコンペの2位の方も使用されていました。

GitHub - TimSalimans/HiggsML: My second place solution to the Higgs Boson Machine Learning Challenge

  • 多クラス分類でも使用されている方がいました。otto のコンペで、商品を9 つのクラスに分類する問題で、stacked generalization の1st level に使用されていました。コードも公開されていますので、参考になると思います。

otto_2015/model.rgf.stack.R at master · diefimov/otto_2015 · GitHub

metric とloss の目安
以後、RGFの使い方を中心に見ていきます。まず評価関数に対してどのようにfit させるかについてです。
rgf のloss はLog, LS, Exp の3つから選択することになりますが、毎回3 つとも試すのは面倒なので第一候補の目安としては、経験的に次の表のように選べばよさそうです。

metirc loss
logloss LS (or Log)
auc Log(or LS)
rmse LS

使用上の注意点:
クラス分類では、そのクラスに属するかどうかが +1 と-1 で表現されています。(ただし、wrapper を使う分には気にしなくてもOK。)
perl を使うため事前にインストールする必要があります。

パラメータ
reg_L2: 正則化パラメータ
1, 0.1, 0.01 を基本的に試す。
loss: 損失関数(LS, Log, Expo)
LS: square loss, (p-y)^2/2;
Expo: exponential loss, exp(-py);
Log: logistic loss, log(1 + exp(-py));

test_interval: 100
test_interval ごとにモデルをセーブします
max_leaf_forest: 500
葉の数がmax_leaf_forest に到達するまで実行します。
Verbose: 進捗

実装関連
train_x_fn: 訓練データのデータ点
train_y_fn: 訓練データのラベル
test_x_fn: 検証用データのデータ点
model_fn: 予測に用いるモデルのファイル
prediction_fn: 予測したデータを格納するファイル名
SaveLastModelOnly: 最後に実行したモデルだけがセーブされる
model_fn_for_warmstart: 指定したファイルから訓練の続きを行える。(early stopping の実装などに使える)

python のwrapper
python では、便利なwrapper が以下の2 つあります。
GitHub - MLWave/RGF-sklearn: Scikit-learn API toy wrapper for Regularized Greedy Forests

GitHub - fukatani/rgf_python: Python Wrapper of Regularized Greedy Forest.
です。後者の方を試してみます。

git clone https://github.com/fukatani/rgf_python.git 
python setup.py install

なのですが、自分の環境では失敗したため、rgf.py をそのまま読み込むことにしました。実行する前にrgf.py の

loc_exec = 'C:\\Users\\rf\\Documents\\python\\rgf1.2\\bin\\rgf.exe'
loc_temp = 'temp/'

この部分を修正する必要があります。

from sklearn import datasets
from sklearn.utils.validation import check_random_state
from sklearn.cross_validation import StratifiedKFold
from rgf import RGFClassifier

iris = datasets.load_iris()
rng = check_random_state(0)
perm = rng.permutation(iris.target.size)
iris.data = iris.data[perm]
iris.target = iris.target[perm]

rgf = RGFClassifier(max_leaf=400,
                    algorithm="RGF_Sib",
                    test_interval=100,)

# cross validation
rgf_score = 0
n_folds = 3

for train_idx, test_idx in StratifiedKFold(iris.target, n_folds):
    xs_train = iris.data[train_idx]
    y_train = iris.target[train_idx]
    xs_test = iris.data[test_idx]
    y_test = iris.target[test_idx]
    rgf.fit(xs_train, y_train)
    rgf_score += rgf.score(xs_test, y_test)

rgf_score /= n_folds
print('score: {0}'.format(rgf_score))
# score: 0.959967320261

となって動作していることが確認できます。こちらでは、多クラス分類にも対応しています。(original は2値分類のみ。)

R のwrapper
R でのwrapper はまだ見られない感じで、とりあえず自分のを貼っておきます。
GitHub - puyokw/RGF-R: R wrapper for Regularized Greedy Forest
これをrgf-src.R として使用しています。
path にはrgf1.2 があるディレクトリを指すようにしてください。今のところ、2値分類でMetircs がlogloss の場合のみになっています。(夏休みにもう少し更新していきたいと思っています。auc とrmse(regression) と多クラス分類への対応)
たとえばnumerai のデータを用いてみます。feature はfeature1 からfeature21 まででmetrics はlogloss の2 値分類となっています。

path <- 'C:/Users/KawaseYoshiaki/Desktop/tmp/'
source(paste0(path,'rgf-src.R'))
train <- read_csv(paste0(path,"numerai_training_data.csv"))
test <- read_csv(paste0(path,"numerai_tournament_data.csv"))
testId <- test$t_id
target <- train$target
test$t_id <- NULL 
train$target <- NULL

(tmp <- RGFCV(train,target,nround=500,lambda=1,nfold=5) )# 200, 0.6916646 

pred <- RGF(train,test,target,nround=tmp$bestNum*100,lambda=1)
submission <- data.frame(t_id=testId, probability=pred$prediction)
write_csv(submission,paste0(path,'rgf.csv'))

f:id:puyokw:20160717202732p:plain
検証の間隔が100 ごとになっているため、今のところbestNum の値が1/100 で出力しているため、pred のときのnround は100 倍しています。

時間があるときにまた追記していきたいと思っています。

winpython でdeeplearning !

最近deeplearning が流行っていてwindows 上で環境構築しようとされている方がいるのではということで、winpython を使ってお手軽に環境構築することを今回のテーマとしてみました。
WinPython で以下の3つのライブラリをGPU で実行できるようにするのが目的です。
1. keras
2. lasagne (noleran はpython2 系のみ)
3. mxnet (cpu only)

結果としては、keras とlasagne は動きましたが、mxnet はcpu のみしかできませんでした。

まずWinPython をダウンロードします。
winpython.github.io
自分の場合、WinPython の2.7.10 と3.4.4 は既に入れていましたので、ここでは3.4.4 で説明します。
C ドライブ直下にインストールしてみます。環境変数の設定は、

C:\WinPython-64bit-3.4.4.2\python-3.4.4.amd64;C:\WinPython-64bit-3.4.4.2\python-3.4.4.amd64\Scripts

の2つを追加します。(しなくてもOK。その場合python の起動はC:\WinPython-64bit-3.4.4.2\python-3.4.4.amd64\python.exe を自分で実行することになります。)

WinPython ではkeras とlasagne が入っていますので、バージョンを更新してからサンプルプログラムを動かしてみます。
まずgit power shell で

git clone https://github.com/Theano/Theano.git 
git clone https://github.com/fchollet/keras.git 
git clone https://github.com/Lasagne/Lasagne.git 

として、次にコマンドプロンプトで(path を通していない場合winpython command prompt から)

(適宜 pip uninstall theano などしてから)
python setup.py install

を各々のディレクトリで実行して最新版にします。

この段階ではCPU モードでの実行となります(WinPython2.7.10.3ではkeras やtheano はgithub からダウンロードして動いたが、3.4.4.2では動かず)。たとえば
keras/examples at master · fchollet/keras · GitHub
にあるmnist_mlp.py などが試せます。

C:\WinPython-64bit-2.7.10.3\python-2.7.10.amd64\keras\examples>python mnist_cnn.py
X_train shape: (60000L, 1L, 28L, 28L)
60000 train samples
10000 test samples
Train on 60000 samples, validate on 10000 samples
Epoch 1/12
  128/60000 [..............................] - ETA: 1142s - loss: 2.3501 - acc: 0.1016  
  256/60000 [..............................] - ETA: 1141s - loss: 2.4655 - acc: 0.1719  
  384/60000 [..............................] - ETA: 1139s - loss: 2.3930 - acc: 0.1797  
  512/60000 [..............................] - ETA: 1138s - loss: 2.2773 - acc: 0.2168  
  640/60000 [..............................] - ETA: 1134s - loss: 2.1294 - acc: 0.2687  
  768/60000 [..............................] - ETA: 1137s - loss: 2.0266 - acc: 0.3047  
  896/60000 [..............................] - ETA: 1134s - loss: 1.9686 - acc: 0.3147 
  1024/60000 [..............................] - ETA: 1133s - loss: 1.9176 - acc: 0.3359 
  1152/60000 [..............................] - ETA: 1132s - loss: 1.8382 - acc: 0.3715 
  1280/60000 [..............................] - ETA: 1134s - loss: 1.7686 - acc: 0.3937

このようにmnist_cnn.py をcpu で実行する(実行環境: keras 0.2.0, theano 0.7.0)と、非常に時間がかかります。

GPU

次にGPU モードの使い方です。

CUDA
まずCUDA をダウンロードします。
CUDA 7.5 Downloads | NVIDIA Developer
そして、インストールします。上手くインストールされてパスが通っていれば、コンソールで

> nvcc --version

nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2015 NVIDIA Corporation
Built on Tue_Aug_11_14:49:10_CDT_2015
Cuda compilation tools, release 7.5, V7.5.17

cuda のバージョンが表示されることで確認できます。

cuDNN
cuDNN は主にConvolutional Neural Networks を高速化できるのですが、こちらは開発者登録をすることでダウンロードできます。
NVIDIA cuDNN | NVIDIA Developer
こちらもコマンドプロンプトで(path を通していない場合はWinPythonCommandPromptを用いてください)

python -c "from theano.sandbox.cuda.dnn import dnn_available as d; print(d() or d.msg)"

とするとTrueと表示されることで確認できます。
.theanorc (theanorc.txt もたぶんOK)というファイルを作成します。内容は次のようにします。

[global]
floatX = float32
device = gpu0
[nvcc]
fastmath = True

これを

C:\WinPython-64bit-3.4.4.2\settings 

のフォルダ下に置きます。そして

#!/usr/bin/env python
from theano import function, config, shared, sandbox
import theano.tensor as T
import numpy
import time

vlen = 10 * 30 * 768  # 10 x #cores x # threads per core
iters = 1000

rng = numpy.random.RandomState(22)
x = shared(numpy.asarray(rng.rand(vlen), config.floatX))
f = function([], T.exp(x))
print(f.maker.fgraph.toposort())
t0 = time.time()
for i in range(iters):
    r = f()
t1 = time.time()
print('Looping %d times took' % iters, t1 - t0, 'seconds')
print('Result is', r)
if numpy.any([isinstance(x.op, T.Elemwise) for x in f.maker.fgraph.toposort()]):
    print('Used the cpu')
else:
    print('Used the gpu')

をtheanotest.py として実行します。うまく設定できていれば、"Used the gpu" と表示されます。

keras
keras/mnist_mlp.py at master · fchollet/keras · GitHub
にあるものを動かしてみます。多層パーセプトロン:

C:\WinPython-64bit-3.4.4.2\notebooks>python mnist_mlp.py
Using Theano backend.
DEBUG: nvcc STDOUT mod.cu
   Creating library C:/Users/UserName/AppData/Local/Theano/compiledir_Windows-10-10.0.14361-Intel64_Family_6_Model_60_Stepping_3_GenuineIntel-3.4.4-64/tmp4y9he2sa/m91973e5c136ea49268a916ff971b7377.lib and object C:/Users/UserName/AppData/Local/Theano/compiledir_Windows-10-10.0.14361-Intel64_Family_6_Model_60_Stepping_3_GenuineIntel-3.4.4-64/tmp4y9he2sa/m91973e5c136ea49268a916ff971b7377.exp

Using gpu device 0: GeForce GTX 970M (CNMeM is disabled, cuDNN 4007)
60000 train samples
10000 test samples
____________________________________________________________________________________________________
Layer (type)                     Output Shape          Param #     Connected to     
====================================================================================================
dense_1 (Dense)                  (None, 512)           401920      dense_input_1[0][0]
____________________________________________________________________________________________________
activation_1 (Activation)        (None, 512)           0           dense_1[0][0]    
____________________________________________________________________________________________________
dropout_1 (Dropout)              (None, 512)           0           activation_1[0][0]
____________________________________________________________________________________________________
dense_2 (Dense)                  (None, 512)           262656      dropout_1[0][0]  
____________________________________________________________________________________________________
activation_2 (Activation)        (None, 512)           0           dense_2[0][0]    
____________________________________________________________________________________________________
dropout_2 (Dropout)              (None, 512)           0           activation_2[0][0]
____________________________________________________________________________________________________
dense_3 (Dense)                  (None, 10)            5130        dropout_2[0][0]  
____________________________________________________________________________________________________
activation_3 (Activation)        (None, 10)            0           dense_3[0][0]    
====================================================================================================
Total params: 669706
____________________________________________________________________________________________________
Train on 60000 samples, validate on 10000 samples
Epoch 1/20
  128/60000 [..............................] - ETA: 11s - loss: 2.2559 - acc: 0.1016  256/60000 [..............................] - ETA: 8s - loss: 2.1970 - acc: 0.1445 60000/60000 [==============================] - 6s - loss: 0.2476 - acc: 0.9243 - val_loss: 0.1038 - val_acc: 0.9686
Epoch 2/20
  128/60000 [..............................] - ETA: 10s - loss: 0.0986 - acc: 0.9531  256/60000 [..............................] - ETA: 8s - loss: 0.0763 - acc: 0.9688 60000/60000 [==============================] - 6s - loss: 0.1038 - acc: 0.9682 - val_loss: 0.0869 - val_acc: 0.9733
Epoch 3/20
  128/60000 [..............................] - ETA: 10s - loss: 0.0519 - acc: 0.9844  256/60000 [..............................] - ETA: 8s - loss: 0.0469 - acc: 0.9844 60000/60000 [==============================] - 6s - loss: 0.0756 - acc: 0.9771 - val_loss: 0.0639 - val_acc: 0.9820
Epoch 4/20
  128/60000 [..............................] - ETA: 10s - loss: 0.0236 - acc: 0.9922  256/60000 [..............................] - ETA: 8s - loss: 0.0490 - acc: 0.9805  5376/60000 [=>............................] - ETA: 5s - loss: 0.0528 - acc: 0.9833

(略)

Epoch 18/20
  128/60000 [..............................] - ETA: 10s - loss: 0.0029 - acc: 1.0000  256/60000 [..............................] - ETA: 8s - loss: 0.0100 - acc: 0.9961 60000/60000 [==============================] - 6s - loss: 0.0187 - acc: 0.9952 - val_loss: 0.1021 - val_acc: 0.9825
Epoch 19/20
  128/60000 [..............................] - ETA: 10s - loss: 8.3644e-04 - acc: 1.  256/60000 [..............................] - ETA: 8s - loss: 5.5119e-04 - acc: 1.0  384/60000 [..............................] - ETA: 7s - loss: 0.0016 - acc: 1.0000 60000/60000 [==============================] - 6s - loss: 0.0173 - acc: 0.9955 - val_loss: 0.0990 - val_acc: 0.9843
Epoch 20/20
  128/60000 [..............................] - ETA: 10s - loss: 4.2615e-04 - acc: 1.  256/60000 [..............................] - ETA: 8s - loss: 0.0024 - acc: 1.0000 60000/60000 [==============================] - 6s - loss: 0.0172 - acc: 0.9956 - val_loss: 0.1186 - val_acc: 0.9836
Test score: 0.118557494809
Test accuracy: 0.9836

畳み込みニューラルネット
keras/mnist_cnn.py at master · fchollet/keras · GitHub
を試します。

C:\WinPython-64bit-3.4.4.2\notebooks>python mnist_cnn.py
Using Theano backend.
DEBUG: nvcc STDOUT mod.cu
   Creating library C:/Users/UserName/AppData/Local/Theano/compiledir_Windows-10-10.0.14361-Intel64_Family_6_Model_60_Stepping_3_GenuineIntel-3.4.4-64/tmpit9hpb56/m91973e5c136ea49268a916ff971b7377.lib and object C:/Users/UserName/AppData/Local/Theano/compiledir_Windows-10-10.0.14361-Intel64_Family_6_Model_60_Stepping_3_GenuineIntel-3.4.4-64/tmpit9hpb56/m91973e5c136ea49268a916ff971b7377.exp

Using gpu device 0: GeForce GTX 970M (CNMeM is disabled, cuDNN 4007)
X_train shape: (60000, 1, 28, 28)
60000 train samples
10000 test samples
DEBUG: nvcc STDOUT mod.cu
   Creating library C:/Users/UserName/AppData/Local/Theano/compiledir_Windows-10-10.0.14361-Intel64_Family_6_Model_60_Stepping_3_GenuineIntel-3.4.4-64/tmpcw4rv5wn/m9d548c8287cab38fe1bee8a07f1ae00e.lib and object C:/Users/UserName/AppData/Local/Theano/compiledir_Windows-10-10.0.14361-Intel64_Family_6_Model_60_Stepping_3_GenuineIntel-3.4.4-64/tmpcw4rv5wn/m9d548c8287cab38fe1bee8a07f1ae00e.exp

Train on 60000 samples, validate on 10000 samples
Epoch 1/12
60000/60000 [==============================] - 27s - loss: 0.3826 - acc: 0.8826 - val_loss: 0.1019 - val_acc: 0.9681
Epoch 2/12
60000/60000 [==============================] - 27s - loss: 0.1513 - acc: 0.9556 - val_loss: 0.0675 - val_acc: 0.9785
Epoch 3/12
60000/60000 [==============================] - 27s - loss: 0.1161 - acc: 0.9655 - val_loss: 0.0551 - val_acc: 0.9821
Epoch 4/12
60000/60000 [==============================] - 31s - loss: 0.0984 - acc: 0.9711 - val_loss: 0.0479 - val_acc: 0.9845
Epoch 5/12
60000/60000 [==============================] - 28s - loss: 0.0856 - acc: 0.9752 - val_loss: 0.0455 - val_acc: 0.9850
Epoch 6/12
60000/60000 [==============================] - 30s - loss: 0.0768 - acc: 0.9768 - val_loss: 0.0428 - val_acc: 0.9860
Epoch 7/12
60000/60000 [==============================] - 27s - loss: 0.0667 - acc: 0.9804 - val_loss: 0.0370 - val_acc: 0.9875
Epoch 8/12
60000/60000 [==============================] - 27s - loss: 0.0613 - acc: 0.9819 - val_loss: 0.0357 - val_acc: 0.9884
Epoch 9/12
60000/60000 [==============================] - 28s - loss: 0.0571 - acc: 0.9826 - val_loss: 0.0342 - val_acc: 0.9885
Epoch 10/12
60000/60000 [==============================] - 27s - loss: 0.0545 - acc: 0.9835 - val_loss: 0.0313 - val_acc: 0.9887
Epoch 11/12
60000/60000 [==============================] - 27s - loss: 0.0500 - acc: 0.9849 - val_loss: 0.0325 - val_acc: 0.9881
Epoch 12/12
60000/60000 [==============================] - 27s - loss: 0.0475 - acc: 0.9857 - val_loss: 0.0301 - val_acc: 0.9896
Test score: 0.0301319627388
Test accuracy: 0.9896

lasagne
Lasagne/mnist.py at master · Lasagne/Lasagne · GitHub
を試してみます。

C:\WinPython-64bit-3.4.4.2\notebooks>python mnist.py
DEBUG: nvcc STDOUT mod.cu
   Creating library C:/Users/UserName/AppData/Local/Theano/compiledir_Windows-10-10.0.14361-Intel64_Family_6_Model_60_Stepping_3_GenuineIntel-3.4.4-64/tmp_83wnuzp/m91973e5c136ea49268a916ff971b7377.lib and object C:/Users/UserName/AppData/Local/Theano/compiledir_Windows-10-10.0.14361-Intel64_Family_6_Model_60_Stepping_3_GenuineIntel-3.4.4-64/tmp_83wnuzp/m91973e5c136ea49268a916ff971b7377.exp

Using gpu device 0: GeForce GTX 970M (CNMeM is disabled, cuDNN 4007)
C:\WinPython-64bit-3.4.4.2\python-3.4.4.amd64\lib\site-packages\theano\tensor\signal\downsample.py:6: UserWarning: downsample module has been moved to the theano.tensor.signal.pool module.
  "downsample module has been moved to the theano.tensor.signal.pool module.")
Loading data...
Downloading train-images-idx3-ubyte.gz
Downloading train-labels-idx1-ubyte.gz
Downloading t10k-images-idx3-ubyte.gz
Downloading t10k-labels-idx1-ubyte.gz
Building model and compiling functions...
DEBUG: nvcc STDOUT mod.cu
   Creating library C:/Users/UserName/AppData/Local/Theano/compiledir_Windows-10-10.0.14361-Intel64_Family_6_Model_60_Stepping_3_GenuineIntel-3.4.4-64/tmpwbmnaj3z/m348562874e1ce2ba0b15dfc91612074f.lib and object C:/Users/UserName/AppData/Local/Theano/compiledir_Windows-10-10.0.14361-Intel64_Family_6_Model_60_Stepping_3_GenuineIntel-3.4.4-64/tmpwbmnaj3z/m348562874e1ce2ba0b15dfc91612074f.exp

Starting training...
Epoch 1 of 500 took 2.847s
  training loss:                1.220125
  validation loss:              0.408603
  validation accuracy:          88.50 %
Epoch 2 of 500 took 2.411s
  training loss:                0.565184
  validation loss:              0.304734
  validation accuracy:          91.23 %
Epoch 3 of 500 took 2.378s
  training loss:                0.466600
  validation loss:              0.264648
  validation accuracy:          92.24 %
Epoch 4 of 500 took 2.358s
  training loss:                0.413189
  validation loss:              0.236005
  validation accuracy:          93.04 %
Epoch 5 of 500 took 2.362s
  training loss:                0.374851
  validation loss:              0.214491
  validation accuracy:          93.75 %

(略)

Epoch 498 of 500 took 2.326s
  training loss:                0.018706
  validation loss:              0.056610
  validation accuracy:          98.68 %
Epoch 499 of 500 took 2.323s
  training loss:                0.017923
  validation loss:              0.057117
  validation accuracy:          98.66 %
Epoch 500 of 500 took 2.325s
  training loss:                0.017687
  validation loss:              0.057260
  validation accuracy:          98.67 %
Final results:
  test loss:                    0.047488
  test accuracy:                98.74 %

mxnet
こちらから
https://github.com/dmlc/mxnet/releases
自分の欲しいバージョンのmxnet をダウンロードします。
ここでは、20160531_win10_x64_gpu.7z にしました。これを解凍して、
/3rdparty/cudnn 下にcudnn と対応するフォルダに必要なファイルを入れます。setupenv.cmd をダブルクリックして実行します。次に

cd python
python setup.py install

を実行します。すると

>>> import mxnet as mx
>>> a=mx.nd.zeros((2,3))
>>> print(a.asnumpy())
  [[0. 0. 0.]
   [0. 0. 0.]]

のように実行できます。しかしGPU モードがうまく起動しませんでした。


参考文献
keras:
Keras Documentation
GitHub - fchollet/keras: Deep Learning library for Python. Convnets, recurrent neural networks, and more. Runs on Theano and TensorFlow.

lasagne:
Welcome to Lasagne — Lasagne 0.2.dev1 documentation
GitHub - Lasagne/Lasagne: Lightweight library to build and train neural networks in Theano

mxnet:
MXNet Documents
GitHub - dmlc/mxnet: Lightweight, Portable, Flexible Distributed/Mobile Deep Learning with Dynamic, Mutation-aware Dataflow Dep Scheduler; for Python, R, Julia, Scala, Go, Javascript and more

カテゴリー変数に embedding layer を用いたNeural Net

kaggle のRossmann の3 位のNeokami Inc(entron)さんの用いた手法が面白かったので、その概要の紹介などをしていきたいと思います。
まず手法の名前は、"Entity Embeddings of Categorical Variables" で、
[1604.06737] Entity Embeddings of Categorical Variables
論文にもなっています。コードはGithub にありますので、興味のある方はご覧ください。
github.com
(これはPython3 を用いて書かれています。)

embedding layer を用いた他のコンペでの有力なsolution。
kaggle のtaxi コンペ: Taxi Trajectory Winners’ Interview: 1st place, Team ? | No Free Hunch
Netflix: Deep learning solution for netflix prize | karthkk

Rossmann のコンペでは、いくつかの日に対して各店舗の売上の予測を行っています。
今回は"Entity Embeddings of Categorical Variables"の手法について見ていきます。まずカテゴリ変数の扱いはたいてい、1つの変数ですべて整数に置き換えて表現、あるいはone-hot encoding のようにダミー変数で boolean 型で表現するだと思いますが、この手法を用いることで、カテゴリー変数の近さ(類似度)を図示できるというのが面白いところです。たとえば、曜日については
f:id:puyokw:20160521214850p:plain
のように図示されます。これを見ると平日と休日で売り上げの傾向が異なるというのが分かります。同様に、店舗ごとや月ごとのデータもプロットできます。(上記のgithub に記載されています)
f:id:puyokw:20160521215346p:plain

カテゴリー変数を上手く扱いたいときあるいは、NN でカテゴリー変数が多いときに試してみたいなと思っています。
やり方としましては、NeuralNet でembedding layer を用いて学習し、そのモデルを用いてt-sne で次元を落として視覚化しています。
コードの方は、

models = []
# 曜日 7 -> 7 x 6 -> 6 
model_dow = Sequential()
model_dow.add(Embedding(7, 6, input_length=1))
model_dow.add(Reshape(dims=(6,)))
models.append(model_dow)

# 月 12 -> 12 x 6 -> 6 
model_month = Sequential()
        model_month.add(Embedding(12, 6, input_length=1))
        model_month.add(Reshape(dims=(6,)))
        models.append(model_month)
# 他も同様
# 上で定義したモデルを結合する
self.model = Sequential()
self.model.add(Merge(models, mode='concat'))
# 以下はいつも通り
self.model.add(Dropout(0.02))
self.model.add(Dense(1000, init='uniform'))
self.model.add(Activation('relu'))
self.model.add(Dense(500, init='uniform'))
self.model.add(Activation('relu'))
self.model.add(Dense(1))
self.model.add(Activation('sigmoid'))
self.model.compile(loss='mean_absolute_error', optimizer='adam')

で、イメージとしては
f:id:puyokw:20160523013817p:plain
となります。
次に、始めに図示していたplot のやり方についてです。これは上図の7 x 6 や12 x 6 となっている部分を視覚化のためにどちらも 6 -> 2 次元(3次元でもOK)へとt-sne で次元を落とします。すなわち、それぞれ 7 x 2 と 12 x 2 となります。

import pickle
from sklearn import manifold
import matplotlib.pyplot as plt
import numpy as np

# 作成したNN のmodel を読み込む
with open("models.pickle", 'rb') as f:
    models = pickle.load(f)

# entity embedding layer の重みをそれぞれ分かりやすい名前を付ける
model = models[0].model
weights = model.layers[0].get_weights()
store_embedding = weights[0]
dow_embedding = weights[1]
year_embedding = weights[4]
month_embedding = weights[5]
day_embedding = weights[6]
german_states_embedding = weights[20]
woy_embedding = weights[21]
weather_event_embedding = weights[30]

# entity embedding layer の重みに対してt-sne を適用する
# 曜日
tsne = manifold.TSNE(init='pca', random_state=0, method='exact')
Y = tsne.fit_transform(dow_embedding)
names = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat','Sun']
# plot する
plt.figure(figsize=(8,8))
plt.scatter(-Y[:, 0], -Y[:, 1])
for i, txt in enumerate(names):
    plt.annotate(txt, (-Y[i, 0],-Y[i, 1]))

plt.savefig('dow_embedding.png')

# 月
tsne = manifold.TSNE(init='pca', random_state=0, method='exact')
Y = tsne.fit_transform(month_embedding)
names = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
plt.figure(figsize=(8,8))
plt.scatter(-Y[:, 0], -Y[:, 1])
for i, txt in enumerate(names):
    plt.annotate(txt, (-Y[i, 0],-Y[i, 1]))

plt.savefig('month_embedding.png')

などで行えます。距離はt-sne 空間での距離となっています。
他のコンペで実際に試してみたいなと思っています。