4.1 分类 vs 回归
在机器学习中,任务通常分为两大类:
-
回归(Regression) :用于预测连续数值,如房价、温度、工资等。例如:
- 预测明天的气温(28.5°C)。
- 预测一辆二手车的价格(30,000元)。
-
分类(Classification) :用于预测离散类别,如垃圾邮件 vs 正常邮件。例如:
- 判断一封邮件是否是垃圾邮件("垃圾邮件" or "正常邮件")。
- 预测一个贷款申请是否会被批准("批准" or "拒绝")。
什么时候用分类?什么时候用回归?
任务 | 分类还是回归? | 预测示例 |
---|---|---|
预测明天的气温 | 回归 | 28.5°C |
判断邮件是否为垃圾邮件 | 分类 | "垃圾邮件" or "正常邮件" |
预测一辆二手车的价格 | 回归 | 30,000元 |
判断贷款是否会被批准 | 分类 | "批准" or "拒绝" |
4.2 训练垃圾邮件分类器
我们将使用 Python 训练一个垃圾邮件分类器 ,并使用 Kaggle 上的 SMS Spam Collection Dataset 提高准确率。
1. 载入 Kaggle 数据集
首先,我们需要加载 Kaggle 上的垃圾邮件数据集。
python
import pandas as pd
# 载入 Kaggle 的垃圾邮件数据集
df = pd.read_csv("spam.csv", encoding="latin-1")
# 只保留必要的列
df = df[['v1', 'v2']]
df.columns = ['label', 'email']
# 将标签转换为数值(1 = 垃圾邮件, 0 = 正常邮件)
df['label'] = df['label'].map({'spam': 1, 'ham': 0})
print(df.head()) # 查看前5行数据
print("数据集大小:", len(df))
示例输出:
bash
label email
0 0 Go until jurong point, crazy.. Available only ...
1 0 Ok lar... Joking wif u oni...
2 1 Free entry in 2 a wkly comp to win FA Cup fina...
3 0 U dun say so early hor... U c already then say...
4 0 Nah I don't think he goes to usf, he lives aro...
数据集大小: 5572
🔹 解释:
pd.read_csv("spam.csv", encoding="latin-1")
:从 CSV 文件读取数据。df[['v1', 'v2']]
:只保留v1
(标签)和v2
(邮件内容)。df['label'].map({'spam': 1, 'ham': 0})
:将"spam"
变成1
,"ham"
变成0
,方便机器学习模型处理。
2. 处理文本(增加 max_features)
为什么要转换文本?
机器学习模型无法直接理解文字,我们需要将邮件文本转换成数值。
我们使用 TfidfVectorizer
进行文本特征提取:
python
from sklearn.feature_extraction.text import TfidfVectorizer
vectorizer = TfidfVectorizer(ngram_range=(1, 2), max_features=10000)
X = vectorizer.fit_transform(df["email"])
y = df["label"]
🔹 解释:
TfidfVectorizer(ngram_range=(1,2), max_features=10000)
:ngram_range=(1,2)
:考虑单词和短语(如"free"
和"free money"
)。max_features=10000
:选取最重要的 10000 个单词特征。
3. 训练 & 测试集划分
python
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)
🔹 解释:
test_size=0.2
:测试集占 20%。stratify=y
:确保训练集和测试集中垃圾邮件和正常邮件的比例相同,避免类别不均衡。
4. 解决类别不平衡(SMOTE 过采样垃圾邮件)
为什么要解决类别不平衡?
如果数据集中正常邮件的数量远远多于垃圾邮件,模型可能会倾向于预测所有邮件都是正常邮件,从而得到较高的"假准确率"(即准确率看起来很高,但实际上垃圾邮件检测效果很差)。
例如:
- 90% 的邮件是正常邮件,10% 是垃圾邮件。
- 如果模型"偷懒",直接预测所有邮件都是正常邮件,它的准确率会高达 90%!
- 但这是错误的分类,因为垃圾邮件没有被正确检测出来。
如何解决?
我们使用 SMOTE(Synthetic Minority Over-sampling Technique) 来生成更多垃圾邮件样本,使两类数据更加均衡:
python
from imblearn.over_sampling import SMOTE
smote = SMOTE(sampling_strategy=0.5, random_state=42)
X_train_resampled, y_train_resampled = smote.fit_resample(X_train, y_train)
🔹 解释:
SMOTE(sampling_strategy=0.5)
:让垃圾邮件占训练数据的 50%。fit_resample(X_train, y_train)
:自动生成垃圾邮件数据,使两类数据均衡。
5. 训练逻辑回归模型(调整参数)
python
from sklearn.linear_model import LogisticRegression
model = LogisticRegression(C=1.0, solver='saga', max_iter=2000)
model.fit(X_train_resampled, y_train_resampled)
🔹 解释:
C=1.0
:适当降低正则化,防止模型欠拟合。solver='saga'
:适用于大数据集。max_iter=2000
:增加迭代次数,确保模型收敛。
6. 预测 & 评估
python
from sklearn.metrics import accuracy_score
y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print("🔥 终极优化后的模型准确率:", accuracy)
示例输出:
bash
🔥 终极优化后的模型准确率: 0.9865470852017937
🔹 解释:
accuracy_score(y_test, y_pred)
计算模型的预测准确率。
7. 测试新邮件
python
new_email = ["Win a free iPhone now! Click here to claim!"]
new_X = vectorizer.transform(new_email)
prediction = model.predict(new_X)
print("📩 预测结果:", "垃圾邮件" if prediction[0] == 1 else "正常邮件")
示例输出:
bash
📩 预测结果: 垃圾邮件
4.6 课后练习
✅ 运行代码,查看模型准确率(目标:98%+ )
✅ 修改 max_features=20000
,尝试是否能提高效果
✅ 添加更多垃圾邮件,提高样本数量