美文网首页
2020-08-17--线性回归02

2020-08-17--线性回归02

作者: program_white | 来源:发表于2020-08-19 23:08 被阅读0次

1.多元线性回归

一元线性回归和多元线性回归之间的区别简略的说就是因变量x的数量不同(影响因素)。

将其映射在数据中就是一个是一列的数据,一个是多列的数据。再精确一点可以理解为一个是类似于Series的数据,另一个是类似于DataFrame的数据。

例如:

我们之前的波士顿房价的影响因素就是多个影响因素,他的数据部分是多个列的,因为他是多个列的,所以不能直观的表达在坐标轴上。

1.多元线性回归公式推导

多元线性回归的表达式:y_head = a(0)+a(1)*x(1)+a(2)*x(2)+a(3)*x(3)+...+a(n)*x(n)

在这个表达式中:

  • x为影响y的因素,也就是数据中的列
  • a是每一列x与y之间的线性关系的一个模型参数
  • 与y = ax+b比较,a(0)就是b,a(1-n)就是a。

那么我们的目标还是使每个点的(真实值-预测值)^2 最小。
为什么使用^2,在本节开始已经说明。

用表达式表示出来:

接着我们要对y_head(i)这个公式做一个推导,使其向量化,更容易计算:

观察上式,像不像两个矩阵的点乘,所以

上式的y_head(i) = X(i) (.) @ 计算的是第i行的预测函数表达式,也就是坐标轴上的一个点,那么如果有m个点的话,就生成一个m*n的二维矩阵来表达。

最终将其转为矩阵Xb和矩阵@的点乘:

现在回到我们的损失函数表达式,我们将公式中【 y(i)-y_head(i) 】看作一个向量w,这个向量包含着每一行数据的误差值w(i),那么就可以将损失函数转为:

上式中第二行的公式计算结果为一个标量,分解开来就是W( * )W,但是W是一个向量,要计算其点乘的值,就必须转置后点乘,那么其点乘的结果用向量表示出来就可以转化为第三行的形式(W^T(*)W),这样的话计算出来就是一个标量值了

补充:(一个1xm的行向量乘以一个mx1的列向量等于一个数)

为什么表达式的结果为W(*)W,见下方推导:


最终:

这一步的推导我们之后再说。

2.矩阵求导基础知识

d:求导,citations(倒e):求偏导

1.标量/向量求导:

标量对行,列向量求导的相互转化:

(dy / dx)^T = dy / d(x^T)

向量对标量的求导同之前的原理类似,即向量的每个分量那个对标量一次求导,最后所得依然是与原向量同维的向量,此处不再赘述。

2.行向量/列向量求导

一个1 * m的行向量y^T,对 一个n * 1 的列向量x,求导,最终得到的是n * m阶的矩阵。

例如:

还有特殊情况就是:

1.自己的转置对自身求导的结果为单位矩阵I。

2.给向量点乘一个矩阵,进行转置后,对该向量求导,结果为矩阵的转置:

3.列向量/行向量求导

m * 1的列向量 对 1 * n的行向量求导,最终得到的是m * n阶的矩阵。

对比(4)(7)的式子,二者五位转置:

5.公式推导

1.公式1

x(向量)为n * 1的列向量,a(向量)为n * 1的列向量

其推导过程相当于分子为标量,分母为列向量,计算出来的结果。

上述的式子相当于y对每一个x求偏导后的结果,其结果就是n个a组成的a(向量)

2.公式2

B为n * n 的矩阵,x(向量)为n * 1的列向量

推导结果:

B矩阵的值为:

推导过程:
1.先计算分子,分子是一个标量,分子为三个矩阵向量点乘,先计算前两个,再点乘最后一个,最后计算结果为一个值。

2.这样就转化为标量对列向量求导了:

3.单纯只看其中一项进行分析:

  1. 那么整个值进行分解观察的话,就为:

括号括的值为Bt,圈起来的是B。将上式分解为向量和矩阵的点乘关系,便是出来就是结果了。

补充:向量/矩阵之间的加法计算为对应位置元素相加。

3.损失函数以及多元系数的公式确定

那么有了公式1,2,现在回到我们的损失函数中,这个w就是之前的citations。

所以对损失函数使用上述公式进行变换:

那么系数怎么确定呢,我们要损失函数最小,也就是说其对w求导时令其等于0时最小,所以:

那么多元线性回归公式的多元系我们就用向量x,y推导出来了。

4.多元线性回归实现

1.准备工作

那么我们求出来的w值是一个向量,因为我们时多元线性回归,w(0)是截距,其他是各个x的系数。

注意公式中的X(b)不是单纯的数据集,而是经过变换的数据集,在上边我们推到过:



每行的第一列数据都是1。
所以在计算w时,传进来的训练数据我们要先转换类似于X(b)的数据集。

我们在计算出w之后,进行测试时,要计算y_head,在之前我们也推导了y_head的向量化计算公式:

2.实现我们自己的 Linear Regression

类中方法:

  • fit_normal() : 训练模型,根据公式确定w的值,返回对象本身
  • perdict() : 根据w的值和y_head的计算公式,计算测试集的预测值y_head。
  • mean_squared_error() : 计算MSE
  • r2_score() : 计算R^2,也就是得分。
class LinearRegression:

    def __init__(self):
        """初始化Linear Regression模型"""

        ## 系数向量(θ1,θ2,.....θn)
        self.coef_ = None
        ## 截距 (θ0)
        self.interception_ = None
        ## θ向量
        self._theta = None

    def fit_normal(self, X_train, y_train):

        # 拼接为X(b)格式的数据,-----在每行的第一列之前加上1.
        ones_vector = np.ones((len(X_train),1))
        X_b = np.hstack([ones_vector,X_train])

        # 根据X_b带入公式计算w
        # arr.dot(arr):点乘
        # np.linalg.inv(arr):矩阵的逆
        self._theta = np.linalg.inv(X_b.T.dot(X_b)).dot(X_b.T).dot(y_train)

        self.coef_ = self._theta[1:]
        self.interception_ = self._theta[0]

        return self


    def perdict(self,X_perdict):

        ones_vector = np.ones((len(X_perdict),1))
        X_b = np.hstack([ones_vector, X_perdict])

        y_head = X_b.dot(self._theta)

        return y_head

    '''MSE'''
    def mean_squared_error(self, y_true, y_predict):
        """计算y_true和y_predict之间的MSE"""
        assert len(y_true) == len(y_predict), \
            "the size of y_true must be equal to the size of y_predict"

        return np.sum((y_true - y_predict) ** 2) / len(y_true)
    
    '''R^2'''
    def r2_score(self, y_true, y_perdict):
        r2_score = 1 - self.mean_squared_error(y_true, y_perdict) / np.var(y_true)
        return r2_score
    
    def __repr__(self):
        return 'LinearRegression'

Main:

from sklearn import datasets
from KNN.Knn_2iris02.train_split_def import train_test_split
from lineCome.Linear.LinearRegression import LinearRegression

boston = datasets.load_boston()

X = boston.data
y = boston.target

X = X[y < 50.0]
y = y[y < 50.0]

x_train,y_train,x_test,y_test = train_test_split(X,y)


lr = LinearRegression()

lr.fit_normal(x_train,y_train)
y_head = lr.perdict(x_test)

print(lr.coef_)     # x系数
print(lr.interception_)      # 截距
print(lr._theta)           # w向量

re = lr.r2_score(y_test,y_head)
print(re)
# 0.737729822018786

可见分数明显比之前的一元线性回归要高。

3.scikit-learn中的回归问题

在sklearn中也有内置的多元线性回归的类,直接调用即可。

不同的是,其对象的score()的参数为训练集和训练集对应的正确的标签,而我们封装的参数为:训练集预测值和训练集对应正确的标签。

from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression

boston = datasets.load_boston()

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)

lr = LinearRegression()

lr.fit(X_train,y_train)

print(lr.coef_)
print(lr.intercept_)

re = lr.predict(X_test)
print(re)

sc = lr.score(X_test,y_test)
print(sc)
# 0.7678939383385928
4.kNN的Regressor(回归)

KNN算法也可以实现,例如,找出某个测试点距离最近的k个点,取他们的平均值,那么这个值就是该点的预测值。

from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler


boston = datasets.load_boston()

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)

#  均值方差归一化
standardScaler = StandardScaler()
# 传入
standardScaler.fit(X_train, y_train)

# 获取训练集和测试集归一化后的结果
X_train_standard = standardScaler.transform(X_train)
X_test_standard = standardScaler.transform(X_test)

from sklearn.neighbors import KNeighborsRegressor
# KNN回归算法
knn_reg = KNeighborsRegressor()
knn_reg.fit(X_train_standard, y_train)
re = knn_reg.score(X_test_standard, y_test)

print(re)
# 0.8208843099992045

网格搜索:
使用网格搜索可以找到最好的算法方案,在KNN中参数有:

  • 是否考虑距离权重
  • k的值
  • 如果考虑距离权重的话,那么计算公式参数p的值
from sklearn import datasets
from sklearn.model_selection import GridSearchCV, train_test_split
from sklearn.neighbors import KNeighborsRegressor
from sklearn.preprocessing import StandardScaler

param_grid = [
    {
        "weights": ["uniform"],
        "n_neighbors": [i for i in range(1, 11)]
    },
    {
        "weights": ["distance"],
        "n_neighbors": [i for i in range(1, 11)],
        "p": [i for i in range(1,6)]
    }
]
# 获取数据集
boston = datasets.load_boston()
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)

