python實(shí)現(xiàn)感知器算法(批處理)
本文實(shí)例為大家分享了Python感知器算法實(shí)現(xiàn)的具體代碼,供大家參考,具體內(nèi)容如下
先創(chuàng)建感知器類:用于二分類
# -*- coding: utf-8 -*- import numpy as np class Perceptron(object): """ 感知器:用于二分類 參照改寫 https://blog.csdn.net/simple_the_best/article/details/54619495 屬性: w0:偏差 w:權(quán)向量 learning_rate:學(xué)習(xí)率 threshold:準(zhǔn)則閾值 """ def __init__(self,learning_rate=0.01,threshold=0.001): self.learning_rate=learning_rate self.threshold=threshold def train(self,x,y): """訓(xùn)練 參數(shù): x:樣本,維度為n*m(樣本有m個(gè)特征,x輸入就是m維),樣本數(shù)量為n y:類標(biāo),維度為n*1,取值1和-1(正樣本和負(fù)樣本) 返回: self:object """ self.w0=0.0 self.w=np.full(x.shape[1],0.0) k=0 while(True): k+=1 dJw0=0.0 dJw=np.zeros(x.shape[1]) err=0.0 for i in range(0,x.shape[0]): if not (y[i]==1 or y[i]==-1): print("類標(biāo)只能為1或-1!請(qǐng)核對(duì)!") break update=self.learning_rate*0.5*(y[i]-self.predict(x[i])) dJw0+=update dJw+=update*x[i] err+=np.abs(0.5*(y[i]-self.predict(x[i]))) self.w0 += dJw0 self.w += dJw if np.abs(np.sum(self.learning_rate*dJw))<self.threshold or k>500: print("迭代次數(shù):",k," 錯(cuò)分樣本數(shù):",err) break return self def predict(self,x): """預(yù)測(cè)類別 參數(shù): x:樣本,1*m維,1個(gè)樣本,m維特征 返回: yhat:預(yù)測(cè)的類標(biāo)號(hào),1或者-1,1代表正樣本,-1代表負(fù)樣本 """ if np.matmul(self.w,x.T)+self.w0>0: yhat=1 else: yhat=-1 return yhat def predict_value(self,x): """預(yù)測(cè)值 參數(shù): x:樣本,1*m維,1個(gè)樣本,m維特征 返回: y:預(yù)測(cè)值 """ y=np.matmul(self.w,x.T)+self.w0 return y
然后為Iris數(shù)據(jù)集創(chuàng)建一個(gè)Iris類,用于產(chǎn)生5折驗(yàn)證所需要的數(shù)據(jù),并且能產(chǎn)生不同樣本數(shù)量的數(shù)據(jù)集。
# -*- coding: utf-8 -*- """ Author:CommissarMa 2018年5月23日 16點(diǎn)52分 """ import numpy as np import scipy.io as sio class Iris(object): """Iris數(shù)據(jù)集 參數(shù): data:根據(jù)size裁剪出來的iris數(shù)據(jù)集 size:每種類型的樣本數(shù)量 way:one against the rest || one against one 注意: 此處規(guī)定5折交叉驗(yàn)證(5-cv),所以每種類型樣本的數(shù)量要是5的倍數(shù) 多分類方式:one against the rest """ def __init__(self,size=50,way="one against the rest"): """ size:每種類型的樣本數(shù)量 """ data=sio.loadmat("C:\\Users\\CommissarMa\\Desktop\\模式識(shí)別\\課件ppt\\PR實(shí)驗(yàn)內(nèi)容\\iris_data.mat") iris_data=data['iris_data']#iris_data:原數(shù)據(jù)集,shape:150*4,1-50個(gè)樣本為第一類,51-100個(gè)樣本為第二類,101-150個(gè)樣本為第三類 self.size=size self.way=way self.data=np.zeros((size*3,4)) for r in range(0,size*3): self.data[r]=iris_data[int(r/size)*50+r%size] def generate_train_data(self,index_fold,index_class,neg_class=None): """ index_fold:5折驗(yàn)證的第幾折,范圍:0,1,2,3,4 index_class:第幾類作為正類,類別號(hào):負(fù)類樣本為-1,正類樣本為1 """ if self.way=="one against the rest": fold_size=int(self.size/5)#將每類樣本分成5份 train_data=np.zeros((fold_size*4*3,4)) label_data=np.full((fold_size*4*3),-1) for r in range(0,fold_size*4*3): n_class=int(r/(fold_size*4))#第幾類 n_fold=int((r%(fold_size*4))/fold_size)#第幾折 n=(r%(fold_size*4))%fold_size#第幾個(gè) if n_fold<index_fold: train_data[r]=self.data[n_class*self.size+n_fold*fold_size+n] else: train_data[r]=self.data[n_class*self.size+(n_fold+1)*fold_size+n] label_data[fold_size*4*index_class:fold_size*4*(index_class+1)]=1 elif self.way=="one against one": if neg_class==None: print("one against one模式下需要提供負(fù)類的序號(hào)!") return else: fold_size=int(self.size/5)#將每類樣本分成5份 train_data=np.zeros((fold_size*4*2,4)) label_data=np.full((fold_size*4*2),-1) for r in range(0,fold_size*4*2): n_class=int(r/(fold_size*4))#第幾類 n_fold=int((r%(fold_size*4))/fold_size)#第幾折 n=(r%(fold_size*4))%fold_size#第幾個(gè) if n_class==0:#放正類樣本 if n_fold<index_fold: train_data[r]=self.data[index_class*self.size+n_fold*fold_size+n] else: train_data[r]=self.data[index_class*self.size+(n_fold+1)*fold_size+n] if n_class==1:#放負(fù)類樣本 if n_fold<index_fold: train_data[r]=self.data[neg_class*self.size+n_fold*fold_size+n] else: train_data[r]=self.data[neg_class*self.size+(n_fold+1)*fold_size+n] label_data[0:fold_size*4]=1 else: print("多分類方式錯(cuò)誤!只能為one against one 或 one against the rest!") return return train_data,label_data def generate_test_data(self,index_fold): """生成測(cè)試數(shù)據(jù) index_fold:5折驗(yàn)證的第幾折,范圍:0,1,2,3,4 返回值: test_data:對(duì)應(yīng)于第index_fold折的測(cè)試數(shù)據(jù) label_data:類別號(hào)為0,1,2 """ fold_size=int(self.size/5)#將每類樣本分成5份 test_data=np.zeros((fold_size*3,4)) label_data=np.zeros(fold_size*3) for r in range(0,fold_size*3): test_data[r]=self.data[int(int(r/fold_size)*self.size)+int(index_fold*fold_size)+r%fold_size] label_data[0:fold_size]=0 label_data[fold_size:fold_size*2]=1 label_data[fold_size*2:fold_size*3]=2 return test_data,label_data
然后我們進(jìn)行訓(xùn)練測(cè)試,先使用one against the rest策略:
# -*- coding: utf-8 -*- from perceptron import Perceptron from iris_data import Iris import numpy as np if __name__=="__main__": iris=Iris(size=50,way="one against the rest") correct_all=0 for n_fold in range(0,5): p=[Perceptron(),Perceptron(),Perceptron()] for c in range(0,3): x,y=iris.generate_train_data(index_fold=n_fold,index_class=c) p[c].train(x,y) #訓(xùn)練完畢,開始測(cè)試 correct=0 x_test,y_test=iris.generate_test_data(index_fold=n_fold) num=len(x_test) for i in range(0,num): maxvalue=max(p[0].predict_value(x_test[i]),p[1].predict_value(x_test[i]), p[2].predict_value(x_test[i])) if maxvalue==p[int(y_test[i])].predict_value(x_test[i]): correct+=1 print("錯(cuò)分?jǐn)?shù)量:",num-correct,"錯(cuò)誤率:",(num-correct)/num) correct_all+=correct print("平均錯(cuò)誤率:",(num*5-correct_all)/(num*5))
然后使用one against one 策略去訓(xùn)練測(cè)試:
# -*- coding: utf-8 -*- from perceptron import Perceptron from iris_data import Iris import numpy as np if __name__=="__main__": iris=Iris(size=10,way="one against one") correct_all=0 for n_fold in range(0,5): #訓(xùn)練 p01=Perceptron()#0類和1類比較的判別器 p02=Perceptron() p12=Perceptron() x,y=iris.generate_train_data(index_fold=n_fold,index_class=0,neg_class=1) p01.train(x,y) x,y=iris.generate_train_data(index_fold=n_fold,index_class=0,neg_class=2) p02.train(x,y) x,y=iris.generate_train_data(index_fold=n_fold,index_class=1,neg_class=2) p12.train(x,y) #測(cè)試 correct=0 x_test,y_test=iris.generate_test_data(index_fold=n_fold) num=len(x_test) for i in range(0,num): vote0=0 vote1=0 vote2=0 if p01.predict_value(x_test[i])>0: vote0+=1 else: vote1+=1 if p02.predict_value(x_test[i])>0: vote0+=1 else: vote2+=1 if p12.predict_value(x_test[i])>0: vote1+=1 else: vote2+=1 if vote0==max(vote0,vote1,vote2) and int(vote0)==int(y_test[i]): correct+=1 elif vote1==max(vote0,vote1,vote2) and int(vote1)==int(y_test[i]): correct+=1 elif vote2==max(vote0,vote1,vote2) and int(vote2)==int(y_test[i]): correct+=1 print("錯(cuò)分?jǐn)?shù)量:",num-correct,"錯(cuò)誤率:",(num-correct)/num) correct_all+=correct print("平均錯(cuò)誤率:",(num*5-correct_all)/(num*5))
實(shí)驗(yàn)結(jié)果如圖所示:
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
python實(shí)現(xiàn)切割url得到域名、協(xié)議、主機(jī)名等各個(gè)字段的例子
今天小編就為大家分享一篇python實(shí)現(xiàn)切割url得到域名、協(xié)議、主機(jī)名等各個(gè)字段的例子,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-07-07python庫Celery異步發(fā)送電子郵件定時(shí)生成報(bào)告實(shí)戰(zhàn)示例
這篇文章主要介紹了python庫Celery異步發(fā)送電子郵件定時(shí)生成報(bào)告實(shí)戰(zhàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01Python使用unittest進(jìn)行有效測(cè)試的示例詳解
這篇文章主要介紹了如何使用?unittest?來編寫和運(yùn)行單元測(cè)試,希望通過閱讀本文,大家能了解?unittest?的基本使用方法,以及如何使用?unittest?中的斷言方法和測(cè)試用例組織結(jié)構(gòu)2023-06-06Python模擬登陸淘寶并統(tǒng)計(jì)淘寶消費(fèi)情況的代碼實(shí)例分享
借助urllib、urllib2和BeautifulSoup等幾個(gè)模塊的常用爬蟲開發(fā)組合,我們能夠輕易實(shí)現(xiàn)一份淘寶對(duì)賬單,這里我們就來看一則Python模擬登陸淘寶并統(tǒng)計(jì)淘寶消費(fèi)情況的代碼實(shí)例分享:2016-07-07Python中Django與Echarts的結(jié)合用法圖文詳解
ECharts是一個(gè)第三方控件,下面這篇文章主要給大家介紹了關(guān)于Python中Django與Echarts的結(jié)合用法,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2022-10-10Django User 模塊之 AbstractUser 擴(kuò)展詳解
這篇文章主要介紹了Django User 模塊之 AbstractUser 擴(kuò)展詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-03-03python新手經(jīng)常遇到的17個(gè)錯(cuò)誤分析
這篇文章主要介紹了python新手經(jīng)常遇到的17個(gè)錯(cuò)誤分析,需要的朋友可以參考下2014-07-07Python快速實(shí)現(xiàn)簡(jiǎn)易貪吃蛇小游戲的示例代碼
貪吃蛇(也叫做貪食蛇)游戲是一款休閑益智類游戲,有PC和手機(jī)等多平臺(tái)版本。既簡(jiǎn)單又耐玩。本文將利用Python語言快速實(shí)現(xiàn)簡(jiǎn)易貪吃蛇小游戲,感興趣的可以嘗試一下2022-10-10