怎样做中文文本的情感分析?

2016课程地址 项目描述地址


什么是情感分析?

就是要识别出用户对一件事一个物或一个人的看法、态度,比如一个电影的评论,一个商品的评价,一次体验的感想等等。根据对带有情感色彩的主观性文本进行分析,识别出用户的态度,是喜欢,讨厌,还是中立。在实际生活中有很多应用,例如通过对 Twitter 用户的情感分析,来预测股票走势、预测电影票房、选举结果等,还可以用来了解用户对公司、产品的喜好,分析结果可以被用来改善产品和服务,还可以发现竞争对手的优劣势等等。

怎么分析,技术上如何实现?

首先这是个分类问题。

最开始的方案是在文中找到具有各种感情色彩属性的词,统计每个属性的词的个数,哪个类多,这段话就属于哪个属性。但是这存在一个问题,例如 don't like ,一个属于否定,一个属于肯定,统计之后变成 0 了,而实际上应该是否定的态度。再有一种情况是,前面几句是否定,后面又是肯定,那整段到底是中立还是肯定呢,为了解决这样的问题,就需要考虑上下文的环境。

2013年谷歌发了两篇论文,介绍了 Continuous Bag of Words (CBOW) 和 Skip-gram 这两个模型,也就是 Word2Vec 方法,这两种模型都是先将每个单词转化成一个随机的 N 维向量,训练之后得到每个单词的最优表示向量,区别是,CBOW 是根据上下文来预测当前词语,Skip-gram 刚好相反,是根据当前词语来预测上下文。

Word2Vec 方法不仅可以捕捉上下文语境,同时还压缩了数据规模,让训练更快更高效。通过这个模型得到的词向量已经可以捕捉到上下文的信息。比如,可以利用基本代数公式来发现单词之间的关系(比如,“国王”-“男人”+“女人”=“王后”)。用这些自带上下文信息的词向量来预测未知数据的情感状况的话,就可以更准确。

今天的小项目,就是用 word2vec 去解决情感分析问题的。先来简单介绍一下大体思路,然后进入代码版块。

思路分为两部分,第一步,就是先用 word2vec 和 SGD 训练出每个单词的最优表示向量。第二步,用 Softmax Regression 对训练数据集的每个句子进行训练,得到分类器的参数,用这个参数就可以预测新的数据集的情感分类。其中训练数据集的每个句子,都对应一个0-1之间的浮点得分,将这个得分化为 0-4 整数型 5 个级别,分别属于 5 种感情类别,讨厌,有点讨厌,中立,有点喜欢,喜欢。然后将每个句子的词转化成之前训练过的词向量,这样哪些词属于哪个类就知道了,然后用分类器得到分类的边界,得到的参数就可以用来进行预测。

具体实现

接下来以一个初学者的角度来讲一下要如何利用这几个模型和算法来实现情感分析这个任务的,因为项目的代码有点多,不方便全写在文章里。可以回复公众号“情感”获取源码下载地址。

第一步,用 word2vec 和 SGD 训练出每个单词的最优表示向量。

  • 执行 c7_run_word2vec.py
  • 其中训练词向量的方法是 c5_word2vec.py
  • 同时用 c6_sgd.py 训练参数,并且将结果保存起来,每1000次迭代保存在一个文件中 saved_params_1000.npy

word2vec: 上面提到了,它有两种模型 CBOW 和 Skip-gram,每一种都可以用来训练生成最优的词向量,同时还有两种 cost function 的定义方式,一种是 Softmax cost function, 一种是 Negative sampling cost function,所以在提到 word2vec 的时候,其实是可以有 4 种搭配的方法的,这个小项目里用到的是 Skip-gram 和 Negative sampling cost function 的结合方式。

先定义 skipgram 函数: 给一个中心词 currentWord,和它的窗口大小为 2C 的上下文 contextWords,要求出代表它们的词向量矩阵 W1 和 W2。

def skipgram(currentWord, C, contextWords, tokens, inputVectors, outputVectors, dataset, word2vecCostAndGradient = softmaxCostAndGradient): """ Skip-gram model in word2vec """ currentI = tokens[currentWord] #the order of this center word in the whole vocabulary predicted = inputVectors[currentI, :] #turn this word to vector representation cost = 0.0 gradIn = np.zeros(inputVectors.shape) gradOut = np.zeros(outputVectors.shape) for cwd in contextWords: #contextWords is of 2C length idx = tokens[cwd] cc, gp, gg = word2vecCostAndGradient(predicted, idx, outputVectors, dataset) cost += cc #final cost/gradient is the 'sum' of result calculated by each word in context gradOut += gg gradIn[currentI, :] += gp return cost, gradIn, gradOut

这里用到的成本函数是 Negative sampling,我们的目的就是要使这个成本函数达到最小,然后用这个极值时的参数 grad, 也就是可以得到要求的 wordvectors。要增加准确度,所以可以多次生成中心词和上下文进行训练,然后取平均值,也就是函数 word2vec_sgd_wrapper 做的事情。

