自学内容网 自学内容网

python机器学习(线性回归_正则化处理)

"""
案例: 演示 线性回归 正则化处理.

解释:
    1. 欠拟合: 模型在训练集, 测试集上表现效果都不好.        模型过于简单了.
    2. 过拟合: 模型在训练集上表现较好, 在测试集上表现不好.   模型过于复杂了.
    3. 正好拟合(泛化程度较高): 模型在训练集, 测试集上表现效果都比较好.

细节: L1正则化, L2正则化区别
    相同点: 都可以降低模型的复杂度, 都可以解决: 过拟合问题.
    不同点:
        L1正则化会使得特征的权重变为0, 一般适用于: 特征选取.
        L2正则化会使得特征的权重趋向于0, 不会变为零. 可以解决 过拟合问题, 一般首选用 它.
"""

# 导包
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error # 计算均方误差
from sklearn.model_selection import train_test_split
from sklearn.linear_model import Ridge, Lasso
# 1. 定义函数, 表示: 欠拟合.
def dm01_欠拟合():
    # 1. 准备数据.
    # 准备噪声(可以简单理解为就是: 随机种子), 噪声相同, 每次生成的随机数(点)相同.
    np.random.seed(21)
    # x: 表示特征, -3 ~ 3之间 随机的小数, 生成: 100个.
    x = np.random.uniform(-3, 3, size=100)
    # y: 表示标签(目标值), 线性关系: 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)

    # 模型训练.
    # 2. 创建 线性回归-正规方程 模型对象.
    estimator = LinearRegression(fit_intercept=True)    # 计算: 偏置.
    # 3. 对数据集做处理.
    X = x.reshape(-1, 1)
    # print(f'处理前 x => {x}')      # 假设: x = [1, 2, 3]
    # print(f'处理后 X => {X}')      # 处理后: X = [[1], [2], [3]]
    # 4. 模型训练.
    estimator.fit(X, y)     # 这里传的是, 处理后的x的值, 即: 二维数组.
    # 5. 模型预测.
    y_predict = estimator.predict(X)
    print(f'预测值为: {y_predict}')
    # 6. 模型评估.
    print(f'均方误差: {mean_squared_error(y, y_predict)}')      # 2.0683653437315512
    # 7. 数据可视化, 绘制图像.
    plt.scatter(x, y)             # 基于: 原始的x(特征), y值(真实值)绘制 散点图.
    plt.plot(x, y_predict, c='r')  # 基于: 原值的x(特征), y值(预测值)绘制 折线图(就是我们的 拟合回归线)
    plt.show()

# 2. 定义函数, 表示: 正好拟合.
def dm02_正好拟合():
    # 1. 准备数据.
    # 准备噪声(可以简单理解为就是: 随机种子), 噪声相同, 每次生成的随机数(点)相同.
    np.random.seed(21)
    # x: 表示特征, -3 ~ 3之间 随机的小数, 生成: 100个.
    x = np.random.uniform(-3, 3, size=100)
    # y: 表示标签(目标值), 线性关系: 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)

    # 模型训练.
    # 2. 创建 线性回归-正规方程 模型对象.
    estimator = LinearRegression(fit_intercept=True)    # 计算: 偏置.
    # 3. 对数据集做处理.
    # 3.1 把数据从 一维数组 => 二维数组, 即: 从 [1, 2, 3] => [[1], [2], [3]]
    X = x.reshape(-1, 1)
    # 3.2 拼接: x 和 x的平方, 把数据从 [[1], [2], [3]] => [[1, 1], [2, 4], [3, 9]]   一元线性回归 => 二元线性回归
    X2 = np.hstack([X, X ** 2])   #
    print(f'处理前 x => {x}')      # 假设: x = [1, 2, 3]
    print(f'处理后 X => {X}')      # 处理后: X = [[1], [2], [3]]
    print(f'处理后 X2 => {X2}')    # 处理后: X = [[1], [2], [3]]

    # 4. 模型训练.
    estimator.fit(X2, y)     # 这里传的是, 处理后的x的值, 即: 二维数组 => 二元线性回归
    # 5. 模型预测.
    y_predict = estimator.predict(X2)
    print(f'预测值为: {y_predict}')
    # 6. 模型评估.
    print(f'均方误差: {mean_squared_error(y, y_predict)}')      # 均方误差: 1.0009503498374301
    # 7. 数据可视化, 绘制图像.
    plt.scatter(x, y)                    # 基于: 原始的x(特征), y值(真实值)绘制 散点图.

    # 细节: 要对x的值进行升序排列, 然后再绘制, 否则会出现: 散点没有连贯性.
    # plt.plot(x, y_predict, c='r')  # 基于: 原值的x(特征), y值(预测值)绘制 折线图(就是我们的 拟合回归线)
    # np.sort(x): 按照x的值 升序排列.
    # np.argsort(x): 按照x的值 升序排列, 返回(x对应的)索引值.
    plt.plot(np.sort(x), y_predict[np.argsort(x)], c='r')  # 基于: 原值的x(特征), y值(预测值)绘制 折线图(就是我们的 拟合回归线)
    plt.show()

