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。

Pandas⑤ (データフレーム 列の追加)

データフレーム 列の追加

データフレームに 列を追加 する場合は、次のように指定します。

 データフレーム[‘列名’] = [データ, データ, ・・・]

辞書型データに 新しいキーと値 を設定するときと同じような感じになります。

以下のサンプルでは、‘D’ という列とデータを追加しています。

[Google Colaboratory]

1
2
3
4
5
6
7
8
9
10
11
import pandas as pd
df = pd.DataFrame(
{'A': [10, 20, 30, 40, 50], # 列Aとその値
'B': [0.8, 1.6, 2.4, 4.3, 7.6], # 列Bとその値
'C': [-1, -2.6, -3.5, -4.3, -5.1] }, # 列Cとその値
index = ['r1', 'r2', 'r3', 'r4', 'r5'] # 行名を設定
)

df['D'] = [1, 2, 3, 4, 5]

df

[実行結果]

データフレームに 列とデータを追加 することができました。

Pandas④ (データフレーム 行の追加)

データフレーム 行の追加

データフレームに行を追加する場合、追加する行をデータフレームとして作成し、append メソッドで追加しまします。

追加するデータフレームは列名を同じにしておく必要があります。

列名が異なると新規の列として追加されるので注意が必要です。

[Google Colaboratory]

1
2
3
4
5
6
7
8
9
10
11
12
import pandas as pd
df1 = pd.DataFrame(
{'A': [10, 20, 30, 40, 50], # 列Aとその値
'B': [0.8, 1.6, 2.4, 4.3, 7.6], # 列Bとその値
'C': [-1, -2.6, -3.5, -4.3, -5.1] }, # 列Cとその値
)
df2 = pd.DataFrame(
{'A': [60, 70, 80, 90, 100], # 列Aとその値
'B': [10.2, 11.6, 12.4, 14.3, 17.6], # 列Bとその値
'C': [-6, -12.6, -13.5, -14.3, -15.1] }, # 列Cとその値
)
df1.append(df2) # df1にdf2を追加

[実行結果]

新規の行が追加されましたが、追加した行のインデックスが 0 から開始されています。

元の行のインデックスに続くようにするためには、appendメソッドの引数に ignore_index=True を指定する必要があります。

[Google Colaboratory]

1
df1.append(df2, ignore_index=True)  # 行インデックスを連続させる

[実行結果]

追加された行のインデックスが、元のデータから連続になっていることを確認できます。

indexオプションで行名を設定している場合は、追加する行データにも行名を付けてから追加します。

[Google Colaboratory]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import pandas as pd
df1 = pd.DataFrame(
{'A': [10, 20, 30, 40, 50], # 列Aとその値
'B': [0.8, 1.6, 2.4, 4.3, 7.6], # 列Bとその値
'C': [-1, -2.6, -3.5, -4.3, -5.1] }, # 列Cとその値
index = ['r1', 'r2', 'r3', 'r4', 'r5'] # 行名を設定
)
df2 = pd.DataFrame(
{'A': [60, 70, 80, 90, 100], # 列Aとその値
'B': [10.2, 11.6, 12.4, 14.3, 17.6], # 列Bとその値
'C': [-6, -12.6, -13.5, -14.3, -15.1] }, # 列Cとその値
index = ['r6', 'r7', 'r8', 'r9', 'r10'] # 行名を設定
)
df1.append(df2) # df1にdf2を追加する

[実行結果]

設定した行名にて、行が追加されていることを確認できます。

Pandas③ (データフレーム 行の取得)

データフレーム 行の取得

データフレーム から特定の行を取得するためには

データフレーム [ 開始行インデックス : 終了行の1つあとのインデックス ]

のように、開始位置終了位置を示すインデックスを指定します。

インデックスは 0 からカウントされます。

注意する点としては、終了位置を示すインデックスで、指定したインデックスよりも1つ手前までが抽出されます。

まずは、2行目から4行目までを抽出してみます。

[Google Colaboratory]

1
2
3
4
5
6
7
8
9
import pandas as pd
df = pd.DataFrame(
{'A': [10, 20, 30, 40, 50], # 列Aとその値
'B': [0.8, 1.6, 2.4, 4.3, 7.6], # 列Bとその値
'C': [-1, -2.6, -3.5, -4.3, -5.1] }, # 列Cとその値
index = ['row1', 'row2', 'row3', 'row4', 'row5'] # 行名を設定
)

df[1 : 4] # 2行目から4行目までを抽出

[実行結果]

次に、先頭の行から2行目までを抽出します。

[Google Colaboratory]

1
df[: 2]               # 先頭の行から2行目までを抽出

[実行結果]

また、行名 を指定して行を抽出することもできます。

[Google Colaboratory]

1
2
# 行名で抽出する
df['row1' : 'row3'] # row1からrow3までを抽出

[実行結果]