def negSamplingCostAndGradient(predicted, target, outputVectors, dataset, K=10):    """ Negative sampling cost function for word2vec models """

    grad = np.zeros(outputVectors.shape)
    gradPred = np.zeros(predicted.shape)    indices = [target]    for k in xrange(K):
        newidx = dataset.sampleTokenIdx()        while newidx == target:
            newidx = dataset.sampleTokenIdx()        indices += [newidx]    labels = np.array([1] + [-1 for k in xrange(K)])
    vecs = outputVectors[indices, :]

    t = sigmoid(vecs.dot(predicted) * labels)
    cost = -np.sum(np.log(t))    delta = labels * (t-1)
    gradPred = delta.reshape((1, K+1)).dot(vecs).flatten()
    gradtemp = delta.reshape((K+1, 1)).dot(predicted.reshape(1, predicted.shape[0]))    for k in xrange(K+1):
        grad[indices[k]] += gradtemp[k, :]    return cost, gradPred, grad

接着用 sgd 迭代 40000 次得到训练好的 wordVectors。

wordVectors0 = sgd(    lambda vec: word2vec_sgd_wrapper(skipgram, tokens, vec, dataset, C,
        negSamplingCostAndGradient),
        wordVectors, 0.3, 40000, None, True, PRINT_EVERY=10)

第二步,用 Softmax Regression 对训练数据集进行分类学习。

  • 执行 c10_sentiment.py
  • 其中用 c6_sgd.py 去训练权重 weights,
  • 然后用 c8_softmaxreg.py 根据训练好的 features,labels,weights 进行类别 label 的预测。

先将数据集分为三部分,training set,deviation set,和 test set。

trainset = dataset.getTrainSentences()
devset = dataset.getDevSentences()testset = dataset.getTestSentences()

在 trainset 中,每句话对应一个情感的得分或者说是分类,先将每个 word 在 token 中找到序号,然后在第一步训练好的 wordvectors 中找到相应的词向量。

trainFeatures[i, :] = getSentenceFeature(tokens, wordVectors, words)

然后用 sgd 和 softmax_wrapper 迭代 10000 次去训练 weights:

weights = sgd(lambda weights: 
softmax_wrapper(trainFeatures, trainLabels, weights, regularization), 
weights, 3.0, 10000, PRINT_EVERY=100)

接着用 softmax regression 进行分类的预测:

 _, _, pred = softmaxRegression(trainFeatures, trainLabels, weights)

上面用到了不同的 REGULARIZATION=[0.0, 0.00001, 0.00003, 0.0001, 0.0003, 0.001, 0.003, 0.01] ,在其中选择 accuracy 最好的 REGULARIZATION 和相应的结果

best_dev = 0for result in results:    if result["dev"] > best_dev:
        best_dev = result["dev"]
        BEST_REGULARIZATION = result["reg"]
        BEST_WEIGHTS = result["weights"]

用这个最好的参数在 test set 上进行预测:

_, _, pred = softmaxRegression(testFeatures, testLabels, BEST_WEIGHTS)

并且的到 accuracy:

print "Test accuracy (%%): %f" % accuracy(testLabels, pred)

下图是 accuracy 和 REGULARIZATION 在 devset 和 trainset 上的趋势:

accuracy


以上就是 sentiment analysis 的基本实现,把它和爬虫相结合,会有很多好玩的玩儿法!

原文发布于微信公众号 - 大数据挖掘DT数据分析(datadw)

原文发表时间:2017-06-12

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏机器之心

业界 | 谷歌最新语义图像分割模型DeepLab-v3+今日开源

选自Google Research Blog 作者:Liang-Chieh Chen、Yukun Zhu 机器之心编译 参与:刘晓坤、路雪 刚刚,谷歌开源了语义...

31560
来自专栏专知

50行PyTorch代码实现生成对抗网络(GANs)

【导读】这是一份非常简单的PyTorch实现GAN教程和代码。文中另附有TensorFlow实现版本。

19640
来自专栏大数据挖掘DT机器学习

基于Kaggle数据的词袋模型文本分类教程

本教程展示了改善文本分类的方法,包括:做一个验证集,为AUC预测概率,用线性模型代替随机森林,使用TF-IDF权衡词汇,留下停用词,加上二元模型或者三元模型等。...

32650
来自专栏人工智能头条

写给大家看的机器学习书【Part3】直观易懂的感知机学习算法PLA

21350
来自专栏机器之心

教程 | Kaggle网站流量预测任务第一名解决方案:从模型到代码详解时序预测

68550
来自专栏大数据挖掘DT机器学习

用交叉验证改善模型的预测表现(适用于Python和R)

原文作者: Sunil Ray 翻译:王鹏宇 我一直对数据界的编程马拉松(Hackathons)保持关注。通过对比排名榜初期和最终的结果, 我发现了一个有趣的现...

55360
来自专栏悦思悦读

利用逻辑回归模型判断用户提问意图

在之前开发聊天机器人的文章里,我们讲解了如何使用在线工具LUIS (https://luis.ai) 开发Chat bot的自然语言理解模型。 在构造问题解决型...

490140
来自专栏新智元

超越GAN!OpenAI提出可逆生成模型,AI合成超逼真人像

【新智元导读】OpenAI最新提出的可逆生成模型Glow,可以使用相对少的数据,快速生成高清的逼真图像,具有GAN和VAE所不具备的精确操作潜在变量、需要内存少...

12500
来自专栏大数据文摘

步长?填充?池化?教你从读懂词语开始了解计算机视觉识别最火模型 | CNN入门手册(中)

19640
来自专栏目标检测和深度学习

深度学习之基础网络演进、分类与定位的权衡|牛喀技研

深度学习,目标检测,图像,智能驾驶 编译:牛喀网-钱伟 前言 本篇关注基础网络架构的演进和处理分类、定位这一矛盾问题上的进展。 基础网络结构的演进 基础网络(...

89470

扫码关注云+社区

领取腾讯云代金券