【實戰案例+代碼】梯度下降法求解線性回歸的python實現及其結果可視化(一)
作者:博觀厚積 Python愛好者社區--專欄作者
簡書專欄:https://www.jianshu.com/u/2f376f777ef1公眾號: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。待續。。。。完整代碼地址:http://note.youdao.com/noteshare?id=4b0d35625b292621bdc8f31f31effa82**寫作不易,特別是技術類的寫作,請大家多多支持,關注、點贊、轉發等等。參考文獻Machine Learning Exercises In Python,Part 1,
http://www.johnwittenauer.net/machine-learning-exercises-in-python-part-1/**
(吳恩達筆記 1-3)——損失函數及梯度下降
http://blog.csdn.net/wearge/article/details/77073142?locationNum=9&fps=1**梯度下降法求解線性回歸之python實現
http://blog.csdn.net/just_do_it_123/article/details/51056260讚賞作者
推薦閱讀:
※深入淺出--梯度下降法及其實現
※機器學習:用梯度下降法實現線性回歸
※為什麼隨機梯度下降方法能夠收斂?
※遺傳演算法寫的這麼厲害。。為什麼在最優化理論裡面罕見有應用,還是以梯度下降為主呢?
※為什麼梯度的負方向是局部下降最快的方向?