机器学习之线性回归

线性回归

复制代码
线性回归介绍(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()
相关推荐
草莓熊Lotso1 小时前
Ext 系列文件系统核心:块、分区、inode 与块组结构详解
android·linux·c语言·开发语言·c++·人工智能·文件
LCG元1 小时前
电机控制进阶:STM32F303硬件比较器实现FOC算法解析
stm32·嵌入式硬件·算法
Katecat996631 小时前
番茄叶片病害识别与分类|基于solo_r50_fpn_3x_coco模型的深度学习应用
深度学习·数据挖掘
丰海洋1 小时前
Leetcode-hot100-136只出现一次的数字
算法·leetcode·职场和发展
编程小白_澄映1 小时前
《机器学习》——聚类
机器学习·支持向量机·聚类
有点心急10211 小时前
SQL 执行 MCP 工具开发(一)
人工智能·python·aigc
We་ct2 小时前
LeetCode 124. 二叉树中的最大路径和:刷题解析
前端·数据结构·算法·leetcode·typescript
清风与日月2 小时前
OpenCV 图像显示高级技巧和常见问题
人工智能·opencv·计算机视觉
摘星编程2 小时前
突破界限!多模态AI如何重塑人机交互的未来?
人工智能·人机交互