前回の記事では、Pythonを用いてIrisデータセットを操作し、データの基本的な扱い方について学びました。今回は、そのデータを使用して、Scikit-learnで提供されているいくつかの基本的な分類モデルについて紹介します。分類は、機械学習の最も基本的なタスクの一つであり、データを事前に定義されたカテゴリに分けるプロセスです。
・Scikit learnのモデルってどういうものかわからない
・実際に使うためのPythonのコードを知りたい。
・訓練してモデルを作る方法を知りたい
こんな疑問に答えます。
・Scikit-learnの様々なモデルの使い方を学べる。
・Pythonコードの書き方を学べる。
・モデルの訓練方法を学べる。またモデルの精度を確認できる。
過去にこれらのブログも作成しているので環境構築やグラフ化の方法など興味があったら見てください。
モデルの選択
Scikit-learnは、機械学習のための強力なPythonライブラリであり、多数の分類アルゴリズムを提供しています。ここでは、以下の4つのモデルを紹介します。
- ロジスティック回帰
- サポートベクターマシン (SVM)
- 決定木
- ランダムフォレスト
これらのモデルを使って、Irisデータセットに含まれるアヤメの種類を実際に予測してみましょう。
モデルの実装と評価
各モデルを実装し、どのように分類問題に取り組むか見ていきましょう。
データの準備
from sklearn.model_selection import train_test_split
X = iris.data # 特徴量
y = iris.target # ラベル
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
X
とy
は、それぞれ特徴量とラベルを表します。
train_test_split関数はデータをランダムに分割します。
test_size=0.2は、全データの20%をテストデータとして保持し、残りの80%を訓練データとして使うことを意味します。
random_stateは乱数のシード値です。この値を設定することで、実行ごとに同じデータ分割が得られるようになります。
1. ロジスティック回帰
ロジスティック回帰は、分類問題を解決するためのシンプルながら強力なアルゴリズムです。ロジスティック回帰は、名前に「回帰」とありますが、二値分類問題に使用されるモデルです。出力を0と1の間に制限するシグモイド関数(ロジスティック関数)を使用します。出力は特定のクラスに属する確率として解釈されます。
適切な使用状況: 単純な二値分類問題や、結果が特定のクラスに属する確率を知りたい場合に適しています。また、特徴量と出力の関係が比較的単純で線形と仮定できる場合に効果的です。
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
model_lr = LogisticRegression()
model_lr.fit(X_train, y_train) # モデルの訓練
predictions_lr = model_lr.predict(X_test) # テストデータの予測
accuracy_lr = accuracy_score(y_test, predictions_lr) # 正確度の計算
print(f"Logistic Regression Accuracy: {accuracy_lr}")
LogisticRegression():ロジスティック回帰モデルを初期化します。
fitメソッドでモデルを訓練し、predictメソッドで予測を行います。
accuracy_score関数で予測の正確度を計算します。
実際にやった結果がこのようになります。ロジスティック回帰の精度は100%という結果になりました。
ロジスティック回帰の視覚化
ロジスティック回帰モデルを視聴者にわかりやすく説明するために、以下の方法で視覚化することができます:
- 決定境界のプロット: ロジスティック回帰は基本的に線形分類器であり、2次元データセットでは、データポイントを分ける直線(決定境界)を描くことができます。この直線は、モデルがクラスを分割する基準となります。
- シグモイド関数のグラフ: ロジスティック回帰の核心はシグモイド関数で、これにより出力を0から1の間の確率に変換します。シグモイド関数のグラフを示すことで、入力値が変化するにつれて予測される確率がどのように変わるかを視覚的に説明できます。
決定境界の例をプログラムにするとこのようになります。
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import make_classification
# デモデータの生成
X, y = make_classification(n_features=2, n_redundant=0, n_informative=2,
random_state=1, n_clusters_per_class=1)
model = LogisticRegression()
model.fit(X, y)
# 決定境界のプロット
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.01),
np.arange(y_min, y_max, 0.01))
Z = model.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.contourf(xx, yy, Z, alpha=0.4)
plt.scatter(X[:, 0], X[:, 1], c=y, s=20, edgecolor='k')
plt.title('Decision Boundary')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.show()
この例では、簡単な2次元データセットを生成し、ロジスティック回帰モデルを訓練して、決定境界をプロットしています。この視覚化により、モデルがどのようにデータポイントを2つのクラスに分けるかを直感的に理解できます。
2. サポートベクターマシン (SVM)
SVMは、データを最適に分割する境界線を見つけ出すことで分類を行うアルゴリズムです。
SVC()は、SVM分類モデルを初期化します。
SVMは特に非線形データの分類に強力ですが、パラメータのチューニングが重要になることもあります。
特徴: SVMは、クラス間のマージンを最大化するようにデータを分割する境界線(または超平面)を見つけることによって分類を行います。カーネルトリックを使用して非線形分類問題にも対応できるのが特徴です。
適切な使用状況: 特徴量の次元が高いデータセットや、線形分離が難しい非線形問題に対して強力です。データポイントが多い場合は計算コストが高くなるため、中小規模のデータセットに適しています。
実際にプログラムを実行するとこうなります。
from sklearn.svm import SVC
model_svc = SVC()
model_svc.fit(X_train, y_train)
predictions_svc = model_svc.predict(X_test)
accuracy_svc = accuracy_score(y_test, predictions_svc)
print(f"SVM Accuracy: {accuracy_svc}")
SVCも同様にAccuracy1.0の結果となります。
SVCの視覚化
SVCモデルの決定境界を視覚化するためには、少し手順が複雑になります。ここでは、2次元データセットに対するSVCモデルの決定境界とサポートベクターを描画する例を示します。
import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm
from sklearn.datasets import make_blobs
# トイデータセットの生成
X, y = make_blobs(n_samples=40, centers=2, random_state=6)
# SVCモデルの訓練
clf = svm.SVC(kernel='linear', C=1000)
clf.fit(X, y)
# プロット用のグリッドを生成
xx = np.linspace(0, 8, 10)
yy = np.linspace(-7, 1, 10)
YY, XX = np.meshgrid(yy, xx)
xy = np.vstack([XX.ravel(), YY.ravel()]).T
Z = clf.decision_function(xy).reshape(XX.shape)
# プロットの設定
plt.contour(XX, YY, Z, colors='k', levels=[-1, 0, 1], alpha=0.5, linestyles=['--', '-', '--'])
plt.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1], s=100,
facecolors='none', edgecolors='k')
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Paired, edgecolors='k')
plt.show()
このコードは、線形SVCモデルを用いて2次元データの決定境界を描画し、さらにサポートベクターを強調表示します。サポートベクターは、決定境界の位置決めに直接関与するデータポイントで、境界に最も近い点として描画されます。
図にするとこんな感じで境界が作成されます。
これらの視覚化は、モデルの動作原理を理解するのに非常に役立ちます。特に、決定木の場合は、どのようにデータを分割していくかのプロセスが明確になり、SVCでは、どのようにして異なるカテゴリーのデータを分離するかが視覚的に捉えられます。
3. 決定木
決定木は、データを分岐させる質問を繰り返すことで分類を行うモデルです。
特徴: 決定木は、データを分類するための条件分岐のシーケンスを作成します。木構造を形成し、各ノードが特徴量に対するテストを表し、ブランチがテストの結果、リーフノードが最終的な出力クラスを表します。
適切な使用状況: データの特徴がカテゴリカルな値を多く含む場合や、モデルの解釈が重要視される場合に適しています。ただし、過学習しやすいため、適切な事前枝刈りや後剪定が必要になります。
from sklearn.tree import DecisionTreeClassifier
model_dt = DecisionTreeClassifier()
model_dt.fit(X_train, y_train)
predictions_dt = model_dt.predict(X_test)
accuracy_dt = accuracy_score(y_test, predictions_dt)
print(f"Decision Tree Accuracy: {accuracy_dt}")
決定木の視覚化
Scikit-learnの決定木を視覚化するためには、pl
ot_tree
関数を使用します。まず、決定木モデルを訓練し、次に訓練されたモデルをplot_tree関数に渡して木構造を描画します。
決定木を視覚化するとこのようになります。
下記プログラムを実行すると、このように図が作成されます。
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier, plot_tree
import matplotlib.pyplot as plt
# データのロード
iris = load_iris()
X, y = iris.data, iris.target
# 決定木モデルの訓練
model = DecisionTreeClassifier()
model.fit(X, y)
# 決定木の視覚化
plt.figure(figsize=(20,10))
plot_tree(model, filled=True, feature_names=iris.feature_names, class_names=iris.target_names, rounded=True)
plt.show()
このようなにクラス分類される条件を記載された図が一瞬で作成できます。
すごいです。
4. ランダムフォレスト
ランダムフォレストは、多数の決定木を組み合わせて動作するアンサンブル学習の一種です。
特徴: ランダムフォレストは、複数の決定木を組み合わせたアンサンブル学習モデルです。各決定木はデータセットのランダムなサブセットから独立して学習し、最終的な出力は各木の投票によって決定されます。
適切な使用状況: 決定木の過学習を抑えつつ、高い予測精度を達成したい場合に適しています。特徴量の重要度を評価する能力もあり、どの特徴量が予測に重要かを知りたい場合にも有用です。大規模なデータセットにも対応でき、汎用性が高いです。
from sklearn.ensemble import RandomForestClassifier
model_rf = RandomForestClassifier()
model_rf.fit(X_train, y_train)
predictions_rf = model_rf.predict(X_test)
accuracy_rf = accuracy_score(y_test, predictions_rf)
print(f"Random Forest Accuracy: {accuracy_rf}")
まとめ
この記事では、Scikit-learnを使用してIrisデータセットの分類問題に取り組むための4つの基本的なモデルを紹介しました。各モデルの訓練と評価を行い、それぞれのモデルがIrisデータセットに対してどのような性能を示すかを見ました。ロジスティック回帰、サポートベクターマシン、決定木、ランダムフォレストの各モデルは、それぞれ異なるアプローチで問題に取り組みますが、全て有効な分類手法であることがわかります。
正確度(accuracy)は、モデルがどの程度正しく予測できたかを示す指標です。しかし、モデルの評価には他にも多くの指標があります。実際のプロジェクトでは、データの特性や問題の要件に応じて、最適なモデルと評価指標を選択することが重要です。
これらの基本的なモデルを通じて、機械学習における分類問題へのアプローチ方法を理解し、さらに複雑なデータセットや問題に挑戦するための基礎を築くことができました。次回は、より高度なモデルや特徴量エンジニアリングの技術について掘り下げていきましょう。