# 3. 定义函数, 表示: 过拟合.
def dm03_过拟合():
    # 1. 准备数据.
    # 准备噪声(可以简单理解为就是: 随机种子), 噪声相同, 每次生成的随机数(点)相同.
    np.random.seed(21)
    # x: 表示特征, -3 ~ 3之间 随机的小数, 生成: 100个.
    x = np.random.uniform(-3, 3, size=100)
    # y: 表示标签(目标值), 线性关系: 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)

    # 模型训练.
    # 2. 创建 线性回归-正规方程 模型对象.
    estimator = LinearRegression(fit_intercept=True)    # 计算: 偏置.
    # 3. 对数据集做处理.
    # 3.1 把数据从 一维数组 => 二维数组, 即: 从 [1, 2, 3] => [[1], [2], [3]]
    X = x.reshape(-1, 1)
    # 3.2 拼接: x, x的平方, x的立方, x的四次方..., 把数据从 [[1], [2], [3]] => [[1, 1....], [2, 4, 8, 16, 32, 64...], [3, 9, 27...]]   一元线性回归 => 二元线性回归
    X3 = np.hstack([X, X ** 2, X ** 3, X ** 4, X ** 5, X ** 6, X ** 7, X ** 8, X ** 9, X ** 10])   # 继续增加 最高次项
    print(f'处理前 x => {x}')      # 假设: x = [1, 2, 3]
    print(f'处理后 X => {X}')      # 处理后: X = [[1], [2], [3]]
    print(f'处理后 X2 => {X3}')    # 处理后: X = [[1], [2], [3]]

    # 4. 模型训练.
    estimator.fit(X3, y)     # 这里传的是, 处理后的x的值, 即: 二维数组 => 多元线性回归
    # 5. 模型预测.
    y_predict = estimator.predict(X3)
    print(f'预测值为: {y_predict}')
    # 6. 模型评估.
    print(f'均方误差: {mean_squared_error(y, y_predict)}')      # 均方误差: 0.9646255969834893
    # 7. 数据可视化, 绘制图像.
    plt.scatter(x, y)                    # 基于: 原始的x(特征), y值(真实值)绘制 散点图.

    # 细节: 要对x的值进行升序排列, 然后再绘制, 否则会出现: 散点没有连贯性.
    # plt.plot(x, y_predict, c='r')  # 基于: 原值的x(特征), y值(预测值)绘制 折线图(就是我们的 拟合回归线)
    # np.sort(x): 按照x的值 升序排列.
    # np.argsort(x): 按照x的值 升序排列, 返回(x对应的)索引值.
    plt.plot(np.sort(x), y_predict[np.argsort(x)], c='r')  # 基于: 原值的x(特征), y值(预测值)绘制 折线图(就是我们的 拟合回归线)
    plt.show()

# 4. 定义函数, 表示: L1正则化 => 解决 过拟合问题的, 降低模型复杂度, 可能会使得权重变为0 => 特征选取.
def dm04_L1正则化():
    # 1. 准备数据.
    # 准备噪声(可以简单理解为就是: 随机种子), 噪声相同, 每次生成的随机数(点)相同.
    np.random.seed(21)
    # x: 表示特征, -3 ~ 3之间 随机的小数, 生成: 100个.
    x = np.random.uniform(-3, 3, size=100)
    # y: 表示标签(目标值), 线性关系: 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)

    # 模型训练.
    # 2. 创建 线性回归-正规方程 模型对象.
    # estimator = LinearRegression(fit_intercept=True)    # 计算: 偏置.
    # 2. 创建 线性回归-L1正则化 模型对象.
    estimator = Lasso(alpha=0.1)    # alpha: 正则化参数, 其值越大, 则正则化程度越高, 即: 权重值越小, 则越容易被截断为0.

    # 3. 对数据集做处理.
    # 3.1 把数据从 一维数组 => 二维数组, 即: 从 [1, 2, 3] => [[1], [2], [3]]
    X = x.reshape(-1, 1)
    # 3.2 拼接: x, x的平方, x的立方, x的四次方..., 把数据从 [[1], [2], [3]] => [[1, 1....], [2, 4, 8, 16, 32, 64...], [3, 9, 27...]]   一元线性回归 => 二元线性回归
    X3 = np.hstack([X, X ** 2, X ** 3, X ** 4, X ** 5, X ** 6, X ** 7, X ** 8, X ** 9, X ** 10])   # 继续增加 最高次项
    print(f'处理前 x => {x}')      # 假设: x = [1, 2, 3]
    print(f'处理后 X => {X}')      # 处理后: X = [[1], [2], [3]]
    print(f'处理后 X2 => {X3}')    # 处理后: X = [[1], [2], [3]]

    # 4. 模型训练.
    estimator.fit(X3, y)     # 这里传的是, 处理后的x的值, 即: 二维数组 => 多元线性回归
    # 5. 模型预测.
    y_predict = estimator.predict(X3)
    print(f'预测值为: {y_predict}')
    # 6. 模型评估.
    print(f'均方误差: {mean_squared_error(y, y_predict)}')      # 均方误差: 1.026270345364126
    # 7. 数据可视化, 绘制图像.
    plt.scatter(x, y)                    # 基于: 原始的x(特征), y值(真实值)绘制 散点图.

    # 细节: 要对x的值进行升序排列, 然后再绘制, 否则会出现: 散点没有连贯性.
    # plt.plot(x, y_predict, c='r')  # 基于: 原值的x(特征), y值(预测值)绘制 折线图(就是我们的 拟合回归线)
    # np.sort(x): 按照x的值 升序排列.
    # np.argsort(x): 按照x的值 升序排列, 返回(x对应的)索引值.
    plt.plot(np.sort(x), y_predict[np.argsort(x)], c='r')  # 基于: 原值的x(特征), y值(预测值)绘制 折线图(就是我们的 拟合回归线)
    plt.show()

# 5. 定义函数, 表示: L2正则化 => 解决 过拟合问题的, 降低模型复杂度. 会使得权重趋向于0, 不会变为0.
def dm05_L2正则化():
    # 1. 准备数据.
    # 准备噪声(可以简单理解为就是: 随机种子), 噪声相同, 每次生成的随机数(点)相同.
    np.random.seed(21)
    # x: 表示特征, -3 ~ 3之间 随机的小数, 生成: 100个.
    x = np.random.uniform(-3, 3, size=100)
    # y: 表示标签(目标值), 线性关系: 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)

    # 模型训练.
    # 2. 创建 线性回归-正规方程 模型对象.
    # estimator = LinearRegression(fit_intercept=True)    # 计算: 偏置.
    # 2. 创建 线性回归-L2正则化 模型对象.
    estimator = Ridge(alpha=0.1)    # alpha: 正则化参数, 其值越大, 则正则化程度越高, 即: 权重值越小, 则越容易被截断为0.

    # 3. 对数据集做处理.
    # 3.1 把数据从 一维数组 => 二维数组, 即: 从 [1, 2, 3] => [[1], [2], [3]]
    X = x.reshape(-1, 1)
    # 3.2 拼接: x, x的平方, x的立方, x的四次方..., 把数据从 [[1], [2], [3]] => [[1, 1....], [2, 4, 8, 16, 32, 64...], [3, 9, 27...]]   一元线性回归 => 二元线性回归
    X3 = np.hstack([X, X ** 2, X ** 3, X ** 4, X ** 5, X ** 6, X ** 7, X ** 8, X ** 9, X ** 10])   # 继续增加 最高次项
    print(f'处理前 x => {x}')      # 假设: x = [1, 2, 3]
    print(f'处理后 X => {X}')      # 处理后: X = [[1], [2], [3]]
    print(f'处理后 X2 => {X3}')    # 处理后: X = [[1], [2], [3]]

    # 4. 模型训练.
    estimator.fit(X3, y)     # 这里传的是, 处理后的x的值, 即: 二维数组 => 多元线性回归
    # 5. 模型预测.
    y_predict = estimator.predict(X3)
    print(f'预测值为: {y_predict}')
    # 6. 模型评估.
    print(f'均方误差: {mean_squared_error(y, y_predict)}')      # 均方误差: 0.964988964298911
    # 7. 数据可视化, 绘制图像.
    plt.scatter(x, y)                    # 基于: 原始的x(特征), y值(真实值)绘制 散点图.

    # 细节: 要对x的值进行升序排列, 然后再绘制, 否则会出现: 散点没有连贯性.
    # plt.plot(x, y_predict, c='r')  # 基于: 原值的x(特征), y值(预测值)绘制 折线图(就是我们的 拟合回归线)
    # np.sort(x): 按照x的值 升序排列.
    # np.argsort(x): 按照x的值 升序排列, 返回(x对应的)索引值.
    plt.plot(np.sort(x), y_predict[np.argsort(x)], c='r')  # 基于: 原值的x(特征), y值(预测值)绘制 折线图(就是我们的 拟合回归线)
    plt.show()

# 6. 在main函数中测试.
if __name__ == '__main__':
    # dm01_欠拟合()
    # dm02_正好拟合()
    # dm03_过拟合()
    # dm04_L1正则化()
    dm05_L2正则化()


原文地址:https://blog.csdn.net/weixin_43147086/article/details/142963357

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!