查看: 143|回复: 1

Python NLP文本预处理实战:分词清洗向量化全流程指南

[复制链接]
发表于 2 小时前 | 显示全部楼层 |阅读模式
文本预处理在NLP流程中扮演基石角色,目标是把非结构化文本转化为机器学习和深度学习模型能够理解的数值化表示。预处理的质量直接影响后续模型的效果,因此掌握一套系统、可复用的预处理代码十分必要。本文将基于Python生态,从分词、清洗、向量化到特征工程逐步展开,并提供可直接使用的脚本片段。

一、分词处理

对于中文等没有自然分隔符的语言,分词是首要步骤。推荐使用jieba库,它支持精确模式、全模式和搜索引擎模式。精确模式适合文本分析,全模式速度快但存在歧义,搜索引擎模式在精确模式基础上对长词再次切分,适合检索场景。
  1. import jieba
  2. text = "自然语言处理是人工智能的重要分支"
  3. print(jieba.lcut(text))  # 精确模式
  4. print(jieba.lcut(text, cut_all=True))  # 全模式
  5. print(jieba.lcut_for_search(text))  # 搜索引擎模式
复制代码

此外,jieba内置词性标注功能,通过posseg模块可获取每个词的词性标签。常见标签包括n(名词)、v(动词)、a(形容词)、ns(地名)、nr(人名)等。
  1. import jieba.posseg as pseg
  2. words = pseg.lcut("我爱北京天安门")
  3. for word, flag in words:
  4.     print(f"{word}({flag})", end=" ")
复制代码

当默认词典无法识别专业术语时,可以加载自定义词典。词典文件格式为“词语 词频 词性”,每行一个词。也可通过jieba.add_word动态添加。
  1. jieba.load_userdict("user_dict.txt")
  2. jieba.add_word('Transformer模型', freq=10, tag='n')
  3. print(jieba.lcut("自然语言处理和深度学习是人工智能的核心"))
复制代码

命名实体识别(NER)可利用jieba的词性标签提取人名、地名、机构名。如果要更准确,可以使用百度开源的LAC库。
  1. from LAC import LAC
  2. lac = LAC(mode='lac')
  3. result = lac.run("李白出生于蜀郡绵州昌隆县")
  4. print(result)
复制代码

停用词过滤是常见操作,通常加载一个停用词表,对分词结果进行过滤。停用词多为高频虚词,如“的、是、在”。
  1. stopwords = {'的', '了', '在', '是', '我', '有', '和', '就', '不', '人'}
  2. def remove_stopwords(words, stopwords):
  3.     return [word for word in words if word not in stopwords]
复制代码

二、文本清洗

