Pythonで線形回帰の重回帰分析を行う方法【機会学習】

Pythonで線形回帰の重回帰分析を行う方法【機会学習】 プログラミング

この記事では、Pythonで重回帰分析を簡単に行う方法を説明しています。
そのため、「重回帰分析とは?」という小難しいことは書いていません。

「とりあえず、Pythonで重回帰分析を試したい」人向けの記事内容です。
そして、そのための環境構築やプログラムについて説明しています。

あとは、標準化についても理解できるようになります。
実際の数値とともに説明しており、イメージしやすいと思います。

本記事の内容

  • Pythonで重回帰分析を行うための環境
  • とりあえず、Pythonで重回帰分析を行う
  • 重回帰分析の精度(回帰係数・決定係数)
  • Pythonで線形回帰の重回帰分析を行う方法【機会学習】のまとめ

まずは、今回の記事で利用している環境の説明からです。

Pythonで重回帰分析を行うための環境

  • Windows 10 Home (バージョン1909)※以下の説明は64bit前提
  • Python 3.7.3
  • NumPy 1.18.5
  • Pandas 0.24.2
  • Matplotlib 3.2.1
  • scikit-learn  0.20.3

Pythonの上記ライブラリは、すべてインストールしておいてください。
インストールコマンドを載せておきます。

pip install numpy
pip install matplotlib
pip install pandas
pip install scikit-learn

Matplotlibのグラフを日本語化対応していない場合は、以下の記事をご覧ください。
この記事を参考にすれば、日本語化対応が簡単にできます。

とりあえず、Pythonで重回帰分析を行う

折角なので、実際のデータで分析してみます。
以下のページで表示されているデータを利用します。
https://senkyo-local.info/m_ranking/
https://senkyo-local.info/f_ranking/

議員報酬が、次の項目により予測できるかどうか?

  • 都道府県
  • 財政力指数
  • 歳入
  • 人口
  • 面積
  • 人口密度

この場合、議員報酬が目的変数です。
そして、上記の項目が説明変数となります。

データを準備する

なお、上記で示した選挙サイトは私が開発したモノです。
そのため、スクレイピングをせず、データベースよりデータを取得しています。

815市区のデータをcity_info.csvに保存します。
city_info.csvの内容(最初の5行)は、以下。

モジュール読み込み

とりあえず、重回帰分析を行います。
そのために必要なモジュールをimportします。

import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression

データ読み込み

DataFrame (データフレーム)として、読み込みます。

# csv読み込み
df = pd.read_csv('./data/city_info.csv')

目的変数と説明変数を用意する

データフレームから抽出しています。

# 目的変数(Y)
Y = np.array(df['annual_income'])

# 説明変数(X)
col_name = ['prefecture_id', 'population', 'area', 'population_density', 'fiscal_index', 'revenue']
X = np.array(df[col_name])

訓練(学習)データとテストデータを用意する

train_test_splitにより、簡単に分割しています。

# データの分割(訓練データとテストデータ)
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.3, random_state=0)

test_size=0.3にして、各データを次の比率に分割です。
訓練データ:テストデータ = 7:3

分割時点での各変数の状態は、以下。

重回帰分析を実行する

これだけで重回帰分析ができるなんて、便利ですよね。
ライブラリの作成者に感謝です。

# モデル構築 
model = LinearRegression()

# 学習
model.fit(X_train, Y_train)

分析結果を確認する

結果を確認するコードは、以下。

# 回帰係数
coef = pd.DataFrame({"col_name":np.array(col_name),"coefficient":model.coef_}).sort_values(by='coefficient')

# 結果
print("【回帰係数】", coef)
print("【切片】:", model.intercept_)
print("【決定係数(訓練)】:", model.score(X_train, Y_train))
print("【決定係数(テスト)】:", model.score(X_test, Y_test))

とりあえず、ここまでのコードをすべて載せておきます。

import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression

# csv読み込み
df = pd.read_csv('./data/city_info.csv')

# 目的変数(Y)
Y = np.array(df['annual_income'])

# 説明変数(X)
col_name = ['prefecture_id', 'population', 'area', 'population_density', 'fiscal_index', 'revenue']
X = np.array(df[col_name])

# データの分割(訓練データとテストデータ)
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.3, random_state=0)

# モデル構築 
model = LinearRegression()

# 学習
model.fit(X_train, Y_train)

# 予測
#Y_pred = model.predict(X_test)

# 検証
#print(Y_test[:5])
#print(Y_pred[:5])

# 回帰係数
coef = pd.DataFrame({"col_name":np.array(col_name),"coefficient":model.coef_}).sort_values(by='coefficient')

# 結果
print("【回帰係数】", coef)
print("【切片】:", model.intercept_)
print("【決定係数(訓練)】:", model.score(X_train, Y_train))
print("【決定係数(テスト)】:", model.score(X_test, Y_test))

このコードの実行結果は、以下。

【回帰係数】              col_name   coefficient
5             revenue -6.946525e-03
1          population  7.678455e+00
3  population_density  1.792167e+02
2                area  1.116185e+03
0       prefecture_id  1.211776e+04
4        fiscal_index  2.778381e+06
【切片】: 3657613.4779733205
【決定係数(訓練)】: 0.7270440949040748
【決定係数(テスト)】: 0.7148728383097965

