Pythonのscikit-learnでRandomForest vs SVMを比較してみた
- メディア: ペーパーバック
- クリック: 27回
- この商品を含むブログ (1件) を見る
Random Forest
Random Forestとは
機械学習の方法論の一つで決定木ベースの集団学習アルゴリズムを取り入れたものです。説明変数の依存が少ないことや学習が高速であることが特徴として挙げられています。英語サイトの方で特徴として紹介されているRFの内容について記述します。
Features
- 大きなデータに対して効率よく処理される。
- 変数の削除をすることなく入力した数千の変数を扱う事ができる。
- どの変数が分類に対して重要なのかを計算して与えてくれる。
- 木の構築処理中に一般的なエラーの偏りの無い計算を生成する。
- 高い割合でデータが誤っている時に誤りのデータを計算し、精度を保つ効果的な手法を持っている。
- アンバランスなデータが与えられたクラス群の中でエラーのバランスに対する手法を持っている。
- 生成された木は今後他のデータに適用させるために保存する事ができる。
- 変数とクラスタリング間の関係性に関する情報を計算する。
- クラスタリングに利用される隣接するケースを計算する。
- 上の特性はラベリングやクラスタリングされていないデータやはずれ値に対しても拡張する事ができる。
- 変数の相互作用を発見するための実験的な方法を推薦する。
Remarks
- RFではoverfitは存在しない。
- RFは複数の木として処理できるし、それは処理速度が速い。
- 5万のデータと100の変数を持ったデータに対して、100個の木に割り当て、800Mhzのマシンで11分で処理が終わる。
- RFではCross-Validationをする必要がない。out-of-bag (oob) エラー計算がその代わりとなる。
Mac × Pythonで利用する
env
pythonは2.7を利用します。元々設定されていたPythonは2.6.7だったのですが、install時に色々と問題がでてきたので2.7に変えます。複数のPythonを使い分けるにはpython_selectというコマンドがあったのですが、現在は使えなくなっているようです。その代わりにport select --setで切り替えます。
$ sudo port select --set python python27 $ python -V Python 2.7.2Package
MacOSX 10.6.8とPythonでRandomForestを利用するには以下のパッケージが必要になります。
※scikit-learnにはRandomForest以外のアルゴリズムも含まれているので、その他の機械学習ツールを使いたい場合も以下を参考にすると設定できると思います。
- Scientific Computing Tools For Python ― Numpy
- 数学関数を提供。Matlabのような機能を備えている。
- SciPy -
- Numpyを基礎にした統計的な関数を提供。
- scikit-learn: machine learning in Python ― scikit-learn 0.12.1 documentation
設定手順
※easy_installで上のpackageをinstallを試みましたが、scipyのinstallで失敗します。UMFPACKというパッケージが存在しないことが原因のようですが、直接的な解決方法が分かりませんでした。もし直接的な解決方法をご存知の方いましたら教えていただけると助かります。
$ sudo easy_install-2.7 scipy Searching for scipy Reading http://pypi.python.org/simple/scipy/ Reading http://www.scipy.org Download error: [Errno 61] Connection refused -- Some packages may not be found! Reading http://sourceforge.net/project/showfiles.php?group_id=27747&package_id=19531 Reading http://new.scipy.org/Wiki/Download Best match: scipy 0.11.0 Downloading http://pypi.python.org/packages/source/s/scipy/scipy-0.11.0.zip#md5=40b700ddde9ddab643b640fff7a9d753 Processing scipy-0.11.0.zip Running scipy-0.11.0/setup.py -q bdist_egg --dist-dir /tmp/easy_install-7aUbZx/scipy-0.11.0/egg-dist-tmp-phUwYf Running from scipy source directory. /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/numpy-1.6.2-py2.7-macosx-10.6-x86_64.egg/numpy/distutils/system_info.py:470: UserWarning: UMFPACK sparse solver (http://www.cise.ufl.edu/research/sparse/umfpack/) not found. Directories to search for the libraries can be specified in the numpy/distutils/site.cfg file (section [umfpack]) or by setting the UMFPACK environment variable. warnings.warn(self.notfounderror.__doc__) error: None間接的な解決方法として、ぐぐってみたら以下のようなサイトを見つけました。ScipySuperpackというものを利用してnumpy,matplotlib,scipyをinstallします。
ScipySuperpackのinstall.shを実行します。実行時に質問を聞かれますが、nで答えます。
$ curl -o install_superpack.sh "https://raw.github.com/fonnesbeck/ScipySuperpack/master/install_superpack.sh" $ sh install_superpack.sh Are you installing from a repository cloned to this machine (if unsure, answer no)? (y/n) n Cloning Scipy Superpack Cloning into ScipySuperpack... remote: Counting objects: 452, done. remote: Compressing objects: 100% (226/226), done. remote: Total 452 (delta 240), reused 433 (delta 221) Receiving objects: 100% (452/452), 332.41 MiB | 1.11 MiB/s, done. Resolving deltas: 100% (240/240), done. (略) Reading http://pypi.python.org/simple/patsy/ Reading https://github.com/pydata/patsy Best match: patsy 0.1.0 Downloading http://pypi.python.org/packages/source/p/patsy/patsy-0.1.0.zip#md5=4be1210fb5050fb83b6859fe7706b339 Processing patsy-0.1.0.zip Running patsy-0.1.0/setup.py -q bdist_egg --dist-dir /tmp/easy_install-u6TbHU/patsy-0.1.0/egg-dist-tmp-CXu4_o no previously-included directories found matching 'doc/_build' zip_safe flag not set; analyzing archive contents... Adding patsy 0.1.0 to easy-install.pth file Installed /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/patsy-0.1.0-py2.7.egg Cleaning up DoneRandomForestの実行
RFの実行にlibsvmのサンプルデータでもあるirisを使います。LIBSVM Data: Classification, Regression, and Multi-label データに付けられたlabelとfeatureをそれぞれPythonのRandomForestClassifierに渡せるように分解し、学習データと評価データを用意します。irisは150個のサンプルデータなので75個ずつに振り分けられます。学習データをfitさせ、評価データでpredictさせます。実行してみた結果としては71/75を正確にpredictできていたので、Accuracyは94.6%でした。処理時間は0.36s user 0.17s system 99% cpu 0.536 totalと出ました。以下はテスト用のコードです。
$ wget http://www.csie.ntu.edu.tw/~cjlin/libsvmtools/datasets/multiclass/iris.scale $ time python rf.py predict ok id = 0 predict ok id = 1 predict ok id = 2 predict ok id = 3 predict ok id = 4 predict ok id = 5 predict ok id = 6 predict ok id = 7 predict ok id = 8 predict ok id = 9 predict ok id = 10 predict ok id = 11 predict ok id = 12 (略) predict miss id = 60 predict miss id = 61 predict ok id = 62 predict miss id = 63 predict ok id = 64 (略) python rf.py 0.36s user 0.17s system 99% cpu 0.536 total#!/usr/bin/env python # -*- coding: utf-8 -*- import re from sklearn.ensemble import RandomForestClassifier training_label = [] training_data = [] predict_label = [] predict_data = [] num = 0 file = open( './iris.scale' , 'r' ) for line in file : line = line.rstrip() node = [] label = re.search( r'^(.*?)\s', line ).group(1) for i in range(1,5) : try : pattern = r'%s' % ( str( i ) + ':(.*?\s)' ) match = re.search( pattern, line ).group(1) if match is None : node.append(0) else: node.append(match) except AttributeError : node.append(0) continue if num % 2 == 0 : training_data.append( node ) training_label.append( label ) else : predict_data.append( node ) predict_label.append( label ) num = num + 1 predict_data = training_data model = RandomForestClassifier() model.fit(training_data, training_label) output = model.predict(predict_data) for i in range( 0,len( output ) ) : str = "ok" if( int( predict_label[i] ) == int( output[i] ) ) else "miss" print "predict %s id = %d" % ( str, i )SVMの実行
同じ要領でSVMも実行してみました。kernelは線形を利用しています。結果としては68 / 75が正確にpredictされていてAccuracyは90.6%でした。処理時間は0.38s user 0.20s system 97% cpu 0.599 totalとなりました。以下にPythonのテストコードを載せます。
$ time python svm.py predict ok id = 0 predict ok id = 1 predict ok id = 2 predict ok id = 3 predict ok id = 4 predict ok id = 5 predict ok id = 6 predict ok id = 7 predict ok id = 8 predict ok id = 9 predict ok id = 10 predict ok id = 11 predict ok id = 12 (略) predict ok id = 37 predict miss id = 38 predict ok id = 39 predict ok id = 40 predict miss id = 41 predict ok id = 42 (略) python svm.py 0.38s user 0.20s system 97% cpu 0.599 total#!/usr/bin/env python # -*- coding: utf-8 -*- import re,numpy as np from sklearn import svm training_label = [] training_data = [] predict_label = [] predict_data = [] num = 0 file = open( './iris.scale' , 'r' ) for line in file : line = line.rstrip() node = [] label = re.search( r'^(.*?)\s', line ).group(1) for i in range(1,5) : try : pattern = r'%s' % ( str( i ) + ':(.*?\s)' ) match = re.search( pattern, line ).group(1) if match is None : node.append(0) else: node.append( float( match ) ) except AttributeError : node.append(0) continue if num % 2 == 0 : training_data.append( node ) training_label.append( label ) else : predict_data.append( node ) predict_label.append( label ) num = num + 1 model = svm.libsvm.fit( np.array( training_data ), np.float64( np.array( training_label ) ), kernel='linear' ) output = svm.libsvm.predict( np.array( predict_data ), *model, **{'kernel' : 'linear'} ) for i in range( 0, len(output) ) : str = "ok" if( int( predict_label[i] ) == int( output[i] ) ) else "miss" print "predict %s id = %d" % ( str, i )
比較のまとめ
- irisのデータに関してはRandomForestの方がAccuraryが良い結果が出た。
- 75件の学習/評価データに対する処理速度は若干ながらRandomForestの方が速い事が分かった。