Help us understand the problem. What is going on with this article?

時系列コンペでよく使用されるsin, cosへの変換とは

More than 1 year has passed since last update.

塩コンペに関しては、大会1位を飾ったphalanxさんが記事を書いているのでぜひとも参照してください!自分もやったことは記事内の2ヶ月〜最終日以外はほぼ同じです。

本題

時系列のコンペでは、特徴量として各訓練例が取得された時間や日付を組み込むことがあります。
しかしhourを例に考えてみると、23時の次は0時ですがこの間には数値的なつながりがありません。そこで循環性を考慮できるように三角関数を各特徴量に適用させます。

%matplotlib inline
import pandas as pd
import numpy as np

dates = pd.date_range(start='2017-01-01', end='2017-12-31', freq='H')
df = pd.DataFrame(data=np.zeros(len(dates)), index=dates, columns=['test'])
df.head()

使用DF.PNG

これで2017年1月から12月まで24時間ごとの特徴量を作成することができました。
インデックスから時系列の情報を抽出します。

df['year']  = df.index.year
df['month'] = df.index.month
df['day']   = df.index.day
df['hour']  = df.index.hour
df['dow']   = df.index.dayofweek

これで時系列の情報を抽出できました。

df[df.index.month == 1]['dow'].plot(grid=True)

通常のdow.png

これで1月の曜日の情報を見てみると、日曜日(dow==6)の次が月曜日(dow==0)になっており、隣り合った日であっても数値的には隣り合っていません。
そこで循環性を持つように三角関数を使用して特徴量を変換します。

def encode(df, col):
    # この方法だと場合によって最大値が変化するデータでは正確な値は出ない
    # 例:月の日数が30日や31日の場合がある
    df[col + '_cos'] = np.cos(2 * np.pi * df[col] / df[col].max())
    df[col + '_sin'] = np.sin(2 * np.pi * df[col] / df[col].max())
    return df

df = encode(df, 'dow')
df = encode(df, 'hour')
df = encode(df, 'day')
df = encode(df, 'month')

実際に高校でやったように三角関数を図に出力してみると、各特徴量が循環性を持っていることがわかります。

# 例:月の循環性
df.plot.scatter('month_sin', 'month_cos').set_aspect('equal')

通常のdowの円.png

なおよりデータを細かくしたいときは、一つ小さな時系列情報を組み込めば表現はできます。

df['dow+hour'] = df['dow'] + df['hour'] / 24
df = encode(df, 'dow+hour')
df.plot.scatter('dow+hour_sin', 'dow+hour_cos').set_aspect('equal')

通常のdowhourの円.png

参考文献

shimopino
Sierに新卒入社したエンジニア
nssol
お堅いと評判のユーザ系SIerです。※各記事の内容は個人の見解であり、所属する組織の公式見解ではありません。
https://www.nssol.nipponsteel.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした