本文實例為大家分享了Python感知器算法實現的具體代碼,供大家參考,具體內容如下
先創建感知器類:用于二分類
# -*- coding: utf-8 -*- import numpy as np class Perceptron(object): """ 感知器:用于二分類 參照改寫 https://blog.csdn.net/simple_the_best/article/details/54619495 屬性: w0:偏差 w:權向量 learning_rate:學習率 threshold:準則閾值 """ 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*m(樣本有m個特征,x輸入就是m維),樣本數量為n y:類標,維度為n*1,取值1和-1(正樣本和負樣本) 返回: 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("類標只能為1或-1!請核對!") 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("迭代次數:",k," 錯分樣本數:",err) break return self def predict(self,x): """預測類別 參數: x:樣本,1*m維,1個樣本,m維特征 返回: yhat:預測的類標號,1或者-1,1代表正樣本,-1代表負樣本 """ if np.matmul(self.w,x.T)+self.w0>0: yhat=1 else: yhat=-1 return yhat def predict_value(self,x): """預測值 參數: x:樣本,1*m維,1個樣本,m維特征 返回: y:預測值 """ y=np.matmul(self.w,x.T)+self.w0 return y然后為Iris數據集創建一個Iris類,用于產生5折驗證所需要的數據,并且能產生不同樣本數量的數據集。
# -*- coding: utf-8 -*-"""Author:CommissarMa2018年5月23日 16點52分"""import numpy as npimport scipy.io as sio class Iris(object): """Iris數據集 參數: data:根據size裁剪出來的iris數據集 size:每種類型的樣本數量 way:one against the rest || one against one 注意: 此處規定5折交叉驗證(5-cv),所以每種類型樣本的數量要是5的倍數 多分類方式:one against the rest """ def __init__(self,size=50,way="one against the rest"): """ size:每種類型的樣本數量 """ data=sio.loadmat("C://Users//CommissarMa//Desktop//模式識別//課件ppt//PR實驗內容//iris_data.mat") iris_data=data['iris_data']#iris_data:原數據集,shape:150*4,1-50個樣本為第一類,51-100個樣本為第二類,101-150個樣本為第三類 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折驗證的第幾折,范圍:0,1,2,3,4 index_class:第幾類作為正類,類別號:負類樣本為-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#第幾個 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模式下需要提供負類的序號!") 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#第幾個 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:#放負類樣本 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("多分類方式錯誤!只能為one against one 或 one against the rest!") return return train_data,label_data def generate_test_data(self,index_fold): """生成測試數據 index_fold:5折驗證的第幾折,范圍:0,1,2,3,4 返回值: test_data:對應于第index_fold折的測試數據 label_data:類別號為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
新聞熱點
疑難解答