从线性回归到逻辑回归:一个初学者的机器学习入门笔记
机器学习听起来很复杂,但它的基本过程并不神秘。我们先准备数据,让模型从数据中寻找规律,再用没有参与训练的数据检查模型是否可靠。
对于初学者来说,线性回归和逻辑回归是两个非常适合入门的模型。线性回归可以预测房价、销量等连续数值;逻辑回归可以判断邮件是不是垃圾邮件、客户会不会流失等类别问题。
本文将从线性回归开始,依次学习拟合优度、逻辑回归、模型评价、正则化和交叉验证,并使用 Python 完成简单的代码实现。
一、认识线性回归
线性回归主要用于预测连续数值。
例如:
- 根据房屋面积预测房价;
- 根据广告投入预测商品销量;
- 根据学习时间预测考试成绩;
- 根据温度预测用电量。
如果只有一个输入特征,线性回归可以写成下面的形式:
y = wx + b
其中:
x表示输入的数据;y表示模型的预测结果;w表示特征的权重;b表示截距。
假设我们要根据学习时间预测考试成绩,得到下面的公式:
考试成绩 = 5 × 学习时间 + 50
如果每天学习 6 小时,模型预测的成绩就是:
5 × 6 + 50 = 80
真实数据通常不会完全分布在一条直线上。线性回归要做的,就是寻找一条尽量靠近所有样本的直线。
二、使用 Python 实现线性回归
Python 中可以使用 scikit-learn 提供的 LinearRegression 创建线性回归模型。
下面使用糖尿病数据集进行演示:
from sklearn.datasets import load_diabetes
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
# 读取数据
X, y = load_diabetes(return_X_y=True) #糖尿病数据集,sklearn 内置经典回归数据集。
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.2,
random_state=42
)
# 创建线性回归模型
model = LinearRegression()
# 训练模型
model.fit(X_train, y_train)
# 使用测试集进行预测
y_pred = model.predict(X_test)
# 评价模型
print("均方误差:", mean_squared_error(y_test, y_pred))
print("R²:", r2_score(y_test, y_pred))
这段代码中,X 保存输入特征,y 保存需要预测的目标值。
train_test_split() 用于把数据分成训练集和测试集。其中:
test_size=0.2表示拿出 20% 的数据作为测试集;random_state=42用于固定随机结果,方便重复实验。
fit() 表示训练模型,predict() 表示使用训练好的模型进行预测。
需要注意,测试集不能提前参与训练。如果模型已经见过测试数据,最后得到的成绩就不能代表它处理新数据的能力。
三、均方误差与拟合优度 R²
模型完成预测后,需要使用评价指标判断效果。
线性回归常见的评价指标包括均方误差和拟合优度 R²。
均方误差会计算预测值与真实值之间的差距,再对误差进行平方并求平均。
误差需要平方,主要有两个原因:
- 避免正误差和负误差互相抵消;
- 让较大的预测错误受到更加明显的惩罚。
均方误差越小,通常说明预测值越接近真实值。
不过,均方误差会受到数据单位的影响。例如预测房价时,误差可能是几万元;预测温度时,误差可能只有几度。因此,不同任务之间不能只看均方误差进行比较。
R² 可以理解为模型对数据变化的解释程度:

