Scikit-learnで実践する初めての機械学習

人工知能(AI)や機械学習という言葉が日常的に聞かれるようになりました。しかし、「AI開発は専門家だけの領域」と感じて、一歩を踏み出せずにいる方も多いのではないでしょうか。実は、現代のプログラミング言語とライブラリの進化により、初心者でも基本的なAIモデル、特に機械学習モデルを構築することが十分に可能です。その中でも、Python は、シンプルで読みやすい文法と豊富なライブラリにより、データサイエンスAI開発の分野で圧倒的な支持を得ています。

このチュートリアルでは、Pythonの機械学習ライブラリの中でも特に初心者に優しいと評判の「Scikit-learn」を使い、機械学習モデル作成の全プロセスをゼロから体験します。データの前処理から始まり、モデルの訓練、そして性能評価に至るまで、一つ一つのステップを丁寧に解説していきます。「何から始めればいいかわからない」という方でも、この記事を読み終える頃には、自分の手でデータを分析し、未来を予測するモデルを作る楽しさとその基本を理解できるようになるでしょう。さあ、一緒にScikit-learnで始める機械学習の世界へ旅立ちましょう。

なぜ今、PythonとScikit-learnなのか?

AI・機械学習の世界には数多くのツールや言語が存在しますが、その中でもなぜ「Python」と「Scikit-learn」の組み合わせが、特に初学者にとって最高の出発点と言えるのでしょうか。その理由を、開発者としての視点から深く掘り下げてみましょう。

Python: データサイエンスの「共通言語」

プログラミング言語としてのPythonが持つ魅力は、その圧倒的な汎用性とシンプルさにあります。もともと教育用に開発された経緯もあり、Pythonの文法は人間が読むことを強く意識して設計されています。これにより、プログラミング経験が浅い人でも、比較的短期間でコードを読み書きできるようになります。

しかし、データサイエンス分野でPythonがデファクトスタンダードとなった理由はそれだけではありません。鍵となるのは、その強力なエコシステムです。

  • NumPy: 高速な数値計算を可能にするライブラリです。多次元配列(ベクトルや行列)の操作に特化しており、機械学習アルゴリズムの根幹を支える計算処理を効率的に行います。
  • Pandas: 表形式のデータを扱うためのライブラリで、「DataFrame」という強力なデータ構造を提供します。データの読み込み、クリーニング、変換、集計など、分析の前段階で行う面倒な作業を驚くほど簡単にしてくれます。
  • Matplotlib & Seaborn: データを視覚化するためのライブラリです。グラフやチャートを簡単に作成でき、データの傾向やパターンを直感的に理解するのに役立ちます。百聞は一見に如かず、データ分析において視覚化は不可欠なプロセスです。
  • Jupyter Notebook: コード、テキスト、数式、視覚化を一つのドキュメントにまとめて実行できる対話型の開発環境です。試行錯誤を繰り返しながら分析を進めるデータサイエンスのワークフローに最適で、多くの研究者や開発者に愛用されています。

これらのライブラリがシームレスに連携することで、Pythonは単なるプログラミング言語から、データ収集からモデル構築、結果の可視化までを一気通貫で行える強力なデータ分析プラットフォームへと変貌します。このエコシステムの存在こそが、Pythonを学ぶ最大のメリットの一つです。

Scikit-learn: 機械学習の「スイスアーミーナイフ」

Scikit-learnは、この強力なPythonエコシステムの上に構築された、オープンソースの機械学習ライブラリです。その最大の特徴は、一貫性のあるシンプルなAPI(Application Programming Interface)と、網羅性の高さにあります。

Scikit-learnを使えば、多種多様な機械学習アルゴリズムを、驚くほど統一された手順で利用できます。

  1. モデルのインスタンス化: model = AlgorithmName()
  2. モデルの学習: model.fit(X_train, y_train)
  3. 予測の実行: predictions = model.predict(X_test)

この3ステップの基本パターンを覚えれば、分類、回帰、クラスタリング、次元削減など、様々な種類のアルゴリズムを同じように扱えます。これにより、学習者は個々のアルゴリズムの複雑な実装に頭を悩ませることなく、「どのアルゴリズムが目の前の問題に最適か」という本質的な問いに集中できるのです。これは、初学者が機械学習の全体像を掴む上で非常に大きな助けとなります。

他のライブラリとの比較

機械学習、特に深層学習(ディープラーニング)の分野では、TensorFlowやPyTorchといったライブラリも非常に有名です。では、これらとScikit-learnはどう違うのでしょうか。以下の表で比較してみましょう。

