以下のサイトを参考に、重回帰分析をやってみました。
https://qiita.com/karaage0703/items/f38d18afc1569fcc0418
やりたいこと
ワインのアルコール度数を予測する
どうやって
2つの説明変数(密度と揮発酸)を使って学習
実装手順
- データの読みこみ
- データの可視化
- 正規化
- 重回帰分析
実装内容
参考にしたサイトでは、正規化と重回帰分析のステップで、複数の手法が取り上げられているが、今回はpandasの標準化+正規化なし重回帰分析を行う。
データの読み込み
import pandas as pd
df = pd.read_csv('winequality-red.csv', sep=';')
df.head()
x = df[['density', 'volatile acidity']]
y = df[['alcohol']]
x1 = df[['density']]
x2 = df[['volatile acidity']]
print(x.shape)
print(y.shape)
データの可視化
from mpl_toolkits.mplot3d import Axes3D #3Dplot
import matplotlib.pyplot as plt
import seaborn as sns
fig=plt.figure()
ax=Axes3D(fig)
ax.scatter3D(x1, x2, y)
ax.set_xlabel("x1")
ax.set_ylabel("x2")
ax.set_zlabel("y")
plt.show()
PickUP
from mpl_toolkits.mplot3d import Axes3D #3Dplot
内容
3次元のグラフを描画するモジュールのインポート
ポイント
アタリマエダガ、3次元のグラフだってあるし、pythonでの実行は可能
正規化
正規化とは、なにか
データを使いやすいように、整理したり変形したりすること
なぜ、正規化が必要なのか
単位や桁の違う入力変数どうしの、影響度合いを比べることができないから
pandasで正規化
xss_pd = (x - x.mean()) / x.std()
内容
説明変数の値から説明変数の平均を引いて、説明変数の不偏分散で割る
ポイント
pandasのstd()メソッドのデフォルトは、不偏分散になっている。
普通の分散を使いたいときは、引数にddof=1を渡す。
標準化についての整理
方法としては、3つ
- scikit-learnのStandardScalerを使う
- pandasを使う
- Numpyを使う
それぞれのデフォルト値が違う。
- scikit-learn: 分散
- pandas: 不偏分散
- numpy: 分散
だから、分散か不偏分散かを意識して標準化を行うことが重要
重回帰分析
先ほど、せっかく正規化したが、正規化なしの重回帰分析を行う。
from sklearn.linear_model import LinearRegression
import numpy as np
model_lr = LinearRegression()
model_lr.fit(x, y)
print(model_lr.coef_)
print(model_lr.intercept_)
print(model_lr.score(x, y))
fig=plt.figure()
ax=Axes3D(fig)
ax.scatter3D(x1, x2, y)
ax.set_xlabel("x1")
ax.set_ylabel("x2")
ax.set_zlabel("y")
mesh_x1 = np.arange(x1.min()[0], x1.max()[0], (x1.max()[0]-x1.min()[0])/20)
mesh_x2 = np.arange(x2.min()[0], x2.max()[0], (x2.max()[0]-x2.min()[0])/20)
mesh_x1, mesh_x2 = np.meshgrid(mesh_x1, mesh_x2)
mesh_y = model_lr.coef_[0][0] * mesh_x1 + model_lr.coef_[0][1] * mesh_x2 + model_lr.intercept_[0]
ax.plot_wireframe(mesh_x1, mesh_x2, mesh_y)
plt.show()
print(model_lr.coef_)
print(model_lr.intercept_)
print(model_lr.score(x, y))
PickUp
mesh_x1 = np.arange(x1.min()[0], x1.max()[0], (x1.max()[0]-x1.min()[0])/20)
内容
配列をつくる(中身は、x1の最大値・最小値・最大値から最小値を引いて20で割った値)
mesh_y = model_lr.coef_[0][0] * mesh_x1 + model_lr.coef_[0][1] * mesh_x2 + model_lr.intercept_[0]
内容
3次元グラフのy軸を求める
→理論的な説明が全くできない。
→特にイミフな単語たち
- mesh_x1(メッシュって?)
- intercept_(誰かのボール取ったん?)
まとめ
全体の流れはわかった。ただ、3次元のグラフとなると、途端に自分の語彙力では言語化できないことが多いと痛感した。mesh、interceptは日常的にも耳にする単語だけど、たぶん数学的な意味はきっと自分が思っているそれとは違うことはわかる。英語を学んでいたときも、大変であり楽しかった、この言葉ってもともとこんな意味だったんだという気付き。メッシュもインターセプトも、それぞれアパレル、スポーツ発の言葉ではないだろうから、そういう言語を学ぶ醍醐味を楽しみながら学習を進めていきたい。