菜鸟入门_Python_机器学习(1)_线性可分的双月实验
@sprt
*寫在開頭:博主在開始學(xué)習(xí)機(jī)器學(xué)習(xí)和Python之前從未有過任何編程經(jīng)驗(yàn),這個系列寫在學(xué)習(xí)這個領(lǐng)域一個月之后,完全從一個入門級菜鳥的角度記錄我的學(xué)習(xí)歷程,代碼未經(jīng)優(yōu)化,僅供參考。有錯誤之處歡迎大家指正。
系統(tǒng):win7-CPU;
編程環(huán)境:Anaconda2-Python2.7,IDE:pycharm5;
參考書籍:
《Neural Networks and Learning Machines(Third Edition)》- Simon Haykin;
《Machine Learning in Action》- Peter Harrington;
《Building Machine Learning Systems with Python》- Wili Richert;
C站里都有資源,也有中文譯本。
我很慶幸能跟隨老師從最基礎(chǔ)的東西學(xué)起,進(jìn)入機(jī)器學(xué)習(xí)的世界。*
第一課主要了解一下機(jī)器學(xué)習(xí)的概念和深度學(xué)習(xí)現(xiàn)在的主流的模型和成果,這方面在這篇博文里沒什么可說的,網(wǎng)上隨便搜。然后簡單強(qiáng)調(diào)了Python的幾個用到的庫,numpy、math、matplotlib等,我大部分還是網(wǎng)上自學(xué),給幾個參考鏈接:
http://www.2cto.com/kf/201407/317115.html
http://www.jb51.net/article/49397.htm
http://www.mamicode.com/info-detail-507676.html
http://www.xuebuyuan.com/1420264.html
http://www.2cto.com/kf/web/Python/
我花了一天的時間了解了Python的基本語句,然后來看我們的任務(wù):
Generate random data in two groups controlled by parameters r, w, d, Na, Nb, and plot out. (ref. p61 on Haykin)
?Implement Perceptron Convergence Algorithm p54 on Haykin in PyCharm, and then apply to your data sets with following different parameters
?r=10, w=2, d=2, Na=100, Nb=100
?r=10, w=2, d=-2, Na=100, Nb=100
《Neural Networks and Learning Machines(Third Edition)》這本書中對所謂的‘雙月’做了很多處理,簡單來說就是生成這樣一個東西:
看起來很簡單,但是我第一次編程還是比較蒙蔽的,莫名的恐懼和厭惡……總之多敲敲代碼就好了。好歹最后搞了出來:
# -*- coding:gb2312 -*- import matplotlib.pyplot as plt import numpy as np import math # 生成雙月 def point_sample(N,r,w,d):x_sample = []y_sample = []inner_r = r - (w/2)outer_r = r + (w/2)#point the area Awhile True:data_x_A = np.random.uniform(-outer_r,outer_r)data_y_A = np.random.uniform(0,outer_r)r_A = math.sqrt((data_x_A**2) + (data_y_A**2))if r_A >= inner_r and r_A <= outer_r:x_sample.append(data_x_A)y_sample.append(data_y_A)if len(x_sample) == N:breakelse:continueelse:continue#point the area Bwhile True:data_x_B = np.random.uniform(-outer_r + r,outer_r + r)data_y_B = np.random.uniform(-d - outer_r,-d)r_B = math.sqrt(((data_x_B - r)**2) + ((data_y_B + d)**2))if r_B >= inner_r and r_B <= outer_r:x_sample.append(data_x_B)y_sample.append(data_y_B)if len(x_sample) == 2 * N:breakelse:continueelse:continueplt.figure(1)plt.plot(x_sample,y_sample,'b*')data_xy = np.array([np.reshape(x_sample,len(x_sample)),np.reshape(y_sample,len(y_sample))]).transpose()return data_xy最后,為了方便之后處理都轉(zhuǎn)置成了二維的數(shù)據(jù)。
呃……似乎有點(diǎn)挫,給一個網(wǎng)上的版本,簡化了很多:
可以發(fā)現(xiàn)充分利用numpy庫可以讓代碼簡化很多。OK,雙月得到了,兩個區(qū)域之間的距離我們定義的較大,讓他們線性可分,然后用一個Rosenblatt感知機(jī)分開。
很多地方介紹機(jī)器學(xué)習(xí)都會首先介紹單層感知機(jī),作為之后神經(jīng)網(wǎng)絡(luò)的基礎(chǔ),它可以看做類似于神經(jīng)細(xì)胞的結(jié)構(gòu),多個輸入,各自有可訓(xùn)練權(quán)值,經(jīng)過求和并激活之后輸出
到底為什么要加偏置Bias呢?一種思想是,假設(shè)模型的輸出始終與真實(shí)的數(shù)據(jù)有差距,我們?yōu)榱酥鸩秸{(diào)整這個差距,我們在輸入層對每個樣本添加了一維特征,相當(dāng)于在輸出端添加了一個始終為一的觀察點(diǎn)。從這個角度去看,偏置是可以去掉的,我們可以通過不斷調(diào)整輸入的權(quán)值來優(yōu)化網(wǎng)絡(luò)。通常為了方便計算將偏置作為輸入的一部分:
其中所謂的學(xué)習(xí)率是自己設(shè)定的,我理解的就是給誤差一個權(quán)值,它不能太大,否則會讓權(quán)值在更新時跳過最優(yōu)值而不斷震蕩,也不能太小,否則會導(dǎo)致尋找最有權(quán)值的過程太慢。激活函數(shù)的目的是將輸入的加權(quán)和歸一化并更好的體現(xiàn)分類特性,因?yàn)槲覀円诸惖碾p月是線性可分的而且是兩類,激活函數(shù)用符號函數(shù)就好。而統(tǒng)計誤差的時候我們用常用的最小均方誤差(這個不了解的可以自己查),之后我們用這個誤差不斷更新權(quán)值,達(dá)到想要的分類效果。有兩種方式來判斷網(wǎng)絡(luò)時候達(dá)到我們想要的效果,一種是限定迭代次數(shù),另一種是看代價函數(shù)(誤差)值時候降低到我們設(shè)定的足夠低的標(biāo)準(zhǔn)。我這里使用第一種方法,一開始嘗試迭代50次,直接上代碼:
N = 100 d = -2 r = 10 w = 2 a = 0.1 num_MSE = [] num_step = [] data = dbmoon(N, d, r, w)x0 = [1 for x in range(1,201)] x = np.array([np.reshape(x0, len(x0)), np.reshape(data[0:2*N, 0], len(data)), np.reshape(data[0:2*N, 1], len(data))]).transpose() m = np.array([1, 0, 0]) b_pre = [1 for y in range(1, 101)] b_pos = [-1 for y in range(1, 101)] b=b_pre+b_posdef sgn(v):if v >= 0:return 1else:return -1 #compute y(n) def compute_yn(myw, myx):return sgn(np.dot(myw.T, myx)) #Update the weights def new_w(old_w, myd, myx, a):return old_w+a*(myd-compute_yn(old_w,myx))*myxfor ii in range(50):i = 0sum=0for xn in x:m = new_w(m, b[i], xn, a)sum += (b[i]-compute_yn(m, xn))**2+0.0i += 1#compute MSEmean_square =np.sqrt(sum/N/2)num_MSE.append(mean_square)print mean_squareprint iinum_step.append(ii+1) plt.subplot(212) plt.plot(num_step, num_MSE, 'r-')print m #draw The decision boundary testx = np.array(range(-15, 25)) testy = -testx*m[1]/m[2]-m[0]/m[2] plt.subplot(211) plt.plot(data[0:N, 0], data[0:N, 1], 'r*', data[N:2*N, 0], data[N:2*N, 1], 'b*', testx, testy, 'g--') plt.show()最后的結(jié)果:
分得很好,MSE曲線下降的也很快。但是當(dāng)我們把雙月之間的距離調(diào)成線性不可分時,分類效果很差,而且MSE曲線不斷震蕩,如何應(yīng)對這種情況我們之后討論。
總結(jié)
以上是生活随笔為你收集整理的菜鸟入门_Python_机器学习(1)_线性可分的双月实验的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 武大计算机导师蔡贤涛,程媛(武汉大学计算
- 下一篇: 基于MatlabSimulink的汽车等