天天看點

python對于一進制線性回歸模型_機器學習3- 一進制線性回歸+Python實作

1. 線性模型

給定 \(d\) 個屬性描述的示例 \(\boldsymbol{x} = (x_1; x_2; ...; x_d)\),其中 \(x_i\) 為 \(\boldsymbol{x}\) 在第 \(i\) 個屬性上的取值,線性模型(linear model)試圖學得一個通過屬性的線性組合來進行預測的函數,即:

\[f(\boldsymbol{x}) = w_1x_1 + w_2x_2 + ... + w_dx_d +b \tag{1.1}

\]

使用向量形式為:

\[f(\boldsymbol{x}) = \boldsymbol{w}^T\boldsymbol{x}+b \tag{1.2}

\]

其中 \(\boldsymbol{w} = (w_1;w_2;...;w_d)\),表達了各屬性在預測中的重要性。

2. 線性回歸

給定資料集 \(D = \lbrace(\boldsymbol{x}_1,{y}_1), (\boldsymbol{x}_2,{y}_2), ..., (\boldsymbol{x}_m,{y}_m)\rbrace\),其中 \(\boldsymbol{x}_i = (x_{i1}; x_{i2}; ...; x_{id})\),\(y_i \in \mathbb{R}\)。線性回歸(linear regression)試圖學得一個能盡可能準确地預測真實輸出标記的線性模型,即:

\[f(\boldsymbol{x}_i) = \boldsymbol{w}^T\boldsymbol{x}_i+b \text{,使得} f(\boldsymbol{x}_i) \simeq y_i\tag{2.1}

\]

2.1 一進制線性回歸

先隻考慮輸入屬性隻有一個的情況,\(D = \lbrace({x}_1,{y}_1), ({x}_2,{y}_2), ..., ({x}_m,{y}_m)\rbrace\),\(x_i \in \mathbb{R}\)。對離散屬性,若屬性值存在序(order)關系,可通過連續化将其轉化為連續值。

如”高度“屬性的取值“高”、“中”、“低”,可轉化為\(\{1.0, 0.5, 0.0\}\)。

若不存在序關系,則假定有 \(k\) 種可能的屬性值,将其轉化為 \(k\) 維向量。

如“瓜類”屬性的取值有“冬瓜”、“西瓜”、“南瓜”,可轉化為 \((0,0,1),(0,1,0),(1,0,0)\)。

線性回歸試圖學得:

\[f(x_i) = wx_i+b\text{,使得}f(x_i)\simeq y_i \tag{2.2}

\]

為使 \(f(x_i)\simeq y_i\),即:使 \(f(x)\) 與 \(y\) 之間的差别最小化。

考慮回歸問題的常用性能度量——均方誤差(亦稱平方損失(square loss)),即讓均方誤差最小化:

\[\begin{aligned}

(w^*,b^*) = \underset{(w,b)}{arg\ min}\sum_{i=1}^m(f(x_i)-y_i)^2 \\

= \underset{(w,b)}{arg\ min}\sum_{i=1}^m(y_i-wx_i-b)^2

\end{aligned}

\tag{2.3}

\]

\(w^*,b^*\) 表示 \(w\) 和 \(b\) 的解。

均方誤差對應了歐幾裡得距離,簡稱歐氏距離(Euclidean distance)。

基于均方誤差最小化來進行模型求解的方法稱為最小二乘法(least square method)。線上性回歸中,就是試圖找到一條直線,使得所有樣本到直線上的歐氏距離之和最小。

下面需要求解 \(w\) 和 \(b\) 使得 \(E_{(w,b)} = \sum\limits_{i=1}^m(y_i-wx_i-b)^2\) 最小化,該求解過程稱為線性回歸模型的最小二乘參數估計(parameter estimation)。

\(E_{(w,b)}\) 為關于 \(w\) 和 \(b\) 的凸函數,當它關于 \(w\) 和 \(b\) 的導數均為 \(0\) 時,得到 \(w\) 和 \(b\) 的最優解。将 \(E_{(w,b)}\) 分别對 \(w\) 和 \(b\) 求導數得:

\[\frac{\partial{E_{(w,b)}}}{\partial(w)} = 2\Big(w\sum_{i=1}^m x_i^2 - \sum_{i=1}^m (y_i-b)x_i\Big) \tag{2.4}

\]

\[\frac{\partial{E_{(w,b)}}}{\partial(b)} = 2\Big(mb - \sum_{i=1}^m (y_i-wx_i)\Big) \tag{2.5}

\]

