实用指南:自然语言处理NLP的数据预处理:从原始文本到模型输入(MindSpore版)

news/2025/11/30 16:17:59/文章来源:https://www.cnblogs.com/gccbuaa/p/19289563

自然语言处理(NLP)任务中,数据预处理的质量直接影响模型性能。即使是最先进的大模型,在未经处理的原始文本上也难以发挥作用。本文将详细介绍 NLP 数据预处理的核心步骤,并基于 MindSpore 框架提供代码实现,帮助你构建完整的预处理流水线。

为什么数据预处理至关重要?

原始文本数据通常存在噪声(如错别字、特殊符号)、格式不一致(如大小写混合)、冗余信息(如重复段落)等问题。预处理的目标是:

  • 统一数据格式,降低模型学习难度
  • 去除噪声,减少干扰信息
  • 将文本转化为模型可理解的数值形式
  • 适应特定任务需求(如分类、翻译、摘要)

下面以情感分析任务为例(输入文本,输出正面 / 负面标签),演示完整预处理流程。

数据预处理核心步骤

1. 数据加载与探索

首先需要加载数据并初步探索,了解数据分布(如文本长度、标签分布),为后续处理提供依据。

示例数据格式(CSV)

text,label
"这部电影太精彩了!推荐大家去看",1
"剧情拖沓,浪费时间...",0
"演员演技在线,但结局有点仓促",1
...

MindSpore 加载代码

import mindspore.dataset as ds
import pandas as pd
import matplotlib.pyplot as plt
# 加载CSV数据
df = pd.read_csv("reviews.csv")
print(f"数据集规模:{len(df)}条")
print(f"标签分布:{df['label'].value_counts().to_dict()}")
# 可视化文本长度分布
df["text_len"] = df["text"].apply(lambda x: len(x))
plt.hist(df["text_len"], bins=50)
plt.title("文本长度分布")
plt.xlabel("长度")
plt.ylabel("数量")
plt.show()
# 转换为MindSpore数据集
dataset = ds.NumpySlicesDataset(df[["text", "label"]].values, column_names=["text", "label"])

2. 文本清洗

去除无关字符、统一格式,减少噪声干扰。常见操作包括:

  • 去除特殊符号、标点
  • 大小写转换(通常转为小写)
  • 去除多余空格
  • 处理中英文混合场景(如保留中文,清理无意义符号)

清洗函数实现

import re
def clean_text(text):# 去除URLtext = re.sub(r"http\S+", "", text)# 去除特殊符号和标点(保留中文、字母、数字)text = re.sub(r"[^\u4e00-\u9fa5a-zA-Z0-9\s]", "", text)# 转为小写(英文)text = text.lower()# 去除多余空格text = re.sub(r"\s+", " ", text).strip()return text
# 应用清洗函数
dataset = dataset.map(operations=lambda x: (clean_text(x[0]), x[1]), input_columns=["text", "label"])

3. 分词(Tokenization)

将连续文本拆分为最小语义单位(词语或子词),是 NLP 的基础步骤。中文通常使用 jieba、THULAC 等工具,英文可直接按空格分词(或使用更复杂的子词分词)。

中文分词实现

import jieba
def tokenize(text):# 中文分词,过滤空字符串tokens = [token for token in jieba.cut(text) if token.strip()]return tokens
# 应用分词
dataset = dataset.map(operations=lambda x: (tokenize(x[0]), x[1]), input_columns=["text", "label"])

示例效果

  • 原始文本:"这部电影太精彩了!推荐大家去看"
  • 清洗后:"这部电影太精彩了推荐大家去看"
  • 分词后:["这部", "电影", "太", "精彩", "了", "推荐", "大家", "去看"]

4. 去除停用词

停用词是指在文本中频繁出现但语义贡献小的词(如 “的”、“是”、“在”),去除它们可以减少冗余,提升效率。

停用词处理

# 加载停用词表(可自定义或使用公开表)
with open("stopwords.txt", "r", encoding="utf-8") as f:stopwords = set(f.read().splitlines())
def remove_stopwords(tokens):return [token for token in tokens if token not in stopwords]
# 应用去停用词
dataset = dataset.map(operations=lambda x: (remove_stopwords(x[0]), x[1]), input_columns=["text", "label"])

示例效果

  • 分词后:["这部", "电影", "太", "精彩", "了", "推荐", "大家", "去看"]
  • 去停用词后:["电影", "精彩", "推荐", "大家"]

5. 词表构建与数值映射

模型无法直接处理文本,需要将词语转换为数值。这一步需要:

  • 构建词表(记录词语与索引的映射)
  • 将分词后的文本转换为索引序列

词表构建实现

from collections import Counter
# 收集所有词,统计频率
all_tokens = []
for data in dataset.create_dict_iterator():all_tokens.extend(data["text"])
# 按频率排序,保留前5000个词(超参数)
word_counts = Counter(all_tokens).most_common(5000)
# 构建词表:预留0(PAD)、1(UNK)
vocab = {"": 0, "": 1}
for word, _ in word_counts:vocab[word] = len(vocab)
print(f"词表大小:{len(vocab)}")
# 保存词表
import json
with open("vocab.json", "w", encoding="utf-8") as f:json.dump(vocab, f, ensure_ascii=False)

数值映射

def tokens_to_ids(tokens):# 未在词表中的词用代替return [vocab.get(token, 1) for token in tokens]
# 应用映射
dataset = dataset.map(operations=lambda x: (tokens_to_ids(x[0]), x[1]), input_columns=["text", "label"])

示例效果

  • 去停用词后:["电影", "精彩", "推荐", "大家"]
  • 数值映射后:[56, 128, 34, 92](假设词表中对应索引)

6. 序列长度对齐(Padding/Truncation)

模型输入需要固定长度,因此需对序列进行截断(超长)或填充(不足)。

长度对齐实现

import mindspore.dataset.transforms as C
import mindspore.dataset.vision as vision
# 设定最大长度(根据前面的长度分布统计结果)
max_seq_len = 32
def pad_sequence(ids):# 截断超长序列if len(ids) > max_seq_len:return ids[:max_seq_len]# 填充短序列(用的索引0)else:return ids + [0] * (max_seq_len - len(ids))
# 应用长度对齐
dataset = dataset.map(operations=lambda x: (pad_sequence(x[0]), x[1]), input_columns=["text", "label"])

7. 数据划分与格式转换

最后将数据集划分为训练集、验证集,并转换为模型可接受的格式(如 Tensor)。

最终处理步骤

# 划分训练集(80%)和验证集(20%)
dataset = dataset.shuffle(buffer_size=len(df))  # 打乱数据
train_size = int(0.8 * len(df))
train_dataset, val_dataset = dataset.split([train_size, len(df) - train_size])
# 转换为Tensor格式
train_dataset = train_dataset.map(operations=C.TypeCast(mstype.int32), input_columns=["text"])
train_dataset = train_dataset.map(operations=C.TypeCast(mstype.int32), input_columns=["label"])
val_dataset = val_dataset.map(operations=C.TypeCast(mstype.int32), input_columns=["text"])
val_dataset = val_dataset.map(operations=C.TypeCast(mstype.int32), input_columns=["label"])
# 批量处理(设置batch_size)
train_dataset = train_dataset.batch(batch_size=32)
val_dataset = val_dataset.batch(batch_size=32)
# 查看最终数据格式
for batch in train_dataset.create_dict_iterator():print("文本张量形状:", batch["text"].shape)  # (32, 32)print("标签张量形状:", batch["label"].shape)  # (32,)break

完整预处理流水线总结

将上述步骤整合,可构建一个可复用的预处理函数:

def preprocess_pipeline(file_path, max_seq_len=32, vocab_path=None):# 1. 加载数据df = pd.read_csv(file_path)dataset = ds.NumpySlicesDataset(df[["text", "label"]].values, column_names=["text", "label"])# 2. 文本清洗dataset = dataset.map(operations=lambda x: (clean_text(x[0]), x[1]), input_columns=["text", "label"])# 3. 分词dataset = dataset.map(operations=lambda x: (tokenize(x[0]), x[1]), input_columns=["text", "label"])# 4. 去停用词dataset = dataset.map(operations=lambda x: (remove_stopwords(x[0]), x[1]), input_columns=["text", "label"])# 5. 词表构建/加载与映射if vocab_path:with open(vocab_path, "r", encoding="utf-8") as f:vocab = json.load(f)else:all_tokens = []for data in dataset.create_dict_iterator():all_tokens.extend(data["text"])word_counts = Counter(all_tokens).most_common(5000)vocab = {"": 0, "": 1}for word, _ in word_counts:vocab[word] = len(vocab)with open("vocab.json", "w", encoding="utf-8") as f:json.dump(vocab, f, ensure_ascii=False)dataset = dataset.map(operations=lambda x: (tokens_to_ids(x[0]), x[1]), input_columns=["text", "label"])# 6. 长度对齐dataset = dataset.map(operations=lambda x: (pad_sequence(x[0], max_seq_len), x[1]), input_columns=["text", "label"])# 7. 划分与转换dataset = dataset.shuffle(buffer_size=len(df))train_size = int(0.8 * len(df))train_dataset, val_dataset = dataset.split([train_size, len(df) - train_size])train_dataset = train_dataset.map(operations=C.TypeCast(mstype.int32), input_columns=["text", "label"]).batch(32)val_dataset = val_dataset.map(operations=C.TypeCast(mstype.int32), input_columns=["text", "label"]).batch(32)return train_dataset, val_dataset, vocab

注意事项

  1. 预处理的任务相关性:不同任务(如机器翻译、命名实体识别)可能需要调整步骤(如翻译需保留句子结构,NER 需保留特殊符号)。
  2. 超参数调整:max_seq_len、词表大小等需根据数据分布调整,过长会增加计算量,过短会丢失信息。
  3. 效率优化:MindSpore 的 map 操作支持多线程加速(通过num_parallel_workers参数),大规模数据可开启。
  4. 可复现性:保存词表等中间结果,确保测试 / 部署时使用相同的预处理规则。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/981996.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mac 防止brew 安装 nginx 后不通过服务直接启动

直接看代码~,逻辑很简单,把原命令替换掉NGINX_BIN=$(which nginx) sudo mv "$NGINX_BIN" "${NGINX_BIN}.bin" sudo tee "$NGINX_BIN" << EOF #!/bin/bashNGINX_REAL="${B…

2025年云南高三高考冲刺培训排名:高考冲刺培训推荐几家?

TOP1 推荐:昆明市五华区滇云教育培训学校有限公司 推荐指数:★★★★★ 口碑评分:云南家长公认的靠谱高考冲刺机构 专业能力:滇云教育是经五华区教体局批准的正规培训机构,以16年高考补习经验为根基,构建精细化管…

从小工到专家3

篇三:《终身成长:重新定义成功的思维模式》读后感 —— 专家的格局:用 “成长思维” 抵御职业天花板​ 成为行业内公认的 “专家” 后,我曾一度陷入 “能力固化” 的焦虑:担心自己的知识体系过时,害怕被新生代超…

2025常州本地美食新地标TOP5权威推荐:挖掘城市烟火味,

在消费升级与城市文旅融合的浪潮下,本地美食新地标已成为城市文化传播与消费活力的核心载体。2024年常州餐饮消费数据显示,美食打卡地带动的餐饮客流量年增35%,但消费者常遇特色同质化体验单一化文化割裂化三大痛点…

CICD(一)CI/CD概述及GitLab部署和一些Git命令 - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

11.30代码大全二

一、核心认知:代码的本质是“与人沟通” 很多人误以为代码是写给计算机执行的,实则代码首先是写给人看的,其次才是给机器运行的——毕竟代码的生命周期中,编写时间仅占10%,其余90%都在阅读、修改、调试和维护。这…

KFCoder - 敏捷冲刺日志 - 3rd

第 3 篇 Scrum 冲刺博客(2025 年 11 月 29 日) 一、站立式会议记录项目 内容会议时间 2025 年 11 月 29 日 09:00-09:13(13 分钟)会议地点 团队参会人员 徐新曜、许国伟、罗芷忻、田璐、陈曦、白子璇、辜艺淇会议照…

11.30代码大全二(2)

二、关键原则与实践保持代码清晰可读命名是最重要的事:变量、函数、类名应准确表达其用途,避免缩写(除非广泛认可)。例如,用 CalculateTotalPrice() 而非 CalcTP() 。 ​ 注释应解释“为什么”而非“是什么”:…

KFCoder - 敏捷冲刺日志 - 2nd

