欢迎光临
我们一直在努力

36 Python 时序和文本:中文文本处理入门:为什么要先做分词和停用词过滤?

中文文本处理入门:为什么要先做分词和停用词过滤?

刚接触文本分析时,很多人都会有一个疑问:

文本明明已经有内容了,为什么不能直接拿去做分类、聚类或者情感分析?

这个问题其实正好指向了文本挖掘里最基础、也最关键的一步:文本预处理。
文本挖掘通常包括文本预处理、文本挖掘和模式评估与表示三个主要过程 。如果预处理没有做好,后面的分析效果往往会受到明显影响。

这篇文章主要回答两个问题:

  • 为什么中文文本通常要先分词?
  • 为什么分词之后还要做停用词过滤?
  • 下面就从这两个问题开始。


    一、为什么文本不能直接分析?

    从人的角度看,一段文本的意思通常很容易理解。比如下面几条评论:

    • 这个电影真的很好看,我很喜欢
    • 剧情太拖沓了,不推荐
    • 演员表现不错,但是节奏一般
    • 画面很棒,音乐也很好听

    人很容易看出它们在表达什么,但计算机并不能直接做到这一点。
    因为对计算机来说,原始文本最开始只是一串字符,它并不知道:

    • 哪些字应该组合成一个词
    • 哪些词更重要
    • 哪些词只是语气词或结构词
    • 哪些词真正能帮助区分文本内容

    而文本挖掘的目标,是从大量文本数据中抽取未知但有用的知识。由于文本数据具有模糊性、非结构化等特点,所以文本挖掘本身就是一项相对复杂的工作 。

    这也是为什么文本不能直接“原样进入模型”,而需要先经过预处理。


    二、文本预处理在做什么?

    文本预处理的作用,可以简单理解为:

    先把原始文本整理成计算机更容易处理的形式。

    在文本挖掘流程中,文本预处理的任务是选取与任务相关的文本,并将其转化成文本挖掘工具可以处理的中间形式 。

    对于中文文本来说,这里面最基础的两步通常就是:

  • 分词
  • 停用词过滤
  • 这两步看起来简单,但后面的很多工作都建立在它们之上。


    三、为什么中文文本通常要先分词?

    这个问题和中文本身的表达方式有关。

    英文文本通常有空格,例如:

    This movie is very good

    至少可以先按空格切开。

    但中文通常是连续书写的,例如:

    这个电影真的很好看我很喜欢

    对计算机来说,它并不知道应该切成:

    • 这个 / 电影 / 真的 / 很 / 好看 / 我 / 很 / 喜欢

    还是别的形式。

    在中文文本处理中,一般认为词语是最小的语义单元。一句话可以由多个词语组成,而词语又可以由一个或多个汉字组成。因此,在进行文本分类等任务之前,首先要把文本切分成计算机可以处理的语义单元 。
    也正因为如此,和英文相比,中文文本预处理更重要,也更复杂 。


    四、什么是分词?

    分词就是把连续的中文文本切分成一个个词语。

    比如下面这句话:

    这个电影真的很好看,我很喜欢

    分词之后,可能会得到这样的结果:

    这个 / 电影 / 真的 / 很 / 好看 / 我 / 很 / 喜欢

    分词的意义在于:

    • 把整句文本拆成更小的语义单元
    • 为后续的统计分析提供基础
    • 为特征提取和建模做准备

    如果不先分词,后续很多文本分析工作很难展开。


    五、分词之后为什么还不够?

    分词做完之后,文本确实从“句子”变成了“词语集合”,但这还不等于已经可以直接做分析。

    原因在于:词出现得多,并不等于它就更有价值。

    在你提供的课件中也提到,文本中的词并不是出现频率越高,代表性就越强 。

    例如下面这些词:

    它们可能在很多文本里都频繁出现,但对于表达主题帮助很小。
    这些词既不能很好地区分不同文本,也很难帮助模型判断文本内容。

    所以,分词之后还需要继续做一步处理:停用词过滤。


    六、什么是停用词?

    如果一个词在文档中出现得很频繁,但并不能帮助表达主题,比如“的”“啊”“唉”这类词,那么这些词对区分文档是没有意义的,这类词就叫做停用词(Stop Word) 。

    停用词通常有几个特点:

    • 出现频率高
    • 信息量低
    • 对文本分类、聚类、关键词提取等任务帮助不大

    因此,通常需要把这些词从原始文本中去掉,这个过程就叫做停用词过滤 。


    七、为什么要做停用词过滤?

    停用词过滤的目的,核心上是为了减少噪声,让文本中更有价值的信息更容易保留下来。

    可以从几个角度来理解。

    1. 停用词会干扰统计结果

    如果不做过滤,词频统计里排在前面的,往往会是“的”“了”“我”“也”这一类词。
    这些词虽然常见,但通常不能代表文本主题。

    2. 停用词会降低区分度

    如果我们要判断一段文本是正面评价还是负面评价,那么像“的”“了”这种词在两类文本里都可能大量出现,它们并不能帮助分类。

    3. 停用词会影响后续特征提取

    后面做词袋模型、TF-IDF 或文本分类时,如果保留了太多停用词,就会引入很多低价值特征,影响分析效果 。

    所以停用词过滤并不是“可有可无的小优化”,而是文本预处理中很常见、也很必要的一步 。


    八、停用词一般怎么过滤?

    常见有两种方式。

    方法 1:按词频比例过滤

    统计每个词在整个文档集中的出现情况,如果某个词出现得过于频繁,比如超过文档总量的一定比例(例如 80%),就把它视为停用词 。

    这种方法的特点是:

    • 可以结合当前语料自动判断高频词
    • 但阈值设置有一定经验性
    • 也可能误删一些高频但其实有用的词

    方法 2:使用停用词表

    另一种更常见的方法,是提前准备一个停用词表,凡是出现在表里的词都过滤掉 。

    常见停用词表包括:

    • 哈工大停用词表
    • 四川大学机器学习智能实验室停用词库
    • 百度停用词表

    对于入门练习和一般课程实验来说,通常直接使用停用词表会更方便。


    九、代码演示:中文分词与停用词过滤

    下面用一个简单示例,把“分词 + 停用词过滤”的流程完整跑一遍。


    十、准备示例文本

    先准备几条电影评论文本:

    texts = [
    "这个电影真的很好看,我很喜欢,演员演技也不错。",
    "剧情太拖沓了,看得我想睡觉,不推荐。",
    "画面非常漂亮,但是故事比较一般。",
    "音乐很好听,节奏也不错,整体体验很好。",
    "这部电影太无聊了,浪费时间。"
    ]


    十一、安装并导入依赖库

    如果本地还没有安装 jieba,先执行:

    pip install jieba

    然后导入:

    import jieba
    from collections import Counter


    十二、第一步:对文本进行分词

    texts = [
    "这个电影真的很好看,我很喜欢,演员演技也不错。",
    "剧情太拖沓了,看得我想睡觉,不推荐。",
    "画面非常漂亮,但是故事比较一般。",
    "音乐很好听,节奏也不错,整体体验很好。",
    "这部电影太无聊了,浪费时间。"
    ]

    segmented_texts = []
    for text in texts:
    words = jieba.lcut(text)
    segmented_texts.append(words)

    for i, words in enumerate(segmented_texts, 1):
    print(f"文本{i}分词结果:{words}")

    运行后,不同环境下分词结果可能略有差异,但大体上会得到一组词语序列。


    十三、第二步:准备停用词表

    为了方便演示,这里手工定义一个小型停用词表。
    实际项目中,也可以换成外部停用词文件。

    stopwords = {
    "的", "了", "我", "也", "很", "太", "这部", "这个",
    ",", "。", "!", "?", "是", "在", "不", "得", "看得"
    }

    这里要提醒一点:

    停用词表不是绝对固定的。
    比如做情感分析时,“不”有时就很重要,不一定适合直接删除。


    十四、第三步:进行停用词过滤

    filtered_texts = []

    for words in segmented_texts:
    filtered_words = [word for word in words if word not in stopwords and word.strip()]
    filtered_texts.append(filtered_words)

    for i, words in enumerate(filtered_texts, 1):
    print(f"文本{i}过滤后结果:{words}")

    过滤之后,保留下来的词通常会更接近文本真正想表达的内容。


    十五、过滤前后做一个对比

    把原文本、分词结果和过滤后结果放在一起看,会更直观。

    for i in range(len(texts)):
    print(f"\\n======== 文本{i+1} ========")
    print("原文本:", texts[i])
    print("分词结果:", segmented_texts[i])
    print("过滤后:", filtered_texts[i])

    你会看到,过滤后留下来的词往往更有分析价值,比如:

    • 电影
    • 好看
    • 喜欢
    • 演员
    • 演技
    • 剧情
    • 拖沓
    • 睡觉
    • 推荐
    • 音乐
    • 无聊
    • 浪费时间

    相比之下,“的、了、我、很”这类词就没有那么重要。


    十六、统计高频词,看看过滤效果

    为了更直观地看到停用词过滤的作用,可以分别统计过滤前和过滤后的高频词。

    1. 统计过滤前高频词

    all_words_before = []
    for words in segmented_texts:
    all_words_before.extend([w for w in words if w.strip()])

    counter_before = Counter(all_words_before)

    print("======== 过滤前高频词 ========")
    for word, count in counter_before.most_common(15):
    print(f"{word}: {count}")

    2. 统计过滤后高频词

    all_words_after = []
    for words in filtered_texts:
    all_words_after.extend(words)

    counter_after = Counter(all_words_after)

    print("\\n======== 过滤后高频词 ========")
    for word, count in counter_after.most_common(15):
    print(f"{word}: {count}")

    一般情况下,过滤前高频词里会出现很多标点和功能词;过滤之后,留下来的词会更接近文本主题。

    这也正好说明了一个很重要的结论:

    词频高,不代表词就更有代表性 。


    十七、完整可运行代码

    下面是一份可以直接复制运行的完整代码。

    import jieba
    from collections import Counter

    # 1. 原始文本
    texts = [
    "这个电影真的很好看,我很喜欢,演员演技也不错。",
    "剧情太拖沓了,看得我想睡觉,不推荐。",
    "画面非常漂亮,但是故事比较一般。",
    "音乐很好听,节奏也不错,整体体验很好。",
    "这部电影太无聊了,浪费时间。"
    ]

    # 2. 停用词表(演示版)
    stopwords = {
    "的", "了", "我", "也", "很", "太", "这部", "这个",
    ",", "。", "!", "?", "是", "在", "不", "得", "看得"
    }

    # 3. 分词
    segmented_texts = []
    for text in texts:
    words = jieba.lcut(text)
    segmented_texts.append(words)

    # 4. 停用词过滤
    filtered_texts = []
    for words in segmented_texts:
    filtered_words = [word for word in words if word not in stopwords and word.strip()]
    filtered_texts.append(filtered_words)

    # 5. 输出对比结果
    for i in range(len(texts)):
    print(f"\\n======== 文本{i+1} ========")
    print("原文本:", texts[i])
    print("分词结果:", segmented_texts[i])
    print("过滤后:", filtered_texts[i])

    # 6. 统计过滤前高频词
    all_words_before = []
    for words in segmented_texts:
    all_words_before.extend([w for w in words if w.strip()])

    counter_before = Counter(all_words_before)

    print("\\n======== 过滤前高频词 ========")
    for word, count in counter_before.most_common(15):
    print(f"{word}: {count}")

    # 7. 统计过滤后高频词
    all_words_after = []
    for words in filtered_texts:
    all_words_after.extend(words)

    counter_after = Counter(all_words_after)

    print("\\n======== 过滤后高频词 ========")
    for word, count in counter_after.most_common(15):
    print(f"{word}: {count}")

    输出

    Building prefix dict from the default dictionary …
    Loading model from cache C:\\Users\\35979\\AppData\\Local\\Temp\\jieba.cache
    Loading model cost 0.603 seconds.
    Prefix dict has been built successfully.

    ======== 文本1 ========
    原文本: 这个电影真的很好看,我很喜欢,演员演技也不错。
    分词结果: ['这个', '电影', '真的', '很', '好看', ',', '我', '很', '喜欢', ',', '演员', '演技', '也', '不错', '。']
    过滤后: ['电影', '真的', '好看', '喜欢', '演员', '演技', '不错']

    ======== 文本2 ========
    原文本: 剧情太拖沓了,看得我想睡觉,不推荐。
    分词结果: ['剧情', '太', '拖沓', '了', ',', '看得', '我', '想', '睡觉', ',', '不', '推荐', '。']
    过滤后: ['剧情', '拖沓', '想', '睡觉', '推荐']

    ======== 文本3 ========
    原文本: 画面非常漂亮,但是故事比较一般。
    分词结果: ['画面', '非常', '漂亮', ',', '但是', '故事', '比较', '一般', '。']
    过滤后: ['画面', '非常', '漂亮', '但是', '故事', '比较', '一般']

    ======== 文本4 ========
    原文本: 音乐很好听,节奏也不错,整体体验很好。
    分词结果: ['音乐', '很', '好听', ',', '节奏', '也', '不错', ',', '整体', '体验', '很', '好', '。']
    过滤后: ['音乐', '好听', '节奏', '不错', '整体', '体验', '好']

    ======== 文本5 ========
    原文本: 这部电影太无聊了,浪费时间。
    分词结果: ['这部', '电影', '太', '无聊', '了', ',', '浪费时间', '。']
    过滤后: ['电影', '无聊', '浪费时间']

    ======== 过滤前高频词 ========
    ,: 8
    。: 5
    很: 4
    电影: 2
    我: 2
    也: 2
    不错: 2
    太: 2
    了: 2
    这个: 1
    真的: 1
    好看: 1
    喜欢: 1
    演员: 1
    演技: 1

    ======== 过滤后高频词 ========
    电影: 2
    不错: 2
    真的: 1
    好看: 1
    喜欢: 1
    演员: 1
    演技: 1
    剧情: 1
    拖沓: 1
    想: 1
    睡觉: 1
    推荐: 1
    画面: 1
    非常: 1
    漂亮: 1


    十八、如果要读取外部停用词表

    如果你已经准备好了 stopwords.txt 文件,也可以这样写:

    import jieba

    # 读取停用词表
    with open("stopwords.txt", "r", encoding="utf-8") as f:
    stopwords = set(line.strip() for line in f)

    text = "这个电影真的很好看,我很喜欢,演员演技也不错。"

    words = jieba.lcut(text)
    filtered_words = [word for word in words if word not in stopwords and word.strip()]

    print("分词结果:", words)
    print("过滤结果:", filtered_words)

    这种方式更适合后续扩展到更大的文本集。


    十九、几个容易忽略的问题

    1. 词频高,不一定就重要

    这是文本处理中很常见的误区。
    出现得多,只能说明它常见,不代表它真的有区分能力 。

    2. 停用词表不是固定不变的

    不同任务中,停用词可能不同。
    某些词在一个任务里没用,在另一个任务里可能很重要。

    3. 分词不是文本预处理的全部

    分词和停用词过滤只是开始。
    后面通常还会继续做文本表征,比如词袋模型或 TF-IDF,把词变成算法可以处理的数值形式 。


    二十、课后思考

    可以试着想一想下面几个问题:

  • 如果我要做“好评 / 差评”分类,停用词表能不能直接照搬?
  • “不”这个词在情感分析中到底该不该删?
  • 如果文本换成新闻标题,而不是电影评论,停用词会不会发生变化?
  • 如果完全不做停用词过滤,后面的特征提取会受到什么影响?

  • 二十一、小结

    这篇文章主要讲了两件事。

    第一,为什么中文文本通常要先分词。
    因为中文没有天然空格,而词语通常被看作最小语义单元,所以分词是文本处理的基础 。

    第二,为什么分词之后还要做停用词过滤。
    因为文本中的词并不是出现频率越高就越重要,那些高频但对表达主题帮助不大的词,需要在预处理阶段先过滤掉 。

    可以把这一步简单理解成:

    • 分词:把文本拆开
    • 停用词过滤:把噪声去掉

    这两步处理之后,文本才更适合进入后续的特征提取和建模流程。

    赞(0)
    未经允许不得转载:171主机测评 » 36 Python 时序和文本:中文文本处理入门:为什么要先做分词和停用词过滤?
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址