回帰モデル(regression)

  • 回帰の目的:$p$次元の入力変数${\bf x}$の値から目標変数$y$の値を予測すること
    はじめに、以下のように記号を定義します。
表記 内容
$y_i$ 目標変数の観測値
$x_{i,j}$ 入力変数の観測値
${\bf x}_i$ $=(x_{i,1},\cdots,x_{i,p})^T$:入力変数のベクトルの観測値
$N$ 観測データ数($i=1,\cdots,N$)
$p$ 入力変数の次元数($j=1,\cdots,p$)
$D$ $={({\bf x}_i,y_i) i=1,\cdots,N}$:有限データ集合
$y$ 目標変数(target)、目的変数、非説明変数、従属変数、応答変数
$x_j$ 入力変数(input)、説明変数、独立変数、特徴量(feature)、predictor
${\bf x}$ 入力変数のベクトル

*目標変数や入力変数は様々な名称で呼ばれています。

線形回帰モデル

既知のパラメータ$\beta_j$とし、パラメータのベクトルを${\bf \beta}=(\beta_1,\cdots,\beta_p)^T$とします。線形回帰モデルでは、入力${\bf x}$、既知のパラメータ${\bf \beta}$を用いて、目標変数$y$を回帰超平面(回帰直線)で予想します。 \begin{eqnarray} y({\bf x})&=&\beta_0 + \beta_1 x_1 + \cdots + \beta_p x_p \\ &=&\sum_{j=0}^{p} \beta_j x_j \\ &=&{\bf x}^T {\bf \beta} \end{eqnarray} *ダミー変数$x_0=1$としています。

例として、Boston house-prices (ボストン市の住宅価格)のデータを用います。$i$を1から5まで出力します(ただし、Pythonのインデックスは0からはじまります)。


In [6]:
%pwd


Out[6]:
'/Users/ry8128/workspace/study_python'

In [12]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import datasets
%matplotlib inline

In [2]:
boston = datasets.load_boston()
df = pd.DataFrame(boston.data, columns=boston.feature_names)
df.head(5)


Out[2]:
CRIM ZN INDUS CHAS NOX RM AGE DIS RAD TAX PTRATIO B LSTAT
0 0.00632 18.0 2.31 0.0 0.538 6.575 65.2 4.0900 1.0 296.0 15.3 396.90 4.98
1 0.02731 0.0 7.07 0.0 0.469 6.421 78.9 4.9671 2.0 242.0 17.8 396.90 9.14
2 0.02729 0.0 7.07 0.0 0.469 7.185 61.1 4.9671 2.0 242.0 17.8 392.83 4.03
3 0.03237 0.0 2.18 0.0 0.458 6.998 45.8 6.0622 3.0 222.0 18.7 394.63 2.94
4 0.06905 0.0 2.18 0.0 0.458 7.147 54.2 6.0622 3.0 222.0 18.7 396.90 5.33

観測データ数$N$と入力変数と目標変数を合わせた次元数$p+1$をshapeメソッドで出力します。


In [13]:
df.shape


Out[13]:
(506, 13)

データの各属性は以下の値が格納されています。


In [1]:
#from IPython.display import HTML
属性名 内容
CRIM 人口1人当たりの犯罪発生数
ZN 25,000平方フィート以上の住居区画の占める割合
INDUS 小売業以外の商業が占める面積の割合
CHAS チャールズ川によるダミー変数(1:川の周辺,0:それ以外)
NOX NOxの濃度
RM 住居の平均部屋数
AGE 1940年より前に建てられた物件の割合
DIS 5つのボストン市の雇用施設からの距離(重み付け済)
RAD 環状高速道路へのアクセスしやすさ
TAX $10,000ドルあたりの不動産税率の総計
PTRATIO 町毎の児童と教師の比率
B 町毎の黒人(Bk)の比率を次の式で表したもの。1000(Bk–0.63)^2
LSTAT 給与の低い職業に従事する人口の割合(%)

In [15]:
df.corr()