項目 Scikit-learn TensorFlow PyTorch
主な用途 伝統的な機械学習全般(分類、回帰、クラスタリングなど) 深層学習(ニューラルネットワーク)、大規模な数値計算 深層学習(特に研究分野で人気)、柔軟なモデル構築
学習難易度 非常に低い。統一されたAPIで直感的。 中〜高。Keras APIにより簡略化されたが、依然として概念は複雑。 中程度。Pythonicな書き方ができ直感的だが、自由度が高い分、学習コストもかかる。
エコシステム NumPy, Pandas, Matplotlibと完全に統合。 TensorBoard(可視化)、TensorFlow Serving(デプロイ)など、独自の強力なエコシステムを持つ。 豊富な研究用ライブラリやツール群と連携。
得意なデータ 構造化データ(表形式のデータ) 非構造化データ(画像、音声、テキスト) 非構造化データ(画像、音声、テキスト)
おすすめのユーザー 機械学習初心者、データサイエンティスト、迅速なプロトタイピング 研究者、本番環境へのモデルデプロイを目指す開発者 研究者、最新の論文を素早く実装したい開発者

結論: TensorFlowやPyTorchが「複雑なニューラルネットワークをゼロから構築するための強力なエンジン」であるのに対し、Scikit-learnは「実績のある機械学習アルゴリズムを手軽に試せる、完成されたツールの詰め合わせ」と言えます。まずはScikit-learnで機械学習の基本的な考え方とワークフローをマスターし、その上でより複雑な問題に挑戦するためにTensorFlowやPyTorchへ進むのが、最も効率的で挫折の少ない学習ロードマップです。

開発環境の準備:AIモデル開発の第一歩

優れた道具があっても、それを使うための作業場がなければ何も始まりません。ここでは、Pythonを使ったAIモデル開発に最適な開発環境を構築する手順を解説します。一見地味な作業ですが、安定した環境は後の学習効率を大きく左右する重要な土台となります。

1. Pythonのインストール

まず、お使いのコンピュータにPythonがインストールされているか確認します。ターミナル(WindowsではコマンドプロンプトやPowerShell)を開き、以下のコマンドを入力してください。


python --version
# または
python3 --version

バージョン番号(例: `Python 3.10.4`)が表示されればインストール済みです。バージョンが3.8以上であれば、このチュートリアルを進める上で特に問題はありません。もしインストールされていない、またはバージョンが古い場合は、公式サイトから最新版をダウンロードしてインストールしましょう。

Python公式サイトへ

Windowsユーザーへの注意: インストーラーを実行する際、「Add Python X.X to PATH」というチェックボックスに必ずチェックを入れてください。これにより、どのディレクトリからでも `python` コマンドを実行できるようになります。

2. 仮想環境の構築:プロジェクトごとの「隔離部屋」

開発を進めていくと、プロジェクトAではライブラリXのバージョン1.0が必要なのに、プロジェクトBではバージョン2.0が必要、といった「依存関係のコンフリクト」が発生することがあります。これを避けるために、プロジェクトごとに独立したPython環境(仮想環境)を作成するのがベストプラクティスです。

Python 3.3以降には `venv` というモジュールが標準で付属しており、簡単に仮想環境を作成できます。

まず、プロジェクト用のディレクトリを作成し、そこに移動します。


mkdir my_ml_project
cd my_ml_project

次に、そのディレクトリ内に `venv` という名前の仮想環境を作成します。


python3 -m venv venv

最後に、作成した仮想環境を「有効化(activate)」します。これにより、これ以降のコマンドはこの仮想環境内で実行されるようになります。

  • macOS / Linux:
    
    source venv/bin/activate
    
  • Windows:
    
    .\venv\Scripts\activate
    

有効化されると、プロンプトの先頭に `(venv)` と表示されます。これで、システム全体を汚すことなく、このプロジェクト専用のライブラリを自由にインストールできます。

3. 必須ライブラリのインストール

仮想環境が有効になった状態で、このチュートリアルで必要となるライブラリを `pip` (Pythonのパッケージインストーラ) を使って一括でインストールします。


pip install numpy pandas scikit-learn matplotlib seaborn jupyterlab
各ライブラリの役割:
  • numpy: 数値計算の基礎。
  • pandas: データ操作と分析。
  • scikit-learn: 機械学習アルゴリズムとツール。
  • matplotlib: 基本的なデータ可視化。
  • seaborn: Matplotlibをベースにした、より美しい統計的グラフ作成。
  • jupyterlab: 対話的にコードを実行できる高機能な開発環境。

4. JupyterLabの起動

すべてのライブラリがインストールされたら、JupyterLabを起動してみましょう。ターミナルで以下のコマンドを実行します。


jupyter lab

自動的にブラウザが立ち上がり、JupyterLabのインターフェースが表示されます。左側のファイルブラウザから「New Launcher」を開き、「Notebook」の「Python 3」カーネルを選択すれば、分析を開始する準備は完了です。JupyterLabは、コードをセル単位で実行し、その結果をすぐ下に表示できるため、データ分析の試行錯誤に非常に適しています。

これで、あなたのマシンは本格的なデータサイエンス・ワークステーションになりました。次のセクションから、いよいよ実際のデータを使って機械学習の世界に飛び込んでいきましょう。

プロジェクトの全体像:機械学習モデル作成の流れ

機械学習プロジェクトは、闇雲にコードを書き始めるものではありません。成功のためには、確立された一連のプロセスに従うことが重要です。このプロセスを理解することは、個々の技術を学ぶこと以上に価値があると言えるでしょう。ここでは、一般的な機械学習プロジェクトのワークフローを概観します。このチュートリアル全体が、この流れに沿って進んでいきます。

  1. 問題設定 (Problem Definition)

    すべての始まりは「何を解決したいのか?」という問いです。ビジネス上の課題を、機械学習で解ける具体的な問題に落とし込みます。例えば、「顧客が解約するかどうかを予測したい(分類問題)」、「来月の売上を予測したい(回帰問題)」、「顧客を似たようなグループに分けたい(クラスタリング問題)」などです。今回は、教育用データセットとして有名な「アヤメ(Iris)の花の種類を、花びらの大きさなどから予測する」という分類問題に取り組みます。

  2. データ収集 (Data Collection)

    問題を解決するために必要なデータを集めます。データは、社内データベース、公開されているデータセット、Webスクレイピングなど、様々なソースから得られます。幸いなことに、Scikit-learnには練習用のデータセットが多数同梱されており、今回はその中から「Irisデータセット」を使用します。

  3. 探索的データ分析 (EDA) & データ前処理

    集めたデータを"調理"する、最も重要で時間のかかるフェーズです。

    • 探索的データ分析 (Exploratory Data Analysis, EDA): データを可視化したり、基本的な統計量を計算したりして、データにどのような特徴やパターンが隠れているかを探ります。欠損値の有無、外れ値の存在、変数間の相関などを確認します。
    • データ前処理 (Data Preprocessing): EDAで得られた知見を元に、モデルが学習しやすいようにデータを整形します。欠損値の補完、カテゴリ変数の数値化、特徴量のスケーリングなどが含まれます。「Garbage in, garbage out(ゴミを入れれば、ゴミしか出てこない)」という言葉があるように、この工程の質がモデルの性能を大きく左右します。

  4. モデルの選択 (Model Selection)

    問題の種類(分類、回帰など)やデータの特性に基づいて、使用する機械学習アルゴリズムを選択します。Scikit-learnには多種多様なモデルが用意されているため、最初はシンプルなモデル(ロジスティック回帰、k-近傍法など)から試し、徐々に複雑なモデル(サポートベクターマシン、ランダムフォレストなど)を検討していくのが一般的です。

  5. モデルの学習 (Model Training)

    準備したデータを使い、選択したモデルにパターンを学習させます。これは、Scikit-learnでは .fit() メソッドを呼び出すだけで完了します。この段階で、データは通常「学習用データ(Training Data)」と「テスト用データ(Test Data)」に分割され、学習には前者のみを使用します。

  6. モデルの評価 (Model Evaluation)

    学習済みモデルが、未知のデータに対してどれだけうまく予測できるかを評価します。ここで「テスト用データ」が登場します。学習に使っていないデータで性能を測ることで、モデルの真の汎化性能を客観的に評価できます。正解率、適合率、再現率、F1スコア、混同行列など、問題に応じた適切な評価指標を用います。

  7. (発展) ハイパーパラメータチューニング & デプロイ

    モデルの性能が不十分な場合、モデルの挙動を制御する「ハイパーパラメータ」を調整して、性能向上を目指します(チューニング)。満足のいく性能が得られたモデルは、最終的に実際のアプリケーションやシステムに組み込み(デプロイ)、予測サービスとして利用されることになります。

この一連の流れは、一度で終わることは稀です。多くの場合、評価結果を元に前処理やモデル選択に戻り、何度もイテレーションを繰り返しながら、より良いモデルを目指していくことになります。このサイクルを理解し、粘り強く改善を続ける姿勢が、優れたデータサイエンティストには不可欠です。

実践①:データと向き合う探索的データ分析 (EDA)

理論の学習はここまでです。いよいよJupyterLab上でコードを動かし、実際のデータに触れていきましょう。最初のステップは、探索的データ分析(EDA)です。これは、データセットの中身を深く理解し、その後の分析方針を立てるための非常に重要なプロセスです。ここでは、Pythonでのデータ分析と可視化の基本を学びます。

1. データの読み込み

Scikit-learnに組み込まれているIrisデータセットを読み込みます。そして、データ操作に便利なPandasのDataFrame形式に変換します。これがデータ分析の定石です。


import pandas as pd
import numpy as np
from sklearn.datasets import load_iris

# Irisデータセットをロード
# bunchオブジェクトとしてデータが格納されている
iris_bunch = load_iris()

# 特徴量データ(説明変数)をDataFrameに変換
# カラム名は bunch.feature_names から取得
X = pd.DataFrame(iris_bunch.data, columns=iris_bunch.feature_names)

# 目的変数(ターゲット)をDataFrameに変換
# 0, 1, 2 の数値で品種が表現されている
y = pd.DataFrame(iris_bunch.target, columns=['species'])

Bunchオブジェクトとは? Scikit-learnのサンプルデータセットは、`Bunch`という辞書ライクなオブジェクトで提供されます。データ本体は`.data`、特徴量の名前は`.feature_names`、ターゲット(正解ラベル)は`.target`、ターゲットの名前は`.target_names`というキーでアクセスできます。

