データ $(x_i, y_i)$ に直線 $y = ax + b$ をあてはめて、誤差の2乗の和
\[ \sum_{i=1}^{n} (ax_i + b - y_i)^2 \]が最小になるような $a$ と $b$ を求めるのが(通常の線形の)回帰分析です。
なぜ「回帰」というのでしょうか。
正規分布の乱数を2組作って、足したり引いたりして、ある程度の相関があるようにして、プロットしてみます:
import numpy as np import matplotlib.pyplot as plt import seaborn as sns rng = np.random.default_rng(20200112) r1 = rng.standard_normal(500) # 正規乱数 r2 = rng.standard_normal(500) # 正規乱数 x = r1 + r2 / 2 y = r1 - r2 / 2 x = x / np.std(x) # 標準偏差で割る y = y / np.std(y) # 標準偏差で割る np.corrcoef(x, y) # 相関係数
array([[1. , 0.59072439], [0.59072439, 1. ]])
sns.regplot(x=x, y=y) plt.axis('equal')
x軸とy軸のスケールを等しくしているので、各データ点に最も近い直線は斜め45°の主軸のはずですが、xが与えられたときにyの値を(最小2乗法の意味で)最もよく近似するのは45°より水平に近い直線です。
np.polyfit(x, y, 1)
array([ 0.59072439, -0.04323489])
この直線の傾きは0.59ほどです。
注意深く見られたかたは、この直線の傾きと相関係数とがぴったり一致することに気づかれたと思います。実は、データを用意するときに、x = x / np.std(x)
、y = y / np.std(y)
として標準偏差を 1 に揃えたのですが、このときは直線の傾きと相関係数とが一致します。
例えばxを親の身長、yを子の身長とすると、だいたいこんな感じに相関しているのですが、親が平均身長より3cm高ければ、子の身長は平均身長より2cm高い程度で、子は親より平均に近いことが多いということになります。この傾向(「平均への回帰」)を調べるために使われた方法ですので、こういう方法を「回帰分析」といいます。
より詳しく調べるには、t検定でも紹介したpingouinパッケージを使います。
import pingouin as pg pg.linear_regression(x, y)
names coef se T ... r2 adj_r2 CI[2.5%] CI[97.5%] 0 Intercept -0.043235 0.036303 -1.190957 ... 0.348955 0.347648 -0.114560 0.028090 1 x1 0.590724 0.036157 16.337822 ... 0.348955 0.347648 0.519686 0.661763
おっと! 画面の幅が足りないので途中が省略されてしまいました。小数第5桁までにしてみましょう:
pg.linear_regression(x, y).round(5)
names coef se T pval r2 adj_r2 CI[2.5%] CI[97.5%] 0 Intercept -0.04323 0.03630 -1.19096 0.23424 0.34896 0.34765 -0.11456 0.02809 1 x1 0.59072 0.03616 16.33782 0.00000 0.34896 0.34765 0.51969 0.66176
これで係数(coef)、その標準誤差(se)、$p$ 値(pval)、95%信頼区間(CI)などが出力されました。
別の例をやってみましょう。気象庁の地球温暖化のデータです。
import pandas as pd df = pd.read_csv('http://www.data.jma.go.jp/cpdinfo/temp/list/csv/an_wld.csv', encoding='cp932') sns.regplot(x='年', y='世界全体', data=df)
直線の傾きを求めてください。
このCSVファイルについては気象庁の「世界の年平均気温偏差」データでも説明しています。
$y$ の値が 0 から 1 までに限られる回帰です。確率を予測するときに使います。データは、起こった($y_i = 1$)か起こらない($y_i = 0$)かのどちらかです。予測の式は
\[ y = \frac{1}{1 + e^{-(ax+b)}} \]です。$a$ と $b$ は最小2乗法ではなく最尤法で求めます。つまり、
\[ \prod_{y_i = 1} \frac{1}{1 + e^{-(ax_i+b)}} \cdot \prod_{y_i = 0} \left( 1 - \frac{1}{1 + e^{-(ax_i+b)}} \right) \]を最大にするような $a$ と $b$ を求めます。
Python での例はタイタニック号のところに出てきます。
Last modified: