回帰

線形回帰

データ $(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を親の身長,yを子の身長とすると,だいたいこんな感じに相関しているのですが,親が平均身長より3cm高ければ,子の身長は平均身長より2cm高い程度で,子は親より平均に近いことが多いということになります。この傾向(「平均への回帰」)を調べるために使われた方法ですので,こういう方法を「回帰分析」といいます。

別の例をやってみましょう。気象庁の地球温暖化のデータです。

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)

現在,上のデータの最新の部分(速報値)に * が付いているため,数値と解釈できなくなっています。HTML版によれば * は「1月から11月までの月平均気温の偏差をもとに算出した速報値」だそうです。とりあえず

df['世界全体'] = df['世界全体'].str.replace('*', '', regex=False).astype(float)

のようにすれば数値に変換できます。

直線の傾きを求めてください。

ロジスティック回帰

$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: