## 现代情感分析方法

2018 年 1 月 12 日 算法与数学之美

>>>>

Word2Vec 和 Doc2Vec

from gensim.models.word2vec import Word2Vec

model = Word2Vec.load_word2vec_format('vectors.txt', binary=False) #C text 格式

from gensim.models.word2vec import Word2Vec

model.most_similar(positive=['woman', 'king'], negative=['man'], topn=5)

[(u'queen', 0.711819589138031),

(u'monarch', 0.618967592716217),

(u'princess', 0.5902432799339294),

(u'crown_prince', 0.5499461889266968),

(u'prince', 0.5377323031425476)]

“biggest” – “big” + “small” = “smallest”

model.most_similar(positive=['biggest','small'], negative=['big'], topn=5)

[(u'smallest', 0.6086569428443909),

(u'largest', 0.6007465720176697),

(u'tiny', 0.5387299656867981),

(u'large', 0.456944078207016),

(u'minuscule', 0.43401968479156494)]

“ate” – “eat” + “speak” = “spoke”

model.most_similar(positive=['ate','speak'], negative=['eat'], topn=5)

[(u'spoke', 0.6965223550796509),

(u'speaking', 0.6261293292045593),

(u'conversed', 0.5754593014717102),

(u'spoken', 0.570488452911377),

(u'speaks', 0.5630602240562439)]

import numpy as np

with open('food_words.txt', 'r') as infile:

with open('sports_words.txt', 'r') as infile:

with open('weather_words.txt', 'r') as infile:

def getWordVecs(words):

vecs = []

for word in words:

word = word.replace('n', '')

try:

vecs.append(model[word].reshape((1,300)))

except KeyError:

continue

vecs = np.concatenate(vecs)

return np.array(vecs, dtype='float') #TSNE expects float type values

food_vecs = getWordVecs(food_words)

sports_vecs = getWordVecs(sports_words)

weather_vecs = getWordVecs(weather_words)

from sklearn.manifold import TSNE

import matplotlib.pyplot as plt

ts = TSNE(2)

reduced_vecs = ts.fit_transform(np.concatenate((food_vecs, sports_vecs, weather_vecs)))

#color points by word group to see if Word2Vec can separate them

for i in range(len(reduced_vecs)):

if i &lt; len(food_vecs):

#food words colored blue

color = 'b'

elif i &gt;len(food_vecs) and i &lt; (len(food_vecs) + len(sports_vecs)):

#sports words colored red

color = 'r'

else:

#weather words colored green

color = 'g'

plt.plot(reduced_vecs[i,0], reduced_vecs[i,1], marker='o', color=color, markersize=8)

import numpy as np

with open('food_words.txt', 'r') as infile:

with open('sports_words.txt', 'r') as infile:

with open('weather_words.txt', 'r') as infile:

def getWordVecs(words):

vecs = []

for word in words:

word = word.replace('n', '')

try:

vecs.append(model[word].reshape((1,300)))

except KeyError:

continue

vecs = np.concatenate(vecs)

return np.array(vecs, dtype='float') #TSNE 要求浮点型的值

food_vecs = getWordVecs(food_words)

sports_vecs = getWordVecs(sports_words)

weather_vecs = getWordVecs(weather_words)

from sklearn.cross_validation import train_test_split

from gensim.models.word2vec import Word2Vec

# 1 代表积极情绪，0 代表消极情绪

y = np.concatenate((np.ones(len(pos_tweets)), np.zeros(len(neg_tweets))))

x_train, x_test, y_train, y_test = train_test_split(np.concatenate((pos_tweets, neg_tweets)), y,test_size=0.2)

# 零星的预处理

def cleanText(corpus):

corpus = [z.lower().replace('n','').split() for z in corpus]

return corpus

x_train = cleanText(x_train)

x_test = cleanText(x_test)

n_dim = 300

# 初始化模型并创建词汇表（vocab）

imdb_w2v = Word2Vec(size=n_dim, min_count=10)

imdb_w2v.build_vocab(x_train)

# 训练模型 (会花费几分钟)

imdb_w2v.train(x_train)

# 对训练数据集创建词向量，接着进行比例缩放（scale）。

def buildWordVector(text, size):

vec = np.zeros(size).reshape((1, size))

count = 0.

for word in text:

try:

vec += imdb_w2v[word].reshape((1, size))

count += 1.

except KeyError:

continue

if count != 0:

