0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

線形回帰分析してみる その1

Last updated at Posted at 2021-09-12

改訂履歴 
2021.09.13 タイトル変更
#1.今回の目的
はじめまして。Chimoと申します。
今回Qiitaに初めて記事を書いてみようと思います。

会社での調べものやE資格の勉強の際はいつもQiitaを除いており、皆様の記事に大変お世話になりました。
私ごときが投稿するのは非常に緊張しますが、頑張ります。

記事に関してご意見やご感想ございましたら、勉強になりますのでコメントいただけますと幸いです。

さて、今回は記事を書く練習を兼ね、Boston Housingのデータセットを用いて
住宅価格の線形回帰モデルを作ることを目標にしたいと思います。

#2.データセット読み込み「Boston Housing」
scikit-learnに付属するデータセットから、Boston Housingを読み込みます。

import numpy as np
import matplotlib.pyplot as plt
#%matplotlib inline で アウトプット行にグラフを表示できる様になるらしい
%matplotlib inline
from sklearn.datasets import load_boston

以下の様に変数XとYに読み込ませます。

boston = load_boston()
X=boston.data #各特徴量
Y=boston.target #目的変数
fname=boston.feature_names #各特徴量の名称

X,Y,fnameのデータを取り出すと、ちゃんとデータが入っていることが確認できます。

X[:,1] #スライスで0行目を表示

(結果)
array([ 18. , 0. , 0. , 0. , 0. , 0. , 12.5, 12.5, 12.5,
12.5, 12.5, 12.5, 12.5, 0. , 0. , 0. , 0. , 0. ,
~中略~
0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ,
0. , 0. ])

Y[:5] #0~4個目までの要素を表示

(結果)
array([24. , 21.6, 34.7, 33.4, 36.2])

fname #各特徴量の名前

(結果)
array(['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD',
'TAX', 'PTRATIO', 'B', 'LSTAT'], dtype='<U7')
#3.関数作成
##3.1 散布図表示
以下の通り散布図を表示させるための関数を作成します。

def plotdata(X,Y,num):
    plt.xlabel(fname[num],fontsize=14)
    plt.ylabel('住宅価格[千ドル]',fontsize=14,fontname="MS Gothic")
    plt.title(fname[num] + 'と住宅価格[千ドル]の関係',fontsize=14,fontname="MS Gothic")
    plt.scatter(X,Y,c='b')
    plt.draw()
    return

作った関数で"ZN"(*0)と価格の散布図を表示させると以下の通りです。

plotdata(X[:,1],Y,1)

(結果)
ZN.png

(*0)ZNは25,000 平方フィート以上の住居区画の占める割合

##3.2 仮説
次の式で仮説:h(線形回帰モデル)を定義します。
h = X * a + b
ここでXは入力データ,a,bはパラメータを示します。

def h(X,a,b):
    h = X * a + b
    return h

##3.3 目的関数
以下の通り目的関数:Jを実装します。(数式の載せ方がわからない・・w)

def J(h,Y):
    m = Y.size
    J = np.sum(( h - y )**2) / (2*m)
    return J

#4.線形回帰の学習
##4.1 用いる特徴量
13個の特徴量を散布図で見ると"RM"(*1)が住宅価格と相関してそうなので,
適当ですが特徴量はこちらを選ぶことにします。

plotdata(X[:,5],Y,5)

(結果)
RM.png
(*1)RMは住居の平均部屋数
##4.2 学習の実施
3で作成した仮説と目的関数の関数を用いて,最急降下法によりパラメータa,bを学習させます。
ここで再急降下法は目的関数Jを各パラメータで偏微分して求めます(数式の載せ方がry)。

結果から,学習したパラメータa,bと,コスト関数の下がり具合を示したグラフが得られます。
グラフによると,100~125回くらい学習すれば十分な様ですね。

m = X.size

c = [] #costの累計に用いる配列をクリア

alpha = 0.01 #学習率

a = 0 #パラメータを初期化
b = 0

for i in range(200): #200回学習
    H = h(X[:,5], a, b) #仮説にRM,パラメータ初期値を代入
    J = j(H,Y) #目的関数の値を計算
    
    c.append( J )#目的関数の値を累計
    
    a = a - alpha * np.sum(( H - Y) * X[:,5]) / m # 最急降下法によりパラメータを学習
    b = b - alpha * np.sum( H - Y) / m

plt.plot(c[0:200])#目的関数の値の類型をプロット
print('パラメータa:',a)
print('パラメータb:',b)

(結果)
パラメータa: 3.567989796463954
パラメータb: 0.4941873961329116
cost.png
#5.学習結果のプロットと考察
##5.1 学習結果のプロット
4.2にて学習した仮説h_resultをRMの散布図上に重ねてみます。

h_result = a * X[:,5] + b

plotdata(X[:,5],Y,5)
plt.xlim([0,10])
plt.ylim([0,52])
plt.plot(X[:,5],h_result, c='red')

(結果)
reg.png

学習回数を10→20→・・・90→100→200(おまけ)に連れ、仮説h_resultは以下gifの様にうごきました。
reg.gif

##5.2 考察
RMのプロットに対し、感覚的にはh_resultの傾きはもう少しきつい方がよさそうに思えます。
学習データの前処理を行わずに学習させたので、外れ値の影響を受けているものと推測しています。

#6.感想
初めて記事を書いてみましたが、とても楽しかったです。
数式の載せ方については調べておきたく思います・・・
次回以降でRMの前処理後の回帰や住宅価格の予測,重回帰等にも挑戦してみたいと思います。

以 上

0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?