4.3IMDB影评得分

  • 下载数据。
    已经标有情感倾向的训练文件labeledTrainData.tsv,里面有25000条影评以及对应的情感倾向标识;
    待测试文件testData.tsv,同样也另有25000条电影评论;
    无标注但是数据量更大的影评文件unlabeledTrainData.tsv。

  • 搭建模型。
    接下来分别采用scikit-learn中的朴素贝叶斯模型以及隶属于集成模型的梯度提升树分类模型,对电影评论进行文本情感分析。具体而言,在朴素贝叶斯模型中依然使用“词袋法”对每条电影评论进行特征向量化,并且借助CountVectorizer和TfidfVectorizer:另一方面,先利用无标注影评文件中训练词向量,然后将每条电影评论中所有词汇的平均向量作为特征训练梯度提升树分类模型。

import pandas as pd

train=pd.read_csv('/Users/daqi/Documents/ipython/Python机器学习及实践/官方资料/Datasets/IMDB/labeledTrainData.tsv', header=0, delimiter="\t",quoting=3)
test=pd.read_csv('/Users/daqi/Documents/ipython/Python机器学习及实践/官方资料/Datasets/IMDB/testData.tsv', header=0, delimiter="\t",quoting=3)
train.head()
test.head()
from bs4 import BeautifulSoup
import re
from nltk.corpus import stopwords
import nltk
#nltk.download('stopwords')如果报错找不到stopwords加上这行代码
#定义review_to_text函数,完成对原始评论的三项数据预处理任务。
def review_to_text(review,remove_stopwords):
#任务1:去掉html标记。
    raw_text=BeautifulSoup(review,'html').get_text()
#任务2:去掉非字母字符。
    letters=re.sub('[^a-zA-Z]',' ',raw_text)
    words=letters.lower().split()
#任务3:如果remove_stopwords被激活,则进一步去掉评论中的停用词。
    if remove_stopwords:
        stop_words=set(stopwords.words('english'))
        words=[w for w in words if w not in stop_words]
#返回每条评论经此三项预处理任务的词汇列表
    return words
#分别对原始训练和测试数据集进行上述三项预处理。
X_train=[]
for review in train['review']:
    X_train.append(' '.join(review_to_text(review,True)))
X_test=[]
for review in test['review']:
    X_test.append(' '.join(review_to_text(review,True)))

y_train=train['sentiment']
#导入文本特征抽取器CountVectorizer与TfidfVectorizer.
from sklearn.feature_extraction.text import CountVectorizer,TfidfVectorizer

#从Scikit-learn中导入朴素贝叶斯模型
from sklearn.naive_bayes import MultinomialNB

#导入Pipeline用于方便搭建系统流程
from sklearn.pipeline import Pipeline

#导入GridSearchCV用于超参数组合的网格搜索。
from sklearn.grid_search import GridSearchCV
#使用Pipeline搭建两组使用朴素贝叶斯模型的分类器,区别在于分别使用CountVectorizer与TfidfVectorizer对文本特征进行抽取
pip_count=Pipeline([('count_vect',CountVectorizer(analyzer='word')),('mnb',MultinomialNB())])
pip_tfidf=Pipeline([('tfidf_vect',TfidfVectorizer(analyzer='word')),('mnb',MultinomialNB())])

#分别配置用于模型超参数搜索的组合
params_count={'count_vect__binary':[True,False],'count_vect__ngram_range':[(1,1),(1,2)],'mnb__alpha':[0.1,1.0,10.0]}
params_tfidf={'tfidf_vect__binary':[True,False],'tfidf_vect__ngram_range':[(1,1),(1,2)],'mnb__alpha':[0.1,1.0,10.0]}

#使用采用4折交叉验证的方法对使用CountVectorizer的朴素贝叶斯模型进行并行化超参数搜索。
gs_count=GridSearchCV(pip_count,params_count,cv=4,n_jobs=-1,verbose=1)
gs_count.fit(X_train,y_train)

#输出交叉验证中最佳的准确性得分以及超参数组合。
print(gs_count.best_score_)
print(gs_count.best_params_)

0.88216
{'count_vect__binary': True, 'count_vect__ngram_range': (1, 2), 'mnb__alpha': 1.0}

#以最佳的超参数组合配置模型并对测试数据进行预测
count_y_predict=gs_count.predict(X_test)

#使用采用4折交叉验证的方法对使用TfidfVectorizer的朴素贝叶斯模型进行并行化超参数搜索。
gs_tfidf=GridSearchCV(pip_tfidf,params_tfidf,cv=4,n_jobs=-1,verbose=1)
gs_tfidf.fit(X_train,y_train)

