<jupyter_start><jupyter_text>author: leezeeyee   date: 2021/4/13  link: [github](https://github.com/easilylazy/pattern-recognition)<jupyter_code>import pandas as pd

import random
import numpy as np<jupyter_output><empty_output><jupyter_text>Lecture 9编程作业给定IRIS数据集做如下题目实验，该数据集有三类目标，每个类别有50个样本，每个样本有四维特征。实验时每个类别随机选30个样本进行训练，另外20个样本用于测试。  1. 以感知器算法为基础分类算法，编写一个OVO多类分类器算法，对上述数据集进行实验，分析结果。    2. 编写Softmax算法实现多类别分类，对上述数据集进行实验，分析结果。<jupyter_code>irisData=pd.read_csv('iris.csv')
irisData.head()
irisData['Species'][60]<jupyter_output><empty_output><jupyter_text>types<jupyter_code>setosas=irisData[irisData['Species']=='setosa']
versicolors=irisData[irisData['Species']=='versicolor']
virginicas=irisData[irisData['Species']=='virginica']
setosas.head()
versicolors.head()
virginicas.head()<jupyter_output><empty_output><jupyter_text>sample for train<jupyter_code>def some(x, n):
    return x[random.sample(x.index, n)]
virginicas.index
trainSetosas=setosas.sample(frac=0.6)
trainVersi=versicolors.sample(frac=0.6)
trainVirgin=virginicas.sample(frac=0.6)
testSetosas=setosas.sample(frac=0.4)
testVersi=versicolors.sample(frac=0.4)
testVirgin=virginicas.sample(frac=0.4)
wholeData=[]
for data in [setosas,versicolors,virginicas]:
    values=data[['Sepal.Length',	'Sepal.Width',	'Petal.Length',	'Petal.Width']]
    wholeData.append(np.asarray(values.iloc[:,:]))
trainData=[]
for train in [trainSetosas,trainVersi,trainVirgin]:
    values=train[['Sepal.Length',	'Sepal.Width',	'Petal.Length',	'Petal.Width']]
    trainData.append(np.asarray(values.iloc[:,:]))
testData=[]
for test in [testSetosas,testVersi,testVirgin]:
    values=test[['Sepal.Length',	'Sepal.Width',	'Petal.Length',	'Petal.Width']]
    testData.append(np.asarray(values.iloc[:,:]))<jupyter_output><empty_output><jupyter_text>Train<jupyter_code>def addSingleBias(X):
    N=X.shape[0]
    X=np.reshape(X,[N,1])
    bias_vector=np.ones([1,1])
    return np.row_stack((bias_vector,X))
def addBias(X):
    '''
    为维数为N,d的向量X添加偏置向量
    Args:
        X(numpy.ndarray):shape为[N,d]
    Returns:
        numpy.ndarray:shape为[N,d+1]，且第一列列向量全为1
    '''
    
    try:
        N=X.shape[0]
        d=X.shape[1]
        if d == 1:
            return addSingleBias(X)
        bias_vector=np.ones([N,1])
        return np.column_stack((bias_vector,X))
        
    except:
        return addSingleBias(X)
trainData=np.asarray(trainData)
testData=np.asarray(testData)
trainData[0][:5]<jupyter_output><empty_output><jupyter_text>整体<jupyter_code>def Perce2(TrainX_sh,TrainY_sh):
    learning_rate=1
    minErr=60
    W=np.zeros([5,1])
    for iteration in range(20):
        for i in range(len(TrainX_sh)):
            X=TrainX_sh[i].reshape([5,1])
            y=TrainY_sh[i]
            if np.dot(W.transpose(),X)*y<=0:
                W_temp=W+learning_rate*y*X
                res=np.dot(TrainX_sh,W)*TrainY_sh
                err1=len(res[res<=0])
                res=np.dot(TrainX_sh,W_temp)*TrainY_sh
                err2=len(res[res<=0])
                # if err1>=err2:
                W=W_temp
            res=np.dot(TrainX_sh,W)*TrainY_sh
            err1=len(res[res<=0])
            if err1<minErr:
                    minErr=err1
                    # print('******************')
                    # print(W)
                    W_end=W
                    # print(err1) 
        if minErr==0:
            break
    return W_end<jupyter_output><empty_output><jupyter_text>train for weights<jupyter_code># 1 for left and -1 for right
rounds=[[0,1],[0,2],[1,2]]
# length of train data for 1 round
length=60
# Ws
Ws=[]
for round in rounds:
    print(round)
    left=round[0]
    right=round[1]
    # load data
    X1=addBias(trainData[left])
    X2=addBias(trainData[right])
    TrainX=np.row_stack([X1,X2])
    TrainY=np.r_[np.ones([len(X1),1]),-1*np.ones([len(X2),1])]
    X1_t=addBias(testData[left])
    X2_t=addBias(testData[right])
    TestX=np.r_[X1_t,X2_t]
    TestY=np.r_[np.ones([len(X1_t),1]),-1*np.ones([len(X2_t),1])]
   
    # shuffle
    numArray=np.arange(length)
    np.random.shuffle(numArray)

    TrainX_sh=TrainX[numArray]
    TrainY_sh=TrainY[numArray]
    # train
    W_end=Perce2(TrainX_sh,TrainY_sh)
    Ws.append(W_end)
    # test
    testRes=np.dot(TestX,W_end)*TestY
    err=len(testRes[testRes<=0])
    print(err)<jupyter_output>[0, 1]
0
[0, 2]
0
[1, 2]
0<jupyter_text>test OvO<jupyter_code>for test_i in range(len(testData)):
    print(test_i)
    X_t=addBias(testData[test_i])
    # X_t=addBias(wholeData[test_i])
    for X in X_t:
        records=np.zeros(len(testData))
        for i in range(len(rounds)):
            round=rounds[i]
            # print(round)
            left=round[0]
            right=round[1]
            W=Ws[i]
            # print(np.dot(X,W))
            res=np.dot(X,W)
            if res>0:
                records[left]+=1
            else:
                records[right]+=1
        # print(records)
        # print(np.argmax(records))
        if test_i!=np.argmax(records):
            print(W)
            print(X)<jupyter_output>0
1
2<jupyter_text>单轮  shuffle data<jupyter_code>length=60
numArray=np.arange(length)
np.random.shuffle(numArray)
X1=addBias(trainData[0])
X2=addBias(trainData[1])
TrainX=np.row_stack([X1,X2])
TrainY=np.r_[np.ones([len(X1),1]),-1*np.ones([len(X2),1])]
print(TrainX[25:35])
print(TrainY[25:35])
TrainX_sh=TrainX[numArray]
TrainY_sh=TrainY[numArray]
if np.not_equal(TrainX[numArray[0]],TrainX_sh[0]).any():
    print('error!')
learning_rate=0.1<jupyter_output><empty_output><jupyter_text>def Perce(X,y,w_ini,epoch=5,step=False,separable=True):    leastWrong=len(y)    totalMistake=len(y)    wT=w_ini.transpose()    for t in range(epoch):        wrong=0        print(t)        for i in range(len(y)):            ynE=np.dot(wT,np.transpose(X[i]))            if ynE*y[i]<=0:                 represent error, need to correct w                wT1=wT+y[i]*X[i]                if separable :                    wrong+=1                    wT=wT1                    if step:                        yield wT,wrong                else:                    res=np.multiply(np.dot(X,wT1.transpose()),y)                     mistake=len(res[res<=0])                    print(mistake)                    if mistake<totalMistake:                        wT=wT1                        totalMistake=mistake                        yield wT,mistake        if separable and wrong<leastWrong:            leastWrong=wrong            print('wrong time: ',end='')            print(wrong)            print(wT)            yield wT,wrong            if wrong==0:                break W=np.zeros([5,1])for i in Perce(TrainX_sh,TrainY_sh,w_ini=W,epoch=5,step=False,separable=False):    print(i)<jupyter_code>TrainY_sh[i]
learning_rate=1
minErr=60
W=np.zeros([5,1])
for iteration in range(20):
    for i in range(len(TrainX_sh)):
        # print(X1[i])
        X=TrainX_sh[i].reshape([5,1])
        # print(X)
        y=TrainY_sh[i]
        # print(X)
        # print(y)
        if np.dot(W.transpose(),X)*y<=0:
            W_temp=W+learning_rate*y*X
            # print(W_temp)
            res=np.dot(TrainX_sh,W)*TrainY_sh
            err1=len(res[res<=0])
            res=np.dot(TrainX_sh,W_temp)*TrainY_sh
            err2=len(res[res<=0])
            
            # if err1>=err2:
            W=W_temp
            # print(err1)
            # print(err2) 
        
        res=np.dot(TrainX_sh,W)*TrainY_sh
        err1=len(res[res<=0])
        # print(err1)
        if err1<minErr:
                minErr=err1
                print('******************')
                print(W)
                W_end=W
                print(err1)<jupyter_output>******************
[[1. ]
 [5.1]
 [3.8]
 [1.5]
 [0.3]]
30
******************
[[ 1. ]
 [ 0.8]
 [ 6.1]
 [-8.2]
 [-3.3]]
0<jupyter_text>validation<jupyter_code># W_end=np.asarray([[ 1.,   0.7 , 3.9 ,-8.2 ,-2.7]])
trainRes=np.dot(TrainX_sh,W_end)*TrainY_sh
err=len(trainRes[trainRes<=0])
print(err)
TestX=np.row_stack([addBias(testData[0]),addBias(testData[1])])
TestY=np.r_[np.ones([len(testData[0]),1]),-1*np.ones([len(testData[0]),1])]
testRes=np.dot(TestX,W_end)*TestY
err=len(testRes[testRes<=0])
print(err)
print(testData[0][:3])
print(testData[1][:3])
W_end=np.asarray([[1. , 4.5, 2.3, 1.3, 0.3]])
np.dot(TrainX_sh,W_end.transpose())*TrainY_sh

foo=np.asarray(values.iloc[:,:])<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.16557161629434955, 'fraction_numerical': 0.027475809341775174, 'mean_word_length': 2.870550161812298, 'pattern_counts': {'":': 0, '<': 59, '<?xml version=': 0, '>': 45, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '11', 'dir': 'jupyter-structured-clean-dedup', 'id': '643893', 'license': 'MIT', 'n_tokens_mistral': 3547, 'n_tokens_neox': 3441, 'n_words': 385, 'path': 'multiClass/iris.ipynb', 'repo_name': 'easilylazy/pattern-recognition', 'size': '8371'}