Out[15]:
CRIM ZN INDUS CHAS NOX RM AGE DIS RAD TAX PTRATIO B LSTAT
CRIM 1.000000 -0.199458 0.404471 -0.055295 0.417521 -0.219940 0.350784 -0.377904 0.622029 0.579564 0.288250 -0.377365 0.452220
ZN -0.199458 1.000000 -0.533828 -0.042697 -0.516604 0.311991 -0.569537 0.664408 -0.311948 -0.314563 -0.391679 0.175520 -0.412995
INDUS 0.404471 -0.533828 1.000000 0.062938 0.763651 -0.391676 0.644779 -0.708027 0.595129 0.720760 0.383248 -0.356977 0.603800
CHAS -0.055295 -0.042697 0.062938 1.000000 0.091203 0.091251 0.086518 -0.099176 -0.007368 -0.035587 -0.121515 0.048788 -0.053929
NOX 0.417521 -0.516604 0.763651 0.091203 1.000000 -0.302188 0.731470 -0.769230 0.611441 0.668023 0.188933 -0.380051 0.590879
RM -0.219940 0.311991 -0.391676 0.091251 -0.302188 1.000000 -0.240265 0.205246 -0.209847 -0.292048 -0.355501 0.128069 -0.613808
AGE 0.350784 -0.569537 0.644779 0.086518 0.731470 -0.240265 1.000000 -0.747881 0.456022 0.506456 0.261515 -0.273534 0.602339
DIS -0.377904 0.664408 -0.708027 -0.099176 -0.769230 0.205246 -0.747881 1.000000 -0.494588 -0.534432 -0.232471 0.291512 -0.496996
RAD 0.622029 -0.311948 0.595129 -0.007368 0.611441 -0.209847 0.456022 -0.494588 1.000000 0.910228 0.464741 -0.444413 0.488676
TAX 0.579564 -0.314563 0.720760 -0.035587 0.668023 -0.292048 0.506456 -0.534432 0.910228 1.000000 0.460853 -0.441808 0.543993
PTRATIO 0.288250 -0.391679 0.383248 -0.121515 0.188933 -0.355501 0.261515 -0.232471 0.464741 0.460853 1.000000 -0.177383 0.374044
B -0.377365 0.175520 -0.356977 0.048788 -0.380051 0.128069 -0.273534 0.291512 -0.444413 -0.441808 -0.177383 1.000000 -0.366087
LSTAT 0.452220 -0.412995 0.603800 -0.053929 0.590879 -0.613808 0.602339 -0.496996 0.488676 0.543993 0.374044 -0.366087 1.000000

In [13]:
sns.heatmap(df.corr())


Out[13]:
<matplotlib.axes._subplots.AxesSubplot at 0x113dd1080>

各データをユークリッド空間$\mathbb{R}^{p+1}$上の点とし、2次元のみ可視化します。


In [3]:
from highcharts import Highchart

In [22]:
x_label = 'AGE'
y_label = 'NOX'
H = Highchart(width=500, height=500)
data = list(zip(df[x_label], df[y_label]))
H.add_data_set(data, 'scatter', '観測値')
H.set_options('xAxis', {'title': {'text': x_label}})
H.set_options('yAxis', {'title': {'text': y_label}, 'lineWidth': 2})
H.set_options('title', {'text': '散布図'})
H


Out[22]:

In [23]:
import webbrowser
open('regression_scatter.html', 'w').write(H.buildhtml())


Out[23]:
9169

In [24]:
webbrowser.open('regression_scatter.html')


Out[24]:
True
  • 目的:回帰超平面(回帰直線)のパラメータ${\bf \beta}$を推定すること

線形回帰モデルでは、 \begin{eqnarray} y({\bf x})&=&\beta_0 + \beta_1 x_1 + \cdots + \beta_p x_p \\ &=&\sum_{j=0}^{p} \beta_j x_j \\ &=&{\bf x}^T {\bf \beta} \end{eqnarray} とし、パラメータ${\bf \beta}$を既知としました。実際には、${\bf \beta}$はわからないため、推定する必要があります。

