爲了更好的學習線性迴歸,首先複習一次函數的特性:算法
假設如今有一些數據點,咱們利用一條直線對這些點進行擬合(該線稱爲最佳擬合直線),這個擬合過程就稱做爲迴歸,以下圖所示:網絡
迴歸問題分爲模型的學習和預測兩個過程。基於給定的訓練數據集構建一個模型,根據新的輸入數據預測相應的輸出。機器學習
迴歸問題按照輸入變量的個數能夠分爲一元迴歸和多元迴歸;按照輸入變量和輸出變量之間關係的類型,能夠分爲線性迴歸和非線性迴歸。函數
在迴歸分析中,只包括一個自變量和一個因變量,且兩者的關係可用一條直線表示,這種迴歸分析稱爲一元線性迴歸分析,能夠用y=ax+b表示。假設有一個房屋銷售的數據以下(例子來源於網絡):學習
面積(m^2) 銷售價錢(萬元)ui
123 250spa
150 320.net
87 1603d
102 220code
… …
根據面積和總價做圖,x軸是房屋的面積,y軸是房屋的售價:
利用曲線對數據集進行擬合,若是這個曲線是一條直線,那就被稱爲一元線性迴歸。
假設要銷售一個新的面積,沒有對應的價格,這個時候能夠用一條曲線去儘可能準的擬合原始數據,而後根據新的面積,在將曲線上這個點對應的值返回。若是用一條直線去擬合,多是下面的樣子:
綠色的點就是咱們想要預測的點。
機器學習過程:首先給出一個輸入數據,咱們的算法會經過一系列的過程獲得一個估計的函數,這個函數有能力對沒有見過的新數據給出一個新的估計,也被稱爲構建一個模型。就如同上面的線性迴歸函數。
假設我去銀行申請貸款,銀行會根據咱們的工資、年齡等條件給咱們計算貸款額度。假設額度只與年齡和工資有關,下面有5個申請人的基本信息(樣本)。那麼,如何根據這些數據構建一個模型,來預測其餘人的貸款額度呢?(表格數據來源於網絡)
對於一個線性關係,咱們使用y=ax+b表示,但在這種關係中y只受一個x的影響,兩者的關係可用一條直線近似表示,這種關係叫一元線性迴歸。
而在本例中,額度(Y)工資(X1)和年齡(X2)的影響,能夠近似的當作下圖:
圖中紅點爲樣本數據,如今,咱們的目標是根據給定的數據集擬合一個平面,使得各個樣本數據到達平面的偏差最小。由此獲得線性迴歸的模型函數:。額度受到多個變量的影響,稱之爲多元線性迴歸。
將上式中的θ和x分別表示成兩個一維矩陣[θ0 θ1 θ2]和[x0 x1 x2],則可將上式化爲(x0爲咱們加入的一列,每一個值爲1)。
然而,實際結果不可能徹底符合咱們的預期,樣本和擬合平面一定存在偏差,假設對於每個樣本,都存在:(實際值=預測值+偏差),其中爲真實偏差。
所以,把偏差值帶入高斯分佈函數:,獲得機率密度函數:
{ p(y|x;θ)表示在給定了參數θ的狀況下,給定一個x就能求出對應的y }
所以,若是存在大量的樣本,咱們就能夠經過和作關於θ的參數估計。
這裏思考一個問題:當偏差趨於0時,預測的值越接近真實值。上面的機率密度函數是否是能夠理解爲:參數θ和x樣本數據組合後的預測值接近y的機率越大越好呢?x是已知的樣本數據,要想偏差趨於0時,那麼預測值要越大越好(越接近真實值),也就是參數θ越大越好。那麼怎樣才能讓參數θ越大越好呢?
引入似然函數:
對於因變量Y,最大似然估計就是去找到Y的參數值θ ,使其發生機率最大,利用已知的樣本結果,反推最有可能(最大機率)致使這樣結果的參數值θ 。
由極大似然估計的定義,咱們須要L(θ )最大,須要兩邊取對數對這個表達式進行化簡以下:
紅色方框被標記的兩個部分均爲常數,不會影響最終結果。所以,減法後面的式子應當越小越好:
(最小二乘法)
最小二乘法定義:最小二乘法又稱最小平方法,它經過最小化偏差的平方和尋找數據的最佳函數匹配。利用最小二乘法能夠簡便地求得未知的數據,並使得這些求得的數據與實際數據之間偏差的平方和爲最小。
接下來最小化目標函數,θ 取何值的時,目標函數取得最小值,而目標函數連續,那麼 θ 必定爲目標函數的極值點,所以對目標函數求偏導就能夠找到極值點。將上式化簡,並對θ求偏導(矩陣求導知識):
化簡過程:
最終結果:
首先導入三大件:
import numpy as np import pandas as pd import matplotlib.pyplot as plt
數據集分佈狀況:
#數據分佈狀況展現 x_train = [[6], [8], [10], [14], [18]] y_train = [[7], [9], [13], [17.5], [18]] x_train = np.array(x_train) #把數據轉換爲ndarray結構方便矩陣計算 y_train = np.array(y_train) #把數據轉換爲ndarray結構方便矩陣計算 plt.plot(x_train,y_train,'r.') plt.show()
計算損失值:
# 計算損失值得函數 def cost(x,y,k,b): cost = 0 for i in range(len(x)): cost += (y[i] - (x[i] * k + b)) ** 2 return cost / (2 * len(x))
定義基本變量:
k = 0 # 定義參數 b = 0 # 定義截距 lr = 0.001 # 步長 apochs = 5000 # 迭代次數
梯度降低函數:
# 梯度降低函數 def gradient_descent(x,y,k,b,lr,apochs): m = len(x) for i in range(apochs): k_grad = 0 b_grad = 0 for j in range(len(x)): b_grad += (-1/m) * (y[j] - (k * x[j] + b)) #對b求導 k_grad += (-1/m) * (y[j] - (k * x[j] + b)) * x[j] #對k求導 k = k - lr * k_grad #參數更新 b = b - lr * b_grad #參數更新 return k,b
最後結果:
print("staring: k= {} b={} cost={}".format(k,b,cost(x_train,y_train,k,b))) #進行梯度降低前的值 k,b = gradient_descent(x_train,y_train,k,b,lr,apochs) print("runing......") print("ending: k= {} b={} cost={}".format(k,b,cost(x_train,y_train,k,b))) # 梯度降低後損失值由原來的93降到了0.9 plt.plot(x_train,y_train,'r.') plt.plot(x_train,k * x_train + b,'b') plt.show()
from sklearn.linear_model import LinearRegression model = LinearRegression() #建立線性迴歸模型 model.fit(x_train, y_train) #把數據放入模型 xx = np.linspace(0, 26, 100)#生成了0-26之間(包含0和26)的1行100列的一個矩陣 #print(xx) xx = xx.reshape(-1, 1)#將1行100列的矩陣轉化成100行1列的矩陣形式 #print(xx) yy = model.predict(xx) #根據假設的xx值,進行預測 plt.scatter(x_train, y_train) plt1, = plt.plot(xx, yy, label="Degree=1") plt.axis([0, 25, 0, 25]) plt.xlabel('pizza size') plt.ylabel('Pizza price') plt.legend() plt.show() print('model score:', model.score(x_train, y_train)) # 模型評分
end~