令式子 (2.4) 和 (2.5) 為 \(0\) 得到 \(w\) 和 \(b\) 的最優解的閉式(closed-form)解:

\[w = \frac{\sum_\limits{i=1}^m y_i(x_i-\overline{x})}{\sum\limits_{i=1}^m x_i^2 - \frac{1}{m}\Big(\sum\limits_{i=1}^m x_i\Big)^2} \tag{2.6}

\]

\[b = \frac{1}{m}\sum_{i=1}^m (y_i-wx_i) \tag{2.7}

\]

其中 \(\overline{x} = \frac{1}{m}\sum\limits_{i=1}^m x_i\) 為 \(x\) 的均值。

其他解法:

\[方差\ var(x) = \frac{\sum\limits_{i=1}^m(x_i-\bar{x})^2}{m-1}

\]

\[協方差\ cov(x,y) = \frac{\sum_\limits{i=1}^m (x_i-\overline{x})(y_i-\overline{y})}{n-1}

\]

\[w = \frac{cov(x,y)}{var(x)} = \frac{\sum_\limits{i=1}^m (x_i-\overline{x})(y_i-\overline{y})}{\sum\limits_{i=1}^m (x_i-\overline{x})^2}

\]

\[b = \bar{y} - w\bar{x}

\]

3. 一進制線性回歸的Python實作

現有如下訓練資料,我們希望通過分析披薩的直徑與價格的線性關系,來預測任一直徑的披薩的價格。

python對于一進制線性回歸模型_機器學習3- 一進制線性回歸+Python實作

其中 Diameter 為披薩直徑,機關為“英寸”;Price 為披薩價格,機關為“美元”。

3.1 使用 stikit-learn

3.1.1 導入必要子產品

import matplotlib.pyplot as plt

import numpy as np

import pandas as pd

from sklearn.linear_model import LinearRegression

3.1.2 使用 Pandas 加載資料

pizza = pd.read_csv("pizza.csv", index_col='Id')

pizza.head() # 檢視資料集的前5行

python對于一進制線性回歸模型_機器學習3- 一進制線性回歸+Python實作

3.1.3 快速檢視資料

我們可以使用 matplotlib 畫出資料的散點圖,x 軸表示披薩直徑,y 軸表示披薩價格。

def runplt():

plt.figure()

plt.title("Pizza price plotted against diameter")

plt.xlabel('Diameter')

plt.ylabel('Price')

plt.grid(True)

plt.xlim(0, 25)

plt.ylim(0, 25)

return plt

dia = pizza.loc[:,'Diameter'].values

price = pizza.loc[:,'Price'].values

print(dia)

print(price)

plt = runplt()

plt.plot(dia, price, 'k.')

plt.show()

[ 6 8 10 14 18]

[ 7. 9. 13. 17.5 18. ]

python對于一進制線性回歸模型_機器學習3- 一進制線性回歸+Python實作

3.1.4 使用 stlearn 建立模型

model = LinearRegression() # 建立模型

X = dia.reshape((-1,1))

y = price

model.fit(X, y) # 拟合

X2 = [[0], [25]] # 取兩個預測值

y2 = model.predict(X2) # 進行預測

print(y2) # 檢視預測值

plt = runplt()

plt.plot(dia, price, 'k.')

plt.plot(X2, y2, 'g-') # 畫出拟合曲線

plt.show()

[ 1.96551724 26.37284483]

python對于一進制線性回歸模型_機器學習3- 一進制線性回歸+Python實作

這裡 fit()方法學得了一進制線性回歸模型 \(f(x) = wx+b\),這裡 \(x\) 指披薩的直徑,\(f(x)\) 為預測的披薩的價格。

fit() 的第一個參數 X 為 shape(樣本個數,屬性個數) 的數組或矩陣類型的參數,代表輸入空間;

第二個參數 y 為 shape(樣本個數,) 的數組類型的參數,代表輸出空間。

3.1.5 模型評估

成本函數(cost function)也叫損失函數(lost function),用來定義模型與觀測值的誤差。

模型預測的價格和訓練集資料的差異稱為訓練誤差(training error)也稱殘差(residuals)。

plt = runplt()

plt.plot(dia, price, 'k.')

plt.plot(X2, y2, 'g-')

# 畫出殘差

yr = model.predict(X)

for index, x in enumerate(X):

plt.plot([x, x], [y[index], yr[index]], 'r-')

plt.show()

python對于一進制線性回歸模型_機器學習3- 一進制線性回歸+Python實作

根據最小二乘法,要得到更高的性能,就是讓均方誤差最小化,而均方誤差就是殘差平方和的平均值。

print("均方誤差為: %.2f" % np.mean((model.predict(X)-y) ** 2))

均方誤差為: 1.75

3.2 手動實作

3.2.1 計算 w 和 b

\(w\) 和 \(b\) 的最優解的閉式(closed-form)解為:

\[w = \frac{\sum_\limits{i=1}^m y_i(x_i-\overline{x})}{\sum\limits_{i=1}^m x_i^2 - \frac{1}{m}\Big(\sum\limits_{i=1}^m x_i\Big)^2} \tag{2.6}

\]

\[b = \frac{1}{m}\sum_{i=1}^m (y_i-wx_i) \tag{2.7}

\]

其中 \(\overline{x} = \frac{1}{m}\sum\limits_{i=1}^m x_i\) 為 \(x\) 的均值。

\[方差\ var(x) = \frac{\sum\limits_{i=1}^m(x_i-\bar{x})^2}{m-1}

\]

\[協方差\ cov(x,y) = \frac{\sum_\limits{i=1}^m (x_i-\overline{x})(y_i-\overline{y})}{n-1}

\]

\[w = \frac{cov(x,y)}{var(x)} = \frac{\sum_\limits{i=1}^m (x_i-\overline{x})(y_i-\overline{y})}{\sum\limits_{i=1}^m (x_i-\overline{x})^2}

\]

\[b = \bar{y} - w\bar{x}

\]

下面使用 Python 計算 \(w\) 和 \(b\) 的值:

# 法一:

# w = np.sum(price * (dia - np.mean(dia))) / (np.sum(dia**2) - (1/dia.size) * (np.sum(dia))**2)

# b = (1 / dia.size) * np.sum(price - w * dia)

#法二:

variance = np.var(dia, ddof=1) # 計算方差,doff為貝塞爾(無偏估計)校正系數

covariance = np.cov(dia, price)[0][1] # 計算協方差

w = covariance / variance

b = np.mean(price) - w * np.mean(dia)

print("w = %f\nb = %f" % (w, b))

y_pred = w * dia + b

plt = runplt()

plt.plot(dia, price, 'k.') # 樣本點

plt.plot(dia, y_pred, 'b-') # 手動求出的線性回歸模型

plt.plot(X2, y2, 'g-.') # 使用LinearRegression.fit()求出的模型

plt.show()

w = 0.976293

b = 1.965517

python對于一進制線性回歸模型_機器學習3- 一進制線性回歸+Python實作

可以看到兩條直線重合,我們求出的回歸模型與使用庫求出的回歸模型相同。

3.2.2 功能封裝

将上述代碼封裝成類:

class LinearRegression:

"""

拟合一進制線性回歸模型

Parameters

----------

x : shape 為(樣本個數,)的 numpy.array

隻有一個屬性的資料集

y : shape 為(樣本個數,)的 numpy.array

标記空間

Returns

-------

self : 傳回 self 的執行個體.

"""

def __init__(self):

self.w = None

self.b = None

def fit(self, x, y):

variance = np.var(x, ddof=1) # 計算方差,doff為貝塞爾(無偏估計)校正系數

covariance = np.cov(x, y)[0][1] # 計算協方差

self.w = covariance / variance

self.b = np.mean(y) - w * np.mean(x)

# self.w = np.sum(y * (x - np.mean(x))) / (np.sum(x**2) - (1/x.size) * (np.sum(x))**2)

# self.b = (1 / x.size) * np.sum(y - self.w * x)

return self

def predict(self, x):

"""

使用該線性模型進行預測

Parameters

----------

x : 數值 或 shape 為(樣本個數,)的 numpy.array

屬性值

Returns

-------

C : 傳回預測值

"""

return self.w * x + self.b

使用:

# 建立并拟合模型

model = LinearRegression()

model.fit(dia, price)

x2 = np.array([0, 25]) # 取兩個預測值

y2 = model.predict(x2) # 進行預測

print(y2) # 檢視預測值

runplt()

plt.plot(dia, price, 'b.')

plt.plot(x2, y2, 'y-') # 畫出拟合

plt.show()

[ 1.96551724 26.37284483]

python對于一進制線性回歸模型_機器學習3- 一進制線性回歸+Python實作

此文原創禁止轉載,轉載文章請聯系部落客并注明來源和出處,謝謝!

作者: Raina_RLN https://www.cnblogs.com/raina/