どんな直線がいいかいろいろ試してみましょう。


In [25]:
from ipywidgets import interact

In [45]:
b0_min = int(df[y_label].min()*1000)/1000
b0_max = int(df[y_label].max()*1000)/1000
b0_step = int((df[y_label].max()-df[y_label].min())/100*1000)/1000
b_min = int(df[x_label].min()*1000)/1000
b_max = int(df[x_label].max()*1000)/1000
b1_step = int((b0_max-b0_min)/(b_max-b_min)*10000)/100000
b1_min = b1_step-b1_step*10
b1_max = b1_step+b1_step*10

In [48]:
@interact
def plot(b0=(b0_min,b0_max,b0_step),b1=(b1_min,b1_max,b1_step)):
    x_tmp = np.linspace(int(df[x_label].min()),int(df[x_label].max())+1,50) 
    y_tmp = b0 + b1 * x_tmp
    fig = plt.figure(figsize=(7,7))
    plt.xlim([int(df[x_label].min()+0.5),int(df[x_label].max())+1])
    plt.ylim([int(df[y_label].min()+0.5),int(df[y_label].max())+1])
    plt.xlabel(x_label)
    plt.ylabel(y_label)
    plt.scatter(df[x_label],df[y_label])
    plt.plot(x_tmp,y_tmp,color='r')
    plt.grid()
    plt.show()


スライダーを動かすことで、切片と傾きを調節できます。

最小2乗法

最小2乗法は誤差の2乗和を最小にするようにパラメータ${\bf \beta}$を決定します。

観測誤差$\epsilon_i$を \begin{eqnarray} \epsilon_i &=& y_i - y({\bf x}_i) \\ &=& y_i - \sum_{j=0}^{p} \beta_j x_{i,j} \\ \end{eqnarray} とします。観測誤差のベクトルは \begin{equation} {\bf \epsilon}= \begin{bmatrix} y_1 - {\bf x}_1^T {\bf \beta} \\ \vdots \\ y_N - {\bf x}_N^T {\bf \beta} \end{bmatrix}= \begin{bmatrix} y_1 \\ \vdots \\ y_N \end{bmatrix}- \begin{bmatrix} {\bf x}_1^T {\bf \beta} \\ \vdots \\ {\bf x}_N^T {\bf \beta} \end{bmatrix}={\bf y}- \begin{bmatrix} {\bf x}_1^T \\ \vdots \\ {\bf x}_N^T \end{bmatrix} {\bf \beta}={\bf y}-{\bf X}{\bf \beta} \end{equation} となります。ただし、${\bf y}=(y_1,\cdots,y_N)^T$、${\bf X}=(x_{ij})$とします。

誤差の2乗和を最小化する以下の問題を解くことにより、${\bf \beta}$を求めます。 $$\min_{\bf \beta} \sum_{i=1}^N (y_i - {\bf x}_i^T {\bf \beta})^2$$

