機械学習の広範な理解を目指すための書籍紹介
対象読者(主観)
- 教師あり学習、教師なし学習、モデル評価、特徴量エンジニアリングについて広く学習したい方。
- 数式なしの理論でとりあえずは問題ない方。
- 実装までの手厚いサポートがほしい方。
- 機械学習をとりあえず手を動かして学習し、予測のプロセスを体験したい初学者。
何が学べるか
本書の章構成は以下の通りです。
1章 はじめに
本書で用いるライブラリの概略などを紹介しています。過学習等の説明もここに含まれていた気がします。
2章 教師あり学習
初学者でも理解できるよう、詳細な説明で導入があり、現在広く使われている学習手法を幅広くカバーしています。scikit-learnを使ったPythonコードが豊富に提供されており、実装も簡単でとても読み進めやすいです。
3章 教師なし学習と前処理
この章は読み流しました。前半では、教師なし学習の目的が簡単に説明されており、後半は実際に用いられている手法の紹介があります。私は今回はパスしましたが、教師なし学習に興味が湧いたら戻ってきたいと思います。
4章 データの表現と特徴量エンジニアリング
個人的に、一番有用な情報源だという認識をしています。KaggleやSIGNATEなどのコンペに参加した人であればわかると思いますが、モデルの性能を上げるために必要なデータの前処理にスポットを当てた章です。別書「Kaggleで勝つデータ分析の技術」などと内容が被る部分も多いので、そちらに詳しい方は読み飛ばしても良いと思います(「Kaggleで勝つ」の方が圧倒的に詳しく、実用的です)。
5章 モデルの評価と改良
交差検証をはじめとする、モデル評価と改良のTipsが多く仕込まれています! 機械学習の要はここだと思いますので、皆さんぜひじっくり読んでほしいところです。
6章 アルゴリズムチェーンとパイプライン
scikit-learnのパイプラインという機能の使い方の説明があります。複雑な前処理やモデルの組み合わせをシンプルに記述できるので、実務でも役立つ知識です。
7章 テキストデータの処理
文章をscikit-learnで処理する方法について詳細に解説されています。実用性には欠けるかなという印象ですが、基礎を押さえるには良いかもしれません。
8章 おわりに
まとめです。本書で学んだことを振り返り、次のステップへの道筋を示しています。
参考資料
以下、私のノートです。メモなので全然まとまりはなく、局所的なものですが、参考までに。
ノート抜粋
- 教師あり学習と教師なし学習の違いを理解することが重要。
- 特徴量エンジニアリングはモデルの性能に直結するため、データの前処理は手を抜かない。
- 交差検証やハイパーパラメータチューニングを活用してモデルを最適化する。
- パイプラインを使うことでコードの可読性と再利用性が向上する。
k-最近傍法
目的
1つの近傍点、つまり訓練データに含まれる点の中で、予測したいデータポイントに最も近い点「最近傍点」を見つけること。
実装
# ライブラリのインポート
import mglearn
# k-最近傍法の分類をプロット
mglearn.plots.plot_knn_classification(n_neighbors=3)
ライブラリmglearnをインポートしていれば、上記のコード単体で、k-最近傍法を用いてforgeの図を視認できます。
# 必要なライブラリのインポート
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
# データの分割
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
# インスタンス化
clf = KNeighborsClassifier(n_neighbors=3)
# モデルの訓練
clf.fit(X_train, y_train)
# テストデータで予測
print('Test and prediction: {}'.format(clf.predict(X_test)))
# モデルの精度を評価
print('Test set accuracy: {:.2f}%'.format(clf.score(X_test, y_test)*100))
追記
最近傍点の数
最近傍点の数(k)は、少なくすると複雑なモデルに対応し、多くすると単純なモデル向きになります。
回帰バージョン
回帰を行う変種が存在し、これはKNeighborsClassifierの代わりにKNeighborsRegressorを用いることで、上記同様に使用できます。(ちなみに、回帰なのでデータセットは連続した値を出力するwaveなどを用いる方が良いです)
利点と欠点
利点: 理解しやすく、実装が簡単。
欠点: 処理速度が遅く、多数の特徴量を持つデータには適応できない(数百以上)。また、ほとんどの特徴量が0となる疎なデータセットでも特に性能が悪いです。
したがって、ほとんど現場では使われません。
線形モデル
目的
入力特徴量の線形関数を用いて予測を行うものです。一般に回帰のプロセスを持ちます。
多数の特徴量を持つデータに対しては、非常に強力です。
特徴量がサンプル数を上回るデータ(主に巨大なデータ)を扱えるのは、一般的に線形モデルに限られます。逆に、次元数が小さい場合には、他のモデルの方が良い汎化性能を持つことが十分に期待できます。
実装
追記
線形モデルの予測
単一の特徴量に対しては直線、二つなら平面、高次元においては予測は超平面になります。
ニューラルネットワーク
概要
最大の利点は、大量のデータを用いて、非常に複雑なモデルを構築できることです。
しかし、この利点の裏返しが欠点となり、非常に強力なネットワークは学習に時間がかかることがあります。
また、データを慎重に前処理する必要があります。
パラメータの調整
一般的なやり方として:
- 過剰適合するように、大きなネットワークを構成する。
- ネットワークを小さくするか、alphaを増やして正則化を強化し、汎化性能を向上させる。
パラメータを学習する際のアルゴリズム
adam
ほとんどの場合でうまくいくが、データのスケールに敏感である。したがって、データの平均を0、分散を1にしておくことが大事である。
lbfgs
頑健だが、モデルが大きい場合や、大規模なデータセットには時間がかかる。
sgd
研究者がよく用いる高度なモデル。多くの設定パラメータがあり、上級者向き。
参考リンク: MLP Classifier
データセット
forge
概要
2クラス分類データセット。2つの特徴量に対して、26個のデータポイントがあります。つまり、2次元データです。
使用例
クラス分類タスクでの使用が一般的です。
呼び出し
X, y = mglearn.datasets.make_forge()
# X の形状: (26, 2)
# y の形状: (26,)
wave
概要
1次元で、出力値が連続。サンプル数は40。出力が連続値であることから、回帰アルゴリズムの挙動を見るために用いられます。
使用例
回帰アルゴリズムのテストに適しています。
呼び出し
X, y = mglearn.datasets.make_wave(n_samples=40)
# サンプル数を自分で指定可能
cancer(ウィスコンシン乳がんデータセット)
概要
各サンプルについて、10種類の特徴が3つの統計量(平均値、標準偏差、最大値)で計測され、特徴量数は30になります。
サンプル数: 569
特徴量数: 30(すべて数値)
クラス数: 2(良性と悪性)
クラスラベル: 0(悪性)、1(良性)
使用例
非常に広く用いられているデータセットです。SVMやニューラルネットワークはもちろん、決定木やk-最近傍法でも使えます。
呼び出し
from sklearn.datasets import load_breast_cancer
data = load_breast_cancer()
# データの分割例
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
data.data, data.target, stratify=data.target, random_state=42)
boston_housing(倫理的な問題で削除済み)
概要
サンプル数: 506
特徴量数: 13(数値型、またはカテゴリ型の特徴量)
特徴量には、人口1人あたりの犯罪率や高速道路へのアクセスのしやすさなどがあります。
使用例
回帰モデルのテストに使用されてきましたが、現在は倫理的な問題で削除されています。
呼び出し
from sklearn.datasets import load_boston
boston = load_boston()
# boston のデータの形状は (506, 13)
ガウス分布
概要
ユーザーが指定した数のクラスを持つランダムなデータポイントを生成し、それぞれのクラスタが異なる分布を持つように設定できます。出力は数値データであり、離散的です。
使用例
出力が離散的であるため、線形モデルのクラスタリングテスト等で用いられます。
呼び出し
from sklearn.datasets import make_blobs
# random_state を設定することで、毎回同じデータセットを使用できます
X, y = make_blobs(random_state=42)
print('X.shape:', X.shape)
print('X[:,0].shape:', X[:,0].shape)
print('X[:,1].shape:', X[:,1].shape)
mglearn.discrete_scatter(X[:, 0], X[:, 1], y)
moons(半月型)
概要
二次元の半月型のデータを生成する際に用います。二つのクラスに分類される二つの半月型の分布が見られます。
使用例
クラスの境界面がかなり複雑になるため、モデルがデータを非線形にクラス分類できるかを判定するのに用いられます。
呼び出し
from sklearn.datasets import make_moons
X, y = make_moons(n_samples=100, noise=0.25, random_state=3)
# n_samples: データの数
# noise: データの点が「月」の形から外れる度合い
# random_state: 乱数生成のシード
ライブラリ
mglearn
二次元の散布図を描く
mglearn.discrete_scatter(x1, x2, y)
# x1: x軸にプロットするデータ
# x2: y軸にプロットするデータ
# y: データポイントのクラス
二次元のドットを境界線で分割する
mglearn.plots.plot_2d_separator(classifier, X, fill=False, ax=None,
eps=None, alpha=1, cm='b', linewidth=None, threshold=None)
classifier: 訓練済みの機械学習モデルを指定
X: 二次元の特徴量データの配列
fill: 境界の内側の領域を塗り潰すかどうか(デフォルトはFalse)
matplotlib
import matplotlib.pyplot as plt
縦軸と横軸にラベルをつける
plt.xlabel('横軸のラベル')
plt.ylabel('縦軸のラベル')
プロットする点の説明を入れる
plt.legend(['一つ目のドットの説明', '二つ目のドットの説明'], loc=1)
# loc は説明を配置する位置(1は右上、4は右下)
図の表示
plt.show()
2変数1次元の散布図
plt.plot(X, y, 'o')
# 'o' と指定すると、丸い点をプロット
適合不足と過剰適合
適合不足(アンダーフィッティング)
特徴: 訓練セットのスコアとテストセットのスコアの値が近いが、全体的に精度が低い。
原因: 特徴量が足りていない、モデルが単純すぎる。
過剰適合(オーバーフィッティング)
特徴: 訓練セットのスコアが非常に高いが、テストセットのスコアが低い。モデルが訓練データに依存しすぎており、一般化性能に欠ける。
原因: 特徴量が多すぎる、モデルが複雑すぎる。
コメント