线性回归
-
线性回归的原理
一个结果可能是由几个原因共同导致的,将几个原因量化,认为这种影响是线性的,这就是线性回归。
举例:房子的价格可能受面积x1、位置x2的影响,那么认为房价y=a+θ1x1+θ2x2 -
线性回归损失函数、代价函数、目标函数
•损失函数(Loss Function):度量单样本预测的错误程度,损失函数值越小,模型就越好。
•代价函数(Cost Function):度量全部样本集的平均误差。
•目标函数(Object Function):代价函数和正则化函数,最终要优化的函数。
常用的损失函数包括:0-1损失函数、平方损失函数、绝对损失函数、对数损失函数等;常用的代价函数包括均方误差、均方根误差、平均绝对误差等。 -
线性回归的优化方法
·梯度下降法
·最小二乘法矩阵求解
·牛顿法
·拟牛顿法 -
线性回归的评价指标
·均方误差(MSE)
·均方根误差(RMSE)
·平均绝对误差(MAE)
但以上评价指标都无法消除量纲不一致而导致的误差值差别大的问题,最常用的指标是𝑅2。R2,可以避免量纲不一致问题
我们可以把𝑅 2 理解为,回归模型可以成功解释的数据方差部分在数据固有方差中所占的比例,𝑅 2 越接近1,表示可解释力度越大,模型拟合的效果越好。 -
sklearn.linear_model参数详解
fit_intercept : 默认为True,是否计算该模型的截距。如果使用中心化的数据,可以考虑设置为False,不考虑截距。注意这里是考虑,一般还是要考虑截距。
normalize: 默认为false. 当fit_intercept设置为false的时候,这个参数会被自动忽略。如果为True,回归器会标准化输入参数:减去平均值,并且除以相应的二范数。当然啦,在这里还是建议将标准化的工作放在训练模型之前。通过设置sklearn.preprocessing.StandardScaler来实现,而在此处设置为false。
copy_X : 默认为True, 否则X会被改写。
n_jobs: int 默认为1. 当-1时默认使用全部CPUs ??(这个参数有待尝试)
可用属性:
coef_:训练后的输入端模型系数,如果label有两个,即y值有两列。那么是一个2D的array
intercept_: 截距
可用的methods:
fit(X,y,sample_weight=None): X: array, 稀疏矩阵 [n_samples,n_features] y: array [n_samples, n_targets] sample_weight: 权重 array [n_samples] 在版本0.17后添加了sample_weight
get_params(deep=True): 返回对regressor 的设置值
predict(X): 预测 基于 R^2值
score: 评估 -
练习题:请用以下数据(可自行生成尝试,或用其他已有数据集)
1、首先尝试调用sklearn的线性回归函数进行训练;
2、用最小二乘法的矩阵求解法训练数据;
3、用梯度下降法训练数据;
4、比较各方法得出的结果是否一致。
# -*- coding: utf-8 -*-
"""
Created on Sun Apr 19 19:15:23 2020
@author: 一只腰鱼
"""
#生成数据
import numpy as np
from sklearn.linear_model import LinearRegression
import matplotlib.pyplot as plt
#先尝试调用sklearn的线性回归模型训练数据
#生成随机数
#原来每次运行代码时设置相同的seed,则每次生成的随机数也相同,如果不设置seed,则每次生成的随机数都会不一样。
np.random.seed(1234)
x = np.random.rand(500,3)
#构建映射关系,模拟真实的数据待预测值,映射关系为y = 4.2*x1 + 5.7*x2 + 10.8*x3,可自行设置值进行尝试
#y = 4.2+ x.dot(np.array([5.7,10.8]))
y = x.dot(np.array([4.2,5.7,10.8]))
'''
# 调用模型
lr = LinearRegression(fit_intercept=True)
#此处fit_intercept=True或者False都可,因为生成的函数没有截距,如果设成有截距,因为样本少,模型预测准确,会认为截距等于0
# 训练模型
lr.fit(x,y)
print("估计的参数值为:%s" %(lr.coef_))
# 计算R平方
print('R2:%s' %(lr.score(x,y)))
# 任意设定变量,预测目标值
x_test = np.array([2,4,5]).reshape(1,-1)
y_hat = lr.predict(x_test)
print("预测值为: %s" %(y_hat))
y_test = x_test.dot(np.array([4.2,5.7,10.8]))
print("实际值为: %s" %(y_test))
'''
'''
#最小二乘法的矩阵求解 𝜃=(𝑋 𝑇 𝑋) (−1) 𝑋 𝑇 𝑌
class LR_LS():
def __init__(self):
self.w = None
def fit(self, X, y):
# 最小二乘法矩阵求解
#============================= show me your code =======================
self.w = np.linalg.inv(X.T.dot(X)).dot(X.T).dot(y)
#============================= show me your code =======================
def predict(self, X):
# 用已经拟合的参数值预测新自变量
#============================= show me your code =======================
y_pred = X.dot(self.w)
#============================= show me your code =======================
return y_pred
if __name__ == "__main__":
lr_ls = LR_LS()
lr_ls.fit(x,y)
print("估计的参数值:%s" %(lr_ls.w))
x_test = np.array([2,4,5]).reshape(1,-1)
# y_test = 4.2 + x_test.dot(np.array([5.7,10.8]))
y_test = x_test.dot(np.array([4.2,5.7,10.8]))
print("预测值为: %s" %(lr_ls.predict(x_test)))
print("实际值为: %s" % y_test)
'''
'''
class LR_GD():
def __init__(self):
self.w = None
def fit(self,X,y,alpha=0.02,loss = 1e-10): # 设定步长为0.002,判断是否收敛的条件为1e-10
y = y.reshape(-1,1) #重塑y值的维度以便矩阵运算
[m,d] = np.shape(X) #自变量的维度
self.w = np.zeros((d)) #将参数的初始值定为0
tol = 1e5
#============================= show me your code =======================
while tol > loss:
h_f = X.dot(self.w).reshape(-1,1)
theta = self.w + alpha*np.mean(X*(y - h_f),axis=0) #计算迭代的参数值
tol = np.sum(np.abs(theta - self.w))
self.w = theta
#============================= show me your code =======================
def predict(self, X):
# 用已经拟合的参数值预测新自变量
y_pred = X.dot(self.w)
return y_pred
if __name__ == "__main__":
lr_gd = LR_GD()
lr_gd.fit(x,y)
print("估计的参数值为:%s" %(lr_gd.w))
x_test = np.array([2,4,5]).reshape(1,-1)
y_test = x_test.dot(np.array([4.2,5.7,10.8]))
print("预测值为:%s" %(lr_gd.predict(x_test)))
print("实际值为: %s" % y_test)
'''