配列からスライド窓を取得するやつを書いた


はじめに

時系列データを機械学習させるときにスライド窓というのを使うらしいので、そういつやつを書いた。こんなんscikit-learnあたりが持ってるんじゃね?と思ってググったんだけど意外といいサンプルが出てこなかった。自分のググり力が低いせいに違いないが、時間がもったいないので自作することにしました。せっかく作ったので貼っておきます。


やりたいこと

こういう配列を

[10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]

こうしたい

[[10 11 12 13 14 15 16 17 18 19]

[11 12 13 14 15 16 17 18 19 20]
[12 13 14 15 16 17 18 19 20 21]
[13 14 15 16 17 18 19 20 21 22]
[14 15 16 17 18 19 20 21 22 23]
[15 16 17 18 19 20 21 22 23 24]
[16 17 18 19 20 21 22 23 24 25]
[17 18 19 20 21 22 23 24 25 26]
[18 19 20 21 22 23 24 25 26 27]
[19 20 21 22 23 24 25 26 27 28]
[20 21 22 23 24 25 26 27 28 29]]

要するに、指定した列数(上記は10)で一個ずつ値をずらした配列つくって最後の値までの分を行として並べたいわけである。こういうのをスライド窓(Sliding Window)というらしい。時系列データを機械学習するときの教師データとしてよく使われるみたいだ。あんまよくわかってないけど。


関数を書いた

こんな感じ。numpy.arangeがなければオレに光は射さなかっただろう


getSlidingWindow.py

import numpy as np

def getSlidingWindow(a, size, step=1):
if not ((type(size) == type(0)) and (type(step) == type(0))):
raise Exception("type(size) and type(step) must be int.")
if step > size:
raise Exception("step must not be larger than size.")
if size > len(a):
raise Exception("size must not be larger than array length.")
a = np.asarray(a)
h = ((len(a)-size)/step)+1
indexer = np.arange(size)[None, :] + step*np.arange(int(h))[:, None]
window = a[indexer]
return window


実行してみる


run.py

a = list(range(10,30))

print(a)
print('-----')
print(getSlidingWindow(a, 10))

結果は以下のようになる。期待通り

[10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]

-----
[[10 11 12 13 14 15 16 17 18 19]
[11 12 13 14 15 16 17 18 19 20]
[12 13 14 15 16 17 18 19 20 21]
[13 14 15 16 17 18 19 20 21 22]
[14 15 16 17 18 19 20 21 22 23]
[15 16 17 18 19 20 21 22 23 24]
[16 17 18 19 20 21 22 23 24 25]
[17 18 19 20 21 22 23 24 25 26]
[18 19 20 21 22 23 24 25 26 27]
[19 20 21 22 23 24 25 26 27 28]
[20 21 22 23 24 25 26 27 28 29]]

値をスライドするステップ数も指定可能


run.py

a = list(range(10,30))

print(a)
print('-----')
print(getSlidingWindow(a, 10, 3))

3つずれたスライド窓になる

[10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]

-----
[[10 11 12 13 14 15 16 17 18 19]
[13 14 15 16 17 18 19 20 21 22]
[16 17 18 19 20 21 22 23 24 25]
[19 20 21 22 23 24 25 26 27 28]]


まとめ

いまやりたいことにはこれで十分。いろいろな時系列データを処理してみたいと思います。