import os
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import ListedColormap
os.chdir(r'D:\projects\wordpress\ex52')
os.getcwd()

class Perceptron(object):
    #Rosenblatt's perceptron
    def __init__(self,eta=0.01,n_iter=10):
        self.eta=eta # learning rate, [0,1]
        self.n_iter=n_iter # passes over the training dataset 

    def fit(self,X,y): # fitting training data
        # X = training vector, shape = [n_samples,n_features]
        # n_samples = number of samples
        # n_features = number of features
        # y = target values, shape = [n_samples]
        self.w_=np.zeros(1+X.shape[1]) # weights after fitting
        self.errors_ = [] # number of misclassification in every epoch
        
        for _ in range(self.n_iter):
            errors = 0
            for xi, target in zip(X,y):
                update = self.eta * (target - self.predict(xi))
                self.w_[1:] = self.w_[1:] + update * xi
                self.w_[0] = self.w_[0] + update
                errors = errors + int(update != 0.0)
            
            self.errors_.append(errors)
        
        return self

    def net_input(self,X):
        # calculate net input
        return np.dot(X,self.w_[1:]) + self.w_[0]
    
    def predict(self,X):
        # return class label after unit step 
        return np.where(self.net_input(X) >= 0.0,1,-1)
           
url='https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data'
df=pd.read_csv(url,header=None)
print(df.tail())
y=df.iloc[0:100,4].values
y=np.where(y=='Iris-setosa',-1,1)
X=df.iloc[0:100,[0,2]].values
plt.scatter(X[:50,0],X[:50,1],color='red',marker='o',label='Setosa')
plt.scatter(X[50:100,0],X[50:100,1],color='blue',marker='x',label='Versicolor')
plt.xlabel('Sepal Length ')
plt.ylabel('Petal Length')
plt.legend(loc='upper left')
plt.tight_layout()
plt.savefig("example52.png", dpi=100)
plt.show()

ppn=Perceptron(eta=0.1,n_iter=10)
ppn.fit(X,y)
plt.plot(range(1,len(ppn.errors_)+1),ppn.errors_,marker='o')
plt.xlabel('Epoch')
plt.ylabel('Number of classification errors')
plt.tight_layout()
plt.savefig("example52_2.png", dpi=100)
plt.show()

def plot_decision_regions(X,y,classifier,resolution=0.02):
    markers=('s','x','o','^','v')
    colors=('red','blue','lightgreen','gray','cyan')
    cmap = ListedColormap(colors[:len(np.unique(y))])
    x1_min,x1_max=X[:,0].min()-1,X[:,0].max()+1
    x2_min,x2_max=X[:,1].min()-1,X[:,1].max()+1
    xx1,xx2=np.meshgrid(np.arange(x1_min,x1_max,resolution),
                        np.arange(x2_min,x2_max,resolution))
    Z=classifier.predict(np.array([xx1.ravel(),xx2.ravel()]).T)
    Z=Z.reshape(xx1.shape)
    plt.contourf(xx1,xx2,Z,alpha=0.2,cmap=cmap)
    plt.xlim(xx1.min(),xx1.max())
    plt.ylim(xx2.min(),xx2.max())
    
    for idx,cl in enumerate(np.unique(y)):
        plt.scatter(x=X[y==cl,0],y=X[y==cl,1],alpha=0.9,color=cmap(idx),marker=markers[idx],label=cl)

plot_decision_regions(X, y, classifier=ppn)
plt.xlabel('sepal length [cm]')
plt.ylabel('petal length [cm]')
plt.legend(loc='upper left')    
plt.tight_layout()
plt.savefig("example52_3.png", dpi=100)
plt.show()
plt.close()