一. 一元線性回歸
對於線性回歸最簡單的就是一元線性回歸,我們先拿一元線性回歸作為入門的例子,等理解了這個,對於多元線性回歸也就好理解了,都是一樣的道理(對不起大家字寫的不好!)
1.1官方定義
百科的定義:線性回歸是利用數理統計中回歸分析,來確定兩種或兩種以上變量間相互依賴的定量關系的一種統計分析方法,運用十分廣泛。其表達形式為y = wx+b+e,e為誤差服從均值為0的正態分布(此處我加上了偏置b,定義上是沒有的,因為在最終的求解中我們需要求得b的解,所以是需要的。)。
一元線性函數:y = wx + b這個式子比較簡單,相信大家在初高中都學過,就是由w、b控制二維空間中的一條直線.而y' = w'x + b' + e 就是我們根據樣本數據擬合出來的一條直線,e為誤差,實際上 y=y'.
1.2一元線性回歸推導
(1)從誤差着手: ----1
式中ε為誤差
由於誤差服從正太分布(高斯分布),正太分布概率密度函數為: ----2
(2)將1式代入2式:
(3)接下來就是使用最大似然估計來求解上式,但是在此之前先說一下概率密度函數和最大似然函數,不然很多同學、同志對這兩步怎么來的和為什么要這么做不是很清楚。
歸根結底我們要求得y-y'最小時w和b的值,換句話說就是求得誤差最小時的w和b,公式2概率密度函數是一個均值為0的函數,因為誤差均值為0,也就是關於y軸對稱,如下圖:
將1式代入2式后,現在變成了求解關於w、b的函數P(yi|xi;w,b)概率問題,其中P(yi|xi;w,b)yi、xi是已知量,而要求的是w,也就是w的值對應的是誤差的概率值,我們希望誤差越小越好,
由上圖可知,誤差越接近0概率越大,所以引出最大似然估計,就是求得所有樣本的誤差概率乘積最大,也就是誤差最小,對應的w、b就是我們要求得的值。
似然函數為:
(4)為了方便計算轉換成對數似然,因為可以將連乘轉換為加法運算,並且兩邊同時取對數,不影響結果,m為樣本個數:
(5)化解上式:
(6)由於讓似然函數越大越好,誤差和也就越小,所以:
(7)又因為:
(8)所以分別對b、w進行求解偏導,然后導數為0時取得最小值解
對b求偏導:
對w求偏導:
如上圖,對w求偏導將b代入后很容易就求得結果,但是這種形式對於計算機矩陣計算來講會增加復雜度,所以要對其進行轉換,最終轉換成了協方差的形式,其中涉及到一個轉換的技巧 在方塊中后的箭頭進行了推導。
二. 多元線性回歸
2.1 求解方式一正規方程求解
對於多元線性回歸直接寫到紙上進行拍照
第一種求解方式,正規方程解:
2.2 求解方式一正規方程求解
第二種求解方式,梯度下降:
最終寫成了向量的形式:
2.3 梯度下降求解Python實現
1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 __author__ = 'zqf' 4 5 import numpy as np 6 import matplotlib.pyplot as plt 7 8 9 def j(x, y, theta): 10 """ 11 損失函數 12 :param x: 訓練數據的x 13 :param y: 訓練數據標簽y 14 :param theta: 梯度值 array 15 :return: 損失值的平均值 16 """ 17 return np.sum((y - x.dot(theta)) ** 2) / len(x) 18 19 20 def dj(x, y, theta): 21 """ 22 梯度計算函數 23 :param x: 訓練數據的x 24 :param y: 訓練數據標簽y 25 :param theta: 梯度值 array 26 :return: 梯度 27 """ 28 return x.T.dot(x.dot(theta) - y) * 2 / len(x) 29 30 31 def gradient_descent(initial_theta, epsilon, x, y, eta, max_iter): 32 """ 33 梯度下降計算 34 :param initial_theta: 初始化theta 35 :param epsilon: 損失最小閾值 36 :param x: 訓練數據的x 37 :param y: 訓練數據標簽y 38 :param eta: 學習率 39 :param max_iter: 最大迭代次數 40 :return: 返回theta array(1, n+1),第一列為截距 41 """ 42 theta = initial_theta 43 i = 0 44 while i < max_iter: 45 gradient = dj(x, y, theta) 46 last_theta = theta 47 theta = theta - (eta * gradient) 48 if abs(j(x, y, theta) - j(x, y, last_theta)) < epsilon: 49 break 50 i += 1 51 return theta 52 53 54 if __name__ == '__main__': 55 train_X = 3 * np.random.random(size=100) 56 train_y = 5 * train_X + 9 + np.random.normal(size=100, scale=1) 57 train_X_b = np.hstack((np.ones([len(train_X), 1]), train_X.reshape(-1, 1))) 58 59 theta_ = gradient_descent(initial_theta=np.zeros(train_X_b.shape[1]), 60 epsilon=1e-4, 61 x=train_X_b, 62 y=train_y, 63 eta=0.01, 64 max_iter=1e8) 65 66 # 繪圖 67 plt.scatter(train_X, train_y) 68 plt.plot(train_X, train_X * theta_[1:] + theta_[0]) 69 plt.show()