ふらふら Diary (仮)

興味のあることを適当に書いていく感じです

irisで線形回帰

はじめに

線形回帰は予測を行うアルゴリズムである。scikit-learnライブラリで線形回帰をする方法についてirisデータセットを使ってまとめてみた。

線形回帰

「ある説明変数が大きくなるにつれて、目的変数も大きく(または小さく)なっていく」関係性をモデル化する手法。
以下の表のように、x が大きくなると y x の定数倍大きくなる状態をいう。

  • 説明変数:  x
  • 目的変数:  y
 x  y
1 2
2 4
3 6
4 8
アルゴリズム

 y = w_0 + w_1 x で表す。この  w_0 w_1 を求めることで、 x が決まれば  y が決まる状態になる。
平均二乗誤差
適切な  w_0 w_1 を求めるために平均二乗誤差を利用することで定量的に判断をすることができる。
平均二乗誤差とは、 n 個のデータが存在するとき、以下の式で表す。
 \dfrac{\Sigma^{n}_{i=1}\{y_i - (w_0 + w_1x_i) \}^2 }{n}
目的変数  y_i と直線  w_0 + w_1x_i の差を 2 乗し、その平均を計算したものとなる。
線形回帰はさまざまな直線のうち、平均二乗誤差が最小となる  w_0 w_1を求める。
分からなかった点としては、最小二乗法だと  \Sigma^n_{i=1}\{y_i - (w_0 + w_1x_i)\}^2 から求めるけど、なぜ平均二乗誤差の最小化と記述されているのかというところ。

具体例

irisのデータセットで線形回帰をしてみる。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.linear_model import LinearRegression

# irisデータセットの読み込み
data = load_iris()
df = pd.DataFrame(data.data, columns=data.feature_names)
df.head()
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm)
0 5.1 3.5 1.4 0.2
1 4.9 3.0 1.4 0.2
2 4.7 3.2 1.3 0.2
3 4.6 3.1 1.5 0.2
4 5.0 3.6 1.4 0.2

irisのデータセットにはあやめの sepal length(がくの長さ)、sepal width(がくの幅)、petal length(花弁の長さ)、petal width(花弁の幅)に加え、それぞれの品種(setosa、versicolor、virginica)の情報がある。
今回は品種 setosa のsepal length、sepal widthのデータを使用して線形回帰をしてみる。

# setosa の sepal length と sepal width の散布図をプロット
plt.scatter(df.iloc[:, 0][data.target == 0], df.iloc[:, 1][data.target == 0])
plt.xlabel(df.columns[0])
plt.ylabel(df.columns[1])
plt.show()

f:id:jetarinA:20200506143603p:plain
setosaのsepal lengthとsepal widthの散布図
何となく線形になっていることが分かる。

model = LinearRegression()

# 説明変数
X = df.iloc[:, 0][data.target==0].values.reshape(-1, 1)
# 目的変数
y = df.iloc[:, 1][data.target==0].values

# 学習
model.fit(X, y)
LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None, normalize=False)

切片と傾きを確認する。

# 切片
print(model.intercept_)
-0.5694326730396493
# 傾き
print(model.coef_)
[0.7985283]

回帰直線を引き確認する。

plt.scatter(X, y)
plt.plot(X, model.predict(X), color='red')
plt.xlabel(df.columns[0])
plt.ylabel(df.columns[1])
plt.show()

f:id:jetarinA:20200506145624p:plain
結果
ある程度当てはまっていること思われる。

おわりに

scikit-learnライブラリで線形回帰をする方法についてirisデータセットを使って記述した。決定係数や線形回帰がうまく当てはまらない例、重回帰については今後まとめていきたい。