梯度下降求解最小二乘

bay1發表於2018-06-22

title: 梯度下降求解最小二乘 date: 2018-05-11 01:31:10 tags: [機器學習,梯度下降法]

最近燙金學長正在學習機器學習,我也抽閒時間上了車~ github (以下都是自己根據末尾文章不理解的地方瞎記錄.

梯度下降法

求解一元線性

梯度下降求解演算法是一種迭代演算法,即在求最小二乘的時候 朝向梯形負方向(梯形正方向定義為增長速度最快)按照一定步長迭代下降 直到符合我們的預期要求 (步長也就是定義的學習率

我們使用機器學習就是擬合我們所需要的方程,使它儘可能的符合預期的"模仿方程式" 即對於一個一元線性方程,我們代入訓練資料,使它每個資料點與預期點的差異越小就好啦~ 即對於y=ax+b,我們可以求ax+b-y作為代價函式(我們評判學習結果的依據模型) 根據一系列的轉換,我們可以得到下面關於一元方程偏導

偏導公式結果

然後就是使用程式碼翻譯公式

# encoding: utf-8
from sklearn import linear_model

alpha = 0.01
# 精度設定
epsilon = 1e-8
# 目標函式y=2x+1
x = [1., 2., 3., 4., 5., 6., 7., 8., 9.]
y = [3., 5., 7., 9., 11., 13., 15., 17., 19.]

# scikit-learn的求解方法
def solve_by_scikit():
    # 使用scikit-learn求解
    # reg = linear_model.SGDClassifier(loss="hinge", penalty="l2")
    # reg.fit(x, y)
    print("暫無")


# 採用梯度下降法求解一元線性迴歸
    def solve_by_gradient():
    # 獲取迴圈的長度
    m = len(x)
    a, b, sse2 = 0, 0, 0
    while True:
        grad_a, grad_b = 0, 0
        for i in range(m):
            # 求(a*x(i)+b-y[i])的a,b偏導
            # 這裡使用common感覺更好,公式相同處
            common = a * x[i] + b - y[i]
            grad_a += x[i] * common
            grad_b += common

            grad_a = grad_a / m
            grad_b = grad_b / m

            # 梯形下降(梯形負方向,速度下降最快)迭代求符合最小值的a,b
            # alpha設定迭代步長,即學習率
            a -= alpha * grad_a
            b -= alpha * grad_b

            sse = 0
            for j in range(m):
                sse += (a * x[j] + b - y[j]) ** 2 / (2 * m)
            # 擬合結果判斷相差絕對值
            if abs(sse2 - sse) < epsilon:
                break
            else:
                sse2 = sse
        print('{0} * x + {1}'.format(a, b))

def main():
    try:
        print("scikit模擬結果:")
        solve_by_scikit()
        print("梯形下降模擬結果:")
        solve_by_gradient()
    except BaseException as e:
        print("\n=>錯誤: ", e)

if __name__ == "__main__":
    main()
複製程式碼

結果

求解多元

待研究

PS:機器學習方便還是很要求數學基礎的,可以說都是數學問題~

參考文章:梯度下降從放棄到入門 梯度下降小結

相關文章