线性回归
线性回归介绍(Linear Regressor): 概述/目的: 用线性公式 来描述 多个自变量(特征) 和 1个因变量(标签)之间 关系的, 对其关系进行建模, 基于特征 预测 标签. 线性回归属于: 有监督学习, 即: 有特征, 有标签, 且标签是连续的. 分类: 一元线性回归: 1个特征列 + 1个标签列 多元线性回归: 多个特征列 + 1个标签列 公式: 一元线性回归: y = kx + b => wx + b k: 数学中叫斜率, 在机器学习中Weight(权重), 简称: w b: 数学中叫截距, 在机器学习中Bias(偏置), 简称: b 多元线性回归: y = w1x1 + w2x2 + w3x3 + ... + wnxn + b = w的转置 * x + b 误差 = 预测值 - 真实值 损失函数(Loss Function, 也叫成本函数, 代价函数, 目标函数, Cost Function): 用于描述 每个样本点 和 其预测值之间关系的, 让损失函数最小, 就是让 误差和小, 线性回归效率, 评估就越高. 问题: 如何让损失函数最小? 答案: 思路1: 正规方程法. 思路2: 梯度下降法. 损失函数分类: 最小二乘: 每个样本点误差的平方和 MSE(Mean Square Error, 均方误差): 每个样本点误差的平方和 / 样本个数 RMSE(Root Mean Square Error, 均方根误差): 均方误差 开平方根 MAE(Mean Absolute Error, 均绝对误差): 每个样本点误差的绝对值和 / 样本个数 矩阵相关: 1范数 = 向量中各元素 绝对值 之和. 2范数 = 向量的模长, 即: 各个元素平方总和, 开平方根
python
"""
线性回归介绍(Linear Regressor):
概述/目的:
用线性公式 来描述 多个自变量(特征) 和 1个因变量(标签)之间 关系的, 对其关系进行建模, 基于特征 预测 标签.
线性回归属于: 有监督学习, 即: 有特征, 有标签, 且标签是连续的.
分类:
一元线性回归: 1个特征列 + 1个标签列
多元线性回归: 多个特征列 + 1个标签列
公式:
一元线性回归:
y = kx + b => wx + b
k: 数学中叫斜率, 在机器学习中Weight(权重), 简称: w
b: 数学中叫截距, 在机器学习中Bias(偏置), 简称: b
多元线性回归:
y = w1x1 + w2x2 + w3x3 + ... + wnxn + b
= w的转置 * x + b
误差 = 预测值 - 真实值
损失函数(Loss Function, 也叫成本函数, 代价函数, 目标函数, Cost Function):
用于描述 每个样本点 和 其预测值之间关系的, 让损失函数最小, 就是让 误差和小, 线性回归效率, 评估就越高.
问题: 如何让损失函数最小?
答案:
思路1: 正规方程法.
思路2: 梯度下降法.
损失函数分类:
最小二乘: 每个样本点误差的平方和
MSE(Mean Square Error, 均方误差): 每个样本点误差的平方和 / 样本个数
RMSE(Root Mean Square Error, 均方根误差): 均方误差 开平方根
MAE(Mean Absolute Error, 均绝对误差): 每个样本点误差的绝对值和 / 样本个数
矩阵相关:
1范数 = 向量中各元素 绝对值 之和.
2范数 = 向量的模长, 即: 各个元素平方总和, 开平方根
"""
# 导包
from sklearn.linear_model import LinearRegression
# 案例: 演示线性回归API入门.
# 1. 准备数据.
x_train = [[160], [166], [172], [174], [180]] # 训练集的特征
y_train = [56.3, 60.6, 65.1, 68.5, 75] # 训练集的标签
x_test = [[176]] # 测试集的特征
# 2. 数据的预处理, 这里不需要.
# 3. 特征工程(特征提取, 特征预处理), 这里不需要.
# 4. 模型训练
# 4.1 创建模型对象.
estimator = LinearRegression()
# 4.2 具体的训练动作.
estimator.fit(x_train, y_train)
# 4.3 因为是线性回归模型, 我们可以查看下: 斜率(w, 权重), 截距(b, 偏置)
print(f'权重: {estimator.coef_}') # 0.92942177
print(f'偏置: {estimator.intercept_}') # -93.27346938775514
# 5. 模型预测.
y_pre = estimator.predict(x_test)
print(f'预测值为: {y_pre}') # 70.3047619
# 6. 模型评估.
房价预测之正规方程法
案例: 演示 正规方程法 线性回归对象 完成 波士顿房价预测案例. 回顾: 线性回归算法 属于 有监督学习之 有特征, 有标签, 且标签是连续的. 线性回归分类: 一元线性回归: 1个特征列, 1个标签列. 多元线性回归: 多个特征列, 1个标签列. 线性回归大白话解释: 它是用线性公式来描述 特征 和 标签之间关系的, 方便做预测, 公式如下: 一元线性回归: y = w * x + b 多元线性回归: y = w1 * x1 + w2 * x2 + w3 * x3 + ... + wn * xn + b = w的转置 * x + b 如何衡量线性回归模型的好坏? 思路: 预测值和真实值之间的误差, 误差越小, 模型越好 => 损失函数 具体的方案: 1. 最小二乘. 每个(样本)误差平方和 2. 均方误差(MSE) 每个(样本)误差平方和 / 样本总数 3. 均方根误差(RMSE) 每个(样本)误差平方和 / 样本总数 的 平方根 4. 平均绝对误差(MAE) 每个(样本)误差绝对值和 / 样本总数 如何让损失函数最小? 思路1: 梯度下降法. => 全梯度下降(Full Gradient Descent, FGD), 随机梯度下降(SGD), 小批量梯度下降(推荐, Min-Batch), 随机平均梯度下降(SAG) 思路2: 正规方程法. 机器学习开发流程: 1. 加载数据. 2. 数据的预处理. 3. 特征工程(特征提取, 特征预处理...) 4. 模型训练. 5. 模型预测. 6. 模型评估
python
"""
案例:
演示 正规方程法 线性回归对象 完成 波士顿房价预测案例.
回顾:
线性回归算法 属于 有监督学习之 有特征, 有标签, 且标签是连续的.
线性回归分类:
一元线性回归: 1个特征列, 1个标签列.
多元线性回归: 多个特征列, 1个标签列.
线性回归大白话解释:
它是用线性公式来描述 特征 和 标签之间关系的, 方便做预测, 公式如下:
一元线性回归: y = w * x + b
多元线性回归: y = w1 * x1 + w2 * x2 + w3 * x3 + ... + wn * xn + b = w的转置 * x + b
如何衡量线性回归模型的好坏?
思路:
预测值和真实值之间的误差, 误差越小, 模型越好 => 损失函数
具体的方案:
1. 最小二乘. 每个(样本)误差平方和
2. 均方误差(MSE) 每个(样本)误差平方和 / 样本总数
3. 均方根误差(RMSE) 每个(样本)误差平方和 / 样本总数 的 平方根
4. 平均绝对误差(MAE) 每个(样本)误差绝对值和 / 样本总数
如何让损失函数最小?
思路1: 梯度下降法. => 全梯度下降(Full Gradient Descent, FGD), 随机梯度下降(SGD), 小批量梯度下降(推荐, Min-Batch), 随机平均梯度下降(SAG)
思路2: 正规方程法.
机器学习开发流程:
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, root_mean_squared_error, mean_absolute_error # 均方误差评估, RMSE, MAE
from sklearn.linear_model import Ridge, RidgeCV
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]]) # hstack()函数作用: 水平拼接数组
target = raw_df.values[1::2, 2]
# print(f'特征: {data.shape}') # (506, 13)
# print(f'标签: {target.shape}') # (506,)
#
# print(f'特征数据: {data[:5]}')
# print(f'标签数据: {target[:5]}')
# 2. 数据的预处理. 切分训练集 和 测试集.
# 参1: 特征数据. 参2: 标签数据. 参3: 测试集占训练集的比例. 参4: 随机种子.
x_train, x_test, y_train, y_test = train_test_split(data, target, test_size=0.2, random_state=23)
# 3. 特征工程(特征提取, 特征预处理...)
# 3.1 创建标准化对象.
transfer = StandardScaler()
# 3.2 对训练集进行标准化.
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
# 4. 模型训练.
# 4.1 创建 线性回归 正规方程 模型对象.
estimator = LinearRegression(fit_intercept=True) # fit_intercept: 是否需要截距(Bias, 偏置), 默认是True
# 4.2 模型训练.
estimator.fit(x_train, y_train)
# 4.3 打印模型计算出的 w(权重, weight) 和 b(偏置, bias).
print(f'权重: {estimator.coef_}')
print(f'偏置: {estimator.intercept_}')
# 5. 模型预测.
y_pre = estimator.predict(x_test)
print(f'预测结果为: {y_pre}')
# 6. 模型评估
# 参1: 测试集的标签数据. 参2: 预测结果.
print(f'均方误差为: {mean_squared_error(y_test, y_pre)}') # MSE: 均方误差, 公式: 每个样本的误差平方和 / 样本总数
print(f'均方根误差为: {root_mean_squared_error(y_test, y_pre)}') # RMSE: 均方根误差, 公式: 每个样本的误差平方和 / 样本总数, 开平方根
print(f'平均绝对误差为: {mean_absolute_error(y_test, y_pre)}') # MAE: 平均绝对误差, 公式: 每个样本的误差 绝对值和 / 样本总数
房价预测之随机梯度下降
案例: 演示 随机梯度下降法 线性回归对象 完成 波士顿房价预测案例. 回顾: 线性回归算法 属于 有监督学习之 有特征, 有标签, 且标签是连续的. 线性回归分类: 一元线性回归: 1个特征列, 1个标签列. 多元线性回归: 多个特征列, 1个标签列. 线性回归大白话解释: 它是用线性公式来描述 特征 和 标签之间关系的, 方便做预测, 公式如下: 一元线性回归: y = w * x + b 多元线性回归: y = w1 * x1 + w2 * x2 + w3 * x3 + ... + wn * xn + b = w的转置 * x + b 如何衡量线性回归模型的好坏? 思路: 预测值和真实值之间的误差, 误差越小, 模型越好 => 损失函数 具体的方案: 1. 最小二乘. 每个(样本)误差平方和 2. 均方误差(MSE) 每个(样本)误差平方和 / 样本总数 3. 均方根误差(RMSE) 每个(样本)误差平方和 / 样本总数 的 平方根 4. 平均绝对误差(MAE) 每个(样本)误差绝对值和 / 样本总数 如何让损失函数最小? 思路1: 梯度下降法. => 全梯度下降(Full Gradient Descent, FGD), 随机梯度下降(SGD), 小批量梯度下降(推荐, Min-Batch), 随机平均梯度下降(SAG) 思路2: 正规方程法. 机器学习开发流程: 1. 加载数据. 2. 数据的预处理. 3. 特征工程(特征提取, 特征预处理...) 4. 模型训练. 5. 模型预测. 6. 模型评估
python
"""
案例:
演示 随机梯度下降法 线性回归对象 完成 波士顿房价预测案例.
回顾:
线性回归算法 属于 有监督学习之 有特征, 有标签, 且标签是连续的.
线性回归分类:
一元线性回归: 1个特征列, 1个标签列.
多元线性回归: 多个特征列, 1个标签列.
线性回归大白话解释:
它是用线性公式来描述 特征 和 标签之间关系的, 方便做预测, 公式如下:
一元线性回归: y = w * x + b
多元线性回归: y = w1 * x1 + w2 * x2 + w3 * x3 + ... + wn * xn + b = w的转置 * x + b
如何衡量线性回归模型的好坏?
思路:
预测值和真实值之间的误差, 误差越小, 模型越好 => 损失函数
具体的方案:
1. 最小二乘. 每个(样本)误差平方和
2. 均方误差(MSE) 每个(样本)误差平方和 / 样本总数
3. 均方根误差(RMSE) 每个(样本)误差平方和 / 样本总数 的 平方根
4. 平均绝对误差(MAE) 每个(样本)误差绝对值和 / 样本总数
如何让损失函数最小?
思路1: 梯度下降法. => 全梯度下降(Full Gradient Descent, FGD), 随机梯度下降(SGD), 小批量梯度下降(推荐, Min-Batch), 随机平均梯度下降(SAG)
思路2: 正规方程法.
机器学习开发流程:
1. 加载数据.
2. 数据的预处理.
3. 特征工程(特征提取, 特征预处理...)
4. 模型训练.
5. 模型预测.
6. 模型评估
"""
# 导包
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, root_mean_squared_error, mean_absolute_error # 均方误差评估, RMSE, MAE
from sklearn.linear_model import Ridge, RidgeCV
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]]) # hstack()函数作用: 水平拼接数组
target = raw_df.values[1::2, 2]
# print(f'特征: {data.shape}') # (506, 13)
# print(f'标签: {target.shape}') # (506,)
#
# print(f'特征数据: {data[:5]}')
# print(f'标签数据: {target[:5]}')
# 2. 数据的预处理. 按照8:2 切分 训练集和测试集.
x_train, x_test, y_train, y_test = train_test_split(data, target, test_size=0.2, random_state=23)
# 3. 特征工程(特征提取, 特征预处理...)
# 3.1 创建 标准化对象.
transfer = StandardScaler()
# 3.2 对训练集和测试集进行标准化处理.
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
# 4. 模型训练.
# estimator = LinearRegression(fit_intercept=True) # 正规方程法 线性回归对象.
# 4.1 创建 梯度下降 线性回归 模型对象.
# 参1: fit_intercept: 是否计算截距.
# 参2: learning_rate: 学习率模式 -> 常量, 即: 不会发生改变.
# 参3: eta0: 学习率.
estimator = SGDRegressor(fit_intercept=True, learning_rate='constant', eta0=0.01)
# 4.2 模型训练.
estimator.fit(x_train, y_train)
# 4.3 打印 权重 和 偏置.
print(f'权重: {estimator.coef_}')
print(f'偏置: {estimator.intercept_}')
# 5. 模型预测.
y_pre = estimator.predict(x_test)
# 6. 模型评估
# MSE: 均方误差, 每个误差的平方和 / 样本总数
print(f'均方误差: {mean_squared_error(y_test, y_pre)}') # 参1: 测试集的真实标签, 参2: 测试集的预测标签
# RMSE: 均方根误差, 均方误差的平方根
print(f'均方根误差: {root_mean_squared_error(y_test, y_pre)}') # 参1: 测试集的真实标签, 参2: 测试集的预测标签
# MAE: 平均绝对误差, 每个误差绝对值和 / 样本总数
print(f'平均绝对误差: {mean_absolute_error(y_test, y_pre)}') # 参1: 测试集的真实标签, 参2: 测试集的预测标签
L1和L2正则化解决过拟合问题
案例: 演示 欠拟合, 正好拟合, 过拟合, L1正则化, L2正则化的 效果图. 回顾: 欠拟合: 模型在训练集 和 测试集表现效果都不好. 正好拟合: 模型在训练集 和 测试集表现效果都好. 过拟合: 模型在训练集表现好, 测试集表现不好. 过拟合, 欠拟合解释: 产生原因: 欠拟合: 模型简单. 过拟合: 模型复杂. 解决方案: 欠拟合: 增加特征, 从而增加 模型的复杂度. 过拟合: 减少模型复杂度, 手动筛选(减少)特征, L1和L2正则化. L1和L2正则化介绍: 目的/思路: 都是基于 惩罚系数 来修改(特征列的)权重的, 惩罚系数越大, 则修改力度就越大, 对应的权重就越小. 区别: L1正则化, 可以实现让权重变为0, 从而达到 特征选择的目的. L2正则化, 只能让权重无限趋近于0, 但是不能为0. 大白话: 我要去爬山, 带了个小包, 装了: 登山杖, 水, 面包, 衣服, 雨伞, 鞋子... 发现包装不下了. L1正则化: 可以实现去掉一些不是必选的, 例如: 当天去, 当前回, 且天气晴朗 -> 不带雨伞, 鞋子, 即: 权重为0 L2正则化: 换一个非常非常大的包, 还是那些物品, 但是空间占用(权重)就变小了...
python
"""
案例:
演示 欠拟合, 正好拟合, 过拟合, L1正则化, L2正则化的 效果图.
回顾:
欠拟合: 模型在训练集 和 测试集表现效果都不好.
正好拟合: 模型在训练集 和 测试集表现效果都好.
过拟合: 模型在训练集表现好, 测试集表现不好.
过拟合, 欠拟合解释:
产生原因:
欠拟合: 模型简单.
过拟合: 模型复杂.
解决方案:
欠拟合: 增加特征, 从而增加 模型的复杂度.
过拟合: 减少模型复杂度, 手动筛选(减少)特征, L1和L2正则化.
L1和L2正则化介绍:
目的/思路:
都是基于 惩罚系数 来修改(特征列的)权重的, 惩罚系数越大, 则修改力度就越大, 对应的权重就越小.
区别:
L1正则化, 可以实现让权重变为0, 从而达到 特征选择的目的.
L2正则化, 只能让权重无限趋近于0, 但是不能为0.
大白话:
我要去爬山, 带了个小包, 装了: 登山杖, 水, 面包, 衣服, 雨伞, 鞋子... 发现包装不下了.
L1正则化: 可以实现去掉一些不是必选的, 例如: 当天去, 当前回, 且天气晴朗 -> 不带雨伞, 鞋子, 即: 权重为0
L2正则化: 换一个非常非常大的包, 还是那些物品, 但是空间占用(权重)就变小了...
"""
# 导包
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression # 正规方程的回归模型
from sklearn.metrics import mean_squared_error, root_mean_squared_error, mean_absolute_error # 均方误差评估, RMSE, MAE
from sklearn.linear_model import Lasso, Ridge # L1正则化, L2正则化
# 1. 定义函数, 模拟: 欠拟合.
def dm01_under_fitting():
# 1. 准备数据.
# 1.1 指定随机种子, 则每次生成(噪声)的数据都是固定的.
np.random.seed(23)
# 1.2 随机生成x轴 100个数据, 模拟: 特征.
x = np.random.uniform(-3, 3, 100) # 参1: 最小值, 参2: 最大值, 参3: 生成个数
# 1.3 基于x轴值, 通过线性公式, 生成y轴 100个数据, 模拟: 标签.
# 线性公式: y = kx + b = 0.5 * x ** 2 + x + 2 + 噪声
y = 0.5 * x ** 2 + x + 2 + np.random.normal(0, 1, 100) # 参1: 平均值, 参2: 标准差, 参3: 生成个数
# 1.4 查看生成的 x轴(特征) 和 y轴(标签)的数据.
print(f'特征(x): {x[:5]}') # [1, 2, 3, 4, 5]
print(f'标签(y): {y[:5]}')
# 2. 数据预处理, 把x轴(特征)转成 多行1列的形式.
X = x.reshape(-1, 1)
print(f'处理后的特征: {X[:5]}') # [[1], [2], [3], [4], [5]]
# 3. 特征工程, 这里不做了, 直接用100条数据, 先训练, 后预测.
# 4. 模型训练.
# 4.1 创建模型对象.
estimator = LinearRegression() # 正规方程 线性回归模型.
# 4.2 模型训练.
estimator.fit(X, y) # 参1: 处理后的特征数据. 参2: 标签数据.
# 5. 模型预测.
y_predict = estimator.predict(X) # 处理后的特征数据
# 6. 模型评估.
print(f'均方误差: {mean_squared_error(y, y_predict)}') # 参1: 真实值, 参2: 预测值.
# 7. 绘图.
plt.scatter(x, y) # 以散点图的形式绘制 真实值.
plt.plot(x, y_predict, color='red') # 以线图的形式绘制 预测值.
plt.show()
# 2. 定义函数, 模拟: 正好拟合.
def dm02_just_fitting():
# 1. 准备数据.
# 1.1 指定随机种子, 则每次生成(噪声)的数据都是固定的.
np.random.seed(23)
# 1.2 随机生成x轴 100个数据, 模拟: 特征.
x = np.random.uniform(-3, 3, 100) # 参1: 最小值, 参2: 最大值, 参3: 生成个数
# 1.3 基于x轴值, 通过线性公式, 生成y轴 100个数据, 模拟: 标签.
# 线性公式: y = kx + b = 0.5 * x ** 2 + x + 2 + 噪声
y = 0.5 * x ** 2 + x + 2 + np.random.normal(0, 1, 100) # 参1: 平均值, 参2: 标准差, 参3: 生成个数
# 1.4 查看生成的 x轴(特征) 和 y轴(标签)的数据.
print(f'特征(x): {x[:5]}') # [1, 2, 3, 4, 5]
print(f'标签(y): {y[:5]}')
# 2. 数据预处理, 把x轴(特征)转成 多行1列的形式.
# 2.1 把上述的x轴(特征)转成 多行1列的形式, 即: [[1], [2], [3], [4], [5]]
X = x.reshape(-1, 1)
print(f'处理后的特征: {X[:5]}') # [[1], [2], [3], [4], [5]]
# 2.2 因为目前特征列只有1列, 模型过于简单, 会出现欠拟合的问题, 我们增加1列 特征列, 从而增加模型的复杂度.
# 即: 把数据从 [[1], [2], [3], [4], [5]] => [[1, 1], [2, 4], [3, 9], [4, 16], [5, 25]]
X2 = np.hstack([X, X ** 2]) # 该函数作用: 横向拼接, 即: 拼接2个数组, 拼接后数组的行数不变, 拼接后数组的列数等于拼接前数组的列数之和.
print(f'处理后的特征: {X2[:5]}')
# 3. 特征工程, 这里不做了, 直接用100条数据, 先训练, 后预测.
# 4. 模型训练.
# 4.1 创建模型对象.
estimator = LinearRegression() # 正规方程 线性回归模型.
# 4.2 模型训练.
estimator.fit(X2, y) # 参1: 处理后的特征数据. 参2: 标签数据.
# 5. 模型预测.
y_predict = estimator.predict(X2) # 处理后的特征数据
# 6. 模型评估.
print(f'均方误差: {mean_squared_error(y, y_predict)}') # 参1: 真实值, 参2: 预测值.
# 7. 绘图.
plt.scatter(x, y) # 以散点图的形式绘制 真实值.
# np.sort(x): 对x轴(特征)排序, 默认是: 升序.
# np.argsort(x): 对x轴(特征)排序, 返回排序后的索引.
# 例如: 排序前x轴是 [11, 33, 22] -> 对应索引: [0, 1, 2]
# 排序后: x轴是 [11, 22, 33] -> 对应索引: [0, 2, 1]
plt.plot(np.sort(x), y_predict[np.argsort(x)], color='red') # 以线图的形式绘制 预测值.
plt.show()
# 3. 定义函数, 模拟: 过拟合.
def dm03_over_fitting():
# 1. 准备数据.
# 1.1 指定随机种子, 则每次生成(噪声)的数据都是固定的.
np.random.seed(23)
# 1.2 随机生成x轴 100个数据, 模拟: 特征.
x = np.random.uniform(-3, 3, 100) # 参1: 最小值, 参2: 最大值, 参3: 生成个数
# 1.3 基于x轴值, 通过线性公式, 生成y轴 100个数据, 模拟: 标签.
# 线性公式: y = kx + b = 0.5 * x ** 2 + x + 2 + 噪声
y = 0.5 * x ** 2 + x + 2 + np.random.normal(0, 1, 100) # 参1: 平均值, 参2: 标准差, 参3: 生成个数
# 1.4 查看生成的 x轴(特征) 和 y轴(标签)的数据.
print(f'特征(x): {x[:5]}') # [1, 2, 3, 4, 5]
print(f'标签(y): {y[:5]}')
# 2. 数据预处理, 把x轴(特征)转成 多行1列的形式.
# 2.1 把上述的x轴(特征)转成 多行1列的形式, 即: [[1], [2], [3], [4], [5]]
X = x.reshape(-1, 1)
print(f'处理后的特征: {X[:5]}') # [[1], [2], [3], [4], [5]]
# 2.2 因为目前特征列只有1列, 模型过于简单, 为了模拟过拟合, 我们增加9列 特征列, 从而增加模型的复杂度.
# 即: 把数据从 [[1], [2], [3], [4], [5]] => [[1, 1**2, 1**3, 1**4, 1**5...], [2, 2**2, 2**3, 2**4, 2**5], [3...]...]
# 该函数作用: 横向拼接, 即: 拼接多个数组, 拼接后数组的行数不变, 拼接后数组的列数等于拼接前数组的列数之和.
X3 = np.hstack([X, X ** 2, X ** 3, X ** 4, X ** 5, X ** 6, X ** 7, X ** 8, X ** 9, X ** 10])
print(f'处理后的特征: {X3[:5]}')
# 3. 特征工程, 这里不做了, 直接用100条数据, 先训练, 后预测.
# 4. 模型训练.
# 4.1 创建模型对象.
estimator = LinearRegression() # 正规方程 线性回归模型.
# 4.2 模型训练.
estimator.fit(X3, y) # 参1: 处理后的特征数据. 参2: 标签数据.
# 5. 模型预测.
y_predict = estimator.predict(X3) # 处理后的特征数据
# 6. 模型评估.
print(f'均方误差: {mean_squared_error(y, y_predict)}') # 参1: 真实值, 参2: 预测值.
# 7. 绘图.
plt.scatter(x, y) # 以散点图的形式绘制 真实值.
# np.sort(x): 对x轴(特征)排序, 默认是: 升序.
# np.argsort(x): 对x轴(特征)排序, 返回排序后的索引.
# 例如: 排序前x轴是 [11, 33, 22] -> 对应索引: [0, 1, 2]
# 排序后: x轴是 [11, 22, 33] -> 对应索引: [0, 2, 1]
plt.plot(np.sort(x), y_predict[np.argsort(x)], color='red') # 以线图的形式绘制 预测值.
plt.show()
# 4. 定义函数, 模拟: L1正则化.
def dm04_l1_regularization():
# 1. 准备数据.
# 1.1 指定随机种子, 则每次生成(噪声)的数据都是固定的.
np.random.seed(23)
# 1.2 随机生成x轴 100个数据, 模拟: 特征.
x = np.random.uniform(-3, 3, 100) # 参1: 最小值, 参2: 最大值, 参3: 生成个数
# 1.3 基于x轴值, 通过线性公式, 生成y轴 100个数据, 模拟: 标签.
# 线性公式: y = kx + b = 0.5 * x ** 2 + x + 2 + 噪声
y = 0.5 * x ** 2 + x + 2 + np.random.normal(0, 1, 100) # 参1: 平均值, 参2: 标准差, 参3: 生成个数
# 1.4 查看生成的 x轴(特征) 和 y轴(标签)的数据.
print(f'特征(x): {x[:5]}') # [1, 2, 3, 4, 5]
print(f'标签(y): {y[:5]}')
# 2. 数据预处理, 把x轴(特征)转成 多行1列的形式.
# 2.1 把上述的x轴(特征)转成 多行1列的形式, 即: [[1], [2], [3], [4], [5]]
X = x.reshape(-1, 1)
print(f'处理后的特征: {X[:5]}') # [[1], [2], [3], [4], [5]]
# 2.2 因为目前特征列只有1列, 模型过于简单, 为了模拟过拟合, 我们增加9列 特征列, 从而增加模型的复杂度.
# 即: 把数据从 [[1], [2], [3], [4], [5]] => [[1, 1**2, 1**3, 1**4, 1**5...], [2, 2**2, 2**3, 2**4, 2**5], [3...]...]
# 该函数作用: 横向拼接, 即: 拼接多个数组, 拼接后数组的行数不变, 拼接后数组的列数等于拼接前数组的列数之和.
X3 = np.hstack([X, X ** 2, X ** 3, X ** 4, X ** 5, X ** 6, X ** 7, X ** 8, X ** 9, X ** 10])
print(f'处理后的特征: {X3[:5]}')
# 3. 特征工程, 这里不做了, 直接用100条数据, 先训练, 后预测.
# 4. 模型训练.
# 4.1 创建模型对象.
# estimator = LinearRegression() # 正规方程 线性回归模型.
# 改为创建 L1正则化对象.
estimator = Lasso(alpha=0.1) # alpha: 正则化系数(惩罚系数), 默认是: 1.
# 4.2 模型训练.
estimator.fit(X3, y) # 参1: 处理后的特征数据. 参2: 标签数据.
# 5. 模型预测.
y_predict = estimator.predict(X3) # 处理后的特征数据
# 6. 模型评估.
print(f'均方误差: {mean_squared_error(y, y_predict)}') # 参1: 真实值, 参2: 预测值.
# 7. 绘图.
plt.scatter(x, y) # 以散点图的形式绘制 真实值.
# np.sort(x): 对x轴(特征)排序, 默认是: 升序.
# np.argsort(x): 对x轴(特征)排序, 返回排序后的索引.
# 例如: 排序前x轴是 [11, 33, 22] -> 对应索引: [0, 1, 2]
# 排序后: x轴是 [11, 22, 33] -> 对应索引: [0, 2, 1]
plt.plot(np.sort(x), y_predict[np.argsort(x)], color='red') # 以线图的形式绘制 预测值.
plt.show()
# 5. 定义函数, 模拟: L2正则化.
def dm05_l2_regularization():
# 1. 准备数据.
# 1.1 指定随机种子, 则每次生成(噪声)的数据都是固定的.
np.random.seed(23)
# 1.2 随机生成x轴 100个数据, 模拟: 特征.
x = np.random.uniform(-3, 3, 100) # 参1: 最小值, 参2: 最大值, 参3: 生成个数
# 1.3 基于x轴值, 通过线性公式, 生成y轴 100个数据, 模拟: 标签.
# 线性公式: y = kx + b = 0.5 * x ** 2 + x + 2 + 噪声
y = 0.5 * x ** 2 + x + 2 + np.random.normal(0, 1, 100) # 参1: 平均值, 参2: 标准差, 参3: 生成个数
# 1.4 查看生成的 x轴(特征) 和 y轴(标签)的数据.
print(f'特征(x): {x[:5]}') # [1, 2, 3, 4, 5]
print(f'标签(y): {y[:5]}')
# 2. 数据预处理, 把x轴(特征)转成 多行1列的形式.
# 2.1 把上述的x轴(特征)转成 多行1列的形式, 即: [[1], [2], [3], [4], [5]]
X = x.reshape(-1, 1)
print(f'处理后的特征: {X[:5]}') # [[1], [2], [3], [4], [5]]
# 2.2 因为目前特征列只有1列, 模型过于简单, 为了模拟过拟合, 我们增加9列 特征列, 从而增加模型的复杂度.
# 即: 把数据从 [[1], [2], [3], [4], [5]] => [[1, 1**2, 1**3, 1**4, 1**5...], [2, 2**2, 2**3, 2**4, 2**5], [3...]...]
# 该函数作用: 横向拼接, 即: 拼接多个数组, 拼接后数组的行数不变, 拼接后数组的列数等于拼接前数组的列数之和.
X3 = np.hstack([X, X ** 2, X ** 3, X ** 4, X ** 5, X ** 6, X ** 7, X ** 8, X ** 9, X ** 10])
print(f'处理后的特征: {X3[:5]}')
# 3. 特征工程, 这里不做了, 直接用100条数据, 先训练, 后预测.
# 4. 模型训练.
# 4.1 创建模型对象.
# estimator = LinearRegression() # 正规方程 线性回归模型.
# 改为创建 L1正则化对象.
# estimator = Lasso(alpha=0.1) # alpha: 正则化系数(惩罚系数), 默认是: 1.
# 改为创建 L2正则化对象.
estimator = Ridge(alpha=10)
# 4.2 模型训练.
estimator.fit(X3, y) # 参1: 处理后的特征数据. 参2: 标签数据.
# 5. 模型预测.
y_predict = estimator.predict(X3) # 处理后的特征数据
# 6. 模型评估.
print(f'均方误差: {mean_squared_error(y, y_predict)}') # 参1: 真实值, 参2: 预测值.
# 7. 绘图.
plt.scatter(x, y) # 以散点图的形式绘制 真实值.
# np.sort(x): 对x轴(特征)排序, 默认是: 升序.
# np.argsort(x): 对x轴(特征)排序, 返回排序后的索引.
# 例如: 排序前x轴是 [11, 33, 22] -> 对应索引: [0, 1, 2]
# 排序后: x轴是 [11, 22, 33] -> 对应索引: [0, 2, 1]
plt.plot(np.sort(x), y_predict[np.argsort(x)], color='red') # 以线图的形式绘制 预测值.
plt.show()
# 6. 测试
if __name__ == '__main__':
# dm01_under_fitting()
# dm02_just_fitting()
# dm03_over_fitting()
# dm04_l1_regularization()
dm05_l2_regularization()