01. 线性回归算法实例

1. 线性回归: 寻找一种能预测的趋势, 线性回归通过一个或者多个自变量(特征值)与因变量(目标值)之间进行建模的回归分析

1.1. 线性关系

  • 二维:直线关系
  • 三维:特征, 目标值, 平面当中

1.2. 线性关系定义

  • 单个特征

    • y = kx + b 加b是为了对于单个特征的情况更加通用
  • 多个特征

    • y = k1房子面积 + k2房子位置 + b

1.3. 线性模型

  • f(x) = w1 * x1 + w2 * x2 +... + wd * xd + b = wT * x, 其中w为权重, b称为偏置项, 可以理解为 w0 x 1,

2. 数组和矩阵的对比

2.1. 数组

  • 0维:5
  • 1维:[5,2,1]
  • 2维:[[5,2,1],[1,2,3]] [[5,2,1]]
  • 3维:[[[]]] [[[5,2,1]]]
  • 数组的运算 加法 乘法
  • 数组在numpy中以ndarray存在,在运算上可以理解为两者是一样的

2.2. 矩阵

  • 大多数算法计算的基础, 矩阵乘法必须是二维的
  • 矩阵乘法:满足了特定运算需求
    • (m行,l列)*(l行,n列)= (m行,n列)

2.3. 代码实现

import numpy as np

a = [[1,2,3,4],[5,6,7,8],[2,3,7,9]]
b = [2,2,2,2]
# 数组的乘法(广播机制)
np.multiply(a, b)
# 矩阵的乘法,必须是二维的
c = [[2],[2],[2],[2]]
np.dot(a, c)

3. 损失函数(误差大小)

3.1. 回归是一种迭代算法

3.2. 最小二乘法

  • yi为第i个训练样本的真实值
  • hw(xi)为第i个训练样本特征值组合预测函数
  • 总损失定义:
    J(θ) = (hw(x1) - y1)2 + (hw(x1) - y1)2 + … + (hw(xm) - ym)2, (尽量去减少这个损失)

3.3. 优化损失函数

  • 目的:

    • 通过迭代,找到模型中最优的w值,使得损失函数最小
  • 方法:

    • 正规方程(不做要求)

      • 缺点: 当特征过于复杂, 求解速度太慢,对于复杂的算法, 不能使用正规方程求解(逻辑回归等)
      • 一次运算得出, 小数据集可以使用(<10000)
      • 不能解决拟合问题
    • 梯度下降(重要)

      • 理解: 沿着损失函数下降的方向找,就能够找到山谷的最低点, 然后更新w的值。 学习速率α需要手动指定
      • 使用:面对训练数据规模十分庞大的任务
      • 不断迭代
    • 回归系数coef_指的就是w

4. sklearn线性回归正规方程、梯度下降API

4.1. 正规方程

  • sklearn.linear_model.LinearRegression

4.2. 梯度下降

  • sklearn.liner_model.SRDRegressor

4.3. 波士顿房价数据案例分析流程

  • 波士顿地区房价数据获取
  • 波士顿地区房价数据分割
  • 训练与测试数据标准化处理
  • 使用最简单的线性回归模型LinearRegression和梯度下降估计SGDRegressor对房价进行预测

5. 回归行能评估

  • 均方误差(Mean Squared Error)
    • 公式:MES = ( (y1 - yx)^2 + (y2 - yx)^2 + ... + (ym - yx)^2 ) / m 注意: ym为预测值, yx为真实值
    • API:sklearn.metrics.mean_squared_error
      • mean_squared_error(y_true,y_pred)

        • 均方误差回归损失
        • y_true:真实值
        • y_pred:预测值
        • return:浮点数结果
      • 注意:真实值,预测值为标准化之前的值

6. 代码实现

from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression, SGDRegressor
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error

# 获取数据
lb = load_boston()

# 分割数据集到训练集和测试集
x_train,x_test, y_train, y_test = train_test_split(lb.data, lb.target, test_size=0.25)

# 进行标准化处理
std_x = StandardScaler()
x_train = std_x.fit_transform(x_train)
x_test = std_x.transform(x_test)

std_y = StandardScaler()
y_train = std_y.fit_transform(y_train.reshape(-1, 1))
y_test = std_y.transform(y_test.reshape(-1, 1))

# estimator预测
# 正规方程求解预测结果
lr = LinearRegression()
lr.fit(x_train, y_train)
print(lr.coef_)
# 预测测试集的房子价格
y_predict = std_y.inverse_transform(lr.predict(x_test))
print(y_predict)
print("正规方程的均方误差:", mean_squared_error(y_true=std_y.inverse_transform(y_test), y_pred=y_predict))

# 梯度下降求解预测结果
sgd = SGDRegressor()
sgd.fit(x_train, y_train.reshape(-1, ))
print(sgd.coef_)
# 预测测试集的房子价格
y_predict = std_y.inverse_transform(sgd.predict(x_test))
print(y_predict)

print("梯度下降的均方误差:", mean_squared_error(y_true=std_y.inverse_transform(y_test), y_pred=y_predict))

