【001】Python實現,單一變量的線性迴歸問題

在下自我介紹

本文講述 單一變量的直線迴歸!!!!!!

Hello,你們可以叫我弛仔,這算是人生中第一篇正式的分享博客。我呢是大一的學生,對機器學習(Machine Learning)感興趣。
hhh,也是剛剛接觸這方面的學習,想在這裏分享初學者的經驗,並且給出一些踩過的坑。

還有,我不是大佬哈!!!歡迎各位跟我一起學習!!!
在這裏插入圖片描述
最終的迴歸結果!

一些概念

擬合是什麼?

在我看來,擬合就是把平面上一系列的點,用一條光滑的曲線連接起來。

因爲點很複雜,我們可以用各種函數去組合來達到我們的目的。

泛化能力是什麼?

訓練集在訓練後,能夠預測位置數據的能力。

簡單的瞭解下即可。

過擬合是什麼?

過擬合,可能我們選擇模型時過於複雜,在訓練時表現極好,實戰卻不行了~

欠擬合是什麼?

與過擬合相反,即訓練時的效果就不佳~那就更不要說實戰拉!

線性迴歸

假設函數(hypothesis)

假設函數(Hypothesis),這個函數可以是簡單的直線,也可以是複雜的多項式組合。(我認爲他就是數學模型,可能不對,若有出入望指正)

代價函數(cost function)

在這裏插入圖片描述
我的圖應該很形象的解釋了他的意義了吧?我們可以由此計算出所有點的預測值y 與 假設函數h(x)的差,通過平方(平方是爲了化負爲正)後取均值再除以2,吳恩達老師的課程上就是這麼講噠,通常下除以2,爲了能更進一步的將代價最小化吧??

線性迴歸目標(Goal)

我們的目標:爲了讓預測值與函數值的誤差最小化

即 minimizeJ(theta)

所以引入了梯度下降(Gradient Descent)

梯度下降也可以簡單理解,多維也使很好理解的,我先再次梳理下最基礎的梯度下降
在這裏插入圖片描述
這只是舉了個例子,對J函數求導後,我們發現局部上,導數永遠指向最小值處。
所以有了梯度下降的公式:
在這裏插入圖片描述
這需要用到高數中的偏導知識,如果你已經學過導數,那麼偏導也是很簡單的~
具體推導過程,可以自己動手算一算!

上代碼

import sklearn as sk
"""
單變量的線性迴歸基礎
單變量:一個特徵哈!!!
"""


from sklearn.datasets import load_boston
import numpy as np

#輸出數據的結構
def print_data(data):
    print("Shape:",data.shape,"\n")
    print("Feature:",data['feature_names'], "\n")
    print("Keys:",data.keys(), "\n")

"""
#   計算CostFunction 代價函數
#   X爲特徵矩陣
#   y爲目標
#   theta爲theta係數 1 X n 的矩陣
"""
def computerCost(X ,y ,theta):
    num = len(y)
    y = y.reshape(num,1)
    result = np.power((X.dot(theta.transpose()) - y),2)
    return np.sum(result) /(2* num)


"""
    梯度下降函數
#   Param X train Feature
#   Param y train Target
#   Param theta h(x)=theta(0)+theta(1)*x1
#   Param times 迭代的次數
"""
def gridientDescent(X,y,theta,times,learn_rate):
    number = len(y) #獲取訓練數據的數量
    X[:,1] = X[:,1]/100 #特徵縮放
    temp = np.zeros(theta.shape) #用於更新theta
    cost = np.zeros(times) #記錄每次迭代後代價函數的值
    paramters = len(theta[0]) #參數的個數

    for i in range(times):
        y = y.reshape(number,1)
        H = X.dot(theta.transpose())
        E = H - y
        #print("Y SHAPE:",y.shape)
        #print("H SHAPE:",H.shape)
        #print("E SHAPE:",E.shape)
        for j in range(paramters):#更新theta
            XT = X.transpose()
            XT = XT[j,:]
            XT = XT.reshape(1,len(XT))
            #print("XT",XT.shape)
            term = XT.dot(E)
            temp[0, j] = theta[0, j] - ((1 / number) * learn_rate * term)

        theta = temp
        print(computerCost(X,y,theta))
    return theta


if __name__ == '__main__':
    """
        準備好了嗎?我們開始操作咯!
    #   首先獲取我們的數據
    """
    Boston = load_boston()
    BostonData = Boston.data ##特徵數據
    BostonTarget = Boston.target ##房價
    BostonFeatureName = Boston.feature_names
    print(BostonFeatureName)
    """我們使用AGE 這個特徵做本次的單特徵迴歸"""
    BostonAge = BostonData[:10,6]
    BostonAgeTarget = BostonTarget[:10]
    print('TARGET SHAPE :',BostonAgeTarget.shape)
    print("DATA SHAPE:",BostonAge.shape)
    """發現一共有506條數據,我們獲取其中前10行"""
    print("DATA:\n",BostonAge)




    #給X加入一列,因爲theta0 是一個常數項
    X = np.column_stack((np.ones(len(BostonAgeTarget)),BostonAge))
    theta = np.array([[0,0]]) #參數矩陣
    times  = 100000 #迭代次數
    step = 0.02 #步長
    g = gridientDescent(X,BostonAgeTarget,theta,times,step)

    """將數據可視化"""
    import matplotlib.pyplot as plt

    font = {
    'family': 'SimHei',
    'weight': 'bold',
    'size': '10'
    }
    plt.rc('font', **font)
    plt.rc('axes', unicode_minus=False)
    plt.xlabel("Feature Age")
    plt.ylabel("House Price")
    plt.title("Boston Price Data By Age")
    plt.scatter(x=BostonAge,
                y=BostonAgeTarget,
                c='b',
                alpha=.8,
                label='訓練數據')

    #畫出擬合直線
    x = np.linspace(BostonAge.min(), BostonAge.max(), 100)
    f = g[0, 0] + (g[0, 1] * x /100) #注意除以100,因爲我們做過特徵縮放
    plt.plot(x, f, 'r', label='預測函數')
    plt.legend(loc=2)
    plt.show()


編碼中遇到的坑

  1. 爲了每一步都簡介明瞭,代碼中加入了很多不必要的中間變量,真正實踐的時候不需要這麼複雜哦~
  2. 矩陣的shape,比如讀入target y 後,他的shape 是一維的,但是矩陣是二維的,所以會出現無法做運算。
  3. 儘量輸出Shape,通過矩陣運算法則 ,這樣可以更快的找到編碼可能出錯的位置
  4. 矩陣運算的乘法 * 和 np.dot() 是不同的
  5. 最後矩陣的求解:這是矩陣哦!!大家用學過的線性代數推導一下就明白拉(提示:由見到推複雜,由一個元素推整個矩陣)
    在這裏插入圖片描述

感謝

謝謝大家看完~繼續鑽研吧!

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