使用Keras处理分类文本

时间:2018-03-12 02:11:14

标签: python machine-learning keras text-classification

我正在尝试使用Keras训练基本文本分类NN。我从一个网站下载了12,500个pos和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之间。

我最困惑的事情是:我应该拥有多少层,每层应该拥有多少个神经元,以及第一层应该有多少输入尺寸。

我应该完全采取另一种方法吗?

2 个答案:

答案 0 :(得分:0)

答案 1 :(得分:0)

您也可以使用Keras official tutorial for text classification

基本上,它从IMDB集合中下载了5万条评论,这些评论均处于平衡状态(一半为正面,一半为负面)。他们将(随机)分成一半用于训练,一半用于测试,并以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>令牌)。 (填充是在后期完成的,即在最后完成)

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)

他们的NN体系结构由4层组成:

  1. 输入嵌入层:接受一批评论,每个评论的256个矢量的数字分别为[0,10,000],并尝试查找一个16维矢量(每个单词)来表示它们。
  2. 全局平均池化层:对评论中所有单词(16-D表示)进行平均,并为您提供单个16维向量来表示整个评论。
  3. 完全连接的16个节点的密集层-“香草” NN层。他们选择了ReLu激活功能。
  4. 1个节点的输出层:具有S形激活函数-给出一个从0到1的数字,表示它是一次正面/负面的评价。

这是它的代码:

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%)。