代碼實現:
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進行特征轉換
利用訓練好的模型進行情感預測
根據預測結果輸出對應的情感標簽
總結
這段代碼完整實現了一個中文文本情感分析系統,核心流程包括:
文本數據加載與分詞處理
停用詞過濾凈化文本
構建帶標簽的訓練數據集
文本特征向量化與類別平衡處理
樸素貝葉斯模型訓練與評估
實際文本情感預測應用
通過這個流程,我們可以將非結構化的文本數據轉換為機器學習模型可處理的結構化數據,最終實現對中文文本情感的自動分類。