損失関数を \begin{eqnarray} L({\bf \beta})&=&\sum_{i=1}^N (y_i - {\bf x}_i^T {\bf \beta})^2 \\ &=&(y_1 - {\bf x}_1^T {\bf \beta})(y_1 - {\bf x}_1^T {\bf \beta})+\cdots +(y_N - {\bf x}_N^T {\bf \beta})(y_N - {\bf x}_N^T {\bf \beta})\\ &=&({\bf y}-{\bf X}{\bf \beta})^T ({\bf y}-{\bf X}{\bf \beta}) \\ &=&({\bf y}^T-{\bf \beta}^T {\bf X}^T)({\bf y}-{\bf X}{\bf \beta}) \\ &=&{\bf y}^T {\bf y}-{\bf y}^T {\bf X}{\bf \beta}-{\bf \beta}^T {\bf X}^T {\bf y}+{\bf \beta}^T {\bf X}^T {\bf X}{\bf \beta}\\ &=&{\bf y}^T {\bf y}-2{\bf \beta}^T {\bf X}^T {\bf y}+{\bf \beta}^T {\bf X}^T {\bf X}{\bf \beta} \end{eqnarray} とします。${\bf \beta}$に関する多変数の2次関数なので、勾配が0となる点${\bf \beta}$を求めます。 \begin{eqnarray} \nabla L({\bf \beta})&=&-2X^T Y+2X^T X{\bf \beta}\\ &=&-2(X^T Y-X^T X{\bf \beta})\\ &=&0 \end{eqnarray} これを変形すると、正規方程式 $$X^T X{\bf \beta}=X^T Y$$ が導けます。$X^T X$が正則行列(逆行列を持つ)ならば $$\hat{{\bf \beta}}=(X^T X)^{-1} X^T Y$$ と解が求まります。また、ヘッセ行列$\nabla^2 L({\bf \beta})=2X^T X$が半正定値行列(${\bf \beta}^T {\bf X}^T {\bf X}{\bf \beta}=||{\bf X}{\bf \beta}||^2 \geq 0$を満たす)なので、$L({\bf \beta})$は凸関数(下に凸な関数)です。よって、$\hat{{\bf \beta}}=(X^T X)^{-1} X^T Y$が誤差の2乗和が最小値をとる最適解となり、これを推定値とします。

実際に最小2乗法を計算し可視化してみます。


In [49]:
cols = list(df.columns)
cols.remove('RM')

In [50]:
X = df[cols]#入力変数
X['dammy'] = 1
y = df['RM']#目標変数
print(X.head(5))
print(y.head(5))


      CRIM    ZN  INDUS  CHAS    NOX   AGE     DIS  RAD    TAX  PTRATIO  \
0  0.00632  18.0   2.31   0.0  0.538  65.2  4.0900  1.0  296.0     15.3   
1  0.02731   0.0   7.07   0.0  0.469  78.9  4.9671  2.0  242.0     17.8   
2  0.02729   0.0   7.07   0.0  0.469  61.1  4.9671  2.0  242.0     17.8   
3  0.03237   0.0   2.18   0.0  0.458  45.8  6.0622  3.0  222.0     18.7   
4  0.06905   0.0   2.18   0.0  0.458  54.2  6.0622  3.0  222.0     18.7   

        B  LSTAT  dammy  
0  396.90   4.98      1  
1  396.90   9.14      1  
2  392.83   4.03      1  
3  394.63   2.94      1  
4  396.90   5.33      1  
0    6.575
1    6.421
2    7.185
3    6.998
4    7.147
Name: RM, dtype: float64

In [51]:
#Xのムーア・ペンローズの擬似逆行列
X_mp = np.linalg.inv(X.T.dot(X)).dot(X.T)
#正規方程式の解
beta_hat = X_mp.dot(y)
beta_hat_s = pd.Series(beta_hat,index=X.columns)
print('正規方程式の解')
print(beta_hat_s)


正規方程式の解
CRIM      -0.002359
ZN         0.005127
INDUS     -0.013539
CHAS       0.063889
NOX       -0.856839
AGE        0.006536
DIS       -0.063950
RAD        0.025246
TAX       -0.000669
PTRATIO   -0.049953
B         -0.000674
LSTAT     -0.064843
dammy      8.665639
dtype: float64

In [56]:
x_label = 'DIS'
y_label = 'RM'
x_tmp = np.linspace(int(df[x_label].min()),int(df[x_label].max())+1,50) 
y_tmp = beta_hat_s['dammy'] + beta_hat_s[x_label] * x_tmp
fig = plt.figure(figsize=(7,7))
plt.xlim([int(df[x_label].min())-1,int(df[x_label].max())+1])
plt.ylim([int(df[y_label].min())-1,int(df[y_label].max())+1])
plt.xlabel(x_label)
plt.ylabel(y_label)
plt.scatter(df[x_label],df[y_label])
plt.plot(x_tmp,y_tmp,color='r')
plt.grid()
plt.show()


*単回帰ではないので、2次元プロットにおいて、もっともらしい直線にならないことに留意してください。

確率の概念を導入

