基于TextCNN的情感二分类

0. Cause I just wanna wake up in the fleeting light

  0.1 アイスクリームみた溶けそう、その瞳にみつめられたなら

    新论文方向想好了,一个改进的TextCNN应用实例吧。数据集来源于学长之前打比赛时官方发的2G数据包,大概达到的效果就是通过用户短评去给某个景点的旅行指标进行打分。当然会有一个疑问,在我们现实的应用场景中不都是用户进行打分吗。但这里我要做的是对短评的深层语义进行挖掘,然后得出打分(无奈,为了写论文而写),其实确实没有什么意义,但是自然语言处理就是这样。

    为了给论文做一点铺垫,今天更新一个基于TextCNN的情感二分类问题。这个实验做了很久,4月3号完成的。当时边做边写,用了很多时间给虚拟机的使用写了一个README文档。

    简单描述一下这个问题。电影影评一般属于短评,那么我们要做的就是将任一条用户影评分类至 [positive,negative] 两个标签,也就俗称为情感二分类问题。数据集源自于Movie Review Data这个开源站点http://www.cs.cornell.edu/people/pabo/movie-review-data/ ,里面有不同大小的datasets,均按照positive和negative两个标签分好类,可以根据电脑内存配置和实验需求进行选择。

    现在每个方向都是基于深度学习的XXXX。自然语言处理也不例外,每天学习的还是CNN和RNN。3月份跟老师吵架的时候,因为那时候弄了一个基于LSTM的自动音乐序列生成,也就是训练集不是文本,他因为这个事情跟我生了半个月的气。TextCNN简单来说,就是比卷积神经网络CNN多了一个Embedding层,这个Embedding层的作用就是为了把文字转化为向量和矩阵,完毕。

  0.2 会いたいなんて思っても、恥ずかしいからなかなか言えない

    今天的标题会不会太长了,这一节结合Tensorboard简单说一下TextCNN的网络结构吧。前提是稍微熟悉一点CNN,如果忘记了可以参考我之前写一篇的CNN的学习记录博文,可以说非常的入门级和清晰了。代码将会在第二部给出,运行结果在第三部分给出。

    

图1  tensorboard中展示的TextCNN结构

    可以看到,TextCNN在第一层加入了Embedding层,将输入的文本向量转化为数字向量。在输入Embedding之前,我们需要写一个data_helper的函数,去做文本的切词、去停用词、去标点符号、补齐等操作。把每一条短评处理为相同长度的文本向量(比如每一条都是100个词)后,输入Embedding层。Embedding层调用google开发的Word2vec方法将文本向量映射至数字向量。也就是说,经过Embedding层后每一条短评(100个词为例,每个词为100维)变成 [(x1_1,x1_2,...x1_100)....(x100_1,....x100_100)] 这样一组向量或者成为矩阵进行后续的计算。这里需要补充一点,Embedding层也可以只是简单做一个映射,使用一个已经训练好的词表(该词表每一行代表一个词,第一列为词本身,第二列为100维或200维甚至更高的数字向量表达形式),Embedding层只需要做一个查表和映射就可以了。

    经过Embedding层后的操作和CNN基本没区别,也是遵循Conv+Pool最后在全连接层进行Softmax操作,但在每一步的细节上有区别,这需要去代码里面好好看看,卷积采样窗口和池化方法等等都有不同。针对NLP的CNN常用Pool方法可以参考我之前写的一篇CNN中常见的几种pool操作

    这一小节最后再借用Yoon Kim论文中的一张图进行解释吧,论文参考 Convolutional Neural Networks for Sentence Classification 。wait这个词经过Embedding层后变为下图第一步中的向量形式,然后通过卷积Conv层变成第二步中的方格。然后下图中使用的pool方法为maxpool,因为第二步中多个方格只有一个输出到全连接层中。最后一步,全连接层通过softmax输出一个二分类概率。具体原理可以参考我写的CNN学习记录。


 

图2  TextCNN的情感二分类图示

1. Before these lights they all went dark

    这一部分还是继续上干货,贴代码,总共有4个py文件。简单解释一下作用。

        data_helpers.py:文本文件导入,切词、去停用词、去标点符号,文本向量填充等等。

        eval.py:负责参数和结果的部分输出。

        text_cnn.py:网络定义。

        train.py:训练部分。

    使用时直接运行train.py就可以了。想查看更多的中间过程(比如每条短评经过Embedding层后是什么样子的),参考 https://blog.csdn.net/github_38414650/article/details/74019595 。下面我按上述顺序贴代码。

# data_helpers.py


import numpy as np
import re
import itertools
from collections import Counter
import builtins

def clean_str(string):
    string = re.sub(r"[^A-Za-z0-9(),!?\'\`]", " ", string)
    string = re.sub(r"\'s", " \'s", string)
    string = re.sub(r"\'ve", " \'ve", string)
    string = re.sub(r"n\'t", " n\'t", string)
    string = re.sub(r"\'re", " \'re", string)
    string = re.sub(r"\'d", " \'d", string)
    string = re.sub(r"\'ll", " \'ll", string)
    string = re.sub(r",", " , ", string)
    string = re.sub(r"!", " ! ", string)
    string = re.sub(r"\(", " \( ", string)
    string = re.sub(r"\)", " \) ", string)
    string = re.sub(r"\?", " \? ", string)
    string = re.sub(r"\s{2,}", " ", string)
    return string.strip().lower()

def load_data_and_labels(positive_data_file,negative_data_file):
    positive_examples = list(builtins.open(positive_data_file,"r").readlines())
    positive_examples = [s.strip() for s in positive_examples]
    negative_examples = list(builtins.open(negative_data_file, "r").readlines())
    negative_examples = [s.strip() for s in negative_examples]

    x_text = positive_examples + negative_examples
    x_text = [clean_str(sent) for sent in x_text]

    positive_labels = [[0,1] for _ in positive_examples]
    negative_labels = [[1,0] for _ in negative_examples]
    y = np.concatenate([positive_labels, negative_labels],0)
    return [x_text,y]

def batch_iter(data,batch_size,num_epochs,shuffle=True):
    data = np.array(data)
    data_size = len(data)
    num_batches_per_epoch = int((len(data)-1)/batch_size) + 1

    for epoch in range(num_epochs):
        if shuffle:
            shuffle_indices = np.random.permutation(np.arange(data_size))
            shuffle_data = data[shuffle_indices]
        else:
            shuffle_data = data
        for batch_num in range(num_batches_per_epoch):
            start_index = batch_num * batch_size
            end_index = min((batch_num + 1) * batch_size,data_size)
            yield shuffle_data[start_index:end_index]

 

#! /usr/bin/env python
# eval.py


import tensorflow as tf
import numpy as np
import os
import time
import datetime
import data_helpers
from text_cnn import TextCNN
from tensorflow.contrib import learn
import csv

# Parameters
# ==================================================

# Data Parameters
tf.flags.DEFINE_string("positive_data_file", "./data/pos.txt", "Data source for the positive data.")
tf.flags.DEFINE_string("negative_data_file", "./data/neg.txt", "Data source for the negative data.")

# Eval Parameters
tf.flags.DEFINE_integer("batch_size", 64, "Batch Size (default: 64)")
tf.flags.DEFINE_string("checkpoint_dir", "", "Checkpoint directory from training run")
tf.flags.DEFINE_boolean("eval_train", False, "Evaluate on all training data")

# Misc Parameters
tf.flags.DEFINE_boolean(
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值