Python实现朴素贝叶斯(Naive Bayesian algorithm)

前言

本文使用Python实现了Naive Bayesian分类算法,但只适用于连续性特征值,以后有时间再将离散型的进行补充。此外,对于连续性特征值,本文处理的方式是假设这些特征值服从正态分布,计算每一列特征值的均值和方差,从而得到他们的正态分布概率密度,通过概率密度就可以大致计算每个值对应的条件概率,然后就能得到数据成为某个标签的概率,然后选择对应概率最大的那个标签作为分类结果。本文使用的数据集为iris。

1. 导入所需包

import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
import scipy.stats as st

2. 载入数据

iris = pd.read_csv('iris.csv')

3. 实现Naive Bayesian

'''
说明:计算每个类别下每个特征的平均值和方差

参数:
    x_train:训练集
    y_train:训练标签
返回值:
    mean_and_variance: 每个类别下每个特征的平均值和方差
'''
def cal_mean_and_variance(x_train, y_train):
    labels = list(set(y_train)) # 数据包含的所有类别
    mean_and_variance = {} # 储存每个类别下每个特征的平均值和方差
    for label in labels:
        sameClassData = x_train[y_train == label] # 同一类别的数据
        mean_and_variance[label] = []
        for i in range(0, sameClassData.shape[1]):
            mean = sameClassData.iloc[:,i].mean() # 平均值
            std = sameClassData.iloc[:,i].std(ddof=1) # 无偏估计方差
            mean_and_variance[label].append((mean, std)) # 将平均值和方差组合成元组
    return mean_and_variance

'''
说明:计算模型的准确率

参数:
    pred:预测的标签
    real:真实的标签
返回值:
    accuracy:模型的准确率
'''

def accuracy(pred, real):
    pred_list = pred.to_list()
    real_list = real.to_list()
    corrNum = 0 # 当前模型预测正确的个数
    for i in range(0, len(pred_list)):
        if pred_list[i] == real_list[i]:
            corrNum += 1
    accuracy = float(corrNum) / len(pred_list)
    return accuracy

'''
说明:将数据分类

参数:
    X:待分类的数据
    mean_and_variance:每个类别下每个特征的平均值和方差
    y_train:训练标签
返回值:
    labels[maxInd]:预测的标签
'''

def classify(X, mean_and_variance, y_train):
    probs = [] # 储存数据属于各个类别的概率
    labels = [] # 对应的类别
    label_count = y_train.value_counts() # 各个标签的个数
    for key in mean_and_variance.keys():
        cond_prob = 1 # 以当前类别为条件的条件概率乘积
        for i in range(0, len(mean_and_variance[key])):
            prob_density = st.norm.pdf(X[i], mean_and_variance[key][i][0], mean_and_variance[key][i][1])
            cond_prob = cond_prob * prob_density
        prob = cond_prob * (float(label_count[key]) / len(y_train))
        probs.append(prob)
        labels.append(key)
    maxInd = np.argmax(probs)
    return labels[maxInd]

4. 测试模型

if __name__ == '__main__':
    x_train, x_test, y_train, y_test = train_test_split(iris.iloc[:,0:-1], iris.iloc[:,-1])
    m_and_v = cal_mean_and_variance(x_train, y_train)
    pred = x_test.apply(lambda x : classify(x, m_and_v, y_train), axis=1)
    print(accuracy(pred, y_test)) # 打印准确率

你可能感兴趣的:(python,机器学习,分类)