Juliaによる予測モデル構築・評価
-
Upload
sfchaos -
Category
Data & Analytics
-
view
835 -
download
4
Transcript of Juliaによる予測モデル構築・評価
Juliaによる 予測モデル構築・評価
2015年4月25日 第3回JuliaTokyo
@sfchaos
自己紹介• TwitterID: @sfchaos
• お仕事: データマイニング
• 使用言語: R/Python/Perl/C++/etc.
アジェンダ1. Juliaの機械学習ライブラリ
2. 予測モデル構築・評価の考え方
3. Juliaを用いた予測モデル構築・評価
4. MLBaseパッケージを用いた実行方法
5. まとめ
1. Juliaの機械学習 ライブラリ
Juliaの機械学習パッケージ• Juliaで機械学習を実行するためのパッケージは以下のページにまとまっている.
Awesome Machine Learning https://github.com/josephmisiti/awesome-machine-learning#julia
Juliaの機械学習パッケージ• 先のページの和訳
アルゴリズム パッケージ確率的グラフィカルモデル PGM.jl正則化判別分析 DA.jl回帰分析 Regression.jl局所回帰分析 Loess.jlナイーブベイズ NaiveBayes.jl混合モデル MixedModels.jlマルコフ連鎖モンテカルロ法 SimpleMCMC.jl
MCMC.jl
距離(Maharanobis距離等) Distance.jl決定木,バギング,ランダムフォレスト DecisionTree.jlニューラルネットワーク BackPropNeuralNet.jl
サポートベクタマシン SVM.jlLIBSVM.jl
••• •••
2. 予測モデル構築・ 評価の考え方
予測モデル
目的変数 説明変数
xy)(xfy =
予測モデル f
説明変数 x から目的変数 y を予測する
結果 原因
未知のデータに対する高い予測力と安定性(汎化性能)
が求められる
目的変数 y 予測の例回帰 連続値 売上予測,電力量予測, etc.クラス分類 離散値 退会者予測,故障予測, etc.
特徴量作成
(feature engineering/construction)
• 予測モデル構築における最重要項目
データ
目的変数 説明変数
機械学習の文脈では特徴量,属性(feature)と呼ばれることが多い
xy
モデル評価のスキーム (ホールドアウト検定)
データ
訓練データ
検証データ
モデル構築
予測モデル
モデル検証
検証結果
モデルを評価するフェーズ
データを訓練用と検証用に分けて予測精度を検証
モデルを構築するフェーズ
モデル構築・評価のスキーム (リサンプリング/クロスバリデーション・ブートストラップ)
• 複数セットの訓練・検証データに対して予測モデルを構築し評価
データ
訓練データ
検証データ
モデル構築予測モデル
モデル検証
検証結果
訓練データ
検証データ
モデル構築予測モデル
モデル検証
検証結果
・・・
訓練データと検証データを複数セット作成
検証結果の統合
モデルの評価• クラス分類では,検証データに対してROC曲線や分割表による評価を行うことが多い.
実績
正例 負例
予測正例 TP FP
負例 FN TN
適合率(Precision) = TP/(TP + FP)再現率(Recall) = TP/(TP +FN)正解率(Accuracy) = (TP + TN)/(TP + FP + FN + TN)特異度(Specificity) = TN/(TN + FP), etc.
3. Juliaを用いた予測モデルの構築・評価
使用するデータ• Bank Marketingデータセットを使用. • ポルトガルの銀行で電話による顧客へのダイレクトマーケティング
UCI Machine Learning Repository http://archive.ics.uci.edu/ml/datasets/Bank+Marketing
"age";"job";"marital";"education";"default";"balance";"housing";"loan";"contact";"day";"month";"duration";"campaign";"pdays";"previous";"poutcome";"y" 58;"management";"married";"tertiary";"no";2143;"yes";"no";"unknown";5;"may";261;1;-1;0;"unknown";"no" 44;"technician";"single";"secondary";"no";29;"yes";"no";"unknown";5;"may";151;1;-1;0;"unknown"
データの読み込み• DataFramesパッケージのreadtable関数を使用
Pkg.add(“DataFrames”) using DataFrames # データの読み込み bank = readtable("data/bank-full.csv", separator=‘;’) # 目的変数の変換(yes: 1.0, no: -1.0) bank[:y] = [bank[i, :y] == "yes" ? 1.0 : -1.0 for i in 1:nrow(bank)]
数値の特徴量の正規化• 数値の特徴量は,スケールが同じになるように正規化
# カテゴリ変数の特徴量の変数名 cname_ctg = [:job, :marital, :education, :default, :housing, :loan, :contact, :month, :poutcome] # 数値の特徴量の変数名 cname_num = setdiff(names(bank), [cname_ctg, :y]) # 数値の特徴量の正規化 for cn in cname_num bank[cn] = (bank[:, cn] - mean(bank[cn]))/std(bank[cn]) end
カテゴリ変数のダミー変数への変換
function getdummy{R}(df::DataFrame, cname::Symbol, ::Type{R}) darr = df[cname] vals = sort(levels(darr))[2:end] namedict = Dict(vals, 1:length(vals)) arr = zeros(R, length(darr), length(namedict)) for i=1:length(darr) if haskey(namedict, darr[i]) arr[i, namedict[darr[i]]] = 1 end end newdf = convert(DataFrame, arr) names!(newdf, [symbol("$(cname)_$k") for k in vals]) return newdf end
• Julia Usersに掲載されている方法に従って変換 ※ “DataFrames: convert categorical variables to dummy ones?”https://groups.google.com/forum/#!topic/julia-users/7-Vtpi8w4YI
カテゴリ変数のダミー変数への変換
function convertdummy{R}(df::DataFrame, names::Array{Symbol}, ::Type{R}) # consider every variable from cnames as categorical # and convert them into set of dummy variables, # return new dataframe newdf = DataFrame() for cname in names(df) if !in(cname, cnames) newdf[cname] = df[cname] else dummydf = getdummy(df, cname, R) for dummyname in names(dummydf) newdf[dummyname] = dummydf[dummyname] end end end return newdf end convertdummy(df::DataFrame, cnames::Array{Symbol}) = convertdummy(df, cnames, Int32)
• Julia Usersに掲載されている方法に従って変換 ※ “DataFrames: convert categorical variables to dummy ones?”https://groups.google.com/forum/#!topic/julia-users/7-Vtpi8w4YI
サポートベクタマシンの実行• SVMパッケージのsvm関数でPegasosアルゴリズムを実行.
julia> # ダミー変数に変換 julia> bank_dum = convertdummy(bank_scaled[:, 1:16], cname_ctg) julia> # 説明変数と目的変数の作成 julia> X = array(bank_dum[, 1:42]) julia> Y = array(bank_dum[:, 43]) julia> # SVMの実行 julia> Pkg.add(“SVM”) julia> using SVM julia> model_svm = svm(X, Y) Fitted linear SVM * Non-zero weights: 45211 * Iterations: 100 * Converged: true
ランダムフォレストの実行• build_forest関数でモデルを構築. • apply_forest関数で予測.julia> using DataFrames julia> Pkg.add("DecisionTree") julia> using DecisionTree julia> # 訓練データ,テストデータの作成 julia> bank = readtable("data/bank-full.csv", separator=';') julia> is_train = randbool(nrow(bank)) julia> X_tr, X_te = array(bank[is_train, 1:16]), array(bank[!is_train, 1:16]) julia> Y_tr, Y_te = array(bank[is_train, 17]), array(bank[!is_train, 17]) julia> # モデル構築 julia> model_rf = build_forest(Y_tr, X_tr, 10, 500, 0.7) Ensemble of Decision Trees Trees: 500 Avg Leaves: 1038.174 Avg Depth: 26.596 julia> # 予測 julia> pred = apply_forest(model_rf, X_te) julia> # 分割表 julia> confusion_matrix(pred, Y_te) Classes: {"no","yes"} Matrix: 2x2 Array{Int64,2}: 19419 1489 645 1154
Accuracy: 0.9060201699916325 Kappa: 0.4695774877297327
ランダムフォレストの実行• nfold_CV関数を用いるとクロスバリデーションを実行.
julia> # 10-foldクロスバリデーションの実行(特徴量の個数:4, 木の個数:100, fold数:10, 訓練データの割合:70%) julia> accuracy = nfoldCV_forest(Y, X, 10, 100, 10, 0.7)
DecisionTreeパッケージにはnfold_CV関数が 用意されていたため容易にクロスバリデーションを実行できた.
その他のアルゴリズムでも簡単にできないか?
4. MLBaseパッケージを用いた実行方法
MLBaseパッケージとは• クロスバリデーション,ハイパーパラメータのグリッドサーチなどの処理の統一的なフレームワークを提供.
MLBaseパッケージとは• クロスバリデーション: cross_validate関数
• グリッドサーチ:gridtune関数
• 予測モデルを構築する関数,評価する関数を定義する.
データの読み込み• データの読み込みまでは同じ
using DataFrames # データの読み込み bank = readtable("data/bank-full.csv", separator=';') # 説明変数・目的変数への分割 X = array(bank[:, 1:16]) Y = array(bank[:, 17])
予測モデル構築の関数の定義• 関数内部で,予測モデル構築に用いる関数を実行
using DecisionTree using MLBase srand(123) # 予測モデルを構築する関数 function trainfun(inds) # ランダムフォレストによる予測モデルの構築(特徴量の個数:10, 木の個数:500, 訓練に用いるデータの割合:70%) model = build_forest(Y[inds, 1], X[inds, :], 4, 500, 0.7) return model end
予測モデルを評価する関数の定義• テストデータの予測と実績を比較して,評価指標を算出.
# 予測モデルを評価する関数 function evalfun(model, inds) # 予測 pred = apply_forest(model, X[inds, :]) # 分割表 conf_mat = confusion_matrix(Y[inds, 1], pred).matrix # Precisionの算出 prec = conf_mat[1, 1]/sum(conf_mat[:, 1]) return prec end
クロスバリデーション• cross_validate関数を用いて実行.
# サンプル数 const n = size(X, 1)
# クロスバリデーションの実行 scores = cross_validate( inds -> trainfun(inds), (model, inds) -> evalfun(model, setdiff(1:n, inds)), n, Kfold(n, 10))
予測モデルの構築 (訓練)
評価
ハイパーパラメータのグリッドサーチ• gridtune関数を用いて実行.using MLBase srand(123)
# 予測モデルを構築する関数 function estfun(ntree, nfeature) # 予測モデルの構築(訓練データの割合:70%) model = build_forest(Y, X, nfeature, ntree, 0.7) return model end
# 予測精度を評価する関数 function evalfun(model) # テストデータに対する予測 pred = apply_forest(model, X) # 分割表 conf_mat = confusion_matrix(Y[:, 1], pred[:, 1]).matrix # 評価指標(Precision)の算出 prec = conf_mat[2, 2]/sum(conf_mat[:, 2]) return prec end
# グリッドサーチによるハイパーパラメータの評価(木の個数:{50, 100, 500}, 特徴量の個数:{5, 10, 15}) r = gridtune(estfun, evalfun, ("ntree", [50, 100, 500]), ("nfeature", [5, 10, 15]); verbose=true)
gridtune関数により実行
ハイパーパラメータサーチ+クロスバリデーション
• モデルを評価する関数の中で,クロスバリデーションを実行.
srand(123)
# クロスバリデーションにより予測モデルを評価する関数 function estfun(ntree, nfeature) # クロスバリデーションの実行 scores = cross_validate( inds -> trainfun(inds), (model, inds) -> evalfun(model, inds), n, kfold ) # 評価指標(Precision)の算出 prec = conf_mat[2, 2]/sum(conf_mat[:, 2]) return prec end
# グリッドサーチによるハイパーパラメータの評価(木の個数:{50, 100, 500}, 特徴量の個数:{5, 10, 15}) r = gridtune(estfun, evalfun, ("ntree", [50, 100, 500]), ("nfeature", [5, 10, 15]); verbose=true)
モデルを評価関数の中でcross_validate関数を
実行
5. まとめ
まとめ• Juliaで機械学習を実行するパッケージは. そこそこ揃ってきてはいる.
• MLBaseは,クロスバリデーションやハイパーパラメータのグリッドサーチを統一的なフレームワークで実行.
• Rのcaret/mlrやPythonに比べると,細かい条件や出力の指定ができないなど,まだまだ発展途上.
参考文献• @chezou, Juliaを使った機械学習 http://www.slideshare.net/chezou/hajipata-julia
• @yutajuly, Juliaでスパム判定の機械学習分類器を作るhttp://yutajuly.hatenablog.com/entry/2014/12/17/033243
• @yutajuly, RとPythonとJuliaで機械学習レベル4を目指すhttps://speakerdeck.com/yutajuly/rtopythontojuliateji-jie-xue-xi-reheru4womu-zhi-su