文本情感分析(一):基于词袋模型(VSM、LSA、n-gram)的文本表示

更新时间:2023-07-09 20:04:14 阅读: 评论:0

⽂本情感分析(⼀):基于词袋模型(VSM、LSA、n-gram)
的⽂本表⽰
现在⾃然语⾔处理⽤深度学习做的⽐较多,我还没试过⽤传统的监督学习⽅法做分类器,⽐如SVM、Xgboost、随机森林,来训练模型。因此,⽤Kaggle上经典的电影评论情感分析题,来学习如何⽤传统机器学习⽅法解决分类问题。
通过这个情感分析的题⽬,我会整理做特征⼯程、参数调优和模型融合的⽅法,这⼀系列会有四篇⽂章。这篇⽂章整理⽂本特征⼯程的内容。
⽂本的特征⼯程主要包括数据清洗、特征构造、降维和特征选择等。
⾸先是数据清洗,⽐如去停⽤词、去⾮字母汉字的特殊字符、⼤写转⼩写、去掉html标签等。
然后是特征构建,可以基于词袋模型构造⽂本特征,⽐如向量空间模型的词频矩阵、Tf-Idf矩阵,⼜⽐如LSA和LDA,也可以⽤word2vec、glove等⽂本分布式表⽰⽅法,来构造⽂本特征。此外还可以⽤n-gram构造⽂本特征。
接下来可以选择是否降维,可以⽤PCA或SVD等⽅法对⽂本特征矩阵进⾏降维。
最后选择效果⽐较突出的1个或⼏个特征来训练模型。
⼀、基于向量空间模型的⽂本特征表⽰
向量空间模型(Vector Space Model,VSM)也就是单词向量空间模型,区别于LSA、PLSA、LDA这些话题向量空间模型,但是单词向量空间模型和话题向量空间模型都属于词袋模型,⼜和word2vec等⽂本分布式表⽰⽅法相区别。
向量空间模型的基本想法是:给定⼀个⽂本,⽤⼀个向量表⽰该⽂本的语义,向量的每⼀维对应⼀个单词,其数值是该单词在该⽂本中出现的频数或Tf-Idf。那么每个⽂本就是⼀个向量,特征数量为所有⽂本中的单词总数,通过计算向量之间的余弦相似度可以得到⽂本的相似度。
⽽⽂本集合中的所有⽂本的向量就会构成⼀个单词-⽂本矩阵,元素为单词的频数或Tf-Idf。
在我们这个Kaggle案例中,单词-⽂本矩阵的⾏数为样本的数量,列数为单词的数量,训练集中样本有25000条,选取最⾼频的5000个单词,故矩阵X是(25000,5000)的矩阵。我们以词频和Tf-Idf作为⽂本特征,计算出两个单词-⽂本矩阵,然后分别训练随机森林⼆分类器。
⾸先导⼊所需要的库。
import os,re
import numpy as np
import pandas as pd
from bs4 import BeautifulSoup
from sklearn. import CountVectorizer
from sklearn. import TfidfVectorizer
ble import RandomForestClassifier
from sklearn import metrics
import nltk
pus import stopwords
第⼀步:读取训练数据,⼀共25000条评论数据。"""第⼀步:⽤pandas读取训练数据"""
datafile = os.path.join('..', 'data', 'labeledTrainData.tsv')
# escapechar='\\'⽤来去掉转义字符'\'
df = pd.read_csv(datafile, p='\t', escapechar='\\')汉简
print('Number of reviews: {}'.format(len(df)))
df.head()
第⼆步:对影评数据做预处理。
⼤概有以下环节:
1. 去掉html标签
2. 移除标点
3. 切分成词/token
防踩踏应急预案
4. 去掉停⽤词
5. 重组为新的句⼦
"""第⼆步:数据预处理"""
eng_stopwords = stopwords.words('english')
# 去掉html标签
# 去掉⾮英⽂字符
# 去停⽤词
# 重新组合为句⼦
def clean_text(text):
吸脂后遗症text = BeautifulSoup(text, 'html.parr').get_text()
text = re.sub(r'[^a-zA-Z]', '', text)
words = text.lower().split()
words = [w for w in words if w not in eng_stopwords]
return''.join(words)
df['clean_review'] = df.review.apply(clean_text)
df.head()
第三步:⽤向量空间模型抽取⽂本特征
分别计算单词的词频和Tf-Idf,作为⽂本特征,计算单词-⽂本矩阵。
"""第三步:⽤VSM抽取⽂本特征"""
# 统计词频,作为⽂本特征,计算⽂本-单词矩阵
vectorizer_freq = CountVectorizer(max_features = 5000)
wps表格合并train_vsm_freq = vectorizer_freq.fit_transform(df.clean_review).toarray()
print("以词频为元素的⽂本-单词矩阵的维度是:\n\n",train_vsm_freq.shape)
# 计算tfidf,作为另⼀种⽂本特征,计算⽂本-单词矩阵
vectorizer_tfidf=TfidfVectorizer(max_features=5000)
train_vsm_tfidf=vectorizer_tfidf.fit_transform(df.clean_review).toarray()
print("\n⽤单词向量空间模型成功抽取⽂本特征!\n")
活跃的意思
以词频为元素的⽂本-单词矩阵的维度是:
(25000, 5000)
⽤单词向量空间模型成功抽取⽂本特征!
第四步:训练分类器
决策树为200棵。
"""第四步:⽤随机森林训练⼆分类器"""
"""⾸先使⽤以词频为元素的⽂本-单词矩阵训练⼀个分类器"""
入耳式耳机品牌# 使⽤包外估计作为模型泛化误差的估计,即oob_score=True,那么⽆须再做交叉验证
forest = RandomForestClassifier(oob_score=True,n_estimators = 200)
forest = forest.fit(train_vsm_freq, df.ntiment)
第五步:评估分类器的性能
这⾥没有进⾏交叉验证了,没有划分验证集来计算准确率、召回率和AUC,直接⽤训练集来计算这些指标。因为随机森林通过⾃助采样,可以得到⼤约36.8%的验证集,⽤于评估模型的泛化误差,称这为包外估计,因此我们主要观察包外估计这个指标,来评估分类器的性能。
从评估结果来看,包外估计为0.84232。
"""第五步:评估模型"""
def model_eval(train_data):
print("1、混淆矩阵为:\n")
fusion_iment, forest.predict(train_data)))
print("\n2、准确率、召回率和F1值为:\n")
print(metrics.classification_iment,forest.predict(train_data)))
print("\n3、包外估计为:\n")
b_score_)
print("\n4、AUC Score为:\n")
y_predprob = forest.predict_proba(train_data)[:,1]
_auc_iment, y_predprob))
print("\n====================评估以词频为特征训练的模型==================\n")
model_eval(train_vsm_freq)
第六步:以Tf-Idf作为⽂本特征,训练分类器
结果包外估计为0.84168,⽐词频矩阵的要低⼀点,问题不⼤。
"""再使⽤以tfidf为元素的⽂本-单词矩阵训练⼀个分类器"""
forest = RandomForestClassifier(oob_score=True,n_estimators = 200)
forest = forest.fit(train_vsm_tfidf, df.ntiment)
print("\n====================评估以tfidf为特征训练的模型==================\n")
model_eval(train_vsm_tfidf)
⼆、基于潜在语义分析的⽂本特征表⽰
潜在语义分析(Laten Semantic Analysis,LSA)是⼀种⽂本话题分析的⽅法,特点是可以通过矩阵分解(SVD或者NMF),来发现⽂本与单词之间的基于话题的语义关系。
LSA和VSM有什么关系呢?
1、VSM的优点是单词向量稀疏,计算效率⾼,但是由于⾃然语⾔中⼀词多义和多词⼀义现象的存在,基于单词向量的⽂本表⽰未必能准确表达两个⽂本的相似度。⽽LSA是⽤⽂本的话题来表⽰⽂本,⽂本的话题相似则⽂本的语义也相似,这样可以解决同义词和多义词的问题。
2、VSM得到的是单词-⽂本矩阵,⽽LSA得到的是话题-⽂本矩阵。LSA的话题-⽂本矩阵就是通过对VSM的矩阵进⾏矩阵分解得到的,矩阵分解的⽅法包括SVD奇异值分解和NMF⾮负矩阵分解。
如下图,NMF⾮负矩阵分解后得到话题-⽂本矩阵Y,话题为k个,样本为n个。
在这个情感分析案例中,我们把话题设为300个,把单词-⽂本矩阵降维成(25000, 300)的话题-⽂本矩阵,采⽤的是NMF⾮负矩阵分解的⽅法。
要注意的⼀点是,如果单词-⽂本矩阵的维度是(单词数,⽂本数)这种格式,也就是我们在代码中⽤到的格式,那么在⽤
平生不修善果
sklearn.decomposition.NMF 这个包计算话题-⽂本矩阵时,NMF().fit_transform() 所得的是话题-⽂本矩阵,NMF().components_得到的是单词-话题矩阵。
⽽如果单词-⽂本矩阵的格式和上图的格式⼀样(转置了),那么NMF().components_得到的是话题-⽂本矩阵。
下⾯⾸先⽤NMF计算LSA的话题-⽂本矩阵,取以词频为元素的单词-⽂本矩阵来计算。对⾼维矩阵进⾏矩阵分解的时间复杂度⾮常⾼,所以我⽤⼀下LSA就好了,LDA就不敢再去尝试,因为LDA的时间复杂度更⾼,效果可能不⼀定好。
大学生谈恋爱第⼀步:⽤NMF计算LSA的话题-⽂本矩阵
"""⽤NMF计算LSA的话题-⽂本矩阵"""
from sklearn.decomposition import NMF
# 对以词频为特征的单词-⽂本矩阵进⾏NMF分解
nmf = NMF(n_components=300)
# 得到话题-⽂本矩阵,注意如果输⼊进⾏了转置,那么得到的是单词-话题矩阵
train_lsa_freq = nmf.fit_transform(train_vsm_freq)
print("话题-⽂本矩阵的维度是:\n\n",train_lsa_freq.shape)
话题-⽂本矩阵的维度是:
(25000, 300)
第⼆步:使⽤LSA的话题-⽂本矩阵训练随机森林分类器
包外估计为0.82236,⽐基于VSM的效果要差2个百分点左右,毕竟特征维度降低了。本来想把话题设定为500,也就是把特征维度降到500维,可是计算时间太恐怖了,久久得不到结果。
这真是费⼒不讨好。
"""再使⽤LSA的话题-⽂本矩阵训练⼀个分类器"""
forest = RandomForestClassifier(oob_score=True,n_estimators = 200)
forest = forest.fit(train_lsa_freq, df.ntiment)
print("\n====================评估以LSA为特征训练的模型==================\n")
model_eval(train_lsa_freq)

本文发布于:2023-07-09 20:04:14,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/1074817.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:矩阵   单词   模型   特征   向量   话题
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图