正在加载中...

展开本页目录
算法教程TFIDF_LR-TF‑IDF + 逻辑回归

TFIDF_LR-TF‑IDF + 逻辑回归

No.071 · 在线教程

TFIDFLR-TF-IDF + 逻辑回归 的真实实现位于 core/tfidflrcalculator.py。它使用 sklearn.pipeline.Pipeline 串联:

TFIDF_LR-TF-IDF + 逻辑回归

1. 方法概述

TFIDF_LR-TF-IDF + 逻辑回归 的真实实现位于 core/tfidf_lr_calculator.py。它使用 sklearn.pipeline.Pipeline 串联:

  • TfidfVectorizer
  • LogisticRegression

因此它是一个典型的传统机器学习文本分类器,而不是深度学习模型。

设训练数据为

$$ \mathcal{D}=\{(s_i,y_i)\}_{i=1}^{N} \tag{1} $$

其中 \(s_i\) 为文本,\(y_i\) 为标签。程序要求数据表至少包含 text_columnlabel_column,可选 id_column

2. 数据清洗与语言判定

2.1 清洗逻辑

代码会先对文本列和标签列做字符串化与空值清洗,删除空白文本和空白标签。清洗后的文本记为

$$ \tilde{s}_i=\mathrm{Clean}(s_i) \tag{2} $$

若清洗后有效样本数少于 5,程序直接报错;若标签类别数少于 2,也会报错。

2.2 自动语言判定

language="auto" 时,代码会把前 50 条文本拼接起来检查是否出现中文字符:

$$ \mathrm{lang}(\mathcal{D})= \begin{cases} \text{zh}, & \text{样本文本中含有 CJK 字符}\\ \text{en}, & \text{otherwise} \end{cases} \tag{3} $$

这里的判定是数据集级别的,而不是逐文档判定。

3. 文本表示

3.1 TF-IDF 向量

向量化器始终是 TfidfVectorizer,因此特征值本质上是

$$ x_{iv}=\mathrm{tf}_{iv}\cdot \mathrm{idf}_v \tag{4} $$

其中

$$ \mathrm{idf}_v=\log\frac{1+N}{1+\mathrm{df}_v}+1 \tag{5} $$

具体数值由 sklearnTfidfVectorizer 计算,结果会导出到 IDFTop 工作表。

可调参数包括:

  • ngram_min, ngram_max
  • max_features
  • min_df, max_df
  • use_builtin_stopwords
  • stopwords_path

3.2 tokenizer_mode 的真实含义

代码支持 tokenizer_mode in {"auto","jieba","char","regex"},但要注意:它始终让 TfidfVectorizer 使用 analyzer="word",只是把“分词器”换成不同的 tokenizer。

因此:

  • jieba:先用 jieba.lcut() 得到词,再做词级 n-gram;
  • regex:先做中英文混合正则切分,再做词级 n-gram;
  • char不是 sklearn 的 analyzer="char",而是先把中文连续串切成重叠 2-gram,再做词级 n-gram。

若文本是中文串 \(c_1c_2\dots c_m\),char 模式的基础 token 为

$$ T(s)=[c_1c_2,\ c_2c_3,\ \dots,\ c_{m-1}c_m] \tag{6} $$

然后 TfidfVectorizer 再在这些 2 字 token 上构造 n-gram,所以会产生像 客服 服态的售 售后 这样的特征。results/TFIDF_LR-TF-IDF + 逻辑回归分析结果_20260329_170036.xlsxTopFeatures_*IDFTop 工作表已经展示了这种现象。

3.3 自动分词兜底

tokenizer_mode="auto" 时:

  • 若检测语言为中文,则优先用 jieba
  • jieba 导入失败,则自动回退到上面的中文 2-gram tokenizer;
  • 若检测语言为英文,则走 regex tokenizer。

3.4 停用词

停用词集合可写为

$$ \mathcal{S}=\mathcal{S}_{\text{builtin}}\cup \mathcal{S}_{\text{custom}} \tag{7} $$

但这里有一个实现细节:内置停用词只对英文启用。代码里只有 _builtin_stopwords_en(),中文并没有内置停用词表;界面上也明确写了“使用内置停用词(英文)”。

4. 逻辑回归模型

4.1 判别形式

模型输出可抽象为

$$ z_c(x)=w_c^\top x+b_c \tag{8} $$

并通过逻辑回归的概率形式做分类。二分类时可写为

$$ P(y=1\mid x)=\sigma(w^\top x+b) \tag{9} $$