- R² 越接近
1,模型的拟合效果通常越好; - R² 等于
0,模型和直接使用平均值预测差不多; - R² 小于
0,模型甚至不如直接预测平均值。
初学者容易认为 R² 一定在 0 到 1 之间。实际上,如果模型在测试集上的表现很差,R² 完全可能是负数。
另外,R² 很高也不代表模型一定没有问题。如果训练集得分很高,测试集得分却明显下降,模型可能记住了训练数据中的噪声,这种现象叫作过拟合。
四、逻辑回归解决分类问题
线性回归适合预测连续数值,而逻辑回归主要用于分类。
常见的二分类问题包括:
- 一封邮件是不是垃圾邮件;
- 一位客户会不会流失;
- 一次交易是否存在风险;
- 一个检测结果是阳性还是阴性。
虽然名字中带有“回归”,但逻辑回归的最终任务是分类。
线性模型可以先计算一个结果:
z = wx + b
但是,z 可能是任意数字,无法直接表示概率。
因此,逻辑回归会使用 Sigmoid 函数,把结果压缩到 0 和 1 之间:
p = 1 / (1 + e^(-z))
得到的 p 可以理解为样本属于正类的概率。
例如,模型预测某封邮件是垃圾邮件的概率为 0.8。如果分类阈值是 0.5,它就会被判断为垃圾邮件。
阈值并不一定永远是 0.5。
在疾病筛查中,为了减少漏诊,可以降低阈值,让模型找出更多可能的阳性样本;在审核任务中,如果更担心误判,也可以适当提高阈值。
五、使用 Python 实现逻辑回归
下面使用乳腺癌数据集演示逻辑回归。
需要说明的是,这段代码仅用于学习机器学习流程,不能代替真实的医疗判断。
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
# 读取分类数据
X, y = load_breast_cancer(return_X_y=True)
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
X,
y,
test_size=0.2,
random_state=42,
stratify=y
)
# 建立数据处理和模型训练流程
model = Pipeline([
("scaler", StandardScaler()),
("logistic", LogisticRegression(max_iter=1000))
])
# 训练模型
model.fit(X_train, y_train)
# 预测类别
y_pred = model.predict(X_test)
# 预测属于正类的概率
y_prob = model.predict_proba(X_test)[:, 1]
print("前 5 个预测类别:", y_pred[:5])
print("前 5 个正类概率:", y_prob[:5])
StandardScaler() 用于标准化数据。
不同特征的数值范围可能相差很大。例如,一个特征的范围是 0 到 1,另一个特征的范围可能是几千。如果直接训练,数值较大的特征可能产生不合理的影响。
标准化可以让不同特征处在比较接近的尺度上。
Pipeline 则把标准化和逻辑回归组合在一起。这样做可以保证训练时只使用训练集计算标准化参数,避免测试集信息提前泄漏。
代码中的 stratify=y 表示按照原来的类别比例划分数据。分类数据不平衡时,这个参数尤其有用。
六、分类模型的常用评价指标
分类模型不能只看准确率。
假设 100 个样本中有 95 个正常样本,只有 5 个异常样本。如果模型把所有样本都预测为正常,准确率仍然有 95%。
但是,这个模型一个异常样本也没有找到,显然没有实际价值。
因此,我们还需要查看混淆矩阵、精确率、召回率、F1 值
from sklearn.metrics import (
accuracy_score,
confusion_matrix,
classification_report,
roc_auc_score
)
# 准确率
print("准确率:", accuracy_score(y_test, y_pred))
# 混淆矩阵
print("混淆矩阵:")
print(confusion_matrix(y_test, y_pred))
# 精确率、召回率和 F1 值
print("分类报告:")
print(classification_report(y_test, y_pred))
# ROC-AUC
print("ROC-AUC:", roc_auc_score(y_test, y_prob))
这些指标的含义如下:
- 准确率:全部样本中,预测正确的比例;

- 精确率:被预测为正类的样本中,真正为正类的比例;

- 召回率:所有真正的正类样本中,被模型成功找出的比例;

- F1 值:综合考虑精确率和召回率;