2. データの概要を把握する

データがどのようなものか、まずはPandasの基本的な関数を使って全体像を掴みます。

.head(): 最初の数行を表示

データが正しく読み込めているか、どのようなカラムがあるかを確認します。


# 特徴量データXの先頭5行を表示
print("--- 特徴量データ (X) ---")
print(X.head())

# 目的変数yの先頭5行を表示
print("\n--- 目的変数データ (y) ---")
print(y.head())

.info(): データセットの基本情報

各カラムのデータ型や、欠損値の有無などを一覧で確認できます。データクリーニングの第一歩です。


print("--- Xの基本情報 ---")
X.info()

print("\n--- yの基本情報 ---")
y.info()

出力結果から、Irisデータセットには150個のサンプルがあり、欠損値(Non-Null Countが150でないもの)は存在しないことがわかります。データが非常に綺麗で、前処理が楽であることが予想できます。

.describe(): 基本統計量の算出

数値データの各カラムについて、平均値、標準偏差、最小値、最大値、四分位数などを一括で計算します。これにより、データの分布の中心やばらつき具合を把握できます。


# Xの基本統計量を表示
X.describe()

例えば、`petal length (cm)`(花びらの長さ)は最小1.0cmから最大6.9cmまで、かなり幅広い分布をしていることが見て取れます。

.value_counts(): カテゴリごとのデータ数

目的変数 `y` がどのように分布しているかを確認します。これにより、各クラスのデータ数が均等か、それとも不均衡かを知ることができます。


# 品種ごとのデータ数を確認
y['species'].value_counts()

結果は、0, 1, 2 の各クラスが50個ずつ、完全に均等なデータセットであることがわかります。これはAIモデルを学習させる上で理想的な状況です。

3. データを可視化して洞察を得る

数値だけでは捉えきれないデータのパターンを、グラフを使って直感的に理解します。ここではMatplotlibとSeabornライブラリの力を借ります。

ヒストグラム: 各特徴量の分布を確認

各特徴量がどのような分布をしているか(例:正規分布に近いか、偏りがあるか)を視覚化します。


import matplotlib.pyplot as plt
import seaborn as sns

# Matplotlibのスタイルを設定
plt.style.use('ggplot')

# 4つの特徴量についてのヒストグラムを一度に描画
X.hist(bins=20, figsize=(12, 8))
plt.tight_layout() # グラフの重なりを防ぐ
plt.show()

このグラフから、`sepal width`(がくの幅)は比較的正規分布に近い形をしていますが、`petal length`(花びらの長さ)や`petal width`(花びらの幅)は2つの山を持つ(バイモーダルな)分布をしていることがわかります。これは、おそらく花の種類によってこれらの特徴量が大きく異なることを示唆しています。

ペアプロット: 全特徴量間の関係性を一覧

Seabornのペアプロットは、データフレーム内のすべての数値特徴量の組み合わせに対して、散布図(対角線以外)とヒストグラム(対角線)を一度に描画してくれる非常に強力なツールです。


# PandasのconcatでXとyを一時的に結合して可視化しやすくする
# 品種(species)ごとに色分けしてプロットするため
df_full = pd.concat([X, y], axis=1)

# 品種名を数値から実際の名前へマッピング
df_full['species_name'] = df_full['species'].map({
    0: iris_bunch.target_names[0], 
    1: iris_bunch.target_names[1], 
    2: iris_bunch.target_names[2]
})


# ペアプロットを描画
# hueに'species_name'を指定することで、品種ごとに色分けされる
sns.pairplot(df_full, hue='species_name', vars=iris_bunch.feature_names, height=2)
plt.show()

このペアプロットは、宝の山です。ここから多くの洞察が得られます。

  • `setosa`(青色の点)は、他の2種(`versicolor`, `virginica`)とはっきりと分離できています。特に `petal length` と `petal width` を見ると、`setosa` の値は非常に小さい領域に固まっています。
  • `versicolor`(オレンジ色の点)と `virginica`(緑色の点)は、一部重なり合っているものの、全体的には分離可能に見えます。
  • `petal length` と `petal width` の間には非常に強い正の相関があることがわかります(一方が大きいと、もう一方も大きい)。

このEDAの結果から、「アヤメの花の種類は、特に花びらの長さと幅を使えば、かなり高い精度で分類できそうだ」という強力な仮説を立てることができます。これが、データに基づいた意思決定の第一歩です。

実践②:データをモデルが学習できる形へ(データ前処理)

探索的データ分析でデータの特性を理解したら、次はそのデータを機械学習モデルが「食べやすい」形式に加工するデータ前処理のステップに進みます。生の食材をそのままオーブンに入れるのではなく、下ごしらえをするのと同じです。この工程はモデルの性能に直接影響を与えるため、非常に重要です。

1. データセットの分割: 学習用とテスト用

機械学習モデルを評価する上で最も重要な原則の一つは、「モデルの学習に使ったデータで、そのモデルの性能を評価してはいけない」というものです。なぜなら、モデルは学習データを「暗記」してしまい、見かけ上は高い性能を示しますが、未知の新しいデータに対しては全く役に立たない可能性があるからです。これを過学習(Overfitting)と呼びます。