#输出交叉验证中最佳的准确性得分以及超参数组合
print(gs_tfidf.best_score_)
print(gs_tfidf.best_params_)

0.88712
{'mnb__alpha': 0.1, 'tfidf_vect__binary': True, 'tfidf_vect__ngram_range': (1, 2)}

#以最佳的超参数组合配置模型并对测试数据进行预测
tfidf_y_predict=gs_tfidf.predict(X_test)

#使用pandas对需要提交的数据进行格式化。
submission_count=pd.DataFrame({'id':test['id'],'sentiment':count_y_predict})
submission_tfidf=pd.DataFrame({'id':test['id'],'sentiment':tfidf_y_predict})

#结果输出到本地硬盘
submission_count.to_csv('/Users/daqi/Documents/ipython/Python机器学习及实践/submission_count.csv',index=False)
submission_tfidf.to_csv('/Users/daqi/Documents/ipython/Python机器学习及实践/submission_tfidf.csv',index=False)

#从本地读入未标记数据
unlabeled_train=pd.read_csv('/Users/daqi/Documents/ipython/Python机器学习及实践/官方资料/Datasets/IMDB/unlabeledTrainData.tsv',delimiter='\t',quoting=3)
import nltk.data

#使用使用nltk的tokenizer对影评中的英文句子进行分割
tokenizer=nltk.data.load('tokenizers/punkt/english.pickle')

#定义函数review_to_sentences逐条对影评进行分句。
def review_to_sentences(review,tokenizer):
    raw_sentences=tokenizer.tokenize(review.strip())
    sentences=[]
    for raw_sentences in raw_sentences:
        if len(raw_sentences)>0:
            sentences.append(review_to_text(raw_sentences,False))
    return sentences

corpora=[]
#准备用于训练词向量的数据
for review in unlabeled_train['review']:
    corpora+=review_to_sentences(review,tokenizer)

#配置训练词向量模型的超参数
num_features=300
min_word_count=20
num_workers=4
context=10
downsampling = 1e-3  
from gensim.models import word2vec
#开始词向量模型的训练
model=word2vec.Word2Vec(corpora,workers=num_workers,\
                       size=num_features,min_count=min_word_count,\
                       window=context,sample=downsampling)

model.init_sims(replace=True)

model_name='/Users/daqi/Documents/ipython/Python机器学习及实践/300features_20minwords_10context'
#可以将词向量模型的训练结果长期保存于本地硬盘。
model.save(model_name)

#直接读入已经训练好的词向量模型
from gensim.models import Word2Vec
model=Word2Vec.load(model_name)

#探查一下该向量模型的训练结果
model.most_similar('man')
import numpy as np

#定义一个函数使用词向量产生文本特征向量
def makeFeatureVec(words,model,num_features):
    featureVec=np.zeros((num_features,),dtype='float32')
    nwords=0
    index2word_set=set(model.wv.index2word)
    for word in words:
        if word in index2word_set:
            nwords=nwords+1.
            featureVec=np.add(featureVec,model[word])
    featureVec=np.divide(featureVec,nwords)
    return featureVec

#定义另一个每条影评转化为基于词向量的特征向量(平均词向量)。
def getAvgFeatureVecs(reviews,model,num_features):
    counter=0
    reviewFeatureVecs=np.zeros((len(reviews),num_features),dtype='float32')
    for review in reviews:
        reviewFeatureVecs[counter]=makeFeatureVec(review,model,num_features)
        counter+=1
    return reviewFeatureVecs

#准备新的基于词向量表示的训练和测试特征向量。
clean_train_reviews=[]
for review in train['review']:
    clean_train_reviews.append(review_to_text(review,remove_stopwords=True))

trainDataVecs=getAvgFeatureVecs(clean_train_reviews,model,num_features)

clean_test_reviews=[]
for review in test['review']:
    clean_test_reviews.append(review_to_text(review,remove_stopwords=True))

testDataVecs=getAvgFeatureVecs(clean_test_reviews,model,num_features)
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.grid_search import GridSearchCV

gbc=GradientBoostingClassifier()

# 配置超参数的搜索组合
params_gbc={'n_estimators':[10,100,300],'learning_rate':[0.001,0.1,1.0],'max_depth':[2,3,4]}

gs=GridSearchCV(gbc,params_gbc,cv=4,n_jobs=-1,verbose=1)

gs.fit(trainDataVecs,y_train)

#输出网格搜索得到的最佳性能以及最优超参数组合。
print(gs.best_score_)
print(gs.best_params_)

0.85464
{'learning_rate': 0.1, 'max_depth': 4, 'n_estimators': 300}

参考资料
https://www.cnblogs.com/zhao441354231/p/6056914.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容