#encoding=gbk
import numpy as np
import pandas as pd
import matplotlib.pyplot  as  plt
from sklearn import svm


#导入数据
def  read_data(paths):
    dataMatIn_Xs=[]
    dataMatIn_Ys=[]
    dataMatTest_Xs=[]
    dataMatTest_Ys=[] 
    m=[]
    i=0
    for path  in  paths:
        data=pd.read_excel(path)
        data =data.as_matrix()
        s,n=data.shape
        print(n)
        start=int(s*0.8) #取前百分之八十作为训练集合
        dataMatIn_Xs.append(data[0:start,0:8])
        dataMatIn_Ys.append(data[0:start,8])
        dataMatTest_Xs.append(data[start+1:s,0:8])
        dataMatTest_Ys.append(data[start+1:s,8])     
        m.append(np.shape(dataMatTest_Ys[i])[0])    
        i=i+1
    return dataMatIn_Xs,dataMatIn_Ys,dataMatTest_Xs,dataMatTest_Ys,m





# 多任务体现.重构核的设计
def my_kernel(X, Y):      # 自定义核函数
#    return np.dot(X, Y.T)       #测试什么都不加的情况
    u=2
    if(X.all()==Y.all()):    #测试多任务的情况.这里使用u代替u的分式.
        
        return np.dot(X, Y.T)**u
    else:
        return np.dot(X, Y.T)**(u+1)
    
    
    
    
#测试正确率,召回率  
def accuracy(result,m,dataMatTest_Y):    
    sum=0;
    for j in range(m):  
        if(result[j]==dataMatTest_Y[j]):
            sum+=1;
        
    accura = sum/m
    print("分类精确度: "+str(sum/m)) 
    
    reaccura=[]
    #测试类的召回率
    for s in  range(2):
        
        sum_0=0;
        sum_0_all=0;
        for j in range(m):  
            if(result[j]==s): 
                sum_0_all+=1
                if(result[j]==dataMatTest_Y[j]):
                    sum_0+=1
        if(sum_0_all==0) :
            print("分母为零")
            reaccura.append("0")
        else:
            temp =sum_0/sum_0_all
            reaccura.append(temp)
            print("类别"+str(s)+"的召回率为: "+str(sum_0/sum_0_all));
    return accura,reaccura
    
#main
#文件路径

path=["C:/Users/Administrator/Desktop/公共数据集/yeast/data_new.xlsx",    
      
      "C:/Users/Administrator/Desktop/公共数据集/yeast/data_new_ADSYN.xlsx",
      
      "C:/Users/Administrator/Desktop/公共数据集/yeast/data_new_SMOTE.xlsx"]



#设置惩罚因子,即C+和C-      
#419   321  365  628

C=[7,20]
class_weight_str={0:C[0],1:C[1]}




#训练
dataMatIn_Xs,dataMatIn_Ys,dataMatTest_Xs,dataMatTest_Ys,m = read_data(path)

# print(dataMatIn_Xs)
# print(dataMatIn_Ys)
# print(dataMatTest_Xs)
# print(dataMatTest_Ys)

string_class=["正态合成","ASDYN合成","SMOTE合成"]
keral=[my_kernel,"sigmoid","rbf"]
string_keral=["MTL","SIGIMOD","RBF"]
string_class=["Gaussian","ASDYN","SMOTE"]
#绘图

x=["MTL","Sigimod","rbf"]
reaccsss=[]


fig2 = plt.figure(figsize=(9,6))
ax2=fig2.add_subplot(1,1,1)
for i in  range(3): #外层循环不同合成方法
    accs=[]
    reaccs=[]

    for j in range(3): #内层循环不同核,底层是类别循环
        clf = svm.SVC(kernel=keral[j],class_weight=class_weight_str,gamma=0.001)  #这里使用多任务的核映射
        clf.fit(dataMatIn_Xs[i], dataMatIn_Ys[i])
        
        #预测
        print(string_class[i]+string_keral[j]+":")
        result = clf.predict(dataMatTest_Xs[i])
        acc,reacc = accuracy(result,m[i],dataMatTest_Ys[i])
        accs.append(acc)
        reaccs.append(reacc)        
        print("\n")
        
    reaccsss.append(reaccs)   
   
    ax2.plot(x,accs,marker=".",label=string_class[i])
ax2.set_ylabel("accuracy")
ax2.grid(color="pink",alpha=0.8)
ax2.set_ylim(0.4,1)
ax2.legend(loc="upper right")

#数据重组,便于绘图
pic_value1=[]
for i in range(3):
    pic_value2=[]
    pic_value1.append(pic_value2)
    
    for j in range(2):
        pic_value3=[]
        pic_value2.append(pic_value3)
        
        for t in range(3):
            pic_value3.append(reaccsss[i][t][j])    
            

for  i in  range(2): #类别
    fig = plt.figure(figsize=(15,10))
    ax=fig.add_subplot(2,2,i+1)
    for j in range(3): #合成方法,坐标点表示使用的核函数
        
        ax.set_ylabel("Call_rate")
        ax.plot(string_keral,pic_value1[j][i],marker="*")
        ax.grid(color="pink",alpha=0.8)
plt.show()