中文文本特征提取全解析:从分词、TF-IDF到预训练模型实战

发布时间:2026/10/20 18:13:53
中文文本特征提取全解析:从分词、TF-IDF到预训练模型实战 1. 从词袋到语义向量文本特征提取到底在解决什么问题很多人做机器学习项目卡住的地方往往不是模型选得不好而是特征工程这一步就没做扎实。尤其是文本数据它不像表格数据那样天生就是数字机器根本不认识苹果好吃快递很快这些字。文本特征提取要干的事情说白了就一句话把人类能看懂的文字翻译成机器能计算的数字向量而且尽量不丢失原文想表达的信息。我刚开始接触这块的时候天真地以为只要把每个字转成ASCII码或者Unicode编码就完事了。结果拿去做分类准确率惨不忍睹。原因很简单编码只是给每个字符一个身份证号它不携带任何语义信息。猫和狗的编码可能相差十万八千里但它们在语义上其实很接近。所以文本特征提取的核心目标是让转换后的数字向量能够反映词语之间的语义关系、文本的主题分布以及上下文结构。这个任务在实际项目里出现的频率极高。比如做评论情感分析你需要把用户写的几百字评论变成向量做新闻分类你需要把一篇上千字的文章压缩成固定长度的特征做垃圾短信识别你需要从短短几十个字里提取出判别性强的特征。不同场景对特征提取的要求完全不同这也是为什么文本特征提取有这么多方法从最古老的词袋模型到现在的预训练语言模型每一代方法都在解决上一代的痛点。这篇文章我会把文本特征提取的完整脉络梳理一遍从最基础的中文分词开始到词袋、TF-IDF、N-gram再到词向量和预训练模型每个方法都会讲清楚它为什么被设计出来、适合什么场景、实际用的时候有哪些坑。中文文本特征提取和英文有一个根本性的差异就是中文需要先分词这个环节的坑特别多我会单独用一章来讲。如果你正在做一个文本相关的机器学习项目或者单纯想把这块知识补扎实下面的内容应该能帮你少走不少弯路。2. 中文分词文本特征提取的第一道关卡2.1 为什么中文分词比英文难这么多英文文本天然有空格作为分隔符I love machine learning这句话机器一眼就能看出是四个单词。中文就不一样了我爱机器学习这六个字连在一起机器不知道应该切成我/爱/机器/学习还是我爱/机器/学习还是我/爱/机/器/学习。这种切分歧义是中文分词最核心的难点。更麻烦的是未登录词问题。英文里出现一个新词比如selfie它至少还是由字母组成的独立单元。中文里出现一个新词比如内卷躺平元宇宙如果分词工具的词典里没有收录它就可能被切得七零八落。我做过一个社交媒体文本分类的项目用户发的短文本里全是网络新词用默认词典分词之后绝绝子被切成了绝/绝/子yyds被当成了英文串特征质量非常差。还有一个容易被忽略的点分词粒度会直接影响后续特征的质量。切得太细比如机器学习切成机器和学习那机器学习这个完整概念就丢了切得太粗比如把自然语言处理整个当成一个词那自然语言和语言处理之间的关联又体现不出来。所以分词粒度没有绝对的对错要看你的下游任务是什么。2.2 主流中文分词工具的实际表现对比目前常用的中文分词工具就那么几个我把自己实际用过的几个做个对比方便你选型。工具分词模式自定义词典速度适用场景jieba精确/全/搜索引擎支持快通用场景社区活跃HanLP多粒度支持中等需要词性标注、命名实体识别pkuseg多领域支持中等特定领域文本如新闻、医疗THULAC多粒度支持中等需要词性标注的学术场景jieba是我用得最多的安装简单API直观社区文档也全。它的精确模式适合大多数分类任务搜索引擎模式适合做召回全模式基本用不上因为切得太碎反而引入噪声。HanLP功能更全但依赖也重一些如果你只需要分词jieba就够了。选工具的时候有一个经验不要只看分词准确率这个指标。很多工具在标准测试集上准确率都在95%以上差距很小。真正影响你项目效果的是它对领域词汇的处理能力。比如你做医疗文本那心肌梗死必须是一个词不能被切开你做法律文本不可抗力必须是一个词。所以选工具的时候拿你自己领域的几百条真实文本跑一遍看分词结果符不符合直觉这比看论文里的指标有用得多。2.3 自定义词典让分词工具认识你的领域词汇不管用哪个分词工具自定义词典都是必须做的一步。具体操作很简单以jieba为例你只需要准备一个文本文件每行一个词然后加载进去就行。import jieba # 加载自定义词典 jieba.load_userdict(user_dict.txt) # 或者动态添加单个词 jieba.add_word(内卷) jieba.add_word(躺平) jieba.add_word(元宇宙) text 当代年轻人面对内卷选择躺平却在元宇宙里寻找新机会 words jieba.lcut(text) print(words) # 输出: [当代, 年轻人, 面对, 内卷, 选择, 躺平, , 却, 在, 元宇宙, 里, 寻找, 新, 机会]自定义词典的来源有几个途径。一是从你的业务数据里统计高频n-gram人工筛选出有意义的词二是用新词发现算法自动挖掘比如基于左右邻接熵和互信息的方法三是直接收集行业术语表。我一般会先用第一种方法跑一遍把Top 500的高频未登录词人工过一遍加到词典里效果立竿见影。注意自定义词典不是越多越好。如果你把一些不该合并的词加进去比如把的时加进去反而会破坏分词结果。每加一个词都要想清楚这个词在你的业务场景里是不是一个独立的语义单元。2.4 停用词处理删掉哪些词保留哪些词分词之后下一步通常是去停用词。停用词就是那些出现频率极高但对任务没什么信息量的词比如的了在是和这些。去掉它们可以减少特征维度降低噪声。但停用词表不能随便找一个通用的就用。我见过一个项目做的是情感分析结果把不字去掉了导致好和不好变成了同一个特征模型完全分不清正面和负面。所以停用词表一定要根据任务定制。我的做法是先不加任何停用词跑一遍基线模型看特征重要性排序。那些重要性极低、出现频率又极高的词才考虑加入停用词表。同时对于情感分析、否定检测这类任务不没别无这些否定词必须保留。对于主题分类任务这些词可以去掉。# 一个针对通用分类任务的停用词表示例 stopwords set([ 的, 了, 在, 是, 我, 有, 和, 就, 不, 人, 都, 一, 一个, 上, 也, 很, 到, 说, 要, 去, 你, 会, 着, 没有, 看, 好, 自己, 这, 那, 他, 她, 它 ]) words [w for w in jieba.lcut(text) if w not in stopwords and len(w.strip()) 0]还有一个细节标点符号和特殊字符也要处理。中文文本里经常混着英文标点、表情符号、URL、提及这些需要根据任务决定是保留还是删除。做社交媒体分析的时候表情符号有时候反而是强特征不能一概而论。3. 词袋模型与TF-IDF最经典也最实用的文本向量化方法3.1 词袋模型的直觉与数学表达词袋模型Bag of Words是文本特征提取里最直观的方法。它的核心思想特别简单忽略词序只看每个词出现了没有、出现了几次。就像你把一篇文章里所有的词扔进一个袋子里摇一摇然后统计每个词出现的次数。数学上假设你的词汇表有V个词那每篇文档就可以表示成一个V维的向量向量的第i个分量就是第i个词在这篇文档里出现的次数。比如词汇表是[我, 爱, 机器, 学习]那我爱机器学习就是[1, 1, 1, 1]我爱学习就是[1, 1, 0, 1]。from sklearn.feature_extraction.text import CountVectorizer corpus [ 我爱机器学习, 我爱深度学习, 机器学习很有趣 ] vectorizer CountVectorizer(tokenizerjieba.lcut) X vectorizer.fit_transform(corpus) print(vectorizer.get_feature_names_out()) # 输出: [学习, 我爱, 有趣, 机器, 深度] print(X.toarray()) # 输出: # [[1 1 0 1 0] # [1 1 0 0 1] # [1 0 1 1 0]]词袋模型的优点很明显简单、可解释、计算快。但缺点同样明显。第一它完全丢失了词序信息我打你和你打我在词袋模型里是一样的。第二它假设词与词之间相互独立但实际语言里词与词之间是有强关联的。第三高频词会主导向量像的是这种词出现次数多但信息量低。3.2 TF-IDF给每个词一个合理的权重TF-IDF就是为了解决词袋模型里高频词主导的问题而设计的。它的核心思想是一个词在当前文档里出现得越多它越重要但它在所有文档里出现得越多它就越不重要。TF词频就是某个词在文档里出现的次数除以文档总词数。IDF逆文档频率是总文档数除以包含该词的文档数再取对数。TF-IDF就是两者相乘。from sklearn.feature_extraction.text import TfidfVectorizer corpus [ 我爱机器学习, 我爱深度学习, 机器学习很有趣 ] vectorizer TfidfVectorizer(tokenizerjieba.lcut) X vectorizer.fit_transform(corpus) print(vectorizer.get_feature_names_out()) print(X.toarray())TF-IDF的直觉是如果一个词在几乎所有文档里都出现比如的那它的IDF就接近0权重被压得很低。如果一个词只在少数文档里出现比如深度学习那它的IDF就很高权重被放大。这样真正有区分度的词就会在向量里占据更大的比重。实际用的时候有几个参数需要调。max_df可以过滤掉出现频率过高的词比如设成0.9表示出现在90%以上文档里的词不要。min_df可以过滤掉出现频率过低的词比如设成2表示至少在2篇文档里出现过的词才保留。max_features可以限制词汇表大小比如设成5000只保留TF-IDF权重最高的5000个词。这些参数在数据量大、词汇表爆炸的时候特别有用。3.3 N-gram用局部词序信息弥补词袋的缺陷词袋模型丢掉了词序N-gram就是来补这个缺的。N-gram指的是连续的N个词的组合。比如我爱机器学习2-gram就是[我爱, 爱机器, 机器学习]3-gram就是[我爱机器, 爱机器学习]。from sklearn.feature_extraction.text import TfidfVectorizer corpus [ 我爱机器学习, 我爱深度学习, 机器学习很有趣 ] # 同时使用1-gram和2-gram vectorizer TfidfVectorizer( tokenizerjieba.lcut, ngram_range(1, 2) ) X vectorizer.fit_transform(corpus) print(vectorizer.get_feature_names_out())N-gram的好处是能捕捉到一些局部搭配信息比如机器和学习经常一起出现那机器学习这个2-gram就会成为一个强特征。但N-gram的代价是特征维度会急剧膨胀。假设词汇表有1万个词1-gram有1万个特征2-gram就有接近1亿个可能的组合虽然实际出现的远没有这么多但维度还是会大幅增加。我的经验是对于大多数中文文本分类任务1-gram加2-gram就够了3-gram以上收益很小但计算成本很高。而且中文的2-gram有时候会跨越词边界产生一些没有意义的组合所以最好在分词之后再做N-gram而不是在字符级别做。3.4 词袋和TF-IDF在实际项目中的取舍那到底什么时候用词袋什么时候用TF-IDF我的判断标准是这样的如果文本长度比较均匀而且你关心的是词的出现与否而不是频率那词袋模型就够了。比如短文本分类每条文本就几十个字词频信息本身就不稳定用TF-IDF反而可能引入噪声。如果文本长度差异很大或者你需要做相似度计算、关键词提取那TF-IDF更合适。因为TF-IDF做了归一化长文档和短文档可以在同一个尺度上比较。还有一个实际考虑TF-IDF对参数更敏感。max_df、min_df、max_features这些参数设不好效果可能还不如默认的词袋模型。所以我的建议是先跑一个词袋模型的基线再试TF-IDF用交叉验证比较效果不要凭感觉选。提示词袋和TF-IDF得到的向量通常非常稀疏几千维的向量里可能只有几十个非零值。这种稀疏性对线性模型如逻辑回归、SVM是友好的但对基于距离的算法如KNN就不太友好因为所有文档之间的距离都差不多大。如果要用KNN最好先做降维比如用TruncatedSVD。4. 从离散到连续词向量如何让机器理解语义4.1 词袋模型的语义鸿沟词袋和TF-IDF有一个共同的硬伤它们把每个词当成一个独立的符号词与词之间没有任何语义关联。在词袋模型里猫和狗的向量是正交的余弦相似度为0但谁都知道猫和狗在语义上很接近。这种语义鸿沟导致模型很难泛化比如训练集里只有猫很可爱测试集里出现狗狗真萌模型就完全懵了。要解决这个问题就需要把词映射到一个连续的向量空间里让语义相近的词在空间里的距离也相近。这就是词向量Word Embedding的核心思想。4.2 Word2Vec用上下文定义词的含义Word2Vec是2013年提出的方法它的核心假设是一个词的含义可以由它周围的词来定义。比如猫经常出现在喵毛可爱附近狗经常出现在汪忠诚遛附近那通过大量文本的学习猫和狗的向量就会比较接近因为它们共享一些上下文词。Word2Vec有两种训练方式CBOW和Skip-gram。CBOW是用上下文词预测中心词Skip-gram是用中心词预测上下文词。Skip-gram对低频词的效果更好但训练更慢CBOW训练快但对低频词效果差一些。from gensim.models import Word2Vec import jieba # 假设我们有一个中文语料库 sentences [ 猫很喜欢吃鱼, 狗很喜欢啃骨头, 猫咪在阳光下睡觉, 狗狗在草地上奔跑 ] # 分词 tokenized [jieba.lcut(s) for s in sentences] # 训练Word2Vec模型 model Word2Vec( sentencestokenized, vector_size100, # 词向量维度 window5, # 上下文窗口大小 min_count1, # 最低词频 workers4, # 并行线程数 sg1 # 1表示Skip-gram0表示CBOW ) # 获取词向量 print(model.wv[猫]) print(model.wv.similarity(猫, 狗))实际用的时候vector_size一般设100到300window设5到10min_count根据语料规模设语料大就设大一点过滤掉低频噪声词。sg参数我一般设1因为Skip-gram对低频词更友好而中文里很多有价值的词恰恰是低频的。Word2Vec有一个重要特性词向量可以做算术运算。最经典的例子是国王 - 男人 女人 ≈ 女王。这说明词向量确实捕捉到了一些语义关系。但在中文里这种运算的效果没有英文那么稳定因为中文的语义关系更复杂而且分词质量会直接影响词向量的质量。4.3 GloVe与FastText不同思路的改进GloVe是另一种词向量方法它的出发点和Word2Vec不同。Word2Vec是基于局部上下文窗口预测的GloVe是基于全局共现矩阵分解的。它先统计整个语料里词与词的共现次数构建一个共现矩阵然后对这个矩阵做分解得到词向量。GloVe的好处是训练可以并行化而且对全局统计信息的利用更充分。FastText是Facebook提出的方法它在Word2Vec的基础上引入了子词信息。具体来说它把每个词拆成字符n-gram比如机器学习拆成机器器学学习以及更细的字符组合。这样即使一个词没在训练集里出现过只要它的子词在训练集里出现过也能得到一个合理的向量。这对中文特别有用因为中文的新词、专有名词特别多FastText能更好地处理未登录词。from gensim.models import FastText model FastText( sentencestokenized, vector_size100, window5, min_count1, workers4, sg1, min_n2, # 最小字符n-gram长度 max_n4 # 最大字符n-gram长度 ) # 即使猫咪没在训练集里出现也能得到向量 print(model.wv[猫咪])4.4 预训练语言模型文本特征提取的当前最优解Word2Vec和GloVe有一个根本性局限每个词只有一个固定的向量不管上下文是什么。苹果在吃苹果和苹果发布会里含义完全不同但Word2Vec给出的向量是一样的。这就是所谓的一词多义问题。预训练语言模型如BERT及其变体解决了这个问题。它们通过深层神经网络和注意力机制根据上下文动态生成每个词的向量。同一个词在不同句子里会有不同的向量表示这更符合语言的实际情况。from transformers import BertTokenizer, BertModel import torch # 加载预训练模型和分词器 tokenizer BertTokenizer.from_pretrained(bert-base-chinese) model BertModel.from_pretrained(bert-base-chinese) text 苹果很好吃但苹果公司的股价跌了 inputs tokenizer(text, return_tensorspt) outputs model(**inputs) # 获取最后一层的隐藏状态 last_hidden_states outputs.last_hidden_state print(last_hidden_states.shape) # 输出: torch.Size([1, 序列长度, 768])用预训练模型做特征提取一般取最后一层的[CLS] token的向量作为整句的表示或者对所有token的向量做平均池化。768维的向量包含了丰富的语义信息直接拿去做分类效果通常比TF-IDF好很多。但预训练模型也有代价。第一计算资源要求高推理速度比TF-IDF慢几个数量级。第二模型体积大动辄几百MB部署到移动端或嵌入式设备很困难。第三对短文本的效果提升可能没有想象中那么大因为短文本本身信息量就少预训练模型的优势发挥不出来。我的实际经验是如果数据量在几千条以上任务对语义理解要求高如情感分析、意图识别那预训练模型值得一试。如果数据量很小或者任务对实时性要求高那TF-IDF加线性模型可能更划算。不要盲目追求最新方法适合的才是最好的。5. 中文文本特征提取的完整实战流程5.1 数据清洗比模型选择更重要的一步我做过很多文本项目最后发现效果差异最大的往往不是模型而是数据清洗。中文文本的噪声特别多全角半角混用、繁简混用、表情符号、URL、HTML标签、重复字符这些不处理干净后面特征提取再精细也白搭。我的清洗流程一般是这样的第一步统一编码和全半角。把所有文本转成UTF-8全角字符转半角繁体转简体。这一步用unicodedata和opencc就能搞定。第二步去除无关内容。URL、邮箱、电话号码、HTML标签这些根据任务决定是否保留。做社交媒体分析的时候URL通常去掉但话题标签#和提及可能保留。第三步处理重复字符和表情。连续重复的字符比如好好好好好可以压缩成好表情符号可以转成文字描述或者直接去掉。import re import unicodedata def clean_text(text): # 全角转半角 text unicodedata.normalize(NFKC, text) # 去除URL text re.sub(rhttp\S|www\.\S, , text) # 去除邮箱 text re.sub(r\S\S, , text) # 去除HTML标签 text re.sub(r.*?, , text) # 压缩连续重复字符 text re.sub(r(.)\1{2,}, r\1\1, text) # 去除多余空白 text re.sub(r\s, , text).strip() return text注意清洗规则要根据任务定制。做情感分析的时候感叹号和问号是有信息量的不能随便去掉。做主题分类的时候这些标点就可以去掉。5.2 特征提取流水线的搭建把前面讲的步骤串起来一个完整的中文文本特征提取流水线大概是这样的import jieba from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.pipeline import Pipeline from sklearn.linear_model import LogisticRegression # 1. 自定义分词函数 def chinese_tokenizer(text): words jieba.lcut(text) # 去停用词和单字 words [w for w in words if w not in stopwords and len(w) 1] return words # 2. 构建流水线 pipeline Pipeline([ (tfidf, TfidfVectorizer( tokenizerchinese_tokenizer, ngram_range(1, 2), max_df0.9, min_df2, max_features10000 )), (clf, LogisticRegression(max_iter1000)) ]) # 3. 训练和预测 pipeline.fit(X_train, y_train) y_pred pipeline.predict(X_test)这个流水线的好处是分词、向量化、分类全部封装在一起用的时候直接fit和predict不用担心数据泄露问题。而且可以很方便地替换组件比如把TF-IDF换成CountVectorizer或者把逻辑回归换成SVM只需要改一行代码。5.3 特征维度与模型效果的平衡特征维度不是越高越好。维度太高模型容易过拟合训练也慢维度太低信息丢失太多模型欠拟合。怎么找这个平衡点我的做法是画一条学习曲线。横轴是特征维度通过max_features控制纵轴是验证集上的F1分数。一般会看到一个先上升后下降的趋势最高点就是比较合适的维度。对于中文文本分类这个点通常在5000到20000之间具体取决于语料规模和任务复杂度。还有一个技巧是用卡方检验或互信息做特征选择。SelectKBest可以帮你从TF-IDF向量里选出最相关的K个特征往往能用更少的特征达到相近甚至更好的效果。from sklearn.feature_selection import SelectKBest, chi2 from sklearn.pipeline import Pipeline pipeline Pipeline([ (tfidf, TfidfVectorizer(tokenizerchinese_tokenizer)), (select, SelectKBest(chi2, k5000)), (clf, LogisticRegression(max_iter1000)) ])5.4 效果评估与迭代方向文本特征提取做完之后怎么判断做得好不好不能只看准确率。对于类别不平衡的数据准确率会误导你。我一般会看这几个指标宏平均F1、加权平均F1、以及每个类别的精确率和召回率。如果发现某个类别的召回率特别低那可能是这个类别的特征不够有区分度。这时候可以回去看这个类别的文本分析它的关键词是什么是不是分词没分对或者停用词表把这个类别的关键信息去掉了。如果整体效果都不好那可能是特征提取方法不适合这个任务。比如做细粒度情感分析TF-IDF可能就不够用因为不是很满意和不是很失望在词袋模型里几乎一样但情感极性完全相反。这时候就需要上预训练模型或者引入情感词典作为额外特征。还有一个容易被忽略的迭代方向错误分析。把模型预测错的样本拿出来一条一条看你会发现很多问题其实出在数据质量上而不是模型上。比如标注错误、文本太短、噪声太多。修数据往往比调模型收益更大。6. 那些只有踩过才知道的坑6.1 分词不一致导致的训练测试偏差这个问题特别隐蔽。你在训练集上用jieba分词训练了一个TF-IDF向量化器保存了词汇表。然后在测试集或者线上环境如果分词结果和训练时不一致比如jieba版本升级了、自定义词典没加载、停用词表变了那向量化出来的特征就和训练时对不上模型效果会断崖式下跌。我的解决办法是把分词器和向量化器一起保存用的时候一起加载。不要分开保存更不要在线上的代码里重新初始化分词器。import joblib # 保存整个流水线 joblib.dump(pipeline, text_pipeline.pkl) # 加载 pipeline joblib.load(text_pipeline.pkl)6.2 新词和领域词汇的持续更新中文新词出现得特别快今天的热词明天可能就过时了。如果你的模型需要长期运行自定义词典和停用词表需要定期更新。我一般会设置一个监控机制统计线上预测置信度低的样本人工检查里面有没有新词然后定期更新词典。但更新词典之后向量化器的词汇表也会变旧模型就不能直接用了。所以要么定期重新训练模型要么在向量化的时候用vocabulary参数固定词汇表新词直接忽略。两种方案各有优劣看你的业务对时效性的要求。6.3 短文本特征稀疏的应对策略短文本是文本特征提取里最难啃的骨头。一条微博可能就十几个字分词之后只剩五六个词TF-IDF向量里非零值寥寥无几模型根本学不到东西。我试过几种应对策略。一是引入外部知识比如用预训练词向量做初始化或者用知识图谱补充关联信息。二是做特征增强比如把用户的性别、年龄、历史行为等结构化特征拼接到文本特征上。三是用字符级特征代替词级特征因为短文本里字符级信息反而更完整。四是直接用预训练模型因为预训练模型在大量语料上训练过对短文本的语义理解能力更强。这几种策略我都在不同项目里用过效果最好的是预训练模型加结构化特征拼接。但计算成本也最高需要根据业务场景权衡。6.4 类别不平衡对特征提取的隐性影响类别不平衡不仅影响模型训练也影响特征提取。如果某个类别的样本特别少那这个类别的关键词在TF-IDF里的IDF值会偏高因为包含这些词的文档少。这会导致这些词在向量里的权重被过度放大模型可能过度依赖这几个词来做判断泛化能力差。我的做法是在特征提取阶段就对少数类别做数据增强比如同义词替换、回译、或者用生成模型造一些样本。另外在TF-IDF的max_df和min_df参数上也要更保守一些避免少数类别的特征被过度放大。6.5 预训练模型微调时的特征提取陷阱用预训练模型做特征提取有一个常见的误区直接把预训练模型的输出拿去做分类不微调。这样效果往往不如微调后的模型因为预训练模型学的是通用语言知识和你的具体任务之间有差距。微调的时候学习率要设得很小通常在1e-5到5e-5之间。太大容易破坏预训练学到的知识太小又学不到任务特定的信息。另外微调的数据量不能太少至少几千条否则容易过拟合。如果数据量实在不够可以考虑只微调最后几层或者用Adapter等参数高效微调方法。还有一个坑是序列长度。BERT默认最大长度是512个token超过会被截断。中文里512个token大概对应300到400个汉字长文本会被截掉一部分。如果关键信息在文本末尾截断之后就丢了。解决办法是用滑动窗口把长文本切成多段分别提取特征再融合或者用支持长文本的模型变体。7. 方法选型不同场景下该用哪种特征提取方案7.1 按数据量选型数据量是选型的第一决定因素。我总结了一个简单的对照表数据量推荐方案理由 1000条TF-IDF 线性模型数据太少预训练模型容易过拟合1000-10000条TF-IDF 树模型或微调预训练模型两者都可以试看任务复杂度 10000条微调预训练模型数据充足预训练模型优势明显 100000条预训练模型 领域继续预训练可以进一步挖掘数据价值这个表只是参考实际还要看任务难度和计算资源。我见过500条数据微调BERT效果就很好的案例也见过10万条数据TF-IDF吊打BERT的情况。关键还是多做实验用验证集说话。7.2 按任务类型选型不同任务对特征的要求不一样。主题分类、情感分析、意图识别、命名实体识别每个任务的最优方案都不同。主题分类对词袋和TF-IDF就很友好因为主题通常由关键词决定词序不重要。情感分析对词序和否定词敏感N-gram和预训练模型更合适。意图识别通常文本很短需要外部知识补充。命名实体识别是序列标注任务需要token级别的特征预训练模型几乎是标配。7.3 按部署环境选型如果模型要部署到服务器那预训练模型没问题GPU推理很快。如果要部署到移动端或浏览器那模型体积和推理速度就是硬约束TF-IDF加线性模型可能更实际。如果要做实时推理延迟要求在毫秒级那TF-IDF几乎是唯一选择。我的一般原则是先用简单方法跑一个基线如果效果满足业务要求就不要上复杂模型。简单模型可解释性好、维护成本低、出问题容易排查。复杂模型虽然效果好但调试和部署的代价也大。技术选型不是越新越好而是越合适越好。8. 写在最后一些个人体会文本特征提取这个领域方法更新很快但核心思想其实很稳定怎么把文字里的信息尽可能完整地转换成数字同时去掉噪声和冗余。词袋、TF-IDF、词向量、预训练模型每一代方法都在这个方向上往前走了一步但没有哪一种方法是万能的。我自己的经验是不要一上来就追求最新最复杂的方法。先把数据清洗做好把分词和停用词处理好用TF-IDF跑一个基线。很多时候基线的效果已经能满足业务需求了。如果不够再逐步升级方法每次升级都要有明确的理由和可量化的收益。还有一个体会是特征提取的效果很大程度上取决于你对数据的理解。你得知道你的文本里有什么词、什么句式、什么噪声才能设计出合适的特征。多花时间看数据比多花时间调模型参数收益更大。我见过太多人一上来就调BERT的超参数结果数据里一半是重复样本清洗一下效果就上去了。最后中文文本特征提取有一些特殊性分词、新词、简繁混用这些问题在英文里不存在需要额外注意。但中文也有一些优势比如字符本身携带语义信息有时候字符级特征比词级特征更鲁棒。多尝试不同的粒度找到最适合你任务的那一种。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询