7. 过拟合和欠拟合

  • 过拟合

    • 一个假设在训练数据上能够获得比其他假设更好的拟合,但是在训练数据外的数据集上却不能很好地拟合数据,此时认为这个假设出现了过拟合的现象。(模型过于复杂)

      • 模型复杂的原因:数据的特征和目标值之间的关系不仅仅是线性关系
    • 原因:原始特征过多,存在一些嘈杂特征,模型过于复杂是因为模型尝试去兼顾各个测试数据点

    • 解决办法:

      • 进行特征选择,消除关联性大的特征(很难做)
      • 交叉验证(让所有数据都有过训练), 没有解决过拟合问题,能够检验
      • 正则化
        • 尽可能减小高次项特征的影响
  • 欠拟合

    • 一个假设在训练数据上不能获得更好的拟合,但是在训练数据外的数据集上也不能很好地拟合数据,此时认为这个假设出现了欠拟合的现象。(模型过于简单)
    • 原因: 学习到数据的特征过少
    • 解决办法:增加数据的特征数量

8. 带有正则化的线性回归-Ridge

  • 正则化:尽量减少高次项的影响

  • L2正则化:可以使得W的每个元素都很小,都接近于0

  • 优点:越小的参数说明模型越简单,越简单的模型则越不容易产生过拟合现象

  • 岭回归Ridge

    • sklearn.linear_model.Ridge(alpha=1.0)
      • 具有l2正则化的线性最小二乘法

      • alpha:正则化力度

      • coef_:回归系数

  • 代码实现

from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression, SGDRegressor, Ridge
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error

# 获取数据
lb = load_boston()

# 分割数据集到训练集和测试集
x_train,x_test, y_train, y_test = train_test_split(lb.data, lb.target, test_size=0.25)

# 进行标准化处理
std_x = StandardScaler()
x_train = std_x.fit_transform(x_train)
x_test = std_x.transform(x_test)

std_y = StandardScaler()
y_train = std_y.fit_transform(y_train.reshape(-1, 1))
y_test = std_y.transform(y_test.reshape(-1, 1))

# estimator预测
# 正规方程求解预测结果
lr = LinearRegression()
lr.fit(x_train, y_train)
print(lr.coef_)
# 预测测试集的房子价格
y_predict = std_y.inverse_transform(lr.predict(x_test))
print(y_predict)
print("正规方程的均方误差:", mean_squared_error(y_true=std_y.inverse_transform(y_test), y_pred=y_predict))

# 梯度下降求解预测结果
sgd = SGDRegressor()
sgd.fit(x_train, y_train.reshape(-1, ))
print(sgd.coef_)
# 预测测试集的房子价格
y_predict = std_y.inverse_transform(sgd.predict(x_test))
print(y_predict)

print("梯度下降的均方误差:", mean_squared_error(y_true=std_y.inverse_transform(y_test), y_pred=y_predict))

# 岭回归求解预测结果
rd = Ridge()
rd.fit(x_train, y_train.reshape(-1, ))
print(rd.coef_)
# 预测测试集的房子价格
y_predict = std_y.inverse_transform(rd.predict(x_test))
print(y_predict)

print("岭回归的均方误差:", mean_squared_error(y_true=std_y.inverse_transform(y_test), y_pred=y_predict))
  • 线性回归 LinearRegression与Ridge对比
    • 岭回归:回归得到的回归系数更符合实际,更可靠。另外,能让估计参数的波动范围变小,变的更稳定。在存在病态数据偏多的研究中有较大的实用价值。

9. 模型的保存于加载

  • 保存模型
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression, SGDRegressor, Ridge
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error
from sklearn.externals import joblib

# 获取数据
lb = load_boston()

# 分割数据集到训练集和测试集
x_train,x_test, y_train, y_test = train_test_split(lb.data, lb.target, test_size=0.25)

# 进行标准化处理
std_x = StandardScaler()
x_train = std_x.fit_transform(x_train)
x_test = std_x.transform(x_test)

std_y = StandardScaler()
y_train = std_y.fit_transform(y_train.reshape(-1, 1))
y_test = std_y.transform(y_test.reshape(-1, 1))

# 岭回归求解预测结果
rd = Ridge()
rd.fit(x_train, y_train.reshape(-1, ))
print(rd.coef_)
# 预测测试集的房子价格
y_predict = std_y.inverse_transform(rd.predict(x_test))
print(y_predict)

print("岭回归的均方误差:", mean_squared_error(y_true=std_y.inverse_transform(y_test), y_pred=y_predict))
# 保存模型
joblib.dump(rd, "./tmp/test.pkl")
  • 加载模型
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression, SGDRegressor, Ridge
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error
from sklearn.externals import joblib

# 获取数据
lb = load_boston()

# 分割数据集到训练集和测试集
x_train,x_test, y_train, y_test = train_test_split(lb.data, lb.target, test_size=0.25)

# 进行标准化处理
std_x = StandardScaler()
x_train = std_x.fit_transform(x_train)
x_test = std_x.transform(x_test)

std_y = StandardScaler()
y_train = std_y.fit_transform(y_train.reshape(-1, 1))
y_test = std_y.transform(y_test.reshape(-1, 1))

# 加载保存模型
model = joblib.load("./tmp/test.pkl")
model.fit(x_train, y_train.reshape(-1, ))
print(model.coef_)

# 预测测试集的房子价格
y_predict = std_y.inverse_transform(model.predict(x_test))
print(y_predict)

print("加载保存模型岭回归的均方误差:", mean_squared_error(y_true=std_y.inverse_transform(y_test), y_pred=y_predict))
  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值