実行例は「saka.mokumoku」の「Google Colabotry」環境に保存してある
1.iris データセットの説明
データセットのロード
load_iris 関数でロードする
データセットの説明
DESCR (description) の中身を見る
Attribute の意味
sepal length:ガクの長さ
sepal width:ガクの幅
petal length:花弁の長さ
petal width :花弁の幅
from sklearn.datasets import load_iris
iris = load_iris()
#
print(iris.DESCR)
データセットの内容
データセットの形状・・・特徴量は 4 個で、150 個のデータ
形状は shape で確認する
花の種類・・・target_names に3種類の花が格納されている
setosa、’versicolor、’virginica
先頭5件・・・iris.data
4 つの特徴量(ガクの長さ、幅、花弁の長さ、幅)
iris.target
3種類、0(=setosa), 1(=versicolor), 2(=virginica)
print(iris.data.shape)
#
print(iris.target_names)
#
for data, target in zip(iris.data[:5], iris.target[:5]):
print(data, target)
2.データフレーム作成
データフレームにするとデータを扱いやすくなる
target の行が 0, 1, 2 だと分かりにくいので種類名に置き換える
describeで平均値、最小、最大値を眺める
import pandas as pd
#
df = pd.DataFrame(iris.data, columns=iris.feature_names)
df['target'] = iris.target
df.loc[df['target'] == 0, 'target'] = "setosa"
df.loc[df['target'] == 1, 'target'] = "versicolor"
df.loc[df['target'] == 2, 'target'] = "virginica"
#
print(df.describe())
3.ペアプロットする
各特徴量のペアごとに散布図を表示する
特徴量のペアで見ても同じ品種が固まっているので、比較的分類しやすい
import seaborn as sns
#
sns.pairplot(df, hue="target")
4.分類アルゴリズム
分類アルゴリズムの特徴を見るために
作成したモデルの決定境界(decision boundary)を表示する
モデルを validation 用、test 用に分けたり、正答率の評価は行わない
X に訓練データをセットする
特徴量はガクの長さ、花弁の長さの2つだけを使用する
y に教師データとして品種をセットする
描画用にコードを準備する
# import some data to play with
X = iris.data[:, [0, 2]]
y = iris.target
import numpy as np
import matplotlib.pyplot as plt
# graph common settings
h = .02 # step size in the mesh
x_min, x_max = X[:, 0].min() - .5, X[:, 0].max() + .5
y_min, y_max = X[:, 1].min() - .5, X[:, 1].max() + .5
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
def decision_boundary(clf, X, y, ax, title):
clf.fit(X, y)
# Plot the decision boundary. For that, we will assign a color to each
# point in the mesh [x_min, x_max]x[y_min, y_max].
Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
# Put the result into a color plot
Z = Z.reshape(xx.shape)
ax.pcolormesh(xx, yy, Z, cmap=plt.cm.Paired)
# Plot also the training points
ax.scatter(X[:, 0], X[:, 1], c=y, edgecolors='k', cmap=plt.cm.Paired)
# label
ax.set_title(title)
ax.set_xlabel('sepal length')
ax.set_ylabel('petal length')
5.教師あり学習
k-近傍法 (k-NN)
モデルには訓練データセットを格納するだけ
予測時は、予測したいデータポイントの近くの k 個の近傍点を確認し
その中で一番多数派のクラスを予測結果として採用する
KNeighborsClassifierを使用する
n_neighbors で予測に使用する近傍点の数を設定する
n_neighbors = 1 の場合は決定境界が鋭角になる部分もある
数が多くなるに従いなだらかになっていき、
10 になると境界が単純になりすぎて予測性能が落ちる
from sklearn.neighbors import KNeighborsClassifier
fig, axes = plt.subplots(1, 4, figsize=(12, 3))
for ax, n_neighbors in zip(axes, [1, 3, 6, 10]):
title = "%s neighbor(s)"% (n_neighbors)
clf = KNeighborsClassifier(n_neighbors=n_neighbors)
decision_boundary(clf, X, y, ax, title)
ロジスティック回帰
回帰とあるが、分類アルゴリズム
LogisticRegressionを使用する
決定境界は直線になる
C は正則化の度合いを調整するパラメータ
正則化は学習時にペナルティを与えることで過学習を抑える
C を大きくすると正則化が弱くなり過学習気味になる
Cを小さくするとデータの特徴を大雑把にしか獲得できない
ロジスティック回帰などの線形モデルは
高次元(特徴量の数が多い)のデータに対して有効
高速のため、他の手法では学習できない
from sklearn.linear_model import LogisticRegression
fig, axes = plt.subplots(1, 3, figsize=(10, 3))
for ax, C in zip(axes, [0.01, 1, 100]):
title = "C=%s"% (C)
clf = LogisticRegression(C=C)
decision_boundary(clf, X, y, ax, title)
線形サポートベクタマシン
LinearSVCを使用する
線形なので、決定境界も直線になる
C はロジスティック回帰同様、正則化の度合いを調整するパラメータ
from sklearn.svm import LinearSVC
fig, axes = plt.subplots(1, 3, figsize=(10, 3))
for ax, C in zip(axes, [0.01, 1, 100]):
title = "C=%s"% (C)
clf = LinearSVC(C=C)
decision_boundary(clf, X, y, ax, title)
カーネル法を用いたサポートベクタマシン
SVM とも呼ばれる
線形カーネルベクタマシンと比べて、非線形な分離が可能
SVCを使用する
C は正則化のパラメータ
gamma は訓練データの影響が及ぶ範囲
小さいと遠くまで、大きいと近くになる
大きすぎると過学習になり
小さすぎると大雑把にしかデータの特徴を獲得できない
from sklearn.svm import SVC
fig, axes = plt.subplots(3, 3, figsize=(10, 10))
for ax_row, C in zip(axes, [0.01, 1, 100]):
for ax, gamma in zip(ax_row, [0.1, 1, 10]):
title = "C=%s, gamma=%s"% (C, gamma)
clf = SVC(C=C, gamma=gamma)
decision_boundary(clf, X, y, ax, title)
決定木
質問を通してデータを分類する手法
あやめの場合には
花弁の長さが何センチ以上 or 未満
ガクの長さが何センチ以上 or 未満・・・と質問を繰り返す
DecisionTreeRegressor を使用する
max_depth がツリーの深さで、質問数になる
多ければいいわけでもなく、
訓練データに過剰適合するので過学習となる
from sklearn.tree import DecisionTreeRegressor
fig, axes = plt.subplots(1, 3, figsize=(10, 3))
for ax, max_depth in zip(axes, [1, 3, 8]):
title = "max_depth=%s"% (max_depth)
clf = DecisionTreeRegressor(max_depth=max_depth)
decision_boundary(clf, X, y, ax, title)
ランダムフォレスト、勾配ブースティング回帰木
ランダムフォレストは異なる決定木をたくさん作り
全ての決定木で予測した結果から
もっとも確率が高くなるラベルを正解とする
個々の木だと過剰適合しているかもしれないが、
多くの結果を集約することで過学習を抑制する効果がある
RandomForestClassifier を使う
勾配ブースティング回帰木もたくさんの決定木を作るが、
一つ前の決定木の予測値と正解のズレを修正するように
次の木を作っていく
GradientBoostingClassifier を使う
ランダムフォレストよりモデル構築に時間がかかり
パラメータ設定のチューニングが大変らしいが、
その分予測性能がよくなる
GBDT = Gradient Boosting Decision Tree
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import GradientBoostingClassifier
fig, axes = plt.subplots(1, 2, figsize=(7, 3))
clfs = [RandomForestClassifier(), GradientBoostingClassifier()]
titles = ["RandomForestClassifier", "GradientBoostingClassifier"]
for ax, clf, title in zip(axes, clfs, titles):
decision_boundary(clf, X, y, ax, title)
ニューラルネットワーク
MLPClassifier を使う
隠れ層 15 個で計算した結果を図示する
同じパラメータでも決定境界が異なってくる
異なる理由は、異なる初期状態から学習を開始するから
from sklearn.neural_network import MLPClassifier
fig, axes = plt.subplots(1, 4, figsize=(12, 3))
for ax, n in zip(axes, [15, 15, 15, 15]):
title = ""
clf = MLPClassifier(hidden_layer_sizes=[n, n])
decision_boundary(clf, X, y, ax, title)
6.教師なし学習
k-means
教師データなしで分類する手法
KMeans を使う
n_clustersで何個に分類するかを指定する
from sklearn.cluster import KMeans
fig, axes = plt.subplots(1, 4, figsize=(12, 3))
for ax, n_clusters in zip(axes, [2, 3, 4, 5]):
title = "n_clusters=%s"% (n_clusters)
clf = KMeans(n_clusters=n_clusters)
decision_boundary(clf, X, y, ax, title)