これを避けるため、手持ちのデータセットを「学習用データ(Training set)」と「テスト用データ(Test set)」の2つに分割します。

  • 学習用データ: モデルにパターンを学ばせるために使用します。全体の70%〜80%を割り当てるのが一般的です。
  • テスト用データ: 学習には一切使用せず、学習済みモデルの性能を公平に評価するために取っておきます。

Scikit-learnには、この分割を簡単に行うための `train_test_split` という便利な関数が用意されています。


from sklearn.model_selection import train_test_split

# データを学習用とテスト用に分割
# X: 特徴量データ, y: 目的変数データ
# test_size=0.3: 全体の30%をテストデータに割り当てる
# random_state=42: 乱数を固定し、何度実行しても同じ分割結果になるようにする(再現性の確保)
# stratify=y: 元のデータのクラス比率を保ったまま分割する(分類問題で特に重要)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=42, stratify=y
)

# 分割後の各データの形状を確認
print("--- 分割後のデータ形状 ---")
print(f"X_train: {X_train.shape}")
print(f"X_test: {X_test.shape}")
print(f"y_train: {y_train.shape}")
print(f"y_test: {y_test.shape}")

`random_state` の重要性: `random_state` を指定しないと、実行するたびに分割のされ方が変わってしまい、モデルの評価結果が安定しません。実験の再現性を確保するために、この引数を設定することは非常に重要です。

`stratify=y` の重要性: `stratify=y` を指定すると、`y_train` と `y_test` の中のクラスの割合(0, 1, 2の比率)が、元の `y` の比率と同じになるように分割してくれます。クラスのデータ数に偏りがある(不均衡な)データセットでは、この指定が欠かせません。

2. 特徴量のスケーリング: 単位を揃える

多くの機械学習アルゴリズム、特に距離ベースのアルゴリズム(k-近傍法、サポートベクターマシンなど)や、勾配降下法を用いるアルゴリズム(ロジスティック回帰、ニューラルネットワークなど)は、特徴量のスケール(単位や範囲)が異なるとうまく機能しないことがあります。

例えば、「長さ(cm)」と「重さ(kg)」という2つの特徴量があったとします。長さが1〜100の範囲、重さが1〜5の範囲だった場合、モデルは数値の大きい「長さ」の方をより重要な特徴量だと誤解してしまう可能性があります。これを防ぐために、すべての特徴量を同じスケールに変換する処理、それが特徴量スケーリングです。

代表的なスケーリング手法として、以下の2つがあります。

  • StandardScaler (標準化): 各特徴量の平均が0、標準偏差が1になるように変換します。外れ値の影響を受けにくいとされています。
  • MinMaxScaler (正規化): 各特徴量の最小値が0、最大値が1になるように変換します。

今回は `StandardScaler` を使ってみましょう。ここでも重要な注意点があります。

スケーラーの学習は学習用データのみで行う!

`StandardScaler` も一種の「学習」を行います(具体的には、各特徴量の平均と標準偏差を計算します)。この計算は、学習用データ (`X_train`) のみを使って行う必要があります。そして、その計算された平均・標準偏差を使って、学習用データとテスト用データの両方を変換します。

もしテスト用データも含めてスケーラーを学習させてしまうと、テスト用データの情報がモデルの学習プロセスに漏れ出てしまい(データリーケージ)、モデルの性能を不当に高く評価してしまう原因になります。


from sklearn.preprocessing import StandardScaler

# StandardScalerのインスタンスを作成
scaler = StandardScaler()

# 1. 学習用データ(X_train)を使って、スケーラーを学習(fit)させる
scaler.fit(X_train)

# 2. 学習させたスケーラーを使って、学習用データとテスト用データの両方を変換(transform)する
X_train_scaled = scaler.transform(X_train)
X_test_scaled = scaler.transform(X_test)

# 変換後のデータはNumPy配列になるため、再度DataFrameに変換して確認
X_train_scaled_df = pd.DataFrame(X_train_scaled, columns=X.columns)
X_test_scaled_df = pd.DataFrame(X_test_scaled, columns=X.columns)

print("--- スケーリング後の学習データ (先頭5行) ---")
print(X_train_scaled_df.head())

print("\n--- スケーリング後の学習データの基本統計量 ---")
# 平均がほぼ0, 標準偏差がほぼ1になっていることを確認
print(X_train_scaled_df.describe())

これで、データは完全にクリーンになり、モデルを学習させる準備が整いました。地道な作業でしたが、この丁寧な前処理が、後のモデル性能を大きく向上させるのです。

実践③:Scikit-learnで機械学習モデルを訓練する

いよいよ、このチュートリアルの核心部分であるモデルの学習です。前処理済みのデータを使って、コンピュータに「アヤメの種類を見分ける方法」を学ばせていきます。Scikit-learnの素晴らしい点は、このプロセスが驚くほどシンプルで直感的なことです。

