17.3 示例:识别恶意评论

完整演示代码请见本书GitHub上的17-2.py。

1.数据清洗与特征化

这次我们的样本依然采用Movie Review Data数据集。Movie Review Data数据集包含1000条正面评论和1000条负面评论,被广泛应用于文本分类尤其是恶意评论识别方面。本书使用其最新的版本,polarity dataset v2.0,详细的介绍请参考第3章相关内容。

Movie Review Data数据集的每条评论都保存成单独的一个文本文件,正面和负面评论放置在不同的文件夹下面,使用词袋模型将文本向量化。

读取文件,把每个文件转换成一个字符串:


def load_one_file(filename):
    x=""
    with open(filename) as f:
        for line in f:
            x+=line
    return x

遍历读取文件夹下全部文件:


def load_files(rootdir,label):
    list = os.listdir(rootdir)
    x=[]
    y=[]
    for i in range(0, len(list)):
        path = os.path.join(rootdir, list[i])
        if os.path.isfile(path):
            print "Load file %s" % path
            y.append(label)
            x.append(load_one_file(path))
    return x,y

根据不同文件夹,标记为正面和负面,其中正面评论标记为0,负面评论标记为1:


def load_data():
    x=[]
    y=[]
x1,y1=load_files("../data/movie-review-data/review_polarity/txt_sentoken/pos/",0) x2,y2=load_files("../data/movie-review-data/review_polarity/txt_sentoken/neg/", 1)
    x=x1+x2
    y=y1+y2
    return x,y

使用词袋模型将数据向量化,并且使用train_test_split将样本随机划分成训练集合和测试集合,分配比例为0.4,这个比例可以根据自己的需要进行调整,不过一般都是建议使用40%作为测试数据:


x,y=load_data()
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.4, random_state=0)
vp = learn.preprocessing.VocabularyProcessor(max_document_length=MAX_DOCUMENT_LENGTH, min_frequency=1)
vp.fit(x)
x_train = np.array(list(vp.transform(x_train)))
x_test = np.array(list(vp.transform(x_test)))
n_words=len(vp.vocabulary_)
print(‘Total words: %d' % n_words)

2.训练样本

构造CNN,使用一维卷积函数:


network = input_data(shape=[None, MAX_DOCUMENT_LENGTH], name='input')
network = tflearn.embedding(network, input_dim=n_words+1, output_dim=128)
branch1 = conv_1d(network, 128, 3, padding='valid', activation='relu', regularizer="L2")
branch2 = conv_1d(network, 128, 4, padding='valid', activation='relu', regularizer="L2")
branch3 = conv_1d(network, 128, 5, padding='valid', activation='relu', regularizer="L2")
network = merge([branch1, branch2, branch3], mode='concat', axis=1)
network = tf.expand_dims(network, 2)
network = global_max_pool(network)
network = dropout(network, 0.5)
network = fully_connected(network, 2, activation='softmax')
network = regression(network, optimizer='adam', learning_rate=0.001,
                     loss='categorical_crossentropy', name='target')

3.验证效果

CNN算法在fit函数中直接指定了测试数据集合(testX,testY):


model = tflearn.DNN(network, tensorboard_verbose=0)
model.fit(trainX, trainY, n_epoch = 10, shuffle=True, validation_set=(testX, testY), show_metric=True, batch_size=32)

运行程序,准确率66%左右,比之前NB和RNN算法有提升。