【實戰案例+代碼】梯度下降法求解線性回歸的python實現及其結果可視化(一)

作者:博觀厚積 Python愛好者社區--專欄作者

簡書專欄:jianshu.com/u/2f376f777

公眾號:Python愛好者社區

編者註:本文包含了使用Python2.X讀取數據、數據處理、作圖,構建梯度下降法函數求解一元線性回歸,並對結果進行可視化展示,是非常綜合的一篇文章,包含了Python的數據操作、可視化與機器學習等內容。學習了這一篇文章就大概了解或掌握相關Python編程與數據分析等內容。另外,本文還巧妙地進行了一個設計,這使得本文Python代碼也可用於多元線性回歸,這是區別與現有網路上大多數梯度下降法求解線性回歸的Python實現不同,具體會在文中說明。

一、梯度下降法與回歸分析

梯度下降法則是一種最優化演算法,它是用迭代的方法求解目標函數得到最優解,是在cost function(成本函數)的基礎上,利用梯度迭代求出局部最優解。在這裡關於梯度下降法不做過多介紹,相關資料已經很多且後邊還會結合構建的函數進行分析,借用網上常用的一個比喻去直觀解釋。

比如,我們在一座大山上的某處位置,由於我們不知道怎麼下山,於是決定走一步算一步,也就是在每走到一個位置的時候,求解當前位置的梯度,沿著梯度的負方向,也就是當前最陡峭的位置向下走一步,然後繼續求解當前位置梯度,向這一步所在位置沿著最陡峭最易下山的位置走一步。這樣一步步的走下去,一直走到覺得我們已經到了山腳。當然這樣走下去,有可能我們不能走到山腳,而是到了某一個局部的山峰低處。

回歸在數學上來說是給定一個點集,能夠用一條曲線去擬合之,如果這個曲線是一條直線,那就被稱為線性回歸,線性回歸大家應該很熟悉,在這裡也不過多解釋,後邊構造代碼的時候也會去分析一些,在回歸分析中,只包括一個自變數和一個因變數,即y=a+bx+u稱為一元線性回歸分析。若是包含多個因變數則是多元線性回歸,即y=a+b1x1+b2x2+…+bnxn+u。

二、用Python讀取所要使用的數據

數據來自於UCI的機器學習資料庫中的Auto-mpg汽車燃料效率(mpg),共有398個樣本,以及9個變數,分別是mpg(燃料效率)、cylinders(發動機里的氣缸數量)、displacement(發動機的位移)、horsepower(發動機的馬力,有缺失值)、weight(汽車的重量)、acceleration(汽車的加速性能)、model year(汽車類型的生產年份)、car name(汽車品牌)等等。在導入numpy、pandas、matplotlib、math等數據處理相關模塊後,通過讀取url來導入數據,部分數據網頁呈現形式截圖如下:

網頁數據呈現形式有兩個需要注意的地方(這也是許多UCI數據的特點):一是沒有表頭,我們就在代碼中構建name列表並加入pd.read_csv中,否則的話數據第一行就會作為表頭;二是數據間用空格來間隔,我們就在pd.read_cs加入delim_whitespace=True來分列,默認分隔符為逗號。

import numpy as np import pandas as pd import matplotlib.pyplot as plt import mathurl = https://archive.ics.uci.edu/ml/machine-learning-databases/auto-mpg/auto-mpg.datanames =["mpg","cylinders","displacement","horsepower", "weight","acceleration","model year","origin","car name"]cars = pd.read_csv(url, delim_whitespace=True,names=names)#值與值之間,使用空白字元來指定你想要的分隔符cars.head(5)

得到結果:

對其中的mpg與acceleration繪製散點圖如下:

plt.scatter(cars["mpg"] ,cars["acceleration"]) #mpg燃料效率;acceleration汽車的加速性能plt.xlabel(mpg)plt.ylabel(acceleration)#設置坐標軸標籤plt.show()

三、數據處理——構建X、Y變數

將mpg,weight列單獨拿出來,作為構建回歸分析的X、Y變數,代碼如下:

data = cars[[mpg,acceleration]]#選取表格中的mpg,weight列data.insert(0, Ones, 1) #在data第1-2列之間插入全是1的一列數# set X (training data) and y (target variable)cols = data.shape[1] #計算data的列數,在這裡cols為3X = data.iloc[:,0:cols-1] y = data.iloc[:,cols-1:cols]

在這裡可能很多人會有疑問:為什麼要插入一列全是1的數據?為什麼還要採用iloc選取列的函數來重新定義X、y,本文分析的變數mpg,weight不是已經有了么?

因此,在這裡我們需要對回歸分析模型著重說一下。事實上,無論是一元線性回歸如y=β0+β1x,還是多元線性回歸如y=β0+β1x1+β2x2+…+βnxn+u,都可以用矩陣形式表示:

對於一元線性回歸,那麼上數矩陣就是取k=2,X變數也就是前兩列,即1和X21—X2n的矩陣,這就是為什麼要在data中插入全是1的一列意義所在,然後用iloc選取前兩列為X變數,最後一列為y變數。

四、先用最小二乘法求解回歸併計算損失函數

為了比較梯度下降法的求解結果,在這裡先用最小二乘法求解回歸,具體求解過程不再細述,其求解公式為:

線性回歸的平方差損失函數為:

代碼如下

X = np.matrix(X.values) y = np.matrix(y.values) #首先要把變數由data frames 轉變為矩陣形式from numpy.linalg import invfrom numpy import dottheta_n = dot(dot(inv(dot(X.T, X)), X.T), y) # theta = (XX)^(-1)XYprint theta_ndef computeCost(X, y, theta): inner = np.power(((X * theta.T) - y), 2)return np.sum(inner) / (2 * len(X))X.shape, theta_n.shape, y.shapelr_cost = computeCost(X, y, theta_n.T)print(lr_cost)

得到結果為:theta_n=[12.0811332, 0.1482892]T,為2*1(2行1列)矩陣,所以在計算損失函數中要進行轉置(theta_n.T)。因為涉及到矩陣計算,所以要用「X.shape, theta_n.shape, y.shape」命令看一下三個矩陣的形式。

得到的損失值lr_cost為3.12288717494。

待續。。。。

完整代碼地址:note.youdao.com/notesha**

寫作不易,特別是技術類的寫作,請大家多多支持,關注、點贊、轉發等等。

參考文獻

Machine Learning Exercises In Python,Part 1,

johnwittenauer.net/mach**

(吳恩達筆記 1-3)——損失函數及梯度下降

blog.csdn.net/wearge/ar**

梯度下降法求解線性回歸之python實現

blog.csdn.net/just_do_i

讚賞作者

推薦閱讀:

深入淺出--梯度下降法及其實現
機器學習:用梯度下降法實現線性回歸
為什麼隨機梯度下降方法能夠收斂?
遺傳演算法寫的這麼厲害。。為什麼在最優化理論裡面罕見有應用,還是以梯度下降為主呢?
為什麼梯度的負方向是局部下降最快的方向?

TAG:可視化 | Python | 梯度下降 |