在自然语言处理(NLP)领域,文本分类是最基础也最实用的任务之一。今天我要分享的是一个基于传统机器学习方法的文本情感分类实战项目,使用TF-IDF特征和逻辑回归模型在IMDb影评数据集上构建分类器。这个方案虽然不涉及深度学习,但在实际业务中仍然具有重要价值——它训练速度快、可解释性强,而且往往能提供不错的baseline性能。
这个项目的数据集来自Hugging Face的stanfordnlp/imdb,包含50,000条电影评论(25,000训练/25,000测试),任务是判断每条评论的情感倾向(正面/负面)。我们将使用词和双词组合(1-2gram)的TF-IDF作为特征,配合逻辑回归分类器,最终在测试集上达到了约87.5%的准确率和94.8%的AUC值。
TF-IDF(Term Frequency-Inverse Document Frequency)是文本处理中最经典的特征表示方法之一。它的核心思想是:一个词在当前文档中出现次数越多(TF越高),同时在所有文档中出现次数越少(IDF越高),这个词的区分能力就越强。
数学表达式为:
code复制TF-IDF(t,d) = TF(t,d) × IDF(t)
其中:
在我们的实现中,特别关注了几个关键参数:
ngram_range=(1,2):同时考虑单个词和双词组合min_df=2:过滤掉只在单个文档中出现的罕见词max_df=0.95:过滤掉出现在95%以上文档中的常见词stop_words="english":移除英语停用词这些参数的选择不是随意的:
逻辑回归虽然名字中有"回归",但它实际上是一种经典的线性分类模型。它的工作原理可以分为三步:
线性变换:z = wᵀx + b
概率映射:σ(z) = 1/(1+e⁻ᶻ)
决策阈值(默认0.5):
在文本分类任务中,逻辑回归有几个显著优势:
我们使用的关键参数:
C=1.0:正则化强度的倒数,控制模型复杂度max_iter=2000:最大迭代次数,确保收敛solver="liblinear":适合小规模数据的优化算法首先加载IMDb数据集并进行初步分析:
python复制from datasets import load_dataset
import pandas as pd
ds = load_dataset("stanfordnlp/imdb")
train_df = pd.DataFrame({"text": ds["train"]["text"], "label": ds["train"]["label"]})
test_df = pd.DataFrame({"text": ds["test"]["text"], "label": ds["test"]["label"]})
print(train_df["label"].value_counts())
输出显示标签分布均衡(约50%正/负),这是评估指标选择的重要依据。
从训练集中划分20%作为验证集:
python复制from sklearn.model_selection import train_test_split
X_train, X_valid, y_train, y_valid = train_test_split(
train_df["text"],
train_df["label"],
test_size=0.2,
random_state=42,
stratify=train_df["label"]
)
注意使用了分层抽样(stratify)保持正负样本比例。
使用TF-IDF向量化文本:
python复制from sklearn.feature_extraction.text import TfidfVectorizer
vectorizer = TfidfVectorizer(
lowercase=True,
stop_words="english",
ngram_range=(1, 2),
min_df=2,
max_df=0.95
)
X_train_tfidf = vectorizer.fit_transform(X_train)
X_valid_tfidf = vectorizer.transform(X_valid)
X_test_tfidf = vectorizer.transform(test_df["text"])
这里的关键点:
训练逻辑回归分类器:
python复制from sklearn.linear_model import LogisticRegression
clf = LogisticRegression(
max_iter=2000,
C=1.0,
solver="liblinear"
)
clf.fit(X_train_tfidf, y_train)
我们实现了综合评估函数,计算多个指标:
python复制from sklearn.metrics import accuracy_score, precision_recall_fscore_support, roc_auc_score
def evaluate_binary(y_true, y_pred, y_proba):
return {
"accuracy": accuracy_score(y_true, y_pred),
"precision": precision_recall_fscore_support(y_true, y_pred, average="binary")[0],
"recall": precision_recall_fscore_support(y_true, y_pred, average="binary")[1],
"f1": precision_recall_fscore_support(y_true, y_pred, average="binary")[2],
"roc_auc": roc_auc_score(y_true, y_proba)
}
在验证集和测试集上的评估结果:
| 数据集 | 准确率 | 精确率 | 召回率 | F1分数 | ROC-AUC |
|---|---|---|---|---|---|
| 验证集 | 0.8892 | 0.8903 | 0.8917 | 0.8910 | 0.9554 |
| 测试集 | 0.8749 | 0.8751 | 0.8773 | 0.8752 | 0.9480 |
通过混淆矩阵和错例分析发现主要错误类型:
n-gram范围扩展:
特征过滤调整:
文本预处理增强:
正则化强度C:
类别权重调整:
决策阈值优化:
线性SVM:
SGDClassifier:
朴素贝叶斯:
模型部署:
性能优化:
监控与更新:
可解释性报告:
这个传统机器学习方案虽然在绝对性能上可能不如最新的深度学习模型,但在许多实际业务场景中仍然是首选——特别是当需要快速迭代、模型可解释性要求高,或者计算资源有限时。通过系统的特征工程和细致的调参,TF-IDF+逻辑回归完全可以达到满足业务需求的性能水平。