線性回歸可以用以下式子進行描述:
線性回歸即連續值的**問題,即根據給定的x以及模型引數θ的計算下,使得該方程的相應能夠無限逼近真實值y。
下面來舉乙個連續值**的簡單例子:
y = w * x + b
當知道兩組引數時,即可通過消元法求得引數w與b,即可得到該方程的精確解。即w = 1.477, b = 0.089
1.567 = w * 1 + b
3.043 = w * 2 + b
但是現實生活中往往不能夠精確求解,首先因為模型本身的方程是未知的,採集的資料都是帶有一定偏差的,其次我們觀測到的資料往往是帶有一定雜訊的。因此需要在上面式子中增加乙個雜訊因子ε,即
y = w * x + b + ε,我們假設ε~n(0,1) ,即 ε服從均值為0,方差為1的高斯分布,上述分布如下圖所示:
即絕大部分數值都分布在0的附近,離0較遠的數值分布較少。
通過高斯分布,上述求解過程可變為:
1.567 = w * 1 + b + eps
3.043 = w * 2 + b + eps
4.519 = w * 3 + b + eps
當我們想要得到合適的w與b的值時,需要多觀測幾組資料,通過多組觀測資料的迭代,獲得綜合性能最優的w與b。
那麼,我們如何求解w和b兩個引數呢?
這裡,需要引進乙個損失函式的概念,即真實值與**值之間的誤差,損失函式公式如下所示:
要想獲得效能最優的w與b,即在滿足損失函式達到最小值這個條件下的w與b,這裡的損失函式為每組觀測值誤差的求和。
所以,我們已經將模型引數w與b引數估計的問題轉化為最小化損失函式的問題。
接下來,我們使用梯度下降演算法來實現模型引數w與b的確定。在此處不多解釋到底什麼是梯度下降演算法,梯度可以簡單理解為函式的導數,梯度的方向即使得函式值增大的方向。例如:
比如目標函式為f(x),函式在上述三個點導數的方向指向函式值增大的方向,也可以理解為函式極大值的方向,當我們想最小化損失函式時,即求解損失函式的最小值,並獲得對應點的w與b,即我們想要獲得的模型引數。在上圖中,損失函式最小值大概在5的附近,讓模型引數驗證梯度的反方向進行異動,每次異動固定的步長,即learning rate,通過不斷地反覆迭代,找到最優的模型引數。
所以,我們需要對目標函式進行求偏導數,即分別計算w'與b'
並按照如下方式進行梯度的更新
python**推導:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
__author__ = 'seven'
import numpy as np
# y = wx + b
def calculate_loss_function(w, b, points):
total_error = 0
for i in range(len(points)):
x = points[i, 0]
y = points[i, 1]
total_error += ((w * x + b) - y) ** 2
return total_error / float(len(points))
def step_gradient(w_current, b_current, points, learning_rate):
w_gradient = 0
b_gradient = 0
n = float(len(points))
for i in range(len(points)):
x = points[i, 0]
y = points[i, 1]
# w_gradient = 2x(wx+b-y)
w_gradient += 2 / n * x * ((w_current * x + b_current) - y)
# b_gradient = 2(wx+b-y)
b_gradient += 2 / n * ((w_current * x + b_current) - y)
new_w = w_current - learning_rate * w_gradient
new_b = b_current - learning_rate * b_gradient
return [new_w, new_b]
def gradient_descent_runner(starting_w, starting_b, learning_rate, num_iterations, points):
w = starting_w
b = starting_b
for i in range(num_iterations):
w, b = step_gradient(w, b, points, learning_rate)
return [w, b]
def run():
# 構建模擬資料並新增雜訊,並擬合y = 1.477x + 0.089
x = np.random.uniform(0, 100, 100)
y = 1.477 * x + 0.089 + np.random.normal(0, 1, 1)
points = np.array([[i, j] for i, j in zip(x, y)])
learning_rate = 0.0001
initial_b = 0
initial_w = 0
num_iterations = 1000
print(f'原始損失函式值為:, w=, b=')
w, b = gradient_descent_runner(initial_w, initial_b, learning_rate, num_iterations, points)
print(f'經過次迭代, 損失函式的值為:, w=, b=')
if __name__ == '__main__':
run()
執行效果如下: 十大經典的機器學習演算法
弱人工智慧近幾年取得了重大突破,悄然間,已經成為每個人生活中必不可少的一部分。以我們的智慧型手機為例,看看到底溫藏著多少人工智慧的神奇魔術。下圖是一部典型的智慧型手機上安裝的一些常見應用程式,可能很多人都猜不到,人工智慧技術已經是手機上很多應用程式的核心驅動力。十大經典的機器學習演算法 圖1 智慧型...
十大經典排序演算法
載自 排序演算法是 資料結構與演算法 中最基本的演算法之一。排序演算法可以分為內部排序和外部排序,內部排序是資料記錄在記憶體中進行排序,而外部排序是因排序的資料很大,一次不能容納全部的排序記錄,在排序過程中需要訪問外存。常見的內部排序演算法有 插入排序 希爾排序 選擇排序 氣泡排序 歸併排序 快速排...
十大經典排序演算法
不穩定排序種類為4種 快速排序 核心思想是partition操作 二分法分而治之 平均時間複雜度nlogn 希爾排序 高階版的插入排序,先把間隔較遠的子串行排序,最後間隔為1時,等同於插入排序 插入排序在序列有序時,時間複雜度常數級,所以先讓子串行總體有序,能有效降低時間複雜度 平均時間複雜度n 1...