# 数据处理
#  均值方差归一化
standardScaler = StandardScaler()
# 传入
standardScaler.fit(X_train, y_train)
# 获取训练集和测试集归一化后的结果
X_train_standard = standardScaler.transform(X_train)
X_test_standard = standardScaler.transform(X_test)


# 进行网格搜索最佳方案
knn_reg = KNeighborsRegressor()
grid_search = GridSearchCV(knn_reg, param_grid, n_jobs=-1, verbose=1)
grid_search.fit(X_train_standard, y_train)

print(grid_search.best_params_)
# {'n_neighbors': 6, 'p': 1, 'weights': 'distance'}

# 获取最好的模型算法组合
re = grid_search.best_estimator_
print(re.score(X_test_standard,y_test))

# 使用KNN中默认的回归方案
knn_reg = KNeighborsRegressor()
knn_reg.fit(X_train_standard, y_train)
re = knn_reg.score(X_test_standard, y_test)
print(re)

第一个re的值总比第二个re的值要高。

5.线性回归参数的可解释性

当我们使用线性回归算法计算出来w后,我们知道了每个x变量的系数,那么这个系数的意义是什么呢?

加载数据和训练数据:

from sklearn import datasets
from sklearn.linear_model import LinearRegression

boston = datasets.load_boston()

X = boston.data
y = boston.target

X = X[y < 50.0]
y = y[y < 50.0]

lin_reg = LinearRegression()
lin_reg.fit(X, y)

对每一列对房价y的影响效果排序:

# x的系数
re = lin_reg.coef_
print(re)
# [-1.06715912e-01  3.53133180e-02 -4.38830943e-02  4.52209315e-01
#  -1.23981083e+01  3.75945346e+00 -2.36790549e-02 -1.21096549e+00
#   2.51301879e-01 -1.37774382e-02 -8.38180086e-01  7.85316354e-03
#  -3.50107918e-01]
import numpy as np
sort = np.argsort(re)     # 对索引排序
print(sort)
# [ 4  7 10 12  0  2  6  9 11  1  8  3  5]

# 根据排好序的索引对列名进行排序输出
feature = boston.feature_names[sort]
print(feature)
# ['NOX' 'DIS' 'PTRATIO' 'LSTAT' 'CRIM' 'INDUS' 'AGE' 'TAX' 'B' 'ZN' 'RAD'
#  'CHAS' 'RM']
# 越往前的列表示对房价越没有增高的作用,如果是负的,对房价起反作用。

例如:RM对应的是房间数,是正相关最大的特征,也就是说房间数越多,房价越高,这是很合理的 NOX对应的是一氧化氮浓度,也就是说一氧化氮浓度越低,房价越低,这也是非常合理的 由此说明,我们的线性回归具有可解释性,我们可以在对研究一个模型的时候,可以先用线性回归模型看一下,然后根据感性的认识去直观的判断一下是否符合我们的语气

相关文章

  • 2020-08-17--线性回归02

    1.多元线性回归 一元线性回归和多元线性回归之间的区别简略的说就是因变量x的数量不同(影响因素)。 将其映射在数据...

  • 机器学习实战——回归

    本章内容】 线性回归 局部加权线性回归 岭回归和逐步线性回归 例子 【线性回归】 wHat = (X.T*X).I...

  • 线性回归模型

    参考:1.使用Python进行线性回归2.python机器学习:多元线性回归3.线性回归概念 线性回归模型是线性模...

  • 通俗得说线性回归算法(二)线性回归实战

    前情提要:通俗得说线性回归算法(一)线性回归初步介绍 一.sklearn线性回归详解 1.1 线性回归参数 介绍完...

  • 第一次打卡

    线性回归主要内容包括: 线性回归的基本要素线性回归模型从零开始的实现线性回归模型使用pytorch的简洁实现线性回...

  • 2020-02-14

    线性回归:线性回归分为一元线性回归和多元线性回归,一元线性回归用一条直线描述数据之间的关系,多元回归是用一条曲线描...

  • 逻辑回归和线性回归对比

    简单说几点 线性回归和逻辑回归都是广义线性回归模型的特例。他们俩是兄弟关系,都是广义线性回归的亲儿子 线性回归只能...

  • 算法概述-02

    1.逻辑回归和线性回归的联系和区别: 逻辑回归和线性回归的都是广义的线性回归。 线性回归是根据最小二乘法来建模,逻...

  • 【机器学习实践】有监督学习:线性分类、回归模型

    线性模型 为线性模型 分类和回归的区别 分类:离散回归:连续本文主要关注线性回归模型 常用线性回归模型类型 OLS...

  • 统计学习基础复习浓缩版

    1.简单线性回归 2.多元线性回归 3.多项式回归 4.广义线性回归(含逻辑斯谛回归) 广义线性回归模型通过拟合响...

网友评论

      本文标题:2020-08-17--线性回归02

      本文链接:https://www.haomeiwen.com/subject/wibqjktx.html