python與機器學習實戰 [何宇健] [2017.7第一版]
交流QQ:1825587919
交流WX:ly1825587919
機器學習緒論
- ......
機器學習常用術語
- ......
使用python進行機器學習
- ......
python一些第三方庫的安裝
- ......
第一個機器學習樣例
該問題來自Coursera上的斯坦福大學機器學習課程:
現有47個房子的面積和價格,需要建立一個模型對新的房價進行預測
即有這樣的理解:
- 輸入數據只有一維,即房子的面積
- 目標數據也只有一維,即房子的價格
- 需要做的,就是根據已知房子的面積和價格的關系進行機器學習
雖然機器學習算法很多,但通常而言,進行機器學習的過程會包含以下三步:
- 獲取與處理數據
- 選擇與訓練模型
- 評估與可視化結果
獲取與處理數據
原始數據如下:
1 2104,399900 2 1600,329900 3 2400,369000 4 1416,232000 5 3000,539900 6 1985,299900 7 1534,314900 8 1427,198999 9 1380,212000 10 1494,242500 11 1940,239999 12 2000,347000 13 1890,329999 14 4478,699900 15 1268,259900 16 2300,449900 17 1320,299900 18 1236,199900 19 2609,499998 20 3031,599000 21 1767,252900 22 1888,255000 23 1604,242900 24 1962,259900 25 3890,573900 26 1100,249900 27 1458,464500 28 2526,469000 29 2200,475000 30 2637,299900 31 1839,349900 32 1000,169900 33 2040,314900 34 3137,579900 35 1811,285900 36 1437,249900 37 1239,229900 38 2132,345000 39 4215,549000 40 2162,287000 41 1664,368500 42 2238,329900 43 2567,314000 44 1200,299000 45 852,179900 46 1852,299900 47 1203,239500
在這個例子里,采取常用的將輸入數據標准化的做法,數學公式為X=(X-X拔)/std(X),X拔表示X的均值,std(X)表示X的標准差。
1 #導入庫 2 import numpy 3 import matplotlib.pyplot as plot 4 5 #定義存儲數組 x 和目標數組 y 6 x,y = [],[] 7 for sample in open(r'prices_data.txt','r'): 8 #調用python中的split方法並將逗號作為參數傳入 9 _x,_y = sample.split(',') 10 x.append(float(_x)) 11 y.append(float(_y)) 12 #轉為numpy數組進一步處理 13 x,y = numpy.array(x),numpy.array(y) 14 #標准化 15 x= (x-x.mean()) /x.std() 16 #以散點圖的形式畫出 17 plot.figure() 18 plot.scatter(x,y,c='g',s=6) 19 plot.show()
這段代碼即實現數據的可視化工作,下圖分別為將x不做標准化和做標准化后的運行結果
選擇與訓練模型
接下來便是選擇訓練模型,通過可視化數據,很有可能通過線性回歸中的多項式擬合來進行訓練。
PS:多項式擬合只是線性回歸的很小一部分
f(x|p;n)=p0xn+p1xn-1+p2xn-2+...+pn-1x+pn
L(p;n)=1/2(求和)[f(x|p;n)-y]2
其中f(x|p;n)就是模型,p,n都是模型的參數,L(p;n)則是模型的損失函數,這里采用常見的平方損失函數,也就是所謂的歐式距離(向量的二范數)
接下來就是最小化這個損失函數
#開始訓練 x0=numpy.linspace(-2,4,100) def get_model(deg): min_p=numpy.polyfit(x,y,deg) #該函數返回L(p;n)最小的參數p,亦即多項式的各項系數 yy=lambda input_x=x0:numpy.polyval(min_p,input_x) #根據輸入的值x(默認為x0),返回預測的值y, return yy
評估與可視化結果
為了簡單起見,我們取n=1,2,4,7,10,得到一些訓練出來的損失值
#根據參數n、輸入的x,y返回相對應的損失 def get_cost(deg,input_x,input_y): return 0.5* ((get_model(deg)(input_x) - input_y) ** 2).sum() #定義幾個不同的n進行測試 text=(1,2,4,7,10) for d in text: print(get_cost(d,x,y))
得到的結果如下:
96732238800.4
96709317398.4
94112406641.7
79655422575.4
75874846680.1
Process finished with exit code 0
分析可得出,似乎n=10優於n=7,4,2,而n=1最差
我們再直觀的做出圖像:
#畫出相應的圖像 plot.scatter(x,y,c='g',s=20) for d in text: plot.plot(x0,get_model(d)(),label='degree={}'.format(d)) plot.xlim(-2,4) plot.ylim(1e5,8e5) plot.legend() plot.show()
分析這張圖,可以發現,n=1和n=2時擬合的最好,而n=4,7,10都開始出現過擬合了,n=10 時已經非常不合理了
至此我們便解決了這個問題,取n=1,則函數模型為y=ax+b;參數為:y=[ 105764.13349282 340412.65957447]
即 y=105764x+340412
如果不進行標准化,得出的模型為y=[ 134.52528772 71270.49244873]
即y=134.5x+71270.5