データ分析初心者の備忘録

不定期で更新していきます。

scikit-learnで使える機械学習手法まとめ


機械学習ライブラリscikit-learnを活用して実行できるアルゴリズムの特徴と実行方法、実行結果をまとめました。 アルゴリズムの実行にはUIC Machine Learning Repositoryに登録されているBreast Cancer Wisconsinデータセットを用いています。 なお、理論の説明というよりは使用する際の注意点や実行方法をメインに記載しています。

目次

  • 使用するデータセットの確認
  • パーセプトロン
  • ロジスティック回帰
  • SVM (サポートベクトルマシン)
  • 決定木
  • ランダムフォレスト
  • k近傍分類器(KNN: k-nearest neighbor classifier)

使用するデータセットの確認

UIC Machine Learning Repositoryに登録されているBreast Cancer Wisconsinデータセットを用います。 データセットの1列目はユニークIDで、2列目がクラスラベル(M、Bの2値)です。

import pandas as pd
import urllib

#データセットの読み込み
#breast cancer wisconsin dataset
df = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases'
                     '/breast-cancer-wisconsin/wdbc.data', header=None)

print('rows, columns:', df.shape)
df.head()

f:id:kuze3110:20171015234448p:plain

なお、決定境界を可視化したい都合上、特徴量を2つに絞って学習に使います。

#使用する特徴量2個に絞った上でデータの確認
X = df.loc[:,[4,14]]
X.head()

データの確認のため、MとBのラベルごとにデータをプロットします。

%matplotlib inline
import matplotlib.pyplot as plt

X1 = df[df[1] == 'M'] #クラスラベルがMのデータを抽出
X1.head()
X1_array = X1.loc[:,[4,14]].values

X0 = df[df[1] == 'B'] #クラスラベルがBのデータを抽出
X0.head()
X0_array = X0.loc[:,[4,14]].values

plt.scatter(X1_array[:,0], X1_array[:,1], c = 'blue', marker = "x") #Mは青色で☓のマーカー
plt.scatter(X0_array[:,0], X0_array[:,1], c = 'red', marker = "s") #Bは赤色で■のマーカー

plt.title("scatterplot")
plt.xlabel("feature1")
plt.ylabel("feature2")
plt.show()

f:id:kuze3110:20171015234852p:plain

使用するデータセットをトレーニングデータとテストデータに分割

データセットを8:2の比率で分け、それぞれトレーニングデータ、テストデータとします。

from sklearn.cross_validation import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.20, random_state = 1)

データの標準化

from sklearn.preprocessing import StandardScaler

sc = StandardScaler()
sc.fit(X_train)
X_train_std = sc.transform(X_train)
X_test_std = sc.transform(X_test)

パーセプトロン

線形識別関数を用いたネットワークモデル。  完全な線形分離が不可能なデータセットでは収束しないため、一般に実務のデータ解析で使われることは少ない。

実行例

from sklearn.linear_model import Perceptron

#エポック数40, 学習率0.1でパーセプトロンのインスタンスを生成
ppn = Perceptron(n_iter=40, eta0=0.1, random_state=0)
#トレーニングデータをモデルに適合させる
ppn.fit(X_train_std, y_train)

#テストデータで予測を実施
y_pred = ppn.predict(X_test_std)
#誤分類のサンプルの個数を表示
print('Misclassified samples: %d' % (y_test != y_pred).sum())
#Misclassified samples: 12

from sklearn.metrics import accuracy_score
#分類の正解率を表示
print('Accuracy: %.2f' % accuracy_score(y_test, y_pred))
#Accuracy: 0.89

f:id:kuze3110:20171015235528p:plain

コード中に出てくる「正解率」の定義は「1-誤分類率」。 不均衡データの場合はモデルの精度が悪くても正解率の値が高くなりがちなので注意が必要。

ロジスティック回帰

「回帰」という名前だが、回帰ではなく分類のためのモデルであり、 線形分離と二値分類に関して、パーセプトロンより優れた分類モデル。

実行例

from sklearn.linear_model import LogisticRegression
#ロジスティック回帰のインスタンスを生成
lr = LogisticRegression(C=1000.0, random_state=0)
#トレーニングデータをモデルに適合させる
lr.fit(X_train_std, y_train)

#サンプルの所属確率を予測
y_pred = lr.predict(X_test_std)
print('Misclassified samples: %d' % (y_test != y_pred).sum())
#Misclassified samples: 12

