目录

一、项目背景与数据准备

1.1 数据读取与初步处理

1.2文本分词

二、核心数据清洗:移除停用词

2.1 什么是停用词?

2.2 如何移除停用词?

三、模型训练:朴素贝叶斯分类器

3.1 数据标签化与合并

3.2 数据切分

3.3 词向量转换

3.4 训练朴素贝叶斯模型

四、模型评估与应用

4.1 模型评估

4.2 模型应用:预测新文本


今天我们将深入探讨文本情感分析的完整流程。我们将从数据准备开始,重点讲解数据清洗的关键步骤,然后详细介绍如何使用朴素贝叶斯算法训练一个情感分类模型,并最终实现对新文本的预测。本文将侧重于数据清洗和模型应用部分,帮助大家更好地理解和掌握文本分析的核心技术。

一、项目背景与数据准备

在开始之前,让我们简要了解一下我们的项目。我们将使用苏宁易购的用户评价数据,包括好评和差评,来训练一个模型,使其能够自动判断新的评价是好评还是差评。

1.1 数据读取与初步处理

首先,我们需要读取并初步处理数据。这里我们使用pandas库来读取文本文件,并对数据进行简单的预处理。



import pandas as pd

# 读取差评数据
cp_content = pd.read_table(r".\差评1.txt", encoding='utf-8', engine='python', header=None)
cp_content.rename(columns={0: "content"}, inplace=True)

# 读取好评数据
yzpj_content = pd.read_table(r".\优质好评1.txt", encoding='utf-8', header=None)
yzpj_content.rename(columns={0: "content"}, inplace=True)

读取两个文本文件(差评和好评),并将默认的列名重命名为content,以便后续处理。这是数据准备的第一步,确保我们有干净、规范的数据输入。

1.2文本分词

对文本进行分词处理。分词是将连续的文本拆分成一个个独立词语的过程,这是中文文本分析的基础步骤。我们使用jieba分词库来完成这项工作。

import jieba
#对差评分词
cp_segments=[]
contents=cp_content.content.values.tolist()
for content in contents:
    results=jieba.lcut(content)
    if len(results)>1:
        cp_segments.append(results)
# 对好评分词(步骤类似)
yzpj_segments = []
contents = yzpj_content["content"].values.tolist()
for content in contents:
    results = jieba.lcut(content)
    if len(results) > 1:
        yzpj_segments.append(results)

使用jieba.lcut()对每条评论进行精确分词,并过滤掉分词后长度小于等于 1 的无意义评论。分词后的结果将用于后续的特征提取和模型训练。

二、核心数据清洗:移除停用词

数据清洗是文本分析中至关重要的一步,它直接影响模型的性能。其中,移除停用词是数据清洗的核心环节之一。

2.1 什么是停用词?

停用词是指那些在文本中频繁出现但对文本含义影响不大的词语,例如 “的”、“是”、“我”、“很”、“啊” 等。这些词语虽然数量众多,但携带的信息量很少,移除它们可以减少特征维度,提高模型效率和准确性。

2.2 如何移除停用词?

我们首先需要一个停用词库,然后定义一个函数来移除文本中的停用词。
 

# 导入停用词库
stopwords = pd.read_csv(r".\StopwordsCN.txt", encoding='utf8', engine='python', index_col=False)
stopwords_list=stopwords.stopword.values.tolist()

def drop_stopwords(contents,stopwords):
    segments_clean = []
    for content in contents:
        line_clean=[]
        for word in content:
            if word nor in stopwords:
                line_clean.append(word)
        segments_clean.append(line_clean)
    return segments_clean

# 对差评数据去除停用词
contents = cp_segments  # 直接使用分词后的结果
cp_fc_contents_clean_s = drop_stopwords(contents, stopwords_list)

# 对好评数据去除停用词
contents = yzpj_segments
yzpj_fc_contents_clean_s = drop_stopwords(contents, stopwords_list)

1.导入停用词库:我们从一个文本文件中读取停用词列表。这个文件包含了中文中常见的停用词。
2. 定义drop_stopwords函数:
输入:一个包含分词结果的列表(contents)和一个停用词列表(stopwords)。
输出:一个移除了停用词的分词结果列表。
核心逻辑:通过双重循环,外层循环遍历每一条评论,内层循环遍历评论中的每个词,判断该词是否为停用词。如果不是停用词,则将其保留下来。
3. 调用函数:我们分别对差评和好评的分词结果调用这个函数,得到清洗后的数据。

三、模型训练:朴素贝叶斯分类器

数据清洗完成后,我们就可以开始训练我们的情感分类模型了。我们选择朴素贝叶斯算法,它简单高效,非常适合处理文本分类问题。

3.1 数据标签化与合并
 

首先,我们需要为数据添加标签:好评为 0,差评为 1。然后将好评和差评数据合并成一个完整的训练数据集。

# 为数据添加标签:好评为0,差评为1
cp_train = pd.DataFrame({'segments_clean': cp_fc_contents_clean_s, 'label': 1})
yzpj_train = pd.DataFrame({'segments_clean': yzpj_fc_contents_clean_s, 'label': 0})

# 合并数据
pj_train = pd.concat([cp_train, yzpj_train], ignore_index=True)

3.2 数据切分

为了评估模型的泛化能力,我们需要将数据集划分为训练集和测试集。训练集用于训练模型,测试集用于评估模型在新数据上的表现。

from sklearn.model_selection import train_test_split

# 划分训练集和测试集,测试集占比30%
x_train, x_test, y_train, y_test = train_test_split(
    pj_train['segments_clean'].values, 
    pj_train['label'].values, 
    test_size=0.3,
    random_state=0
)

