线性回归(正规方程法,梯度下降法,R_square测试),以房价预测为例

线性回归(正规方程法,梯度下降法,R_square测试),以房价预测为例

线性回归:对于存在线性关系的数据(如房价与房间数,楼层数等之间的关系),根据已知数据拟合出其线性关系(求出表示房间数,楼层数x与房价y的关系的函数)
线性回归(正规方程法,梯度下降法,R_square测试),以房价预测为例
可以用正规方程法,梯度下降法解决线性回归问题。正规方程法时间复杂度比梯度下降法高很多。

正规方程法

线性回归中需要通过训练已有数据拟合出的目标函数
线性回归(正规方程法,梯度下降法,R_square测试),以房价预测为例
如何拟合出目标函数?使损失函数尽量小
线性回归(正规方程法,梯度下降法,R_square测试),以房价预测为例
一顿数学化简后得出正规方程解

线性回归(正规方程法,梯度下降法,R_square测试),以房价预测为例
线性回归(正规方程法,梯度下降法,R_square测试),以房价预测为例
代码
首先初始化

import numpy as np
from sklearn.metrics import r2_score

class LinearRegression:
    def __init__(self):
        self.coef_=None                                         
        self.interception_=None                                     #偏移量,常数,即theta[0]
        self._theta=None                                         

正规方程解(开始训练过程)

    def fit_normal(self,X_train,y_train):                           
        assert X_train.shape[0]==y_train.shape[0]                   
        X_b=np.hstack([np.ones((len(X_train),1)),X_train])                  #将要训练的x以矩阵形式传入,加一列常数项的系数,全为1,对应偏移量,方便向量化计算
        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

训练结束,代入待预测的特征值,返回所求y


    def predict(self,X_predict):                                    
        assert self.intercept_ is not None and self.coef_ is not None
        assert X_predict.shape[1] == len(self.coef_)
        X_b=np.hstack([np.ones((len(X_predict),1)),X_predict])       #将要预测的x加一列,全为1
        return X_b.dot(self._theta)                                 

R_Square测试准确性(直接用sklearn里已有的函数)
手动实现及原理见梯度下降法代码
这里把数据集所有数据拿来训练了,没有留出测试数据,数据集的分割详见阶梯下降算法

    def score(self,X_test,y_test):                                  
        y_predict=self.predict(X_test)
        return r2_score(y_test,y_predict)                           
  def __repr__(self):
        return "LinearRegression()"

最后导入数据集
首先数据预处理一番

import numpy as np
import matplotlib .pyplot as plt
from sklearn.datasets import load_boston

boston=load_boston()           #sklearn的自带数据

X_train=boston.data            #调用库自带数据集
y_train=boston.target

X_train=X_train[y_train<50.0]         #排除训练数据中比较奇怪而特殊,影响结果的数据
y_train=y_train[y_train<50.0]

print("训练数据的维度:",boston.data.shape)
#实例化类 LinearRegression
modle=LinearRegression()
modle.fit_normal(X_train,y_train)

print(modle.coef_)                   #拟合出所求函数
print(modle.interception_)

批量梯度下降法

导入需要的包

import numpy as np
import matplotlib .pyplot as plt

损失函数
线性回归(正规方程法,梯度下降法,R_square测试),以房价预测为例

def j(theta,X_b,y):                        #损失函数
    try:
        return np.sum((y-X_b.dot(theta))**2)/len(X_b)
    except:
        return float('inf')

损失函数的梯度(偏导数)
线性回归(正规方程法,梯度下降法,R_square测试),以房价预测为例

def  dj(theta,X_b,y):                                      #每一点的求导的公式(向量化计算)
    return X_b.T.dot(X_b.dot(theta)-y)*2/len(X_b) 

梯度下降算法
线性回归(正规方程法,梯度下降法,R_square测试),以房价预测为例
学习率是超参数(不可以过大,过小)

def gradient_decent(X_b,y,initial_theta,eta,n_iters=1e4,epsilon=1e-8):      #eta:学习率
    theta=initial_theta
    i_iter=0                                                                #i_iter:次数

    while i_iter<n_iters:                                           #限制次数10000次
        gradient=dj(theta,X_b,y)                              #求梯度(偏导数)
        last_theta=theta                                         #记录进行算法前的theta,用于算完比,两次之间差距很小说明找到目标了
        theta=theta-eta*gradient                            #梯度下降法的核心

        if(abs(j(theta,X_b,y)-j(last_theta,X_b,y))<epsilon):    #代入函数本身,两次下降函数值间距小于10的-8次方就算足够精确了,找到结果
            break
        i_iter+=1                                          #记下次数
    return theta

导入波士顿房价预测数据集
并进行数据预处理

from sklearn.datasets import load_boston
boston=load_boston()                                          #sklearn的自带数据导入
X_b = boston.data
initial_theta=np.zeros(X_b.shape[1]+1)                       #初始化theta(0)theta的大小是x的13个特征再+1个偏移量
                                                                           #shape[1] 0.1.2.3代表第几维的维数
y=boston.target
eta=0.01                                                   #学习率取0.01比较合适

对数据归一化,避免因训练数据过大过小造成结果不准确

from sklearn.preprocessing import StandardScaler               #归一化所需的包
StandardScaler=StandardScaler()
StandardScaler.fit(X_b)                                        #归一化
X_b=StandardScaler.transform(X_b)
X_b=np.hstack([np.ones((len(X_b),1)),X_b])                   #给x加一列(全为1),对应theta的偏移量,方便向量化运算

分割数据,分为训练数据和测试数据

from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test=train_test_split(X_b,y)     #最好加一个种子,让随机分割的数据可以重复利用。然鹅我没加种子
print("训练数据量:",x_train.shape)
print("测试数据量:",x_test.shape)
#调用算法,求出theta
theta=gradient_decent(X_b,y,initial_theta,eta)
print("theta的维度:",theta.shape)

#开始预测!
def predict(X_predict):  
    return X_predict.dot(theta)                       # 返回预测的结果y
y_predict=predict(x_test)   

R_square法测试准确度

线性回归(正规方程法,梯度下降法,R_square测试),以房价预测为例

def mse(y_true,y_predict):                                              #公式,其实有函数可以直接求MSE
    #assert len(y_true)==len(y_predict)
    return np.sum((y_true-y_predict).dot((y_true-y_predict).T))/len(y_true)
def R_Square(y_true,y_predict):
    return 1-mse(y_true,y_predict)/np.var(y_true)
Rsquare=R_Square(y_test,y_predict)
print("算法准确度:",Rsquare)