編者注:本文包含了使用Python2.X讀取數據、數據處理、做圖,構建梯度降低法函數求解一元線性迴歸,並對結果進行可視化展現,是很是綜合的一篇文章,包含了Python的數據操做、可視化與機器學習等內容。學習了這一篇文章就大概瞭解或掌握相關Python編程與數據分析等內容。另外,本文還巧妙地進行了一個設計,這使得本文Python代碼也可用於多元線性迴歸,這是區別與現有網絡上大多數梯度降低法求解線性迴歸的Python實現不一樣,具體會在文中說明。python
1、梯度降低法與迴歸分析算法
梯度降低法則是一種最優化算法,它是用迭代的方法求解目標函數獲得最優解,是在cost function(成本函數)的基礎上,利用梯度迭代求出局部最優解。在這裏關於梯度降低法不作過多介紹,相關資料已經不少且後邊還會結合構建的函數進行分析,借用網上經常使用的一個比喻去直觀解釋。數據庫
好比,咱們在一座大山上的某處位置,因爲咱們不知道怎麼下山,因而決定走一步算一步,也就是在每走到一個位置的時候,求解當前位置的梯度,沿着梯度的負方向,也就是當前最陡峭的位置向下走一步,而後繼續求解當前位置梯度,向這一步所在位置沿着最陡峭最易下山的位置走一步。這樣一步步的走下去,一直走到以爲咱們已經到了山腳。固然這樣走下去,有可能咱們不能走到山腳,而是到了某一個局部的山峯低處。編程
迴歸在數學上來講是給定一個點集,可以用一條曲線去擬合之,若是這個曲線是一條直線,那就被稱爲線性迴歸,線性迴歸你們應該很熟悉,在這裏也不過多解釋,後邊構造代碼的時候也會去分析一些,在迴歸分析中,只包括一個自變量和一個因變量,即y=a+bx+u稱爲一元線性迴歸分析。如果包含多個因變量則是多元線性迴歸,即y=a+b1x1+b2x2+…+bnxn+u。
2、用Python讀取所要使用的數據數組
數據來自於UCI的機器學習數據庫中的Auto-mpg汽車燃料效率(mpg),共有398個樣本,以及9個變量,分別是mpg(燃料效率)、cylinders(發動機裏的氣缸數量)、displacement(發動機的位移)、horsepower(發動機的馬力,有缺失值)、weight(汽車的重量)、acceleration(汽車的加速性能)、model year(汽車類型的生產年份)、car name(汽車品牌)等等。在導入numpy、pandas、matplotlib、math等數據處理相關模塊後,經過讀取url來導入數據,部分數據網頁呈現形式截圖以下:ruby
![](http://static.javashuo.com/static/loading.gif)
網頁數據呈現形式有兩個須要注意的地方(這也是許多UCI數據的特色):一是沒有表頭,咱們就在代碼中構建name列表並加入pd.read_csv中,不然的話數據第一行就會做爲表頭;二是數據間用空格來間隔,咱們就在pd.read_cs加入delim_whitespace=True來分列,默認分隔符爲逗號。
其代碼以下:bash
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)
獲得結果:網絡
![](http://static.javashuo.com/static/loading.gif)
對其中的mpg與acceleration繪製散點圖以下:機器學習
plt.scatter(cars["mpg"] ,cars["acceleration"]) #mpg燃料效率;acceleration汽車的加速性能 plt.xlabel('mpg') plt.ylabel('acceleration')#設置座標軸標籤 plt.show()
![](http://static.javashuo.com/static/loading.gif)
3、數據處理——構建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爲3 X = 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,均可以用矩陣形式表示:
![](http://static.javashuo.com/static/loading.gif)
對於一元線性迴歸,那麼上數矩陣就是取k=2,X變量也就是前兩列,即1和X21—X2n的矩陣,這就是爲何要在data中插入全是1的一列意義所在,而後用iloc選取前兩列爲X變量,最後一列爲y變量。
4、先用最小二乘法求解迴歸並計算損失函數
爲了比較梯度降低法的求解結果,在這裏先用最小二乘法求解迴歸,具體求解過程再也不細述,其求解公式爲:
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
X = np.matrix(X.values)
y = np.matrix(y.values) #首先要把變量由data frames 轉變爲矩陣形式 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)
獲得結果爲: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。
def gradientDescent(X, y, theta, alpha, iters):
temp = np.matrix(np.zeros(theta.shape))#構建零值矩陣
parameters = int(theta.ravel().shape[1])#計算須要求解的參數個數
cost = np.zeros(iters) #構建iters個0的數組
for i in range(iters):
error = (X * theta.T) - y #計算hθ(x)-y
for j in range(parameters):
term = np.multiply(error, X[:,j])#計算兩矩陣(hθ(x)-y)x
temp[0,j] = theta[0,j] - ((alpha / len(X)) * np.sum(term))
theta = temp
cost[i] = computeCost(X, y, theta)
return theta, cost
theta,cost分別爲:
接下來,繪製擬合曲線
alpha = 0.001
iters = 100000
theta = np.matrix(np.array([0,0]))
# perform gradient descent to "fit" the model parameters
g, cost = gradientDescent(X, y, theta, alpha, iters)
g
computeCost(X, y, g)
x = np.linspace(data.mpg.min(), data.mpg.max(), 100)
print(x)
f = g[0, 0] + (g[0, 1] * x)
print(f)
fig,ax = plt.subplots(figsize=(8,6))
ax.plot(x, f, 'r', label='Prediction')
ax.scatter(data.mpg, data.acceleration, label='Traning Data') #散點
ax.legend(loc=2)
ax.set_xlabel('mpg')
ax.set_ylabel('acceleration')
最後繪製代價曲線
fig, bx = plt.subplots(figsize=(8,6))
bx.plot(np.arange(iters), cost, 'r')
bx.set_xlabel('Iterations')
bx.set_ylabel('Cost')
bx.set_title('Error vs. Training Epoch')
plt.show()
可知,iterations爲13000-2000時代價曲線基本穩定。
完整代碼地址: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
做者:博觀厚積連接:https://www.jianshu.com/p/82c7b3ceff66來源:簡書著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。