Scikit-learnの統一されたAPIパターン

前述の通り、Scikit-learnの多くのモデル(Estimatorと呼ばれます)は、共通のインターフェースを持っています。基本は以下の3ステップです。

  1. インポート (Import): 使いたいモデルのクラスを `sklearn` からインポートします。
  2. インスタンス化 (Instantiate): インポートしたクラスから、モデルのオブジェクトを作成します。このとき、モデルの挙動を調整するハイパーパラメータを指定できます。
  3. 学習 (Fit): 作成したモデルオブジェクトの .fit() メソッドを呼び出し、学習用データ(X_train, y_train)を渡します。

このパターンを一度覚えれば、様々なアルゴリズムを簡単に試すことができます。今回は、初学者が概念を理解しやすいk-近傍法(k-Nearest Neighbors, k-NN)というアルゴリズムを使ってみましょう。

k-近傍法 (k-NN) とは?

k-NNは、非常にシンプルで直感的な分類アルゴリズムです。「ご近所さんの多数決で決める」と考えるとわかりやすいでしょう。

  1. 新しい未知のデータ点(分類したいアヤメ)が与えられます。
  2. 学習データの中から、その新しいデータ点に最も「近い」データ点をk個見つけます。(この「近さ」は、特徴量空間におけるユークリッド距離などで計算されます)
  3. 見つけたk個のデータ点(ご近所さん)が、どのクラスに属しているかを見ます。
  4. k個の中で最も多数派だったクラスを、新しいデータ点の予測結果とします。

例えば、k=5の場合、最も近い5つの学習データのうち3つが「versicolor」、2つが「virginica」であれば、新しいデータは「versicolor」だと予測します。この「k」の値が、モデルの挙動を決める重要なハイパーパラメータになります。

k-NNアルゴリズムの図解
k-NNの概念図。新しいデータ点(緑)は、k=3なら赤クラス、k=5なら青クラスに分類される。

モデルの学習コード

それでは、実際にk-NNモデルを学習させてみましょう。コードはたったの数行です。


from sklearn.neighbors import KNeighborsClassifier

# 1. インスタンス化
# n_neighborsがハイパーパラメータkにあたる。今回は5に設定。
knn_model = KNeighborsClassifier(n_neighbors=5)

# 2. 学習 (Fit)
# 前処理済みの学習データ (X_train_scaled, y_train) を使用
# y_trainはDataFrameなので、.values.ravel()で1次元のNumPy配列に変換して渡すのが一般的
knn_model.fit(X_train_scaled, y_train.values.ravel())

print("k-NNモデルの学習が完了しました。")
print(knn_model)

たったこれだけです! これで、`knn_model` という変数の中に、105個の学習データ(Irisデータセットの70%)の特徴と正解ラベルの関係性を「記憶」した、学習済みのモデルが完成しました。k-NNは厳密には学習フェーズで複雑な計算をせず、データをそのまま保持するだけなので「遅延学習」とも呼ばれますが、Scikit-learn上では他のモデルと同じ `fit` メソッドで統一的に扱えます。

他のモデルも試してみよう

Scikit-learnのAPIの美しさを体感するために、他のアルゴリズムも試してみましょう。例えば、ロジスティック回帰(Logistic Regression)やサポートベクターマシン(Support Vector Machine, SVM)も、ほぼ同じコードで学習できます。


# --- ロジスティック回帰 ---
from sklearn.linear_model import LogisticRegression

# インスタンス化
log_reg_model = LogisticRegression(random_state=42)

# 学習
log_reg_model.fit(X_train_scaled, y_train.values.ravel())

print("ロジスティック回帰モデルの学習が完了しました。")
print(log_reg_model)


# --- サポートベクターマシン (SVM) ---
from sklearn.svm import SVC

# インスタンス化
svm_model = SVC(random_state=42)

# 学習
svm_model.fit(X_train_scaled, y_train.values.ravel())

print("\nサポートベクターマシンモデルの学習が完了しました。")
print(svm_model)

このように、モデルのコア部分(アルゴリズム)を入れ替えるだけで、様々なアプローチを簡単に試せるのがScikit-learnの強力な点です。これにより、開発者は迅速なプロトタイピングとモデル間の性能比較に集中できます。

さて、モデルは学習されましたが、これはまだスタートラインに立ったに過ぎません。このモデルが本当に「賢い」のか、未知のデータに対してどれほどの予測能力を持っているのかを、次のステップで厳密に評価していきます。

実践④:モデルの性能を評価する

モデルの学習が完了したら、その性能を客観的に評価するフェーズに入ります。自己満足で終わらせず、モデルがどれだけ優れているか(あるいは、どこに課題があるか)を数値で示すことは、データサイエンスにおいて不可欠なスキルです。ここでは、学習には一切使っていない「テスト用データ」を用いて、モデルの真の実力を測ります。

1. テストデータで予測を行う

学習済みのモデル(`knn_model`)を使って、テストデータ(`X_test_scaled`)に対する予測を行います。学習が .fit() だったのに対し、予測は .predict() メソッドを使います。これもScikit-learnの統一されたパターンです。