vec /= count

return vec

from sklearn.preprocessing import scale

train_vecs = np.concatenate([buildWordVector(z, n_dim) for z in x_train])

train_vecs = scale(train_vecs)

# 在测试推特数据集中训练 Word2Vec

imdb_w2v.train(x_test)

# 创建测试推特向量并缩放

test_vecs = np.concatenate([buildWordVector(z, n_dim) for z in x_test])

test_vecs = scale(test_vecs)

# 使用分类算法（例如：随机逻辑回归（Stochastic Logistic Regression）来训练数据集，接着从 sklearn.linear_model 导入 SGDClassifier 进行模型处理）

lr = SGDClassifier(loss='log', penalty='l1')

lr.fit(train_vecs, y_train)

print 'Test Accuracy: %.2f'%lr.score(test_vecs, y_test)

# 创建 ROC 曲线

from sklearn.metrics import roc_curve, auc

import matplotlib.pyplot as plt

pred_probas = lr.predict_proba(test_vecs)[:,1]

fpr,tpr,_ = roc_curve(y_test, pred_probas)

roc_auc = auc(fpr,tpr)

plt.plot(fpr,tpr,label='area = %.2f' %roc_auc)

plt.plot([0, 1], [0, 1], 'k--')

plt.xlim([0.0, 1.0])

plt.ylim([0.0, 1.05])

plt.legend(loc='lower right')

plt.show()

from NNet import NeuralNet

nnet = NeuralNet(100, learn_rate=1e-1, penalty=1e-8)

maxiter = 1000

batch = 150

_ = nnet.fit(train_vecs, y_train, fine_tune=False, maxiter=maxiter, SGD=True, batch=batch, rho=0.9)

print 'Test Accuracy: %.2f'%nnet.score(test_vecs, y_test)

import gensim

LabeledSentence = gensim.models.doc2vec.LabeledSentence

from sklearn.cross_validation import train_test_split

import numpy as np

with open('IMDB_data/pos.txt','r') as infile:

with open('IMDB_data/neg.txt','r') as infile:

with open('IMDB_data/unsup.txt','r') as infile:

# 1 代表积极情绪，0 代表消极情绪

y = np.concatenate((np.ones(len(pos_reviews)), np.zeros(len(neg_reviews))))

x_train, x_test, y_train, y_test = train_test_split(np.concatenate((pos_reviews, neg_reviews)), y,test_size=0.2)

# 零星的预处理

def cleanText(corpus):

punctuation = """.,?!:;(){}[]"""

corpus = [z.lower().replace('n','') for z in corpus]

corpus = [z.replace('&lt;br /&gt;', ' ') for z in corpus]

# 将标点视为一个单词

for c in punctuation:

corpus = [z.replace(c, ' %s '%c) for z in corpus]

corpus = [z.split() for z in corpus]

return corpus

x_train = cleanText(x_train)

x_test = cleanText(x_test)

unsup_reviews = cleanText(unsup_reviews)

# Gensim 的 Doc2Vec 工具要求每个文档/段落包含一个与之关联的标签。我们利用 LabeledSentence 进行处理。格式形如 “TRAIN_i” 或者 “TEST_i”，其中 “i” 是假的评论索引。

def labelizeReviews(reviews, label_type):

labelized = []

for i,v in enumerate(reviews):

label = '%s_%s'%(label_type,i)

labelized.append(LabeledSentence(v, [label]))

return labelized

x_train = labelizeReviews(x_train, 'TRAIN')

x_test = labelizeReviews(x_test, 'TEST')

unsup_reviews = labelizeReviews(unsup_reviews, 'UNSUP')

<gensim.models.doc2vec.LabeledSentence at 0xedd70b70>

import random

size = 400

# 实例化 DM 和 DBOW 模型

model_dm = gensim.models.Doc2Vec(min_count=1, window=10, size=size, sample=1e-3, negative=5,workers=3)

model_dbow = gensim.models.Doc2Vec(min_count=1, window=10, size=size, sample=1e-3,negative=5, dm=0, workers=3)

# 对所有评论创建词汇表

model_dm.build_vocab(np.concatenate((x_train, x_test, unsup_reviews)))

model_dbow.build_vocab(np.concatenate((x_train, x_test, unsup_reviews)))

# 多次传入数据集，通过每次滑动（shuffling）来提高准确率。

all_train_reviews = np.concatenate((x_train, unsup_reviews))

