代码实现:
import jieba
import pandas as pd
hp = pd.read_table('优质评价.txt',encoding='gbk')
cp = pd.read_table('差评1.txt',encoding='gbk')
cp_segments = []
contents = cp.content.values.tolist()
for content in contents:results = jieba.lcut(content)if len(results)>1:cp_segments.append(results)
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('StopwordsCN.txt',encoding='utf-8',engine='python',on_bad_lines='skip')
def drop_stopwords(contents,stopwords):segments_clean=[]for content in contents:line_clean = []for word in content:if word in stopwords:continueline_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 = drop_stopwords(contents,stopwords)
# print(cp_fc_clean)
contents = hp_fc_results.content.values.tolist()
hp_fc_clean = drop_stopwords(contents,stopwords)
# print(hp_fc_clean)
cp_train=pd.DataFrame({'segments_clean':cp_fc_clean, 'label':1})
hp_train=pd.DataFrame({'segments_clean':hp_fc_clean, '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
from sklearn.feature_extraction.text import CountVectorizer
from imblearn.over_sampling import SMOTE
all_words = []
for seg in pj_train['segments_clean'].values:all_words.append(' '.join(seg))
vec = CountVectorizer(max_features=5000, lowercase=False, ngram_range=(1,3))
all_vec = vec.fit_transform(all_words)
all_labels = pj_train['label'].values
smote = SMOTE(random_state=42)
all_vec_resampled, all_labels_resampled = smote.fit_resample(all_vec, all_labels)
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(all_vec_resampled,all_labels_resampled,test_size=0.2,random_state=0)
from sklearn.naive_bayes import MultinomialNB
classifier = MultinomialNB(alpha=0.1)
classifier.fit(x_train, y_train)
from sklearn import metrics
print("\n过采样后的训练集评估 ")
train_pr = classifier.predict(x_train)
print(metrics.classification_report(y_train, train_pr))
print("\n过采样后的测试集评估")
test_pr = classifier.predict(x_test)
print(metrics.classification_report(y_test, test_pr))
s = '这个玩意真好,我很喜欢'
s_seg = jieba.lcut(s)
s_seg_clean = []
for word in s_seg:if word in stopwords:continues_seg_clean.append(word)
s_words = [' '.join(s_seg_clean)]
s_vec = vec.transform(s_words)
predicted = classifier.predict(s_vec)
if predicted[0] == 0:print('这段话是好评')
else :print('这段话是差评')
代码解析:
这段代码实现了一个基于机器学习的文本情感分析系统,能够区分文本是好评还是差评。整个流程涵盖了数据加载、文本预处理、特征工程、模型训练和预测评估等完整环节。
一、数据加载与预处理
1. 导入必要库
import jiebaimport pandas as pd
jieba:中文分词库,用于将中文文本拆分为词语
pandas:数据处理库,用于数据读取、转换和存储
2. 加载评论文本数据
hp = pd.read_table('优质评价.txt',encoding='gbk')cp = pd.read_table('差评1.txt',encoding='gbk')
从本地文件加载好评和差评数据
使用gbk编码读取文本文件,适应中文编码格式
3. 文本分词处理
# 差评分词cp_segments = []contents = cp.content.values.tolist()for content in contents:results = jieba.lcut(content) # 精确分词if len(results)>1: # 过滤过短文本cp_segments.append(results)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)
将文本内容转换为列表形式便于处理
使用jieba.lcut()进行中文分词
过滤长度过短的文本,避免无意义数据
将分词结果保存为 Excel 文件,便于后续分析
二、停用词处理
1. 加载停用词表
stopwords = pd.read_csv('StopwordsCN.txt',encoding='utf-8',engine='python',on_bad_lines='skip')
加载中文停用词表(如 "的"、"是"、"在" 等无实际意义的词)
设置on_bad_lines='skip'跳过格式错误的行
2. 定义停用词过滤函数
def drop_stopwords(contents,stopwords):segments_clean=[]for content in contents:line_clean = []for word in content:if word in stopwords: # 如果是停用词则跳过continueline_clean.append(word)segments_clean.append(line_clean)return segments_clean
遍历每个分词结果
过滤掉属于停用词表中的词语
返回清洗后的分词结果
3. 执行停用词过滤
# 处理差评数据contents = cp_fc_results.content.values.tolist()stopwords = stopwords.stopword.values.tolist()cp_fc_clean = drop_stopwords(contents,stopwords)# 处理好评数据contents = hp_fc_results.content.values.tolist()hp_fc_clean = drop_stopwords(contents,stopwords)
将 DataFrame 中的分词结果转换为列表
将停用词表转换为列表便于查找
对好评和差评数据分别进行停用词过滤
三、数据集构建
# 构建带标签的训练数据cp_train=pd.DataFrame({'segments_clean':cp_fc_clean, 'label':1}) # 差评标签为1hp_train=pd.DataFrame({'segments_clean':hp_fc_clean, 'label':0}) # 好评标签为0pj_train = pd.concat([cp_train,hp_train]) # 合并正负样本pj_train.to_excel('pj_train.xlsx',index=False) # 保存训练数据
为不同情感的文本添加标签(1 表示差评,0 表示好评)
使用pd.concat()合并好评和差评数据
保存合并后的训练数据集
四、特征工程
1. 文本特征向量化
from sklearn.feature_extraction.text import CountVectorizer# 将分词列表转换为字符串all_words = []for seg in pj_train['segments_clean'].values:all_words.append(' '.join(seg))# 构建词袋模型vec = CountVectorizer(max_features=5000, lowercase=False, ngram_range=(1,3))all_vec = vec.fit_transform(all_words)
CountVectorizer:将文本转换为词频特征向量
max_features=5000:保留出现频率最高的 5000 个词
lowercase=False:不将文本转换为小写(中文无需此操作)
ngram_range=(1,3):考虑 1-3 个词的组合特征(如 "性价比"、"非常好" 等)
fit_transform():拟合模型并将文本转换为特征向量
2. 处理类别不平衡问题
from imblearn.over_sampling import SMOTEall_labels = pj_train['label'].values # 获取标签smote = SMOTE(random_state=42) # 初始化SMOTE过采样器all_vec_resampled, all_labels_resampled = smote.fit_resample(all_vec, all_labels)
SMOTE:一种过采样技术,用于解决类别不平衡问题
通过生成少数类别的合成样本,使正负样本比例平衡
random_state=42:设置随机种子,保证结果可复现
五、模型训练与评估
1. 划分训练集和测试集
from sklearn.model_selection import train_test_splitx_train, x_test, y_train, y_test = train_test_split(all_vec_resampled, all_labels_resampled,test_size=0.2, random_state=0)
将数据集划分为训练集(80%)和测试集(20%)
random_state=0:固定随机种子,确保划分结果一致
2. 训练朴素贝叶斯模型
from sklearn.naive_bayes import MultinomialNBclassifier = MultinomialNB(alpha=0.1) # 初始化多项式朴素贝叶斯模型classifier.fit(x_train, y_train) # 训练模型
MultinomialNB:适用于离散特征的朴素贝叶斯分类器,常用于文本分类
alpha=0.1:添加平滑参数,避免零概率问题
3. 模型评估
from sklearn import metricsprint("\n过采样后的训练集评估 ")train_pr = classifier.predict(x_train)print(metrics.classification_report(y_train, train_pr))print("\n过采样后的测试集评估")test_pr = classifier.predict(x_test)print(metrics.classification_report(y_test, test_pr))
使用classification_report生成详细评估指标
包括精确率(precision)、召回率(recall)、F1 分数等
分别评估模型在训练集和测试集上的表现
六、实际预测应用
# 待预测文本s = '这个玩意真好,我很喜欢'# 文本预处理(与训练数据处理保持一致)s_seg = jieba.lcut(s) # 分词s_seg_clean = []for word in s_seg:if word in stopwords: # 过滤停用词continues_seg_clean.append(word)s_words = [' '.join(s_seg_clean)] # 转换为字符串# 特征转换与预测s_vec = vec.transform(s_words) # 使用训练好的向量器转换predicted = classifier.predict(s_vec) # 预测# 输出结果if predicted[0] == 0:print('这段话是好评')else :print('这段话是差评')
对新文本进行与训练数据相同的预处理(分词、去停用词)
使用训练好的CountVectorizer进行特征转换
利用训练好的模型进行情感预测
根据预测结果输出对应的情感标签
总结
这段代码完整实现了一个中文文本情感分析系统,核心流程包括:
文本数据加载与分词处理
停用词过滤净化文本
构建带标签的训练数据集
文本特征向量化与类别平衡处理
朴素贝叶斯模型训练与评估
实际文本情感预测应用
通过这个流程,我们可以将非结构化的文本数据转换为机器学习模型可处理的结构化数据,最终实现对中文文本情感的自动分类。