連載|線性迴歸

線性模型|線性迴歸

基本形式

給定由d個屬性描述的示例X=(x1;x2;...;xd)X=(x_1;x_2;...;x_d),其中xix_iXX在第i個屬性上的取值,線性模型想要通過一個屬性的線性組合來得到一個預測的函數,即:

f(x)=w1x1+w2x2+...+wdxd+bf(x)=w_1x_1+w_2x_2+...+w_dx_d+b

一般用向量的形式可以寫成:

f(x)=wTX+bf(x)=w^TX+b

其中w=(w1;w2;...;wd)w=(w_1;w_2;...;w_d),當w和b學得之後,模型就得以確定。

迴歸分析

迴歸分析是用來評估變量之間關係的統計過程,用來解釋自變量x與因變量y之間的關係,即當自變量x發生改變時,因變量y會如何發生改變。

線性迴歸

線性迴歸是迴歸分析的一種,評估的自變量x和因變量y之間是一種線性關係。當只有一個自變量時,稱爲簡單線性迴歸,當具有多個自變量時,稱爲多元線性迴歸。

對線性關係的理解:

  • 畫出來的圖像是直的。
  • 每個自變量的最高次項是1。

簡單的線性迴歸我們可以直接表示成如下形式:

y^=wx+b\widehat{y}=wx+b

注:此時的自變量只有一個值。

多元線性迴歸有多個自變量的值,而對於每一個自變量x都有一個與其對應的參數w,我們可以把x和w表示出向量或者矩陣的形式,表示方法如下:

y^=wTX+b\widehat{y}=w^TX+b

對於向量來說可以展開成下面的形式:

wT=w1,w2,...,wnw^T={w_1,w_2,...,w_n}

X=x1,x2,...,xnX=x_1,x_2,...,x_n

y^=w1x1+w2x2+...+wnxn+b\widehat{y}=w_1x_1+w_2x_2+...+w_nx_n+b

簡單線性迴歸的代碼展示如下

import numpy as np
# 線性迴歸函數
from sklearn.linear_model import LinearRegression
# 用於切分數據集
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris

# 加載鳶尾花數據集
iris = load_iris()
# 使用花瓣長和花瓣寬作爲x,y
X, y = iris.data[:, 2].reshape(-1, 1), iris.data[:, 3]

lr = LinearRegression()
X_train, X_test, y_train, y_test = train_test_split(X,
                                                    y,
                                                    test_size=0.25,
                                                    random_state=0)
lr.fit(X_train, y_train)
print("權重:", lr.coef_)
print("截距:", lr.intercept_)
y_hat = lr.predict(X_test)
print("擬合函數:", 'y={}x+{}'.format(lr.coef_[0], lr.intercept_))
import matplotlib.pyplot as plt

# mac下使用中文
plt.rcParams["font.family"] = 'Arial Unicode MS'
# win下使用中文
# plt.rcParams["font.family"] = 'SimHei'
plt.rcParams["axes.unicode_minus"] = False
plt.rcParams["font.size"] = 15

plt.figure(figsize=(10, 6), dpi=300)
plt.scatter(X_train, y_train, c='orange', label='訓練集')
plt.scatter(X_test, y_test, c='blue', marker='D', label='測試集')
plt.plot(X, lr.predict(X), 'r-')
plt.legend()
plt.xlabel("花瓣長")
plt.ylabel("花瓣寬")
plt.figure(figsize=(15, 6), dpi=300)
plt.plot(y_test, label="真實值", color='r', marker='o')
plt.plot(y_hat, label="預測值", ls='--', color='g', marker='o')
plt.xlabel("測試集數據序號")
plt.ylabel("數據值")
plt.legend()

多元線性迴歸的代碼如下:

import numpy as np
# 線性迴歸函數
from sklearn.linear_model import LinearRegression
# 用於切分數據集
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris

# 加載鳶尾花數據集
iris = load_iris()
# 使用鳶尾花的data和target作爲x和y
X, y = iris.data, iris.target

lr = LinearRegression()
X_train, X_test, y_train, y_test = train_test_split(X,
                                                    y,
                                                    test_size=0.25,
                                                    random_state=0)
lr.fit(X_train, y_train)
print("權重:", lr.coef_)
print("截距:", lr.intercept_)
y_hat = lr.predict(X_test)
print(
    "擬合函數:",
    'y={}x1+{}x2+{}x3+{}x4+{}'.format(lr.coef_[0], lr.coef_[1], lr.coef_[2],
                                      lr.coef_[3], lr.intercept_))

線性迴歸的損失函數

損失函數:

理論值於觀測值之差(誤差、殘差)的平方和。

L=i=1n(yi^yi)2L=\sum _{i=1}^{n}(\widehat{y_{i}}-y_i)^2

其中yi^\widehat{y_i}表示預測值,yiy_i表示真實值。

損失函數的求解

  1. 列出目標函數E(損失函數j(θ)j(\theta)),此時的樣本值用yi^=hθ(x(i))=xθ\widehat{y_{i}}=h_{\theta}(x^{(i)})=x\theta來表示。

  2. 求損失函數關於參數的導數,使導數爲0,代表損失函數最小。

  3. 此時的參數即爲我們所求未知解的參數。

矩陣下最小二乘法的求解過程:

首先明確一下向量和矩陣的導數:

  • AXX=AT\frac{\partial AX}{\partial X}=A^T
  • XTAXX=(A+AT)X\frac{\partial X^TAX}{\partial X}=(A+A^{T})X

假設一個條件 :滿足正定矩陣(XTY)T=(XYT)T(X^TY)^T=(XY^T)^T

  • 第一步(這裏的1/2)是爲了方便後面的計算。

J(θ)=i=1n(yi^yi)2=12(XθY)T(XθY)J(\theta)=\sum _{i=1}^{n}(\widehat{y_{i}}-y_i)^2=\frac{1}{2}(X\theta-Y)^T(X\theta-Y)

J(θ)=12(XTθTXθXTθTYYTXθ+YTY)J(\theta)=\frac{1}{2}(X^T\theta^TX\theta-X^T\theta^TY-Y^TX\theta+Y^TY)

J(θ)θ=12(2XTXθXTYXTY)\frac{\partial J(\theta)}{\partial \theta}=\frac{1}{2}(2X^TX\theta-X^TY-X^TY)

J(θ)θ=XTXθXTY\frac{\partial J(\theta)}{\partial \theta}=X^TX\theta-X^TY

  • 第二步

XTXθXTY=0X^TX\theta-X^TY=0

  • 第三步

解得:θ=(XTX)1XTY\theta=(X^TX)^{-1}X^TY

最小二乘法的求解代碼

import numpy as np
import matplotlib.pyplot as plt

# 在直線 y = 5x+3 附近生成隨機點
X = np.arange(0, 5, 0.1)
Z = [5 * x + 3 for  x in X]
Y = [np.random.normal(z, 0.5) for z in Z] 
plt.plot(X, Y, 'ro')
plt.show()
from scipy.optimize import leastsq

# 需要擬合的函數func :指定函數的形狀
def func(p,x):
    k,b=p
    return k*x+b
 
# 誤差函數:
def error(p,x,y):
    # yi-y
    return func(p,x)-y

# 設置函數的初始參數
p0=[1,20]
Para=leastsq(error,p0,args=(X,Y))
print(Para)
k,b=Para[0]

_X = [0, 5]  
_Y = [b + k * x for x in _X]

plt.plot(X, Y, 'ro', _X, _Y, 'b', linewidth=2)  
plt.title("y = {}x + {}".format(k, b))  
plt.show()

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章