編者注:本文包含了使用Python2.X讀取數(shù)據(jù)、數(shù)據(jù)處理、作圖,構(gòu)建梯度下降法函數(shù)求解一元線性回歸,并對(duì)結(jié)果進(jìn)行可視化展示,是非常綜合的一篇文章,包含了Python的數(shù)據(jù)操作、可視化與機(jī)器學(xué)習(xí)等內(nèi)容。學(xué)習(xí)了這一篇文章就大概了解或掌握相關(guān)Python編程與數(shù)據(jù)分析等內(nèi)容。另外,本文還巧妙地進(jìn)行了一個(gè)設(shè)計(jì),這使得本文Python代碼也可用于多元線性回歸,這是區(qū)別與現(xiàn)有網(wǎng)絡(luò)上大多數(shù)梯度下降法求解線性回歸的Python實(shí)現(xiàn)不同,具體會(huì)在文中說明。
一、梯度下降法與回歸分析
梯度下降法則是一種最優(yōu)化算法,它是用迭代的方法求解目標(biāo)函數(shù)得到最優(yōu)解,是在cost function(成本函數(shù))的基礎(chǔ)上,利用梯度迭代求出局部最優(yōu)解。在這里關(guān)于梯度下降法不做過多介紹,相關(guān)資料已經(jīng)很多且后邊還會(huì)結(jié)合構(gòu)建的函數(shù)進(jìn)行分析,借用網(wǎng)上常用的一個(gè)比喻去直觀解釋。
比如,我們在一座大山上的某處位置,由于我們不知道怎么下山,于是決定走一步算一步,也就是在每走到一個(gè)位置的時(shí)候,求解當(dāng)前位置的梯度,沿著梯度的負(fù)方向,也就是當(dāng)前最陡峭的位置向下走一步,然后繼續(xù)求解當(dāng)前位置梯度,向這一步所在位置沿著最陡峭最易下山的位置走一步。這樣一步步的走下去,一直走到覺得我們已經(jīng)到了山腳。當(dāng)然這樣走下去,有可能我們不能走到山腳,而是到了某一個(gè)局部的山峰低處。
回歸在數(shù)學(xué)上來說是給定一個(gè)點(diǎn)集,能夠用一條曲線去擬合之,如果這個(gè)曲線是一條直線,那就被稱為線性回歸,線性回歸大家應(yīng)該很熟悉,在這里也不過多解釋,后邊構(gòu)造代碼的時(shí)候也會(huì)去分析一些,在回歸分析中,只包括一個(gè)自變量和一個(gè)因變量,即y=a+bx+u稱為一元線性回歸分析。若是包含多個(gè)因變量則是多元線性回歸,即y=a+b1x1+b2x2+…+bnxn+u。
二、用Python讀取所要使用的數(shù)據(jù)
數(shù)據(jù)來自于UCI的機(jī)器學(xué)習(xí)數(shù)據(jù)庫中的Auto-mpg汽車燃料效率(mpg),共有398個(gè)樣本,以及9個(gè)變量,分別是mpg(燃料效率)、cylinders(發(fā)動(dòng)機(jī)里的氣缸數(shù)量)、displacement(發(fā)動(dòng)機(jī)的位移)、horsepower(發(fā)動(dòng)機(jī)的馬力,有缺失值)、weight(汽車的重量)、acceleration(汽車的加速性能)、model year(汽車類型的生產(chǎn)年份)、car name(汽車品牌)等等。在導(dǎo)入numpy、pandas、matplotlib、math等數(shù)據(jù)處理相關(guān)模塊后,通過讀取url來導(dǎo)入數(shù)據(jù),部分?jǐn)?shù)據(jù)網(wǎng)頁呈現(xiàn)形式截圖如下:

網(wǎng)頁數(shù)據(jù)呈現(xiàn)形式有兩個(gè)需要注意的地方(這也是許多UCI數(shù)據(jù)的特點(diǎn)):一是沒有表頭,我們就在代碼中構(gòu)建name列表并加入pd.read_csv中,否則的話數(shù)據(jù)第一行就會(huì)作為表頭;二是數(shù)據(jù)間用空格來間隔,我們就在pd.read_cs加入delim_whitespace=True來分列,默認(rèn)分隔符為逗號(hào)。
其代碼如下:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import math
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/auto-mpg/auto-mpg.data'
names =["mpg","cylinders","displacement","horsepower",
"weight","acceleration","model year","origin","car name"]
cars = pd.read_csv(url, delim_whitespace=True,names=names)#值與值之間,使用空白字符來指定你想要的分隔符
cars.head(5)
得到結(jié)果:

對(duì)其中的mpg與acceleration繪制散點(diǎn)圖如下:
plt.scatter(cars["mpg"] ,cars["acceleration"]) #mpg燃料效率;acceleration汽車的加速性能
plt.xlabel('mpg')
plt.ylabel('acceleration')#設(shè)置坐標(biāo)軸標(biāo)簽
plt.show()

三、數(shù)據(jù)處理——構(gòu)建X、Y變量
將'mpg','weight'列單獨(dú)拿出來,作為構(gòu)建回歸分析的X、Y變量,代碼如下:
data = cars[['mpg','acceleration']]#選取表格中的'mpg','weight'列
data.insert(0, 'Ones', 1) #在data第1-2列之間插入全是1的一列數(shù)
# set X (training data) and y (target variable)
cols = data.shape[1] #計(jì)算data的列數(shù),在這里cols為3
X = data.iloc[:,0:cols-1]
y = data.iloc[:,cols-1:cols]
在這里可能很多人會(huì)有疑問:為什么要插入一列全是1的數(shù)據(jù)?為什么還要采用iloc選取列的函數(shù)來重新定義X、y,本文分析的變量'mpg','weight'不是已經(jīng)有了么?
因此,在這里我們需要對(duì)回歸分析模型著重說一下。事實(shí)上,無論是一元線性回歸如y=β0+β1x,還是多元線性回歸如y=β0+β1x1+β2x2+…+βnxn+u,都可以用矩陣形式表示:

對(duì)于一元線性回歸,那么上數(shù)矩陣就是取k=2,X變量也就是前兩列,即1和X21—X2n的矩陣,這就是為什么要在data中插入全是1的一列意義所在,然后用iloc選取前兩列為X變量,最后一列為y變量。
四、先用最小二乘法求解回歸并計(jì)算損失函數(shù)
為了比較梯度下降法的求解結(jié)果,在這里先用最小二乘法求解回歸,具體求解過程不再細(xì)述,其求解公式為:


X = np.matrix(X.values)
y = np.matrix(y.values) #首先要把變量由data frames 轉(zhuǎn)變?yōu)榫仃囆问?from numpy.linalg import inv
from numpy import dot
theta_n = dot(dot(inv(dot(X.T, X)), X.T), y) # theta = (X'X)^(-1)X'Y
print theta_n
def 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.shape
lr_cost = computeCost(X, y, theta_n.T)
print(lr_cost)
得到結(jié)果為:theta_n=[12.0811332, 0.1482892]T,為2*1(2行1列)矩陣,所以在計(jì)算損失函數(shù)中要進(jìn)行轉(zhuǎn)置(theta_n.T)。因?yàn)樯婕暗骄仃囉?jì)算,所以要用“X.shape, theta_n.shape, y.shape”命令看一下三個(gè)矩陣的形式。
得到的損失值lr_cost為3.12288717494。
待續(xù)。。。。
完整代碼地址:http://note.youdao.com/noteshare?id=4b0d35625b292621bdc8f31f31effa82**
寫作不易,特別是技術(shù)類的寫作,請(qǐng)大家多多支持,關(guān)注、點(diǎn)贊、轉(zhuǎn)發(fā)等等。
參考文獻(xiàn):
- Machine Learning Exercises In Python,Part 1,
http://www.johnwittenauer.net/machine-learning-exercises-in-python-part-1/** - (吳恩達(dá)筆記 1-3)——損失函數(shù)及梯度下降
http://blog.csdn.net/wearge/article/details/77073142?locationNum=9&fps=1** - 梯度下降法求解線性回歸之python實(shí)現(xiàn)
http://blog.csdn.net/just_do_it_123/article/details/51056260