「Pythonによる機械学習入門」 第2部 基礎編のまとめ

「Pythonによる機械学習入門」を読みましたので、第2部で得たことをまとめます。

総評すると「scikit-learnを使えば機械学習で有名な各種手法がお手軽に試せるぜ」といった感じです。

あくまで入門なので「どう使えば良いのか?」が主たる関心事で、「その方法でなぜ答えに近づけるのか?答えから遠のいてしまうのか?」「AとBの使い分けをどうすれば良いのか?」といった手法に対する理論的な説明は、別で学ぶ必要があります。

とはいえ、scikit-learnに加えてpandasやpyplotなども紹介されており、第3部ではデータのクレンジングやグリッドサーチなどについても触れられていますので、今あるデータをこね回してみるのには十分かと思います。

全体は4部構成で、第1部が導入、第2部が分類・回帰・クラスタリングに関する基礎編、第3部が手の写真画像を使った分類とセンサデータの回帰を行う実践編、第4部が付録となっており、今回は第2部についてまとめます。

Pythonによる機械学習入門

Pythonによる機械学習入門

第3章 分類問題

scikit-learn付属のdigitsデータセット(8×8ピクセルの手書き数字画像)を使って、0〜9のラベルで分類します。

scikit-learnを使えば、classifier = tree.DecisionTreeClassifier()で呼び出すメソッドを変えることで簡単に分類器の種類へ変更できます。

from sklearn import tree
from sklearn import metrics

# 学習
classifier = tree.DecisionTreeClassifier()
classifier.fit(images[:train_size], labels[:train_size])

# 検証
predicted = classifier.predict(images[train_size:])

# 比較
print('Accuracy:', metrics.accuracy_score(expected, predicted))
  • 学習データと訓練データの分離方法
    • ホールドアウト検証では、対象データの一部をテストデータとして取り出してそれ以外全てを学習データとする
    • k-分割交差検証では、対象データをk個に分割して、内1個をテストデータ・それ以外を学習データとして、k回の学習・検証(推論)を繰り返し、平均値を認識率とする
      • 少数のデータの中で学習データとテストデータをやりくりする方法で、kが小さいほど学習データが増えるので性能は向上させやすい(学習・検証の回数が増えるので、時間はかかる)
  • 分類器の性能指標
    • 正答率(Accuracy):全検証データの内、正しく分類された検証データの割合
    • 適合率(Precision):あるラベルに分類されたデータの内、正しく分類された検証データの割合
    • 再現率(Recall):あるラベルに分類されるべき検証データの内、そのラベルに分類された割合
    • F値(F-measure):適合率と再現率の調和平均
    • 検証データに偏りがある場合、ラベルごとに算出される適合率や再現率の方が実体を正しく捉えられるケースも有る
  • アンサンブル学習では、性能の低い分類器(弱仮説器)を組み合わせて、それぞれの分類結果を集約する
    • Random Forestでは、学習データセットから重複・欠落を許したサブセットを作って、サブセット数だけ弱仮設器を学習させて、多数決で検証する(バギング)
    • AdaBoostでは、難度の高い学習データを分類できる弱仮設器を重視するように、重み付けする(ブースティング)
  • SVMでは、サンプルとの距離の二乗和が最大となるように分割する、2クラス分類器
    • 3クラス以上の場合は複数の分類器を組み合わせる

第4章 回帰問題

線形関数・非線形関数の値に乱数値を加えて擬似的に生成した波形のサンプルに対して、scikit-learnで線形回帰・非線形回帰を行います。

  • 線形回帰と非線形回帰
    • y=x2の場合でも、X=x2と変数に置き換えられるなら、それは線形回帰できる
  • model = linear_model.LinearRegression()を置き換えることで、使うモデルを変更できる
    • 最小二乗法、SVM、Random Forest、k-近傍法
from sklearn import linear_model

# 学習
model = linear_model.LinearRegression()
model.fit(x, y)

# 結果(傾きと切片)
print(model.coef_)
print(model.intercept_)
  • 重回帰(2変数以上)の場合は、入力を[[x1_1, x2_1], [x1_2, x2_2], ...]のような多次元配列にする
    • y = 3 * x**2 + 2 * x + 4の場合も、[[x1**2, x1], [x2**2, x2], ...]とすることで重回帰分析(線形)できる
x1_x2 = np.c_[x1, x2]
model = linear_model.LinearRegression()
model.fit(x1_x2, y)
  • 変数が多すぎる(例えば、4変数で表せる関数を9変数で回帰させる、など)と、表現力が高すぎて過学習の原因となる
    • モデルの複雑度を加味するRidge回帰やLasso回帰(罰則付き回帰)
    • 変数の数(ハイパーパラメータ)をどうやって推定するのか

第5章 クラスタリング

scikit-learn付属のirisデータセットを使って、花弁の長さと幅の値からあやめの品種(3種類)に分類します。

from sklearn import datasets

iris = datasets.load_iris()

iris['data'][i][j] # i番目のあやめのj番目のデータ
iris['target'][i] # i番目のあやめの品種
  • k-meansではクラスタ数を予め決めて、クラスタに属するデータから中心への距離が最小となるように、所属や中心を変更する
from sklearn import cluster

# k-means法で3クラスタに分類
model = cluster.KMeans(n_clusters=3)
# 学習
model.fit(data)
  • 階層的凝集型クラスタリングでは、1データ1クラスタからスタートして、近くのデータを凝集させながら、指定のクラスタ数まで絞る
    • 最短距離法、最長距離法、群平均法、ウォード法
  • 非階層的クラスタリング(k-meansもこの1つ)では、評価関数を定義して、その評価関数が最適になるように分割する方法
    • Affinity Propagation