使用 TFIDF+分类器 范式进行企业级文本分类(二)

1.开场白

上一期讲了 TF-IDF 的底层原理,简单讲了一下它可以将文本转为向量形式,并搭配相应分类器做文本分类,且即便如今的企业实践中也十分常见。详情请见我的上一篇文章 从One-Hot到TF-IDF(点我跳转)

光说不练假把式,在这篇文章中,你更加深刻了解TF-IDF是如何做文本分类的。具体有:

  1. 使用sklearn库进行TFIDF向量化
  2. 使用不同的分类器(SVM, 随机森林, XGBoost)做文本分类
  3. 搭配不同分类器的效果如何?

在开始之前推荐一个Github的开源项目。里面有很多开源数据集,很适合新手去探索 --> NLP民工乐园(本篇文章的数据集也是取自这里)

2.原理

1.TFIDF

TFIDF的原理虽然之前已经介绍了,但是这里还是简单讲一下好了。

TF-IDF(Term Frequency-Inverse Document Frequency)是一种用于信息检索和文本挖掘的加权技术,用于评估一个词在文档中的重要程度。它由两部分组成:

1. 词频(Term Frequency, TF)
衡量一个词在当前文档中出现的频率:

T F ( t , d ) = f t , d ∑ t ′ ∈ d f t ′ , d TF(t, d) = \frac{f_{t,d}}{\sum_{t' \in d} f_{t',d}} TF(t,d)=tdft,dft,d

其中:

  • f t , d f_{t,d} ft,d:词 t t t 在文档 d d d 中的出现次数
  • ∑ t ′ ∈ d f t ′ , d \sum_{t' \in d} f_{t',d} tdft,d:文档 d d d 中所有词的出现次数总和

2. 逆文档频率(Inverse Document Frequency, IDF)
衡量一个词的普遍重要性(在多少文档中出现):

I D F ( t , D ) = log ⁡ ( N ∣ { d ∈ D : t ∈ d } ∣ ) IDF(t, D) = \log \left( \frac{N}{|\{d \in D : t \in d\}|} \right) IDF(t,D)=log({dD:td}N)

其中:

  • N N N:语料库中文档的总数
  • ∣ { d ∈ D : t ∈ d } ∣ |\{d \in D : t \in d\}| {dD:td}:包含词 t t t 的文档数量

3. TF-IDF 最终公式
将TF和IDF相乘得到最终权重:

T F - I D F ( t , d , D ) = T F ( t , d ) × I D F ( t , D ) TF\text{-}IDF(t, d, D) = TF(t, d) \times IDF(t, D) TF-IDF(t,d,D)=TF(t,d)×IDF(t,D)

4. 变体说明
实际应用中可能存在不同变体,例如:

  • TF变体:对数缩放 T F = log ⁡ ( 1 + f t , d ) TF = \log(1 + f_{t,d}) TF=log(1+ft,d)
  • IDF变体:避免除零 I D F = log ⁡ ( N 1 + n t ) + 1 IDF = \log(\frac{N}{1 + n_t}) + 1 IDF=log(1+ntN)+1
  • 归一化:对文档向量进行L2归一化

2.SVM

全名支持向量机,简称SVM,在2000年前后的CPU时代,它也曾是顶流。

具体原理见我的另一篇文章,这是一篇背书于《统计学习方法》的、用严谨的数学进行SVM推导的文章 --> 支持向量机

之所以他曾是顶流,主要因为它具备如下优势

  1. SVM不存在现代深度学习反向传播的过拟合
  2. 小样本数据集上表现良好
  3. CPU环境下就能训练、推理,边缘设备(普通电脑)上也能跑起来
  4. 数学背景好,理论严谨

但是现在又被“淘汰”了,原因有:

  1. 大数据时代,SVM拓展性不足,数据量庞大的情况下训练很慢,相反深度学习可以利用GPU的并行,加速推理
  2. 泛化能力有限,SVM需要手动特征,而深度学习可以端到端自动学习特征
  3. 非线性场景能力有限,即便有核技巧处理非线性场景,但是函数选择和调参比较麻烦。
  4. 深度学习可以叠的很深,可以学习到数据中更加抽象、深层的信息,但SVM与之相比是浅层模型,学习到的信息有限。

关于支持向量机的作者 Vapnik,他还和现任人工智能的三驾马车 LeCun 有一段有趣的轶事,他们两个同为贝尔实验室的同事,因为学术之争处处不合。后来他们两位之间的争论某种意义上来说也代表了传统机器学习和深度学习之间的对碰。具体请见我的另一篇文章 自然语言处理发展史(点我跳转)

