0
2

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 5 years have passed since last update.

Lesson7: Regression まとめ Intro to Machine learning@Udacity

0
Posted at

概要

今までのレッスンで学んできたのは、すべてアウトプットが離散的(2値)だったが、数値を推定するものを回帰という。例えば、年齢から、年収を予測するようなもの。
下記の図の、赤い丸から直線を引くこと。
regression.jpg
Slope:直線の傾き
Intercept:切片

Coding it up!

上記のage-net worth問題を回帰で解く。
このプログラミングはUdacityに埋め込んであるpythonで、ブラウザで行う。ちなみにpython2系です。

studentMain.py
import numpy
import matplotlib
matplotlib.use('agg')

import matplotlib.pyplot as plt
from studentRegression import studentReg
from class_vis import prettyPicture, output_image
from ages_net_worths import ageNetWorthData

ages_train, ages_test, net_worths_train, net_worths_test = ageNetWorthData()

reg = studentReg(ages_train, net_worths_train)#studentReg()にてregression

plt.clf()
plt.scatter(ages_train, net_worths_train, color="b", label="train data")
plt.scatter(ages_test, net_worths_test, color="r", label="test data")
plt.plot(ages_test, reg.predict(ages_test), color="black")
plt.legend(loc=2)
plt.xlabel("ages")
plt.ylabel("net worths")

plt.savefig("test.png")
output_image("test.png", "png", open("test.png", "rb").read())

studentRegression.py

def studentReg(ages_train, net_worths_train):
    ### import the sklearn regression module, create, and train your regression
    ### name your regression reg
    ### your code goes here!
    from sklearn import datasets, linear_model
    reg = linear_model.LinearRegression()
    reg.fit(ages_train, net_worths_train)
    
    return reg

<出力>
regression_quiz.png

青い点がトレーニングデータで、赤い点がテストデータ。linear regression(線形回帰)が引いた線が、直線。いい感じにひけてますねー。テストデータはトレーニングデータで引いた回帰式が、どのくらい正しいか評価するのに使う(reg.score())。テストデータでスコアが低いと、過学習しているということ。

よく使うAttributesとmethodsの紹介

.coef_ : 回帰式の係数出力 .intercept_ : 切片を出力 .score(ages_test, Net_worths_tests) : テストデータでの精度出す。 .score(ages_train, net_worths_train) : トレーニングデータでの精度出して、テストデータと比べ、過学習か判定する。

回帰式の評価の仕方

どうやって回帰式:y = ax + b のa,bを決めているかというと、

\sum_{全トレーニングデータ} (トレーニングポイント-推定値)  

を最小化しているみたい。
最小化する方法はいくつかあって、有名なのは
・Ordinary Least Squares(OLS):最小二乗回帰
・Gradient descent:最急降下法

最小二乗法:Ordinary Least Squares(OLS)

最小二乗法の場合、実際にどうやって回帰式を求めているのかは
最小二乗法の意味と計算方法 - 回帰直線の求め方がわかりやすかった。

下記引用(数式かくの面倒だったので、スクリーンショト画像です)
数式.png
詳しくは上記リンク先参照。

なぜ誤差の計算の仕方が「絶対値の引き算」ではなく「二乗の引き算」なのかは、下記図参照。二乗しないと収束しないんですね。

regression.png

r sqeared:決定係数

学習して得られた回帰線をどうやって評価するか?すぐ思いつくのは評価方法に、SSE(Sum of Squared Error)を使うことだが、これだと、データ数が多ければ、それだけSSEも大きくなってしまう。そこで出てくるのは決定係数。
入力特徴量と出力の関係をどの程度よく表しているかを表現する。1に近いほどよく表している。
学習した予測器の評価に使う値。なのでclf.score(X,y)のメソッドで使える。

ここがすごくわかりやすかったです。
27-4. 決定係数と重相関係数
簡潔に言うと、

R^2 = \frac{\sum_{i=1}^{n}{(データのyの平均から推定値がどれだけ差があるか)^2}}{\sum_{i=1}^{n}{(データのy平均値と各データのyがどれだけ差があるか)^2}}

ポイントは、各データに対する推定値の平均からの差分(回帰変動)を各データの生のyの平均からの差分(全変動)で割っているので、データ数と比例して大きくならない点ですね。二乗しているのはおそらく、そうしないと二乗誤差の時と同じように収束しないからでしょう。

Multi-variate regression:多変量回帰

今までは入力-出力の関係が1vs1の場合を話ししてきたが、複数vs1の場合もある。

Mini-project

Enronデータセットを使って、さまざまな特徴量から、ボーナスの額を推定する回帰を行う。
後半には、outlier(外れ値)が、回帰に与える影響を見ていく。

参考はsklearn正式ドキュメントsklearn.linear_model.LinearRegression


### list the features you want to look at--first item in the 
### list will be the "target" feature
features_list = ["bonus","salary",]
data = featureFormat( dictionary, features_list, remove_any_zeroes=True)
target, features = targetFeatureSplit( data )

### training-testing split needed in regression, just like classification
from sklearn.cross_validation import train_test_split
feature_train, feature_test, target_train, target_test = train_test_split(features, target, test_size=0.5, random_state=42)
train_color = "b"
test_color = "r"


### Your regression goes here!
### Please name it reg, so that the plotting code below picks it up and 
### plots it correctly. Don't forget to change the test_color above from "b" to
### "r" to differentiate training points from test points.
# print(dictionary.items())

from sklearn import linear_model
reg = linear_model.LinearRegression()
print("**feature_train**\n"+str(feature_train))
print("**target_train**\n"+str(target_train))
reg.fit(feature_train,target_train)