原始文本常包含HTML标签、URL、特殊符号、多余空格等。正则表达式是最灵活的清洗工具。
  1. import re
  2. def clean_text(text):
  3.     text = re.sub(r'<[^>]+>', '', text)  # 去除HTML标签
  4.     text = re.sub(r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', '', text)  # 去除URL
  5.     text = re.sub(r'[^\u4e00-\u9fa5a-zA-Z0-9\s,。!?、;:""''()]', '', text)  # 保留中文标点
  6.     text = re.sub(r'\s+', ' ', text).strip()
  7.     return text
复制代码

数字处理有三种模式:替换为占位符、直接删除、保留。在文本分类场景中,替换为<NUM>可减少特征维度。
  1. def process_numbers(text, mode='replace'):
  2.     if mode == 'replace':
  3.         return re.sub(r'\d+', '<NUM>', text)
  4.     elif mode == 'remove':
  5.         return re.sub(r'\d+', '', text)
  6.     else:
  7.         return text
复制代码

大小写统一使用字符串的lower/upper/title方法。注意中文不受影响。
  1. def normalize_case(text, mode='lower'):
  2.     if mode == 'lower':
  3.         return text.lower()
  4.     elif mode == 'upper':
  5.         return text.upper()
  6.     elif mode == 'title':
  7.         return text.title()
复制代码

对于复杂的HTML文本,建议使用BeautifulSoup库提取纯文本。
  1. from bs4 import BeautifulSoup
  2. def remove_html_tags(text):
  3.     soup = BeautifulSoup(text, 'html.parser')
  4.     return soup.get_text()
复制代码

三、文本向量化

计算机无法直接处理单词,需将文本转换为数值向量。One-hot编码简单但高维稀疏,且无法表达语义关系。手动实现或使用sklearn的OneHotEncoder。
  1. import numpy as np
  2. from collections import Counter
  3. def one_hot_encode(texts):
  4.     all_words = []
  5.     for text in texts:
  6.         words = jieba.lcut(text)
  7.         all_words.extend(words)
  8.     word_counts = Counter(all_words)
  9.     vocab = sorted(word_counts.keys())
  10.     word_to_idx = {word: idx for idx, word in enumerate(vocab)}
  11.     encoded_texts = []
  12.     for text in texts:
  13.         words = jieba.lcut(text)
  14.         encoded = []
  15.         for word in words:
  16.             one_hot = np.zeros(len(vocab))
  17.             one_hot[word_to_idx[word]] = 1
  18.             encoded.append(one_hot)
  19.         encoded_texts.append(encoded)
  20.     return encoded_texts, vocab, word_to_idx
复制代码

词袋模型(Bag of Words)用词频向量表示句子。使用CountVectorizer可快速构建。
  1. from sklearn.feature_extraction.text import CountVectorizer
  2. vectorizer = CountVectorizer()
  3. jieba_cut = lambda x: ' '.join(jieba.lcut(x))
  4. cut_docs = [jieba_cut(doc) for doc in documents]
  5. X = vectorizer.fit_transform(cut_docs)
  6. print(vectorizer.get_feature_names_out())
复制代码

TF-IDF通过词频和逆文档频率加权,突出重要词。sklearn的TfidfVectorizer集成该功能,并可计算文档相似度(余弦相似度)。
  1. from sklearn.feature_extraction.text import TfidfVectorizer
  2. from sklearn.metrics.pairwise import cosine_similarity
  3. tfidf_vectorizer = TfidfVectorizer()
  4. tfidf_matrix = tfidf_vectorizer.fit_transform(cut_docs)
  5. sim_matrix = cosine_similarity(tfidf_matrix)
复制代码

Word2Vec能学习语义向量,使用gensim库可训练CBOW或Skip-gram模型。CBOW用上下文预测中心词,训练快;Skip-gram用中心词预测上下文,对罕见词更好。
  1. from gensim.models import Word2Vec
  2. tokenized_sentences = [jieba.lcut(s) for s in sentences]
  3. model_cbow = Word2Vec(sentences=tokenized_sentences, vector_size=100, window=5, min_count=1, workers=4, sg=0)
  4. model_sg = Word2Vec(sentences=tokenized_sentences, vector_size=100, window=5, min_count=1, workers=4, sg=1)
  5. print(model_cbow.wv.most_similar('自然语言处理', topn=3))
复制代码

在深度学习模型中,Embedding层将词索引映射为稠密向量。可自定义训练,也可加载预训练词向量作为权重。
  1. from tensorflow.keras.layers import Embedding
  2. from tensorflow.keras.preprocessing.text import Tokenizer
  3. from tensorflow.keras.preprocessing.sequence import pad_sequences
  4. tokenizer = Tokenizer()
  5. tokenizer.fit_on_texts(cut_texts)
  6. sequences = tokenizer.texts_to_sequences(cut_texts)
  7. padded = pad_sequences(sequences, maxlen=max_length, padding='post')
  8. embedding_layer = Embedding(input_dim=vocab_size, output_dim=50, input_length=max_length)
复制代码

四、特征处理

N-gram特征考虑词序,常用bi-gram或tri-gram。sklearn的CountVectorizer可直接设置ngram_range。
  1. vectorizer_ngram = CountVectorizer(ngram_range=(1, 2))
  2. X_ngram = vectorizer_ngram.fit_transform(cut_docs)
复制代码

另外,句子长度规范、统计特征(如词数、标点数量)也可作为特征加入模型。

五、完整预处理流程示例

将上述模块组合成一个流水线函数:
  1. def preprocess_pipeline(text, stopwords, num_mode='replace', case_mode='lower', use_ner=False):
  2.     text = clean_text(text)
  3.     text = process_numbers(text, num_mode)
  4.     text = normalize_case(text, case_mode)
  5.     words = jieba.lcut(text)
  6.     words = remove_stopwords(words, stopwords)
  7.     if use_ner:
  8.         entities = extract_entities(text)
  9.         words = entities['person'] + entities['location'] + entities['organization']
  10.     return words
复制代码

六、最佳实践建议

- 预处理流程应在训练和测试集上保持一致,避免数据泄露。
- 自定义词典需根据业务领域持续更新,降低未登录词比例。
- TF-IDF和Word2Vec的维度选择需实验调优,通常在100~300之间。
- 停用词表在不同任务中差异较大,建议基于数据统计生成领域停用词。
- 推荐工具库:jieba、gensim、sklearn、tensorflow、keras、LAC、BeautifulSoup。

进阶方向:预训练语言模型(BERT、GPT)的Tokenizer和子词单位处理,这在本文的基础上可进一步学习。
回复

使用道具 举报

发表于 2 小时前 | 显示全部楼层

Re: Python NLP文本预处理实战:分词清洗向量化全流程指南

感谢楼主分享这么详细的NLP预处理实战指南,从分词到向量化覆盖得很全面。尤其喜欢你把jieba的三种模式、自定义词典、停用词过滤和清洗正则都贴了代码,对初学者很友好。 有一点想请教:向量化部分只讲了One-hot,实际中TF-IDF和Word2Vec这类词嵌入也很常用,楼主有没有考虑把这些也纳入流程?另外,清洗环节对繁体字或拼音的处理有没有推荐的技巧?期待后续能补充特征工程部分的更多细节。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-6-10 12:37 , Processed in 0.032700 second(s), 18 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部