Pythonライブラリ「scikit-learn」で単回帰分析を行う方法についてサンプルコード付きで解説します。
単回帰分析とは
以下の図は、VTuberの「チャンネル登録者数」から「視聴者数」を予測する単回帰モデルを作成するイメージです。
単回帰分析(Simple Linear Regression)では、1つの特徴量($x$)から1つのターゲット変数($y$)を予測するモデルを作成します。数学的には以下の式で表されます。
予測値を計算する式:$ \hat{y} = ax + b $ 実測値の関係:$ y = ax + b + \varepsilon $
各変数の意味をまとめると以下表になります。例は、VTuberの「チャンネル登録者数」から「視聴者数」を予測する場合です。
| 変数 | 説明 | 例 |
|---|---|---|
| $ \hat{y} $ | モデルが計算したターゲット変数(目的変数)の推定値 | 視聴者数(予測値) |
| $ y $ | 実際に観測されたターゲット変数(目的変数)の値 | 視聴者数(実測値) |
| $ x $ | 特徴量(予測したい値に影響を与えるもの。説明変数ともいう) | チャンネル登録者数(実測値) |
| $ a $ | 傾き($x$が1増えると$y$がどれだけ増えるか。重み、回帰係数ともいう) | 登録者数が1人増えたときの視聴者数の増加量 |
| $ b $ | 切片($x=0$のときの$y$の値) | 登録者数が0人のときの理論的な視聴者数 |
| $ ε $ | 誤差項(予測と実際のズレ) | 「モデルが説明できない部分」であり、ノイズや他の未考慮の要因を含みます。 |
予測値を計算する式 $ \hat{y} = ax + b $は、「$x$に比例して$\hat{y}$が変化する関係」を表す、傾き$a$、切片$b$の一次関数です。グラフにすると以下のようなまっすぐな直線になります。この直線を「回帰直線」といいます。
単回帰分析の仕組みについては、以下ページで別途解説しています。
動画で見る
サンプルコード① 単回帰モデルの作成
Pythonライブラリ「Scikit-learn」を用いて、単回帰分析によりVTuberの「チャンネル登録者数」から「視聴者数」を予測してみましょう。
以下のような4名のVTuberの初回配信における「チャンネル登録者数」と「視聴者数」の実測値のデータがあるとします。
| 配信回 | チャンネル登録者数(x) | 視聴者数(y) |
|---|---|---|
| 兎野ぴこり#1 | 150,000 | 4,000 |
| 港あくび#1 | 120,000 | 3,100 |
| 星空スバリ#1 | 100,000 | 2,500 |
| 修士みより#1 | 80,000 | 1,700 |
scikit-learnのLinearRegression クラスを使って、「チャンネル登録者数」から「視聴者数」を予測する回帰直線を求めるPythonプログラムを作成すると、以下のようになります。
実行結果の解説
小数第4位で切り捨てすると、回帰直線の式は以下のように求まります。
$ \hat{y} = 0.0324x – 823.3644 $
上式の$ \hat{y} $は視聴者数の推測値、$x$はチャンネル登録者数となります。 よって、例えばチャンネル登録者数20万人の視聴者数は以下の計算により、約5656人と推定できます。
$ \hat{y} = 0.0324 \times 200,000 – 823.3644 = 5656.6356$
なお、どのような計算により回帰直線を求めているかなど、数理的な仕組みについては、以下ページで学ぶことができます。
コード解説
from sklearn.linear_model import LinearRegression
import numpy as np
LinearRegressionは、線形回帰モデルを使うためのクラスnumpyは、数値配列を扱うためのライブラリ
# 特徴量(説明変数): VTuberのチャンネル登録者数
X = np.array([[150000], [120000], [100000], [80000]])
# ターゲット変数(目的変数): 視聴者数
y = np.array([4000, 3100, 2500, 1700])
Xは 特徴量(チャンネル登録者数)で、2次元配列(shape = (4, 1))にしているのは、sklearnの仕様に合わせるためです。yは ターゲット変数(視聴者数)で、1次元配列。
# 線形回帰モデルを用いて、登録者数と視聴者数の関係を学習
model = LinearRegression()
model.fit(X, y)
model = LinearRegression()は 線形回帰モデルのクラス(LinearRegression)からインスタンスを生成(model)。model.fit(X, y)で、訓練データ(X:特徴量、y:ターゲット変数)でモデルが学習します。fitメソッドは、最小二乗法で最も誤差が少ない直線を求めています。
# 回帰直線の傾き(登録者数が1人増えるごとの視聴者数の増加量)を出力
print("傾き a:", model.coef_[0])
# 回帰直線の切片(登録者数が0人のときの理論的な視聴者数)を出力
print("切片 b:", model.intercept_)
model.coef_属性(プロパティ)は、学習後に得られる 回帰係数(重み) がNumPy配列で格納されています。model.coef_[0]は単回帰直線の傾き$a$(登録者数が1人増えると、視聴者数がどれだけ増えるか)。- 傾き$a$ ≈ 0.0324 → 登録者数が1万人増えると、視聴者数は約324人増える。
model.intercept_は 学習後に得られる切片$b$が「float型の数値(単回帰)」または「NumPy配列(重回帰)」で格納されています(登録者数が0人だった場合の理論的な視聴者数)。- 切片 ≈ -823 → 実際には「視聴者数がマイナスになる」ということはありえません。これは、モデルがデータの外側まで予測しようとしたために、現実とは合わない結果が出ています。こうした「データの外側での予測」は、正しくないことが多く、これを「外挿の限界」と呼びます。

コメント
youtubeからこちらのサイトに来ました。
貴重な情報ありがとうございます。
【Scikit-learn】単回帰分析の所で質問なんですが、
# 説明変数xに “x1″のデータを使用
x = data.loc[:, [‘x1’]].values
# 目的変数yに “x2″のデータを使用
y = data[‘x2’].values
にするとあります。
locでx1のデータを抜き出すのと、x2のデータではデータの型が違うのですか?
どちらもSeries型となって、valuesでnumpy配列にしていると思うのですが。
xが2次元配列、yが1次元配列というところまで勉強している程度なんで、
基礎的な質問で申し訳ないですが、どのような意図でこのようにしているのか教えて下さい。
fit()にXとyを代入する際、説明変数Xは行列(2次元配列)を与える必要があります。
data[‘x2’].valuesだと、1次元配列として1つの配列を取得するため、二次元配列に変換してやるコードを追加する必要があります。
その手間を省く意味と、重回帰の場合はlocを使わないといけないという理由でdata.loc(複数のカラムを2次元配列で取得)としています。
https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LinearRegression.html
fit(self, X, y, sample_weight=None)[source] X{array-like, sparse matrix} of shape (n_samples, n_features) Training data yarray-like of shape (n_samples,) or (n_samples, n_targets) Target values. Will be cast to X’s dtype if necessary