多分类时则由 sklearn 默认的 LogisticRegression 机制处理。

4.2 真实正则化口径

这个模块最容易被 README 或界面误导的地方在于 penalty

界面和参数结构都支持:

  • penalty in {"l1","l2"}
  • solver in {"liblinear","lbfgs","saga"}

并且 set_params() 里还会纠正非法组合,例如 l1 + lbfgs 会改回 liblinear。但是 _build_model() 真正构造模型时调用的是:

LogisticRegression(C=..., l1_ratio=..., solver=..., class_weight=..., max_iter=...)

没有把 penalty=self.params.penalty 传进去。因此按照 sklearn 默认行为,真实训练目标仍然是默认的 l2 正则逻辑回归,而不是用户在参数区看到的可切换 l1/l2

所以从真实实现出发,优化目标更接近

$$ \min_{w,b}\; \sum_{i=1}^{N}\log\big(1+\exp(-y_i(w^\top x_i+b))\big) \;+\; \lambda \lVert w\rVert_2^2 \tag{10} $$

其中 \(\lambda\) 与 C 成反比。换句话说,Parameters 工作表虽然会写出 penalty 的值,但模型实际仍按 l2 训练。

4.3 类别不平衡处理

class_weight="balanced",则 LogisticRegression 会启用类别平衡权重;若选择 none,则传入 class_weight=None

5. 评估流程

5.1 Holdout 模式

eval_mode="holdout" 时,程序调用 train_test_split() 进行随机划分:

$$ \mathcal{D}_{\mathrm{train}}\cup\mathcal{D}_{\mathrm{test}}=\mathcal{D} \tag{11} $$

若勾选 stratify=True,则优先按标签分层。为了避免小样本分层时报错,代码会根据最小类别样本数 \(m_{\min}\) 自动修正测试集比例:

$$ r_{\mathrm{eff}}= \min\!\Big(\max(r,\frac{1}{m_{\min}}),\,1-\frac{1}{m_{\min}}\Big) \tag{12} $$

其中 \(r\) 是用户请求的 test_size。修正后的比例会写入 effective_test_size,是否修正则写入 test_size_adjusted

5.2 交叉验证模式

eval_mode="cv" 时,程序使用

  • StratifiedKFold
  • cross_val_predict(..., method="predict")
  • cross_val_predict(..., method="predict_proba")

来生成全样本预测。若每类样本太少,折数会自动缩减为 min(cv_folds, min_count),但至少要求每类 2 条样本。

交叉验证完成后,代码还会再对全量数据拟合一次,以便导出:

  • IDFTop
  • TopFeatures_Pos
  • TopFeatures_Neg
  • TopFeatures_ByClass

这点是 2026-02-12 的修复内容,说明当前版本的 CV 输出已经不只是指标,而是也会补齐论文需要的解释性结果。

6. 指标、预测表与解释性输出

6.1 分类指标

准确率定义为

$$ \mathrm{Accuracy}=\frac{1}{M}\sum_{i=1}^{M}\mathbf{1}(\hat y_i=y_i) \tag{13} $$

其中 \(M\) 在 holdout 模式下是测试集大小,在 CV 模式下是全样本数。

混淆矩阵为

$$ \mathrm{CM}_{ab}=\sum_i \mathbf{1}(y_i=a,\hat y_i=b) \tag{14} $$

程序还会导出 classification_report() 生成的 precisionrecallf1-scoresupport

6.2 ROC / PR

只有二分类时,程序才尝试计算 ROC-AUC、ROC 曲线和 PR 曲线。代码把正类定义为:

$$ y_{+}=\text{sorted(labels)}[1] \tag{15} $$

也就是按照标签字符串排序后的第二个标签,而不是用户显式指定的“正类”。随后使用对应列的 predict_proba 结果计算 roc_aucROCPR

6.3 预测明细

Predictions 工作表在两种评估方式下口径不同:

  • holdout:只保存测试集样本;
  • cv:保存全量样本的交叉验证预测。

另外还有一个实现差异:

  • cv 分支如果存在 id_column,会把原始 ID 列插入预测表;
  • holdout 分支没有把原始 ID 列写回 Predictions

6.4 系数解释

lr.coef_ 可用时,程序按权重排序导出 Top 特征。

二分类时:

$$ \mathrm{TopPos}=\operatorname{argsort}_{j}^{\downarrow}(w_j),\qquad \mathrm{TopNeg}=\operatorname{argsort}_{j}^{\uparrow}(w_j) \tag{16} $$

对应:

  • TopFeatures_Pos
  • TopFeatures_Neg

多分类时,则对每个类别分别取该类系数最大的若干特征,输出到 TopFeatures_ByClass

7. 输出结果与复现

7.1 Excel 工作表

save_results() 的真实输出工作表为:

  • Parameters
  • LabelDistribution
  • Metrics
  • ConfusionMatrix
  • ClassificationReport
  • Predictions
  • IDFTop
  • TopFeatures_Pos
  • TopFeatures_Neg
  • TopFeatures_ByClass
  • ROC
  • PR
  • Charts

其中:

  • TopFeatures_ByClass 只在多分类时出现;
  • ROCPR 只在二分类且概率计算成功时出现。

7.2 图表

当前实现会尝试生成 4 张图:

  • confusion_matrix.png
  • top_coeff.png
  • roc_curve.png
  • pr_curve.png

这些图对应的路径会写入 Charts 工作表。

7.3 复现脚本

结果页会自动写出 repro_tfidf_lr.py。这个脚本会:

  • 复制输入文件到 repro_inputs/
  • 重新导入 core.tfidf_lr_calculator
  • 用同一份 params 再跑一次 run_analysis()

因此它是对真实核心代码的直接复现,不是手写伪代码。

8. 实现说明与注意事项

结合代码与真实结果,这个模块在论文说明里应明确写出以下边界:

  1. 它的文本表示固定是 TF-IDF,不支持 CountVectorizer。
  2. char 模式不是 sklearn 原生字符分析器,而是“中文 2 字滑窗 tokenizer + 词级 n-gram”。
  3. 内置停用词只覆盖英文,中文主要依赖 jieba 分词或 2-gram tokenizer 与自定义停用词。
  4. holdout 模式只导出测试集预测,CV 模式才导出全样本预测。
  5. 最关键的一点是:尽管 UI 暴露了 penalty=l1/l2,但真实训练仍然落在默认 l2 正则逻辑回归上。

9. 论文写作模板

可在论文“方法部分”中写为:

“本文采用 TF-IDF 与逻辑回归相结合的文本分类方法对文本样本进行建模。首先,对原始文本进行清洗、分词和停用词过滤,并利用 TF-IDF 将文本转换为稀疏向量表示;其次,基于逻辑回归建立监督分类模型,学习词项特征与类别标签之间的线性关系;随后,在评估样本上输出类别预测、分类概率及相关评价指标;最后,结合特征系数排序、预测结果表和导出图表,对模型分类性能及关键判别词项进行分析。”

10. 单篇终审补充

10.1 图题与表题对齐建议

  • Parameters 表可写为:表X TF-IDF + 逻辑回归参数设置表。
  • LabelDistribution 表可写为:表X TF-IDF + 逻辑回归标签分布表。
  • Metrics 表可写为:表X TF-IDF + 逻辑回归模型指标表。
  • ConfusionMatrix 表可写为:表X TF-IDF + 逻辑回归混淆矩阵表。
  • ClassificationReport 表可写为:表X TF-IDF + 逻辑回归分类报告表。
  • Predictions 表可写为:表X TF-IDF + 逻辑回归预测结果表。
  • IDFTop 表可写为:表X TF-IDF 高频权重词项表。
  • TopFeatures_Pos 表可写为:表X TF-IDF + 逻辑回归正向高权重特征表。
  • TopFeatures_Neg 表可写为:表X TF-IDF + 逻辑回归负向高权重特征表。
  • ROC 表可写为:表X TF-IDF + 逻辑回归 ROC 曲线数据表。
  • PR 表可写为:表X TF-IDF + 逻辑回归 PR 曲线数据表。
  • Charts 表可写为:表X TF-IDF + 逻辑回归图表索引表。
  • confusion_matrix.png 建议写为:图X TF-IDF + 逻辑回归混淆矩阵图。
  • top_coeff.png 建议写为:图X TF-IDF + 逻辑回归系数排序图。
  • roc_curve.png 建议写为:图X TF-IDF + 逻辑回归 ROC 曲线图。
  • pr_curve.png 建议写为:图X TF-IDF + 逻辑回归 PR 曲线图。

10.2 终审说明

  • 当前代表性结果目录可采用 results/TFIDF_LR-TF-IDF + 逻辑回归分析结果_20260329_170036。其中主工作簿为 TFIDF_LR-TF-IDF + 逻辑回归分析结果_20260329_170036.xlsx
  • 当前真实工作表为 Parameters/LabelDistribution/Metrics/ConfusionMatrix/ClassificationReport/Predictions/IDFTop/TopFeatures_Pos/TopFeatures_Neg/ROC/PR/Charts。论文表题应按这套英文 sheet 名落地,不宜擅自改成别的分类器模板术语。
  • 当前稳定实体图文件为 charts/confusion_matrix.pngcharts/top_coeff.pngcharts/roc_curve.pngcharts/pr_curve.png。其中 ROC/PR 只适用于当前二分类成功输出的目录,正文若换到多分类目录,不应继续沿用这两张图的说法。
  • 真实 repro 脚本稳定命名为 repro_tfidf_lr.py。在普通结果目录下通常通过 INPUT_FILE = 'repro_inputs/tfidf_lr_sample.csv' 读取输入副本;在 UI 链路目录下则可能改为 repro_inputs/window1_classic_cls_input.csv。附录应按实际结果目录的脚本内容写明输入来源。
  • 代码层虽然暴露了 penalty 等参数,但当前实现口径仍应以真实导出结果和真实脚本参数为准。论文若要讨论正则项设置,必须以具体运行目录中 Parameters 表记录的参数快照为依据。

10.3 全量强化补充

  • 这篇文档当前若要同时覆盖“主结果完整性”和“repro 链完整性”,更合适绑定 具体的算法3/NLP基础/TFIDF_LR-TF-IDF + 逻辑回归/results/TFIDF_LR-TF-IDF + 逻辑回归分析结果_20260329_070819,而不是只引用后出的 20260329_170036
  • 该目录首层主工作簿为 TFIDF_LR-TF-IDF + 逻辑回归分析结果_20260329_070819.xlsx,实际工作表为 ParametersLabelDistributionMetricsConfusionMatrixClassificationReportPredictionsIDFTopTopFeatures_PosTopFeatures_NegROCPRCharts
  • 与主工作簿同层存在主图目录 charts/,其中真实图片为 confusion_matrix.pngpr_curve.pngroc_curve.pngtop_coeff.png。因此图题、图号和附录路径应绑定首层 charts/,不应把内嵌再生产物目录中的图混为首轮运行图片。
  • 该目录首层同时存在完整复现入口 repro_tfidf_lr.py 和输入副本 repro_inputs/tfidf_lr_sample.csv,说明这一目录本身就构成了完整的“主运行 + repro 输入”证据链。
  • 需要特别区分的是:同一目录内部又嵌套了两个再生产物子目录 TFIDF_LR-TF-IDF + 逻辑回归分析结果_20260329_071157/TFIDF_LR-TF-IDF + 逻辑回归分析结果_20260329_151152/,它们各自再次生成了新的 xlsx 与 charts/ 图片。这些是 repro 执行后的再生成结果,不应与首层主结果混写成一轮导出。
  • 因此正文最严谨的写法应是:首层目录用于说明用户本次分析的直接输出,嵌套时间戳子目录用于说明 repro_tfidf_lr.py 重新运行后生成的后续结果。若论文想证明可复现性,应把两层目录明确区分。
  • 之前“以 20260329_170036 代表当前结果”的表述需要修正为“20260329_170036 可代表较新的主结果结构,但若需要完整 repro 证据,应优先引用 20260329_070819”。这是当前磁盘现状下更准确的描述。
  • 结合真实目录结构,Charts 工作表更适合写成“图表路径索引表”,Predictions 适合写“测试集预测结果表”,IDFTopTopFeatures_Pos/Neg 适合支撑“词项解释性”段落;而 ROC/PR 只能在当前二分类目录中引用,换目录时应重新核实是否实际存在。

11. 软件实现核查补充(2026-07)

  • 当前实现的主结果目录应写作 具体的算法3/NLP基础/TFIDF_LR-TF-IDF + 逻辑回归/results/TFIDF_LR-TF-IDF + 逻辑回归分析结果_20260329_070819,主工作簿以 TFIDF_LR-TF-IDF + 逻辑回归分析结果_20260329_070819.xlsx 为准。
  • 正文应围绕 ParametersLabelDistributionMetricsConfusionMatrixClassificationReportPredictionsIDFTopTopFeatures_PosTopFeatures_NegROCPRCharts 来写。
  • 图证应绑定首层 charts/ 目录中的 confusion_matrix.pngpr_curve.pngroc_curve.pngtop_coeff.png,不要把嵌套 repro 子目录中的副本混进主结果。
  • repro_tfidf_lr.py + repro_inputs/tfidf_lr_sample.csv 是标准结果目录内复现口径;后续嵌套目录只是再生产物,不应写成第二套主结果。