3.XGBoost

XGBoost 是梯度提升树GBDT的改良版,他们都是树模型的一种。

什么?你问我什么是树模型?好吧,这里我来解答一下,其实树模型是决策树类模型的简称,业内常常管决策树类的模型叫输模型。

至于决策树模型,可以见我另一篇文章 决策树(点我跳转)

跳转文章讲了决策树模型的基本原理,从纯数学的角度出发,带你理解决策树模型。

有了决策树的基础,理解GBDT和XGBoost就不是问题了。

那么让我们先了解GBDT,再看一看他是如何从GBDT过渡到XGBoost的吧

1.GBDT(梯度提升树)

GBDT(Gradient Boosting Decision Tree)的核心思想是通过加法模型(Additive Model)将多个弱分类器(通常是决策树)的预测结果逐步累加,从而逼近真实值
具体来说, 每一轮迭代都会训练一个新的弱分类器,使其拟合当前模型的负梯度(即残差的近似),而非直接拟合残差本身。
这里的“残差”可以理解为当前模型的预测值与真实值之间的误差方向,而GBDT通过梯度下降的策略逐步减少这一误差。

如图,Y = Y1 + Y2 + Y3
在这里插入图片描述

举一个非常简单的例子,比如我今年30岁了,但计算机或者模型GBDT并不知道我今年多少岁,那GBDT咋办呢?

它会在第一个弱分类器(或第一棵树中)随便用一个年龄比如20岁来拟合,然后发现误差有10岁;
接下来在第二棵树中,用6岁去拟合剩下的损失,发现差距还有4岁;
接着在第三棵树中用3岁拟合剩下的差距,发现差距只有1岁了;
最后在第四课树中用1岁拟合剩下的残差,完美。
最终,四棵树的结论加起来,就是真实年龄30岁。

实际工程中,gbdt是计算负梯度,用负梯度近似残差.

那么为什么用负梯度近似残差呢?

回归任务下,GBDT 在每一轮的迭代时对每个样本都会有一个预测值,此时的损失函数为均方差损失函数,
在这里插入图片描述

那此时的负梯度是这样计算的
在这里插入图片描述

所以,当损失函数选用均方损失函数时,每一次拟合的值就是(真实值 - 当前模型预测的值),即残差。
此时的变量是 y i y^i yi,即“当前预测模型的值”,也就是对它求负梯度。

2.XGBoost(极度梯度提升)

核心思想如图
在这里插入图片描述
在这里插入图片描述

(作者陈天奇大佬的原图)
可以看到,男孩的计算得分是两个树的相加 2+0.9=2.9

这不和GBDT一样么!

确实,如果不考虑工程实现、解决问题上的一些差异,xgboost与gbdt比较大的不同就是目标函数的定义

xgboost的目标函数如下图所示:
在这里插入图片描述
在这里插入图片描述

XGBoost的核心算法思想不难,基本就是:

  1. 不断地添加树,不断地进行特征分裂来生长一棵树,每次添加一个树,其实是学习一个新函数f(x),去拟合上次预测的残差。
  2. 当我们训练完成得到k棵树,我们要预测一个样本的分数,其实就是根据这个样本的特征,在每棵树中会落到对应的一个叶子节点,每个叶子节点就对应一个分数
  3. 最后只需要将每棵树对应的分数加起来就是该样本的预测值。

为什么XGBoost要用泰勒展开,优势在哪里?

XGBoost使用了一阶和二阶偏导, 二阶导数有利于梯度下降的更快更准. 使用泰勒展开取得函数做自变量的二阶导数形式, 可以在不选定损失函数具体形式的情况下, 仅仅依靠输入数据的值就可以进行叶子分裂优化计算, 本质上也就把损失函数的选取和模型算法优化/参数选择分开了. 这种去耦合增加了XGBoost的适用性, 使得它按需选取损失函数, 可以用于分类, 也可以用于回归。

3.数据集

该篇文章数据集地址 酒店评论 (也出自开头推荐的那个Github开源项目里)

该数据集是一个酒店评价数据集,有两个字段:

  • review为用户评论
  • label为情感的正负类标签,其中1为正面情绪,0为负面情绪

数据集预览
在这里插入图片描述

4.技术实践

1.sklearn中的使用TFIDF

前提:安装sklearn

pip install scikit-learn

在 scikit-learn (sklearn) 中,TfidfVectorizer 是用于 TF-IDF文本特征提取的主要类。它属于 sklearn.feature_extraction.text 模块,主要用于将文本数据转换为数值特征矩阵

下面讲一下它的关键参数吧~

  1. stop_words{‘english’}, list, default=None
  2. ngram_range: tuple (min_n, max_n)` default=(1, 1)
    a. 要提取的不同n-gram的n值范围的下限和上限。将使用min_n<=n<=max_n的所有n值。
  3. max_dffloat or int, default=1.0:
    i. 在构建词汇表时,忽略文档频率严格高于给定阈值的术语(特定于语料库的停用词)。如果在[0.0,1.0]范围内,则该参数表示文档的比例,即整数绝对计数。如果词汇表不是None,则忽略此参数。
  4. min_df float or int, default=1
    i. 在构建词汇表时,忽略文档频率严格低于给定阈值的术语。这个值在文献中也被称为截止值。如果浮点数在[0.0,1.0]的范围内,则该参数表示文档的比例,即整数绝对计数。如果词汇表不是None,则忽略此参数。
  5. max_features int, default=None
    i. 如果不是None,则构建一个词汇表,只考虑语料库中按词频排序的顶级max_features。否则,将使用所有功能。
    如果词汇表不是None,则忽略此参数。
  6. smooth_idf bool, default=True
    i. 通过在文档频率上加1来平滑idf权重,就像看到一个额外的文档包含集合中的每个术语一样。
  7. sublinear_tf bool, default=False
    i. 应用亚线性tf缩放,即将 tf 替换为1 + log(tf)。
tfidf = TfidfVectorizer(max_features=5000, stop_words=stopwords, ngram_range=(1,2),min_df=3,           # 过滤低频词max_df=0.9,          # 过滤高频词# sublinear_tf=True, # 对数平滑,降低词频影响
)
X = tfidf.fit_transform(train_df['processed_text'])
  1. 总结
    a. 注意调整ngram_rangemax_features 。直接对效率和特征表示能力相关联。

2.XGBoost

前提:安装XGBoost

pip install xgboost

下面讲讲xgboost的使用吧

1. 通用参数
宏观函数控制 在 xgboost.config_context() 设置
a. verbosity: Valid values of 0 (silent), 1 (warning), 2 (info), and 3 (debug).

2. 一般参数:
a. booster [default= gbtree ]。使用哪种助推器。可以是gbtree、gblinear或dart;gbtree和dart使用基于树的模型,而gblinear使用线性函数。
b. device [default= cpu]
c. nthread [如果未设置,则默认为可用的最大线程数]

3. Booster 参数
a. eta [default=0.3, alias(别名): learning_rate]
b. gamma [default=0, alias: min_split_loss][0,∞]

  • 在树的叶子节点上进行进一步分区所需的最小损失减少。gamma越大,算法就越保守。请注意,没有进行分割的树可能仍然包含一个非零分数的终端节点。

c. max_depth [default=6][0,∞]

  • 树的最大深度。增加此值将使模型更加复杂,更有可能过度拟合。0表示深度没有限制。请注意,XGBoost在训练深层树时会大量消耗内存。精确树方法需要非零值。

d. min_child_weight [default=1][0,∞]

  • 孩子结点所需实例权重的最小总和。如果树分区步骤导致叶节点的实例权重之和小于min_child_weight,则构建过程将放弃进一步的分区。在线性回归任务中,这只对应于每个节点中需要的最小实例数。min_child_weight越大,算法就越保守。

e. subsample [default=1]

  • 训练实例的子样本比率。将其设置为0.5意味着XGBoost将在种植树木之前随机采样一半的训练数据。这将防止过拟合。子采样将在每次增强迭代中发生一次。

f. lambda [default=1, alias: reg_lambda]

  • 权重的L2正则化项。增加此值将使模型更加保守。range: [0, ∞]

g. alpha [default=0, alias: reg_alpha]

  • 权重上的L1正则化项。增加此值将使模型更加保守。range: [0, ∞]

h. tree_method string [default= auto] auto, exact, approx, hist

  • auto: 与hist-tree方法相同。
  • exact: 精确贪婪算法。枚举所有拆分的候选人。
  • approx:使用分位数草图和梯度直方图的近似贪婪算法。
  • hist: 更快的直方图优化近似贪婪算法。

i. scale_pos_weight [default=1]

  • 控制正负权重的平衡,对不平衡的类很有用。需要考虑的典型值:sum(负实例)/sum(正实例)。

4. 特定学习任务参数
指定学习任务和相应的学习目标。目标选项如下

  • objective [default=reg:squarederror]
    a. reg:squarederror: 平方误差:损失平方的回归
    b. reg:squaredlogerror: 平方对数误差:具有平方对数损失的回归。所有输入标签都必须大于-1
    c. reg:logistic: 逻辑回归,输出概率
    d. reg:pseudohubererror:伪Huber误差:使用伪Huber损失的回归,这是绝对损失的两次可微替代方案。
    e. reg:absoluteerror: 绝对误差:L1误差回归。当使用树模型时,在树构建后刷新叶值。如果在分布式训练中使用,叶值将作为所有工人的平均值计算,这并不能保证是最优的。
    f. reg:quantileerror:分位数损失,也称为弹球损失。
    g. binary:logistic: 二元逻辑回归:用于二元分类的逻辑回归,输出概率
    h. binary:logitraw: 二元分类的逻辑回归,逻辑转换前的输出分数
    i. binary:hinge:二元分类的铰链损失。这使得预测为0或1,而不是产生概率。
    j. multi:softmax: 设置XGBoost使用softmax目标进行多类分类,还需要设置num_class(类的数量)
    k. multi:softprob: 与softmax相同,但输出一个 ndatanclass 向量,该向量可以进一步整形为ndatanclass矩阵。结果包含每个数据点属于每个类的预测概率。
  • eval_metric [default according to objective] :验证数据的评估指标,将根据目标分配默认指标(回归的rmse,分类的logloss,排名的平均精度:映射等)
    a. rmse: 均方根误差
    b. mae: 平均绝对误差
    c. logloss: 负对数似然
    d. auc: ROC曲线下与坐标轴围成的面积。可用于分类和学习任务排名。
    • 用于二分类时,目标函数应为binary:logistic或类似的处理概率的函数。
    • 用于多分类时,目标函数应为multi:softprob而非multi:softmax,因为后者不输出概率。AUC通过1对其余类计算,参考类由类别比例加权。
    • 当输入数据集只包含负样本或正样本时,输出为NaN。具体行为取决于实现,例如scikit-learn会返回0.5。

5. XGBoost调优

1.控制过拟合

当你观察到训练精度很高,但测试精度很低时,很可能会遇到过拟合问题

在XGBoost中,通常有两种方法可以控制过拟合:

第一种方法是直接控制模型的复杂性
a. 包括 max_depth, min_child_weight and gamma.

第二种方法是增加随机性,使训练对噪声具有鲁棒性。
a. 包括 subsample and colsample_bytree
b. 您还可以减小步长 eta。执行此操作时,请记住增加num_round

2.处理不平衡数据集

数据集非常不平衡。这会影响XGBoost模型的训练,有两种方法可以改进它。

  • 如果你只关心预测的整体性能指标(AUC)
    • 通过 scale_pos_weight平衡正负权重
  • 如果你关心预测正确的概率
    • 将参数 max_delta_step设置为有限数(比如1)以帮助收敛

5.使用TFIDF做特征,用SVM或XGBoost做分类器,做酒店评价的情感分析

在这里插入图片描述

1.分词

ps:由于中文和英文不一样,英文会天然的使用空格进行分词,但是中文的一句话是连贯的。如:

英文:I want to go to Beijing.
中文:我想去北京。

如果把英语交给模型,模型收到的是 ["I", "want", "to", "go", "to", "Beijing", "."],总共6个词。
但是如果把中文交给模型,模型收到的是 我想去北京。,总共1个词。

故在NLP中,中文领域都是要分词的。

但是中文如果直接以“字”分词,效果可能很可能不好,因为中文是以词为单位的。如 北京 (一个词)和 (两个字)是两个完全不同的概念。

如果是传统的机器学习文本分类,如SVM和XGBoost通常是采用 Jieba 库来进行分词的。

关于这个库我以后会专门出一篇文章来讲。

总之,在这篇文章中先不考虑jieba的原理,你只需要知道他可以进行如下方式的分词即可。

text = "我要去北京。"
print(jieba.lcut(text))# # ['我要', '去', '北京', '。']

1.这里使用的是 lcut而不是cut,是因为方便打印展示,lcut会直接返回list(迭代器),而cut会返回一个生成器<generator object Tokenizer.cut at 0x164a07a00>.
2.其实业务中大多还是采用生成器cut的形式,因为生成器是惰性迭代计算的,内存效率高。


简单解释一下生成器和迭代器的区别。

生成器 vs 迭代器(列表)(以"我要去北京。"为例)

列表:像把所有分词结果装进盒子
lcut(“我要去北京。”) → 直接给你 [‘我要’, ‘去’, ‘北京’, ‘。’]
生成器:像现用现做的流水线
cut(“我要去北京。”) → 需要时才一个个生成:
‘我要’ → ‘去’ → ‘北京’ → ‘。’

区别:
列表:一次性全做好(占内存,但能反复用)
生成器:用的时候才做(省内存,但只能用一次)

(如果同学不理解生成器和列表的区别,可以评论或留言,我会迅速转门出一篇文章来阐述他俩的区别)


2.使用SVM做分类器

import time
import pandas as pd
import jieba
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.svm import SVC
from sklearn.metrics import classification_report# 记录总开始时间
total_start = time.time()# 1. 数据加载
print("1. 正在加载数据...")
start = time.time()
data = pd.read_csv('/Users/zhangqingjie/Downloads/ChnSentiCorp_htl_all.csv')  # 替换为你的文件路径
print(f"数据加载完成,用时: {time.time() - start:.2f}秒")
print(f"数据样本数: {len(data)}")# 2. 中文分词
print("\n2. 正在进行中文分词...")
start = time.time()def chinese_tokenizer(text):return ' '.join(jieba.cut(text))data['review'] = data['review'].fillna('')
data['tokenized_review'] = data['review'].apply(chinese_tokenizer)
print(f"分词完成,用时: {time.time() - start:.2f}秒")# 3. 数据划分
print("\n3. 正在划分训练集和测试集...")
start = time.time()
X_train, X_test, y_train, y_test = train_test_split(data['tokenized_review'], data['label'], test_size=0.2, random_state=42,shuffle=True
)
print(f"数据划分完成,用时: {time.time() - start:.2f}秒")
print(f"训练集大小: {len(X_train)}, 测试集大小: {len(X_test)}")# 4. TF-IDF特征提取
print("\n4. 正在进行TF-IDF特征提取...")
start = time.time()
tfidf = TfidfVectorizer(max_features=5000)
X_train_tfidf = tfidf.fit_transform(X_train)
X_test_tfidf = tfidf.transform(X_test)
print(f"TF-IDF特征提取完成,用时: {time.time() - start:.2f}秒")
print(f"特征维度: {X_train_tfidf.shape[1]}")# 5. SVM模型训练
print("\n5. 正在训练SVM模型...")
start = time.time()
svm_model = SVC(kernel='linear', random_state=42)
svm_model.fit(X_train_tfidf, y_train)
print(f"SVM模型训练完成,用时: {time.time() - start:.2f}秒")# 6. 模型评估
print("\n6. 正在评估模型...")
start = time.time()
y_pred = svm_model.predict(X_test_tfidf)
print("分类报告:")
print(classification_report(y_test, y_pred))
print(f"模型评估完成,用时: {time.time() - start:.2f}秒")# 总用时
print(f"\n总用时: {time.time() - total_start:.2f}秒")

最终效果

分类报告:precision    recall  f1-score   support0       0.84      0.76      0.80       5051       0.89      0.93      0.91      1049accuracy                           0.88      1554macro avg       0.87      0.85      0.86      1554
weighted avg       0.88      0.88      0.88      1554

3.使用XGBoost做分类器

import time
import pandas as pd
import jieba
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import TfidfVectorizer
from xgboost import XGBClassifier
from sklearn.metrics import classification_report# 记录总开始时间
total_start = time.time()# 1. 数据加载
print("1. 正在加载数据...")
start = time.time()
data = pd.read_csv('/Users/zhangqingjie/Downloads/ChnSentiCorp_htl_all.csv')  # 替换为你的文件路径
print(f"数据加载完成,用时: {time.time() - start:.2f}秒")
print(f"数据样本数: {len(data)}")# 2. 中文分词
print("\n2. 正在进行中文分词...")
start = time.time()def chinese_tokenizer(text):return ' '.join(jieba.cut(text))data['review'] = data['review'].fillna('')
data['tokenized_review'] = data['review'].apply(chinese_tokenizer)
print(f"分词完成,用时: {time.time() - start:.2f}秒")# 3. 数据划分
print("\n3. 正在划分训练集和测试集...")
start = time.time()
X_train, X_test, y_train, y_test = train_test_split(data['tokenized_review'], data['label'], test_size=0.2, random_state=42,shuffle=True
)
print(f"数据划分完成,用时: {time.time() - start:.2f}秒")
print(f"训练集大小: {len(X_train)}, 测试集大小: {len(X_test)}")# 4. TF-IDF特征提取
print("\n4. 正在进行TF-IDF特征提取...")
start = time.time()
tfidf = TfidfVectorizer(max_features=5000)
X_train_tfidf = tfidf.fit_transform(X_train)
X_test_tfidf = tfidf.transform(X_test)
print(f"TF-IDF特征提取完成,用时: {time.time() - start:.2f}秒")
print(f"特征维度: {X_train_tfidf.shape[1]}")# 5. XGBoost模型训练
print("\n5. 正在训练XGBoost模型...")
start = time.time()
xgb_model = XGBClassifier(n_estimators=100,max_depth=6,learning_rate=0.1,random_state=42,use_label_encoder=False,eval_metric='logloss'
)
xgb_model.fit(X_train_tfidf, y_train)
print(f"XGBoost模型训练完成,用时: {time.time() - start:.2f}秒")# 6. 模型评估
print("\n6. 正在评估模型...")
start = time.time()
y_pred = xgb_model.predict(X_test_tfidf)
print("分类报告:")
print(classification_report(y_test, y_pred))
print(f"模型评估完成,用时: {time.time() - start:.2f}秒")# 总用时
print(f"\n总用时: {time.time() - total_start:.2f}秒")

效果如下:

              precision    recall  f1-score   support0       0.82      0.65      0.73       5051       0.85      0.93      0.89      1049accuracy                           0.84      1554macro avg       0.84      0.79      0.81      1554
weighted avg       0.84      0.84      0.84      1554

4.效果对比

模型类别精确率召回率F1分数准确率
SVM00.840.760.800.88
10.890.930.91
XGBoost00.820.650.730.84
10.850.930.89

看起来SVM更胜一筹啊。

调调参,尝试抢救一下XGBoost

xgb_model = XGBClassifier(n_estimators=800,max_depth=8,subsample=0.8,        # 每棵树随机采样80%数据learning_rate=0.03,random_state=42,use_label_encoder=False, objective='binary:logistic',eval_metric='logloss'
)

现在效果如下

分类报告:precision    recall  f1-score   support0       0.82      0.73      0.77       5051       0.88      0.92      0.90      1049accuracy                           0.86      1554macro avg       0.85      0.82      0.83      1554
weighted avg       0.86      0.86      0.86      1554

貌似还是差点意思。。。

6. 总结与收获

通过本篇文章的实践,我们系统地学习了如何使用TF-IDF结合不同分类器进行文本分类任务。以下是本次实践的核心收获:

5.1 关键技术掌握

  1. TF-IDF特征提取

    • 熟练使用sklearn的TfidfVectorizer进行文本向量化
    • 理解了max_featuresngram_range等关键参数对特征空间的影响
    • 掌握了中文分词处理技巧
  2. 分类器应用对比

    • 实现了SVM和XGBoost两种主流分类器
    • 观察到SVM在本任务中表现略优(88% vs 86%准确率)
    • 实践了XGBoost的参数调优过程
  3. 完整Pipeline构建

    • 从数据加载、预处理到模型训练评估的全流程实践
    • 掌握了文本分类任务的标准化开发流程

5.2 实践洞见

  1. SVM的优势显现

    • 在小规模文本数据上,SVM展现出更好的分类性能
    • 特别是对负类(差评)的识别更准确(F1 0.80 vs 0.77)
    • 验证了SVM在高维稀疏特征上的优势
  2. XGBoost的调参经验

    • 通过调整n_estimators、learning_rate等参数提升效果
    • 发现树模型需要更精细的参数调整才能达到理想效果
    • 证明了boosting算法在文本分类中的适用性
  3. 特征工程的关键性

    • TF-IDF作为基础特征提取方法仍然非常有效
    • 中文分词质量直接影响最终分类效果
    • 特征维度控制(max_features)对模型效率影响显著

思考题🤔

  1. 在本实验中,SVM在文本分类任务上表现略优于XGBoost(88% vs 86%准确率)。结合文章提到的原理,你认为可能是什么原因导致的?如果数据集规模扩大10倍,结果可能会发生怎样的变化?为什么?

  2. TF-IDF的ngram_range没有特别指定,其实内部是采用默认值的tfidf = TfidfVectorizer(max_features=5000, ngram_range=(1,1)),(即仅使用单词)。如果将其改为(1,2)(包含单词和双词组合),你认为会对分类效果产生什么影响?尝试修改代码并观察结果,验证你的猜想。

下期预告🚀
现在的NLP模型大多是预训练语言模型BERT类和GPT的衍生,你知道最初的预训练语言模型是什么样的么?

在 Transformer 和注意力机制崛起之前,Word2Vec 率先用『词向量』颠覆了传统 NLP——它让单词不再是孤立的符号,而是蕴含语义的数学向量。

下一期将深入拆解:
🔹 为什么Word2Vec是预训练模型的雏形
🔹 CBOW和Skip-Gram究竟有什么区别?
🔹 GloVe、FastText 等变体如何改进 Word2Vec?

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

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

相关文章

硬件设计-MOS管快速关断的原因和原理

目录 简介&#xff1a; 来源&#xff1a; MOS管快关的原理 先简单介绍下快关的原理&#xff1a; 同电阻时为什么关断时间会更长 小结 简介&#xff1a; 本章主要介绍MOS快速关断的原理和原因。 来源&#xff1a; 有人会问&#xff0c;会什么要求快速关断&#xff0c;而…

Linux进阶命令

目录 一、touch 1. 基本语法 2. 常用选项 二、which 1. 基本语法 2. 主要功能 3. 常用选项 三、find 1. 基本语法 2. 常用选项和表达式 四、more 1. 基本语法 2. 常用操作 3. 对比 more 和 less 五、grep 1. 基本语法 2. 常用选项 六、wc 1. 基本语法 2. 常…

阿里云实时计算Flink版产品体验测评

阿里云实时计算Flink版产品体验测评 什么是阿里云实时计算Flink应用场景实时计算Flink&自建Flink集群性价比开发效率运维管理企业安全 场景落地 什么是阿里云实时计算Flink 实时计算Flink大家可能并不陌生&#xff0c;在实时数据处理上&#xff0c;可能会有所接触&#xf…

用户登录不上linux服务器

一般出现这种问题&#xff0c;重新用root用户修改lsy用户的密码即可登录&#xff0c;但是当修改了还是登录不了的时候&#xff0c;去修改一个文件用root才能修改&#xff0c; 然后在最后添加上改用户的名字&#xff0c;例如 原本是只有user的&#xff0c;现在我加上了lsy了&a…

Android Jetpack架构组件——用Compose工具包构建基本的布局

推荐文章 构建基本布局 | Android Basics Compose - First Android app | Android Developers 向 Android 应用添加图片 | Android Developers

SLAM(七)-卡尔曼滤波

SLAM&#xff08;七&#xff09;-卡尔曼滤波 一、卡尔曼滤波(KF)二、扩展卡尔曼滤波(EKF)三、误差状态卡尔曼滤波(ESKF) 参考《概率机器人》、《Principles of GNSS&#xff0c;lnertial and Multisensor lntegrated Navigation Systems (Second Edition)》 一、卡尔曼滤波(KF)…

Electron 应用太重?试试 PakePlus 轻装上阵

Electron 作为将 Web 技术带入桌面应用领域的先驱框架&#xff0c;让无数开发者能够使用熟悉的 HTML、CSS 和 JavaScript 构建跨平台应用。然而&#xff0c;随着应用规模的扩大&#xff0c;Electron 应用的性能问题逐渐显现——内存占用高、启动速度慢、安装包体积庞大&#xf…

Vue.js组件安全工程化演进:从防御体系构建到安全性能融合

——百万级流量场景下的安全组件架构与源码级解决方案 文章目录 总起&#xff1a;安全工程化的组件革命 分论&#xff1a; 一、现存组件架构的七宗罪与安全改造路径   1.1 组件生态安全赤字现状   1.2 架构级安全缺陷深度剖析   1.3 性能与安全的死亡螺旋 二、百万级…

MCP+cursor使用嘴操作数据库(不用编写SQL语句实现CURD)

文章目录 1.如何进行相关配置2.如何添加MCP server3.如何进行相关的操作3.0数据的查询3.1数据的插入3.2数据的修改3.3多表连接查询 1.如何进行相关配置 这个跟昨天的高德地图的配置非常的相似&#xff0c;因此这个地方我就不进行过多的这个说明了&#xff0c;就是新加一个全聚…

效率工具- git rebase 全解

一、前言 对于git rebase 一直不太了解,这几天想着提高下git提交质量,就发现了这个好用的指令,顺便记录一下,好加深记忆 贴出官方文档以便大家进一步学习 Git 二、rebase是作用 rebase 官方解释为变基,可以理解为移动你的分支根节点,维护一个更好的提交记录。rebase把你当前…

小爱音箱接入大模型DeepSeek及TTS

简介 相信看过钢铁侠的朋友们&#xff0c;都梦想拥有一个像贾维斯这样全能的人工智能管家。而现在随着AI的发展&#xff0c;这个愿景将随我们越来越近。现阶段&#xff0c;我们可以将小爱音箱接入DeepSeek&#xff0c;将其从“人工智障”进化成上知天文&#xff0c;下懂地理的半…

软件架构评估利器:质量效用树全解析

质量效用树是软件架构评估中的一种重要工具&#xff0c;它有助于系统地分析和评估软件架构在满足各种质量属性方面的表现。以下是关于质量效用树的详细介绍&#xff1a; 一、定义与作用 质量效用树是一种以树形结构来表示软件质量属性及其相关效用的模型。它将软件的质量目标…

[IEEE TIP 2024](cv即插即用模块分享)IdeNet信息增强模块 性能提升必备!

论文地址&#xff1a;https://ieeexplore.ieee.org/document/10661228 代码地址&#xff1a;https://github.com/whyandbecause/IdeNet 什么是伪装目标检测&#xff08;COD&#xff09;&#xff1f; 伪装目标检测&#xff08;Camouflaged Object Detection, COD&#xff09;是…

biblatex 的 Biber 警告​​:tex文件运行无法生成参考文献和目录

原因​​&#xff1a;使用了 biblatex 管理参考文献&#xff0c;但未运行 biber 生成参考文献数据。 ​​解决​​&#xff1a;更新 LaTeX Workshop 配置 修改你的 settings.json&#xff0c;添加 biber 工具并更新编译流程&#xff1a; {"latex-workshop.latex.tools&…

thingsboard3.9.1编译问题处理

问题1&#xff1a; [ERROR] Failed to execute goal org.thingsboard:gradle-maven-plugin:1.0.12:invoke (default) on project http: Execution default of goal org.thingsboard:gradle-maven-plugin:1.0.12:invoke failed: Plugin org.thingsboard:gradle-maven-plugin:1.…

深入浅出Redis 缓存使用问题 | 长文分享

目录 数据一致性 先更新缓存&#xff0c;后更新数据库【一般不考虑】 先更新数据库&#xff0c;再更新缓存【一般不考虑】 先删除缓存&#xff0c;后更新数据库 先更新数据库&#xff0c;后删除缓存【推荐】 怎么选择这些方案&#xff1f;采用哪种合适&#xff1f; 缓存…

Express中间件(Middleware)详解:从零开始掌握(2)

1. 请求耗时中间件的增强版 问题&#xff1a;原版只能记录到控制台&#xff0c;如何记录到文件&#xff1f; 改进点&#xff1a; 使用process.hrtime()是什么&#xff1f;获取更高精度的时间支持将日志写入文件记录更多信息(IP地址、状态码)工厂函数模式使中间件可配置 con…

如何设置Ubuntu服务器版防火墙

在Ubuntu服务器中&#xff0c;默认使用 ufw&#xff08;Uncomplicated Firewall&#xff09;作为防火墙管理工具。它是对iptables的简化封装&#xff0c;适合快速配置防火墙规则。以下是设置防火墙的详细步骤&#xff1a; 1. 安装与启用 ufw 安装&#xff08;通常已预装&…

畅游Diffusion数字人(23):字节最新表情+动作模仿视频生成DreamActor-M1

畅游Diffusion数字人(0):专栏文章导航 前言:之前有很多动作模仿或者表情模仿的工作,但是如果要在实际使用中进行电影级的复刻工作,仅仅表情或动作模仿还不够,需要表情和动作一起模仿。最近字节跳动提出了一个表情+动作模仿视频生成DreamActor-M1。 目录 贡献概述 核心动…

模型开发中的微调是干什么

在模型开发中&#xff0c;微调&#xff08;Fine-tuning&#xff09; 是指利用预训练模型&#xff08;Pre-trained Model&#xff09;的参数作为初始值&#xff0c;在特定任务或数据集上进一步调整模型参数的过程。它是迁移学习&#xff08;Transfer Learning&#xff09;的核心…