print("slope:"+str(reg.coef_))
print("intercept:"+str(reg.intercept_))
score_tr = reg.score(feature_train,target_train)
print("score_train:"+str(score_tr))
score_te = reg.score(feature_test,target_test)
print("score_test:"+str(score_te))


Your regression goes here!以下を書いた。

<出力>
**feature_train**
[array([415189.]), array([243293.]), array([213625.]), array([184899.]), array([248546.]), array([221003.]), array([197091.]), array([261516.]), array([309946.]), array([248146.]), array([213999.]), array([278601.]), array([304110.]), array([269076.]), array([262663.]), array([272880.]), array([240189.]), array([339288.]), array([278601.]), array([265214.]), array([201955.]), array([251654.]), array([365038.]), array([330546.]), array([76399.]), array([229284.]), array([261879.]), array([329078.]), array([211844.]), array([267102.]), array([239502.]), array([211788.]), array([170941.]), array([273746.]), array([182245.]), array([262788.]), array([304588.]), array([271442.]), array([314288.])]
**target_train**
[1000000.0, 1500000.0, 1000000.0, 325000.0, 850000.0, 70000.0, 400000.0, 750000.0, 700000.0, 600000.0, 5249999.0, 800000.0, 2000000.0, 650000.0, 700000.0, 750000.0, 1250000.0, 8000000.0, 1350000.0, 600000.0, 4175000.0, 1100000.0, 1100000.0, 900000.0, 100000.0, 400000.0, 1000000.0, 750000.0, 200000.0, 1200000.0, 500000.0, 1700000.0, 350000.0, 1000000.0, 200000.0, 1000000.0, 2500000.0, 3100000.0, 800000.0]
slope:[5.44814029]
intercept:-102360.5432938796
score_train:0.04550919269952436
score_test:-1.48499241736851

regression_0.png
トレーニングデータで学習して傾きと切片出して、テストデータで直線引いてる。

Video44

3行目の
features_list = ["bonus","salary",]

features_list = ["bonus",“long_term_incentive”,]
に書き換えればよい。コードは上記。

<出力>
feature_train
[array([200000.]), array([100000.]), array([69223.]), array([1586055.]), array([1617011.]), array([300000.]), array([974293.]), array([156250.]), array([1617011.]), array([1294981.]), array([694862.]), array([300000.]), array([422158.]), array([323466.]), array([175000.]), array([125000.]), array([2234774.]), array([554422.]), array([335349.]), array([71023.]), array([554422.]), array([554422.]), array([75000.]), array([2035380.]), array([983346.]), array([275000.]), array([304805.])]
target_train
[325000.0, 750000.0, 1700000.0, 1200000.0, 2000000.0, 1000000.0, 1350000.0, 100000.0, 1500000.0, 3000000.0, 2600000.0, 700000.0, 600000.0, 400000.0, 200000.0, 400000.0, 200000.0, 100000.0, 600000.0, 600000.0, 1100000.0, 2000000.0, 300000.0, 8000000.0, 1150000.0, 300000.0, 4175000.0]
slope:[1.19214699]
intercept:554478.7562150093
score_train:0.21708597125777662
score_test:-0.5927128999498639
regression_longterm.png

トレーニングデータへのスコアは下がったが、テストデータに対しては上がっている。スコアだけを見ると特徴量としてはlong_term_incentiveのほうが優れていることがわかる。

Video46:外れ値

外れ値(Outliner)の影響を見てみるために、トレーニングデータに外れ値があると、どの程度回帰線が変化するのか見てみる。
外れ値があるテストデータ(赤)でトレーニングして(テストデータとトレーニングデータデータを入れ替えている)、プロットする為に、下記コードを足すよう指示あり。
reg.fit(feature_test, target_test)
plt.plot(feature_train, reg.predict(feature_train), color="b")
print("slope_new:"+str(reg.coef_))
を下のほうに足した。


### draw the scatterplot, with color-coded training and testing points
import matplotlib.pyplot as plt
for feature, target in zip(feature_test, target_test):
    plt.scatter( feature, target, color=test_color ) 
for feature, target in zip(feature_train, target_train):
    plt.scatter( feature, target, color=train_color ) 

### labels for the legend
plt.scatter(feature_test[0], target_test[0], color=test_color, label="test")
plt.scatter(feature_test[0], target_test[0], color=train_color, label="train")

### draw the regression line, once it's coded
try:
    plt.plot( feature_test, reg.predict(feature_test) )
except NameError:
    pass

### Video46で足すように指示されたコード###
reg.fit(feature_test, target_test)
plt.plot(feature_train, reg.predict(feature_train), color="b") 
print("slope_new:"+str(reg.coef_))
######

plt.xlabel(features_list[1])
plt.ylabel(features_list[0])
plt.legend()
plt.show()

<出力>
slope_new:[2.27410114]
regression_mini.png

左下に、短い回帰線が追加されている。トレーニングデータに対して、プロットしているので、回帰線の長さが、短いのはご愛敬。
確かに一番右の外れ値に影響されて、回帰線がかなり寝ているのがわかる。

感想

今回復習と記録のために2回目受けてみた。
最小二乗法で誤差計算しないと、回帰線が一意に決まらないことが直観的に示せたのは良かった!
決定係数は完全に忘れていたので、復習してよかった。

調べた英単語

constraint・・・n, 強制、圧 迫、束縛、制約
arbitrary・・・n, 任意の、恣意(しい)的な、勝手な
discrete・・・n, 分離した、不連続の(continuous vs discrete)
coefficient・・・n, 係数
shortcoming・・・n, 短所、欠点
hefty・・・adj, かなりの、重い、屈強な
ex)hefty bonus

0
2
0

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
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?