データ集合$D$は母集団から抽出された標本であると仮定します。すなわち、観測値$y_i$は確率変数$$Y=y(X)+\epsilon$$の確率分布に従って、生成された値と考えます。ここで、$X$は入力変数の確率変数のベクトルです。また、$\epsilon$~ $N(0,\sigma^2)$($\epsilon$は期待値0、分散$\sigma^2$の正規分布に従う)と仮定します。観測値$y_i$は有限集合$\{y_i|i=1,\cdots,N\}$の要素でしたが、$Y$は無限集合$\mathbb{R}$を考えています。 $Y$の期待値は \begin{eqnarray} E[Y]&=&E[y(X)+\epsilon]\\ &=&E[y(X)]+E[\epsilon]\\ &=&E[y(X)]\\ &=&E[X^T {\bf \beta}]\\ &=&E[X^T]{\bf \beta} \end{eqnarray} ですが、$X=x$のときの条件付き期待値は \begin{eqnarray} E[Y|X=x]&=&E[y(x)+\epsilon]\\ &=&y(x)+E[\epsilon]\\ &=&y(x)\\ &=&x^T {\bf \beta}\\ \end{eqnarray} となります。また、$X=x$のときの$Y$の条件付き分散は \begin{eqnarray} Var[Y|X=x]&=&E[(Y-E[Y])^2|X=x]\\ &=&E[(y(X)+\epsilon-E[y(X)])^2|X=x]\\ &=&E[(y(x)+\epsilon-E[y(x)])^2]\\ &=&E[(y(x)+\epsilon-y(x))^2]\\ &=&E[\epsilon^2]\\ &=&\sigma^2 \end{eqnarray} となります。よって、$X=x$のとき$Y$~$N(y(x),\sigma^2)$($Y$は期待値$y(x)$、分散$\sigma^2$の正規分布に従う)となります。

\begin{eqnarray} E[L] &=& E[(Y-f(X))^2] \\ &=& \int_{\mathbb{R}^{p+1}} (y-f({\bf x}))^2 Pr(d{\bf x},dy) \\ &=& \int_{\mathbb{R}^{p}} \int_{\mathbb{R}} (y-f({\bf x}))^2 Pr(dy|d{\bf x})Pr(d{\bf x})\\ &=& E_X[ E_{Y|X} [(Y-f(X))^2|X]] \end{eqnarray}

同時分布を$X$で条件付けしている。

EPEを最小化するためには,それぞれの$x$について最小化を行う.$c=f(x)$とすると \begin{equation} f(x)=argmin_{c} E_{Y|X} [(Y-c)^2|X=x] \end{equation} と求められる.この解は条件付き期待値 \begin{equation} f(x)=E[Y|X=x] \end{equation}

最尤法

パラメータ${\bf \beta}$のとき、データ${\bf x}_i,y_i$を観測する確率 $$P[{\bf x}_i,y_i|{\bf \beta}]$$ とする。各サンプルは独立に観測されると仮定し、尤度関数 $$\Pi_i P[{\bf x}_i,y_i|{\bf \beta}]$$ と定義する。 対数尤度関数は $$L({\bf \beta}) = \sum_{i=1}^{N} \log P[{\bf x}_i,y_i|{\bf \beta}]$$ となる。正規分布を仮定すると \begin{eqnarray} L({\bf \beta}) &=& \sum_{i=1}^{N} \log \frac{1}{\sqrt{2 \pi \sigma^2}} \exp{(-\frac{(y_i - {\bf x}_i^T {\bf \beta})^2}{2\sigma^2})} \\ &=& \sum_{i=1}^{N}( \log(1) - \log (\sqrt{2 \pi \sigma^2}) -\frac{(y_i - {\bf x}_i^T {\bf \beta})^2}{2\sigma^2})) \end{eqnarray} パラメータは${\bf \beta}$のみなので対数尤度の最小化は $$\min_{\bf \beta} \sum_{i=1}^N (y_i - {\bf x}_i^T {\bf \beta})^2$$ に等しい。


In [ ]: