一元線性回歸及非線性回歸(學習筆記)


回歸(Regression)

”回歸到中等“

房價預測:

房價預測
特征值(feature)與標簽/結果(target)
模型

  • 回歸分析(regression analysis)用來建立方程模擬兩個或者多個變量之間如何關聯
  • 被預測的變量叫做:因變量(dependent variable),輸出(output)
  • 被用來進行預測的變量叫做:自變量(independent variable),輸入(input)
  • 一元線性回歸包含一個自變量和一個因變量
  • 以上兩個變量的關系用一條直線來模擬
  • 如果包含兩個以上的自變量,則稱作多元回歸分析(multiple regression)

 

\[a_\theta(x) = \theta_0 + \theta_1x \]

這個方程對應的圖像是一條直線,稱作回歸線。其中,\(\theta_1\)為回歸線的斜率,\(\theta_0\)為回歸線的截距.\(x\)是因為只有一個自變量。

一元線性回歸——正相關:
方程圖像

一元線性回歸——負相關:
負相關圖像

一元線性回歸——不相關:
不相關圖像

求解方程系數:

求解方程系數1

 

判斷哪一條線最好:

求解方程系數2

 

代價函數(Cost Function)

  • 最小二乘法
  • 真實值y,預測值\(h_\theta(x)\),則誤差平方為\((y -h_\theta(x))^2\)
  • 找到核視的參數,使的誤差平方和:

\[j(\theta_0,\theta_1) = \frac{1}{2m}\sum_(i = 1)^m(y^i - h_\theta(x^i))^2 最小 \]

代價函數1

假設的目標一元線性回歸方程:

\[a_\theta(x) = \theta_0 + \theta_1x \]

該方程的參數有兩個分別為:

\[\theta_0,\theta_1 \]

該方程的代價函數為:

\[ j(\theta_0,\theta_1) = \frac{1}{2m}(\sum_{i=0}^m(y^i - h_\theta(x^i))^2 \]

預期的目標是:

\[arg~min~j(\theta_0,\theta_1) \]

\[arg~min_{(\theta_0,\theta_1)}~~\frac{1}{2m}(\sum_{i=0}^m(y^i - h_\theta(x^i))^2 \]

為了研究簡化以上步驟,先只對\(\theta_1\)進行研究,截距\(\theta_0 = 0\)

得到的方程如下:

\[a_\theta(x) = \theta_1x \]

該方程的代價函數為:

\[ j(\theta_1) = \frac{1}{2m}(\sum_{i=0}^m(y^i - h_\theta(x^i))^2 \]

預期目標變為:

\[arg~min~j(\theta_1) arg~min_{(\theta_1)}~~\frac{1}{2m}(\sum_{i=0}^m(y^i - h_\theta(x^i))^2 \]

舉例:這里令\(\theta_0 = 0\),改變\(\theta_1\)的值,觀察costFunction的變化情況:
theta = 1
theta = 0.5
theta = 0
將大量\(\theta_1\)帶入運算,最終得到關於\(\theta_1\)的costfunction的圖像:
costfunction

而若同時考慮\(\theta_0\)\(\theta_1\)時,圖像如下:

costfunction_3d
costfunction_2d

這便是代價函數(cost function)

 

梯度下降法(Gradient Descent)

當我們有了一個代價函數\(j(\theta_0,\theta_1)\)后,如何去尋找\(min_{(\theta_0,\theta_1)}j(\theta_0,\theta_1)\)呢?

我們需要:

  • 初始化\(\theta_0,\theta_1\)
  • 不斷改變\(\theta_0,\theta_1\),直到\(j(\theta_0,\theta_1)\)達到一個全局最小值,或者局部極小值。(不斷迭代,優化函數模型)

此時我們便需要梯度下降函數來幫助我們尋找極小值(最小值)

gradient_decent_1

在圖像上任取一點,在對這個點求導,這個導數,便是這個點的梯度,我們沿着這個梯度不斷下降,便可以成功的到達最低點,也就是\(arg~min~j(\theta_0,\theta_1)\)當然如果我們初始點選的位置不好,那便會下降到局部的極小值點處,而非全局最小值點。如圖:

gradient_decent_2

這個迭代方法,稱為梯度下降法,用函數表示成:

梯度下降函數(gradient-decent)

\[repeat~until~convergence\\ \theta_j = \theta_j - \alpha\frac{\partial}{\partial\theta_j}(for~j = 0~and~j = 1) \]

其中\(\alpha\)稱為學習率(learning rate)

注:

在對\(j(\theta_0,\theta_1)\)更新時,我們需要的是同步更新,即:

\[temp0 := \theta_0 - \alpha\frac{\partial}{\partial\theta_0}j(\theta_0,\theta_1)\\ temp1 := \theta_1 - \alpha\frac{\partial}{\partial\theta_1}j(\theta_0,\theta_1)\\ \theta_0 :=temp0\\ \theta_1 :=temp1\\ \]

而不是以下這種異步更新:

\[temp0 := \theta_0 - \alpha\frac{\partial}{\partial\theta_0}j(\theta_0,\theta_1)\\ \theta_0 :=temp0\\ temp1 := \theta_1 - \alpha\frac{\partial}{\partial\theta_1}j(\theta_0,\theta_1)\\ \theta_1 :=temp1\\ \]

這種方法有可能會得到正確的答案,但異步更新並不是梯度下降函數所定義的跟新方法。

學習率

關於學習率,它是用來調節每次函數梯度下降時,下降的高度。用圖說話:
下圖是關於\(\theta_1\)的costfunction
learning_rate1

當我們將學習率設置的比較恰當時,比較理想的情況如下:
learning_rate2

而下面這種情況便是學習率設置過大,導致無法下降到極小值點:
learning_rate3

但是學習率也不能設置過小,設置過小,會導致函數迭代次數過多,消耗大量資源,時間消耗較大:
learning_rate4

梯度下降法的缺點也很明顯,不同的起點選擇,有可能會下降到局部極小值,而不能正確的取到全局最小值,如圖:
gradient_decent_disadvantage

可見學習率不能太小,也不能太大,可以多嘗試一些值(0.1.0.001,0.003,0.002,。。。)

用梯度下降法來求解線性回歸

梯度下降法:

\[repeat~until~convergence\\ \theta_j = \theta_j - \alpha\frac{\partial}{\partial\theta_j}(for~j = 0~and~j = 1) \]

線性回歸的模型和代價函數:

\[a_\theta(x) = \theta_0 + \theta_1x \\ j(\theta_0,\theta_1) = \frac{1}{2m}(\sum_{i=0}^m(y^i - h_\theta(x^i))^2 \]

對上式分別求偏導得:

\[repeat~until~convergence \\ \theta_0 = \theta_0 - \alpha\frac{1}{m}(\sum_{i=0}^m(y^i - h_\theta(x^i)) \\ \theta_1 = \theta_1 - \alpha\frac{1}{m}(\sum_{i=0}^m(y^i - h_\theta(x^i)) · x^{(i)} \]

用以上方法,便可對簡單的線性模型進行線性回歸

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

#載入數據
data = pd.read_csv("data.csv",encoding="gbk",header=None)

#數據切割
x_data = data.iloc[:,0]
y_data = data.iloc[:,1]

#設置圖像大小
plt.xlim(20,80)
plt.ylim(20,120)

#顯示散點圖
plt.scatter(x_data,y_data,c = 'r')
plt.show()

#設置學習率
lr = 0.0001

#截距theta1
theta1 = 0

#斜率theta0
theta0 = 0

#樣本總個數
m = len(x_data)

#最大迭代次數
epochs = 50

#代價函數
def CostFunction(theta0, theta1, x_data, y_data, m):
    totalError = 0
    for i in range(m):
        totalError += ((theta0 + theta1 * x_data[i]) - y_data[i])**2
    return totalError / float(( 2 * m))
    
a = np.ones(50)
b = np.ones(50)
ans = np.ones(50)
#梯度下降函數
def gradient_decent(theta0, theta1, lr, m, x_data, y_data , epochs):
    for i in range(epochs):
        theta0_grad = 0
        theta1_grad = 0
        for j in range(m):
            theta0_grad += (theta0 + theta1 * x_data[j]) - y_data[j]
            theta1_grad += ((theta0 + theta1 * x_data[j]) - y_data[j]) * x_data[j]
        theta0 = theta0 - lr * (1 / m) * theta0_grad
        theta1 = theta1 - lr * (1 / m) * theta1_grad
        a[i] = theta0;
        b[i] = theta1;
        ans[i] = CostFunction(theta0,theta1,x_data,y_data,m)
       ##每迭代5次,輸出一次圖像
       #if i % 5 == 0:
       #    print("epochs:",i)
       #    plt.plot(x_data,y_data,'b.')
       #    plt.plot(x_data,theta1 * x_data + theta0,'r')
       #    plt.show()
    return theta0,theta1
    
theta0,theta1 = gradient_decent(theta0, theta1, lr, m, x_data, y_data , epochs)
plt.scatter(x_data,y_data,c = 'r')
plt.plot(x_data,theta0 + theta1 * x_data,'b')
plt.show()
print(theta0,theta1,CostFunction(theta0,theta1,x_data ,y_data , m))

#3D梯度下降
ax = plt.axes(projection='3d')
ax.plot3D(a,b,ans,'red')

#3d等高線梯度下降
A,B = np.meshgrid(a,b)
ans = CostFunction(A,B,x_data,y_data,m)
fig = plt.figure()
ax = Axes3D(fig)
ax.plot_surface(A,B,ans,rstride = 1,cstride = 1,cmap = plt.get_cmap('rainbow'))

#2d等高線
plt.contourf(A,B,ans,7,alpha = 0.75,cmap = plt.cm.hot)
plt.show()

凸函數(convex)

convex
在處理線性回歸問題時,若采用梯度下降的方法,我們理想的代價函數函數便是上圖右側的凸函數(convex),而左側的非凸函數(non-convex)很容易取到局部極小值,對線性回歸有很大的干擾,往往得不到正確的結果。


免責聲明!

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



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