はじめに
機械学習という言葉を聞いたことはあるけれど、「実際に何ができるのか?」「どうやって学習するのか?」と疑問に思っている方も多いでしょう。
この記事では、機械学習の中でも最も基本的な「教師あり学習」について、プログラミング初心者の方にも分かりやすく詳しく解説します。難しい専門用語はできるだけ避け、具体例を交えながら説明していきますので、ぜひ最後までお読みください。
さっそく始めてみましょう。
1. 教師あり学習とは?
● 教師あり学習の概要
機械学習には大きく分けて「教師あり学習」「教師なし学習」「強化学習」の3種類があります。
その中でも最も基本的で初心者が取り組みやすいのが教師あり学習です。
教師あり学習とは、「正解が分かっているデータ(=教師データ)」をもとにコンピュータに学習させ、新しいデータに対して予測を行わせる手法です。人間が教師となって「この入力に対してはこの出力が正解ですよ」と教えることから「教師あり」と呼ばれています。
分かりやすく例えると、以下のようなプロセスを踏みます:
- 正解がわかっているデータをコンピュータに与える
- コンピュータがそのデータからパターンを学習する
- 新しい未知のデータに対して予測を行う
私たちの日常生活でもこのような学習方法は使われています。例えば、子供に「これはリンゴ」「これはミカン」と教えることで、子供は新しく見た果物がリンゴなのかミカンなのかを判断できるようになります。これと同じような学習を機械にさせるのが教師あり学習です。
この学習が終わると、新しいデータに対して予測を行うことができるようになります。
教師あり学習の具体的な活用例
実社会では、教師あり学習は様々な場面で活用されています:
具体的な例を挙げると:
-
過去の売上データから翌月の売上を予測する
-
入力:過去数ヶ月の売上データ、季節、イベント情報など
-
出力:翌月の予測売上
-
-
手書きの数字画像を認識し、どの数字かを判別する
-
入力:手書きの数字の画像データ
-
出力:0から9までの数字のいずれか
-
-
顧客データをもとに、商品を購入するかどうかを予測する
-
入力:顧客の年齢、性別、過去の購買履歴など
-
出力:購入する確率(0%~100%)
-
これらの例では、大量の「入力データと正解の組」を用意し、コンピューターに学習させます。学習が終わると、新しい入力データに対して予測を行うことができるようになります。
● 教師あり学習の2つの種類
教師あり学習には、大きく分けて2種類のタスクがあります。
-
回帰(Regression):数値を予測する問題
回帰は、入力データから連続的な数値を予測するタスクです。例えば:
- 不動産価格予測: 家の面積、築年数、立地などから価格を予測する
- 気象予報: 過去の気象データから翌日の気温や降水量を予測する
- 株価予測: 過去の株価データや経済指標から将来の株価を予測する
- 売上予測: 過去のトレンドやマーケティング施策から将来の売上を予測する
回帰問題の出力は「10.5万円」「25.3度」のような連続的な数値になります。
-
分類(Classification):カテゴリを予測する問題
分類は、入力データをあらかじめ定義されたカテゴリ(クラス)に振り分けるタスクです。例えば:
- メールフィルタリング: メールが「スパム」か「通常メール」かを判別する(2クラス分類)
- 画像認識: 写真に写っている動物が「犬」「猫」「鳥」などどの動物かを分類する(多クラス分類)
- 感情分析: 文章が「ポジティブ」「ネガティブ」「中立」のどの感情を表しているかを判別する
- 疾病診断: 患者のデータから特定の病気の有無を判定する
分類問題の出力は「スパム」「犬」「ポジティブ」といった離散的なカテゴリになります。
初心者の方は最初に回帰問題に取り組むことをおすすめします。なぜなら回帰問題は結果を視覚化しやすく、学習の進み具合を直感的に理解できるからです。
では、実際にPythonを使って回帰問題を解いてみましょう!
2. Pythonで教師あり学習を試してみよう
Pythonは機械学習に広く使われているプログラミング言語です。しかし、初心者の方にとっては、環境構築が難しく感じられるかもしれません。
そこで、Google Colabというウェブサービスを使うことをおすすめします。
● Google Colabの使い方
-
Google Colabにアクセスする(https://colab.research.google.com/)
-
「新しいノートブック」を作成する
-
表示されたページの上部にあるセルに、以下で紹介するコードをコピー&ペーストする
-
セルの左側にある再生ボタン(▶)をクリックして実行する
これだけで、ブラウザ上でPythonのコードを実行できます。
● 実践例:家の面積から価格を予測する回帰問題
では、具体的な例として「家の面積から価格を予測する」回帰問題を解いてみましょう。コードの各部分を詳しく解説していきます。
以下のコードをGoogle Colabにコピー&ペーストして実行してみてください:
このコードは、家の面積(㎡)から価格(万円)を予測する簡単な回帰モデルを作成します。コードの詳細な解説は後ほど行います。
# 必要なライブラリをインポート import numpy as np # 数値計算のためのライブラリ import pandas as pd # データを扱うためのライブラリ import matplotlib.pyplot as plt # グラフ描画用のライブラリ from sklearn.model_selection import train_test_split # データを学習用とテスト用に分割 from sklearn.linear_model import LinearRegression # 線形回帰モデル from sklearn.metrics import mean_absolute_error # 誤差を測る指標 # 仮のデータを作成(家の面積と価格) data = { "Area": [30, 40, 50, 60, 70, 80, 90, 100, 110, 120], # 平米 "Price": [300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200] # 万円 } # データフレーム化 df = pd.DataFrame(data) # 辞書型データをPandasのDataFrameに変換 # データを訓練用とテスト用に分割 X = df[["Area"]] # 説明変数(面積) y = df["Price"] # 目的変数(価格) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # データの分割 # モデルの作成と学習 model = LinearRegression() # 線形回帰モデルのインスタンスを作成 model.fit(X_train, y_train) # モデルにデータを学習させる # 予測 y_pred = model.predict(X_test) # テストデータに対して予測を行う # 結果の表示 print("予測結果:", y_pred) # 予測した値を出力 print("実際の値:", y_test.values) # 実際の値を出力 print("誤差:", mean_absolute_error(y_test, y_pred)) # 実際の値との誤差を表示 # グラフの描画 plt.figure(figsize=(10, 6)) # グラフのサイズを指定 plt.scatter(X, y, label="実際のデータ", color='blue') # 実際のデータを散布図として描画 plt.plot(X, model.predict(X), color='red', label="回帰直線") # 回帰直線を描画 plt.xlabel("面積 (㎡)") # x軸のラベル plt.ylabel("価格 (万円)") # y軸のラベル plt.title("家の面積と価格の関係") # グラフのタイトル plt.legend() # 凡例を表示 plt.grid(True) # グリッド線を表示 plt.show() # グラフを表示
コードの詳細解説
1. ライブラリのインポート
Pythonでは、様々な機能を「ライブラリ」という形で使います。これは料理に例えると、基本的な調理器具や調味料のようなものです。主に使用するライブラリは:
- NumPy (np): 数値計算のための基本ライブラリ。行列やベクトルの計算を効率的に行えます。
- Pandas (pd): データ分析に特化したライブラリ。Excelのような表形式のデータを扱います。
- Matplotlib (plt): グラフ描画のためのライブラリ。結果を視覚化するのに使います。
- Scikit-learn (sklearn): 機械学習のためのライブラリ。様々な機械学習モデルや前処理ツールが含まれています。
各ライブラリの名前の後に as
と書いて別名(エイリアス)をつけることがよくあります。
例えば import numpy as np
は「numpyをnpという短い名前で使えるようにする」という意味です。
2. データの準備
# 仮のデータを作成(家の面積と価格) data = { "Area": [30, 40, 50, 60, 70, 80, 90, 100, 110, 120], # 平米 "Price": [300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200] # 万円 } # データフレーム化 df = pd.DataFrame(data) # 辞書型データをPandasのDataFrameに変換
この部分では、サンプルデータを作成しています。実際のプロジェクトでは、CSVファイルやデータベースからデータを読み込むことが多いですが、今回は簡単のために直接データを定義しています。
- data: Pythonの辞書型(dictionary)で、「Area(面積)」と「Price(価格)」という2つのキーを持ちます。
- pd.DataFrame: Pandasのデータフレーム(表形式のデータ構造)に変換しています。これにより、表計算ソフトのように扱えるようになります。
このサンプルデータでは、家の面積と価格が完全な比例関係になっています(面積10㎡に対して価格100万円)。実際のデータではこのように完全な比例関係にはなりませんが、学習の初めの一歩としては理解しやすいデータです。
3. データの分割
# データを訓練用とテスト用に分割 X = df[["Area"]] # 説明変数(面積) y = df["Price"] # 目的変数(価格) 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=42: 乱数のシードを固定する(常に同じ分割結果になるようにする)
これにより、以下の4つの変数が作られます:
- X_train: 訓練用の入力データ
- X_test: テスト用の入力データ
- y_train: 訓練用の出力データ
- y_test: テスト用の出力データ
4. モデルの作成と学習
# モデルの作成と学習 model = LinearRegression() # 線形回帰モデルのインスタンスを作成 model.fit(X_train, y_train) # モデルにデータを学習させる
ここでは、線形回帰(Linear Regression)というシンプルなモデルを使用します。線形回帰は、入力と出力の関係を直線で表現するモデルです。
- model = LinearRegression(): 線形回帰モデルのインスタンス(実体)を作成
- model.fit(X_train, y_train): 訓練データを使ってモデルを学習させる
fit()
メソッドは「合わせる」という意味で、訓練データの入力(X_train)と出力(y_train)の関係を最もよく表す直線を見つけ出す処理を行います。
5. 予測
# 予測 y_pred = model.predict(X_test) # テストデータに対して予測を行う
学習したモデルを使って、テストデータ(X_test)に対する予測(y_pred)を行います。ここで重要なのは、テストデータは学習に使っていないデータである点です。つまり、モデルが見たことのないデータに対してどれだけ正確に予測できるかを確認しています。
6. 結果の表示
# 結果の表示 print("予測結果:", y_pred) # 予測した値を出力 print("実際の値:", y_test.values) # 実際の値を出力 print("誤差:", mean_absolute_error(y_test, y_pred)) # 実際の値との誤差を表示
- y_pred: モデルが予測した価格
- y_test.values: テストデータの実際の価格
- mean_absolute_error: 平均絶対誤差(予測値と実際の値の差の絶対値の平均)
この誤差が小さいほど、モデルの予測精度が高いということになります。
7. グラフの描画
# グラフの描画 plt.figure(figsize=(10, 6)) # グラフのサイズを指定 plt.scatter(X, y, label="実際のデータ", color='blue') # 実際のデータを散布図として描画 plt.plot(X, model.predict(X), color='red', label="回帰直線") # 回帰直線を描画 plt.xlabel("面積 (㎡)") # x軸のラベル plt.ylabel("価格 (万円)") # y軸のラベル plt.title("家の面積と価格の関係") # グラフのタイトル plt.legend() # 凡例を表示 plt.grid(True) # グリッド線を表示 plt.show() # グラフを表示
最後に、データとモデルの関係を視覚化します。
- plt.scatter: 実際のデータ点を散布図(点)として描画
- plt.plot: モデルが予測する直線を描画
- plt.xlabel, plt.ylabel: 軸のラベルを設定
- plt.title: グラフのタイトルを設定
- plt.legend: 凡例(グラフ内の各要素の説明)を表示
- plt.grid: 格子線を表示
- plt.show: グラフを表示
このグラフを見ると、データ点(青い点)と予測直線(赤い線)の関係が一目でわかります。今回のデータは完全な線形関係なので、全ての点が直線上にありますが、実際のデータでは多少のバラつきがあるでしょう。
実行結果の解釈
コードを実行すると、次のような結果が表示されるはずです:
- 予測結果: テストデータに対する価格の予測値
- 実際の値: テストデータの実際の価格
- 誤差: 予測値と実際の値の平均絶対誤差
- グラフ: 面積と価格の関係を表す散布図と回帰直線
このサンプルデータでは完全な線形関係を設定したため、誤差は非常に小さく(または0に近く)、グラフでも全ての点が直線上に並びます。しかし実際のデータでは、様々な要因(立地、築年数、階数など)により、多少のバラつきが生じます。
線形回帰の数学的な背景(簡易版)
線形回帰の基本的な考え方は、データの関係を以下の式で表現することです:
y = ax + b
ここで:
- y: 予測値(今回の例では家の価格)
- x: 入力値(今回の例では家の面積)
- a: 傾き(単位面積あたりの価格変化)
- b: 切片(面積が0の時の価格、理論上の値)
機械学習では、誤差が最小になるような a と b の値を自動的に探します。このプロセスを「最小二乗法」と呼びます。
今回のコードでは、model.fit()
を実行した時点で、この計算が内部的に行われています。学習後、以下のようにして傾きと切片の値を確認することができます
print("傾き(coefficient):", model.coef_[0]) print("切片(intercept):", model.intercept_)
この値を使って、新しい面積に対する価格を手動で計算することもできます。例えば、面積が75㎡の家の価格を予測する場合:
new_area = 75 predicted_price = model.coef_[0] * new_area + model.intercept_ print(f"面積{new_area}㎡の家の予測価格: {predicted_price}万円")
3. 教師あり学習の発展:より複雑なモデルへ
これまで紹介した線形回帰は、教師あり学習の中でも最も基本的なモデルです。しかし、実際のデータはもっと複雑で、単純な直線では表現できないことが多いです。
より高度な回帰モデル
実際の機械学習では、以下のような高度なモデルも使われます:
- 多項式回帰(Polynomial Regression): 直線ではなく曲線でデータの関係を表現します
- 決定木回帰(Decision Tree Regression): データを階層的に分割して予測します
- ランダムフォレスト(Random Forest): 複数の決定木を組み合わせて予測精度を高めます
- サポートベクターマシン(Support Vector Machine, SVM): データを高次元空間に写像して分析します
- ニューラルネットワーク(Neural Network): 人間の脳の神経回路を模倣した深層学習モデルです
これらのモデルも基本的には同じようにscikit-learnのAPIを使って実装できます。例えば、決定木回帰は以下のように実装できます:
from sklearn.tree import DecisionTreeRegressor # 決定木回帰モデルの作成と学習 tree_model = DecisionTreeRegressor(max_depth=3) # 木の深さを3に制限 tree_model.fit(X_train, y_train) # 予測 y_pred_tree = tree_model.predict(X_test)
複数の特徴量を使った予測
実際の問題では、予測に影響する要素(特徴量)は通常複数あります。例えば、家の価格予測では、面積だけでなく、以下のような要素も影響します:
- 築年数
- 最寄り駅からの距離
- 階数
- 日当たり
- 周辺環境
複数の特徴量を使った線形回帰は、以下のように表現できます:
y = a₁x₁ + a₂x₂ + a₃x₃ + ... + b
ここで:
- y: 予測値(家の価格など)
- x₁, x₂, x₃, …: 各特徴量(面積、築年数、駅距離など)
- a₁, a₂, a₃, …: 各特徴量の係数(重み)
- b: 切片
コードの実装はほとんど同じですが、入力データ(X)に複数の列を含めるだけです:
# 複数の特徴量を持つデータを準備 data_multi = { "Area": [30, 40, 50, 60, 70, 80, 90, 100, 110, 120], # 平米 "Age": [20, 15, 10, 5, 3, 10, 15, 5, 2, 1], # 築年数 "Station_Distance": [10, 5, 3, 5, 7, 2, 3, 8, 10, 15], # 駅からの距離(分) "Price": [280, 320, 480, 520, 650, 800, 820, 930, 1100, 1150] # 万円 } df_multi = pd.DataFrame(data_multi) # 説明変数(特徴量)と目的変数を分離 X_multi = df_multi[["Area", "Age", "Station_Distance"]] # 複数の特徴量 y_multi = df_multi["Price"] # データ分割、モデル学習、予測は同じように行います
これにより、より正確な予測が可能になります。
4. 教師あり学習を使う際の注意点
過学習(オーバーフィッティング)
教師あり学習を使う際の大きな課題の一つが「過学習(オーバーフィッティング)」です。これは、モデルが訓練データに対しては非常に良く適合するが、新しいデータに対しては精度が落ちる現象です。
例えるなら、「テスト問題と同じ問題集を丸暗記したけれど、少し形式が変わった問題には答えられない」という状況です。
過学習を防ぐための一般的な方法:
- 十分なデータ量を確保する: 少ないデータで複雑なモデルを学習させると過学習しやすい
- モデルの複雑さを制限する: 決定木の深さを制限するなど
- 正則化(Regularization)を使う: モデルのパラメータが大きくなりすぎないように制限を加える
- 交差検証(Cross-validation): データを複数の部分に分け、それぞれをテストセットとして評価する
特徴量エンジニアリング
特徴量エンジニアリングとは、元のデータから予測に役立つ新しい特徴を作り出すプロセスです。例えば:
- 家の「築年数」と「リフォーム年数」から「最後の改修からの経過年数」を計算する
- 「日付」から「曜日」「月」「季節」などの情報を抽出する
- 「郵便番号」から「地域の平均所得」などの外部データと連携する
良い特徴量を作ることは、モデルの精度向上に大きく貢献します。
データの前処理
実際のデータは、そのままでは使えないことが多いです。データの前処理には以下のような作業があります:
- 欠損値の処理: データに抜けがある場合、平均値で埋めるなどの対処が必要
- 外れ値の処理: 極端に大きいまたは小さい値を適切に処理する
- 正規化/標準化: 異なるスケールの特徴量を同じスケールに揃える
- カテゴリ変数の処理: 「地域名」などの文字列データを数値に変換する
これらの前処理を適切に行うことで、モデルの学習がスムーズになり、精度も向上します。
5. まとめ
この記事では、機械学習の基本である「教師あり学習」について、以下の内容を解説しました:
- 教師あり学習の基本概念:
- 正解がわかっているデータから学習し、新しいデータを予測する手法
- 回帰(数値予測)と分類(カテゴリ予測)の2種類がある
- Pythonでの実装方法:
- Google Colabを使った環境構築
- 必要なライブラリ(NumPy, Pandas, Matplotlib, Scikit-learn)の使い方
- 線形回帰モデルによる家の価格予測の例
- 発展的な内容:
- より高度なモデル(決定木、ランダムフォレストなど)
- 複数の特徴量を使った予測
- 過学習やデータ前処理などの注意点
機械学習は奥が深い分野ですが、この記事で紹介した基本を押さえれば、他のモデルや応用にも挑戦しやすくなります。ぜひGoogle Colabで実際にコードを動かして、機械学習を試してみて下さい。