前面我们已经讲了中文分词、停用词、词袋模型和 TF-IDF。现在终于可以把它们接起来训练一个真正能跑的文本分类 baseline。这里的 baseline 指的是第一版可运行基线。它不一定是最终最强模型但必须简单、清楚、可复现后面的优化都可以拿它做对照。为什么选 TF-IDF 逻辑回归这个组合非常适合入门文本分类。TF-IDF 负责把文本变成数字特征逻辑回归负责学习这些特征和标签之间的关系。它有几个优点训练速度快参数不复杂效果通常不差比较容易解释适合当作后续模型的对照组。如果一个复杂模型比这个 baseline 还差就说明要先检查数据、标签、特征和评估方式而不是继续堆模型。很多人拿到文本分类任务会想直接上 BERT但先跑通这条基线更稳妥。两者对比特性TF-IDF 逻辑回归BERT 微调训练时间几秒几十分钟到几小时内存占用几十 MB几 GB可解释性看权重就知道哪个词重要黑盒需要 LIME/SHAP中文分词依赖jieba 即可自带 tokenizer小数据效果收敛快需要足够数据如果 TF-IDF 逻辑回归已经达到 92% 准确率BERT 可能提升到 95%但是否值得花几十倍算力要看具体场景。先把基线跑通再决定要不要上更重的模型。准备数据假设我们有一个 DataFrameimportpandasaspd dfpd.read_csv(text_classification.csv)print(df.head())至少需要两列text 原始中文文本 label 文本类别训练之前先做几个基本检查print(df.shape)print(df[label].value_counts())print(df[text].isna().sum())如果有空文本、重复文本、标签极度不平衡要先处理否则模型结果很容易失真。分词函数中文文本要先分词。importjieba stopwords{的,了,是,在,和,也}defcut_text(text):wordsjieba.lcut(str(text))words[w.strip()forwinwordsifw.strip()]words[wforwinwordsifwnotinstopwords]return .join(words)df[text_cut]df[text].apply(cut_text)这里返回的是空格分隔的字符串因为TfidfVectorizer默认按空格和规则切分 token。划分训练集和测试集接下来划分数据。fromsklearn.model_selectionimporttrain_test_split X_train,X_test,y_train,y_testtrain_test_split(df[text_cut],df[label],test_size0.2,random_state42,stratifydf[label],)stratifydf[label]的作用是尽量保持训练集和测试集里的类别比例一致。分类任务里这一点很重要。如果某个类别样本本来就少随机划分可能让测试集里这个类别过少评估就不稳定。建立 Pipeline推荐把 TF-IDF 和模型放进 Pipeline。fromsklearn.pipelineimportPipelinefromsklearn.feature_extraction.textimportTfidfVectorizerfromsklearn.linear_modelimportLogisticRegression pipePipeline([(tfidf,TfidfVectorizer(max_features5000,min_df2,ngram_range(1,2))),(model,LogisticRegression(max_iter1000)),])这样做有两个好处。第一流程更清楚训练和预测都用同一条链路。第二后面做交叉验证和调参时不容易发生数据泄漏。调参方向基线跑通后调参主要看两个地方。向量化部分TfidfVectorizer(max_features3000,# 保留的词汇量ngram_range(1,2),# (1,2) 表示单字词加双字词组min_df2,# 只保留出现在至少 2 篇文档中的词max_df0.85,# 过滤出现在 85% 以上文档中的词sublinear_tfTrue,# 用 1log(TF) 抑制超高词频)逻辑回归部分LogisticRegression(C1.0,# 正则化强度越小正则越强max_iter1000,# 迭代次数特征多时要加大class_weightbalanced,# 类别不均衡时加这个)C是正则化强度的倒数调小能抑制过拟合调大则让模型更贴合训练数据。类别不平衡时class_weightbalanced会让少数类获得更高权重。训练和预测训练很简单pipe.fit(X_train,y_train)预测y_predpipe.predict(X_test)如果你想看每个类别的概率y_probapipe.predict_proba(X_test)不是所有模型都有predict_proba但逻辑回归通常可以用。看第一版分数先用classification_report看整体表现。fromsklearn.metricsimportclassification_reportprint(classification_report(y_test,y_pred))它会输出每个类别的 precision、recall、f1-score 和 support。不要只盯着 accuracy。文本分类里少数类的 recall 和 F1 经常更关键。查看哪些词说了算逻辑回归的好处是可解释。它的系数直接告诉你每个特征词对分类的影响不需要额外的解释工具。vecpipe.named_steps[tfidf]clfpipe.named_steps[model]wordsvec.get_feature_names_out()# 找出对第一个类别预测贡献最大的 10 个词top_indicesclf.coef_[0].argsort()[-10:][::-1]foriintop_indices:print(f{words[i]}:{clf.coef_[0][i]:.3f})跑完会看到一组词和对应权重。权重越高说明这个词越倾向把样本分到这个类别。如果权重高的词看起来和类别无关往往说明数据或分词环节有问题。保存 baseline训练完成后可以保存模型。importjoblib joblib.dump(pipe,text_classifier_baseline.joblib)以后加载modeljoblib.load(text_classifier_baseline.joblib)model.predict([功能 不好用 经常 闪退])因为我们保存的是整个 Pipeline所以 TF-IDF 词表和逻辑回归模型都会一起保存。baseline 的价值baseline 的价值不只是给出一个分数而是建立一条标准流程。后面你可以逐步对比换停用词表有没有提升加 bigram 有没有提升调C参数有没有提升换朴素贝叶斯、SVM、随机森林有没有提升增加数据后有没有提升。每次只改一个主要变量才能知道到底是什么带来了变化。这一课先记住TF-IDF 逻辑回归是一条很适合文本分类入门的 baseline。核心流程是清洗文本 - 中文分词 - 划分数据 - TF-IDF - 逻辑回归 - 评估下一课我们不急着换模型而是先学会读懂评估结果混淆矩阵、分类报告和错分样本。在线阅读点击这里阅读博客原文原文地址https://bestsdz.xyz/posts/tfidf-logistic-regression-baseline/