scikit-learn
前回、ワインの分類で、意外とpHが強い事に驚いた。元データはポルトガルで採取された ものだそうだけど、みんなそんなものなの?
The Importance of pH in Wine Making によると、そんなものらしい。化学実験器具の写真が出てたので、本当にそんなの使ってるのと 思って当たってみたら、 初めてのワイン分析なんてのが出てきた。わーい、化学実験室だ。楽しそう。
糖度とアルコール度、酸度とpHの話なんてのも有った。なる程ね。
>> r = dlmread ('red.csv', ';'); >> w = dlmread ('white.csv', ';'); >> statistics (r(:,9)) ans = 2.74000 3.21000 3.31000 3.40000 4.01000 3.31111 0.15439 0.19350 3.80067 >> statistics (w(:,9)) ans = 2.72000 3.09000 3.18000 3.28000 3.82000 3.18827 0.15100 0.45764 3.52901
赤ワインと白ワインのpHの統計情報を、octaveに調べてもらった。白ワインの方が微妙に pHが低いな。
histするとヒストグラムが出てくるんだけど、これのCUI版って無いのかしら? そんなの shell技で何とかするんだ!
sakae@debian:/tmp$ cut -f9 -d';' red.csv | cut -c-3 | sort | uniq -c 1 2.7 8 2.8 20 2.9 6 3 80 3.0 234 3.1 377 3.2 449 3.3 242 3.4 127 3.5 38 3.6 12 3.7 1 3.8 2 3.9 2 4.0 sakae@debian:/tmp$ cut -f9 -d';' white.csv | cut -c-3 | sort | uniq -c 6 2.7 64 2.8 367 2.9 74 3 803 3.0 1391 3.1 1093 3.2 664 3.3 280 3.4 106 3.5 33 3.6 13 3.7 4 3.8
小数点以下2桁目を切り捨ての強引さを発揮。ph 3 と、pH 3.0X の揺れが有るんで、ちょいと 汚い統計データになっちゃったけど、まあ、これがunix流の解決方法。
sakae@debian:/tmp$ cut -f12 -d';' red.csv | sort | uniq -c 10 3 53 4 681 5 638 6 199 7 18 8 sakae@debian:/tmp$ cut -f12 -d';' white.csv | sort | uniq -c 20 3 163 4 1457 5 2198 6 880 7 175 8 5 9
ついでに品質ランクの分布も見ておく。こういう風にランクと言うかクラスを上手に 学習するって、機械学習は苦手なの? 前回は余り良い結果が得られなかったけど。
scikit-learnに戻ってくる
という事で、svmにこだわる事なく、視野を広めてみるかな。
scikit-learn 0.18 チュートリアル 適切なモデルの選択
scikit-learn 0.18 チュートリアル scikit-learnによる機械学習の紹介
scikit-learn 0.18 User Guide 1.4 サポートベクターマシン
Scikit learnより グリッドサーチによるパラメータ最適化
scikit-leran on OpenBSD
この際だからLinuxのぬるま湯だけじゃなくて、BSD系にも入れてみよう。常用してるOpenBSDで やってみる。
scikit-learn 0.18.1を見ると、pipで入るよと書いてある。どのWebを検索しても同様。ならば、簡単々と思ってやって みたら、pipが途中でtimeoutしちゃう。時間を置いてからやってみても同様。 OpenBSDの秘密のセキュリティチェックに引っかかって、中止してくれたんですかね?
ならば、tar玉を落としてきてやってみれ。pipで玉を扱う方法を知らないので、取り合えず 展開して中を覗いてみたよ。Makefileが有ったんで、gmakeしたら、cythonが必要と抜かす。
pipでcythonを入れようとしたら、やっぱりtimeout。こうなるとOpenBSDの何処かがおかしいな。 先を急ぐので、tar玉から入れた。(結構時間がかかる)そして、scikitに戻ってgmakeしたら 無事にコンパイル出来た。続いてtestするように言われたけど、省略。
exampleが有ったので試してみると、scikitなんて入っていないと言われた。そうか、makeは コンパイルするだけなのねと合点承知の助。付近を見渡したら、python得意の setup.pyを発見。そうか、これを使えとな。
sudo python setup.py install
これで、再度cythonが長い時間をかけてコンパイル、そしてインストールが行われた。やれやれ ですよ。
examples/applications/svm_gui.py 面白いな。マウスの左か右ボタンをキャンバス上で 適当にクリックして点を置く。それから、3種の方法で評価をする。適当にやってみたら
bash-4.3# python svm_gui.py ========== Libsvm GUI ========== A simple graphical frontend for Libsvm mainly intended for didactic purposes. You can create data points by point and click and visualize the decision region induced by different kernels and parameter settings. To create positive examples click the left mouse button; to create negative examples click the right button. If all examples are from the same class, it uses a one-class SVM. fit the model (Linear) Accuracy: 61.5384615385 fit the model (RBF) Accuracy: 92.3076923077 fit the model (Poly) Accuracy: 73.0769230769
同じデータでも、評価方法によって随分と差が出るものだな。
こうして、軽く動くのを確認。以前のやつを引っ張り出して、自分の土俵で動かしてみようと したら、pandasが入ってなかったので、手動で入れた。 numpyのconfigを確認しとく
In [2]: numpy.show_config() openblas_info: NOT AVAILABLE blas_info: library_dirs = ['/usr/local/lib'] libraries = ['blas'] language = f77 atlas_threads_info: NOT AVAILABLE lapack_opt_info: library_dirs = ['/usr/local/lib'] libraries = ['lapack', 'blas'] define_macros = [('NO_ATLAS_INFO', 1)] language = f77 lapack_info: library_dirs = ['/usr/local/lib'] libraries = ['lapack'] language = f77
基本的なもので、出来上がっていた。intelさんにOpenBSDの支援を乞う。
import pandas as pd from sklearn.neural_network import MLPClassifier from sklearn import svm from sklearn import preprocessing def get_wine(file): a = pd.read_csv(file, delimiter=';') return a.iloc[:,:-1], a.iloc[:,-1] def main(): min_max_scaler = preprocessing.MinMaxScaler() X, Y = get_wine('red.csv') clf = svm.SVC(gamma=8, C=2) # clf = MLPClassifier(solver="sgd",random_state=0,max_iter=10000) clf.fit(min_max_scaler.fit_transform(X), Y) U, V = get_wine('red.csv') pred = clf.predict(min_max_scaler.fit_transform(U)) print (clf.score(min_max_scaler.fit_transform(U), V)) if __name__ == "__main__": main()
In [11]: run -t wine.py 0.73153942428 IPython CPU timings (estimated): User : 0.34 s. System : 0.25 s. Wall time: 0.59 s. In [12]: run -t wine.py 0.57634543179 IPython CPU timings (estimated): User : 1.12 s. System : 10.70 s. Wall time: 11.81 s.
svmとDNNの対決。これを見ると、svmは速い上手いという結論だな。
scikit-learnで糖尿病データの回帰分析をやってみた
sakae@debian:~/ML/sci$ ipython --matplotlib In [2]: import pandas as pd In [3]: import seaborn as sns In [4]: a = pd.read_csv('red.csv', delimiter=';') In [5]: a.iloc[1,:] Out[5]: fixed acidity 7.8000 volatile acidity 0.8800 citric acid 0.0000 residual sugar 2.6000 chlorides 0.0980 free sulfur dioxide 25.0000 total sulfur dioxide 67.0000 density 0.9968 pH 3.2000 sulphates 0.6800 alcohol 9.8000 quality 5.0000 Name: 1, dtype: float64 In [6]: sns.jointplot(x='quality', y='pH', data=a) Out[6]: <seaborn.axisgrid.JointGrid at 0x7efc9fb642b0>
Seaborn: statistical data visualization
簡単に美しいグラフ描画ができるPythonライブラリSeaborn入門
grid-search
scikit-learn上でsvmを使うとなると(深層学習は火力が必要なので敬遠)やはり、パラメータ のチューニングをしたい。そんなの簡単、例が出てた。
Parameter estimation using grid search with cross-validation
それをアレンジするよ。下記は変更部分。フィーチャデータの全てで、一番大きいの、小さいのを 見つけてスケーリングしてたのを改め、列毎にスケーリングするようにしておいた。
import pandas as pd from sklearn import preprocessing def get_wine(file): a = pd.read_csv(file, delimiter=';') return a.iloc[:,:-1], a.iloc[:,-1] X, y = get_wine('white.csv') X_scaled = preprocessing.scale(X) # Split the dataset in two equal parts X_train, X_test, y_train, y_test = train_test_split( X_scaled, y, test_size=0.5, random_state=0) # Set the parameters by cross-validation tuned_parameters = [{'kernel': ['rbf'], 'gamma': [100,10,1,0.1,0.01], 'C': [1, 10, 100, 1000]}, ] :
与えたファイルを半分に分け、一方をトレーニングに使用。最適なパラメータを見つけ出す。 もう半分のデータで実地試験と言う流れ。
# Tuning hyper-parameters for precision {'kernel': 'rbf', 'C': 10, 'gamma': 10} Detailed classification report: precision recall f1-score support 3 0.00 0.00 0.00 10 4 1.00 0.08 0.15 88 5 0.96 0.23 0.37 733 6 0.50 0.99 0.66 1070 7 1.00 0.25 0.40 461 8 1.00 0.26 0.41 86 9 0.00 0.00 0.00 1 avg / total 0.77 0.56 0.50 2449 # Tuning hyper-parameters for recall {'kernel': 'rbf', 'C': 100, 'gamma': 0.1} Detailed classification report: precision recall f1-score support 3 0.00 0.00 0.00 10 4 0.18 0.18 0.18 88 5 0.61 0.59 0.60 733 6 0.58 0.68 0.63 1070 7 0.57 0.44 0.50 461 8 0.52 0.29 0.37 86 9 0.00 0.00 0.00 1 avg / total 0.57 0.57 0.57 2449
precisionとrecallのどちらを優先させるかで、パラメータは変わってくるとな。 このprecisionとかの説明は、 適合率 precision 再現率 recall に有った。機械学習に限らず、ググル様とかも大事にする指標だな。
なお、表の左列の数字は、教師データの番号、一番右側のsupport列は、その個数。 資料が少ないと的中率も落ちるのね。
そこで、頻出するクラスを削ってみた。
sakae@debian:~/ML/sci$ egrep -v '(5|6)$' white.csv > z.csv sakae@debian:~/ML/sci$ wc z.csv 1244 1252 67289 z.csv
# Tuning hyper-parameters for recall {'C': 100, 'gamma': 0.01, 'kernel': 'rbf'} precision recall f1-score support 3 0.00 0.00 0.00 6 4 0.78 0.67 0.72 86 7 0.79 0.97 0.87 437 8 0.40 0.02 0.04 91 9 0.00 0.00 0.00 2 avg / total 0.72 0.77 0.72 622
今度は、2つだけのクラス分類
# Tuning hyper-parameters for recall {'C': 10, 'gamma': 0.1, 'kernel': 'rbf'} precision recall f1-score support 5 0.64 0.63 0.64 708 6 0.77 0.78 0.77 1119 avg / total 0.72 0.72 0.72 1827
やはり、教師データが多い方が正確な予想が出来るって結論になるかな。
etc
filetype:pdf site:.ac.jp を加えて、ぐぐると良質な資料が得られるとな。