ビッグデータを使って統計分析がしたい! 【データ分析編②OLSを使ってみる】

こんにちわ。井上です。

少し間が空いてしまいましたが、 データ分析編②です。

今回の目的は、pandasを使いデータを加工しstatsmodelsの最小二乗法(Ordinary Least Square)を使ってとある日付の電力使用量を予測してみます。

最後に分析結果と実際のデータが、一致したのかどうか検証してみます。

それでは、実際のデータを使って説明していきたいと思います。

用意するデータ

電力使用量データ 東京電力のホームページより取得
(2016/4/1 00:00~2016/8/13 23:00 1時間ごと)
天気データ 気象庁のホームページより取得
(東京の気温、2016/1/1~2016/8/13 1日の最低、最高気温)
※CSVデータとしてダウンロードできるので、プロジェクト内のcsvフォルダに配置しておきます。

以上の2つのデータを使って分析をしていきます。
それぞれの値を取得して加工するところを見ていきましょう。

電力使用量を取得するプログラム


def getPuData():

    # 使用電力量の取得
    power_usage = pd.read_csv('http://www.tepco.co.jp/forecast/html/images/juyo-2016.csv', 
                          skiprows=3, 
                          names=['date',  'time',  'actual'], 
                          encoding='Shift_JIS')

    # 日付と時間を合わせてキーとする
    dt_key = pd.to_datetime(power_usage['date']+' '+power_usage['time'])
    power_usage.index = dt_key

    # 日付のフォーマットを変更する(天気とマージするときのキー)
    date = pd.to_datetime(power_usage['date'])
    power_usage['date'] = date

    # 曜日を取得 0:mon、1:tue、2:wed、3:thu、4:fri、5:sut、6:sun
    power_usage['week'] = power_usage['date'].apply(lambda x: x.weekday())

    # 時間を削除(使用しない)
    del power_usage['time']

    # 日付ごとの最大値を取得する
    daily_max = power_usage.resample('D',  how='max',  kind='period')

    return daily_max

【解説】

4~7行目:
CSVデータを取得します。3行目まではヘッダー部になるので読み飛ばします。
3つのデータが取得できるので、ぞれぞれに名前を付けます。(日付、時間、値)

10行目以降:
取得したデータの加工を行います。
気温データとの紐付けや、1時間毎になっているデータを日毎に変更します。

気温を取得するプログラム


def getWeatherData():

    # 気温データの取得
    weather = pd.read_csv('C:/anaconda_pleiades/workspace/weather/csv/weather.csv', 
                          names=['date',  'temp_high',  'temp_low'])

    # 日付のフォーマットを変更する(使用電力量とマージするときのキー)
    dt = pd.to_datetime(weather['date'])
    weather['date'] = dt

    return weather

【解説】

4~5行目:
CSVデータを読み込みます。
3つのデータが取得できるので、ぞれぞれに名前を付けます。(日付、最高気温、最低気温)

8行目以降:
取得したデータの加工を行います。
電力データとの紐付けキーを作成します。

メイン関数と予測のプログラム

# mainメソッド
if __name__ == "__main__":

    # 電力データの取得
    power_usage_daily_max = getPuData()

    # 天気データの取得
    weather = getWeatherData()

    # 電力データと天気データをマージする
    data = pd.merge(power_usage_daily_max,  weather)

    # 説明変数の設定
    x = data[['week',  'temp_high',  'temp_low']]

    # 定数項を加える
    x = sm.add_constant(x,  prepend=False)

    # 目的変数の設定
    y = data['actual']

    # 最小二乗法で分析
    model = sm.OLS(y,  x)
    results = model.fit()

    # 結果の出力
    print(results.summary())

【解説】

11行目:
取得した2つのデータを、日付をキーにしてマージを行います。

14行目:
説明変数(分析をする要素)を決めます。

17行目:
切片を定義します。

20行目:
目的変数(予測する要素)を決めます。

23~24行目:
最小二乗法で分析を行います。

27行目:
結果の出力

【出力結果】
result

赤く囲んだ部分が予測で使用する切片と固定値になります。

予測してみる

予測日 :2016/8/19(金)
最高気温:32℃
最低気温:24℃
(8/15 19:00時点)

出力結果より計算を行うと、

予測 = -105.5226 * 6 + 28.5050 * 32 + 48.9081 * 24 + 2377.1443
   = 3830kW

さて、実際はどうなのでしょうか。

予測結果

予測日 :2016/8/19(金)
最高気温:33℃(予測より1℃上昇)
最低気温:25℃(予測より1℃上昇)

CSVをダウンロードして見てみると・・・・

result2
 
見事にはずれました!
10%以上ずれてますね。気温が予想よりも1℃高かったからでしょうか。

気温に実際の値をいれて計算してみます。

予測2 = -105.5226 * 6 + 28.5050 * 33 + 48.9081 * 25 + 2377.1443
   = 3907kW

これも全然合わないですね。
目的変数と説明変数の関係がマッチしていないのかもしれません。
お盆休みも関係していると思われます。

まとめ

いかがでしたでしょうか。
今回はOLS(最小二乗法)を使って予測をしてみました。

他にも予測方法はいくつかあるので、またご紹介できればと思います。
それにしても全然いい結果が出ないな……。

《関連記事》
ビッグデータを使って統計分析がしたい! 【準備編】
ビッグデータを使って統計分析がしたい! 【データ取得編】
ビッグデータを使って統計分析がしたい! 【グラフ表示編】
ビッグデータを使って統計分析がしたい! 【データ分析編①】

記事をシェア
MOST VIEWED ARTICLES