for epoch in range(10):

perm = np.random.permutation(all_train_reviews.shape[0])

model_dm.train(all_train_reviews[perm])

model_dbow.train(all_train_reviews[perm])

# 从我们的模型中获得训练过的向量

def getVecs(model, corpus, size):

vecs = [np.array(model[z.labels[0]]).reshape((1, size)) for z in corpus]

return np.concatenate(vecs)

train_vecs_dm = getVecs(model_dm, x_train, size)

train_vecs_dbow = getVecs(model_dbow, x_train, size)

train_vecs = np.hstack((train_vecs_dm, train_vecs_dbow))

# 训练测试数据集

x_test = np.array(x_test)

for epoch in range(10):

perm = np.random.permutation(x_test.shape[0])

model_dm.train(x_test[perm])

model_dbow.train(x_test[perm])

# 创建测试数据集向量

test_vecs_dm = getVecs(model_dm, x_test, size)

test_vecs_dbow = getVecs(model_dbow, x_test, size)

test_vecs = np.hstack((test_vecs_dm, test_vecs_dbow))

from sklearn.linear_model import SGDClassifier

lr = SGDClassifier(loss='log', penalty='l1')

lr.fit(train_vecs, y_train)

print 'Test Accuracy: %.2f'%lr.score(test_vecs, y_test)

#Create ROC curve

from sklearn.metrics import roc_curve, auc

%matplotlib inline

import matplotlib.pyplot as plt

pred_probas = lr.predict_proba(test_vecs)[:,1]

fpr,tpr,_ = roc_curve(y_test, pred_probas)

roc_auc = auc(fpr,tpr)

plt.plot(fpr,tpr,label='area = %.2f' %roc_auc)

plt.plot([0, 1], [0, 1], 'k--')

plt.xlim([0.0, 1.0])

plt.ylim([0.0, 1.05])

plt.legend(loc='lower right')

plt.show()

from NNet import NeuralNet

nnet = NeuralNet(50, learn_rate=1e-2)

maxiter = 500

batch = 150

_ = nnet.fit(train_vecs, y_train, fine_tune=False, maxiter=maxiter, SGD=True, batch=batch, rho=0.9)

print 'Test Accuracy: %.2f'%nnet.score(test_vecs, y_test)

• A Word is Worth a Thousand Vectors

• Word2Vec Tutorial

• Gensim

• Scikit-Learn: Working with Text Data

• Natural Language Processing with Python

### 相关内容

251+阅读 · 2020年6月15日

210+阅读 · 2020年4月26日

95+阅读 · 2020年2月8日

116+阅读 · 2020年2月3日

77+阅读 · 2020年2月3日

96+阅读 · 2019年12月13日
AINLP
15+阅读 · 2019年6月6日

9+阅读 · 2019年4月12日

21+阅读 · 2018年3月20日

58+阅读 · 2018年1月26日

22+阅读 · 2018年1月6日

29+阅读 · 2017年12月20日

6+阅读 · 2017年11月16日

11+阅读 · 2017年10月19日

69+阅读 · 2017年7月3日
Arxiv
31+阅读 · 2018年11月13日
Arxiv
6+阅读 · 2018年8月2日
Arxiv
6+阅读 · 2018年3月29日
Arxiv
7+阅读 · 2018年1月30日
Arxiv
25+阅读 · 2018年1月24日
Arxiv
5+阅读 · 2018年1月23日
VIP会员

251+阅读 · 2020年6月15日

210+阅读 · 2020年4月26日

95+阅读 · 2020年2月8日

116+阅读 · 2020年2月3日

77+阅读 · 2020年2月3日

96+阅读 · 2019年12月13日

AINLP
15+阅读 · 2019年6月6日

9+阅读 · 2019年4月12日

21+阅读 · 2018年3月20日

58+阅读 · 2018年1月26日

22+阅读 · 2018年1月6日

29+阅读 · 2017年12月20日

6+阅读 · 2017年11月16日

11+阅读 · 2017年10月19日

69+阅读 · 2017年7月3日

Arxiv
31+阅读 · 2018年11月13日
Arxiv
6+阅读 · 2018年8月2日
Arxiv
6+阅读 · 2018年3月29日
Arxiv
7+阅读 · 2018年1月30日
Arxiv
25+阅读 · 2018年1月24日
Arxiv
5+阅读 · 2018年1月23日
Top