模式识别课程,统计了学生的身高体重鞋码等数据,利用贝叶斯分类器,分别计算协方差为单位阵、协方差为一样、协方差不同时候的准确率,以下为实现代码。代码很乱。。
数据下载:
链接:https://pan.baidu.com/s/1s5eQwivZQD941UB8QQvI0A
提取码:uhaz

# -*- coding: utf-8 -*-
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import mglearn 
import sklearn
from sklearn import metrics
import math
from sklearn.cross_validation import train_test_split
from sklearn.preprocessing import MinMaxScaler
path='C:/pypractise/4/liver_patient_prediction/survey_data.xls'#文件路径
def preprocessing_data(data): 
    #将数据缩放到0-1之间(程序中未使用)
    scaler=MinMaxScaler()
    scaler.fit(data)
    data_scaled=scaler.transform(data)
    return data_scaled
def pro_xiema():
    #处理鞋号统一成厘米数
    xiema=[]
    data=pd.read_excel(path)
    data_xiema=data['鞋码']
    data_np=np.array(data_xiema)
    for i in data_np:
        if i<30:
            xiema.append(float(i))
        elif i<45:
            i=(i+10)/2
            xiema.append(float(i))
        else:
            i=i/10
            xiema.append(float(i))
    return xiema
def read_data(path):
    #读数据   
    data=pd.read_excel(path)
    data['鞋码'] = pro_xiema()                   
    return data
def calculate_cov(height,weight,feet):
    #计算协方差和逆,输入为身高体重脚长,返回值为协方差矩阵和其逆
    xx=np.cov(height)
    yy=np.cov(weight)
    zz=np.cov(feet)
    xy=np.cov(height,weight)
    xz=np.cov(height,feet)
    yz=np.cov(weight,feet)
    cov=[[xx,xy[0,1],xz[0,1]],[xy[0,1],yy,yz[0,1]],[xz[0,1],yz[0,1],zz]]
    cov=np.array(cov,dtype=float)
    cov_inverse = np.linalg.inv(cov)
    return cov,cov_inverse
def bayes_net1(X_train): 
    ###贝叶斯网络计算协方差为单位阵,输入为train——身高体重鞋码的数据
    np.transpose(X_train)   
    #贝叶斯多维正太分布似然函数
    I=[[1,0,0],
       [0,1,1],
       [0,0,1]]
    data=read_data(path)
#  分别求男女的  协方差
    data_b=data[data['性别']==0]   #男生数据
    data_g=data[data['性别']==1]   #女生数据
#    #得到女生的参数
    data_g=np.array(data_g)
    data_b=np.array(data_b)
    height_g=data_g[:,2]   #得到女生的身高体重鞋码
    weight_g=data_g[:,3]
    feet_g=data_g[:,5]
#    #得到男生的参数
    height_b=data_b[:,2]   #得到男生的身高体重鞋码
    weight_b=data_b[:,3]
    feet_b=data_b[:,5]   
    
########****************************#############以上为读数据        
    #计算男生的均值矩阵
    u_b=[np.mean(height_b),np.mean(weight_b),np.mean(feet_b)]  
    #计算女生的均值矩阵
    u_g=[np.mean(height_g),np.mean(weight_g),np.mean(feet_g)]
    u_b=np.array([u_b])   #数组化
    u_g=np.array([u_g])   #数组化
#########****************************############以上为求u  
    #计算整体的公式
    #协方差为单位阵时候
    q1=math.log(np.linalg.det(I))
    q2=np.dot(np.dot((X_train-u_b),I),np.transpose(X_train-u_b))
    q3=3*math.log(2*3.14)
    q4=math.log(np.linalg.det(I))
    q5=np.dot(np.dot((X_train-u_g),I),np.transpose(X_train-u_g))
    ln_b=-1/2*(q1+q2+q3)
    ln_g=-1/2*(q4+q5+q3)       
    #进行预测,并返回男生还是女生
    if ln_b-ln_g>0:
        pre=0
    else:
        pre=1    
    return pre    
def bayes_net2(X_train): 
    ###贝叶斯网络(协方差一样)计算,输入为train——身高体重鞋码的数据
    np.transpose(X_train)   
    data=read_data(path)
    #分别的得到身高体重鞋码的数据
    data_h=data['身高']   
    data_w=data['体重']
    data_x=data['鞋码']
#  分别求男女的u值
    data_b=data[data['性别']==0]   #男生数据
    data_g=data[data['性别']==1]   #女生数据
#    #得到女生的参数
    data_g=np.array(data_g)
    data_b=np.array(data_b)
    height_g=data_g[:,2]   #得到女生的身高体重鞋码
    weight_g=data_g[:,3]
    feet_g=data_g[:,5]
#    #得到男生的参数
    height_b=data_b[:,2]   #得到男生的身高体重鞋码
    weight_b=data_b[:,3]
    feet_b=data_b[:,5]       
