LoginSignup
36
45

More than 3 years have passed since last update.

tsfreshで時系列データの統計的処理を簡単に

Posted at

概要

時系列データを処理する機会があり、便利そうなものを発見したので、使い方のメモ。

以下の公式を参照。
tsfresh

tsfresh is a python package. It automatically calculates a large number of time series characteristics, the so called features. Further the package contains methods to evaluate the explaining power and importance of such characteristics for regression or classification tasks.

使い方

以下はJupyter Notebook上で実行しています。

ライブラリのインポート

!pip install tsfresh
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline

時系列データの作成

適当なダミーデータを作成。

timeline = np.arange(10000)

data = np.sin(timeline/100) + np.cos((timeline/100) * 3) + (np.random.rand(len(timeline)))*0.2

plt.plot(timeline[:1000], data[:1000])
plt.xlabel('time')
plt.ylabel('data')
plt.show()

image

feature_extractionで特徴量を計算

feature_calculatorsという関数があるので、これを使うと様々な特徴量を計算できる。
feature_extraction

import tsfresh.feature_extraction.feature_calculators as feature_calculators

range_data = data[:600]


mean_abs_change = feature_calculators.mean_abs_change(data)
# 前後のポイント間での差分の平均値
# np.mean(np.abs(np.diff(x))) と等しい

first_location_of_maximum = feature_calculators.first_location_of_maximum(data)
# 最大値が観測される位置

fft_aggregated = feature_calculators.fft_aggregated(data, [{'aggtype': 'skew'}])
# フーリエ変換

number_peaks = feature_calculators.number_peaks(data[:1000], 50)
# ピークの数

index_mass_quantile = feature_calculators.index_mass_quantile(data[:1000], [{'q': 0.5},{'q': 0.1}])
# パーセンタイル処理

linear_trend = feature_calculators.linear_trend(range_data, [{'attr': "slope"},{'attr': 'intercept'},{'attr': 'rvalue'}])
# 単純なトレンド分析。attrに関しては下記を参照
# https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.linregress.html

autocorrelation = feature_calculators.autocorrelation(data, 100)
# 自己相関の計算

この中のlinear_trendを使って、時系列データのトレンドを計算してみる。

trend = linear_trend[0][1] * timeline + linear_trend[1][1]

plt.plot(timeline[:600], data[:600])
plt.plot(timeline[:600], trend[:600])
plt.xlabel('time')
plt.ylabel('data')
plt.show()

image

当たり前だが、正しく計算できていそう。

まとめて特徴量を計算

個別にではなくて、とりあえずたくさん特徴量を計算したい場合は、extract_featuresを使えばよさそう。

from tsfresh import extract_features

# こちらはDataFrameではないといけないようなので変換する。
# 1つのデータフレーム内に複数の時系列データがある形を想定しているらしく、どのデータが時系列としてひとまとまりなのか識別するカラムが必要(column_idで指定)
# 今回は1種類しか入っていないので、すべて1にした
temp = pd.DataFrame(data, columns=['value'], dtype='float')

temp['id'] = 1
temp.head()

extracted_features = extract_features(temp, column_id='id')
display(extracted_features.columns)
Index(['value__abs_energy', 'value__absolute_sum_of_changes',
       'value__agg_autocorrelation__f_agg_"mean"__maxlag_40',
       'value__agg_autocorrelation__f_agg_"median"__maxlag_40',
       'value__agg_autocorrelation__f_agg_"var"__maxlag_40',
       'value__agg_linear_trend__f_agg_"max"__chunk_len_10__attr_"intercept"',
       'value__agg_linear_trend__f_agg_"max"__chunk_len_10__attr_"rvalue"',
       'value__agg_linear_trend__f_agg_"max"__chunk_len_10__attr_"slope"',
       'value__agg_linear_trend__f_agg_"max"__chunk_len_10__attr_"stderr"',
       'value__agg_linear_trend__f_agg_"max"__chunk_len_50__attr_"intercept"',
       ...
       'value__symmetry_looking__r_0.9',
       'value__symmetry_looking__r_0.9500000000000001',
       'value__time_reversal_asymmetry_statistic__lag_1',
       'value__time_reversal_asymmetry_statistic__lag_2',
       'value__time_reversal_asymmetry_statistic__lag_3',
       'value__value_count__value_-1', 'value__value_count__value_0',
       'value__value_count__value_1', 'value__variance',
       'value__variance_larger_than_standard_deviation'],
      dtype='object', name='variable', length=794)

これだけで794個も特徴量が計算できたらしい。

まとめ

numpy1行で終わるようなものも多いが、まとめて特徴量計算したいときには便利かもしれない。特にextract_features。
時間を見つけてもう少し使ってみたい。

36
45
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
36
45