- 印刷する
- PDF
Keras text classification
- 印刷する
- PDF
Classic/VPC環境で利用できます。
このノートブックは、映画レビュー(review)テキストをポジティブ(positive)またはネガティブ(negative)に分類します。この例は、二進(binary)-またはクラス(class)が2つである- 分類問題です。二進分類は機械学習において重要なイシューで、広く使われます。
ここでは、インターネット映画データベース(Internet Movie Database)で収集した50,000件の映画レビューテキストを盛り込んだIMDBデータセットを使用します。25,000件のレビューは訓練用に、25,000件はテスト用に分かれています。訓練セットとテストセットのクラスはバランスがとれています。すなわち、ポジティブなレビューとネガティブなレビューの数が一致します。
このノートブックは、モデルを作成して訓練するためにTensorFlowの高レベルPython APIであるtf.kerasを使用します。tf.kerasを使用した高度なテキスト分類チュートリアルは、MLCCテキスト分類ガイドをご参照ください。
import tensorflow as tf
from tensorflow import keras
import numpy as np
print(tf.__version__)
# 2.3.0
IMDBデータセットのダウンロード
IMDBデータセットはTensorFlowとともに提供されます。レビュー(単語のシーケンス(sequence))は、あらかじめ前処理して整数シーケンスに変換されています。各整数は、語彙辞典にある特定の単語を意味します。
以下のコードは、IMDBデータセットをコンピュータにダウンロードします。(または、過去にダウンロードした場合、キャッシュされたコピーを使用します):
imdb = keras.datasets.imdb
(train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000)
パラメータのnum_words=10000は、訓練データでもっとも頻繁に登場する上位10,000個の単語を選択します。データのサイズを適切に維持するために、稀に登場する単語は除外します。
データの探索
ではデータの形式を見てみましょう。このデータセットのサンプルは前処理された整数配列です。この整数は、映画レビューに登場する単語を表します。ラベル(label)は整数の0または1です。0はネガティブなレビューで、1はポジティブなレビューです。
print(「訓練サンプル:{}、ラベル:{}」.format(len(train_data), len(train_labels)))
# 訓練サンプル:25000、ラベル:25000
レビューのテキストは、語彙辞典の特定の単語を表す整数に変換されています。1番目のレビューを確認してみます。
print(train_data[0])
# [1, 14, 22, 16, 43, 530, 973, 1622, 1385, 65, 458, 4468, 66, 3941, 4, 173, 36, 256, 5, 25, 100, 43, 838, 112, 50, 670, 2, 9, 35, 480, 284, 5, 150, 4, 172, 112, 167, 2, 336, 385, 39, 4, 172, 4536, 1111, 17, 546, 38, 13, 447, 4, 192, 50, 16, 6, 147, 2025, 19, 14, 22, 4, 1920, 4613, 469, 4, 22, 71, 87, 12, 16, 43, 530, 38, 76, 15, 13, 1247, 4, 22, 17, 515, 17, 12, 16, 626, 18, 2, 5, 62, 386, 12, 8, 316, 8, 106, 5, 4, 2223, 5244, 16, 480, 66, 3785, 33, 4, 130, 12, 16, 38, 619, 5, 25, 124, 51, 36, 135, 48, 25, 1415, 33, 6, 22, 12, 215, 28, 77, 52, 5, 14, 407, 16, 82, 2, 8, 4, 107, 117, 5952, 15, 256, 4, 2, 7, 3766, 5, 723, 36, 71, 43, 530, 476, 26, 400, 317, 46, 7, 4, 2, 1029, 13, 104, 88, 4, 381, 15, 297, 98, 32, 2071, 56, 26, 141, 6, 194, 7486, 18, 4, 226, 22, 21, 134, 476, 26, 480, 5, 144, 30, 5535, 18, 51, 36, 28, 224, 92, 25, 104, 4, 226, 65, 16, 38, 1334, 88, 12, 16, 283, 5, 16, 4472, 113, 103, 32, 15, 16, 5345, 19, 178, 32]
映画レビューは長さがまちまちです。以下のコードは、1番目のレビューと2番目のレビューの単語数を出力します。ニューラルネットワークの入力は同じ長さである必要があります。後にこの問題を解決します。
len(train_data[0]), len(train_data[1])
# (218, 189)
整数を単語に再び変換する
整数を再度テキストに変換する方法があれば、有効活用できるでしょう。ここでは、整数と文字列をマッピングしたディクショナリ(dictionary)オブジェクトにクエリするヘルパー(helper)関数を作成します。
# 単語と整数インデックスをマッピングしたディクショナリ
word_index = imdb.get_word_index()
# 最初のいくつかのインデックスは辞典に定義されています。
word_index = {k:(v+3) for k,v in word_index.items()}
word_index["<PAD>"] = 0
word_index["<START>"] = 1
word_index["<UNK>"] = 2 # unknown
word_index["<UNUSED>"] = 3
reverse_word_index = dict([(value, key) for (key, value) in word_index.items()])
def decode_review(text):
return ' '.join([reverse_word_index.get(i, '?') for i in text])
"""
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/imdb_word_index.json
1646592/1641221 [==============================] - 0s 0us/step
"""
decode_review関数を使用して1番目のレビューテキストを出力できるようになりました。
decode_review(train_data[0])
# "<START> this film was just brilliant casting location scenery story direction everyone's really suited the part they played and you could just imagine being there robert <UNK> is an amazing actor and now the same being director <UNK> father came from the same scottish island as myself so i loved the fact there was a real connection with this film the witty remarks throughout the film were great it was just brilliant so much that i bought the film as soon as it was released for <UNK> and would recommend it to everyone to watch and the fly fishing was amazing really cried at the end it was so sad and you know what they say if you cry at a film it must have been good and this definitely was also <UNK> to the two little boy's that played the <UNK> of norman and paul they were just brilliant children are often left out of the <UNK> list i think because the stars that play them all grown up are such a big profile for the whole film but these children are amazing and should be praised for what they have done don't you think the whole story was so lovely because it was true and was someone's life after all that was shared with us all"
データの準備
レビュー-整数配列-は、ニューラルネットワークに注入する前に、Tensorに変換されている必要があります。変換する方法はいくつかあります。
- ワンホットエンコーディング(one-hot encoding)は、整数配列を0と1でできているベクトル に変換します。例えば、配列[3, 5]を、インデックス3と5だけ1で、残りはすべて0である10,000次元ベクトルに変換することができます。次に、実数ベクトルデータを扱える層-Dense層-をニューラルネットワークの1番目の層として使用します。この方法はnum_words * num_reviewsサイズの行列が必要であるため、多くのメモリを使います。
- 他の方法では、整数配列の長さをすべて同じくするために、パディング(padding)を追加してmax_length * num_reviewsサイズの整数Tensorを作成します。こういった形式のTensorを扱えるエンベディング(embedding)層をニューラルネットワークの1番目の層として使用できます。
このチュートリアルでは2番目の方式を使用します。
映画レビューは同じ長さである必要があるため、pad_sequences関数を使用して長さを合わせます。
train_data = keras.preprocessing.sequence.pad_sequences(train_data,
value=word_index["<PAD>"],
padding='post',
maxlen=256)
test_data = keras.preprocessing.sequence.pad_sequences(test_data,
value=word_index["<PAD>"],
padding='post',
maxlen=256)
``
サンプルの長さを確認してみます。
```python
len(train_data[0]), len(train_data[1])
# (256, 256)
(パディングされた)1番目のレビューの内容を確認してみます。
print(train_data[0])
"""
[ 1 14 22 16 43 530 973 1622 1385 65 458 4468 66 3941
4 173 36 256 5 25 100 43 838 112 50 670 2 9
35 480 284 5 150 4 172 112 167 2 336 385 39 4
172 4536 1111 17 546 38 13 447 4 192 50 16 6 147
2025 19 14 22 4 1920 4613 469 4 22 71 87 12 16
43 530 38 76 15 13 1247 4 22 17 515 17 12 16
626 18 2 5 62 386 12 8 316 8 106 5 4 2223
5244 16 480 66 3785 33 4 130 12 16 38 619 5 25
124 51 36 135 48 25 1415 33 6 22 12 215 28 77
52 5 14 407 16 82 2 8 4 107 117 5952 15 256
4 2 7 3766 5 723 36 71 43 530 476 26 400 317
46 7 4 2 1029 13 104 88 4 381 15 297 98 32
2071 56 26 141 6 194 7486 18 4 226 22 21 134 476
26 480 5 144 30 5535 18 51 36 28 224 92 25 104
4 226 65 16 38 1334 88 12 16 283 5 16 4472 113
103 32 15 16 5345 19 178 32 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0]
"""