train_test_split函数将数据随机划分为训练集和测试集。
test_size=0.3表示测试集占总数据的 30%。
random_state=0设置随机种子,确保每次运行代码时划分结果一致,便于复现。

3.3 词向量转换

文本数据仍然是列表形式,我们需要将其转换为数值型的词向量。这里我们使用词袋模型(Bag of Words),通过CountVectorizer来实现。

from sklearn.feature_extraction.text import CountVectorizer

# 将分词后的列表转换为空格分隔的字符串
words = []
for line in x_train:
    words.append(' '.join(line))

# 初始化词向量转换器
vec = CountVectorizer(max_features=4000, lowercase=False, ngram_range=(1, 3))
vec.fit(words)  # 基于训练集构建词库

# 将训练集文本转换为词向量
x_train_vec = vec.transform(words)

' '.join(line):将分词后的列表(如['手机', '质量', '很好'])转换为字符串(如"手机 质量 很好"),这是CountVectorizer要求的输入格式。
 CountVectorizer:将文本转换为词频矩阵。
max_features=4000:只保留词频最高的前 4000 个词作为特征,防止特征维度过高导致的维度灾难。
lowercase=False:不将单词转换为小写,保留大小写信息。
ngram_range=(1, 3):考虑 1 个词(unigram)、2 个词(bigram)和 3 个词(trigram)的组合,这有助于捕捉更多的语义信息,例如 “性价比高” 这样的短语。
vec.fit(words):根据训练集的文本构建词库,这一步非常重要,确保了测试集和新数据的词向量转换基于相同的词库。
vec.transform(words):将训练集文本转换为词向量矩阵,每一行代表一个评论,每一列代表一个词,值为该词在评论中出现的次数。

3.4 训练朴素贝叶斯模型

现在我们可以用转换后的词向量来训练朴素贝叶斯分类器了。

from sklearn.naive_bayes import MultinomialNB

# 初始化多项式朴素贝叶斯分类器
classifier = MultinomialNB(alpha=0.1)
classifier.fit(x_train_vec, y_train)  # 训练模型


MultinomialNB:适用于离散特征(如词频)的朴素贝叶斯分类器,是文本分类中最常用的模型之一。
alpha=0.1:平滑系数,用于避免在计算条件概率时出现概率为 0 的情况(即某个词在某一类中从未出现过)。alpha 值越大,平滑效果越明显

四、模型评估与应用

模型训练完成后,我们需要评估它的性能,并将其应用于新的文本预测

4.1 模型评估

我们将在训练集和测试集上分别进行预测,并使用分类报告来评估结果。

from sklearn import metrics

# 在训练集上进行预测并评估
train_pr = classifier.predict(x_train_vec)
print("训练集分类报告:")
print(metrics.classification_report(y_train, train_pr))

# 在测试集上进行预测并评估
test_words = []
for line in x_test:
    test_words.append(' '.join(line))
test_pr = classifier.predict(vec.transform(test_words))
print("\n测试集分类报告:")
print(metrics.classification_report(y_test, test_pr))

classifier.predict(...):使用训练好的模型进行预测。
metrics.classification_report(...):生成详细的分类报告,包括:
精确率(Precision):预测为某一类的样本中,实际确实是该类的比例。
召回率(Recall):实际为某一类的样本中,被正确预测出来的比例。
F1 值(F1-score):精确率和召回率的调和平均数,综合衡量模型性能。
支持度(Support):某一类的样本数量。
通过对比训练集和测试集的分类报告,我们可以判断模型是否过拟合或欠拟合。如果训练集性能很好但测试集性能很差,说明模型过拟合了。

4.2 模型应用:预测新文本

模型训练和评估完成后,我们就可以用它来预测新的用户评价了。

import jieba

def predict_sentiment(sentence):
    """
    预测单句文本的情感倾向
    :param sentence: 待预测的文本字符串
    :return: 预测结果(好评/差评)
    """
    # 步骤1:分词(与训练数据预处理逻辑一致!)
    seg_list = jieba.lcut(sentence)
    
    # 步骤2:去停用词(与训练数据预处理逻辑一致!)
    seg_list = [w for w in seg_list if w not in stopwords_list and len(w) > 1]
    
    # 步骤3:转为CountVectorizer要求的格式(空格分隔字符串)
    s_str = ' '.join(seg_list)
    
    # 步骤4:用训练好的词库转换为词向量(必须用vec.transform,不能用fit!)
    s_vec = vec.transform([s_str])
    
    # 步骤5:模型预测
    pred_label = classifier.predict(s_vec)[0]
    
    # 步骤6:输出结果
    return "好评" if pred_label == 0 else "差评"

# 交互式预测
print("\n--- 情感预测演示 ---")
while True:
    s = input("请输入要判断的句子(输入'q'退出):")
    if s.lower() == 'q':
        break
    result = predict_sentiment(s)
    print(f"预测结果:{result}\n")

1.分词:使用jieba.lcut()对输入的句子进行分词,这一步必须与训练数据的分词逻辑完全一致。
2. 去停用词:同样,必须使用与训练数据相同的停用词库和过滤条件(如len(w) > 1)来清洗分词结果。这是保证预测准确性的关键!
3. 格式转换:将分词后的列表转换为空格分隔的字符串,以适应CountVectorizer的输入格式。
4. 词向量转换:使用训练好的vec对象的transform方法将新文本转换为词向量。注意:这里绝对不能使用fit方法,否则会重新构建词库,导致模型失效。
5. 模型预测:将转换后的词向量输入到训练好的分类器中进行预测,得到预测标签(0 或 1)。

结果输出:根据预测标签输出 “好评” 或 “差评”。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