You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化NLP场景下NLTK停用词移除与词形还原的计算速度

预处理速度优化方案

原代码的性能瓶颈主要来自四个重复开销点,针对性修改后无需更换核心依赖即可把27000条数据的总预处理耗时压到10秒以内,配合多进程加速可降至3-5秒,和模型评估速度基本持平。

核心性能瓶颈说明

  • 重复加载停用词表:remove_stopwords 函数每次调用都重新读取 stopwords.words("english"),没有复用你已经初始化好的 stop 全局集合,反复的IO和对象构建占用了一半以上的耗时
  • 单次POS标注效率极低:get_wordnet_pos 每次仅对单个单词做词性标注,nltk的pos_tag批量处理整句的效率是单次单词语料的上百倍
  • 正则表达式未预编译:punct_strip 函数每次调用都重新编译正则规则,重复计算开销大
  • 多次串行apply:停用词移除和词形还原分两次做apply,多走了一遍逐行串行调度开销,还多次重复做字符串的split/join操作

优化后代码

import pandas as pd
import re
import nltk
from nltk.corpus import stopwords, wordnet
from nltk.stem import WordNetLemmatizer
from nltk.tag import pos_tag

# 全局对象仅初始化加载一次
nltk.download("all")
stop = set(stopwords.words('english'))
lemmatizer = WordNetLemmatizer()
# 预编译正则规则
punct_re = re.compile(r'[^\w\s]')
# 词性映射表提前构建,避免每次函数调用重复生成
tag_dict = {"J": wordnet.ADJ,
            "N": wordnet.NOUN,
            "V": wordnet.VERB,
            "R": wordnet.ADV}

# 合并全部预处理逻辑,单次遍历完成所有操作
def text_preprocess(entry):
    # 1. 批量清洗标点
    clean_text = punct_re.sub(' ', entry)
    # 2. 整句仅做一次POS标注,大幅降低调度开销
    word_pos_pairs = pos_tag(clean_text.split())
    res_words = []
    for word, tag in word_pos_pairs:
        # 同步完成停用词过滤+词形还原,仅遍历单词一次;转小写匹配避免大小写漏匹配的Bug
        if word.lower() not in stop:
            wordnet_pos = tag_dict.get(tag[0].upper(), wordnet.NOUN)
            res_words.append(lemmatizer.lemmatize(word, wordnet_pos))
    return " ".join(res_words)

# 单次apply完成全部预处理,避免多次串行调用
df["Description_processed"] = df["Description"].apply(text_preprocess)

进一步加速方案

如果需要更快的处理速度,安装swifter库后将最后一行替换为以下代码,swifter会自动识别函数逻辑,无法向量化的场景会自动开启多进程利用CPU多核计算,27000条数据的处理耗时可进一步压缩到3-5秒:

import swifter
df["Description_processed"] = df["Description"].swifter.apply(text_preprocess)

内容的提问来源于stack exchange,提问作者SteP

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 23:57:02