########****************************#############以上为读数据 
       
    #计算男生的均值矩阵
    u_b=[np.mean(height_b),np.mean(weight_b),np.mean(feet_b)]  
    #计算女生的均值矩阵
    u_g=[np.mean(height_g),np.mean(weight_g),np.mean(feet_g)]
    u_b=np.array([u_b])   #数组化
    u_g=np.array([u_g])   #数组化 
    #    计算整体协方差和逆
    cov_all,cov_all_inversed=calculate_cov(data_h,data_w,data_x)
#########****************************############以上为求u和协方差矩阵    

    #计算整体的公式
    q1=math.log(np.linalg.det(cov_all))
    q2=np.dot(np.dot((X_train-u_b),cov_all_inversed),np.transpose(X_train-u_b))
    q3=3*math.log(2*3.14)
    q4=math.log(np.linalg.det(cov_all))
    q5=np.dot(np.dot((X_train-u_g),cov_all_inversed),np.transpose(X_train-u_g))    
    ln_b=-1/2*(q1+q2+q3)
    ln_g=-1/2*(q4+q5+q3)       
    #进行预测,并返回男生还是女生
    if ln_b-ln_g>0:
        pre=0
    else:
        pre=1 
    return pre    
def bayes_net3(X_train): 
    ###贝叶斯网络计算(分开求cov),输入为train——身高体重鞋码的数据
    np.transpose(X_train)   
    data=read_data(path)
    #分别的得到身高体重鞋码的数据
#  分别求男女的  协方差
    data_b=data[data['性别']==0]   #男生数据
    data_g=data[data['性别']==1]   #女生数据
#    #得到女生的参数
    data_g=np.array(data_g)
    data_b=np.array(data_b)
    height_g=data_g[:,2]   #得到女生的身高体重鞋码
    weight_g=data_g[:,3]
    feet_g=data_g[:,5]
#    #得到男生的参数
    height_b=data_b[:,2]   #得到男生的身高体重鞋码
    weight_b=data_b[:,3]
    feet_b=data_b[:,5]       
########****************************#############以上为读数据       
    #计算男生的均值矩阵
    u_b=[np.mean(height_b),np.mean(weight_b),np.mean(feet_b)]  
    #计算女生的均值矩阵
    u_g=[np.mean(height_g),np.mean(weight_g),np.mean(feet_g)]
    u_b=np.array([u_b])   #数组化
    u_g=np.array([u_g])   #数组化
   #求男生的协方差矩阵和其逆矩阵,输入参数为男身高体重鞋码
    cov_b,cov_b_inversed=calculate_cov(height_b,weight_b,feet_b) 
   #求女生的协方差矩阵和其逆矩阵,输入参数为女身高体重鞋码
    cov_g,cov_g_inversed=calculate_cov(height_g,weight_g,feet_g)      
   
#########****************************############以上为求u和协方差矩阵    
#    协方差为各自求的时候算Ln
    q1=math.log(np.linalg.det(cov_b))
    q2=np.dot(np.dot((X_train-u_b),cov_b_inversed),np.transpose(X_train-u_b))
    q3=3*math.log(2*3.14)
    q4=math.log(np.linalg.det(cov_g))
    q5=np.dot(np.dot((X_train-u_g),cov_g_inversed),np.transpose(X_train-u_g))
    ln_b=-1/2*(q1+q2+q3)
    ln_g=-1/2*(q4+q5+q3)       
    #进行预测,并返回男生还是女生
    if ln_b-ln_g>0:
        pre=0
    else:
        pre=1 
    return pre    
def data_scatter(x,y):   
    data=read_data(path)   
    data_b=data[data['性别']==0]   #男生数据
    data_g=data[data['性别']==1]   #女生数据
    data_b=np.array(data_b) 
    data_g=np.array(data_g) 
    #特征: 2为身高  3为体重,4为年龄,5为鞋码
    plt.scatter(data_b[:,x],data_b[:,y],c='r',label="boy",s=60)
    plt.scatter(data_g[:,x],data_g[:,y],c='b',label="girl",s=60)
    plt.xlabel('height')
    plt.ylabel('xiema')
    plt.legend(loc='upper right')
    plt.show()
def train1():    
    #机器学习的贝叶斯分类
    feature= ['身高', '体重', '鞋码']     
    data=read_data(path)
    X=data[feature]    
    y=data['性别']        
    X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.30)            
    from sklearn.naive_bayes import GaussianNB
    clf = GaussianNB()
    clf = clf.fit(X_train, y_train)
    y_pred=clf.predict(X_test)
    print("样本总数: %d 错误样本数 : %d" % (X_test.shape[0],(y_test != y_pred).sum()))
    print("sorce:{:.2f}".format(np.mean(y_pred==y_test)))

def train2():
    count=0
    feature= ['身高', '体重', '鞋码']     
    data=read_data(path)
    X=data[feature]    
    y=data['性别']
    X=np.array(X) 
    y=np.array(y)
    for i in range(len(y)):
        shuju=X[i:i+1]  
        #依次取数据(身高 体重 脚长)进行预测 
        y_pre=bayes_net3(shuju)
        if y_pre==y[i]:
            count+=1        #预测正确就加一
    acc=count/len(y)        #计算准确率
    print("准确率是:{}".format(acc))

train2()
#特征: 2为身高  3为体重,4为年龄,5为鞋码
#data_scatter(2,3)

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