不同指标适合不同任务。
垃圾邮件识别可能更在意不要把正常邮件误判为垃圾邮件;疾病筛查可能更重视少漏掉阳性样本。
因此,不能只追求某个指标最高,而要根据实际任务选择重点指标。
七、使用正则化减少过拟合
如果特征很多、样本较少,模型容易把训练数据中的偶然现象也当成规律。
这种情况下,模型在训练集上的表现可能很好,但面对新的测试数据时,表现却明显下降。这种现象叫作过拟合。
正则化可以理解为给模型增加一个限制:模型不仅要减少预测错误,学习到的系数也不能变得过大。
常见的正则化方式有 L1 和 L2。
1. L1 正则化
L1 正则化会惩罚模型中所有系数绝对值的总和。
它可能把部分不重要特征的系数直接变成 0,因此具有一定的特征选择作用。
from sklearn.linear_model import LogisticRegression
model_l1 = LogisticRegression(
penalty="l1",
solver="liblinear",
C=1.0,
max_iter=1000
)
使用 L1 正则化时,需要选择支持它的求解器,例如 liblinear。
2. L2 正则化
L2 正则化会惩罚所有系数平方后的总和。
它通常不会直接把系数变成 0,而是让系数整体变小,使模型更加平滑和稳定。
model_l2 = LogisticRegression(
penalty="l2",
C=1.0,
max_iter=1000
)
在逻辑回归中,参数 C 用于控制正则化程度。
需要特别注意:
C越小,正则化越强;C越大,正则化越弱。
这一点很容易记反。
正则化过弱,模型可能继续过拟合;正则化过强,又可能限制模型学习真正的规律,最终造成欠拟合。
八、交叉验证让结果更加可靠
只划分一次训练集和测试集,得到的成绩可能带有偶然性。
如果测试集刚好比较简单,模型成绩会偏高;如果测试集中刚好有较多难样本,成绩又可能偏低。
交叉验证可以减少这种偶然影响。
以 5 折交叉验证为例:
- 把训练数据分成 5 份;
- 每次使用其中 4 份训练;
- 使用剩下的 1 份进行验证;
- 一共训练和验证 5 次;
- 最后计算 5 次成绩的平均值。
可以使用 cross_val_score() 完成交叉验证:
from sklearn.model_selection import cross_val_score
scores = cross_val_score(
model,
X_train,
y_train,
cv=5,
scoring="accuracy"
)
print("每一折的准确率:", scores)
print("平均准确率:", scores.mean())
这里的 cv=5 表示使用 5 折交叉验证,scoring="accuracy" 表示使用准确率进行评价。
交叉验证应该在训练集内部完成。最终测试集仍然要保留下来,用于最后一次客观检查。
如果反复观察测试集成绩,并根据测试集结果调整模型,测试集实际上也间接参与了训练,最后的评价就会变得不可靠。
九、使用网格搜索选择参数
正则化参数 C 应该设置成多少?应该使用 L1 还是 L2?
这些参数可以通过网格搜索和交叉验证一起选择。
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import StratifiedKFold
# 设置需要尝试的参数
params = {
"logistic__C": [0.01, 0.1, 1, 10],
"logistic__penalty": ["l1", "l2"],
"logistic__solver": ["liblinear"]
}
# 创建分层交叉验证
cv = StratifiedKFold(
n_splits=5,
shuffle=True,
random_state=42
)
# 创建网格搜索
search = GridSearchCV(
model,
param_grid=params,
cv=cv,
scoring="accuracy"
)
# 开始搜索
search.fit(X_train, y_train)
print("最佳参数:", search.best_params_)
print("交叉验证最佳成绩:", search.best_score_)
print("测试集成绩:", search.score(X_test, y_test))
GridSearchCV 会尝试参数表中的不同组合,并通过交叉验证比较这些组合的效果。
StratifiedKFold 表示分层交叉验证,它会尽量保持每一折中的类别比例一致。
网格搜索并不是尝试的参数越多越好。参数组合太多,会明显增加训练时间。
初学时可以先选择少量有代表性的参数,观察结果后再逐步缩小范围。
十、完整的机器学习流程
把前面的内容连起来,一个基础机器学习项目通常包含以下步骤:
明确问题
↓
读取并检查数据
↓
划分训练集与测试集
↓
数据预处理
↓
训练基础模型
↓
选择合适的评价指标
↓
使用正则化和交叉验证调参
↓
在测试集上进行最终评价
首先需要明确问题类型。
如果预测的是房价、销售额、温度等连续数值,通常属于回归问题;如果判断的是正常或异常、成功或失败等类别,通常属于分类问题。
然后检查数据中是否存在缺失值、异常值、特征范围差异和类别不平衡等问题。
模型训练完成后,不能只看训练集成绩,还要关注模型面对新数据时的表现。
如果训练集成绩很高,验证集成绩却比较低,可能发生了过拟合;如果训练集和验证集成绩都很低,可能出现了欠拟合,也可能是现有特征无法提供足够的信息。
十一、总结
通过本文,我们学习了机器学习中的一组基础知识:
- 线性回归用于预测连续数值;
fit()用于训练模型,predict()用于进行预测;- 均方误差越小,通常说明预测误差越小;
- R² 用于衡量模型对数据变化的解释能力;
- 逻辑回归虽然名字中有“回归”,实际主要用于分类;
- Sigmoid 函数可以把结果转换到 0 和 1 之间;
- 分类模型不能只看准确率;
- 精确率、召回率、F1 和 AUC 可以从不同角度评价模型;
- L1 和 L2 正则化可以限制模型复杂度;
- 参数
C越小,正则化越强; - 交叉验证可以让模型评价更加稳定;
- 网格搜索可以帮助我们选择较合适的参数。
更多推荐

所有评论(0)