Pandas⑮ (重回帰分析)

重回帰分析

重回帰分析 は、2つ以上の 説明変数(予測に使うデータ) から1つの 目的変数(予測するデータ) を予測する手法です。

重回帰分析 では、説明変数の数はいくつでもかまいませんが、説明変数が意味のあるものでなければ数を増やしても意味がありません。

説明変数は、前回記事で実施したように 相関関係 を調べて相関の強いものを使用すると、予測の精度 を高めることができます。

サンプルコード

重回帰分析 を行うサンプルコードは下記のようになります。

重回帰分析単回帰分析 と同じように LinearRegressionオブジェクト に対して fitメソッド を実行することで行います。(11行目))

(CSVファイルは前回記事で使用したものを読み込みます。)

[Google Colaboratory]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import pandas as pd
import numpy as np
from sklearn import linear_model

# ファイルを読み込んでdfに格納
df = pd.read_csv('sales.csv')

x = df.iloc[:, 2:5] # 競合店、満足度、品揃え充実度の列
y = df['売上額'] # 売上額の列
model = linear_model.LinearRegression() # LinearRegressionオブジェクトを生成
model.fit(x, y) # 線形重回帰分析を実行

print('回帰係数:', model.coef_) # 係数aを取得
print('切片  :', model.intercept_) # 切片bを取得
print('決定係数:', model.score(x, y)) # 決定係数を取得

[実行結果]

回帰係数 は、それぞれの説明変数の係数(目的変数に与える影響)となります。

絶対値で考えると、満足度(1413.39) が売上に与える影響が一番大きいことが確認できます。

決定係数0.8024 となっており、3つの説明変数で 約80パーセント の確率で説明できることを表しています。

Pandas⑭ (相関を調べる)

相関を調べる

説明変数 として考えられる要因それぞれが 目的変数 とどれくらいの 相関があるかを調べます。

読み込むCSVファイルは以下の通りです。

20店舗について、各店舗ごとの売上額競合店(近隣の競合店の数)満足度(5段階評価)品揃え充実度(5段階評価)のデータになります。

sales.csv (文字コードUTF-8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
店舗,売上額,競合店,満足度,品揃え充実度
0,A店,7990,0,4,4
1,B店,8420,1,4,5
2,C店,3950,3,2,3
3,D店,6870,2,4,4
4,E店,4520,3,3,2
5,F店,3480,2,3,3
6,G店,8900,0,4,4
7,H店,6280,1,3,3
8,I店,8180,1,3,4
9,J店,5330,1,3,3
10,K店,3090,2,2,3
11,L店,8600,0,3,4
12,M店,3880,1,3,2
13,N店,7400,3,4,3
14,O店,4540,3,3,3
15,P店,3450,2,3,3
16,Q店,2350,3,2,2
17,R店,8510,1,4,4
18,S店,4450,3,3,3
19,T店,5320,2,3,2

相関関係を調べるにはNumPyの corrcoef関数 を使用します。

corrcoef関数 の引数には、相関を調べる2つのデータフレーム(列)を指定します。

[Google Colaboratory]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 3項目の要因の相関係数を調べる
import pandas as pd
import numpy as np
from sklearn import linear_model

# ファイルを読み込んでdfに格納
df = pd.read_csv('sales.csv')

# 競合店の数と売上額の相関係数を求める
print('競合店\n', np.corrcoef(df['競合店'], df['売上額']))
# 満足度と売上額の相関係数を求める
print('満足度\n', np.corrcoef(df['満足度'], df['売上額']))
# 品揃え充実度と売上額の相関係数を求める
print('品揃え充実度\n', np.corrcoef(df['品揃え充実度'], df['売上額']))

[実行結果]

競合店と売上額の相関-0.6692負の相関 になっていて、値が少ないほど売上が伸びる関係になっていることが分かります。

満足度と売上額の相関0.7756品揃え充実度と売上額の相関0.7803正の相関になっていて、値が増えるほど売上が伸びる関係になっています。

Pandas⑬ (決定係数)

決定係数

決定係数 とは、回帰モデルがどの程度データにフィットしているか、単回帰式がどの程度の確率で信頼できるのかを評価する指標です。

決定係数調整済み決定係数 に近づくほど、回帰モデル(直線) がデータによくフィットしていることになります。

決定係数 を算出するソースコードは次の通りです。
(前々回記事で作成した回帰モデルを利用しています。)

[Google Colaboratory]

1
2
# 決定係数R^2を求める
print(model.score(x[:, np.newaxis], y)) # 決定係数

[実行結果]

決定係数0 ≦ 決定係数 ≦ 1 の範囲の値をとりますので、 に近いほど回帰式の精度がよいことになります。

今回の結果は 0.9414 なので、かなり 精度が高い ことになります。

Pandas⑫ (回帰直線)

回帰直線

前回記事の続きとしまして、今回は 回帰直線 を描画してみます。

(CSVファイルの読み込みと回帰モデルは前回記事で実行したものを利用します。)

散布図 を描画して、その上に 回帰直線 を描きます。

[Google Colaboratory]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from matplotlib import pyplot as plt
%matplotlib inline

xx = np.arange(20, 40) # 20~40の等差数列を生成
yy = model.predict(xx[:, np.newaxis]) # 回帰分析結果でxxに対するy値を予測する

plt.plot(xx, yy, label='predicted') # 回帰直線をプロット
plt.plot(x, y, 'o', label='sales') # x、yの散布図をプロット

plt.xlabel('temp') # x軸のラベル
plt.ylabel('sale') # y軸のラベル

plt.xlim(20, 40) # x軸の範囲を設定
plt.ylim(0, 500) # y軸の範囲を設定

plt.legend() # 凡例を表示

[実行結果]

回帰直線 を表示することができました。

実測データの最高気温の最小値は24℃、最大値は35℃であり、この間では気温が 1℃上昇 すると、計算上 33.7408(回帰係数)ずつ売上が増えることを示しています。

Pandas⑪ (線形単回帰分析)

線形単回帰分析

機械学習ライブラリの scikit-learn を使って線形回帰モデルを作成い、単回帰分析 を行います。

線形回帰に予測を行うクラスとして linear_model.LinearRegression が用意されています。

このクラスの主なメソッドは下記の通りです。

メソッド 内容
fit(X, y [, sample_weight]) 線形回帰モデルの当てはめを実行。
get_params([deep]) 推定に用いたパラメータを取得
predict(X) 作成したモデルを利用して予測を実行
score(X, y [, sample_weight]) 決定係数R2 を出力。
set_params(**params) パラメータを設定

サンプルコード

csvファイルをデータフレームに読み込み、気温と売上数の 単回帰分析 を行うサンプルコードは次の通りです。

x に代入されるデータは、データフレームの Seriesオブジェクト から Numpyの配列(ndarray) に変換する必要があります。

定数 np.newaxis を、インデックスを指定するブラケットの中に置くことで、1次元配列やベクトルに対して 列次元が1の行列 にすることができます。(10行目)

[Google Colaboratory]

1
2
3
4
5
6
7
8
9
10
11
12
# 線形単回帰分析を実行
import pandas as pd
import numpy as np
from sklearn import linear_model

df = pd.read_csv('data1.csv')
x = df['最高気温'] # 説明変数のデータをxに代入
y = df['売上数'] # 目的変数のデータをyに代入
model = linear_model.LinearRegression() # LinearRegressionオブジェクトを生成
model.fit(x[:, np.newaxis], y) # 線形回帰分析を実行

print(model.coef_, model.intercept_) # 係数aと切片bを取得

読み込むCSVファイルは以下の通りです。

30日間の最高気温とその日の売上数がまとめられています。

data1.csv (文字コードUTF-8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
最高気温,売上数
26,84
25,61
26,85
24,63
25,71
24,81
26,98
26,101
25,93
27,118
27,114
26,124
28,156
28,188
27,184
28,213
29,241
29,233
29,207
31,267
31,332
29,266
32,334
33,346
34,359
33,361
34,372
35,368
32,378
34,394

[実行結果]

回帰係数 a切片 b が表示されました。

直線の傾きを示す回帰係数は 33.7408 という正の値なので、最高気温が高くなれば売上数が増加するという 正の相関 があることが分かります。

y軸との切片 を表す定数項は -760.877 と負の値となっており、x軸の最高気温が0度のときは y の値が大きくマイナスになることを示しています。

予測

最高気温が 25度、35度 のときの 売上数を予測 してみます。

[Google Colaboratory]

1
2
3
4
x1 = [[25]]
x2 = [[33]]
print(model.predict(x1)) # 気温が25度のときの売上予測
print(model.predict(x2)) # 気温が35度のときの売上予測

[実行結果]

気温が25度のとき 82.642、気温が35度のときは 352.569売上数の予測 を行うことができました。

Pandas⑩ (相関係数)

相関係数

相関係数 は、相関関係の強さ を数値化したものです。

相関係数 は、-1 ~ 1 までの値をとります。

相関係数が 正(プラス)の時は正の相関 があることになり、負(マイナス)の時は負の相関関係 があることになります。

相関の強弱の目安を以下の一覧にまとめます。

相関係数(絶対値) 相関の強さ
~0.3未満 ほとんど相関なし
0.3~0.5未満 弱い相関がある
0.5~0.7未満 相関がある
0.7以上 強い相関がある

サンプルコード

Numpy には相関関数を算出する corrcoef関数 があります。

csvファイルをデータフレームに読み込み、気温と売り上げ数の 相関係数 を算出します。

[Google Colaboratory]

1
2
3
4
5
6
7
8
9
import pandas as pd
import numpy as np

df = pd.read_csv('data1.csv') # CSVファイルの読み込み
x = df['最高気温'] # 1列目のデータをベクトルに代入
y = df['売上数'] # 2列目のデータをベクトルに代入

# 気温と売上数の相関係数を求める
np.corrcoef(x, y)

読み込むCSVファイルは以下の通りです。

30日間の最高気温とその日の売上数がまとめられています。

data1.csv (文字コードUTF-8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
最高気温,売上数
26,84
25,61
26,85
24,63
25,71
24,81
26,98
26,101
25,93
27,118
27,114
26,124
28,156
28,188
27,184
28,213
29,241
29,233
29,207
31,267
31,332
29,266
32,334
33,346
34,359
33,361
34,372
35,368
32,378
34,394

[実行結果]

相関係数は 0.97024837 と表示され、相関の強弱の一覧によると 強い相関 があることになります。

つまり、気温と売上の関係には十分に 強い相関関係 があることが分かりました。

Pandas⑨ (基本統計量/一括)

基本統計量(一括)

Pnadasdescribeメソッド を使うと、以下の 基本統計量 をまとめて算出できます。

  • データの個数
  • 平均値
  • 最大値と最小値
  • 標準偏差
  • 第1四分位数(25%)
  • 第2四分位数(50%)
  • 第3四分位数(75%)

[Google Colaboratory]

1
2
3
4
import pandas as pd
df = pd.read_csv('data1.csv') # CSVファイルの読み込み

df.describe() # 基本統計量

[実行結果]

データを値の大きさの順に並べて4等分したとき、区切り位置にある値が 四分位数 です。

第1四分位数(25%)は4等分した最下位の区切りの値、第2四分位数(50%)はその次の区切り位置(真ん中)になります。

第3四分位数(75%)は最上位の区切り位置です。

Pandas⑧ (基本統計量)

基本統計量

Pandas には、統計の基本データとなる 基本統計量 を求めるメソッドがデータフレームに用意されています。

前々回記事で準備したCSVファイルをデータフレームに読み込んで、基本統計量 を求めます。

[Google Colaboratory]

1
2
import pandas as pd
df = pd.read_csv('data1.csv') # CSVファイルの読み込み

平均

データフレームの各列の平均値は、meanメソッド で算出します。

[Google Colaboratory]

1
df.mean() # 平均

[実行結果]

meanメソッド の戻り値は、pandas.Seriesクラスのオブジェクト である1次元のベクトルとなっているので、個々の結果を抽出するには、ブラケットの中に 対象の列名 を指定します。

[Google Colaboratory]

1
2
m = df.mean()
m['最高気温']

[実行結果]

中央値

中央値を求めるには medianメソッド を使います。

[Google Colaboratory]

1
df.median() # 中央値

[実行結果]

分散

分散 を算出するには varメソッド を使用します。

デフォルトで算出されるのは 不偏分散 です。

[Google Colaboratory]

1
df.var()  # 不偏分散

[実行結果]

不偏推定量を用いない分散 を求める場合は、ddof=0 を指定します。

[Google Colaboratory]

1
df.var(ddof=0) # 標本分散

[実行結果]

標準偏差

標準偏差 を求めるには、stdメソッド を使います。

デフォルトで算出されるのは不偏分散から求めた 不偏標準偏差 です。

[Google Colaboratory]

1
df.std()          # 不偏標準偏差

[実行結果]

不偏推定量を用いない標準偏差 を求める場合は、ddof=0 を指定します。

[Google Colaboratory]

1
df.std(ddof=0)   # 標本標準偏差

[実行結果]

Pandas⑦ (散布図)

散布図

前回記事で読み込んだCSVファイルのデータを散布図で表示します。

グラフ作成のライブラリである matplotlib を使います。

Google Colaboratory (Jupyter notebook) でグラフを表示するために %matplotlib inline と宣言しています。(3行目)

この宣言によりソースコードの実行結果としてグラフを表示することができるようになります。

[Google Colaboratory]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# インポートとinlineの宣言
from matplotlib import pyplot as plt
%matplotlib inline

# CSVファイルの読み込み
df = pd.read_csv('data1.csv')

散布図の描画
plt.plot(df['最高気温'], # x軸は気温
df['売上数'], # y軸は売上数
'o' # ドットをプロット
)
plt.xlabel('temperature') # x軸ラベル
plt.ylabel('sales') # y軸ラベル

matplotlib.pyplot.plot関数 を使うとデフォルトで 折れ線グラフ を描画することができます。

第3引数に‘o’を指定することにより 散布図 で描画することができます。

[実行結果]

気温と売上の 散布図 を表示することができました。

Pandas⑥ (データフレーム/CSVファイル読み込み)

CSVファイルをデータフレームに読み込み

Pandas には、表形式のデータを DataFrameオブジェクト として読み込むための関数があります。

関数 内容
read_csv() カンマ区切りのファイルを読み込む。
read_table() タブ区切りのファイルを読み込む。

read_csvread_table は、データの区切り文字が異なるだけで、内部では同じ処理を使っています。

パフォーマンスに差はなく、引数の指定方法も同じです。

サンプルソース

CSVファイルデータフレームに読み込むサンプルソースは次の通りです。

[Google Colaboratory]

1
2
3
4
5
import pandas as pd

df = pd.read_csv("data.csv")

print(df) # データフレームを出力

読み込むCSVファイルは以下の通りです。

30日間の最高気温とその日の売上数がまとめられています。

data.csv (文字コードUTF-8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
最高気温,売上数
26,84
25,61
26,85
24,63
25,71
24,81
26,98
26,101
25,93
27,118
27,114
26,124
28,156
28,188
27,184
28,213
29,241
29,233
29,207
31,267
31,332
29,266
32,334
33,346
34,359
33,361
34,372
35,368
32,378
34,394

[実行結果]

CSVファイルデータフレームに読み込むことができました。

read_csv、read_tableのオプション

read_csvread_tableの主なオプションは以下の通りです。

オプション 内容
filepath_or_buffer 読み込み元のファイルパス、またはURLを指定。
sep 区切り文字。read_csvはデフォルトで ‘,’、read_tableはデフォルトで ‘\t’
delimiter sep の代わりに delimiter 引数でも区切り文字を指定可能。
デフォルトは None。
header ヘッダー行の行数を整数で指定。
デフォルトは ‘infer’。
names ヘッダー行をリストで指定。
デフォルトは None。
index_col 行のインデックスに用いる列番号。
デフォルトは None。
dtype 各列のデータ型。デフォルトは None。
例:{‘a’:np.float64, ‘b’:np.int32}
skiprows 先頭から読み込みをスキップする行数。
デフォルトは None。
skipfooter 末尾から読み込みをスキップする行数。
デフォルトは None。
nrows 読み込む行数。
デフォルトは None。
quotechar ダブルクォートなどでクォートされている場合のクォート文字。
デフォルトは ‘“‘
escapechar エスケープされている場合のエスケープ文字。
デフォルトは None。
comment コメント行の行頭文字を指定。指定した文字で始まる行は無視される。
デフォルトは None。
encoding 文字コード。’utf-8’、’cp932’、’shift_jis’、’euc_jp’などを指定。
デフォルトは None。