見出し画像

scikit-learn機械学習③単純線形回帰:実践編

今回は単純線形回帰をscikit-learnを使って実装します。

scikit-learnは機械学習を行うためのオープンソースのPythonライブラリです。分類、回帰、クラスタリング、次元削減など多様な機械学習タスクをサポートします。

また、豊富な機械学習アルゴリズムだけでなく、データ前処理、モデルのトレーニング、評価、パイプラインの構築など便利な機能が含まれています。

これらの機能は、NumPy、SciPy、Matplotlibなどの他のPython科学計算ライブラリと連携して動作しますが、シンプルなインターフェースを提供しているので使い方は難しくはありません。よって、機械学習の一般的なワークフローを簡単に実行でき、やりたいことに集中できます。

さっそく、始めましょう!


Pythonの環境設定

Pythonの仮想環境を作ってscikit-learnとJupyterなど必要なライブラリをインストールします。

mkdir linear_regression
cd linear_regression

python3 -m venv venv
source venv/bin/activate

# pip をアップグレードしておく
pip install --upgrade pip

# 必要なライブラリをインストール
pip install scikit-learn jupyter matplotlib

Jupyterノートブックを立ち上げてPython3のノートブックを作成してください。

Jupyterノートブック

ブラウザーを使う

Jupyterを使わなくともコマンドラインで全て行うことも可能です。ここでは、Jupyterノートブックをブラウザーで開いて使ってみたい人向けに簡単に使い方を解説します。

Jupyterについては説明するよりもやってみる方が早いので次のようにして実行してください。なお、先ほど設定したPythonの仮想環境の中で実行する必要があります。

jupyter notebook

すると、ブラウザーが立ち上がって次のようなページが開きます。 

venv と見えるのは現在のディレクトリのフォルダを表示しているからです。まず、新しいノートブックを作ります。NewをクリックしてNotebookを選んでください。

すると新しいNotebookが作成されます。Untitled.ipynbという名のファイルをダブルクリックしてください。すると次のような画面が出ます。リストの中にはRなどの言語がサポートされていますが、我々はPythonを使うので Python 3 (ipykernel)を選んでください。

すると次のようなUntitled.ipynbが開き画面に表示されます。


Untitledとなっているのはファイル名からなのですが、クリックすれば変更できます。

とりあえずlinear_regression.ipynbとしておきます。

VSCodeから開く

.ipynbファイルはVisual Studio Codeからも開くことができます。私は普段はもっぱらこちらを使います。プロジェクトには様々な形式のファイルがあるのでなんでもVSCodeから編集した方が便利ですし、GitHub Copilotとの相性も良いです。まあ、Microsoftなので当然ではありますが。

画面はこんな感じです。

エディタには人それぞれ好みがあるので好きな環境を使ってください。なお、VSCodeを使う際にはPython環境を先ほど作成したvenvに設定しておいてください。

上図のように四角の中にコード書くのですが、この四角をセルと呼びます。セルの中にカーソルがある状態で、Run ボタン(あるいは▷)を押すと実行されます。または、CMD+ENTER(macOS)か CTRL+ENTER(Windows)でも実行できます。

さらに、SHIFT-ENTERだとセルを実行した後に次のセルに移動します。次のセルがない場合は自動的に追加されます。

次のように、print('Hello, World!')と書いて実行すると、セルの下に実行結果が表示されます。

このようにJupyterノートブックを使うと実行結果を確かめながらコーディングができるのでデータ分析や機械学習の実験などをする際に重宝されています。

単純線形回帰モデル

まずは、単純線形回帰モデルで実験し機械学習のコーディングの大まかな流れを掴みましょう。

データセットの準備

単純線形回帰では、独立変数$${X}$$と従属変数$${y}$$がそれぞれ一つあります。

import numpy as np

# データセットの準備
X = np.array([[1], [2], [3], [4], [5], [6], [7], [8], [9], [10]])
y = np.array([2.3, 4.5, 5.8, 7.6, 10.1, 11.8, 13.7, 15.9, 18.2, 20.0])

scikit-learnでは、独立変数は一般にベクトルなので、独立変数が一つでも2次元の形式で指定します。

$${X}$$をプリントすると次のように表示されます。

シェイプを確認すると$${(10, 1)}$$と行10列1の2次元になっているのが確認できます。

つまり、一つの独立変数に10個の値があるということです。

仮に二つの独立変数があるデータならば 10 x 2 の行列となります。

ついでに$${y}$$の値も見てみましょう。

シェイプは$${(10, )}$$となっており、一次元のベクトルです。

なお、$${y}$$の値には小さな誤差を含めており、実際には完全な直線にはならないようにしています。

データをグラフにする

データ分析や機械学習では、データがどのような分布を持つのかなど調べることがよくあります。そこからどのようなモデルを使うべきかを考えるためです。そのため、よくデータをグラフにします。

import matplotlib.pyplot as plt

# グラフを書く
plt.scatter(X, y)
plt.show()

これは、matplotlibを使ってデータ点をグラフにしています。セルを実行すると次のようなグラフがセルの下に表示されます。

微妙に直線からずれているのが見えますが、大まか直線なので線形回帰モデルを使うのが妥当だと判断できます。

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

このデータを訓練用とテスト用に分けます。モデルの学習のためには訓練用のデータを使い、モデルの評価のためにテスト用のデータを使います。

from sklearn.model_selection import train_test_split

# データをトレーニングセットとテストセットに分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, 
                                                    random_state=0)

scikit-learnの便利な機能として train_test_split があります。これはデータセットを訓練用とテスト用に分けるためのものです。

test_size = 0.2 としているのはテスト用に20%のデータを使うということです。今回のデータは10個のペアしかないので2個がテスト用にランダムに振り分けられます。なお、random_state = 0 は乱数のシードを固定することで再現性を確保しています。

コンピュータが生成する乱数は、「擬似乱数」と呼ばれます。擬似乱数は、決定論的なアルゴリズムによって生成される数列であり、厳密にはランダムではありません。よって、同じ初期値(シード値)を与えた場合、擬似乱数生成器は毎回同じ数列を生成します。しかし、この数列はランダムに見える性質を持っているため、実用上は乱数として扱われます。

シードを指定しない場合、擬似乱数を生成するプログラムは、実行ごとに異なるシード値を自動的に選択します。たとえば、現在の時刻やプロセスIDなど、実行時に変化する値をシードを計算するために利用することが一般的です。このため、異なる実行で異なるシードが使われるので、乱数列も異なるものが生成されます。つまり、結果が毎回変わるようになります。

機械学習では、乱数シードを固定して毎回同じ条件で訓練することが多いです。これによって誰が同じコードを走らせても同じ結果になることが期待されます。

この再現性は、科学的な研究やモデルの開発プロセスにおいて非常に重要です。実験の結果を公開する際、他の研究者がその結果を検証できるようにするためには、実験の条件を明確にして、同じ条件下で実験を再現できる必要があります。また、モデルのチューニングを行う際にも、異なるパラメータやアーキテクチャが実際に性能にどのような影響を与えるかを正確に評価するためには、その他の条件を一定に保つことが重要です。

ちょっと話がずれましたが、train_test_split によって訓練用とテスト用のデータに分割することができました。

これでモデルを訓練する準備が完了しました。

モデルを訓練データにフィットさせる

scikit-learnで線形回帰を行うためには、LinearRegression を使います。

from sklearn.linear_model import LinearRegression

# 線形回帰モデルのインスタンスを作成
model = LinearRegression()

このようにして生成した LinearRegression モデルを訓練用データにフィットさせます。

# モデルをトレーニングデータにフィットさせる
model.fit(X_train, y_train)

「フィットさせる」とはLinearRegression の中のパラメータを訓練用データに合わせて調節するという意味です。前回解説したように最小二乗法を使って行列の式の解を探します。

今回は、単純線形回帰モデルなので、訓練データに最も適合する直線を見つけるように、直線の傾きと切片の二つのパラメータを計算してくれます。

なお、fit 関数はモデルのオブジェクト自身を返すので、そのまま続けて他の関数を呼び出すことも可能です。例えば、以下のようにすることもできます。

model.fit(X_train, y_train).predict(X_test)

しかし、今回はそのように続けて関数を呼ぶことはしないで、ひとつずつ解説しています。

モデルをテストデータで評価する

次に、テスト用のデータ X_test を使って、モデルに対応する値を予測させます。

# テストデータで予測
y_pred = model.predict(X_test)

この値を表示すると次のようになりました。

テスト用データ y_test は次のようになっていたので、近い値を予測しているのがわかります。

これをより客観的に評価するために平均2乗誤差を計算します。

from sklearn.metrics import mean_squared_error

# モデルの性能を評価
mse = mean_squared_error(y_test, y_pred)

平均2乗誤差(MSE、Mean Squared Error)を使う理由は、そもそも最小2乗法で誤差の二乗の合計を最小化することを目指していたからです。よって、この値がより小さいほどモデルのフィットがうまくいったと言えます。

値をプリントすると次のように出力されました。

この値が良いか悪いかは、そもそものデータの分散などにもよります。MSEがゼロになれば、全ての点が直線上に載っていることになりますが、実際のデータには誤差などがあり、ほとんどの場合はゼロにはなりません。

いずれにせよ、このように評価値を計算しておくと、モデルの変更などをした時に精度の比較をする材料となります。また、他のモデルの結果と比較したりすることでモデルの良し悪しを調べるのにも役に立ちます。


以上、scikit-learnを使った機械学習の大まかな流れを解説しました。

次回予告

次回は多変量線形回帰を実装します。また、scikit-learnに含まれているデータセットを利用します。もう少しデータの分析について解説します。

お楽しみに!

ここから先は

0字

キカベン・読み放題

¥1,000 / 月
初月無料
このメンバーシップの詳細

この記事が気に入ったらチップで応援してみませんか?