通过机器学习技术对中文评论进行情感分析。我们使用了jieba进行中文分词,移除了停用词,并利用词袋模型(Bag of Words)和多项式朴素贝叶斯分类器对评论进行了情感分类。实验结果表明,该模型在测试集上达到了较高的准确率。
1.数据收集
我们收集了两组中文评论数据,分别代表正面(cp)和负面(hp)情感。
import pandas as pd
cp=pd.read_table(r"./评论/cp.txt",encoding='utf-8')
hp=pd.read_table(r"./评论/hp.txt",encoding='utf-8')
2.使用jieba进行中文分词。将分词结果转换为DataFrame,并保存为Excel文件。
import jieba
# 初始化用于存储负面评论分词结果的列表
cp_segments=[]
# 将负面评论内容转换成列表形式
contents=cp.content.values.tolist()
for content in contents:
# 对每个内容字符串使用 jieba.lcut 方法进行分词
results=jieba.lcut(content)
# 如果分词结果大于1个,则添加到列表中
if len(results)>1:
cp_segments.append(results)
# 将正面评论的分词结果列表转换成DataFrame
cp_fc_results=pd.DataFrame({'content':cp_segments})
# 将DataFrame保存为Excel文件,不保存索引
cp_fc_results.to_excel('cp_fc_results.xlsx',index=False)
# 初始化用于存储正面评论分词结果的列表
hp_segments=[]
contents=hp.content.values.tolist()
for content in contents:
results=jieba.lcut(content)
if len(results)>1:
hp_segments.append(results)
hp_fc_results=pd.DataFrame({'content':hp_segments})
hp_fc_results.to_excel('hp_fc_results.xlsx',index=False)
3.移除停用词,以减少数据的噪声。
# 读取停用词
stopwords = pd.read_csv(r"./StopwordsCN.txt", encoding='utf-8', engine='python', index_col=False)
# 定义函数,用于移除停用词
def drop_stopwords(contents,stopwords):
segments_clean=[]
for content in contents:
line_clean=[]
for word in content:
if word in stopwords:
continue
line_clean.append(word)
segments_clean.append(line_clean)
return segments_clean
# 移除正面评论的停用词
contents = cp_fc_results.content.values.tolist()
stopwords_list = stopwords.stopword.values.tolist()
cp_fc_clean_s = drop_stopwords(contents, stopwords_list)
# 移除负面评论的停用词
contents = hp_fc_results.content.values.tolist()
hp_fc_clean_s = drop_stopwords(contents, stopwords_list)
4.使用词袋模型(Bag of Words)将文本数据转换为数值向量
# 创建训练数据集
cp_train = pd.DataFrame({'segments_clean': cp_fc_clean_s, 'label': 1})
hp_train = pd.DataFrame({'segments_clean': hp_fc_clean_s, 'label': 0})
pj_train = pd.concat([cp_train, hp_train])
pj_train.to_excel('pj_train.xlsx', index=False)
# 划分训练集和测试集
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(pj_train['segments_clean'].values, pj_train['label'].values, random_state=0)
# 将训练集转换为字符串格式
words=[]
for line_index in range(len(x_train)):
words.append(' '.join(x_train[line_index]))
print(words)
# 使用词袋模型进行特征提取
from sklearn.feature_extraction.text import CountVectorizer
vec = CountVectorizer(max_features=4000, lowercase=False, ngram_range=(1, 1))
vec.fit(words)
5.采用多项式朴素贝叶斯分类器进行模型训练。
# 训练多项式朴素贝叶斯分类器
from sklearn.naive_bayes import MultinomialNB
classifier = MultinomialNB(alpha=0.1)
classifier.fit(vec.transform(words), y_train)
predict_train = classifier.predict(vec.transform(words))
6.使用准确率、召回率和F1分数等指标来评估模型的性能。
# 打印训练集上的分类报告
from sklearn import metrics
print(metrics.classification_report(y_train,predict_train))
test_words=[]
# 遍历测试集,将每个样本的分词结果转换为字符串格式
for line_index in range(len(x_test)):
test_words.append(' '.join(x_test[line_index]))
predict_test=classifier.predict(vec.transform(test_words))
print(metrics.classification_report(y_test,predict_test))
7.识别评论
s='这个玩意真好,我很喜欢'
a=[]
# 使用jieba进行分词
a0=jieba.lcut(s)
if len(a0)>1:
a.append(a0)
# 将分词结果转换为DataFrame
a1=pd.DataFrame({'content':a},)
# 获取分词结果列表
a2=a1.content.values.tolist()
# 移除停用词
a1_clean_s=drop_stopwords(a1,stopwords)
# 将清理后的分词结果转换为字符串格式,以符合模型预测的输入要求
word_1=[]
for line_index in range(len(a1_clean_s)):
word_1.append(' '.join(a1_clean_s[line_index]))
# 使用分类器进行预测
predict_word_1=classifier=classifier.predict(vec.transform(word_1))
print(predict_word_1)
8.输出结果
9.完整代码
import pandas as pd
cp=pd.read_table(r"./评论/2.txt",encoding='utf-8')
hp=pd.read_table(r"./评论/3.txt",encoding='utf-8')
import jieba
cp_segments=[]
#将内容转换成列表形式
contents=cp.content.values.tolist()
for content in contents:
#对每个内容字符串使用 jieba.lcut 方法进行分词,该方法返回一个列表,包含分词后的结果。
results=jieba.lcut(content)
if len(results)>1:
cp_segments.append(results)
#将列表转换成DataFrame
cp_fc_results=pd.DataFrame({'content':cp_segments})
cp_fc_results.to_excel('cp_fc_results.xlsx',index=False)
hp_segments=[]
contents=hp.content.values.tolist()
for content in contents:
results=jieba.lcut(content)
if len(results)>1:
hp_segments.append(results)
hp_fc_results=pd.DataFrame({'content':hp_segments})
hp_fc_results.to_excel('hp_fc_results.xlsx',index=False)
# 定义函数,用于移除停用词
stopwords=pd.read_csv(r".\StopwordsCN.txt",encoding='utf-8',engine='python',index_col=False)
def drop_stopwords(contents,stopwords):
segments_clean=[]
for content in contents:
line_clean=[]
for word in content:
if word in stopwords:
continue
line_clean.append(word)
segments_clean.append(line_clean)
return segments_clean
contents=cp_fc_results.content.values.tolist()
stopwords=stopwords.stopword.values.tolist()
cp_fc_clean_s=drop_stopwords(contents,stopwords)
contents=hp_fc_results.content.values.tolist()
hp_fc_clean_s=drop_stopwords(contents,stopwords)
cp_train=pd.DataFrame({'segments_clean':cp_fc_clean_s,'label':1})
hp_train=pd.DataFrame({'segments_clean':hp_fc_clean_s,'label':0})
pj_train=pd.concat([cp_train,hp_train])
pj_train.to_excel('pj_trian.xlsx',index=False)
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test=train_test_split(pj_train['segments_clean'].values,pj_train['label'].values,random_state=0)
words=[]
for line_index in range(len(x_train)):
words.append(' '.join(x_train[line_index]))
print(words)
from sklearn.feature_extraction.text import CountVectorizer
vec=CountVectorizer(max_features=4000,lowercase=False,ngram_range=(1,1))
vec.fit(words)
from sklearn.naive_bayes import MultinomialNB
classifier=MultinomialNB(alpha=0.1)
classifier.fit(vec.transform(words),y_train)
predict_train=classifier.predict(vec.transform(words))
from sklearn import metrics
print(metrics.classification_report(y_train,predict_train))
test_words=[]
for line_index in range(len(x_test)):
test_words.append(' '.join(x_test[line_index]))
predict_test=classifier.predict(vec.transform(test_words))
print(metrics.classification_report(y_test,predict_test))
s='这个玩意真好,我很喜欢'
a=[]
a0=jieba.lcut(s)
if len(a0)>1:
a.append(a0)
a1=pd.DataFrame({'content':a},)
a2=a1.content.values.tolist()
a1_clean_s=drop_stopwords(a1,stopwords)
word_1=[]
for line_index in range(len(a1_clean_s)):
word_1.append(' '.join(a1_clean_s[line_index]))
predict_word_1=classifier.predict(vec.transform(word_1))
print(predict_word_1)