# 学習済みk-NNモデルを使い、テストデータに対する予測値を生成
y_pred = knn_model.predict(X_test_scaled)

# 予測結果(最初の10件)と実際の正解ラベル(y_test)を比較
print("--- 予測結果と正解ラベルの比較 ---")
print(f"予測 (y_pred): {y_pred[:10]}")
print(f"正解 (y_test): {y_test.values.ravel()[:10]}")

出力を見ると、多くの予測が正解と一致しているように見えます。しかし、これだけでは全体的な性能はわかりません。より体系的な評価指標を見ていきましょう。

2. 評価指標①: 正解率 (Accuracy)

最も直感的で分かりやすい評価指標が正解率です。これは、「全予測のうち、正解した予測の割合」を示します。

正解率 = (正しく予測できたサンプル数) / (全サンプル数)

Scikit-learnの `metrics` モジュールには、これを計算するための `accuracy_score` 関数が用意されています。


from sklearn.metrics import accuracy_score

# 正解率を計算
accuracy = accuracy_score(y_test, y_pred)

print(f"モデルの正解率 (Accuracy): {accuracy:.4f}")
# モデルオブジェクト自身の .score() メソッドでも計算可能
# print(f"モデルの正解率 (Accuracy): {knn_model.score(X_test_scaled, y_test):.4f}")

正解率は約95.56%と、非常に高い値が出ました。これは、45個のテストサンプルのうち、43個を正しく分類できたことを意味します。素晴らしい結果ですが、正解率だけを見て満足するのは早計です。特に、クラスごとのデータ数が不均衡な場合(例:99%がクラスA、1%がクラスB)、すべてをクラスAと予測するだけで99%の正解率が出てしまい、モデルの性能を誤って評価する可能性があります。

3. 評価指標②: 混同行列 (Confusion Matrix)

モデルが「どのように間違えたか」を詳細に分析するために、混同行列が非常に役立ちます。これは、予測クラスと実際のクラスをクロス集計した表です。

  • 行: 実際のクラス
  • 列: 予測されたクラス
予測: Setosa 予測: Versicolor 予測: Virginica
実際: Setosa True Positive (TP) - -
実際: Versicolor - True Positive (TP) False Negative (FN)
実際: Virginica - False Positive (FP) True Positive (TP)

対角線上の要素は正解した数、それ以外の要素は不正解の種類を示します。例えば、「実際はVersicolorなのに、Virginicaと間違えた」数がわかります。


from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay

# 混同行列を計算
cm = confusion_matrix(y_test, y_pred)
print("--- 混同行列 ---")
print(cm)

# 混同行列を可視化
disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=iris_bunch.target_names)
disp.plot(cmap=plt.cm.Blues)
plt.title("Confusion Matrix for k-NN Model")
plt.show()

この行列から、以下のことが読み取れます。

  • `setosa` は15個すべて正しく分類されています。
  • `versicolor` は15個中14個が正しく分類され、1個が `virginica` と誤分類されています。
  • `virginica` は15個中14個が正しく分類され、1個が `versicolor` と誤分類されています。

モデルがどのクラス間で混同しやすいかが一目瞭然となり、今後の改善のヒントが得られます。

4. 評価指標③: 分類レポート (Classification Report)

最後に、より詳細な評価指標をまとめた分類レポートを見てみましょう。`classification_report` 関数は、クラスごとの適合率 (Precision)再現率 (Recall)F1スコア (F1-Score)を一度に表示してくれます。

  • 適合率 (Precision): モデルが「陽性」と予測したものの中で、実際に「陽性」であったものの割合。誤検知(False Positive)を減らしたい場合に重要。(例:スパムメール判定)
  • 再現率 (Recall): 実際に「陽性」であるものの中で、モデルが「陽性」と正しく予測できたものの割合。見逃し(False Negative)を減らしたい場合に重要。(例:病気の診断)
  • F1スコア (F1-Score): 適合率と再現率の調和平均。これら2つの指標のバランスを取った評価指標です。

from sklearn.metrics import classification_report

# 分類レポートを生成
report = classification_report(y_test, y_pred, target_names=iris_bunch.target_names)
print("--- 分類レポート ---")
print(report)

このレポートから、`setosa` の分類性能は完璧(すべて1.00)であることがわかります。一方で、`versicolor` と `virginica` の性能は若干低いですが、それでも0.93という高いF1スコアを達成しています。`macro avg` (単純平均) や `weighted avg` (各クラスのサンプル数で重み付けした平均) も、モデル全体の性能を要約するのに役立ちます。

これらの評価指標を総合的に見ることで、私たちは「このk-NNモデルは、未知のアヤメのデータに対して約96%の精度を持ち、特にsetosaの分類は完璧だが、versicolorとvirginicaの間でわずかな混同が見られる」と、定量的かつ具体的にモデルの性能を語ることができるようになりました。これが、データに基づいた評価の力です。

次のステップへ:TensorFlowやさらなる学習のために