#正解率
print('Accuracy: %.2f' % accuracy_score(y_test, y_pred))
#Accuracy: 0.89

f:id:kuze3110:20171028164940p:plain

SVM (サポートベクトルマシン)

パーセプトロンの拡張と見なせる。 マージン(クラスを分離する境界線である「超平面」とこの超平面に最も近いトレーニングサンプルとの距離)を最大化させることが目的。 マージンの小さいモデルは過学習に陥りがち。 γパラメータの値を小さくするとトレーニングサンプルの影響力が大きくなり、到達範囲が大きくなることで決定境界がなめらかになる。

《利点》 カーネルトリックを使って非線形問題の解を求めることが可能である。 ロジスティック回帰よりも外れ値の影響を受けにくい。

《欠点》 予測を適切に行うために調節しなければならないパラメータの数が多い。

《補足》
バイアスとバリアンス
バリアンスが高い→過学習が発生しているモデル
バイアスが高い→学習不足になっているモデル

正則化
共線性(特徴量の間の相関の高さ)を処理する手法で、データからノイズを取り除き最終的に過学習を防ぐ
一般的にL2正則化が使われる
なお、正則化を正常に機能させるためには標準化が必要

実行例 (線形SVM)

from sklearn.svm import SVC
#線形SVMのインスタンスを生成
svm = SVC(kernel='linear', C=1.0, random_state=0)
#線形SVMのモデルにトレーニングデータを適合させる
svm.fit(X_train_std, y_train)

#予測
y_pred = svm.predict(X_test_std)
print('Misclassified samples: %d' % (y_test != y_pred).sum())
print('Accuracy: %.2f' % accuracy_score(y_test, y_pred))

#Misclassified samples: 12
#Accuracy: 0.89

f:id:kuze3110:20171028170704p:plain

実行例 (カーネルSVM)

#RBFカーネルによるSVMのインスタンスを生成
svm = SVC(kernel='rbf', random_state=0, gamma=0.2, C=1.0)
svm.fit(X_train_std, y_train)

#予測
y_pred = svm.predict(X_test_std)
print('Misclassified samples: %d' % (y_test != y_pred).sum())
print('Accuracy: %.2f' % accuracy_score(y_test, y_pred))

#Misclassified samples: 13
#Accuracy: 0.89

f:id:kuze3110:20171028170953p:plain

決定木

情報利得(information gain)が最大となるような特徴量でデータを分割する。
特徴量の標準化はしなくてもサンプルの分割に影響しないため、可視化する目的でない場合は標準化しなくても良い。
(決定木では数値の分割条件を値の大小関係として捉えるため、標準化が影響しない)

《補足》
情報利得
「親ノードの不純度」と「子ノードの不純度」の差
子ノードの不純度が低いほど、情報利得は大きくなる

不純度
ノードが純粋ではない程度、すなわちノードに異なるクラスのサンプルがどの程度の割合で混ざっているか定量化する指標
よく使用される不純度の指標としてジニ不純度エントロピー分類誤差がある
ジニ不純度とエントロピーは非常によく似た結果になることが多い

実行例

from sklearn.tree import DecisionTreeClassifier
#エントロピーを指標とする決定木のインスタンスを生成
tree = DecisionTreeClassifier(criterion='entropy', max_depth=3, random_state=0)
#決定木のモデルにトレーニングデータを適合させる
#決定木は特徴量のスケーリングが不要なため、X_train_stdでなくX_trainを使用
tree.fit(X_train, y_train)

X_combined = np.vstack((X_train, X_test))
y_combined = np.hstack((y_train, y_test))

#予測
y_pred = tree.predict(X_test)
print('Misclassified samples: %d' % (y_test != y_pred).sum())
print('Accuracy: %.2f' % accuracy_score(y_test, y_pred))

#Misclassified samples: 15
#Accuracy: 0.87

f:id:kuze3110:20171028171125p:plain

ランダムフォレスト

決定木のアンサンブルである。
個々の決定木をトレーニングする際、全ての特徴量を評価するのではなくその一部をランダムに比較検討するだけ。

《利点》
分類性能が高い
パラメータの調整がそれほど必要でない
決定木ほど過学習に陥りやすくない ハイパーパラメータに適切な値を設定することについては「決定木」に比べてあまり悩む必要はなく、実際に検討が必要なパラメータは選択する決定木の個数(k)だけ