第 2 篇 Scrum 冲刺博客(2025 年 11 月 28 日) 一、站立式会议记录项目 内容会议时间 2025 年 11 月 28 日 09:00-09:12(12 分钟)会议地点 团队参会人员 徐新曜、许国伟、罗芷忻、田璐、陈曦、白子璇、辜艺淇会议照…

2025江苏塑料中空板厂家TOP5权威推荐:中空板咬盖箱/对

包装领域中,企业对定制化塑料中空板制品需求日益增长。2024年数据显示,国内中空板包装市场规模超300亿元,年增速达28%,但30%的投诉集中在产品精度不足、防静电性能不达标、定制周期长三大问题。企业采购常遇坑:电…

2025专业奢侈品回收平台TOP5推荐:综合口碑企业助力安全

奢侈品回收市场需求逐年攀升,但价格不透明、交易周期长、异地回收难等痛点长期困扰用户。2023年行业调研显示,超60%用户遭遇过报价虚高后压价打款延迟等问题。为帮助用户避开回收坑,本文基于鉴定专业度、回款效率、…

同步带轮厂家TOP5权威推荐:同步带轮制造厂甄选指南,专业的

传动系统作为工业设备的动力中枢,其性能直接影响生产效率与设备稳定性。2024年数据显示,国内同步带轮市场规模突破120亿元,年增速达32%,但42%的企业反馈存在定制周期长、匹配精度低、寿命短等痛点——某汽车零部件…

2025常州本地人推荐美食:非遗美食鲜珍珍雪山草鸡火锅,解锁

在常州本地美食江湖中,土著推荐与非遗传承始终是食客们追逐的核心标签。2024年常州餐饮消费数据显示,融合本地特色+养生属性的餐饮门店客流量年增速达38%,但超20%的食客反馈难寻正宗本地非遗美食网红店噱头大于口味…

代码大全阅读笔记4

笔记二:实践指南——代码质量的“三大支柱” 《代码大全》并非纯理论书籍,而是给出了可落地的代码质量提升方案,核心可归纳为“三大支柱”:命名:让代码“自解释”好的命名无需注释就能说明含义,书中提出“使用问…

题解:B4395 [常州市赛 2025] 金币

题解:B4395 [常州市赛 2025] 金币 前言 题目传送门 思路讲解 一个十分经典的约瑟夫问题。 我们可以想象淘汰的过程,相当于每 \(k\) 个人中有1人被淘汰,留下来 \(k-1\) 个人,而且多余的人也会有一人被淘汰,那么我们…

20232317 2025-2026-1 《网络与系统攻防技术》实验七实验报告

1.实验内容 (1)简单应用SET工具建立冒名网站 (2)ettercap DNS spoof (3)结合应用两种技术,用DNS spoof引导特定访问到冒名网站。 2.实验过程 2.1 简单应用SET工具建立冒名网站 在root用户下通过setoolkit命令启…

笔记三

笔记三:调试与优化 —— 提升代码生命力的关键动作 《代码大全》中关于 “调试” 与 “性能优化” 的章节,彻底颠覆了我对这两个环节的片面认知。调试的核心并非 “盲目找 bug”,而是 “系统化排查问题”:首先必须…

笔记二

笔记二:模块化设计 —— 构建高内聚低耦合的代码体系 《代码大全》第二章 “结构化编程” 对模块化设计的深度剖析,让我对 “高内聚、低耦合” 这一抽象原则有了具象化的理解。高内聚强调模块内部功能的单一性与集中…

2025年新能源汽车充电桩生产商哪家好?新能源汽车充电桩生产

随着新能源汽车市场爆发式增长,充电桩作为新能源汽车的血液,其质量、服务与性价比直接影响车主体验与运营商收益。面对鱼龙混杂的市场,如何选择靠谱的充电桩生产商?以下结合源头实力、产品品质、售后服务三大核心维…

2025年专业的奢侈品回收品牌企业推荐:高性价比、口碑好的奢

本榜单依托奢侈品回收行业全维度调研与真实用户口碑,深度筛选出五家标杆企业,为消费者(尤其是奢侈品闲置处置需求用户)提供客观选型依据,助力精准匹配专业、靠谱的服务伙伴。 TOP1 推荐:小葫芦(深圳)互联网有…