PythonとScikit-learnで始める機械学習入門

はい、承知いたしました。PythonとScikit-learnを使った機械学習入門について、約5000語の詳細な記事を作成します。


PythonとScikit-learnで始める機械学習入門

はじめに

現代社会はデータにあふれています。インターネット、スマートフォン、センサー、ビジネスプロセスなど、様々な活動から膨大なデータが生成されています。これらのデータを単に蓄積するだけでなく、そこから有用な知識やパターンを抽出し、未来を予測したり、意思決定を支援したりする技術が求められています。その中心となるのが「機械学習」です。

機械学習は、明示的にプログラムされていないにもかかわらず、データから学習する能力をコンピューターに与える科学分野です。これにより、スパムメールのフィルタリング、顧客の行動予測、医療画像の診断、自動運転車の制御など、多岐にわたる応用が可能になっています。

機械学習を始めるにあたって、Pythonは非常に人気のある言語です。その理由は、豊富なライブラリと活発なコミュニティにあります。特に、Scikit-learn (sklearn) は、機械学習のための最も広く使われているPythonライブラリの一つです。シンプルで一貫性のあるAPIを提供しており、初心者から経験者まで、様々なアルゴリズムを手軽に試すことができます。

この記事では、PythonとScikit-learnを使って機械学習の基本を学び、実際に簡単なモデルを構築するまでのステップを、約5000語の詳細な説明とコード例とともに解説します。

この記事の対象読者:

  • 機械学習に興味があるが、どこから始めたら良いか分からない方。
  • Pythonの基本的な文法は理解している方(必須ではありませんが、コードの理解が深まります)。
  • Scikit-learnを使ってみたい方。

この記事で学べること:

  • 機械学習の基本的な概念(教師あり学習、教師なし学習など)。
  • Scikit-learnを使った機械学習プロジェクトの一般的な流れ。
  • データの前処理の重要性と基本的な手法。
  • 分類問題と回帰問題の解き方。
  • 主要な機械学習アルゴリズムのScikit-learnでの使い方。
  • モデルの評価方法。
  • モデルの性能を改善するための基本的なテクニック。

さあ、PythonとScikit-learnを使った機械学習の世界への第一歩を踏み出しましょう。

環境構築

機械学習を始めるためには、まずPythonと必要なライブラリをインストールする必要があります。最も簡単な方法は、Anacondaディストリビューションをインストールすることです。Anacondaには、Python本体に加え、科学技術計算やデータ分析に必要な多くのライブラリ(NumPy, Pandas, Scikit-learn, Matplotlibなど)があらかじめ含まれています。

  1. Anacondaのインストール:

    • Anacondaの公式サイト (https://www.anaconda.com/products/individual) にアクセスします。
    • お使いのオペレーティングシステム(Windows, macOS, Linux)に合ったインストーラーをダウンロードします。
    • インストーラーを実行し、指示に従ってインストールを進めます。特別な理由がなければ、デフォルトの設定で問題ありません。
  2. 必要なライブラリの確認(Anacondaの場合):

    • Anacondaをインストールした場合、Scikit-learn, NumPy, Pandas, Matplotlibは通常含まれています。
    • 念のため、Anaconda Prompt (Windows) または Terminal (macOS/Linux) を開いて、以下のコマンドでバージョンを確認できます。

    bash
    conda list scikit-learn
    conda list numpy
    conda list pandas
    conda list matplotlib

    • もし含まれていない場合や、最新版にアップデートしたい場合は、以下のコマンドでインストール/アップデートできます。

    bash
    conda install scikit-learn numpy pandas matplotlib

  3. Jupyter Notebookの起動:

    • Jupyter Notebookは、コード、実行結果、説明文、図などを一つのドキュメントにまとめられる対話的な開発環境です。機械学習の実験やプロトタイピングに非常に便利です。
    • Anaconda NavigatorからJupyter Notebookを起動するか、Anaconda Prompt/Terminalで以下のコマンドを実行します。

    bash
    jupyter notebook

    * コマンドを実行すると、ブラウザが起動し、Jupyter Notebookの画面が表示されます。ここで新しいノートブックを作成し、コードを記述していきます。

この記事では、特に断りがない限り、Jupyter Notebookでの実行を想定しています。

機械学習の基本概念

Scikit-learnを使う前に、機械学習の基本的な概念を理解しておきましょう。

機械学習にはいくつかの種類がありますが、ここでは最も一般的な「教師あり学習」と「教師なし学習」に焦点を当てます。

教師あり学習 (Supervised Learning)

教師あり学習では、「入力データ(特徴量)」と「それに対応する正しい出力データ(正解ラベルまたは目的変数)」のペアが与えられたデータセット(訓練データ)を使ってモデルを学習させます。学習済みのモデルは、未知の入力データに対して正しい出力を予測できるようになります。

教師あり学習は、予測したい出力の種類によってさらに二つに分けられます。

  1. 分類 (Classification): 入力データがどのカテゴリに属するかを予測するタスクです。

    • 例:メールがスパムかどうか(スパム/非スパム)、画像に写っているのが猫か犬か(猫/犬)、顧客が商品を購入するかどうか(購入する/しない)。
    • 出力は離散的なクラスラベルです。
  2. 回帰 (Regression): 入力データに基づいて連続的な数値(目的変数)を予測するタスクです。

    • 例:住宅の面積から価格を予測する、過去の株価データから明日の株価を予測する、病気の進行度を予測する。
    • 出力は連続的な数値です。

教師なし学習 (Unsupervised Learning)

教師なし学習では、入力データのみが与えられ、それに対応する正しい出力データはありません。アルゴリズムは、データの内部構造やパターンを自動的に発見します。

教師なし学習の主なタスク:

  1. クラスタリング (Clustering): データセットを、互いに似ているデータ点のグループ(クラスター)に分割します。

    • 例:顧客の購買行動に基づいてセグメント分けする、ニュース記事をトピックごとにまとめる。
  2. 次元削減 (Dimensionality Reduction): データの持つ情報量をできるだけ保ちながら、データの特徴量の数を減らします。データの可視化や、後続の機械学習モデルの訓練を効率化するのに役立ちます。

    • 例:高次元の画像データを2次元や3次元に圧縮して可視化する。

その他の学習手法

  • 強化学習 (Reinforcement Learning): エージェントが環境と相互作用しながら、報酬を最大化するように行動を学習する手法です。ゲームAIやロボット制御などに使われます。この記事では詳しく触れません。

モデル、学習、予測

  • モデル (Model): データから学習された、入力と出力の関係を表現する数式やアルゴリズムのことです。例えば、線形回帰における直線の方程式や、決定木における意思決定のルールなどがモデルにあたります。
  • 学習 (Training): 与えられた訓練データを使って、モデルのパラメータ(例:線形回帰の傾きや切片)を調整するプロセスです。モデルがデータセットのパターンを捉えられるようにします。Scikit-learnでは、通常 fit() メソッドを使用します。
  • 予測 (Prediction): 学習済みのモデルを使って、新しい、見たことのない入力データに対する出力を生成することです。分類問題ならクラスラベル、回帰問題なら数値を予測します。Scikit-learnでは、通常 predict() メソッドを使用します。

データの前処理

機械学習モデルの性能は、使用するデータの質に大きく依存します。生データはノイズが含まれていたり、欠損があったり、モデルが直接扱えない形式だったりすることがよくあります。そのため、データをモデルが扱える形式に整える「前処理 (Preprocessing)」が非常に重要になります。

Scikit-learnは、さまざまな前処理ツールを提供しています。

データの読み込み

まずはデータを読み込む必要があります。CSVファイル形式のデータは、Pandasライブラリを使うのが一般的です。

“`python
import pandas as pd

例として、ここではScikit-learnに付属のデータセットを使います

実データの場合は、pd.read_csv(‘your_data.csv’) のように読み込みます

from sklearn.datasets import load_iris
iris = load_iris()

Scikit-learnのデータセットは辞書のような形式です

data: 特徴量 (NumPy配列)

target: 目的変数 (NumPy配列)

feature_names: 特徴量の名前

target_names: 目的変数の名前

DESCR: データセットの説明

データフレームに変換すると扱いやすいです

df = pd.DataFrame(data=iris.data, columns=iris.feature_names)
df[‘target’] = iris.target
df[‘target_names’] = df[‘target’].apply(lambda x: iris.target_names[x]) # target_names列を追加

print(“データセットの最初の5行:”)
print(df.head())

print(“\nデータセットの情報の確認:”)
df.info()

print(“\n基本統計量の確認:”)
print(df.describe())
“`

出力例:

“`
データセットの最初の5行:
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) target target_names
0 5.1 3.5 1.4 0.2 0 setosa
1 4.9 3.0 1.4 0.2 0 setosa
2 4.7 3.2 1.3 0.2 0 setosa
3 4.6 3.1 1.5 0.2 0 setosa
4 5.0 3.6 1.4 0.2 0 setosa

データセットの情報の確認:

RangeIndex: 150 entries, 0 to 149
Data columns (total 6 columns):
# Column Non-Null Count Dtype
— —— ————– —–
0 sepal length (cm) 150 non-null float64
1 sepal width (cm) 150 non-null float64
2 petal length (cm) 150 non-null float64
3 petal width (cm) 150 non-null float64
4 target 150 non-null int64
5 target_names 150 non-null object
dtypes: float64(4), int64(1), object(1)
memory usage: 7.2+ KB

基本統計量の確認:
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) target
count 150.000000 150.000000 150.000000 150.000000 150.000000
mean 5.843333 3.057333 3.758000 1.199333 1.000000
std 0.828066 0.435866 1.765298 0.762238 0.816962
min 4.300000 2.000000 1.000000 0.100000 0.000000
25% 5.100000 2.800000 1.600000 0.300000 0.000000
50% 5.800000 3.000000 4.350000 1.300000 1.500000
75% 6.400000 3.300000 5.100000 1.800000 2.000000
max 7.900000 4.400000 6.900000 2.500000 2.000000
“`

df.info()で欠損値の有無(Non-Null Countが全データ数と同じか)やデータ型を確認できます。df.describe()で数値列の統計量を確認できます。

欠損値の処理 (Handling Missing Values)

データには欠損値(NaNなど)が含まれていることがあります。多くの機械学習アルゴリズムは欠損値を直接扱うことができません。欠損値の処理方法にはいくつかあります。

  • 欠損値を含む行や列を削除する: 簡単ですが、多くのデータを失う可能性があります。
  • 欠損値を補完する (Imputation): 平均値、中央値、最頻値などで補完する方法や、他の特徴量から予測して補完する方法があります。

Scikit-learnの impute モジュールにある SimpleImputer が便利です。

“`python
import numpy as np
from sklearn.impute import SimpleImputer

サンプルデータ(欠損値を含む)

data = {‘col1’: [1, 2, np.nan, 4, 5],
‘col2’: [np.nan, 2, 3, 4, 5],
‘col3’: [1, 2, 3, 4, np.nan]}
df_missing = pd.DataFrame(data)
print(“欠損値を含むデータ:”)
print(df_missing)

中央値で欠損値を補完

strategy=’mean’, ‘median’, ‘most_frequent’, ‘constant’

imputer = SimpleImputer(missing_values=np.nan, strategy=’median’)

fit()で補完方法を学習し、transform()で適用

fit_transform()はこれを一度に行うメソッド

df_imputed = imputer.fit_transform(df_missing)

print(“\n中央値で補完したデータ:”)
print(pd.DataFrame(df_imputed, columns=df_missing.columns))
“`

出力例:

“`
欠損値を含むデータ:
col1 col2 col3
0 1.0 NaN 1.0
1 2.0 2.0 2.0
2 NaN 3.0 3.0
3 4.0 4.0 4.0
4 5.0 5.0 NaN

中央値で補完したデータ:
col1 col2 col3
0 1.0 3.5 1.0
1 2.0 2.0 2.0
2 3.5 3.0 3.0
3 4.0 4.0 4.0
4 5.0 5.0 3.0
“`

カテゴリカルデータの処理 (Handling Categorical Data)

性別(男性/女性)、都市名(東京/大阪/名古屋)、商品カテゴリ(電化製品/衣料品/食品)のようなカテゴリカルデータは、多くの機械学習アルゴリズムが直接扱うことができません。これらを数値表現に変換する必要があります。

主な方法:

  1. 順序エンコーディング (Ordinal Encoding): カテゴリに順序関係がある場合に使用します(例:S/M/Lを0/1/2に変換)。
  2. One-Hotエンコーディング: カテゴリに順序関係がない場合に使用します。各カテゴリを独立したバイナリ(0または1)の特徴量に変換します。これにより、アルゴリズムがカテゴリ間の大小関係を誤って学習するのを防ぎます。

Scikit-learnの preprocessing モジュールにある OrdinalEncoderOneHotEncoder が使えます。Pandasの get_dummies 関数もOne-Hotエンコーディングによく使われます。

“`python
from sklearn.preprocessing import OrdinalEncoder, OneHotEncoder
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline

サンプルデータ(カテゴリカルデータを含む)

data = {‘color’: [‘Red’, ‘Blue’, ‘Green’, ‘Red’, ‘Blue’],
‘size’: [‘S’, ‘M’, ‘L’, ‘S’, ‘M’],
‘value’: [10, 20, 30, 15, 25]}
df_categorical = pd.DataFrame(data)
print(“カテゴリカルデータを含むデータ:”)
print(df_categorical)

Ordinal Encoding (size列に適用、順序を仮定)

size_order = [[‘S’, ‘M’, ‘L’]] # カテゴリの順序を指定
ordinal_encoder = OrdinalEncoder(categories=size_order)
df_categorical[‘size_encoded’] = ordinal_encoder.fit_transform(df_categorical[[‘size’]])
print(“\nOrdinal Encoding後:”)
print(df_categorical)

One-Hot Encoding (color列に適用)

ColumnTransformerを使うと複数の列に異なる前処理を同時に適用できて便利

ct = ColumnTransformer(
[(‘onehot’, OneHotEncoder(), [‘color’])],
remainder=’passthrough’ # 指定した列以外はそのまま残す
)

fit_transform()は結果をNumPy配列で返す

df_onehot = ct.fit_transform(df_categorical)

結果をデータフレームに戻す(列名に注意)

OneHotEncoderのget_feature_names_out()で新しい列名を取得できる

feature_names_out = ct.get_feature_names_out()
df_onehot = pd.DataFrame(df_onehot, columns=feature_names_out)

print(“\nOne-Hot Encoding後:”)
print(df_onehot)
“`

出力例:

“`
カテゴリカルデータを含むデータ:
color size value
0 Red S 10
1 Blue M 20
2 Green L 30
3 Red S 15
4 Blue M 25

Ordinal Encoding後:
color size value size_encoded
0 Red S 10 0.0
1 Blue M 20 1.0
2 Green L 30 2.0
3 Red S 15 0.0
4 Blue M 25 1.0

One-Hot Encoding後:
onehot__color_Blue onehot__color_Green onehot__color_Red value size_encoded
0 0.0 0.0 1.0 10.0 0.0
1 1.0 0.0 0.0 20.0 1.0
2 0.0 1.0 0.0 30.0 2.0
3 0.0 0.0 1.0 15.0 0.0
4 1.0 0.0 0.0 25.0 1.0
``
One-Hotエンコーディングでは、
color列がonehot__color_Blue,onehot__color_Green,onehot__color_Red`の3つの列に分割され、対応するカテゴリに1、それ以外に0が入っています。

特徴量のスケーリング (Feature Scaling)

多くの機械学習アルゴリズム(特に距離ベースのもの、例:K近傍法、サポートベクターマシン、クラスタリングなど)は、特徴量のスケール(値の範囲)に敏感です。例えば、年齢(0-100)と年収(100万円-1億円)のようにスケールが大きく異なる特徴量があると、年収の方がモデルに与える影響が不均衡に大きくなってしまう可能性があります。

特徴量のスケールを揃えるための主な手法:

  1. 標準化 (Standardization / Z-score normalization): データの平均が0、標準偏差が1になるように変換します。外れ値の影響を受けにくいです。
    $$ x’ = \frac{x – \mu}{\sigma} $$
    ($\mu$: 平均、$\sigma$: 標準偏差)

  2. 正規化 (Normalization / Min-Max scaling): データを特定の範囲(通常は0から1)にスケーリングします。
    $$ x’ = \frac{x – x_{\min}}{x_{\max} – x_{\min}} $$
    ($x_{\min}$: 最小値、$x_{\max}$: 最大値)

Scikit-learnの preprocessing モジュールにある StandardScalerMinMaxScaler を使います。

“`python
from sklearn.preprocessing import StandardScaler, MinMaxScaler

サンプルデータ(スケールが異なる)

data = {‘feature1’: [10, 20, 30, 40, 50],
‘feature2’: [0.1, 0.2, 0.3, 0.4, 0.5],
‘feature3’: [1000, 2000, 3000, 4000, 5000]}
df_scale = pd.DataFrame(data)
print(“スケーリング前のデータ:”)
print(df_scale)

標準化 (StandardScaler)

scaler_std = StandardScaler()
df_scaled_std = scaler_std.fit_transform(df_scale)
print(“\n標準化後のデータ:”)
print(pd.DataFrame(df_scaled_std, columns=df_scale.columns))

正規化 (MinMaxScaler, 0-1の範囲)

scaler_minmax = MinMaxScaler()
df_scaled_minmax = scaler_minmax.fit_transform(df_scale)
print(“\n正規化後のデータ:”)
print(pd.DataFrame(df_scaled_minmax, columns=df_scale.columns))
“`

出力例:

“`
スケーリング前のデータ:
feature1 feature2 feature3
0 10 0.1 1000
1 20 0.2 2000
2 30 0.3 3000
3 40 0.4 4000
4 50 0.5 5000

標準化後のデータ:
feature1 feature2 feature3
0 -1.4 -1.4 -1.4
1 -0.7 -0.7 -0.7
2 0.0 0.0 0.0
3 0.7 0.7 0.7
4 1.4 1.4 1.4

正規化後のデータ:
feature1 feature2 feature3
0 0.0 0.0 0.0
1 0.2 0.2 0.2
2 0.5 0.5 0.5
3 0.8 0.8 0.8
4 1.0 1.0 1.0
“`
標準化後のデータは平均がほぼ0、標準偏差がほぼ1になっています。正規化後のデータは0から1の範囲に収まっています。

データの分割 (Splitting Data)

モデルを評価する際に、訓練に使ったデータと同じデータで評価すると、モデルが未知のデータに対してどれだけうまく機能するかを正しく測ることができません。モデルが訓練データに過剰に適合しすぎて、汎化能力(新しいデータに対する予測能力)が低い状態、いわゆる「過学習 (Overfitting)」を見逃してしまいます。

これを防ぐために、データセットを訓練データ (Training Data) とテストデータ (Test Data) に分割するのが一般的です。
* 訓練データ: モデルの学習に使用します。
* テストデータ: 学習済みのモデルが未知のデータに対してどれだけうまく機能するかを評価するために使用します。テストデータは学習プロセスでは一切使用しません。

Scikit-learnの model_selection モジュールにある train_test_split 関数を使います。

“`python
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris

Irisデータセットを使用

iris = load_iris()
X = iris.data # 特徴量
y = iris.target # 目的変数 (ラベル)

データを訓練用とテスト用に分割

test_size: テストデータの割合 (0.2なら20%)

random_state: 結果を再現可能にするためのシード値。任意の整数を指定。

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

print(“元のデータ数:”, len(X))
print(“訓練データ数:”, len(X_train))
print(“テストデータ数:”, len(X_test))
print(“訓練データの形状:”, X_train.shape)
print(“テストデータの形状:”, X_test.shape)
“`

出力例:

元のデータ数: 150
訓練データ数: 120
テストデータ数: 30
訓練データの形状: (120, 4)
テストデータの形状: (30, 4)

データが指定した割合で分割されていることがわかります。特徴量と目的変数の両方を同じインデックスで分割することが重要です。train_test_split はそれを自動的に行ってくれます。

これで、機械学習モデルを構築するためのデータの準備が整いました。

Scikit-learnを使った最初の機械学習モデル

準備ができたデータを使って、実際に機械学習モデルを構築してみましょう。まずは教師あり学習のタスクである分類と回帰に挑戦します。

Scikit-learnを使ったモデル構築の一般的な流れは以下の通りです。

  1. モデルの選択: 解きたい問題(分類か回帰か、データの性質など)に適したアルゴリズムを選択します。
  2. モデルのインスタンス化: 選択したモデルのクラスからインスタンスを作成します。このとき、モデルのハイパーパラメータ(学習プロセス中にデータから自動的に決定されるパラメータとは異なり、学習前に人間が設定するパラメータ)を設定できます。
  3. モデルの学習: 訓練データ (X_train, y_train) を使ってモデルを学習させます。fit(X_train, y_train) メソッドを使用します。
  4. 予測: 学習済みモデルを使って、新しいデータ (X_test) の予測を行います。predict(X_test) メソッドを使用します。
  5. 評価: 予測結果 (predict(X_test)) とテストデータの実際の値 (y_test) を比較して、モデルの性能を評価します。

教師あり学習:分類 (Classification)

分類問題の例として、先ほども使ったIrisデータセットを使用します。このデータセットは、アヤメの種類(setosa, versicolor, virginicaの3クラス)を、萼片(sepal)と花弁(petal)の長さ・幅の4つの特徴量から予測するタスクです。これは多クラス分類問題です。

ここでは、シンプルな線形モデルであるロジスティック回帰 (Logistic Regression) を使ってみましょう。ロジスティック回帰は名前に「回帰」とつきますが、分類問題に用いられるアルゴリズムです。

“`python
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris
from sklearn.metrics import accuracy_score

データの準備(再度分割)

iris = load_iris()
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)

1. モデルの選択: LogisticRegression

model = LogisticRegression(max_iter=200) # デフォルトのイテレーション回数では収束しない場合があるため増やしています

2. モデルの学習

fitメソッドに訓練データの特徴量とラベルを渡して学習させます

print(“モデルの学習中…”)
model.fit(X_train, y_train)
print(“学習完了。”)

3. 予測

predictメソッドにテストデータの特徴量を渡して予測を行います

y_pred = model.predict(X_test)

予測結果の確認 (最初の10個)

print(“\n実際のラベル (テストデータ先頭10個):”, y_test[:10])
print(“予測ラベル (テストデータ先頭10個): “, y_pred[:10])

4. 評価

分類問題の一般的な評価指標として正解率(Accuracy)があります

正解率: (正しく予測できたデータ数) / (全データ数)

accuracy = accuracy_score(y_test, y_pred)
print(f”\nモデルの正解率: {accuracy:.2f}”)
“`

出力例:

“`
モデルの学習中…
学習完了。

実際のラベル (テストデータ先頭10個): [1 0 2 1 2 0 1 2 1 1]
予測ラベル (テストデータ先頭10個): [1 0 2 1 2 0 1 2 1 1]

モデルの正解率: 1.00
“`
この例では、テストデータ全てを正しく分類できたため、正解率が1.00(100%)となっています。Irisデータセットは比較的単純で、ロジスティック回帰でも高い精度が出やすいデータセットです。

教師あり学習:回帰 (Regression)

回帰問題の例として、Scikit-learnに付属しているDiabetesデータセットを使用します。このデータセットは、10個の特徴量(年齢、性別、BMI、血圧など)から、糖尿病患者の1年後の疾患進行度を予測するタスクです。疾患進行度は連続的な数値です。

ここでは、最も基本的な回帰モデルである線形回帰 (Linear Regression) を使ってみましょう。線形回帰は、目的変数と特徴量の間に線形な関係を仮定するモデルです。

“`python
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_diabetes
from sklearn.metrics import mean_squared_error, r2_score

データの準備

diabetes = load_diabetes()
X = diabetes.data # 特徴量
y = diabetes.target # 目的変数 (疾患進行度)

データを訓練用とテスト用に分割

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

1. モデルの選択: LinearRegression

model = LinearRegression()

2. モデルの学習

print(“モデルの学習中…”)
model.fit(X_train, y_train)
print(“学習完了。”)

学習したモデルの係数と切片を表示

print(f”\n係数 (Coefficients): {model.coef_}”)
print(f”切片 (Intercept): {model.intercept_:.2f}”)

3. 予測

predictメソッドにテストデータの特徴量を渡して予測を行います

y_pred = model.predict(X_test)

予測結果の確認 (最初の10個)

print(“\n実際の値 (テストデータ先頭10個):”, y_test[:10])
print(“予測値 (テストデータ先頭10個): “, y_pred[:10].round(2)) # 小数点以下2桁で表示

4. 評価

回帰問題の一般的な評価指標として平均二乗誤差(Mean Squared Error, MSE)や決定係数(R^2スコア)があります

MSE: 予測値と実際値の差の二乗の平均。値が小さいほど良い。

R^2スコア: モデルが目的変数の分散をどれだけ説明できているかを表す指標。0から1の範囲で、1に近いほど良い。

mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)

print(f”\n平均二乗誤差 (MSE): {mse:.2f}”)
print(f”決定係数 (R^2スコア): {r2:.2f}”)
“`

出力例:

“`
モデルの学習中…
学習完了。

係数 (Coefficients): [ -10.01… 24.84] # 長いので省略
切片 (Intercept): 152.76

実際の値 (テストデータ先頭10個): [151. 75. 141. 206. 135. 97. 138. 67. 49. 168.]
予測値 (テストデータ先頭10個): [149.91 97.18 133.95 197.32 122.23 98.45 142.59 113.47 97.63 158.77]

平均二乗誤差 (MSE): 2900.19
決定係数 (R^2スコア): 0.46
“`
MSEの値自体はデータのスケールに依存するため、他のモデルとの比較などで意味を持ちます。R^2スコアは0.46で、このモデルが疾患進行度の分散の46%程度を説明できていることを示しています。これは必ずしも非常に高い値ではありませんが、線形回帰というシンプルなモデルとしては妥当な結果かもしれません。

これらの例から、Scikit-learnを使えば、数ステップで機械学習モデルを構築し、評価できることがわかります。

他の主要な機械学習アルゴリズム

Scikit-learnには、ロジスティック回帰や線形回帰以外にも、多くの強力なアルゴリズムが実装されています。データや問題の性質によって、適切なアルゴリズムを選択することが重要です。ここでは、いくつかの代表的なアルゴリズムを紹介し、Scikit-learnでの基本的な使い方を示します。

分類アルゴリズム

  • K近傍法 (K-Nearest Neighbors, KNN): 新しいデータ点が、訓練データの中で最も近いK個のデータ点のうち、多数を占めるクラスに分類されます。直感的で理解しやすいですが、データ量が増えると計算コストが高くなる傾向があります。sklearn.neighbors.KNeighborsClassifier を使用します。

“`python
from sklearn.neighbors import KNeighborsClassifier

K近傍法モデル (K=3に設定)

knn = KNeighborsClassifier(n_neighbors=3)

学習

knn.fit(X_train, y_train)

予測

y_pred_knn = knn.predict(X_test)

評価

accuracy_knn = accuracy_score(y_test, y_pred_knn)
print(f”KNN (K=3) モデルの正解率: {accuracy_knn:.2f}”)
“`

  • サポートベクターマシン (Support Vector Machine, SVM): データを異なるクラスに分離する最適な境界(超平面)を見つけようとします。線形だけでなく、カーネルトリックを使って非線形な境界も見つけることができます。分類問題には sklearn.svm.SVC を使用します。

“`python
from sklearn.svm import SVC

サポートベクター分類器 (カーネルとしてRBFを使用)

svc = SVC(gamma=’auto’)

学習

svc.fit(X_train, y_train)

予測

y_pred_svc = svc.predict(X_test)

評価

accuracy_svc = accuracy_score(y_test, y_pred_svc)
print(f”SVM モデルの正解率: {accuracy_svc:.2f}”)
“`

  • 決定木 (Decision Tree): データを特定のルールに基づいて枝分かれさせていき、最終的にクラスを決定する木構造のモデルです。解釈が容易なのが特徴ですが、過学習しやすい傾向があります。sklearn.tree.DecisionTreeClassifier を使用します。

“`python
from sklearn.tree import DecisionTreeClassifier

決定木モデル

dtc = DecisionTreeClassifier(random_state=42)

学習

dtc.fit(X_train, y_train)

予測

y_pred_dtc = dtc.predict(X_test)

評価

accuracy_dtc = accuracy_score(y_test, y_pred_dtc)
print(f”決定木 モデルの正解率: {accuracy_dtc:.2f}”)
“`

  • ランダムフォレスト (Random Forest): 複数の決定木を組み合わせて予測を行うアンサンブル学習手法です。各決定木が少しずつ異なるデータや特徴量を使って学習し、その結果を多数決などで統合することで、決定木単体よりも高い精度と汎化能力を実現します。sklearn.ensemble.RandomForestClassifier を使用します。

“`python
from sklearn.ensemble import RandomForestClassifier

ランダムフォレストモデル (決定木の数 n_estimators=100 に設定)

rfc = RandomForestClassifier(n_estimators=100, random_state=42)

学習

rfc.fit(X_train, y_train)

予測

y_pred_rfc = rfc.predict(X_test)

評価

accuracy_rfc = accuracy_score(y_test, y_pred_rfc)
print(f”ランダムフォレスト モデルの正解率: {accuracy_rfc:.2f}”)
“`

回帰アルゴリズム

  • K近傍法 (KNN Regressor): 新しいデータ点の目的変数を、最も近いK個のデータ点の目的変数の平均値などで予測します。sklearn.neighbors.KNeighborsRegressor を使用します。

“`python
from sklearn.neighbors import KNeighborsRegressor

K近傍回帰モデル (K=3に設定)

knr = KNeighborsRegressor(n_neighbors=3)

学習 (Diabetesデータセットを使用)

knr.fit(X_train, y_train)

予測

y_pred_knr = knr.predict(X_test)

評価

mse_knr = mean_squared_error(y_test, y_pred_knr)
r2_knr = r2_score(y_test, y_pred_knr)
print(f”KNN (K=3) 回帰モデルの MSE: {mse_knr:.2f}, R^2: {r2_knr:.2f}”)
“`

  • サポートベクター回帰 (Support Vector Regression, SVR): SVMを回帰問題に応用したモデルです。目的変数から一定のマージン内に収まるように超平面を見つけます。sklearn.svm.SVR を使用します。

“`python
from sklearn.svm import SVR

サポートベクター回帰モデル

svr = SVR(gamma=’auto’)

学習

svr.fit(X_train, y_train)

予測

y_pred_svr = svr.predict(X_test)

評価

mse_svr = mean_squared_error(y_test, y_pred_svr)
r2_svr = r2_score(y_test, y_pred_svr)
print(f”SVR モデルの MSE: {mse_svr:.2f}, R^2: {r2_svr:.2f}”)
“`

  • 決定木回帰 (Decision Tree Regressor): 決定木を回帰問題に応用したモデルです。葉ノードに到達したデータの目的変数の平均値などで予測します。sklearn.tree.DecisionTreeRegressor を使用します。

“`python
from sklearn.tree import DecisionTreeRegressor

決定木回帰モデル

dtr = DecisionTreeRegressor(random_state=42)

学習

dtr.fit(X_train, y_train)

予測

y_pred_dtr = dtr.predict(X_test)

評価

mse_dtr = mean_squared_error(y_test, y_pred_dtr)
r2_dtr = r2_score(y_test, y_pred_dtr)
print(f”決定木回帰 モデルの MSE: {mse_dtr:.2f}, R^2: {r2_dtr:.2f}”)
“`

  • ランダムフォレスト回帰 (Random Forest Regressor): ランダムフォレストを回帰問題に応用したモデルです。各決定木回帰器の予測値の平均値などを最終的な予測値とします。sklearn.ensemble.RandomForestRegressor を使用します。

“`python
from sklearn.ensemble import RandomForestRegressor

ランダムフォレスト回帰モデル

rfr = RandomForestRegressor(n_estimators=100, random_state=42)

学習

rfr.fit(X_train, y_train)

予測

y_pred_rfr = rfr.predict(X_test)

評価

mse_rfr = mean_squared_error(y_test, y_pred_rfr)
r2_rfr = r2_score(y_test, y_pred_rfr)
print(f”ランダムフォレスト回帰 モデルの MSE: {mse_rfr:.2f}, R^2: {r2_rfr:.2f}”)
“`

教師なし学習アルゴリズム

  • K平均法 (K-Means): データセットを、あらかじめ指定したK個のクラスターに分割するクラスタリングアルゴリズムです。各データ点を、最も近いクラスターの中心(セントロイド)に割り当て、セントロイドを更新することを繰り返します。sklearn.cluster.KMeans を使用します。

“`python
from sklearn.cluster import KMeans
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt # クラスタリング結果の可視化にMatplotlibを使用

Irisデータセットを使用 (ここではラベルは使用せず特徴量のみ)

iris = load_iris()
X = iris.data

K-Meansモデル (クラスター数 K=3に設定)

kmeans = KMeans(n_clusters=3, random_state=42, n_init=10) # n_initは非推奨になるため指定推奨

学習(クラスター中心を見つける)

kmeans.fit(X)

各データ点が属するクラスターラベルを取得

labels = kmeans.labels_

結果の確認(最初の10個のデータ点のクラスター)

print(“最初の10個のデータ点のクラスターラベル:”, labels[:10])

クラスター中心の確認

print(“\nクラスター中心:\n”, kmeans.cluster_centers_)

結果の可視化 (最初の2つの特徴量を使用)

Irisデータセットの本来のラベルと比較してみる

plt.figure(figsize=(10, 5))

plt.subplot(1, 2, 1)
plt.scatter(X[:, 0], X[:, 1], c=labels, cmap=’viridis’)
plt.title(‘K-Means Clustering (Feature 0 vs Feature 1)’)
plt.xlabel(iris.feature_names[0])
plt.ylabel(iris.feature_names[1])

plt.subplot(1, 2, 2)
plt.scatter(X[:, 0], X[:, 1], c=iris.target, cmap=’viridis’)
plt.title(‘Original Iris Labels (Feature 0 vs Feature 1)’)
plt.xlabel(iris.feature_names[0])
plt.ylabel(iris.feature_names[1])

plt.tight_layout()
plt.show()
“`

  • 主成分分析 (Principal Component Analysis, PCA): データの分散が最大になるような新しい軸(主成分)を見つけることで、データの次元を削減する手法です。データの情報をできるだけ失わずに、より少ない特徴量でデータを表現できるようになります。データの可視化によく使われます。sklearn.decomposition.PCA を使用します。

“`python
from sklearn.decomposition import PCA
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt

Irisデータセットを使用

iris = load_iris()
X = iris.data
y = iris.target # 可視化のために元のラベルも使用

PCAモデル (2つの主成分に次元削減)

pca = PCA(n_components=2)

fit_transform()で学習と変換を同時に行う

X_pca = pca.fit_transform(X)

変換後のデータの形状

print(“PCA変換後のデータの形状:”, X_pca.shape)

寄与率(各主成分が元のデータの分散をどれだけ説明できているか)

print(“各主成分の寄与率:”, pca.explained_variance_ratio_)
print(“累積寄与率:”, pca.explained_variance_ratio_.sum())

結果の可視化

plt.figure(figsize=(8, 6))
scatter = plt.scatter(X_pca[:, 0], X_pca[:, 1], c=y, cmap=’viridis’)
plt.title(‘PCA of Iris dataset (2 components)’)
plt.xlabel(‘Principal Component 1’)
plt.ylabel(‘Principal Component 2’)

凡例の追加

legend1 = plt.legend(*scatter.legend_elements(),
loc=”lower left”, title=”Classes”)
plt.add_artist(legend1)

plt.show()
“`
PCAの結果、元の4次元データが2次元に圧縮され、散布図として可視化できました。この図から、アヤメの3つの種類が2次元空間でかなりきれいに分離されていることがわかります。

これらはScikit-learnで利用できる多くのアルゴリズムのごく一部です。Scikit-learnのドキュメントを参考に、様々なアルゴリズムを試してみてください。

モデルの評価と改善

モデルを構築するだけでなく、その性能を適切に評価し、必要であれば改善していくことが機械学習プロジェクトにおいて非常に重要です。

交差検証 (Cross-Validation)

train_test_split でデータを一度だけ分割して評価する方法はシンプルですが、分割の仕方によって評価結果が大きく変動する可能性があります。特にデータ量が少ない場合に不安定になりやすいです。

より信頼性の高い評価を行うために、交差検証 (Cross-Validation) がよく用いられます。K-分割交差検証 (K-Fold Cross-Validation) では、データセットをK個の同じサイズのサブセットに分割し、K回の異なる訓練/評価を行います。各回で異なるサブセットをテストデータとして使用し、残りのK-1個のサブセットを訓練データとして使用します。最終的な評価は、K回の評価結果の平均値などを利用します。

Scikit-learnでは model_selection モジュールの cross_val_score 関数を使うと簡単に実行できます。

“`python
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_iris

データの準備

iris = load_iris()
X = iris.data
y = iris.target

ロジスティック回帰モデル

model = LogisticRegression(max_iter=200)

K-分割交差検証の実行 (K=5)

cv=5 は5分割クロスバリデーションを指定

scores = cross_val_score(model, X, y, cv=5)

print(“各分割での正解率:”, scores)
print(f”交差検証の平均正解率: {scores.mean():.2f}”)
print(f”交差検証の正解率の標準偏差: {scores.std():.2f}”)
“`

出力例:

各分割での正解率: [1. 0.96666667 0.93333333 0.93333333 1. ]
交差検証の平均正解率: 0.97
交差検証の正解率の標準偏差: 0.03

5回の訓練/評価の結果、それぞれで異なる正解率が得られています。これらの平均値(0.97)と標準偏差(0.03)が、モデルの一般的な性能と安定性を示す指標となります。train_test_split による一度の評価よりも、この平均値の方がより信頼性の高いモデル性能の推定値と考えられます。

分類モデルの詳細な評価指標

正解率 (Accuracy) は直感的で分かりやすい指標ですが、特にクラス間のデータ数に偏りがある場合(不均衡データ)、正解率だけではモデルの性能を十分に評価できません。例えば、全データの95%があるクラスに属している場合、常にそのクラスを予測するだけのモデルでも正解率95%を達成できてしまいます。

より詳細な評価のために、以下の指標がよく使われます。これらは通常、混同行列 (Confusion Matrix) を基に計算されます。

  • 混同行列 (Confusion Matrix): 実際のクラスと予測されたクラスの組み合わせを行列形式でまとめたものです。

    • True Positive (TP): 実際も予測も陽性
    • True Negative (TN): 実際も予測も陰性
    • False Positive (FP): 実際は陰性だが予測は陽性(第一種過誤、False Alarm)
    • False Negative (FN): 実際は陽性だが予測は陰性(第二種過誤、Miss)
  • 適合率 (Precision): 陽性と予測されたもののうち、実際に陽性だった割合。 FPをどれだけ少なくできたか。
    $$ \text{Precision} = \frac{TP}{TP + FP} $$

  • 再現率 (Recall / Sensitivity): 実際に陽性だったもののうち、陽性と予測できた割合。FNをどれだけ少なくできたか。
    $$ \text{Recall} = \frac{TP}{TP + FN} $$

  • F1スコア (F1-score): PrecisionとRecallの調和平均。PrecisionとRecallの両方をバランス良く達成しているかを示す指標。
    $$ \text{F1-score} = 2 \times \frac{\text{Precision} \times \text{Recall}}{\text{Precision} + \text{Recall}} $$

  • ROC曲線 (Receiver Operating Characteristic Curve) と AUC (Area Under the Curve): ROC曲線は、様々な閾値における真陽性率 (True Positive Rate = Recall) と偽陽性率 (False Positive Rate = FP / (FP + TN)) の関係を描いた曲線です。AUCはROC曲線の下の面積であり、モデルがランダムな予測よりもどれだけ優れているかを示す指標です。1に近いほど良いモデルです。

Scikit-learnでは metrics モジュールでこれらの指標を計算できます。

“`python
from sklearn.metrics import confusion_matrix, classification_report, roc_curve, auc
import matplotlib.pyplot as plt

ロジスティック回帰モデルで予測 (Irisデータセットを使用)

model = LogisticRegression(max_iter=200)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)

混同行列

cm = confusion_matrix(y_test, y_pred)
print(“混同行列:\n”, cm)

Classification Report (Precision, Recall, F1-scoreなどをまとめて表示)

target_namesを指定するとクラス名が表示される

print(“\nClassification Report:\n”, classification_report(y_test, y_pred, target_names=iris.target_names))

ROC曲線とAUC (バイナリ分類の場合)

Irisは多クラス分類なので、特定のクラス対他のクラスという形で計算する

例: クラス0 (setosa) vs その他

y_test_binary = (y_test == 0).astype(int)
y_pred_proba = model.predict_proba(X_test)[:, 0] # クラス0である確率

fpr, tpr, thresholds = roc_curve(y_test_binary, y_pred_proba)
roc_auc = auc(fpr, tpr)

plt.figure()
plt.plot(fpr, tpr, color=’darkorange’, lw=2, label=f’ROC curve (area = {roc_auc:.2f})’)
plt.plot([0, 1], [0, 1], color=’navy’, lw=2, linestyle=’–‘)
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel(‘False Positive Rate’)
plt.ylabel(‘True Positive Rate’)
plt.title(‘Receiver Operating Characteristic (ROC) Curve (Class 0 vs Others)’)
plt.legend(loc=”lower right”)
plt.show()
“`
Classification Reportを見ると、各クラスごとのPrecision, Recall, F1-scoreが確認できます。Irisデータセットではクラス間のデータ数に偏りがなく、かつモデル性能も高いため、各クラスで高い値が出ています。不均衡データの場合は、PrecisionとRecallの値が大きく異なることがあります。

ROC曲線とAUCはバイナリ分類の評価に特に有効です。AUCの値が高いほど、モデルが陽性クラスと陰性クラスを区別する能力が高いことを示します。

回帰モデルの詳細な評価指標

回帰モデルの評価には、MSE以外にもいくつか指標があります。

  • 平均絶対誤差 (Mean Absolute Error, MAE): 予測値と実際値の差の絶対値の平均。外れ値の影響を受けにくいです。
    $$ MAE = \frac{1}{n} \sum_{i=1}^n |y_i – \hat{y}_i| $$
  • 平方根平均二乗誤差 (Root Mean Squared Error, RMSE): MSEの平方根。MSEと同じく外れ値に敏感ですが、目的変数と同じ単位になるため解釈しやすいです。
    $$ RMSE = \sqrt{\frac{1}{n} \sum_{i=1}^n (y_i – \hat{y}_i)^2} = \sqrt{MSE} $$

Scikit-learnでは mean_absolute_error, mean_squared_error (MSE), r2_score などが利用できます。RMSEは mean_squared_error の結果の平方根を取ることで計算できます。

“`python
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
import numpy as np # RMSE計算に使う

線形回帰モデルで予測 (Diabetesデータセットを使用)

model = LinearRegression()
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # X, yはDiabetesデータセット
model.fit(X_train, y_train)
y_pred = model.predict(X_test)

評価指標の計算

mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
mae = mean_absolute_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)

print(f”平均絶対誤差 (MAE): {mae:.2f}”)
print(f”平均二乗誤差 (MSE): {mse:.2f}”)
print(f”平方根平均二乗誤差 (RMSE): {rmse:.2f}”)
print(f”決定係数 (R^2スコア): {r2:.2f}”)
“`

ハイパーパラメータチューニング (Hyperparameter Tuning)

ほとんどの機械学習モデルには、学習プロセスでは自動的に決定されない「ハイパーパラメータ」があります。例えば、KNNの近傍数K、SVMのCやgamma、ランダムフォレストの決定木の数 (n_estimators) や深さなどです。これらのハイパーパラメータの値によって、モデルの性能は大きく変わることがあります。

モデルの性能を最適化するためには、適切なハイパーパラメータの値を見つける必要があります。このプロセスをハイパーパラメータチューニングと呼びます。

代表的なチューニング手法:

  1. グリッドサーチ (Grid Search): 試したいハイパーパラメータの候補値をいくつか指定し、それらの組み合わせ全てを試して、交差検証で最も性能が良かった組み合わせを選択します。

    • sklearn.model_selection.GridSearchCV を使用します。
  2. ランダムサーチ (Random Search): 試したいハイパーパラメータの範囲を指定し、その範囲内からランダムにいくつかの組み合わせを選んで試します。グリッドサーチよりも効率的に良い組み合わせを見つけられる場合があります。

    • sklearn.model_selection.RandomizedSearchCV を使用します。

以下はグリッドサーチの例です。

“`python
from sklearn.model_selection import GridSearchCV
from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import load_iris

データの準備

iris = load_iris()
X = iris.data
y = iris.target

KNNモデル

knn = KNeighborsClassifier()

チューニングしたいハイパーパラメータとその候補値のリストを含む辞書

n_neighbors: 近傍数

weights: ‘uniform’ (一様重み) or ‘distance’ (距離による重み)

param_grid = {‘n_neighbors’: [3, 5, 7, 9, 11],
‘weights’: [‘uniform’, ‘distance’]}

グリッドサーチの実行

estimator: チューニング対象のモデル

param_grid: チューニングするハイパーパラメータと候補値

cv: 交差検証の分割数

scoring: 評価指標 (デフォルトはモデルによる。分類なら正解率)

grid_search = GridSearchCV(estimator=knn, param_grid=param_grid, cv=5, scoring=’accuracy’)

グリッドサーチを実行 (最適なハイパーパラメータを見つけるために訓練データ全体を使用することが多い)

print(“グリッドサーチ実行中…”)
grid_search.fit(X, y)
print(“グリッドサーチ完了。”)

最も良かったスコアとハイパーパラメータの組み合わせを表示

print(f”最も良かった交差検証スコア: {grid_search.best_score_:.2f}”)
print(“最適なハイパーパラメータ:”, grid_search.best_params_)

最適なハイパーパラメータを持つモデルを取得

best_model = grid_search.best_estimator_

テストデータでの最終評価 (もしテストデータが分離されているなら)

通常はgrid_search.fitに訓練データのみを渡し、最後にbest_modelでテストデータを予測・評価する

例:

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

grid_search.fit(X_train, y_train)

best_model = grid_search.best_estimator_

y_pred_best = best_model.predict(X_test)

print(f”テストデータでの正解率: {accuracy_score(y_test, y_pred_best):.2f}”)

“`

グリッドサーチは、指定した全ての組み合わせを総当たりで試すため、ハイパーパラメータの候補値が多い場合やデータセットが大きい場合に計算コストが非常に高くなる可能性があります。そのような場合はランダムサーチが有効な選択肢となります。

パイプライン (Pipeline)

機械学習のワークフローでは、前処理(欠損値補完、スケーリング、エンコーディングなど)とモデル学習は連続して行われる一連のステップです。これらのステップをまとめて管理するために、Scikit-learnの pipeline モジュールにある Pipeline が便利です。

パイプラインを使う主な利点:

  • コードの簡潔化: 複数の前処理ステップとモデルを一つにまとめることができます。
  • リーク防止: 交差検証やグリッドサーチを行う際に、訓練データで学習した前処理のパラメータ(平均値、最小最大値など)がテストデータに「リーク」してしまうのを防ぎます。Pipeline は、各分割の訓練データで前処理器の fittransform を行い、その訓練データでモデルの fit を行い、同じ前処理器でテストデータを transform してからモデルの predict を行うという正しい手順を自動で行ってくれます。

以下は PipelineGridSearchCV を組み合わせた例です。

“`python
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.model_selection import GridSearchCV
from sklearn.datasets import load_iris

データの準備

iris = load_iris()
X = iris.data
y = iris.target

パイプラインの作成

ステップのリストを渡す。各ステップは (‘ステップ名’, インスタンス) のタプル

例: 標準化 -> SVM

pipeline = Pipeline([
(‘scaler’, StandardScaler()), # 標準化
(‘svc’, SVC()) # SVM分類器
])

チューニングしたいハイパーパラメータとその候補値

パイプライン内のステップのハイパーパラメータを指定する場合は、

‘ステップ名__ハイパーパラメータ名’ の形式で記述します

param_grid = {
‘svc__C’: [0.1, 1, 10, 100],
‘svc__gamma’: [‘scale’, ‘auto’, 0.1, 1]
}

パイプラインを使ってグリッドサーチを実行

grid_search_pipeline = GridSearchCV(pipeline, param_grid, cv=5, scoring=’accuracy’)

学習(グリッドサーチとパイプラインの実行)

print(“パイプラインを使ったグリッドサーチ実行中…”)
grid_search_pipeline.fit(X, y)
print(“完了。”)

最適なスコアとハイパーパラメータ

print(f”最も良かった交差検証スコア: {grid_search_pipeline.best_score_:.2f}”)
print(“最適なハイパーパラメータ:”, grid_search_pipeline.best_params_)

最適なモデル(パイプライン)を取得

best_pipeline = grid_search_pipeline.best_estimator_

新しいデータに対する予測(前処理も含めて自動で行われる)

例: X_test の最初の10個の予測

y_pred_pipeline = best_pipeline.predict(X_test[:10])

print(“予測結果 (テストデータ先頭10個):”, y_pred_pipeline)

``
この例では、まずデータが
StandardScalerで標準化され、その標準化されたデータがSVC` に渡されて学習が行われます。グリッドサーチは、このパイプライン全体に対して交差検証を行いながら最適なハイパーパラメータの組み合わせを探索します。これにより、前処理とモデル学習が密接に連携した状態で最適な設定を見つけることができます。

実践的なヒントと次のステップ

これでScikit-learnを使った機械学習の基本的な流れを理解し、いくつかの主要なアルゴリズムの使い方を学びました。しかし、実際の機械学習プロジェクトは、これだけでは終わりません。さらにモデルの性能を高めたり、より複雑な問題に取り組んだりするためのヒントと、次に学ぶべきことについて触れておきましょう。

過学習 (Overfitting) と 未学習 (Underfitting)

モデルの性能評価において、過学習と未学習は重要な概念です。

  • 未学習 (Underfitting): モデルが訓練データのパターンを十分に捉えられていない状態です。訓練データに対してもテストデータに対しても性能が低いことが多いです。モデルが単純すぎる、特徴量が不足している、データのノイズが多すぎるなどが原因として考えられます。

    • 対策: より複雑なモデルを使う、特徴量を増やす、モデルのハイパーパラメータを調整して表現力を上げる。
  • 過学習 (Overfitting): モデルが訓練データのノイズや個々のデータ点に過剰に適合しすぎて、訓練データに対しては非常に高い性能を示すものの、未知のテストデータに対しては性能が著しく低下する状態です。モデルが複雑すぎる、訓練データが少なすぎる、データのノイズが多いなどが原因として考えられます。

    • 対策: 訓練データ数を増やす、特徴量を減らす(特徴量選択)、モデルを単純化する、正則化(Regularization)を適用する(多くのモデルのハイパーパラメータとして提供されている)、交差検証を活用する、アンサンブル学習を利用する。

訓練データでの評価とテストデータ(または交差検証)での評価結果を比較することで、過学習や未学習の兆候を掴むことができます。訓練スコアが高く、テストスコアが低い場合は過学習の可能性が高いです。

特徴量エンジニアリング (Feature Engineering)

生データをそのままモデルに入力するのではなく、新しい特徴量を作成したり、既存の特徴量を変換したりすることで、モデルの性能が劇的に向上することがあります。これを特徴量エンジニアリングと呼びます。

例えば、日付データから「曜日」や「祝日かどうか」といった特徴量を作成したり、複数の特徴量を組み合わせて新しい特徴量を作成したりします。これはドメイン知識(解決したい問題に関する専門知識)が非常に重要になる作業です。Scikit-learn自体に直接的な特徴量エンジニアリングのツールは多くありませんが、Pandasなどを使ってデータ操作を行い、新しい特徴量を作成します。

大規模データセットへの対応

Scikit-learnは中規模程度のデータセットには非常に適していますが、数億件、数十億件といった大規模データセットを扱う場合にはメモリや計算速度の限界に達することがあります。

大規模データセットを扱う場合は、以下のような選択肢があります。

  • データの一部をサンプリングしてScikit-learnで試す。
  • データを分割して処理する。
  • 大規模データセットに特化したライブラリやフレームワークを使用する:
    • Apache Spark (PySpark)
    • Dask
    • より分散処理やGPUに最適化された深層学習フレームワーク(TensorFlow, PyTorchなど)

Scikit-learnは強力ですが、万能ではありません。データや問題の規模に応じて適切なツールを選択することが重要です。

機械学習プロジェクトの一般的なワークフロー

典型的な機械学習プロジェクトは以下のようなステップで進められます。

  1. 問題定義: 何を予測したいのか、どのようなデータがあるのか、成功の定義は何かなどを明確にする。
  2. データ収集: 必要なデータを集める。
  3. データ理解と探索 (Exploratory Data Analysis, EDA): データの概要を把握し、欠損値、外れ値、特徴量間の関係などを調査する。可視化が有効。
  4. データ前処理: 欠損値処理、エンコーディング、スケーリングなどを行う。
  5. 特徴量エンジニアリング: モデル性能向上のために新しい特徴量を作成する。
  6. モデル選択: 問題に適した機械学習アルゴリズムを選択する。
  7. モデル訓練: 訓練データを使ってモデルを学習させる。
  8. モデル評価: テストデータや交差検証を使ってモデルの性能を評価する。
  9. ハイパーパラメータチューニング: モデル性能を最適化するためにハイパーパラメータを調整する。
  10. デプロイメント: 学習済みのモデルを実際のシステムに組み込んで利用する。
  11. 監視と保守: デプロイ後のモデル性能を継続的に監視し、必要に応じて再学習や改善を行う。

この記事で学んだScikit-learnの機能は、主にステップ4から9を効率的に行うためのものです。

さらに学ぶためのリソース

機械学習の世界は広大で、この記事はほんの入口に過ぎません。さらに学びを深めるためには、以下のリソースが役立ちます。

  • Scikit-learn公式サイトのドキュメント: 最も正確で詳細な情報源です。各アルゴリズムやツールの使い方が網羅されています。(https://scikit-learn.org/stable/documentation.html)
  • 機械学習の専門書籍: 理論的な背景や様々なアルゴリズムについて体系的に学べます。「ゼロから作るDeep Learning」シリーズや、より数学的な内容を含む書籍など、レベルに合わせて選べます。
  • オンラインコース: Coursera, edX, Udacity, Kaggle Learn などで、実践的な機械学習コースが提供されています。
  • Kaggleなどのコンペティションプラットフォーム: 実際のデータセットを使って様々な問題を解くことで、実践的なスキルを磨けます。他の参加者のコードを見るのも非常に参考になります。
  • Qiita, Zennなどの技術ブログ: 最新の情報や具体的な実装例などが見つかります。
  • GitHub上の公開リポジトリ: 実際の機械学習プロジェクトのコードを読んで学ぶことができます。

重要なのは、実際に手を動かしてコードを書き、データを扱い、モデルを試してみることです。理論だけでなく、実践を通して理解を深めていきましょう。

まとめ

この記事では、Pythonと機械学習ライブラリScikit-learnを使って機械学習を始めるための詳細なステップを解説しました。

  • 機械学習の基本的な種類(教師あり学習、教師なし学習)とタスク(分類、回帰、クラスタリング、次元削減)について学びました。
  • 機械学習プロジェクトにおけるデータ前処理の重要性を理解し、欠損値処理、カテゴリカルデータ処理、特徴量スケーリング、データの分割といった基本的な手法をScikit-learnのツールを使って実践しました。
  • Scikit-learnを使ったモデル構築の一般的な流れ(選択、インスタンス化、学習、予測、評価)を、分類問題(ロジスティック回帰)と回帰問題(線形回帰)の例で示しました。
  • KNN、SVM、決定木、ランダムフォレスト、K-Means、PCAといった他の主要なアルゴリズムのScikit-learnでの基本的な使い方を紹介しました。
  • モデルの評価方法として、交差検証、分類の評価指標(混同行列、Precision, Recall, F1-score, ROC/AUC)、回帰の評価指標(MSE, RMSE, MAE, R^2)について詳しく解説しました。
  • モデル性能を改善するためのハイパーパラメータチューニング(グリッドサーチ)と、前処理とモデル学習をまとめるパイプラインの使い方を学びました。
  • 最後に、過学習/未学習、特徴量エンジニアリング、大規模データ対応、一般的な機械学習ワークフロー、そして今後の学習リソースについて触れました。

Scikit-learnは、機械学習アルゴリズムが非常に使いやすく統一的なインターフェースで提供されており、データの前処理からモデル評価まで、機械学習の主要なステップを効率的に行うことができます。機械学習の学習を始めるにあたって、これほど強力でアクセスしやすいライブラリはありません。

この記事を足がかりに、様々なデータセットやアルゴリズムを実際に試してみてください。機械学習は理論だけでなく、多くの実験と試行錯誤が伴う実践的な分野です。楽しみながら、少しずつ理解を深めていきましょう。

データサイエンスと機械学習の世界は常に進化しています。好奇心を持って学び続け、新しい技術やアルゴリズムに挑戦していくことが、この分野で成長していくための鍵となります。

この記事が、あなたの機械学習学習の旅の良いスタートとなることを願っています。


コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

上部へスクロール