【機器學習筆記】一元線性回歸原理、公式及代碼實現


概要

線性回歸是邏輯回歸的基礎,邏輯回歸又是神經網絡的組成部分,用於解決2分類問題

線性回歸是所有算法的基礎

線性關系 與 非線性關系

概念:

  • 線性關系是指變量之間的關系是一次函數,一個自變量x和因變量y的關系表示為一條直線,兩個自變量和因變量y的關系表示為一個平面
  • 非線性關系是指一個自變量x和因變量y的關系表示為一條曲線,兩個自變量和因變量y的關系表示為一個曲面

一個自變量x就等同於一個特征,擬合的時候就是一條線,而如果是多個特征,則是擬合面

線性關系可以理解為就是一次函數,不管有多少個自變量

示例:

  • 線性關系:$$y = a\times x + b$$
  • 非線性關系:$$y = x^2$$

回歸問題

概念:預測一個連續問題的數值,

線性回歸主要用於處理回歸問題,少數情況用於處理分類問題

一元線性回歸

概念:用來描述自變量和因變量都只有一個(一個自變量稱為一元)的情況,且自變量和因變量之間呈線性關系(一次函數)的回歸模型

表示形式:$$y = a \times x + b$$

只有x一個自變量,y為因變量,a為斜率,也稱為x的權重,b為截距

作用:通過一元線性回歸模型尋找到一條合適的直線,最大程度地擬合自變量 x 和因變量 y 之間的關系,這樣我們知道一個 x 的值,就可以通過這條擬合的直線找到最可能的 y

學習一元線性模型的過程就算通過訓練數據得到合適的a和b的過程,也就是該一元線性模型的參數即為 a 和 b,當輸入一個新的測試數據點的時候,我們可以通過訓練好的模型來進行預測。

模型好壞評價方式

目標:預測值與真實值之間的差距越小越好,距離越小,代表我們的模型效果越好

很自然的一個想法是:對於每一個點(x)都計算

\[y - y\_predict \]

然后將所有的值進行累加最后除以樣本數,這樣是為了減少樣本對於結果的影響。

公式:

\[\displaystyle\frac{1}{n}\displaystyle \sum_{i=1}^{n}(y^i-y\_predict^i) \]

這個公式存在的問題:預測出來的值有可能大於真實值也可能小於真實值,這將導致誤差被虛弱,正負中和導致最終累加誤差接近於 0

改進:對每個點的誤差計算取絕對值,也就是\(|y^i-y\_predict^i|\),之后我們再進行累加

問題:后續的誤差計算以及求導問題

絕對值函數,比如$$y = |x|$$在x=0處連續,但是在x處左導數為-1,右導數為1,不相等,可導函數必須光滑,所以函數在x=0不可導

進一步優化:對於每個點計算得到的誤差,對這個結果做一次平方,並且為了忽略樣本數的影響,取平均值

公式:

\[\displaystyle\frac{1}{n}\displaystyle \sum_{i=1}^{n}(y^i-y\_predict^i)^2 \]

最小二乘法

由於

\[\displaystyle y\_predict^i=ax^i+b \]

代入上一節的公式中

\[\displaystyle\frac{1}{n}\displaystyle \sum_{i=1}^{n}(y^i-ax^i-b)^2 \]

通過最小二乘法來尋找最優的參數 a 和 b,從而使這個表達式盡可能的小

概念:一種數學優化技術,通過最小化誤差的平方和來尋找最優的參數

公式:

\[\displaystyle a=\frac{\sum_{i=1}^{n}(x^i-\overline x)(y^i-\overline y)}{\sum_{i=1}^{n}(x^i-\overline x)^2} \]

\[\displaystyle b = \overline y - a\overline x \]

代碼實現

import numpy as np
from matplotlib import pyplot as plt

if __name__ == '__main__':
    # 准備數據
    x = np.array([1, 2, 4, 6, 8])  # 一元線性回歸模型僅處理向量,而不能處理矩陣
    y = np.array([2, 5, 7, 8, 9])
    x_mean = np.mean(x)
    y_mean = np.mean(y)
    
    # 求a和b
    denominator = 0.0  # 分母
    numerator = 0.0  # 分子
    for x_i, y_i in zip(x, y):  # 將x, y向量合並起來形成元組(1, 2)、(2, 5)
        numerator += (x_i - x_mean) * (y_i - y_mean)
        denominator += (x_i - x_mean) ** 2
    a = numerator / denominator
    b = y_mean - a * x_mean
    
    # 用a和b構造線性函數,輸出的預測值存入y_predict
    y_predict = a * x + b  # 這個函數是非常擬合訓練集x的
    
    # 畫出這條直線,以及訓練集的數據
    plt.scatter(x, y, color='b')
    plt.plot(x, y_predict, color='r')
    plt.xlabel('x', fontsize=15)
    plt.ylabel('y', fontsize=15)
    plt.show()
    
    # 輸入測試數據,回歸一個值
    x_test = 7
    y_predict_test = a * x_test + b
    print(y_predict_test)

一元線性回歸模型僅處理向量,而不能處理矩陣

進行一定的封裝以后:

import numpy as np
import matplotlib.pyplot as plt

class SimpleLinearRegressionSelf:

    # 初始化變量
    def __init__(self):
        """初始化simple linear regression模型"""
        self.a_ = None  # 類內使用,非用戶外部輸入的變量
        self.b_ = None  # 類內使用,非用戶外部輸入的變量

    # 訓練模型
    def fit(self, x_train, y_train):
        assert x_train.ndim == 1
        x_mean = np.mean(x_train)
        y_mean = np.mean(y_train)
        denominator = 0.0
        numerator = 0.0

        for x_i, y_i in zip(x_train, y_train):
            numerator += (x_i - x_mean) * (y_i - y_mean)
            denominator += (x_i - x_mean) ** 2
        self.a_ = numerator / denominator
        self.b_ = y_mean - self.a_ * x_mean

        return self

    # 預測
    def predict(self, x_test_group): # 輸入的是向量集合
        # 對輸入向量集合中的每一個向量都進行一次預測,預測的具體實現被封裝在_predict函數中
        return np.array([self._predict(x_test) for x_test in x_test_group])

    def _predict(self, x_test):
        # 求每一個輸入的x_test以得到預測值
        return self.a_ * x_test + self.b_

    # 衡量模型分數
    def mean_squared_error(self, y_true, y_predict):
        return np.sum((y_true - y_predict) ** 2) / len(y_true)

    def r_square(self, y_true, y_predict):
        # 計算指定數據(數組元素)沿指定軸的方差
        return 1 - (self.mean_squared_error(y_true, y_predict) / np.var(y_true))


if __name__ == '__main__':
    x = np.array([1, 2, 4, 6, 8])
    y = np.array([2, 5, 7, 8, 9])

    lr = SimpleLinearRegressionSelf()
    lr.fit(x, y)
    print(lr.predict([7]))
    print(lr.r_square([8, 9], lr.predict([6, 8])))

此處衡量模型分數的公式為:

\[\displaystyle R^2 = 1-\frac{\frac{1}{n}\sum_{i=1}^{n}(y\_predict^i-y^i)^2}{\sum_{i=1}^{n}(\overline y-y^i)^2} \]


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM