特徴量からの周期性の抽出方法



<a href="https://signate.jp/competitions/24">SIGNATEのお弁当コンペ</a>やった時のコードの抜粋

日付を1~365に変換した後にsin,cosに分解
テストデータをpandasで生成後、matplotlibでグラフ上に変換した結果を描画しています。


```python
import pandas as pd
import numpy as np
import math


def convert_cos(x):
    #return np.cos(math.radians(x / 365))
    return np.cos(math.radians(90 - (x / 365)*360))

def convert_sin(x):
    #return np.cos(math.radians(x / 365))
    return np.sin(math.radians(90 - (x / 365)*360))

def datetime_extract(df,df_col='datetime'):

    df['cos_day']=df[df_col].dt.dayofyear
    df['cos_day'] =df['cos_day'].apply(convert_cos)
    df['sin_day']=df[df_col].dt.dayofyear
    df['sin_day'] =df['sin_day'].apply(convert_sin)
    
    return df
```


```python
days =pd.date_range(start='2019/1/1', end='2019/12/31', freq='D')
df = pd.DataFrame(days,columns=["date"])
```


```python
df.head()
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>date</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>2019-01-01</td>
    </tr>
    <tr>
      <th>1</th>
      <td>2019-01-02</td>
    </tr>
    <tr>
      <th>2</th>
      <td>2019-01-03</td>
    </tr>
    <tr>
      <th>3</th>
      <td>2019-01-04</td>
    </tr>
    <tr>
      <th>4</th>
      <td>2019-01-05</td>
    </tr>
  </tbody>
</table>
</div>




```python
df.info()
```

    <class 'pandas.core.frame.DataFrame'>
    RangeIndex: 365 entries, 0 to 364
    Data columns (total 1 columns):
    date    365 non-null datetime64[ns]
    dtypes: datetime64[ns](1)
    memory usage: 2.9 KB
    


```python
df = datetime_extract(df,df_col="date")
df.head()
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>date</th>
      <th>cos_day</th>
      <th>sin_day</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>2019-01-01</td>
      <td>0.017213</td>
      <td>0.999852</td>
    </tr>
    <tr>
      <th>1</th>
      <td>2019-01-02</td>
      <td>0.034422</td>
      <td>0.999407</td>
    </tr>
    <tr>
      <th>2</th>
      <td>2019-01-03</td>
      <td>0.051620</td>
      <td>0.998667</td>
    </tr>
    <tr>
      <th>3</th>
      <td>2019-01-04</td>
      <td>0.068802</td>
      <td>0.997630</td>
    </tr>
    <tr>
      <th>4</th>
      <td>2019-01-05</td>
      <td>0.085965</td>
      <td>0.996298</td>
    </tr>
  </tbody>
</table>
</div>




```python
import matplotlib.pyplot as plt
plt.axes().set_aspect('equal', 'datalim')
plt.plot(df.cos_day,df.sin_day)
plt.show()
```


![output_5_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200770/c03c6442-a326-fbd4-5ece-f703ce8f9e80.png)


kaggler-ja に<a href="https://colab.research.google.com/drive/10LsjANUm4HLOYgELfUK62dqNTIebr9b9">wakameさんの実装例</a>ありました。

KaggleのKernelだと<a href="https://www.kaggle.com/zeroblue/mad-scripts-battle-z/code">ここ</a>