OpenPyXL① (Excelファイルを読み込む)

OpenPyXL

OpenPyXLは、Excelファイルの操作を行うことができる Pythonライブラリ です。

Excelファイルの読み込み

openpyxlモジュールの openpyxl.load_workbook関数 で、Excelファイルを開くことができます。

Google Colaboratory で実行する場合は、Excelファイルは事前に アップロード しておく必要があります。

ローカルで実行する場合には、ソースファイルと 同じフォルダ にExcelファイルをおいて下さい。

[Google Colaboratory]

1
2
3
4
import openpyxl                                 # openpyxlをインポート

book = openpyxl.load_workbook('テスト.xlsx') # Excelブックを取得
print(type(book)) # オブジェクトの種類を表示

[実行結果]

Excelファイルが読み込まれ、オブジェクトを定義しているクラス名の <class ‘openpyxl.workbook.workbook.Workbook’> が出力されました。

Pandas⑯ (重回帰分析/散布図)

重回帰分析/散布図

前回記事で作成した重回帰モデルが適切かどうかを 散布図と直線 を使って確認します。

まず、x軸・y軸ともに 実測値(売上額) をとった直線をプロットします。(6~8行目)

(NumPyの linspace関数 では、等差数列を生成します。)

次に、x軸を 実測値(売上額)、y軸を 予測値(売上額) にとった 散布図 を描画します。(10~13行目)

予測した値が実測値とぴったりであれば、すべてのドットが 直線上 に乗ることになります。

[Google Colaboratory]

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

predict = model.predict(x)
# x=yの直線を描画
plt.plot(np.linspace(min(y),max(y)), # x軸: yの値
np.linspace(min(y),max(y)) # y軸: yの値
)
# 実測値をヨコ軸、予測値をタテ軸にとった散布図を描画
plt.plot(y, # x軸: yの値
predict, # y軸: 予測値
'o'
)
plt.xlabel('y') # x軸ラベル
plt.ylabel('predict(y)') # y軸ラベル

[実行結果]

予測なので実測値との間に 誤差 がありますが、予測値の分布 は実測値(直線)にだいたいフィットしたものとなっていることが確認できます。

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)   # 標本標準偏差

[実行結果]