天天看點

Python機器學習(二):線性回歸算法

機器學習研究的問題分為分類問題和回歸問題。分類問題很好了解,而回歸問題就是找到一條曲線,可以最大程度地拟合樣本特征和樣本輸出标記之間的關系。當給算法一個輸入時,這條曲線可以計算出相應可能的輸出。回歸算法最簡單的就是線性回歸。當樣本特征隻有一個時,稱為簡單線性回歸;當樣本特征有多個時,稱為多元線性回歸。

Python機器學習(二):線性回歸算法
線性回歸

1.簡單線性回歸

由上圖可知,簡單線性回歸隻有一個特征x,一個标記y。假定x和y之間具有類似于線性的關系,就可以使用使用簡單線性回歸算法。假定我們找到了最佳拟合的直線方程

Python機器學習(二):線性回歸算法

最佳拟合的直線方程

則對于每一個樣本點x(i),預測值如下。其中帶箭頭的y是預測值,稱為 y head。右上角的 i 是指樣本的索引。

Python機器學習(二):線性回歸算法

預測值

我們希望預測值和真實值之間的差距盡量小。一般用歐氏距離來衡量。下式稱為損失函數(Loss Function)

Python機器學習(二):線性回歸算法

損失函數

換句話說,我們的目标就是找到一組a和b,使得下式最小

Python機器學習(二):線性回歸算法

y(i)和x(i)是固定的

通過分析不同的問題,我們需要确定問題的損失函數。通過最優化損失函數,獲得機器學習的模型。幾乎所有的參數學習算法都是這樣的套路

那麼這個問題是一個典型的最小二乘法問題,即最小化誤差的平方。推導可得以下公式

Python機器學習(二):線性回歸算法

最小二乘法

可以用python封裝成這種形式

"""
Created by 楊幫傑 on 10/1/18
Right to use this code in any way you want without
warranty, support or any guarantee of it working
E-mail: [email protected]
Association: SCAU 華南農業大學
"""

import numpy as np

class SimpleLinearRegression:

    def __init__(self):
        """初始化Simple Linear Regression 模型"""
        self.a_ = None
        self.b_ = None

    def fit(self, x_train, y_train):
        """根據訓練資料集x_train,y_train訓練Simple Linear Regression 模型"""
        assert x_train.nidm == 1, \
            "Simple Linear Regressor can only solve single feature training data."
        assert len(x_train) == len(y_train), \
            "the size of x_train must be equal to the size of y_train"

        x_mean = np.mean(x_train)
        y_mean = np.mean(y_train)

        """進行向量化可以加快訓練速度"""
        # num = 0.0
        # d = 0.0
        # for x, y in zip(x_train, y_train):
        #     num += (x - x_mean) * (y - y_mean)
        #     d += (x - x_mean) ** 2

        num = (x_train - x_mean).dot(y_train - y_mean)
        d = (x_train - x_mean).dot(x_train - x_mean)

        self.a_ = num/d
        self.b_ = y_mean - self.a_ * x_mean

        return self

    def predict(self, x_predict):
        """給定待預測資料集x_predict, 傳回表示x_predict的結果向量"""
        assert x_predict.ndim == 1, \
            "Simeple Linear Regressor can only solve single feature training data."
        assert self.a_ is not None and self.b_ is not None, \
            "must fit before predict!"

        return np.array([self._predict(x) for x in x_predict])

    def _predict(self, x_single):
        """給定單個待預測資料x_single, 傳回x_single的預測結果值"""
        return self.a_ * x_single + self.b_

    def __repr__(self):
        return "SimpleLinearRegression()"

           

衡量線性回歸模型好壞有多個标準,均方誤差(Mean Squared Error)、均方根誤差(Root Mean Squared Error)、平均絕對誤差(Mean Absolute Error)等。一般使用MSE。

Python機器學習(二):線性回歸算法

均方誤差MSE

Python機器學習(二):線性回歸算法

均方根誤差RMSE

Python機器學習(二):線性回歸算法

平均絕對誤差MAE

而如果想像分類問題一樣将評判得分限制在0和1之間,則應該使用R Square

Python機器學習(二):線性回歸算法

R Square

右邊一項的分子代表使用模型産生的錯誤,分母代表使用平均值進行預測産生的錯誤。分母也可以了解為一個模型,稱為Baseline Model。

R Square的輸出分為以下幾種情況:

  • R^2 = 1,則模型不犯任何錯誤,完美
  • R^2 = 0,模型為基準模型,相當于沒訓練過
  • R^2 < 0,資料可能不存在任何線性關系

2.多元線性回歸

多元線性回歸,就是指樣本特征值有多個。根據這多個特征值來預測樣本的标記值。那麼特征X和參數Θ就是一個向量。

Python機器學習(二):線性回歸算法

多元線性回歸

相類似地,我們需要找到一個損失函數。我們需要找到一組參數Θ,使下式盡可能小

Python機器學習(二):線性回歸算法
Python機器學習(二):線性回歸算法

預測值有n個參數

為了友善進行矩陣運算,我們寫成這種形式

Python機器學習(二):線性回歸算法

X0不是特征輸入!

預測值可以寫成這種形式

Python機器學習(二):線性回歸算法

預測值和參數是n維向量,X是n維矩陣

X展開是這個樣子。每一行是一個樣本點,每一列(除了第一列)是一種特征

Python機器學習(二):線性回歸算法

展開

經過推導,得到這樣一個公式。這成為多元線性回歸的正規方程解(Normal Equation)。結果就是參數向量。

Python機器學習(二):線性回歸算法

我也不知道怎麼來的

Python機器學習(二):線性回歸算法

Θ0就是簡單線性回歸中的b

如上,可以封裝成這種形式

"""
Created by 楊幫傑 on 10/1/18
Right to use this code in any way you want without
warranty, support or any guarantee of it working
E-mail: [email protected]
Association: SCAU 華南農業大學
"""

import numpy as np

class LinearRegression:

    def __init__(self):
        """初始化Linear Regression模型"""
        self.coef_ = None
        self.interception_ = None
        self._theta = None

    def fit_normal(self, X_train, y_train):
        """根據訓練資料集X_train, y_train訓練Linear Regression模型"""
        assert X_train.shape[0] == y_train.shape[0], \
            "the size of X_train must be equal to the size of 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.interception_ = self._theta[0]
        self.coef_ = self._theta[1:]

        return self

    def predict(self, X_predict):
        """給定待預測資料集X_predict, 傳回表示X_predict的結果向量"""
        assert self.interception_ is not None and self.coef_ is not None, \
            "must fit before predict!"
        assert X_predict.shape[1] == len(self.coef_), \
            "the feature number of X_predict must be equal to X_train"

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

        return X_b.dot(self._theta)

    def __repr__(self):
        return "LinearRegression()"

           

sciki-learn中使用線性回歸如下

"""
Created by 楊幫傑 on 10/1/18
Right to use this code in any way you want without
warranty, support or any guarantee of it working
E-mail: [email protected]
Association: SCAU 華南農業大學
"""

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)

lin_reg = LinearRegression()

lin_reg.fit(X_train, y_train)

# 列印結果
print(lin_reg.coef_)
print(lin_reg.intercept_)
print(lin_reg.score(X_test, y_test))

           

輸出如下

Python機器學習(二):線性回歸算法

列印結果

3.總結

線性回歸是許多其他回歸和分類問題的基礎。

它最大的優點是對資料具有很強的解釋性。比如某一項的參數是正數,那麼很可能這個特征和樣本标記之間成正相關,反之成負相關。

優點:

  1. 思想簡單,實作容易
  2. 是許多非線性模型的基礎
  3. 具有很好的可解釋性

缺點:

  1. 假設特征和标記之間有線性關系,現實中不一定
  2. 訓練的時間複雜度比較高

References:

Python3 入門機器學習 經典算法與應用 —— liuyubobobo

機器學習實戰 —— Peter Harrington