使用 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 层组成:

  1. 输入嵌入层:获取一批评论,每个评论有 256 个向量,其编号为 [0, 10,000),并尝试找到一个 16 维向量(对于每个词)来表示它们。
  2. 全局平均池化层:对评论中的所有单词(16 维表示)进行平均,并为您提供一个 16 维向量来表示整个评论。
  3. 16 个节点的全连接密集层 - 'vanilla' NN 层。他们选择了 ReLu 激活函数。
  4. 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%)。