NLP(自然言語処理):pad_sequencesとTimeseriesGeneratorの初歩
NLP(自然言語処理):kerasとLSTMを用いて学習と予測を行うで,Kerasとmodel.fit()の使い方を学びました。
ここでは,pad_sequencesとTimeseriesGeneratorについて学びます。
pad_sequences
自然言語処理では入力される文はさまざまな長さになります。しかし,大量のデータを扱うためにはデータの長さがそろっていた方が効率よく処理できます。
そのため,リストに 0 を挿入して大きさをそろえます。
[[1 2 3]
[1 2 3 4 5 6]
[1 2 3 4]]
--->
[[1 2 3 0 0 0 0 0 0 0]
[1 2 3 4 5 6 0 0 0 0]
[1 2 3 4 0 0 0 0 0 0]]
pad_sequences()
を用いてパディングします。
例えば,さまざまな長さの文をベクトル化したリストtexts
を,文ごとの長さが30単語であるリストにそろえる場合,次のように書きます。
texts = sequence.pad_sequences(texts, maxlen=30, padding="post", truncating="post")
文章をベクトル化したリストtexts
をパディングし,再びtexts
に格納します。
texts =
[[1, 407, 813, 319, 432, 1697, 666, 4, 985, 5, 563, 3, 613, 5,
735, 3, 2599, 1, 525, 4, 526, 3622, 1, 814, 986, 2],
[1, 117, 338, 18, 2600, 3, 892, 2072, 815, 339, 2],
[1, 339, 20, 893, 10, 5, 167, 36, 1, 319, 6, 3623, 36, 1, 67, 320, 2]
......
]
pad_sequences -->
texts =
[[ 1 407 813 319 432 1697 666 4 985 5 563 3 613 5
735 3 2599 1 525 4 526 3622 1 814 986 2 0 0
0 0]
[ 1 117 338 18 2600 3 892 2072 815 339 2 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0]
[ 1 339 20 893 10 5 167 36 1 319 6 3623 36 1
67 320 2 0 0 0 0 0 0 0 0 0 0 0
0 0]
......
]
maxlen=30
はデータの数が30個であるという意味です。単語の数が30個以上の場合,後ろの単語がカットされます。
padding="post"
は0をデータの後ろに挿入します。pre
を指定するとデータの前に0を挿入します。
[1 2 3 4]
padding="pre" --> [0 0 0 1 2 3 4]
padding="post" --> [1 2 3 4 0 0 0]
truncating="post"
は,単語数が30を超えた場合に後ろの方をカットします。
TimeseriesGenerator
TimeseriesGeneratorを用いると,LSTMで必要な時系列データを簡単に用意することができます。
seq_length = 5
for line in range(len(texts)):
dataset = TimeseriesGenerator(texts[line], texts[line], length=seq_length, batch_size=1)
len(texts)
は文章の行数を表します。for
文で行ごとに時系列データを作成します。
texts[line]
が2つありますが,一つは入力データ,もう一つは答えのデータです。通常は,同じ文から入力と答えの両方を抽出するはずです。seq_length=5
はタイムステップの長さです。今回は,5つの連続した単語から次の単語を予測するので,タイムステップの長さは5です。
時系列データと答えがdataset
に格納されます。
texts = [1 2 3 4 5 6 7 8 9 10 ......]
X = [[1 2 3 4 5] Y = [[6]
[2 3 4 5 6] [7]
[3 4 5 6 7] [8]
......] ......]
batch_size
は次のようになります。
texts = [1 2 3 4 5 6 7 8 9 10 ......]
batch_size=1 -->
[[1 2 3 4 5]
[2 3 4 5 6]
[3 4 5 6 7] ......]
batch_size=2 -->
[[1 2 3 4 5]
[3 4 5 6 7]
[5 6 7 8 9] ......]
batch_size=3 -->
[[1 2 3 4 5]
[3 4 5 6 7]
[6 7 8 9 10] ......]
for batch in dataset:
X, Y = batch
x.extend(X[0])
y.extend(Y)
for
文を用いて,dataset
から入力X
と答えY
を取り出し,リストx
とy
に一つずつ追加します。
X
は2次元のリストなので,X[0]
として1次元のリストを追加します。
X = [[1 2 3 4 5]]
X[0]= [1 2 3 4 5]
結果,x
はタイムステップが並んだ一次元のリストになります。
x = [1 2 3 4 5 2 3 4 5 6 3 4 5 6 7 ......]
x = np.reshape(x,(int(len(x)/5),5,1))
LSTMの入力値は(バッチサイズ,タイムステップ,入力次数)の形状をとります。
np.reshapeでx
を3階のテンソルに変換します。
x = [[[1]
[2]
[3]
[4]
[5]]
[[2]
[3]
[4]
[5]
[6]]
[[3]
[4]
[5]
[6]
[7]] ......]
これで,LSTMに入力できる形状になりました。
SNSでシェア