《補足》
アンサンブル
弱い学習アルゴリズムを組み合わせて強い学習アルゴリズムを構築するというもの

強い学習アルゴリズム
汎化誤差が改善され、過学習に陥りにくい

実行例

from sklearn.ensemble import RandomForestClassifier
#エントロピーを指標とするランダムフォレストのインスタンスを生成
forest = RandomForestClassifier(criterion='entropy', #criterionで指標を指定
                                n_estimators=10,  #n_estimatorsで木の数を指定
                                random_state=1,
                                n_jobs=2) #n_jobsパラメータはPCの複数のコアを使うことを指定している

#決定木同様、ランダムフォレストは特徴量のスケーリングが不要なため、X_train_stdでなくX_trainを使用
forest.fit(X_train, y_train)

#予測
y_pred = forest.predict(X_test)
print('Misclassified samples: %d' % (y_test != y_pred).sum())
print('Accuracy: %.2f' % accuracy_score(y_test, y_pred))

#Misclassified samples: 14
#Accuracy: 0.88

f:id:kuze3110:20171028171342p:plain

k近傍分類器(KNN: k-nearest neighbor classifier)

怠惰学習(lazy learner)の一つ。
選択された距離指標に基づきデータ点を分類する。
データセットの特徴量に適した距離指標を選択することが重要。
距離指標としては単純なユークリッド距離が使われることが多く、その場合は各特徴量を標準化する必要がある。

《利点》
予測を行うにあたってのトレーニングを必要としない。

《欠点》
予測の計算コストが高い。

《補足》
パラメトリックモデル
トレーニングデータセットからパラメータを推定するため、元のトレーニングデータセットがなくても新しいデータを分類できる。
パーセプトロン、ロジスティック回帰、線形SVMなど。

ノンパラメトリックモデル
固定のパラメータ集合で特徴づけることができず、パラメータの個数はトレーニングデータセットとともに増加する。
決定木、ランダムフォレスト、カーネルSVMなど。

実行例

from sklearn.neighbors import KNeighborsClassifier
#k近傍法のインスタンスを生成
knn = KNeighborsClassifier(n_neighbors=5, p=2, metric='minkowski') #p=2で指標としてユークリッド距離を指定
#k近傍法のモデルにトレーニングデータを適合させる
knn.fit(X_train_std, y_train)

#予測
y_pred = knn.predict(X_test_std)
print('Misclassified samples: %d' % (y_test != y_pred).sum())
print('Accuracy: %.2f' % accuracy_score(y_test, y_pred))

#Misclassified samples: 14
#Accuracy: 0.88

f:id:kuze3110:20171028171638p:plain

t検定、カイ二乗検定の備忘録

■t検定
主に2群の平均値の差の検定に用いる。
母集団が正規分布に従っている場合、標本分散を用いて算出される統計量tが自由度n-1のt分布に従うという性質を用いて検定を行う。

なお、利用する際は以下の条件を満たしている必要がある。
1.標本が母集団から無作為に抽出されている 2.母集団が正規分布に従っている 3.2群が等分散である

なお、母集団分散が未知でも大標本の場合はt分布でなく正規分布とz統計量を用いて同様の検定をしても問題ないようである。

実行例

#データの確認
summary(iris)
head(iris)
#  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#1          5.1         3.5          1.4         0.2  setosa
#2          4.9         3.0          1.4         0.2  setosa
#3          4.7         3.2          1.3         0.2  setosa
#4          4.6         3.1          1.5         0.2  setosa
#5          5.0         3.6          1.4         0.2  setosa
#6          5.4         3.9          1.7         0.4  setosa

#setosaとvirginicaのがく片の長さについてt検定を行う
setosa_length <- iris$Sepal.Length[iris$Species=="setosa"]
virginica_length <- iris$Sepal.Length[iris$Species=="virginica"]

t.test(setosa_length,virginica_length,paired = FALSE)
#データに対応がある場合paired = TRUEを指定する必要がある

#  Welch Two Sample t-test
#
#data:  setosa_length and virginica_length
#t = -15.386, df = 76.516, p-value < 2.2e-16
#alternative hypothesis: true difference in means is not equal to 0
#95 percent confidence interval:
#  -1.78676 -1.37724
#sample estimates:
#mean of x mean of y 
#    5.006     6.588 

カイ二乗検定
分割表において、2つの分類基準が独立であるかどうかを調べるために使われることが多い。(ピアソンのカイ二乗検定)
観測度数と期待度数の差を用いた統計量Χがカイ二乗分布に従うことを利用した検定。

