正则化
欠拟合与过拟合
过拟合:一个假设 在训练数据上能够获得比其他假设更好的拟合, 但是在测试数据集上却不能很好地拟合数据 (体现在准确率下降),此时认为这个假设出现了过拟合的现象。(模型过于复杂)
欠拟合:一个假设 在训练数据上不能获得更好的拟合,并且在测试数据集上也不能很好地拟合数据 ,此时认为这个假设出现了欠拟合的现象。(模型过于简单)
过拟合和欠拟合的区别:
欠拟合在训练集和测试集上的误差都较大
过拟合在训练集上误差较小,而测试集上误差较大
损失函数案例
波士顿房价预测
案例背景介绍
数据介绍
给定的这些特征,是专家们得出的影响房价的结果属性。不需要自己去探究特征是否有用,只需要使用这些特征。
案例分析
回归当中的数据大小不一致,是否会导致结果影响较大。所以需要做标准化处理。
- 数据分割与标准化处理
- 回归预测
- 线性回归的算法效果评估
回归性能评估
均方误差(Mean Squared Error, MSE)评价机制
- 均方误差回归损失
- y_true:真实值
- y_pred:预测值
- return:浮点数结果
波士顿房价预测_正规方程解法
"""
案例:
波士顿房价预测, 正规方程解法.
回顾:
正规方程解法 和 梯度下降的区别:
相同点: 都可以用来找 损失函数的极小值, 评估 回归模型.
不同点:
正规方程: 一次性求解, 资源开销较大, 适合于小批量干净的数据集, 如果数据没有逆, 也无法计算.
梯度下降: 迭代求解, 资源开销相对较小, 适用于大批量的数据集, 实际开发 更推荐.
分类:
全梯度下降
随机梯度下降
小批量梯度下降
随机平均梯度下降
线性回归模型 评估的方案:
方案1: 平均绝对误差, Mean Absolute Error, 误差绝对值的和 的 平均值.
方案2: 均方误差, Mean Squared Error, 误差的平方和的平均值
方案3: 均方根误差, Root Mean Squared Error, 误差的平方和的平均值的 平方根.
机器学习项目的研发流程:
1. 获取数据.
2. 数据的预处理.
3. 特征工程.
特征提取, 特征预处理(标准化, 归一化), 特征降维, 特征选取, 特征组合.
4. 模型训练.
5. 模型评估.
6. 模型预测.
"""
# 导包
# from sklearn.datasets import load_boston # 数据集
from sklearn.preprocessing import StandardScaler # 特征处理
from sklearn.model_selection import train_test_split # 数据集划分
from sklearn.linear_model import LinearRegression # 正规方程的回归模型
from sklearn.metrics import mean_squared_error, mean_absolute_error, root_mean_squared_error # 均方误差评估 平均绝对值误差评估 均方根误差评估
import pandas as pd
import numpy as np
# 1. 获取数据.
data_url = "http://lib.stat.cmu.edu/datasets/boston"
raw_df = pd.read_csv(data_url, sep="\s+", skiprows=22, header=None)
data = np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :2]])
target = raw_df.values[1::2, 2]
# 查看数据 以及数量
# print(f'特征: {len(data)}, {data[:5]}')
# print(f'目标: {len(target)}, {target[:5]}')
# 2. 数据的预处理.
x_train, x_test, y_train, y_test = train_test_split(data, target, test_size=0.2, random_state=22)
# 3. 特征工程, 特征提取, 特征预处理(标准化, 归一化), 特征降维, 特征选取, 特征组合.
# 3.1 创建标准化对象.
transfer = StandardScaler()
# 3.2 对训练和 和 测试集的 特征进行标准化处理.
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
# 4. 模型训练.
# 4.1 创建 线性回归之 正规方程对象.
# 参数: fit_intercept: 是否计算截距(bias, 偏置), 默认是: True
estimator = LinearRegression(fit_intercept=True)
# 4.2 模型训练.
estimator.fit(x_train, y_train)
# 5. 模型预测.
y_predict = estimator.predict(x_test)
print(f'预测值为:{y_predict}')
print(f'权重:{estimator.coef_}')
print(f'偏置:{estimator.intercept_}')
# 6. 模型评估.
# 参1: 真实值, 参2: 预测值
# MAE(平均绝对误差) 和 RMSE(均方根误差) 都可以衡量模型的预测效果, 如果更关注异常值, 就用 RMSE
print(f'平均绝对误差: {mean_absolute_error(y_test, y_predict)}')
print(f'均方误差: {mean_squared_error(y_test, y_predict)}') # 20.77068478427006
print(f'均方根误差: {root_mean_squared_error(y_test, y_predict)}') # 4.557486674063903
print(f'均方根误差: {np.sqrt(mean_squared_error(y_test, y_predict))}') # 4.557486674063903, 效果同上, sqrt全称是: square root
波士顿房价预测_梯度下降解法
"""
案例:
波士顿房价预测, 梯度下降解法.
回顾:
正规方程解法 和 梯度下降的区别:
相同点: 都可以用来找 损失函数的极小值, 评估 回归模型.
不同点:
正规方程: 一次性求解, 资源开销较大, 适合于小批量干净的数据集, 如果数据没有逆, 也无法计算.
梯度下降: 迭代求解, 资源开销相对较小, 适用于大批量的数据集, 实际开发 更推荐.
分类:
全梯度下降
随机梯度下降
小批量梯度下降
随机平均梯度下降
线性回归模型 评估的方案:
方案1: 平均绝对误差, Mean Absolute Error, 误差绝对值的和 的 平均值.
方案2: 均方误差, Mean Squared Error, 误差的平方和的平均值
方案3: 均方根误差, Root Mean Squared Error, 误差的平方和的平均值的 平方根.
机器学习项目的研发流程:
1. 获取数据.
2. 数据的预处理.
3. 特征工程.
特征提取, 特征预处理(标准化, 归一化), 特征降维, 特征选取, 特征组合.
4. 模型训练.
5. 模型评估.
6. 模型预测.
"""
# 导包
# from sklearn.datasets import load_boston # 数据
from sklearn.preprocessing import StandardScaler # 特征处理
from sklearn.model_selection import train_test_split # 数据集划分
from sklearn.linear_model import LinearRegression # 正规方程的回归模型
from sklearn.linear_model import SGDRegressor # 梯度下降的回归模型
from sklearn.metrics import mean_squared_error, mean_absolute_error, \
root_mean_squared_error # 均方误差评估, 平均绝对值误差评估, 均方根误差评估
import pandas as pd
import numpy as np
# 1. 获取数据.
data_url = "http://lib.stat.cmu.edu/datasets/boston"
raw_df = pd.read_csv(data_url, sep="\\s+", skiprows=22, header=None)
data = np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :2]])
target = raw_df.values[1::2, 2]
print(f'特征: {len(data)}, {data[:3]}')
print(f'标签: {len(target)}, {target[:3]}')
# 2. 数据的预处理. 特征 标签 测试集占比 随机种子
x_train, x_test, y_train, y_test = train_test_split(data, target, test_size=0.2, random_state=22)
# 3. 特征工程, 特征提取, 特征预处理(标准化, 归一化), 特征降维, 特征选取, 特征组合.
# 3.1 创建标准化对象.
transfer = StandardScaler()
# 3.2 对训练和 和 测试集的 特征进行标准化处理.
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
# 4. 模型训练.
# 4.1 创建 线性回归之 梯度下降对象.
# 参数: fit_intercept: 是否计算截距(bias, 偏置), 默认是: True
# estimator = LinearRegression(fit_intercept=True)
# 参1: 是否计算偏置 参2 : 学习率固定为常量 参3: 学习率的值
estimator = SGDRegressor(fit_intercept=True, learning_rate='constant', eta0=0.008)
# 4.2 模型训练.4
estimator.fit(x_train, y_train)
# 5. 模型预测.
y_predict = estimator.predict(x_test)
print(f'权重: {estimator.coef_}')
print(f'偏置: {estimator.intercept_}')
print('-' * 22)
# 6. 模型评估.
# 参1: 真实值, 参2: 预测值
# MAE(平均绝对误差) 和 RMSE(均方根误差) 都可以衡量模型的预测效果, 如果更关注异常值, 就用 RMSE
print(f'平均绝对误差: {mean_absolute_error(y_test, y_predict)}')
print(f'均方误差: {mean_squared_error(y_test, y_predict)}')
print(f'均方根误差: {root_mean_squared_error(y_test, y_predict)}')
print(f'均方根误差: {np.sqrt(mean_squared_error(y_test, y_predict))}')
正则化解决过拟合案例
"""
案例:
演示正则化解决 拟合问题.
回顾:
拟合: 指的是 模型和数据之间存在关系, 即: 预测值 和 真实值之间的关系.
欠拟合: 模型在训练集, 测试集标签都不好.
原因: 模型过于简单了.
过拟合: 模型在训练集表现好, 在测试集表现不好.
原因: 模型过于复杂了, 数据不纯, 数据量少.
正好拟合(泛化): 模型在训练集, 测试集都好
奥卡姆剃刀: 在误差相同(泛化程度一样)的情况下, 优先选择简单的模型.
正则化解释:
概述:
正则化: 是一种对模型复杂度的一种控制, 通过 降低特征的权重 实现.
分类:
L1正则化, 指的是: Lasso模块, 会 降低权重, 甚至可能降为0 -> 特征选取.
L2正则化, 指的是: Ridge模块, 会 降低权重, 但不会降为0.
"""
# 导包
import numpy as np # 主要是做数学相关运算操作等.
import matplotlib.pyplot as plt # Matplotlib绘图的
from sklearn.linear_model import LinearRegression, Lasso, Ridge # 线性回归的 正规方程解法, L1正则化, L2正则化.
from sklearn.metrics import mean_squared_error, root_mean_squared_error, mean_absolute_error # 计算均方误差, 均方根误差, 平均绝对误差
from sklearn.model_selection import train_test_split # 切割测试集和训练集.
# 1. 定义函数, 演示: 欠拟合情况.
def dm01_模型欠拟合():
# 1. 生成数据.
# 1.1 指定随机数种子, 种子一样, 则每次生成的随机数的规则都是相同的.
np.random.seed(22)
# 1.2 生成x轴的坐标.
x = np.random.uniform(-3, 3, size=100)
# 1.3 基于x轴的值, 结合线性公式, 生成y轴的值.
# 回顾一元线性回归公式: y = kx + b, 这里为了数据效果更好, 加入噪声...
# 即: y = 0.5x² + x + 2 + 噪声(正太分布生成的随机数).
# np.random.normal(0, 1, size=100)意思是: 生成正态分布的随机数, 均值是0, 标准差是1, 随机数个数是100.
y = 0.5 * x ** 2 + x + 2 + np.random.normal(0, 1, size=100)
# 1.4 查看数据集.
print(f'x轴的值: {x}') # [1, 2, 3]
print(f'y轴的值: {y}')
# 2. 数据的预处理.
X1 = x.reshape(-1, 1)
print(f'处理后, X: {X1}') # [[1], [2], [3]]
# 3. 创建模型(算法)对象.
# 3.1 线性回归的 正规方程对象.
estimator = LinearRegression()
# 3.2 模型训练.
estimator.fit(X1, y)
# 4. 模型预测.
y_predict = estimator.predict(X1)
print(f'预测值: {y_predict}')
# 5. 模型评估.
print(f'均方误差: {mean_squared_error(y, y_predict)}')
print(f'均方根误差: {root_mean_squared_error(y, y_predict)}')
print(f'平均绝对误差: {mean_absolute_error(y, y_predict)}')
# 6. 绘制图形.
plt.scatter(x, y) # 真实值的x轴, y轴 绘制散点图.
plt.plot(x, y_predict, color='red') # 预测值的x轴, y轴 绘制折线图(充当拟合回归线)
plt.show()
# 2. 定义函数, 演示: 正好拟合的情况.
def dm02_模型正好拟合():
# 1. 生成数据.
# 1.1 指定随机数种子, 种子一样, 则每次生成的随机数的规则都是相同的.
np.random.seed(22)
# 1.2 生成x轴的坐标.
x = np.random.uniform(-3, 3, size=100)
# 1.3 基于x轴的值, 结合线性公式, 生成y轴的值.
# 回顾一元线性回归公式: y = kx + b, 这里为了数据效果更好, 加入噪声...
# 即: y = 0.5x² + x + 2 + 噪声(正太分布生成的随机数).
# np.random.normal(0, 1, size=100)意思是: 生成正态分布的随机数, 均值是0, 标准差是1, 随机数个数是100.
y = 0.5 * x ** 2 + x + 2 + np.random.normal(0, 1, size=100)
# 1.4 查看数据集.
print(f'x轴的值: {x}') # [1, 2, 3]
print(f'y轴的值: {y}')
# 2. 数据的预处理.
X1 = x.reshape(-1, 1)
# np.hstack()解释: 垂直合并, 即: 竖直方向合并.
X2 = np.hstack([X1, X1 ** 2])
print(f'处理后, X1: {X1}') # [[1], [2], [3]]
print(f'处理后, X2: {X2}') # [[1, 1], [2, 4], [3, 9]]
# 3. 创建模型(算法)对象.
# 3.1 线性回归的 正规方程对象.
estimator = LinearRegression()
# 3.2 模型训练.
estimator.fit(X2, y)
# 4. 模型预测.
y_predict = estimator.predict(X2)
print(f'预测值: {y_predict}')
# 5. 模型评估.
print(f'均方误差: {mean_squared_error(y, y_predict)}')
print(f'均方根误差: {root_mean_squared_error(y, y_predict)}')
print(f'平均绝对误差: {mean_absolute_error(y, y_predict)}')
# 6. 绘制图形.
# 6.1 真实值的x轴, y轴 绘制散点图.
plt.scatter(x, y)
# 6.2 根据预测值的x轴(升序排序), y轴值, 绘制折线图(充当拟合回归线).
plt.plot(np.sort(x), y_predict[np.argsort(x)], color='red') # 预测值的x轴, y轴 绘制折线图(充当拟合回归线)
plt.show()
# 3. 定义函数, 演示: 过拟合的情况.
def dm03_模型过拟合():
# 1. 生成数据.
# 1.1 指定随机数种子, 种子一样, 则每次生成的随机数的规则都是相同的.
np.random.seed(22)
# 1.2 生成x轴的坐标.
x = np.random.uniform(-3, 3, size=100)
# 1.3 基于x轴的值, 结合线性公式, 生成y轴的值.
# 回顾一元线性回归公式: y = kx + b, 这里为了数据效果更好, 加入噪声...
# 即: y = 0.5x² + x + 2 + 噪声(正太分布生成的随机数).
# np.random.normal(0, 1, size=100)意思是: 生成正态分布的随机数, 均值是0, 标准差是1, 随机数个数是100.
y = 0.5 * x ** 2 + x + 2 + np.random.normal(0, 1, size=100)
# 1.4 查看数据集.
print(f'x轴的值: {x}') # [1, 2, 3]
print(f'y轴的值: {y}')
# 2. 数据的预处理.
X1 = x.reshape(-1, 1)
# np.hstack()解释: 垂直合并, 即: 竖直方向合并.
X3 = np.hstack([X1, X1 ** 2, X1 ** 3, X1 ** 4, X1 ** 5, X1 ** 6, X1 ** 7, X1 ** 8, X1 ** 9, X1 ** 10])
print(f'处理后, X1: {X1}') # [[1], [2], [3]]
print(f'处理后, X3: {X3}') # [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [2, 4, 8, 16, 32, 64, 128, 256, 512, 1024], [3, 9, 27...]]
# 3. 创建模型(算法)对象.
# 3.1 线性回归的 正规方程对象.
estimator = LinearRegression()
# 3.2 模型训练.
estimator.fit(X3, y)
# 4. 模型预测.
y_predict = estimator.predict(X3)
print(f'预测值: {y_predict}')
# 5. 模型评估.
print(f'均方误差: {mean_squared_error(y, y_predict)}')
print(f'均方根误差: {root_mean_squared_error(y, y_predict)}')
print(f'平均绝对误差: {mean_absolute_error(y, y_predict)}')
# 6. 绘制图形.
# 6.1 真实值的x轴, y轴 绘制散点图.
plt.scatter(x, y)
# 6.2 根据预测值的x轴(升序排序), y轴值, 绘制折线图(充当拟合回归线).
plt.plot(np.sort(x), y_predict[np.argsort(x)], color='red') # 预测值的x轴, y轴 绘制折线图(充当拟合回归线)
plt.show()
# 4. 定义函数, 演示: L1正则化 解决 过拟合.
def dm04_L1正则化():
# 1. 生成数据.
# 1.1 指定随机数种子, 种子一样, 则每次生成的随机数的规则都是相同的.
np.random.seed(22)
# 1.2 生成x轴的坐标.
x = np.random.uniform(-3, 3, size=100)
# 1.3 基于x轴的值, 结合线性公式, 生成y轴的值.
# 回顾一元线性回归公式: y = kx + b, 这里为了数据效果更好, 加入噪声...
# 即: y = 0.5x² + x + 2 + 噪声(正太分布生成的随机数).
# np.random.normal(0, 1, size=100)意思是: 生成正态分布的随机数, 均值是0, 标准差是1, 随机数个数是100.
y = 0.5 * x ** 2 + x + 2 + np.random.normal(0, 1, size=100)
# 1.4 查看数据集.
print(f'x轴的值: {x}') # [1, 2, 3]
print(f'y轴的值: {y}')
# 2. 数据的预处理.
X1 = x.reshape(-1, 1)
# np.hstack()解释: 垂直合并, 即: 竖直方向合并.
X3 = np.hstack([X1, X1 ** 2, X1 ** 3, X1 ** 4, X1 ** 5, X1 ** 6, X1 ** 7, X1 ** 8, X1 ** 9, X1 ** 10])
print(f'处理后, X1: {X1}') # [[1], [2], [3]]
print(f'处理后, X3: {X3}') # [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [2, 4, 8, 16, 32, 64, 128, 256, 512, 1024], [3, 9, 27...]]
# 3. 创建模型(算法)对象.
# 3.1 线性回归的 正规方程对象.
# estimator = LinearRegression()
# 创建 L1正则化对象.
# 参数alpha: 正则化的(惩罚)系数, (惩罚)系数越大, 则正则化项的权重越小.
estimator = Lasso(alpha=0.1)
# 3.2 模型训练.
estimator.fit(X3, y)
# 4. 模型预测.
y_predict = estimator.predict(X3)
print(f'预测值: {y_predict}')
# 5. 模型评估.
print(f'均方误差: {mean_squared_error(y, y_predict)}')
print(f'均方根误差: {root_mean_squared_error(y, y_predict)}')
print(f'平均绝对误差: {mean_absolute_error(y, y_predict)}')
# 6. 绘制图形.
# 6.1 真实值的x轴, y轴 绘制散点图.
plt.scatter(x, y)
# 6.2 根据预测值的x轴(升序排序), y轴值, 绘制折线图(充当拟合回归线).
plt.plot(np.sort(x), y_predict[np.argsort(x)], color='red') # 预测值的x轴, y轴 绘制折线图(充当拟合回归线)
plt.show()
# 5. 定义函数, 演示: L2正则化 解决 过拟合.
def dm05_L2正则化():
# 1. 生成数据.
# 1.1 指定随机数种子, 种子一样, 则每次生成的随机数的规则都是相同的.
np.random.seed(22)
# 1.2 生成x轴的坐标.
x = np.random.uniform(-3, 3, size=100)
# 1.3 基于x轴的值, 结合线性公式, 生成y轴的值.
# 回顾一元线性回归公式: y = kx + b, 这里为了数据效果更好, 加入噪声...
# 即: y = 0.5x² + x + 2 + 噪声(正太分布生成的随机数).
# np.random.normal(0, 1, size=100)意思是: 生成正态分布的随机数, 均值是0, 标准差是1, 随机数个数是100.
y = 0.5 * x ** 2 + x + 2 + np.random.normal(0, 1, size=100)
# 1.4 查看数据集.
print(f'x轴的值: {x}') # [1, 2, 3]
print(f'y轴的值: {y}')
# 2. 数据的预处理.
X1 = x.reshape(-1, 1)
# np.hstack()解释: 垂直合并, 即: 竖直方向合并.
X3 = np.hstack([X1, X1 ** 2, X1 ** 3, X1 ** 4, X1 ** 5, X1 ** 6, X1 ** 7, X1 ** 8, X1 ** 9, X1 ** 10])
print(f'处理后, X1: {X1}') # [[1], [2], [3]]
print(f'处理后, X3: {X3}') # [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [2, 4, 8, 16, 32, 64, 128, 256, 512, 1024], [3, 9, 27...]]
# 3. 创建模型(算法)对象.
# 3.1 线性回归的 正规方程对象.
# estimator = LinearRegression()
# 创建 L1正则化对象.
# 参数alpha: 正则化的(惩罚)系数, (惩罚)系数越大, 则正则化项的权重越小.
# estimator = Lasso(alpha=0.1)
# 创建 L2正则化对象.
estimator = Ridge(alpha=0.1)
# 3.2 模型训练.
estimator.fit(X3, y)
# 4. 模型预测.
y_predict = estimator.predict(X3)
print(f'预测值: {y_predict}')
# 5. 模型评估.
print(f'均方误差: {mean_squared_error(y, y_predict)}')
print(f'均方根误差: {root_mean_squared_error(y, y_predict)}')
print(f'平均绝对误差: {mean_absolute_error(y, y_predict)}')
# 6. 绘制图形.
# 6.1 真实值的x轴, y轴 绘制散点图.
plt.scatter(x, y)
# 6.2 根据预测值的x轴(升序排序), y轴值, 绘制折线图(充当拟合回归线).
plt.plot(np.sort(x), y_predict[np.argsort(x)], color='red') # 预测值的x轴, y轴 绘制折线图(充当拟合回归线)
plt.show()
# 6. 在main方法中测试.
if __name__ == '__main__':
# dm01_模型欠拟合()
# dm02_模型正好拟合()
# dm03_模型过拟合()
# dm04_L1正则化()
dm05_L2正则化()
坚持分享 共同进步 如有错误 欢迎指出