06 基于sklearn的机械学习-欠拟合、过拟合、正则化、逻辑回归

目录

欠拟合、过拟合

欠拟合

过拟合

正则化

[岭回归(Ridge Regression):L2 正则化](#岭回归(Ridge Regression):L2 正则化)

[拉索回归(Lasso Regression):L1 正则化](#拉索回归(Lasso Regression):L1 正则化)

逻辑回归

[Sigmoid 函数](#Sigmoid 函数)

损失函数:交叉熵


欠拟合、过拟合

欠拟合

模型无法捕捉训练数据中的潜在模式和规律,导致在训练集和测试集上表现都很差(误差都很高)。

产生原因

  1. 模型过于简单:例如用线性模型拟合非线性关系(如房价与面积的关系可能是二次曲线,但用一次函数拟合)。

  2. 特征不足:输入特征太少,无法描述数据的关键规律(如预测房价只考虑面积,忽略地段、楼层等重要特征)。

  3. 正则化过度:对模型参数的惩罚太强,导致模型被过度简化。

过拟合

模型过度学习训练数据中的细节(包括噪声 和随机波动),导致在训练集上表现极好,但测试集上表现很差(泛化能力差)。

产生原因

  1. 模型过于复杂:例如用 10 次多项式拟合本应是线性分布的数据。

  2. 训练数据不足或有噪声:样本量少,模型容易记住每个样本的细节(包括噪声);数据中噪声多,模型会学习这些 "错误信息"。

  3. 特征过多:特征维度远大于样本量,模型容易找到巧合的特征组合拟合训练数据。

正则化

在机器学习中,模型训练的目标是 "既拟合训练数据,又能泛化到新数据"。但当模型复杂度过高时,容易出现过拟合(Overfitting)

  • 模型在训练集上表现极好(损失极低),但在测试集上表现很差(损失骤升);

  • 本质原因是模型 "记住" 了训练数据中的噪声和细节,而不是学习到通用规律。

正则化的核心作用 :通过在损失函数中加入 "参数惩罚项",限制参数的取值范围(避免过大),降低模型复杂度,强制模型学习更简单、更稳定的规律,从而缓解过拟合。

正则化的数学本质是修改损失函数,在原始损失(如均方误差 MSE、交叉熵)的基础上,增加一个 "惩罚项",形式如下:

正则化损失 = 原始损失 + 惩罚项

其中:

  • λ (正则化强度):控制惩罚力度。λ =0时无正则化(可能过拟合); λ越大,惩罚越强(参数被限制得越严格,模型越简单,可能欠拟合)。

  • 惩罚项:根据形式不同,分为 L1 正则化和 L2 正则化(对应拉索回归和岭回归)。

岭回归(Ridge Regression):L2 正则化

岭回归是线性回归的改进版本,通过引入L2 正则化解决过拟合问题,适用于特征间存在相关性的场景。

核心思想 :在线性回归的损失函数中加入参数平方和的惩罚项,限制参数的 "大小",避免参数因过度拟合噪声而变得过大。

对应欧氏距离

  • λ增大时,为了使总损失最小,w的值变小(但不会变为 0)。

  • 参数变小后,特征对预测结果的影响更温和,避免了个别特征的微小波动导致预测结果剧烈变化(模型更稳定);

  • 对于共线性特征(如高度相关的两个特征),L2 会让它们的权重 "平均分配",避免某一个特征的权重过大。

适用场景

  • 特征间存在较强相关性(如多重共线性问题)。

  • 需要保留所有特征(不希望任何特征被完全剔除)。

  • 样本量较少或特征维度较高的场景。

API

sklearn.linear_model.Ridge

  • alpha:正则化强度(λ),值越大惩罚越强。默认 1.0

  • fit_intercept:是否计算截距(w₀)。默认 True

  • max_iter:迭代最大次数

  • tol:收敛阈值,损失下降小于该值时停止。

  • 属性:

    • coef_:模型权重(w₁, w₂, ..., wₖ)

    • intercept_:截距(w₀)

python 复制代码
from sklearn.linear_model import Ridge
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error
​
X, y = fetch_california_housing(return_X_y=True,data_home = '../src')
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
scaler =  StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
​
# 岭回归
# tol: 设置停止迭代的阈值
model = Ridge(alpha=0.1,
              max_iter=1000,
              fit_intercept=True,
              tol=0.1)
model.fit(X_train, y_train)
​
y_hat = model.predict(X_test)
print('w:',model.coef_)
print('b:',model.intercept_)
print('loss:',mean_squared_error(y_test, y_hat))

拉索回归(Lasso Regression):L1 正则化

岭回归是线性回归的改进版本,通过引入L2 正则化解决过拟合问题,适用于特征间存在相关性的场景。

核心思想 :在线性回归的损失函数中加入参数绝对值和的惩罚项,不仅限制参数大小,还会将不重要特征的参数 "压缩为 0",实现特征选择。

对应曼哈顿距离

Lasso回归的目标是最小化以下损失函数:

  • L1 惩罚项的特殊性质是会使部分参数变为 0(稀疏性)

  • 当λ足够大时,不重要的特征的权重会被压缩到 0,相当于模型自动 "剔除" 了这些特征;

  • 剩余的非零参数对应更重要的特征,模型复杂度显著降低(特征更少),从而缓解过拟合。

适用场景

  • 高维稀疏数据(特征数量远大于样本量,如文本分类中的词袋特征)。

  • 需要自动筛选特征(减少特征维度,简化模型)。

  • 特征间相关性较低的场景(若特征高度相关,L1 可能随机剔除其中一个)。

API

sklearn.linear_model.Lasso

  • max_iter:迭代次数(L1 收敛较慢,通常需要更大值)

  • warm_start:是否利用上一次训练结果加速本次训练。默认 False

  • alpha:正则化强度,值越大惩罚越强

  • 属性

    • coef_:模型权重(含 0 值,实现特征选择)

    • intercept_:截距

python 复制代码
from sklearn.linear_model import Lasso
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error
​
X, y = fetch_california_housing(return_X_y=True,data_home = '../src')
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
scaler =  StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
​
# 岭回归
# tol: 设置停止迭代的阈值
model = Lasso(alpha=0.1,
              max_iter=1000,
              fit_intercept=True,
              tol=0.1)
model.fit(X_train, y_train)
​
y_hat = model.predict(X_test)
print('w:',model.coef_)
print('b:',model.intercept_)
print('loss:',mean_squared_error(y_test, y_hat))
复制代码

逻辑回归

逻辑回归(Logistic Regression)是一种广泛应用于分类问题的统计学习方法,多用于解决二分类(或多分类)问题。它通过 Sigmoid 函数将线性回归的输出映射到 [0,1] 区间,从而表示样本属于某一类别的概率。

线性回归:

Sigmoid 函数

将线性回归的输出映射到 [0,1] 区间,从而表示样本属于某一类别的概率。

sigmoid激活函数 :

把上面的h(w) 线性的输出再输入到sigmoid函数当中

  • 若f*(*w)> 0.5,预测为正类(1)

  • 若f*(*w)< 0.5,预测为负类(0)

损失函数:交叉熵

逻辑回归不使用 MSE 作为损失函数(非凸函数,易陷入局部最优),而是使用交叉熵损失

对于二分类问题,损失函数:

损失函数图:

当y=1时:

通过损失函数图像,我们知道:

当y=1时,我们希望值越大越好

当y=0时,我们希望值越小越好

综合0和1的损失函数:

  • ,损失简化为−log(y^​i​),y_hat 越接近 1,损失越小

  • =0,损失简化为 -log(1-y^i_hat)):y_hat 越接近 0,损失越小

手动算一下下:

API

sklearn.linear_model.LogisticRegression

  • penalty:正则化类型:'l2'(默认)、'l1''elasticnet'(L1+L2)、'none'

  • C :正则化强度的倒数 C = 1/ λ ,值越小正则化越强。默认 1.0

  • max_iter:最大迭代次数(确保收敛)

  • 属性:

    • coef_:特征权重

    • intercept_:截距

    • predict_proba(X):返回每个样本的类别概率

python 复制代码
from sklearn.preprocessing import StandardScaler
from sklearn.feature_extraction import DictVectorizer
from sklearn.linear_model import LogisticRegression
import pandas as pd
from sklearn.model_selection import train_test_split
​
​
data = pd.read_csv('../src/titanic/titanic.csv')
print(data.to_numpy().shape)
# 列
# print(data.columns)
​
# 加载泰坦尼克号数据集,提取了三个特征:船舱等级 (pclass)、年龄 (age) 和性别 (sex)
y = data['survived'].values
x = data[['pclass', 'age', 'sex']]
# print(x.shape)
# print(x.head())
​
​
​
# 缺失值处理
# 对年龄中的缺失值使用平均值进行填充
x['age'].fillna(x['age'].mean(), inplace=True)
# 转换为字典格式,便于特征向量化
x = x.to_dict(orient='records')
# 字典向量化 转为矩阵
#sparse=False: 转为稠密矩阵
dicter = DictVectorizer(sparse=False)
x = dicter.fit_transform(x)
print("特征名称:", dicter.get_feature_names_out())
print("前10条处理后的特征:\n", x[:10])
​
​
​
scaler = StandardScaler()
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.2,random_state=0)
x_train = scaler.fit_transform(x_train)
x_test = scaler.transform(x_test)
# 逻辑回归
model = LogisticRegression(max_iter=1000,fit_intercept=True)
​
# 训练
model.fit(x_train,y_train)
​
# 准确率
score = model.score(x_test,y_test)
print('score:',score)
python 复制代码
(1313, 11)
特征名称: ['age' 'pclass=1st' 'pclass=2nd' 'pclass=3rd' 'sex=female' 'sex=male']
前10条处理后的特征:
 [[29.      1.      0.      0.      1.      0.    ]
 [ 2.      1.      0.      0.      1.      0.    ]
 [30.      1.      0.      0.      0.      1.    ]
 [25.      1.      0.      0.      1.      0.    ]
 [ 0.9167  1.      0.      0.      0.      1.    ]
 [47.      1.      0.      0.      0.      1.    ]
 [63.      1.      0.      0.      1.      0.    ]
 [39.      1.      0.      0.      0.      1.    ]
 [58.      1.      0.      0.      1.      0.    ]
 [71.      1.      0.      0.      0.      1.    ]]
score: 0.8365019011406845
相关推荐
徐赛俊17 分钟前
# 自动定时运行Python爬虫脚本教程(Windows任务计划程序)
windows·爬虫·python
暴躁的大熊24 分钟前
LLM大模型时代:生活服务领域的“生存革命“与新生态重构
人工智能
程序员秘密基地1 小时前
基于html,css,jquery,django,lstm,cnn,tensorflow,bert,推荐算法,mysql数据库
python·cnn·tensorflow·lstm·推荐算法
Blossom.1181 小时前
基于深度学习的医学图像分析:使用MobileNet实现医学图像分类
人工智能·深度学习·yolo·机器学习·分类·数据挖掘·迁移学习
德育处主任1 小时前
「豆包」加「PromptPilot」等于「优秀员工」
人工智能·llm·aigc
字节跳动安全中心1 小时前
猎影计划:从密流中捕获 Cobalt Strike 的隐秘身影
人工智能·安全·llm
技术炼丹人1 小时前
从RNN为什么长依赖遗忘到注意力机制的解决方案以及并行
人工智能·python·算法
FreeBuf_2 小时前
AI Agents漏洞百出,恶意提示等安全缺陷令人担忧
人工智能·安全
hqxstudying2 小时前
Java开发时出现的问题---语言特性与基础机制陷阱
java·jvm·python
水鳜鱼肥2 小时前
Github Spark 革新应用,重构未来
前端·人工智能