とりあえず、Pythonで重回帰分析ができました。
あくまで、スタートに立っただけですけどね。
でも、これだけのコードで重回帰分析ができることを確認できました。

次以降は、上記の分析の結果について触れていきます。
そのため、「重回帰分析とは?」という小難しい話に入ってしまいます。
興味のある方は、引き続きご覧ください。

重回帰分析の精度(回帰係数・決定係数)

重回帰分析の結果において、ポイントになるのは以下。

  • 回帰係数
  • 決定係数

分析結果をもとにして、これらの係数について解説していきます。

回帰係数

回帰係数は、目的変数への影響度を表しています。
その影響度により、どの説明変数が目的係数に影響を与えたかを判別します。

分析の結果は、以下です。


col_namecoefficient
5revenue-0.006946524906
1population7.678455288
3population_density179.2167402
2area1116.185493
0prefecture_id12117.76435
4fiscal_index2778381.231

これは、明らかに桁が違いますね。
この回帰係数のことを、偏回帰係数と言います。

それぞれの変数を標準化(※)していないのです。
だから、桁が異なる値になってしまっています。

このままでは、使い物になりません。
尺度が違うと表現すればよいかもしれません。

(※)標準化

標準化とは、「各生データの平均値との差」を標準偏差で割ったものです、
かなり大雑把に言うと、比率にして単位を揃えるようなイメージになります。

変数を標準化する

標準化について、論より証拠で実際のデータで確認しましょう。

標準化する前の説明変数(X):最初の5行

11.96E+061121.261743.980.739.87E+08
1258948677.873820.471.33E+08
1116516243.83477.860.445.57E+07
1337392747.66451.260.531.56E+08
18440581.011041.910.624.30E+07

標準化した後の説明変数(X):最初の5行

-1.585197.014583.00897-0.04507830.364487.158
-1.585190.4487121.44859-0.435846-0.7024250.535835
-1.58519-0.102531-0.0788783-0.408343-0.825529-0.0642061
-1.585190.7523081.6942-0.415975-0.4562160.715903
-1.58519-0.226808-0.651874-0.24651-0.0869031-0.163052

比較すれば、標準化の意味がわかりますね。
この標準化した変数を用いて、再び重回帰分析を行います。

標準化のために追加したのは、以下のコードです。
後で、また全コードを載せます。

from sklearn.preprocessing import StandardScaler

~

# 標準化
scaler = StandardScaler()
scaler.fit(np.array(df))
df_std = scaler.transform(np.array(df))
df_std = pd.DataFrame(df_std,columns=df.columns)

変数を標準化した分析結果(回帰係数)は、以下。


col_namecoefficient
5revenue-0.4354990372
0prefecture_id0.07687798468
2area0.1542165142
3population_density0.3037167989
4fiscal_index0.3292135998
1population0.9646640639

この回帰係数のことを標準化偏回帰係数と言います。
これで使えるデータになりました。

population(人口)が、目的変数(議員報酬)に最も影響を与えるようです。
revenue(歳入)は、もっとも影響を与えないことになります。

本当にこの結果が正しいのかどうか、別の角度から検証したいですね。
また、別の記事でやってみようと思います。

決定係数

決定係数は、その回帰分析の精度を表す指標です。

分析結果の決定係数(訓練)は、0.7270440949040748です。
適当に分析した割には、そこそこ精度の高い数値です。

目安としては、0.5以上のようです。
目標は、0.8という記述が多いですね。

その意味では、大した調整もせずに0.72以上はいい感じです。
幸先いい分析のスタートと言えるでしょう。

Pythonで線形回帰の重回帰分析を行う方法【機会学習】のまとめ

まず、完成したコードを載せておきます。

import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import StandardScaler

# csv読み込み
df = pd.read_csv('./data/city_info.csv')

# 標準化
scaler = StandardScaler()
scaler.fit(np.array(df))
df_std = scaler.transform(np.array(df))
df_std = pd.DataFrame(df_std,columns=df.columns)

# 目的変数(Y)
Y = np.array(df_std['annual_income'])

# 説明変数(X)
col_name = ['prefecture_id', 'population', 'area', 'population_density', 'fiscal_index', 'revenue']
X = np.array(df_std[col_name])

# データの分割(訓練データとテストデータ)
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.3, random_state=0)

# モデル構築 
model = LinearRegression()

# 学習
model.fit(X_train, Y_train)

# 回帰係数
coef = pd.DataFrame({"col_name":np.array(col_name),"coefficient":model.coef_}).sort_values(by='coefficient')

# 結果
print("【回帰係数】", coef)
print("【切片】:", model.intercept_)
print("【決定係数(訓練)】:", model.score(X_train, Y_train))
print("【決定係数(テスト)】:", model.score(X_test, Y_test))

Pythonで簡単に重回帰分析を行う方法を説明してきました。
実は、これは機械学習の説明でもあります。
もっと言うと、教師あり学習の機械学習です。

機械学習と聞くと構えてしまいませんか?
私は、どうしても構えてしまいますね。

だから、この記事で機械学習というワードをここまで使いませんでした。
機械学習というより、より精度の高い線形回帰の分析を行うことが目的でした。

それが重回帰分析でした。
そして、その重回帰分析は、機械学習だったということです。

このような感じで分析について進めていけば、ディープラーニングにも到達できるかもしれません。

タイトルとURLをコピーしました