使用 Keras 处理文本以进行分类
Processing Text for Classification with Keras
我正在尝试使用 Keras 训练基本的文本分类神经网络。我从网站上下载了 12,500 条正面影评和 12,500 条负面影评。但是,我无法将数据处理成 Keras 可以使用的内容。
首先,我打开 25000 个文本文件并将每个文件存储到一个数组中。然后我通过这个函数 运行 每个数组(一正一负):
def process_for_model(textArray):
'''
Given a 2D array of the form:
[[fileLines1],[fileLines2]...[fileLinesN]]
converts the text into integers
'''
result = []
for file_ in textArray:
inner = []
for line in file_:
length = len(set(text_to_word_sequence(line)))
inner.append(hashing_trick(line,round(length*1.3),hash_function='md5'))
result.append(inner)
return result
目的是将单词转换为数字,使它们接近 Keras 模型可以使用的东西。
然后我将转换后的数字附加到一个数组中,同时将 0 或 1 作为标签附加到另一个数组中:
training_labels = []
train_batches = []
for i in range(len(positive_encoded)):
train_batches.append(positive_encoded[i])
training_labels.append([0])
for i in range(len(negative_encoded)):
train_batches.append(negative_encoded[i])
training_labels.append([1])
最后我将每个数组转换为 np 数组:
train_batches = array(train_batches)
training_labels = array(training_labels)
但是,我不太确定从这里到哪里去。我相信每条评论都是 168 个字。我不知道如何为这些数据创建合适的模型,或者如何使用 sklearn 将所有数字正确缩放到 0 到 1 之间。
我最困惑的事情是:我应该有多少层,每层应该有多少个神经元,以及第一层应该有多少输入维度。
我应该完全采用另一种方法吗?
这是一个很好的 Keras 教程和这个数据集:https://machinelearningmastery.com/predict-sentiment-movie-reviews-using-deep-learning/
您也可以使用Keras official tutorial for text classification。
它基本上从 IMDB 集中下载了 50k 条评论,均衡(一半正面,一半负面)。他们(随机)分割一半用于训练,一半用于测试,并将 10k (40%) 的训练示例作为验证集。
imdb = keras.datasets.imdb
(train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000)
评论已经在他们的单词字典表示中(即每个评论都是一个数字数组)。整个词典大约有 80k+ 个单词,但他们只使用前 10k 个最常用的单词(特定评论中的所有其他单词都映射到一个特殊的标记 - 未知('<UNK>'
))。
(在教程中,他们创建了一个反向单词词典 - 为了向您展示原始评论。但这并不重要。)
每条评论最多 256 个单词,因此他们对每条评论进行预处理并用 0(<PAD>
标记)填充以防它更短。 (填充完成 post,即在最后)
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)
他们的神经网络架构由 4 层组成:
- 输入嵌入层:获取一批评论,每个评论有 256 个向量,其编号为 [0, 10,000),并尝试找到一个 16 维向量(对于每个词)来表示它们。
- 全局平均池化层:对评论中的所有单词(16 维表示)进行平均,并为您提供一个 16 维向量来表示整个评论。
- 16 个节点的全连接密集层 - 'vanilla' NN 层。他们选择了 ReLu 激活函数。
- 1 个节点的输出层:具有 sigmoid 激活函数 - 给出一个从 0 到 1 的数字,表示它是 positive/negative 评论的置信度。
这是它的代码:
vocab_size = 10000
model = keras.Sequential()
model.add(keras.layers.Embedding(vocab_size, 16))
model.add(keras.layers.GlobalAveragePooling1D())
model.add(keras.layers.Dense(16, activation=tf.nn.relu))
model.add(keras.layers.Dense(1, activation=tf.nn.sigmoid))
然后他们拟合模型并运行它:
model.compile(optimizer='adam',
loss='binary_crossentropy',
metrics=['acc'])
history = model.fit(partial_x_train,
partial_y_train,
epochs=40,
batch_size=512,
validation_data=(x_val, y_val),
verbose=1)
总而言之——他们选择将原本可能是 10k 维的向量简化为只有 16 维,然后 运行 一个密集层 NN——他们获得了相当不错的结果 (87%)。
我正在尝试使用 Keras 训练基本的文本分类神经网络。我从网站上下载了 12,500 条正面影评和 12,500 条负面影评。但是,我无法将数据处理成 Keras 可以使用的内容。
首先,我打开 25000 个文本文件并将每个文件存储到一个数组中。然后我通过这个函数 运行 每个数组(一正一负):
def process_for_model(textArray):
'''
Given a 2D array of the form:
[[fileLines1],[fileLines2]...[fileLinesN]]
converts the text into integers
'''
result = []
for file_ in textArray:
inner = []
for line in file_:
length = len(set(text_to_word_sequence(line)))
inner.append(hashing_trick(line,round(length*1.3),hash_function='md5'))
result.append(inner)
return result
目的是将单词转换为数字,使它们接近 Keras 模型可以使用的东西。
然后我将转换后的数字附加到一个数组中,同时将 0 或 1 作为标签附加到另一个数组中:
training_labels = []
train_batches = []
for i in range(len(positive_encoded)):
train_batches.append(positive_encoded[i])
training_labels.append([0])
for i in range(len(negative_encoded)):
train_batches.append(negative_encoded[i])
training_labels.append([1])
最后我将每个数组转换为 np 数组:
train_batches = array(train_batches)
training_labels = array(training_labels)
但是,我不太确定从这里到哪里去。我相信每条评论都是 168 个字。我不知道如何为这些数据创建合适的模型,或者如何使用 sklearn 将所有数字正确缩放到 0 到 1 之间。
我最困惑的事情是:我应该有多少层,每层应该有多少个神经元,以及第一层应该有多少输入维度。
我应该完全采用另一种方法吗?
这是一个很好的 Keras 教程和这个数据集:https://machinelearningmastery.com/predict-sentiment-movie-reviews-using-deep-learning/
您也可以使用Keras official tutorial for text classification。
它基本上从 IMDB 集中下载了 50k 条评论,均衡(一半正面,一半负面)。他们(随机)分割一半用于训练,一半用于测试,并将 10k (40%) 的训练示例作为验证集。
imdb = keras.datasets.imdb
(train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000)
评论已经在他们的单词字典表示中(即每个评论都是一个数字数组)。整个词典大约有 80k+ 个单词,但他们只使用前 10k 个最常用的单词(特定评论中的所有其他单词都映射到一个特殊的标记 - 未知('<UNK>'
))。
(在教程中,他们创建了一个反向单词词典 - 为了向您展示原始评论。但这并不重要。)
每条评论最多 256 个单词,因此他们对每条评论进行预处理并用 0(<PAD>
标记)填充以防它更短。 (填充完成 post,即在最后)
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)
他们的神经网络架构由 4 层组成:
- 输入嵌入层:获取一批评论,每个评论有 256 个向量,其编号为 [0, 10,000),并尝试找到一个 16 维向量(对于每个词)来表示它们。
- 全局平均池化层:对评论中的所有单词(16 维表示)进行平均,并为您提供一个 16 维向量来表示整个评论。
- 16 个节点的全连接密集层 - 'vanilla' NN 层。他们选择了 ReLu 激活函数。
- 1 个节点的输出层:具有 sigmoid 激活函数 - 给出一个从 0 到 1 的数字,表示它是 positive/negative 评论的置信度。
这是它的代码:
vocab_size = 10000
model = keras.Sequential()
model.add(keras.layers.Embedding(vocab_size, 16))
model.add(keras.layers.GlobalAveragePooling1D())
model.add(keras.layers.Dense(16, activation=tf.nn.relu))
model.add(keras.layers.Dense(1, activation=tf.nn.sigmoid))
然后他们拟合模型并运行它:
model.compile(optimizer='adam',
loss='binary_crossentropy',
metrics=['acc'])
history = model.fit(partial_x_train,
partial_y_train,
epochs=40,
batch_size=512,
validation_data=(x_val, y_val),
verbose=1)
总而言之——他们选择将原本可能是 10k 维的向量简化为只有 16 维,然后 运行 一个密集层 NN——他们获得了相当不错的结果 (87%)。