なお、以下の場合はカイ二乗検定を使うべきではない。 ・条件間に対応がある場合 ・観測度数が20未満の場合 ・期待度数が5未満のセルがある場合

実行例

#データ読み込み、確認
dat <- data.frame(Titanic)
summary(dat)
head(dat)
#  Class    Sex   Age Survived Freq
#1   1st   Male Child       No    0
#2   2nd   Male Child       No    0
#3   3rd   Male Child       No   35
#4  Crew   Male Child       No    0
#5   1st Female Child       No    0
#6   2nd Female Child       No    0
#Freq列でサンプルの出現頻度がわかるようになっている

dat <- dat[dat$Freq!=0,] #頻度が0のデータを除外

#1行1サンプルになるようデータを加工する
titanic.df <- data.frame(Class=rep(dat$Class[1],dat$Freq[1]), #データの出現回数だけ行を増やす
                         Sex=rep(dat$Sex[1],dat$Freq[1]),
                         Age=rep(dat$Age[1],dat$Freq[1]),
                         Survived=rep(dat$Survived[1],dat$Freq[1]))

for (i in 2:nrow(dat)) {
  titanic.df_sub <- data.frame(Class=rep(dat$Class[i],dat$Freq[i]),
                           Sex=rep(dat$Sex[i],dat$Freq[i]),
                           Age=rep(dat$Age[i],dat$Freq[i]),
                           Survived=rep(dat$Survived[i],dat$Freq[i]))
  titanic.df <- rbind(titanic.df,titanic.df_sub)
}

#クロス集計
(test <- xtabs(~Age + Survived, data =  titanic.df))
#       Survived
#Age       No  Yes
# Child   52   57
# Adult 1438  654

#カイ二乗検定
chisq.test(test)

#  Pearson's Chi-squared test with Yates' continuity correction
#
#data:  test
#X-squared = 20.005, df = 1, p-value = 7.725e-06

#chisq.test()ではデフォルトでイェーツ補正がかかるようになっている点に注意

Rで自然言語処理(の準備)

統計ソフトのRを使って自然言語処理をする際に必要な設定のメモです。(インストール方法などはよく忘れてしまうため。。)

 

手順は以下の通りです。なお、Windows7の場合を想定しています。

  • Rのインストール
  • Rstudioのインストール
  • MeCab(形態素解析エンジン)のインストール
  • RMeCab(R上でMeCabを使うためのパッケージ)のインストール
Rのインストール

以下にあるRのダウンロードサイトから インストーラをダウンロードできます。

https://cran.ism.ac.jp/

Download R for Windows>baseの手順で最新版が手に入ります。なお、過去のバージョンを入手したい場合は「Previous releases」から入手可能です。

 

Rstudioのインストール

以下のRstudio公式ページから「Download」を選択してダウンロードできます。こちらもインストーラ形式なので苦労しないです。

www.rstudio.com

 

MeCabのインストール

以下のサイトで「mecab-0.996.exe:ダウンロード」をクリックするとインストーラがダウンロードできます。

http://taku910.github.io/mecab/

なお、MeCab京都大学情報学研究科−日本電信電話株式会社コミュニケーション科学基礎研究所 共同研究ユニットプロジェクトを通じて開発されたオープンソース 形態素解析エンジンです。 また、平均的に ChaSen, Juman, KAKASI (いずれも形態素解析エンジンの一種) より高速に動作します。 ちなみに和布蕪(めかぶ)は, 作者 (工藤拓) の好物です(ダウンロードサイトより一部引用)。

 

コマンドプロンプト上で動くので、システム環境変数のPathを通す必要があります。

 

マイコンピュータ>プロパティ>詳細設定>環境変数>Path で設定が可能です。自分のPCでインストールした場所を追加する (デフォルトではC:\Program Files\MeCab\bin)。

 

コマンドプロンプトを開き (スタートメニュー>ファイル名を指定>cmdと入力) 、mecabと打ち込んでMeCabが起動すれば正しく設定できています。試しに「すもももももももものうち」を入力すると、ちゃんと分解できます。

f:id:kuze3110:20161106223612p:plain

 

RMeCabのインストール 

 Rstudioを起動し、コンソール上で以下のコードを実行すればインストールできます。

install.packages("RMeCab", repos = "http://rmecab.jp/R") 

これで準備完了です!