from sklearn.datasets import load_iris,load_breast_cancer,load_wine
import numpy as np
import matplotlib.pyplot as plt

class model:
    def __init__(self,lr=0.01):
        self.lr = lr

    def sigmoid_predict(self,X,W):
        G=[]
     #   print('X======',X)
      #  print('W======',W)
        for c in range(len(W)):
            G.append(1/(1+np.exp(-np.dot(X,W[c]))))

        return G
    def mse(self,pre,Y):
        loss = 0
        for c in range(len(Y)):
#            print(Y[c],"-",pre[c],"=",Y[c]-pre[c])
            loss += abs(Y[c]-pre[c])
        return loss

    def train(self,X,W,Y):
        loss = 0
        for i in range(len(X)): # data number i
    #        print("CURRENT WEIGHT = ",W)
            pre = self.sigmoid_predict(X[i],W) #pre is vector .. [about class1 predict, class2 ...]
            loss += self.mse(pre,Y[i])
            real = Y[i]
            for c in range(len(W)): # class number c
                for f in range(len(X[i])):
#                   print("c,f",c,f)
                    W[c][f] = W[c][f] - (self.lr *((Y[i][c] - pre[c])/abs(Y[i][c]-pre[c])) * (pre[c]*(1-pre[c])) * X[i][f])
#                    print("W",[c],[f],float(W[c][f]), '-',self.lr,'*','(',float(Y[i][c]-pre[c]),')','/',float(abs(Y[i][c]-pre[c])),'*','(',float(pre[c]),'*','(1-',float(pre[c]),')','*',float(X[i][f]))
#            print("=========================OTHER DATA X[",i,"]==========================================")
#        print("LOSS = ",loss)
        return W,loss                   
    def accuracy(self,X,W,Y):
        for i in range(len(X)):
            pre = self.sigmoid_predict(X[i],W)
            print('as a predict=',pre,'real value =',Y[i])

ml = model(lr = 0.001)

dataset = load_iris()
dataset = load_breast_cancer()
dataset = load_wine()
X = dataset.data
Y = dataset.target

y = Y.tolist()
for i in range(len(Y)):
    a = [0,0,0] # must have style general
    a[y[i]] = 1
    y[i] = a

W = np.zeros((max(Y)+1,len(X[0])))+0.5

testX = [
         [5.2,3.1,1.9,0.4] #0
        ,[6.9,3.2,4.8,1.3] #1
        ,[5.9,3.0,5.12,1.75] #2
        ,[7.7,3.8,6.7,2.2] #2
        ,[4.6,3.4,1.5,0.1] #0
        ,[5.6,2.8,3.65,1.29] #1
        ]
testY = [
        [1,0,0],
        [0,1,0],
        [0,0,1],
        [0,0,1],
        [1,0,0],
        [0,1,0]
        ]

#print("before Train predict = ",ml.sigmoid_predict(test,W))
for i in range(20000):
    W,loss = ml.train(X,W,y)
    print(i,'PER LOSS = ',loss)



print(ml.accuracy(testX,W,testY))















