机器学习-作业2-贝叶斯网络

作业2

实现能处理连续属性的贝叶斯网络。

思路

  1. 怎么自动判断该属性是离散还是连续:计算该属性的不同值有多少个,超过10个就认为是连续,否则是离散的。
  2. 离散的:统计该类、该属性、该值的各个数量,计算概率,为后续计算做准备
  3. 连续的:统计该类、该属性的平均值、方差、标准差,为后续计算做准备
  4. 预测:
    1. 离散的: a n s w e r = w h i c h    j    i n    m a x ( P ( C j ) ∏ P ( w i ∣ C j ) ) answer=which \ \ j \ \ in \ \ max(P(C_j)\prod P(w_i|C_j)) answer=which  j  in  max(P(Cj)P(wiCj))
    2. 连续的: a n s w e r = w h i c h    j    i n    m a x ( 1 2 π σ j e − ( x − u j ) 2 2 σ j 2 ) answer=which \ \ j \ \ in \ \ max(\frac{1}{\sqrt{2π}σ_j} e^{-\frac{(x-u_j)^2}{2σ_j^2}}) answer=which  j  in  max(2π σj1e2σj2(xuj)2)
'''
6. 实现了训练、预测、输出精确度的功能
7. 实现自动判断特征是离散 还是连续,分别对离散、连续特征进行计算
8. 离散连续的判断依据:整个训练集中 该特征的特征值的数量 是否大于10?
'''
import numpy as np
import pandas as pd
from sklearn.datasets import make_blobs
from sklearn.model_selection import train_test_split

class naive_bayes():
    def __init__(self):
        self.pi=3.1415926
        pass

    def fit(self,x,y):
        self.sign_feature=[]#标记特征为离散 false  连续true
        for k in range(x.shape[1]):#特征k
            count=x[x.columns[k]].unique()#计算特征k有多少不同的值
            if len(count)<10:#如果小于10个 处理为离散值 否则处理为连续值
                self.sign_feature.append('false')#标记该特征为离散
            else:
                self.sign_feature.append('true')#标记该特征为连续

        self.classes=y[y.columns[0]].unique()#统计y不同的值 

        self.x_avg={}#计算类j特征k的各个数值平均
        self.s_2={}#方差
        self.s={}#标准差
        self.class_condition_prob={}#类条件概率初始化为字典


        for j in  self.classes:#遍历类j
            for k in range(x.shape[1]):#特征k

                if self.sign_feature[k]:#如果是连续值
                    x_avg=0
                    x_x=[]
                    for i in range(x.shape[0]):#遍历x
                        if y[y.columns[0]][i]==j :
                            x_avg+=x[x.columns[k]][i]
                            x_x.append(x[x.columns[k]][i])
                    x_avg/=len(x_x)
                    s_2=0
                    for i in range(len(x_x)):
                        s_2+=(x_x[i]-x_avg)*(x_x[i]-x_avg)
                    s_2/=len(x_x)
                    s=np.sqrt(s_2)
                    self.x_avg[(j,k)]=x_avg#平均值
                    self.s_2[(j,k)]=s_2#方差
                    self.s[(j,k)]=s#标准差
                else:
                    class_count=y[y.columns[0]].value_counts()#即每个类中样本数  类数*属于该类的样本数
                    #类先验概率
                    self.class_prior=class_count/len(y)  #属于该类的样本数/总样本数
                    p_x_y=x[(y==j).values][x.columns[k]].value_counts()
                    for i in p_x_y.index:
                        self.class_condition_prob[(j,k,i)] = p_x_y[i]/class_count[j]


    def predict(self,x):
        ans=[]
        for i in range(len(x)):
            res=[]
            for j in self.classes:#遍历类 
                p_x_y=1
                for k in range(x.shape[1]):#遍历特征值
                    if self.sign_feature[k]:#如果是连续值
                        temp0=1/(np.sqrt(2*self.pi)*self.s[tuple([j]+[k])])
                        temp1=-(self.x_avg[tuple([j]+[k])]-x[x.columns[k]][i])*(self.x_avg[tuple([j]+[k])]-x[x.columns[k]][i])
                        temp2=temp1/(2*self.s_2[tuple([j]+[k])])
                        p_x_y*=temp0*np.exp(temp2)
                    else:
                        p_y=self.class_prior[j]#类先验概率 
                        p_x_y*=p_y
                        temp=x[x.columns[k]][i]
                        p_x_y*=self.class_condition_prob[tuple([j]+[k]+[temp])]
                res.append(p_x_y)#获得每个类下的概率
            ans.append( self.classes[np.argmax(res)] )#  np.argmax(res) 返回最大值的索引
        return ans


    def accuracy(self,y_hat,y):#计算准确率
        ans=0
        for i in range(len(y_hat)):
            if y_hat[i]==y[i]:
                ans+=1
        print(y_hat==y)#查看错误了哪个? 只错了1个
        return ans/len(y)

    

#构造数据集
x,y=make_blobs(
    n_samples=500,  #样本数
    n_features=2,    #特征值数
    centers=2,  #类标签数
    cluster_std=[1.0,3.0],  #每个类别的方差
    shuffle=True,   #默认为True
    random_state=8)

feature1=np.random.randint(5,size=x.shape[0])

x=np.column_stack((feature1,x))#增加离散的特征值

x_train,x_test,y_train,y_test=train_test_split(x,y,random_state=8)

x_list=['x1','x2','x3']
y_list=['y']
x_train=pd.DataFrame(x_train,columns=x_list)
x_test=pd.DataFrame(x_test,columns=x_list)
y_train=pd.DataFrame(y_train,columns=y_list)#使用列表形式


model=naive_bayes()
model.fit(x_train,y_train)#训练

y_hat=model.predict(x_test)#预测
print(y_hat)#输出预测结果

score=model.accuracy(y_hat,y_test)
print(score)#输出准确率



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MORE_77

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值