ここまで、お疲れ様でした!このチュートリアルを通じて、あなたはPythonとScikit-learnを使い、機械学習プロジェクトの基本的なワークフローを一通り体験しました。問題設定からデータの探索、前処理、モデルの学習、そして厳密な評価まで、データサイエンティストが行うコアな活動の基礎を築いたことになります。これは非常に大きな一歩です。

今回の旅のまとめ

  • Pythonの強力なエコシステム(Pandas, Matplotlib, Seaborn)がデータ分析の基盤となることを学びました。
  • Scikit-learnの統一されたシンプルなAPIを使い、k-NNモデルを構築しました。
  • 探索的データ分析(EDA)を通じてデータから洞察を得る方法を実践しました。
  • データの前処理(分割、スケーリング)の重要性と、その正しい手順を理解しました。
  • 正解率だけでなく、混同行列や分類レポートを用いてモデルを多角的に評価するスキルを身につけました。

しかし、これは広大なAIの世界への入り口に過ぎません。ここからさらに知識を深め、より複雑で面白い課題に挑戦するための道筋は無数に存在します。次に何を学ぶべきか、いくつかの指針を示します。

Scikit-learnをさらに極める

まずは、使い慣れたScikit-learnの中で、さらに探求できる領域がたくさんあります。

  • 他のアルゴリズムを試す: 今回はk-NNを使いましたが、決定木 (Decision Tree)、ランダムフォレスト (Random Forest)、勾配ブースティング (Gradient Boosting) など、Scikit-learnには強力なアルゴリズムが豊富に用意されています。同じデータセットにこれらのモデルを適用し、性能を比較してみましょう。
  • 回帰問題に挑戦する: 今回は分類問題でしたが、住宅価格や株価の予測といった数値を予測する「回帰問題」にも挑戦してみましょう。ボストン住宅価格データセットなど、Scikit-learnには練習用の回帰データセットも含まれています。
  • ハイパーパラメータチューニング: k-NNの「k」のように、モデルの性能を左右するハイパーパラメータを自動的に最適化する手法があります。`GridSearchCV` や `RandomizedSearchCV` を使えば、最も性能の良いハイパーパラメータの組み合わせを効率的に見つけ出すことができます。
  • パイプラインの構築: データ前処理(スケーラーなど)とモデルを一つにまとめる `Pipeline` という機能があります。これを使うと、コードが整理され、データリーケージなどのミスを防ぎやすくなります。

Scikit-learn公式ドキュメントは、これらのトピックを学ぶための最良のリソースです。

深層学習の世界へ: TensorFlowの基本

Scikit-learnが得意とする伝統的な機械学習は、特に構造化データ(表形式のデータ)に対して非常に強力です。しかし、画像認識、自然言語処理、音声認識といった非構造化データを扱うタスクでは、深層学習(ディープラーニング)が圧倒的な性能を発揮します。その代表的なフレームワークが、Googleが開発したTensorFlowです。

Scikit-learnでの経験は、TensorFlowを学ぶ上で決して無駄にはなりません。データの前処理、学習とテストの分割、モデルの評価といった基本的な考え方は、深層学習でも全く同じです。Scikit-learnでワークフローの全体像を掴んだ今だからこそ、より複雑なニューラルネットワークの構築にスムーズに移行できるのです。

TensorFlowの基本的な使い方の第一歩としては、高レベルAPIであるKerasを学ぶのがおすすめです。Kerasを使うと、 마치レゴブロックを組み立てるように、層(Layer)を積み重ねてニューラルネットワークモデルを直感的に構築できます。

例えば、手書き数字画像データセット(MNIST)を分類する簡単なニューラルネットワークは、Kerasを使えば以下のように記述できます。


import tensorflow as tf
from tensorflow import keras

# モデルの定義
model = keras.Sequential([
    keras.layers.Flatten(input_shape=(28, 28)),  # 28x28ピクセルの画像を1次元に変換
    keras.layers.Dense(128, activation='relu'), # 128個のニューロンを持つ中間層
    keras.layers.Dense(10, activation='softmax')   # 10クラス(数字の0-9)への出力層
])

# モデルのコンパイル(損失関数、最適化手法、評価指標を設定)
model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

# モデルの学習 (fitメソッドはScikit-learnと似ている!)
# model.fit(x_train, y_train, epochs=5)

Scikit-learnの経験があれば、このコードの構造も理解しやすいのではないでしょうか。深層学習に興味が湧いたら、次はぜひTensorFlowの公式チュートリアルに挑戦してみてください。

TensorFlow公式チュートリアル (日本語)

結論として

機械学習やAI開発は、一度学べば終わりというものではありません。常に新しい技術やアルゴリズムが登場する、ダイナミックで刺激的な分野です。重要なのは、今回学んだ基本のワークフローを体に染み込ませ、様々なデータセットや課題に対して、粘り強く試行錯誤を繰り返すことです。

この記事が、あなたのPython AI開発 入門の確かな一歩となり、未来の素晴らしいプロジェクトに繋がることを心から願っています。さあ、あなた自身のデータで、世界を分析し、未来を予測してみましょう!

Post a Comment