線性迴歸---Fit A Line

最近在上【開課吧人工智能學院】,第六期【計算機視覺】的課程。講師上課講了線性迴歸與邏輯迴歸。我來簡單總結一下線性迴歸~
那就從我有一個房子開始吧~ 最近想去大城市闖蕩,需要錢,想賣掉老家的房子。我知道自己的房子150平米,我想預估這個房子的價格。我就去賣房子的網站去看別人的房子都是什麼樣的價格。剛開始我很單純,只關注了一個點,就是房子的面積和價格。
我收集了以下數據:(100平米,350萬)(200平米,650萬),就想自己的房子應該介於350萬到650萬之間。

我是學習過數學嘛,想到 y=ax+by = ax + b ,根據兩個數據的規律得到以下經驗:

房子價格 = 3 ✖️房子的面積 + 50。

那我把自己房子的面積帶入,那價格應該是500萬。

以上過程,進一步理解。

  • 關於收集來的簡單數據可看作數據集,簡單記爲(xx ,yy)。
  • 房子的面積可看作特徵
  • 線性方程中的 aabb 可看作參數,根據數據求得 aabb,可看作求參數的過程,也可稱作訓練過程。訓練所用的數據又是訓練集
  • 房子的價格能影響參數的值,這樣的影響,可看作有監督的過程,房子的價格監督 aabb 求解的過程。
  • 函數【房子價格 = 3 ✖️房子的面積 + 50】 可看作一個模型,帶入新的數據【房子的面積】可知道該房子的價格。

那我繼續收集數據~
在這裏插入圖片描述
現在繼續使用一條直線去靠近這些點,便以下的圖示過程,可稱作擬合的過程。
在這裏插入圖片描述
用紅色的線記錄同一個橫軸下直線與點的差異。
在這裏插入圖片描述
加粗樣式
可以看到,當所有紅色的線累計到最短的時候,便是擬合效果最好的時候。
我們將綠色直線的值記爲 y^\hat y。那 y^y|\hat y - y| 表示擬合直線與真實值的誤差(Error),即是紅色的線。則所有數據的平均絕對誤差(Mean Absolute Error,MAE),若有mm個數據,第ii個數據下的真實值表示爲yiy^i,擬合曲線在第個值下的值爲 y^i\hat y^i, MAE表示爲:
MAE=1mi=1my^iyi MAE = \frac 1m\sum_{i=1}^m | \hat y^i - y^i |
同樣,考慮到擬合直線與真實值的面積誤差,稱之爲 Mean Squared Error(MSE),表達式如下:
MSE=12mi=1m(y^iyi)2 MSE = \frac {1}{2m}\sum_{i=1}^m ( \hat y^i - y^i )^2
這樣,我們的目標是希望擬合直線與真實值的誤差最小,可以選擇MSE或者MAE,監督參數的求解,這樣的MSE/MAE的函數,又稱爲損失函數/期望函數/目標函數(cost/loss/target function)。

== 那如何求解參數呢?==
選擇MSE作爲監督的函數 ,cost function = MSE 。
目標是希望 MSE 越小越好,如何讓MSE越來越小呢?也就是隨機調整參數 aabb。通過觀察 cost function的值,監督參數 aabb 的調整。
隨機調整參數有點佛系,比較耗時。
有沒有誰能指點方向,讓參數求解faster呢?
梯度的方向是函數變化最快的方向。梯度便可用於參數求解。CV講師給出瞭如何求參數的過程。
在這裏插入圖片描述那我照葫蘆畫瓢~

  • Hypothesis (擬合的直線) : y=ax+by = ax + b

  • Parameters (參數) : a,ba,b

  • Cost Func (損失函數) : Cost(a,b)=12mi=1m(y^iyi)2Cost(a,b) = \frac {1}{2m}\sum_{i=1}^m ( \hat y^i - y^i )^2

  • Goal :mina,bCost(a,b)\min_{a,b}Cost(a,b)

梯度下降
  • 首先對 aabb 賦值,這個值可以是隨機的,也可以是一個零向量;
  • 改變 aabb 的值,使得 Cost(a,b)Cost(a,b) 按梯度下降的方向進行減少;
  • Cost(a,b)Cost(a,b) 下降到無法下降時爲止,這時 Cost(a,b)Cost(a,b)a,ba,b 的導數爲0.

以上的參數是怎麼改變的呢?
temp0=aλaCost(a,b) temp0 = a - \lambda \frac{\partial }{\partial a} Cost(a,b)

temp1=bλbCost(a,b) temp1 = b - \lambda \frac{\partial }{\partial b} Cost(a,b)

a:=temp0 a := temp0

a:=temp1 a := temp1

λ\lambda 是步長,也被成爲學習率,憑經驗值。

aCost(a,b)\frac{\partial }{\partial a} Cost(a,b)bCost(a,b)\frac{\partial }{\partial b} Cost(a,b) 是多少呢?
aCost(a,b)=1mi=1m(y^iyi)x \frac{\partial }{\partial a} Cost(a,b) = \frac {1}{m}\sum_{i=1}^m (\hat y^i - y^i ) x
bCost(a,b)=1mi=1m(y^iyi) \frac{\partial }{\partial b} Cost(a,b) = \frac {1}{m}\sum_{i=1}^m (\hat y^i - y^i)

參數求解之後,帶入擬合的直線,擬合的直線可以對新的數據進行預測。現在進入代碼實踐的過程~

# inference 擬合的直線 y_hat
def inference(a,b,x):
    y_hat = a * x + b
    return y_hat
    
# cost function
def eval_loss(a,b,x_list,gt_y_list):
    avg_loss = 0
    for i in range(len(x_list)):
        avg_loss += 0.5 * (a * x_list[i] + b - gt_y_list[i]) ** 2
    avg_loss /= len(gt_y_list)
    return avg_loss
# 一個數據的梯度
def gradient(y_hat, gt_y, x):
    diff = y_hat - gt_y
    da = diff * x
    db = diff
    return da,db
    
def cal_step_gradient(x_list, gt_y_list, a, b ,lr):
    avg_da, avg_db = 0, 0
    x_number = len(x_list)
    for i in range( len(x_list)):
        y_hat = inference(a, b, x_list[i])
        da, db = gradient(y_hat, gt_y_list[i], x_list[i])
        avg_da += da
        avg_db += db
    avg_da /= x_number
    avg_db /= x_number
    a -= lr * avg_da
    b -= lr * avg_db
    return a,b
    
def train(x_list, gt_y_list, lr, max_iter):
    a = 0
    b = 0
    num_samples = len(x_list)
    for i in range(max_iter): 
        a, b = cal_step_gradient(x_list, gt_y_list, a, b, lr)
        print('a:{0},b:{1}'.format(a,b))
        print('loss is {}'.format(eval_loss(a,b,x_list,gt_y_list)))
        time.sleep(0.1)
    return a,b

import time
import pandas as pd 
import matplotlib.pyplot as plt
%matplotlib inline

data = pd.DataFrame({'size': [50, 80, 100, 120, 160, 180, 200, 250],
                     'price': [150, 200, 350, 400, 500, 600, 650, 700]})
train(data['size'], data['price'],0.1, 4)

我做的這份筆記只是課堂內容的冰山一角,我要繼續啃冰山了。。。

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