特別講義DS Ch12 回帰分析の応用と一般化線形モデル
1 数量化
前章の重回帰分析では,すべての変数が量的データでした. しかし, 質的データがある場合にはどのように処理するのでしょうか.
説明変数に質的データを含める重回帰分析を数量化1類(Quantification Method Type I)といいます.
基本的に回帰分析における質的データは0/1
からなる擬似的な量的変数であるダミー変数に変換して処理しますがこのような数への変換を総じて数量化といいます.
数量化にはこの他にも,目的変数と説明変数がともに質的データの場合の数量化2類(Quantification Method Type Ⅱ), 説明変数に量的データが混ざっている場合の拡張型数量化2類などがあり,数量化3,4,5,6類なども存在します.
数量化2類に関してはロジスティック回帰,数量化3類に関しては主成分分析が同様の目的で利用されるため,これらに関しては本資料では扱いません.
例えば,以下のような身長と体重,性別,国籍からなるデータがあった場合,新たに性別,国籍の種別の列を設けて当てはまる行に1,当てはまらない行に0を入力する変換を行います.
- 変換前のデータ
id | 体重 | 身長 | 性別 | 国籍 |
---|---|---|---|---|
1 | 65 | 170 | 男 | 日本 |
2 | 58 | 174 | 女 | 米国 |
3 | 78 | 189 | 男 | オランダ |
… | … | … | … | … |
- ダミー変数に変換したデータ
id | 体重 | 身長 | 性別 男 | 日本 | 米国 | オランダ |
---|---|---|---|---|---|---|
1 | 65 | 170 | 1 | 1 | 0 | 0 |
2 | 58 | 174 | 0 | 0 | 1 | 0 |
3 | 78 | 189 | 1 | 0 | 0 | 1 |
… | … | … | … | … | … | … |
まずは,身長,体重,性別からなる,こちらのサンプルデータを利用して,身長,性別から体重を予測する数量化1類を試してみましょう.
まずはデータの確認をしてみます.
import pandas as pd
import matplotlib.pyplot as plt
import japanize_matplotlib
import seaborn as sns
import statsmodels.api as sm
#データの確認
= pd.read_csv('data/quantification.csv')
df print(df)
"""
Gender Height Weight BMI
0 Male 166.430341 71.355369 25.639518
1 Female 164.312585 57.693236 20.834761
2 Male 176.525613 66.619089 22.987388
3 Male 167.807888 52.236903 19.457056
4 Male 179.131402 71.557172 22.652586
.. ... ... ... ...
195 Female 172.033565 64.506115 21.188950
196 Female 158.857271 55.028631 23.924375
197 Male 176.701624 56.014221 20.232505
198 Male 167.925367 69.257515 24.074144
199 Male 172.024625 70.693532 25.084344
"""
データの特徴を見て見るために,クロスプロットを作成します. 質的変数を含めると上手く表現できないので除外しています.
'Height','Weight']], range_padding=0.2)
pd.plotting.scatter_matrix(df[[ plt.show()

また,男女別のプロットを同時に表示させるために,seaborn
のjoinplot
を利用してみましょう. joinplot
では,hue
に質的変数のヘッダーをしていすることで,それぞれの密度プロットを表示してくれます.
#joinplotで男女別に密度プロットを表示
= sns.jointplot(data = df
fig ="Height"
,x ="Weight"
,y ='Gender'
,hue= dict(alpha=0.5))
,joint_kws plt.show()

男女別に異なる分布であることが分かります. データをよく見てみると,男女で傾きが異なるように見えますが,数量化1類で扱えるのは男女別の切片の差のみです. 傾きを質的データに応じて変える場合には後に扱う一般化線形モデルの技法が必要となります.
比較のためにまずは通常の単回帰を行ってみましょう.今回は量的変数が一つしか無いため,正規化や多重共線性のチェックは行っていないことに注意しましょう. 変数が複数ある場合にはそれらの処理が必要になります.
#予測モデルを作成(単回帰)
= sm.add_constant(df['Height'])
X = sm.OLS(df['Weight'],df['Height'])
model = model.fit()
result print(result.summary())
"""
OLS Regression Results
=======================================================================================
Dep. Variable: Weight R-squared (uncentered): 0.980
Model: OLS Adj. R-squared (uncentered): 0.980
Method: Least Squares F-statistic: 9587.
Date: Wed, 09 Oct 2024 Prob (F-statistic): 2.67e-170
Time: 13:14:18 Log-Likelihood: -739.70
No. Observations: 200 AIC: 1481.
Df Residuals: 199 BIC: 1485.
Df Model: 1
Covariance Type: nonrobust
==============================================================================
coef std err t P>|t| [0.025 0.975]
------------------------------------------------------------------------------
Height 0.3981 0.004 97.913 0.000 0.390 0.406
==============================================================================
Omnibus: 22.723 Durbin-Watson: 2.211
Prob(Omnibus): 0.000 Jarque-Bera (JB): 27.460
Skew: 0.793 Prob(JB): 1.09e-06
Kurtosis: 3.882 Cond. No. 1.00
==============================================================================
"""
検定の結果も,予測精度もかなり高いことが分かりますが,ここに男女の違いをいれることで改善されるかをチェックしてみましょう.
数量化1類を行うためにGender
の列をダミー変数化してみます. pandas
では,get_dummies()
を利用することで簡単にダミー変数が作成できます dtype='int'
と指定することで,0/1
のダミー変数となります.省略した場合はTrue/False
の値となるので忘れないようにしましょう.
# カテゴリカルデータのダミー変数化
# get_dummies関数を使う(dtype='it'で0/1の数値に変換)
= pd.get_dummies(df[['Gender','Height']],dtype='int')
X print(X)
"""
Height Gender_Female Gender_Male
0 166.430341 0 1
1 164.312585 1 0
2 176.525613 0 1
3 167.807888 0 1
4 179.131402 0 1
.. ... ... ...
195 172.033565 1 0
196 158.857271 1 0
197 176.701624 0 1
198 167.925367 0 1
199 172.024625 0 1
"""
ダミー変数を利用した重回帰分析を行います. 今回は,男女の2値なので,作成したGender_Male
のみを利用します.
#予測モデルを作成(数量化1類)
= sm.add_constant(X)
X = sm.OLS(df['Weight'],X[['Height','Gender_Male']])
model = model.fit()
result print(result.summary())
"""
OLS Regression Results
=======================================================================================
Dep. Variable: Weight R-squared (uncentered): 0.985
Model: OLS Adj. R-squared (uncentered): 0.985
Method: Least Squares F-statistic: 6535.
Date: Wed, 09 Oct 2024 Prob (F-statistic): 1.62e-181
Time: 13:14:18 Log-Likelihood: -708.75
No. Observations: 200 AIC: 1421.
Df Residuals: 198 BIC: 1428.
Df Model: 2
Covariance Type: nonrobust
===============================================================================
coef std err t P>|t| [0.025 0.975]
-------------------------------------------------------------------------------
Height 0.3668 0.005 72.226 0.000 0.357 0.377
Gender_Male 10.3714 1.224 8.475 0.000 7.958 12.785
==============================================================================
Omnibus: 11.918 Durbin-Watson: 2.088
Prob(Omnibus): 0.003 Jarque-Bera (JB): 16.036
Skew: 0.403 Prob(JB): 0.000329
Kurtosis: 4.129 Cond. No. 350.
==============================================================================
"""
Adj. R-squared (uncentered)
とProb (F-statistic)
の双方が改善され,よりよいモデルができていることが分かります.
このように同一データで複数のモデルを比較し,より良いモデルを選ぶことをモデル選択といいます.
今回は,R-squared
などの値で比較していますが,本来はモデル選択においては,AIC
やBIC
の値を利用した比較を行います. この観点でもAIC
が減少していることから数量化モデルのほうが良いことが分かります. しかし,今回はあくまで数量化の紹介が目的なのでその詳細は割愛します.
モデル選択の詳細は後の一般化線形モデルの節で扱うので,興味がある方はそちらを読んでください.
2 時系列回帰
前の節で質的データの処理を扱ったように,データの分析ではデータの種類に応じて手法を選択する必要があります.
代表的な時間に関するデータ
点過程データ
データの発生時刻が記録されたデータを点過程(Point Process)データと言います. 代表的なものに購入された商品に関して,購入時点の日付とともに記録したPOS(Point of Sales)データなどがあります.
- コンビニPOSデータの例
商品名 | 単価 (円) | 個数 | 購入日時 |
---|---|---|---|
おにぎり | 120 | 2 | 2024-10-01 08:15 |
サンドイッチ | 350 | 1 | 2024-10-01 12:30 |
ペットボトル水 | 100 | 3 | 2024-10-01 14:45 |
カップラーメン | 220 | 1 | 2024-10-02 11:00 |
チョコレート | 150 | 2 | 2024-10-02 15:20 |
時系列データ
決まった時間単位毎に観測項目を集計したデータ時系列(Time Series)データといいます.
例えば, 上の点過程データを日毎,月ごとなど決まった時間単位で集計することで下のような時系列データとなります.
- 日ごとに集計した時系列データの例
日付 | 売上合計 (円) | 購入点数 | 購入回数 |
---|---|---|---|
2024-10-01 | 1060 | 6 | 3 |
2024-10-02 | 520 | 3 | 2 |
2.1 データの準備
以下,時系列回帰などの練習用データを準備します.
今回は,実データとして千葉商科大学の電力データを利用し,電力消費量から曜日や祝日を予測/判別してみましょう. 千葉商科大学では, 自然エネルギー100%大学の取り組みに関連して使用したエネルギーを電力の種別ごとに計測しています. 今回は2021年5月の1号館のデータを利用してみます.
ダウンロードしたデータを作業ディレクトリのデータフォルダに配置したら,いくつかの前処理を施します. まず, 元のデータを確認してみましょう.
import pandas as pd
= pd.read_csv('./data/energy_may_1.csv')
df print(df)
"""
Date 1-1L-1-1-1F西/1(照明):kWh ... 1号館動力盤1_T相/76_T(その他動力):kWh 1-太陽光発電量/82(発電):kWh
0 2021/05/01 0:00 0.000 ... 1.605610 0.0
1 2021/05/01 1:00 0.000 ... 1.555380 0.0
2 2021/05/01 2:00 0.000 ... 1.617734 0.0
3 2021/05/01 3:00 0.000 ... 1.612538 0.0
4 2021/05/01 4:00 0.000 ... 1.569237 0.0
.. ... ... ... ... ...
739 2021/05/31 19:00 0.175 ... 1.978000 0.0
740 2021/05/31 20:00 0.115 ... 1.844633 0.0
741 2021/05/31 21:00 0.000 ... 1.806529 0.0
742 2021/05/31 22:00 0.000 ... 1.811724 0.0
743 2021/05/31 23:00 0.000 ... 1.872346 0.0
"""
データが読み込めたようなのでまずは,列の情報を編集してみましょう. CSVファイルのヘッダーを確認してみると以下のようになっています.
#列を確認する
= list(df.columns)[1:] #Dateを除外
cols print(c) for c in cols]
["""
1-1L-1-1-1F西/1(照明):kWh
1-1L-1-2-1F西/2(照明):kWh
1-1L-1-3-1F西/3(照明):kWh
1-1L-1-4-1F西/4(照明):kWh
1-1L-1-5-1F西/5(照明):kWh
1-1L-1-6-1F西/6(照明):kWh
1-1L-1-7-1F~3Fロビー/7(照明):kWh
1-1L-1-8-1F西/8(照明):kWh
1-1L-1-9-1F西/9(照明):kWh
1-1L-1-10-1F西/10(照明):kWh
1-1L-2-11-1F東/11(照明):kWh
1-1L-2-12-1F東/12(照明):kWh
1-1L-2-13-1F東/13(照明):kWh
1-1L-2-14-1F東/14(照明):kWh
1-1L-2-15-1F東/15(照明):kWh
1-1L-2-16-1F東/16(照明):kWh
1-1L-2-17-1F東/17(照明):kWh
1-1L-11-18-1101教室/18(照明):kWh
1-1L-11-19-1101教室/19(照明):kWh
1-1L-11-20-1101教室/20(照明):kWh
1-1L-11-21-1101教室/21(照明):kWh
1-1L-11-22-1101教室/22(照明):kWh
1-1L-11-23-1101教室/23(照明):kWh
1-1L-12-24-1102教室/24(照明):kWh
1-1L-12-25-1102教室/25(照明):kWh
1-1L-13-26-1103教室/26(照明):kWh
1-1L-13-27-1103教室/27(照明):kWh
1-1L-14-28-1104教室/28(照明):kWh
1-1L-14-29-1104教室/29(照明):kWh
1-1L-14-30-1104教室/30(照明):kWh
1-1L-14-31-1104教室/31(照明):kWh
1-1L-14-32-1104教室/32(照明):kWh
1-1L-14-33-1104教室/33(照明):kWh
1-2L-1-34-2F西/34(照明):kWh
1-2L-1-35-2F西/35(照明):kWh
1-2L-1-36-2F西/36(照明):kWh
1-2L-1-37-2F西/37(照明):kWh
1-2L-1-38-2F西 1201共同研究室1_2照明/38(照明):kWh
1-2L-1-39-2F西/39(照明):kWh
1-2L-1-40-2F西/40(照明):kWh
1-2L-1-41-2F西 共同研究室3~6照明/41(照明):kWh
1-2L-2-42-2F東/42(照明):kWh
1-2L-2-43-2F東/43(照明):kWh
1-2L-2-44-2F東/44(照明):kWh
1-2L-2-45-1202~1204照明/45(照明):kWh
1-2L-2-46-2F東/46(照明):kWh
1-2L-2-47-2F東/47(照明):kWh
1-2L-2-48-1205~1207照明/48(照明):kWh
1-2L-H-49-1208教室/49(照明):kWh
1-2L-I-50-1209教室/50(照明):kWh
1-2L-J-51-1210教室/51(照明):kWh
1-2L-K-52-1211教室/52(照明):kWh
1-2L-L-53-1212教室/53(照明):kWh
1-3L-1-54-3F東/54(照明):kWh
1-3L-1-55-3F東/55(照明):kWh
1-3L-1-56-3F東 ラボスクウェア1_2照明/56(照明):kWh
1-3L-1-57 共同研究室7~9/57(照明):kWh
1-3L-1-58 ラボスクウェア1_2照明/58(照明):kWh
1-3L-1-59 3F東/59(照明):kWh
1-3L-1-60 3F東/60(照明):kWh
1-3L-1-61 共同研究室10~12/61(照明):kWh
1-3L-2-62 3F西/62(照明):kWh
1-3L-2-63 3F西/63(照明):kWh
1-3L-2-64 3F西 ラボスクウェア3_4照明/64(照明):kWh
1-3L-2-65 3F西/65(照明):kWh
1-3L-2-66 共同研究室13西照明/66(照明):kWh
1-3L-2-67 ラボスクウェア3_4照明/67(照明):kWh
1-3L-2-68 3F西/68(照明):kWh
1-3L-2-69 3F西/69(照明):kWh
1-3L-2-70 3F西/70(照明):kWh
1-3L-2-71 3F西 共同研究室13東照明/71(照明):kWh
1号館電灯盤1_R相/73(主幹):kWh
1号館電灯盤2_R相/74(主幹):kWh
1号館電灯盤3_R相/75(主幹):kWh
1号館動力盤1_R相/76(その他動力):kWh
1-GHP-77/77GHP(空調熱源):m3
1号館電灯盤1_T相/73_T(照明等その他):kWh
1号館電灯盤2_T相/74_T(照明等その他):kWh
1号館電灯盤3_T相/75_T(照明等その他):kWh
1号館動力盤1_T相/76_T(その他動力):kWh
1-太陽光発電量/82(発電):kWh
"""
#利用対象部分の抽出
print(list(set([c[c.find('(') : c.find(')')+1] for c in cols])))
# >>> ['(発電)', '(照明)', '(空調熱源)', '(照明等その他)', '(その他動力)', '(主幹)']
このデータでは1号館を「1F西/1,1F西/2」など分電盤毎に分割し,かつ電力の利用対象を「照明,主幹,空調熱源,照明等その他,その他動力,発電」の5種類に分けて記録しています. このうち「照明等その他」はコンセントなどの電源の利用を表しています. この分類は分析の練習用としては細かすぎるので,「照明,電源,動力,空調」の4つにまとめてみます.
# 列の整形
# 場所は無視して,照明(Lighting),電源(Others),動力(Power),空調(Air),だけに分ける
# '照明'を含む列の抽出
'Lighting'] = sum([df[x] for x in df.filter(like='(照明)').columns])
df[# ''を含む列の抽出
'Others'] = sum([df[x] for x in df.filter(like='(照明等その他)').columns])
df[# '動力'を含む列の抽出
'Power'] = sum([df[x] for x in df.filter(like='(その他動力)').columns])
df[# ‘空調'を含む列の抽出
'Air'] = sum([df[x] for x in df.filter(like='(空調熱源)').columns])
df[# 結合した列以外を削除
= df[['Date','Lighting', 'Others', 'Power', 'Air']]
df
# totalを追加
'Total'] = sum(df[x] for x in ['Lighting', 'Others', 'Power', 'Air'])
df[print(df)
"""
Date Lighting Others Power Air Total
0 2021/05/01 0:00 0.000 6.518 2.876935 0 9.394935
1 2021/05/01 1:00 0.000 6.490 2.835366 0 9.325366
2 2021/05/01 2:00 0.000 6.558 2.982589 0 9.540589
3 2021/05/01 3:00 0.000 6.444 2.932360 0 9.376360
4 2021/05/01 4:00 0.000 6.724 2.864810 0 9.588810
.. ... ... ... ... ... ...
739 2021/05/31 19:00 6.773 10.792 3.574950 0 21.139950
740 2021/05/31 20:00 3.743 8.120 3.257986 0 15.120986
741 2021/05/31 21:00 0.118 6.636 3.230273 0 9.984273
742 2021/05/31 22:00 0.000 6.148 3.083049 0 9.231049
743 2021/05/31 23:00 0.000 6.854 3.183508 0 10.037508
"""
一般的に,大学のイベントは時間割に沿って行われるため,電気使用量は曜日によって異なります.
そこで,曜日や祝日の情報を追加して情報量を増やしてみましょう.
datetime
型は,.weekday
属性で曜日が取得できます. .weekday
は0
が月曜日
,6
が日曜日
の数値で返ってくるので,分かりやすく文字列に変更します.
また,土日をHoliday
列で1とする,Holiday
フラグも作成します.
# 曜日の取得
print('曜日の取得')
import datetime as dt
# 日付をインデックスに変更
print(df.index) #現在は,行数がインデックスになっている
# RangeIndex(start=0, stop=744, step=1)
print('-'*10)
#indexを日付に変更
'Date', inplace=True)
df.set_index(print(df.index) # インデックスが変更できたことが確認できる
"""
Index(['2021/05/01 0:00', '2021/05/01 1:00', '2021/05/01 2:00',
'2021/05/01 3:00', '2021/05/01 4:00', '2021/05/01 5:00',
'2021/05/01 6:00', '2021/05/01 7:00', '2021/05/01 8:00',
'2021/05/01 9:00',
...
'2021/05/31 14:00', '2021/05/31 15:00', '2021/05/31 16:00',
'2021/05/31 17:00', '2021/05/31 18:00', '2021/05/31 19:00',
'2021/05/31 20:00', '2021/05/31 21:00', '2021/05/31 22:00',
'2021/05/31 23:00'],
dtype='object', name='Date', length=744)
"""
print('-'*10)
# 現在は日付と時間がただの文字列なので,datatime型に変換する
= pd.to_datetime(df.index)
df.index print(df.index)
"""
DatetimeIndex(['2021-05-01 00:00:00', '2021-05-01 01:00:00',
'2021-05-01 02:00:00', '2021-05-01 03:00:00',
'2021-05-01 04:00:00', '2021-05-01 05:00:00',
'2021-05-01 06:00:00', '2021-05-01 07:00:00',
'2021-05-01 08:00:00', '2021-05-01 09:00:00',
...
'2021-05-31 14:00:00', '2021-05-31 15:00:00',
'2021-05-31 16:00:00', '2021-05-31 17:00:00',
'2021-05-31 18:00:00', '2021-05-31 19:00:00',
'2021-05-31 20:00:00', '2021-05-31 21:00:00',
'2021-05-31 22:00:00', '2021-05-31 23:00:00'],
dtype='datetime64[ns]', name='Date', length=744, freq=None)
"""
print('-'*10)
# 曜日を入れる
'weekday'] = df.index.weekday
df[= { 0:'Mon'
dayOfWeek 1:'Tue'
, 2:'Wed'
, 3:'Thu'
, 4:'Fri'
, 5:'Sat'
, 6:'Sun'}
, 'weekday'] = df['weekday'].map(dayOfWeek)
df[
# 曜日を平日かどうかで分ける
'Holiday'] = 0
df[for i in df.index:
if 'Sat' == df.at[i,'weekday']:
'Holiday'] = 1
df.at[i,elif 'Sun' == df.at[i,'weekday']:
'Holiday'] = 1
df.at[i,else:
'Holiday'] = 0
df.at[i,print(df)
"""
Lighting Others Power Air Total weekday Holiday
Date
2021-05-01 00:00:00 0.000 6.518 2.876935 0 9.394935 Sat 1
2021-05-01 01:00:00 0.000 6.490 2.835366 0 9.325366 Sat 1
2021-05-01 02:00:00 0.000 6.558 2.982589 0 9.540589 Sat 1
2021-05-01 03:00:00 0.000 6.444 2.932360 0 9.376360 Sat 1
2021-05-01 04:00:00 0.000 6.724 2.864810 0 9.588810 Sat 1
... ... ... ... ... ... ... ...
2021-05-31 19:00:00 6.773 10.792 3.574950 0 21.139950 Mon 0
2021-05-31 20:00:00 3.743 8.120 3.257986 0 15.120986 Mon 0
2021-05-31 21:00:00 0.118 6.636 3.230273 0 9.984273 Mon 0
2021-05-31 22:00:00 0.000 6.148 3.083049 0 9.231049 Mon 0
2021-05-31 23:00:00 0.000 6.854 3.183508 0 10.037508 Mon 0
"""
1日の中でも授業時間とそうでない時間によって,消費電力の傾向は異なりそうです. 授業時間割を授業前(before_class),1~5時限,昼休み(break),授業後(after_class)として設定してみましょう.
ここまでの作業ができたら,energy_may_hour.csv
として保存してみます.
#授業時間割の情報を追加する
#2020年から
#https://www.cuc.ac.jp/dpt_grad_sch/graduate_sch/accounting/hours/index.html
#1時限 9:00~10:45
#2時限 10:55~12:40
#昼休み 12:40~13:30
#3時限 13:30~15:15
#4時限 15:25~17:10
#5時限 17:20~19:05
def time2CTime(x):
if 9 <= x.hour <= 11:
return '1'
elif 11 < x.hour <= 12:
return '2'
elif 12 < x.hour <= 13:
return 'break'
elif 13 < x.hour <= 15:
return '3'
elif 15 < x.hour <= 17:
return '4'
elif 17 < x.hour <= 20:
return '5'
else:
return 'after_class'
'period'] = df.index.map(lambda x : time2CTime(x))
df[print(df)
"""
Lighting Others Power Air Total weekday Holiday period
Date
2021-05-01 00:00:00 0.000 6.518 2.876935 0 9.394935 Sat 1 after_class
2021-05-01 01:00:00 0.000 6.490 2.835366 0 9.325366 Sat 1 after_class
2021-05-01 02:00:00 0.000 6.558 2.982589 0 9.540589 Sat 1 after_class
2021-05-01 03:00:00 0.000 6.444 2.932360 0 9.376360 Sat 1 after_class
2021-05-01 04:00:00 0.000 6.724 2.864810 0 9.588810 Sat 1 after_class
... ... ... ... ... ... ... ... ...
2021-05-31 19:00:00 6.773 10.792 3.574950 0 21.139950 Mon 0 5
2021-05-31 20:00:00 3.743 8.120 3.257986 0 15.120986 Mon 0 5
2021-05-31 21:00:00 0.118 6.636 3.230273 0 9.984273 Mon 0 after_class
2021-05-31 22:00:00 0.000 6.148 3.083049 0 9.231049 Mon 0 after_class
2021-05-31 23:00:00 0.000 6.854 3.183508 0 10.037508 Mon 0 after_class
"""
#保存
'data/energy_may_hour.csv',encoding='utf-8-sig') df.to_csv(
今回は1時間毎に集計したデータを時系列分析に用いますが,次の章などで日ごとに集計したデータを利用するので,日毎の集計データも作成しておきましょう.
datetime
型ではdate
によって日付が取得できます.
# 1時間ごとになっているので,一日ごとに集約
'Day'] = df.index.date
df[= df.set_index(df.index.date) # 時間の部分を削除
df print(df)
"""
Lighting Others Power Air Total Day
2021-05-01 0.000 6.518 2.876935 0 9.394935 2021-05-01
2021-05-01 0.000 6.490 2.835366 0 9.325366 2021-05-01
2021-05-01 0.000 6.558 2.982589 0 9.540589 2021-05-01
2021-05-01 0.000 6.444 2.932360 0 9.376360 2021-05-01
2021-05-01 0.000 6.724 2.864810 0 9.588810 2021-05-01
... ... ... ... ... ... ...
2021-05-31 6.773 10.792 3.574950 0 21.139950 2021-05-31
2021-05-31 3.743 8.120 3.257986 0 15.120986 2021-05-31
2021-05-31 0.118 6.636 3.230273 0 9.984273 2021-05-31
2021-05-31 0.000 6.148 3.083049 0 9.231049 2021-05-31
2021-05-31 0.000 6.854 3.183508 0 10.037508 2021-05-31
[744 rows x 6 columns]
"""
同じ日付によってまとめて集計するような作業はfor
文などでもできますが,pandas
のgroupby
メソッドが便利です. groupby('列名')
で指定した列名の同じデータごとにデータを区切ってくれます.
更に, .agg({'列名':'処理方法'})
を追記することでグループごとにデータを集計します.
処理方法は文字列で指定し, sum
(合計),mean
(平均),first
(最初の値)などが利用できます.
集計したデータはenergy_may_day.csv
として保存します.
# 一日単位で集計
= df.groupby('Day').agg({'Lighting':'sum'
df 'Others':'sum'
,'Power':'sum'
,'Air':'sum'
,'Total':'sum'
,'weekday':'first'
,'Holiday':'first'})
,= pd.to_datetime(df.index)
df.index print(df)
"""
Lighting Others Power Air Total weekday Holiday
Day
2021-05-01 57.8590 164.026 150.925638 1 373.810638 Sat 1
2021-05-02 61.3290 170.661 153.542773 0 385.532773 Sun 1
2021-05-03 52.5590 153.860 162.455036 0 368.874036 Mon 0
2021-05-04 27.1570 142.110 190.401666 0 359.668666 Tue 0
2021-05-05 14.9370 141.365 96.532341 0 252.834341 Wed 0
2021-05-06 151.5430 252.266 163.735893 0 567.544893 Thu 0
2021-05-07 137.5760 265.376 90.321215 4 497.273215 Fri 0
2021-05-08 96.8080 202.206 159.786805 4 462.800805 Sat 1
2021-05-09 67.1230 173.335 181.672136 4 426.130136 Sun 1
2021-05-10 124.4350 234.587 187.283113 1 547.305113 Mon 0
2021-05-11 150.7050 271.478 85.611779 1 508.794779 Tue 0
2021-05-12 115.1820 231.200 142.734788 1 490.116788 Wed 0
2021-05-13 137.8290 283.480 80.014654 1 502.323654 Thu 0
2021-05-14 125.5200 235.470 176.655242 4 541.645242 Fri 0
2021-05-15 100.0060 207.944 174.805418 6 488.755418 Sat 1
2021-05-16 62.9970 189.768 101.143069 1 354.908069 Sun 1
2021-05-17 134.4200 253.678 85.963373 4 478.061373 Mon 0
2021-05-18 139.2750 275.532 85.630823 6 506.437823 Tue 0
2021-05-19 111.7410 254.229 79.302779 3 448.272779 Wed 0
2021-05-20 134.6820 258.456 96.874422 0 490.012422 Thu 0
2021-05-21 134.7470 270.402 91.587337 15 511.736337 Fri 0
2021-05-22 85.1020 214.783 89.615409 6 395.500409 Sat 1
2021-05-23 66.4360 176.641 140.140173 4 387.217173 Sun 1
2021-05-24 140.0200 237.016 151.007045 11 539.043045 Mon 0
2021-05-25 133.2290 239.769 183.644077 14 570.642077 Tue 0
2021-05-26 111.7810 220.848 167.229426 11 510.858426 Wed 0
2021-05-27 135.5230 265.379 79.695086 1 481.597086 Thu 0
2021-05-28 132.4820 247.760 141.465190 4 525.707190 Fri 0
2021-05-29 131.5140 226.797 129.222198 12 499.533198 Sat 1
2021-05-30 70.8040 188.536 139.632687 5 403.972687 Sun 1
2021-05-31 123.7695 231.010 164.885098 6 525.664598 Mon 0
"""
'data/energy_may_day.csv',encoding='utf-8-sig') df.to_csv(
作成したデータは,それぞれ時間ごと,日ごととなります. 以下,これらのデータを利用して,時系列解析を実施していきます.
2.2 古典的時系列解析
2.3
3 一般化線形モデル(執筆中)
3.1 ロジスティック回帰
今回利用するデータは時系列データであり本来回帰や判別問題を直接利用するべき対象ではありません.
時系列データはトレンドや周期などの時系列のデータ構造を考慮した,時系列分析を行うべきですが,ここでは独立したデータとして扱っています.
判別を行うための基礎的な手法として目的変数に「成功/失敗」や「0/1」などのベルヌーイ分布に従う二項の質的変数を取り,目的変数の判別を行うロジスティック回帰があります.
なお,二項以上のクラスの識別を行うロジスティック回帰を多項ロジスティック回帰といいますが,ここでは二項の場合のみを扱います.