机器学习基础学习-多元线性回归问题(数学解实现)

1、基本概念

之前的简单线性回归针对的是样本只有一个特征值的情况,当我们的样本中包含了多个特征值的时候,我们就引入了多元线性回归的问题。


在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
我们数据有多个特征、有多少个维度,相应的每一个特征前都有一个系数,这里用theta0、1、2来表示,与此同时,整个直线有个截距,我们先用theta0来表示,这里的theta0相当于之前简单线性回归的b,theta1表示之前的系数a(或者w),在多元线性回归中,相应我们要求n+1个参数,这里就用theta0-n来表示(上面第一张图片的w)
在这里插入图片描述
这里其实和简单线性回归很类似,区别只是由一个特征拓展到了现在有n个特征,所以求解思路其实和简单线性回归一致
在这里插入图片描述
把theta0-n的值,整理成一个向量,我们用列向量的形式表示
在这里插入图片描述
为了使表达式一致,我们在第一项theta0后面也乘上了一个值X0i(本身没有这个X0i这一个特征,为了式子在推导中更方便,虚构了一个X0i横等于1)
在这里插入图片描述
注意这里的Xi是个行向量,这个X是一个矩阵,每一行代表一个样本,每一列代表一个特征,Xi代表从X这个矩阵当中抽出一行。
最后我们可以把第i行的样本预测值简单的表示出来
在这里插入图片描述
进而我们把式子进行推广,推广到所有的样本上
在这里插入图片描述

在这个版本中,将X表示为有m行,n列的矩阵。
Xb表示为有m行,n+1列的矩阵(多了一列第一列恒等于1的一列)

这里的y_hat是一个向量(列向量,一共有m个元素,每个元素对应的是原来的X中经过theta后,得到的预测值),这个向量就是使用多元线性回归当中,根据theta这个参数对每一个样本进行预测的结果。
在这里插入图片描述
这里的推导过程就不多说了,对损失函数求导使其等于0,得到theta的值,这里直接展示推导的结果
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
画个小重点,在上面的所有概念说完之后,总结一下一个theta
在这里插入图片描述
对于样本来说,我们一共有n个维度,theta0相当于是截距(之前我们理解的b,theta1-n是对应原来样本特征Xi的系数)

2、代码实现

这里的解决多元线性回归的问题也能解决一元线性回归的问题。
(1)X_b
在这里插入图片描述

# np.hstack():在水平方向上平铺,就是在横向上多加一列
# np.ones(矩阵大小, 列数)是增加一列恒为1的一列
X_b = np.hstack([np.ones((len(X_train), 1)), X_train])

(2)theta
在这里插入图片描述

# X_b.T是X_b的转置,.dot是点乘,np.linalg.inv是求逆
 self._theta = np.linalg.inv(X_b.T.dot(X_b)).dot(X_b.T).dot(y_train)

(3)系数和截距

self.interception_ = self._theta[0] # 截距
self.coef_ = self._theta[1:] # 系数

(4)预测结果
在这里插入图片描述

  # 预测过程
  def predict(self, X_predict):
    # 给定待预测数据集X_predict,返回表示X_predict的结果向量
    X_b = np.hstack([np.ones((len(X_predict), 1)), X_predict])
    return X_b.dot(self._theta)

(5)精确度计算

  '''
    确定精度,评价多元线性回归的结果
  '''
  def score(self, X_test, y_test):
    # 根据测试数据集X_test 和y_test 确定当前模型的准确度
    y_predict = self.predict(X_test)
    return r2_score(y_test, y_predict) # r2_score求真值y_test和预测值y_predict的r方

(6)总体代码

# 多元线性回归问题;解析解+梯度下降法(也能解决一元线性回归问题)
import numpy as np
from sklearn import datasets
from sklearn.metrics import r2_score
from sklearn.model_selection import train_test_split

class LinearRegression:
  def __init__(self):
      # 初始化Linear Regression模型
      self.coef_ = None # 系数,对应theta1-n,对应的向量
      self.interception_ = None # 截距,对应theta0
      self._theta = None # 定义私有变量,整体计算的theta


  '''
    解析解
  '''
  # 正规化方程
  # 训练过程(解析解)
  def fit_normal(self, X_train, y_train): # X_train和y_train都是矩阵
    # 根据训练数据集X_train, y_ .train训练Linear Regression模型
    # X_train的样本数量和y_train的标记数量应该是一致的
    # 使用shape[0]读取矩阵第一维度的长度,在这里就是列数
    assert X_train.shape[0] == y_train.shape[0], \
    "the size of x_ .train must be equal to the size of y_ train"
    # np.hstack():在水平方向上平铺,就是在横向上多加一列
    # np.ones(矩阵大小, 列数)是增加一列恒为1的一列
    # 得到X_b
    X_b = np.hstack([np.ones((len(X_train), 1)), X_train])
    # X_b.T是X_b的转置,.dot是点乘,np.linalg.inv是求逆
    self._theta = np.linalg.inv(X_b.T.dot(X_b)).dot(X_b.T).dot(y_train)

    self.interception_ = self._theta[0] # 截距
    self.coef_ = self._theta[1:] # 系数
    return self
  
  '''
    预测过程
  '''
  def predict(self, X_predict):
    # 给定待预测数据集X_predict,返回表示X_predict的结果向量
    X_b = np.hstack([np.ones((len(X_predict), 1)), X_predict])
    return X_b.dot(self._theta)

  '''
    确定精度,评价多元线性回归的结果
  '''
  def score(self, X_test, y_test):
    # 根据测试数据集X_test 和y_test 确定当前模型的准确度
    y_predict = self.predict(X_test)
    return r2_score(y_test, y_predict) # r2_score求真值y_test和预测值y_predict的r方

  '''
    显示属性
  '''
  def __repr__(self):
      return "LinearRegression()"


# 加载波士顿房价数据集,并划分为X_train,y_train
# 波士顿房价
boston = datasets.load_boston()

# X_train = boston.data
# y_train = boston.target

X = boston.data
y = boston.target

X = X[y < 50.0]
y = y[y < 50.0]
# 分出测试集合训练集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25)

'''
  实例化(数学解解法)
'''
reg = LinearRegression()
# 进行训练
reg.fit_normal(X_train, y_train) # LinearRegression()
# 预测r方值
print('预测精确度', reg.score(X_test, y_test))
# 截距
print('数学解系数reg.coef_', reg.coef_)
print('数学解截距reg.interception_', reg.interception_)
print('数学解预测值', reg.predict(X_test))
print('y_test测试值', y_test)



这里用到了sklearn的Boston波士顿房价数据集,简介可以参考波士顿房价数据集

对数据集进行训练后,可以得到我们需要的精确度、系数、截距。也可以对比我们的预测值和真实值

Guess you like

Origin blog.csdn.net/m0_47146037/article/details/120955457