1. 程式人生 > >ML學習筆記 2 之線性迴歸

ML學習筆記 2 之線性迴歸

背景

本文以房價預測場景為線索,通過自實現多元線性迴歸演算法,從應用的角度,簡單梳理迴歸類演算法的評價指標及線性迴歸對資料的強解釋性;使用到的資料集為 sklearn 自帶的波士頓房產資料,基本資料結構介紹:

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

boston = datasets.load_boston()
boston.keys() # dict_keys(['data', 'target',
#  'feature_names', 'DESCR'])
X = boston.data 
X.shape # (506, 13)
y = boston.target
y.shape # (506,)
boston.feature_names  # array(['CRIM', 'ZN', 'INDUS',
  # 'RM', 'AGE', 'DIS', 'RAD', 'CHAS', 'NOX', 
  #'TAX', 'PTRATIO', 'B', 'LSTAT'], dtype='<U7')
  # 說明: NOX 一種氧化氮有毒氣體 ; RM  房屋數量

理解線性迴歸

一元線性迴歸

還是房價預測的例子。顯然,房價 y 跟房屋面積、臥室數量等房屋屬性有關。
簡單起見,這裡只考慮臥室數量這個特徵,方便視覺化整體感知一下簡單的線性迴歸過程:

在這裡插入圖片描述
一元線性迴歸的思路即假設上圖中的樣本資料之間具有簡單的線性關係: y_hat = ax+b ,我們要做的就是求出引數 a與b,畫出預測直線。怎麼求 a、b呢?直接想法就是使預測值 y_ha t與房價真實值 y_true 之間的差值儘可能小,即:
在這裡插入圖片描述
令 J(a,b) = y - y_hat 分佈對 a、b求偏導數,可求出上圖中的 a、b值(具體過程略), 程式碼實現如下:

import numpy as np
import matplotlib.pyplot as plt

x = np.array([1.,2.,3,4,2,2.5]) # 房屋數量
y = np.array([1.2,2.5,2,4,3,2.8]) # 房價

x_mean = np.mean(x)
y_mean = np.mean(y)
num = 0.0
d = 0.0
for x_i,y_i in zip(x,y):
    num+=(x_i - x_mean)*(y_i -y_mean)
    d+=(x_i-x_mean)**2
a = num/d
b = y_mean-a*x_mean
y_hat = a*x + b
plt.rcParams['font.sans-serif'] = 'Microsoft YaHei'
plt.scatter(x,y)
plt.plot(x,y_hat,c='y') # 直線即為我們的預測線
plt.rcParams['axes.unicode_minus'] = False
plt.xlabel('房屋數量')
plt.ylabel('房價 (w)')
plt.title('房價-房屋數量關係')
plt.show()

在這裡插入圖片描述

多元線性迴歸

這裡的多元指 theta 有多個。
在這裡插入圖片描述
用最小二乘法可求得(具體推導過程略):
在這裡插入圖片描述

造輪子

自定義一個線性迴歸實現類:

class LinearRegression:
    def __init__(self):
        self.coef_ = None
        self.intercepte_ = None
        self._theta = None
    
    def fit_normal(self,X_train,y_train):
        X_b = np.hstack([np.ones((len(X_train), 1)), X_train])
        self._theta = np.linalg.inv(X_b.T.dot(X_b)).dot(X_b.T).dot(y_train)
        self.intercept_ = self._theta[0]
        self.coef_=self._theta[1:]
        return self
    
    def predict(self,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):
        y_predict = self.predict(X_test)
        return r2_score(y_test,y_predict)
    
    def __repr__(self):
        return "LinearRegression()"

迴歸類模型評價指標定義:

def mean_squared_error(y_true,y_predict):
    return np.sum((y_true-y_predict)**2)/len(y_true)

def root_mean_squared_error(y_true,y_predict):
    return sqrt(mean_squared_error(y_true,y_predict))

def mean_absolute_error(y_true, y_predict):
    return np.sum(np.absolute(y_true - y_predict))/len(y_true)

def r2_score(y_true,y_predict): # R2 指標 依賴 MSE 與 方差
    return 1 - mean_squared_error(y_true,y_predict)/np.var(y_true)

測試:

import numpy as np
from math import sqrt
from sklearn import datasets
from sklearn.model_selection import train_test_split

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, random_state=666,test_size=0.3)
reg = LinearRegression()
reg.fit_normal(X_train,y_train)
y_predict = reg.predict(X_test)
reg.score(X_test,y_test)  # 輸出:0.79838733315901556

迴歸類演算法評價指標

  • 均方誤差 MSE ( Mean Squared Error )
  • 均方根誤差 RMSE ( Root Mean Squared Error )
  • 平均絕對值誤差 MAE (Mean Absolute Error)
    在這裡插入圖片描述
  • R Square
    在這裡插入圖片描述

Linear Reg in Sklearn & Mllib 及線性迴歸對資料的解釋性

求出 theta,|theta| 的大小可以評估對應特徵的重要性:值越大對模型的影響越大,說明該引數越重要。

from sklearn.linear_model import LinearRegression
lin_reg = LinearRegression()
lin_reg.fit(X,y)
lin_reg.score(X_test,y_test)

theta = lin_reg.coef_
theta_sorted = np.sort(theta)
theta_index_sorted = np.argsort(theta)
features_importances = boston.feature_names[theta_index_sorted]
importances = [ (i,j) for i,j in zip(theta_sorted,features_importances)]
print(importances)

輸出:

[(-12.42680725715906, 'NOX'), (-1.2108806885800978, 'DIS'), (-0.838888137346395, 'PTRATIO'), (-0.35095213398646052, 'LSTAT'), (-0.10557429507831202, 'CRIM'), (-0.043517925110529536, 'INDUS'), (-0.023611688131364272, 'AGE'), (-0.013770294250115001, 'TAX'), (0.0079357715891721359, 'B'), (0.035274854897053003, 'ZN'), (0.25074008175454843, 'RAD'), (0.45540522734528655, 'CHAS'), (3.754112288288558, 'RM')]

結果說明 :

  • NOX(一種有毒氣體)的負相關性最大,對房價的下降影響最大;RM(房屋數量)的正相關性最大,對房價的上升影響最大
  • 根據 NOX 與 RM ,我們可以嘗試推斷出一些新的特徵,例如:SO2 等

總結

線性迴歸,屬於引數學習類演算法;knn 屬於非引數類學習演算法
對資料有假設:假設資料間具有線性關係
優點:對資料具有強解釋性,方面評價與挖掘新特徵
多元線性迴歸的正規方程解(Normal Equation)- 即用公式求出來的解涉及到矩陣的求逆,時間複雜度為 O(n^3),即使優化只能達到 O(n^2.4)
引數類學習演算法套路:
通過分析問題,確定問題的損失函式或者效用函式;通過最優化損失函式或者效用函式,獲得機器學習的模型。