【基于机器学习的餐馆评论文本分类分析】( 三 )


import jiebaimport refrom sklearn.model_selection import KFold# 加载停用词表stop_words = set()with open('D:/课程/数据挖掘技术与实践/作业/tc-corpus-answer/停用词表/stopwords.txt', encoding=encoding) as f:for line in f:stop_words.add(line.strip())def preprocess_text(text):# 去除空白字符text = re.sub(r'\s+', '', text)# 分词seg_list = jieba.lcut(text)# 去除停用词和非中文字符seg_list = [token for token in seg_list if token not in stop_words and re.match(r'^[\u4e00-\u9fa5]+$', token)]return ' '.join(seg_list)# 划分数据集为 10 个批次 , 并对每个批次中的 comment 列进行预处理 , 并单独保存到文件中kfold = KFold(n_splits=10, shuffle=True, random_state=42)for i, (train_idx, test_idx) in enumerate(kfold.split(df)):df_batch = df.iloc[test_idx].copy()df_batch['comment'] = df_batch['comment'].apply(preprocess_text)df_batch.to_csv(f'batches_{i+1}.csv', encoding='utf-8', index=False)# 读取第 1 个数据集文件batch_data = http://www.kingceram.com/post/pd.read_csv('batches_1.csv')# 读取其他 9 个数据集文件 , 并与第 1 个数据集合并for i in range(2, 11):batch_data_i = pd.read_csv(f'batches_{i}.csv')batch_data = pd.concat([batch_data, batch_data_i], ignore_index=True)# 将合并后的数据集保存为一个文件batch_data.to_csv('without_data.csv', index=False)batch_data = pd.read_csv('without_data.csv')
在进行分词和去停用词操作后 , 评论文本中出现了缺失值和重复值 , 删除这些数据 。
将数据集和数据集根据合并数据集 。
batch_data = http://www.kingceram.com/post/pd.merge(batch_data, restaurants[['restId', 'name']], on='restId', how='left'
原始文本经过分词和去停用词操作后的结果如下表所示
原始文本整体感觉还是不错的了 ,  , 比较安静惬意 ,  , 坐坐喝喝茶真的是挺舒服的 ,  ,  , 四周的环境绿化也挺不错
分词、去停用词
整体 感觉 不错 安静 惬意 坐坐 喝 喝茶 真的 挺舒服 四周 环境 绿化 挺不错 感觉
可以看出处理效果是非常明显的 , 许多符号和无意义文本都被去除 , 为后文建立模型提供了优质的数据基础 。
1.6 水军数据处理
统计列的字段长度 , 绘制箱线图如下:
import pandas as pdimport matplotlib.pyplot as pltfig, ax = plt.subplots(figsize=(8, 6))ax.boxplot(data['comment_length'],vert=False, widths=0.4, patch_artist=True, boxprops=dict(facecolor='LightBlue'))ax.set_title('Comment Length Boxplot', fontsize=14)ax.set_xlabel('Comment Length', fontsize=12)plt.show()
从上图我们可以看出 , 居然有评论内容的长度有2000字!that‘s !
在数据预处理的过程中 , 试图筛选出网络水军发表的评论 , 并进行清除 , 但是在实际操作过程中没有确定的标准来进行辨别 。
根据同一号在相近的时间内以相似的内容进行评论 , 被高度怀疑是网络水军的做法 , 数据预处理时仅根据这一实践经验进行了部分高度疑似水军数据的删除 。
from difflib import SequenceMatcherimport mathdata = http://www.kingceram.com/post/batch_data.copy()# 将数据集分成20个批次num_batches = 20batch_size = math.ceil(len(data) / num_batches)for i in range(num_batches):start_idx = i * batch_sizeend_idx = min((i+1) * batch_size, len(data))# 取出当前批次的数据batch_data = data.iloc[start_idx:end_idx]# 删除高度疑似水军数据idx_to_drop = []for j in range(1, len(batch_data)):# 判断userId是否相同if batch_data.iloc[j]['userId'] == batch_data.iloc[j-1]['userId']:# 判断时间间隔是否小于等于1分钟if pd.Timestamp(batch_data.iloc[j]['timestamp']) - pd.Timestamp(batch_data.iloc[j-1]['timestamp'])