Experimento 4 de minería de datos de la Universidad Tecnológica de Hebei Algoritmo bayesiano de clasificación de decisiones

1. Propósito experimental

(1) Familiarizado con el algoritmo de toma de decisiones Naive Bayes.
(2) Consultar la base de datos de clientes de AllElectronics para obtener la probabilidad previa y la probabilidad condicional de clase.
(3) Escriba un programa que utilice el algoritmo Naive Bayes para clasificar en el conjunto de muestras, ejecute el algoritmo de clasificación Naive Bayes en los datos relacionados con la tarea y depure el experimento.
(4) Escriba un informe de experimento.

2. Principios experimentales

1. Probabilidad a priori y probabilidad condicional de clase

Probabilidad previa : La probabilidad previa se define como el conjunto de muestras de entrenamiento que pertenece a C i C_iCyoEl número de muestras (tuplas) de la clase y el número total de muestras N i N_inorteyoLa relación se registra como P ( C i ) = N i NP(C_i)=\frac{N_i}{N}PAG ( Cyo)=nortenorteyo.
Probabilidad condicional de clase : La probabilidad condicional de clase se define como el conjunto de muestras de entrenamiento que pertenece a C i C_iCyoClases con características XXEl número de muestras (tuplas) de X ni n_inorteyoy pertenece a C i C_iCyoNúmero de muestras (tuplas) de la clase N i N_inorteyoLa relación se registra como P (P ( X∣C _ _yo)=norteyonorteyo

2. Toma de decisiones bayesiana

El método de decisión (clasificación) bayesiano asigna muestras (tuplas) a C i C_iCyoclase, si y sólo si
P ( C_i)>P(X|C_j)P(C_j), para 1\leq j\leq m, j\neq iP ( X∣C _ _yo) PAG ( Cyo)>P ( X∣C _ _j) PAG ( Cj) ,par 1jmetro ,j=i
entre las cuales, las muestras (tuplas) en el conjunto de muestras de entrenamiento se pueden dividir enmmcategoría m .

3. Contenido y procedimientos experimentales.

1. Contenido experimental

Utilice el clasificador bayesiano para clasificar el vector de características conocido X:

  1. El conjunto de muestra de entrenamiento (tupla) etiquetado por la clase de base de datos de clientes de AllElectronics está programado para calcular la
    probabilidad previa P (Ci) y la probabilidad condicional de clase P (X | Ci), y la función y el método de implementación del código clave se señalan en el informe experimental;

  2. Utilice la programación del método de clasificación bayesiano para clasificar los vectores de características X y señale las funciones y los métodos de implementación de los fragmentos clave del programa en el informe experimental ;
  3. Utilice la muestra de prueba para estimar la tasa de error de clasificación;
  4. Dibuja un diagrama de bloques de un programa o rutina en tu informe de laboratorio.

2. Pasos experimentales

Dado que este problema de clasificación es para determinar si los clientes están dispuestos a comprar computadoras, es decir, C1 corresponde a compra_computadora = sí y C2 corresponde a compra_computadora = no, que es un problema de clasificación de dos categorías. Los pasos experimentales son los siguientes:

  1. Determine los atributos característicos y las divisiones: explore la base de datos proporcionada y descubra los atributos característicos divididos;

  2. Obtenga muestras de capacitación: es decir, el conjunto de muestras de capacitación (tupla) marcado por la clase de base de datos de clientes de AllElectronics dada ;
  3. Calcule la probabilidad previa de cada categoría en la muestra de entrenamiento: P(Ci), i=1, 2;
  4. Calcule la probabilidad condicional de clase en la muestra de entrenamiento: Sea el vector de características (atributos) X, programa para calcular la
    probabilidad condicional de clase P (X | Ci), i = 1, 2;
  5. Clasificar usando un clasificador;

3. Diagrama de bloques del programa

Insertar descripción de la imagen aquí

4. Muestras experimentales

datos.txt
Insertar descripción de la imagen aquí

5. Código experimental

#!/usr/bin/env python  
# -*- coding: utf-8 -*-
#
# Copyright (C) 2021 #
# @Time    : 2022/5/30 21:26
# @Author  : Yang Haoyuan
# @Email   : [email protected]
# @File    : Exp4.py
# @Software: PyCharm

import pandas as pd
import numpy as np
from sklearn.model_selection import KFold
import argparse

parser = argparse.ArgumentParser(description='Exp4')
parser.add_argument('--mode', type=str, choices=["KFold", "train", "test"])
parser.add_argument('--k', type=int, default=7)
parser.add_argument('--AGE', type=str, choices=["youth", "middle_aged", "senior"])
parser.add_argument('--INCOME', type=str, choices=["high", "medium", "low"])
parser.add_argument('--STUDENT', type=str, choices=["yes", "no"])
parser.add_argument('--CREDIT', type=str, choices=["excellent", "fair"], default="fair")
parser.set_defaults(augment=True)
args = parser.parse_args()
print(args)


# 载入数据集
def loadDataset(filename):
    dataSet = []
    with open(filename, 'r') as file_to_read:
        while True:
            lines = file_to_read.readline()  # 整行读取数据
            if not lines:
                break
            p_tmp = [str(i) for i in lines.split(sep="\t")]
            p_tmp[len(p_tmp) - 1] = p_tmp[len(p_tmp) - 1].strip("\n")
            dataSet.append(p_tmp)

    return pd.DataFrame(dataSet, columns=["AGE", "INCOME", "STUDENT", "CREDIT", "BUY"])


# 计算总样本数和各类数量
def count_total(data):
    count = {
    
    }
    group_df = data.groupby(["BUY"])

    count["yes"] = group_df.size()["yes"]
    count["no"] = group_df.size()["no"]

    total = count["yes"] + count["no"]
    return count, total


# 计算各类概率
def cal_base_rates(categories, total):
    rates = {
    
    }
    for label in categories:
        priori_prob = categories[label] / total
        rates[label] = priori_prob
    return rates


# 计算各类条件概率
def f_prob(data, count):
    likelihood = {
    
    'yes': {
    
    }, 'no': {
    
    }}

    # 根据AGE(youth, middle_aged, senior)和BUY(yes, no)统计概率
    df_group = data.groupby(['AGE', 'BUY'])
    try:
        c = df_group.size()["youth", "yes"]
    except:
        c = 0
    likelihood['yes']['youth'] = c / count['yes']

    try:
        c = df_group.size()["youth", "no"]
    except:
        c = 0
    likelihood['no']['youth'] = c / count['no']

    try:
        c = df_group.size()["middle_aged", "yes"]
    except:
        c = 0
    likelihood['yes']['middle_aged'] = c / count['yes']

    try:
        c = df_group.size()["middle_aged", "no"]
    except:
        c = 0
    likelihood['no']['middle_aged'] = c / count['no']

    try:
        c = df_group.size()["senior", "yes"]
    except:
        c = 0
    likelihood['yes']['senior'] = c / count['yes']

    try:
        c = df_group.size()["senior", "no"]
    except:
        c = 0
    likelihood['no']['senior'] = c / count['no']

    # 根据INCOME(high, medium, low)和BUY(yes, no)统计概率
    df_group = data.groupby(['INCOME', 'BUY'])
    try:
        c = df_group.size()["high", "yes"]
    except:
        c = 0
    likelihood['yes']['high'] = c / count['yes']

    try:
        c = df_group.size()["high", "no"]
    except:
        c = 0
    likelihood['no']['high'] = c / count['no']

    try:
        c = df_group.size()["medium", "yes"]
    except:
        c = 0
    likelihood['yes']['medium'] = c / count['yes']

    try:
        c = df_group.size()["medium", "no"]
    except:
        c = 0
    likelihood['no']['medium'] = c / count['no']

    try:
        c = df_group.size()["low", "yes"]
    except:
        c = 0
    likelihood['yes']['low'] = c / count['yes']

    try:
        c = df_group.size()["low", "no"]
    except:
        c = 0
    likelihood['no']['low'] = c / count['no']

    # 根据STUDENT(yes, no)和BUY(yes, no)统计概率
    df_group = data.groupby(['STUDENT', 'BUY'])
    try:
        c = df_group.size()["yes", "yes"]
    except:
        c = 0
    likelihood['yes']['yes'] = c / count['yes']

    try:
        c = df_group.size()["yes", "no"]
    except:
        c = 0
    likelihood['no']['yes'] = c / count['no']

    try:
        c = df_group.size()["no", "yes"]
    except:
        c = 0
    likelihood['yes']['no'] = c / count['yes']

    try:
        c = df_group.size()["no", "no"]
    except:
        c = 0
    likelihood['no']['no'] = c / count['no']

    # 根据CREDIT(excellent, fair)和BUY(yes, no)统计概率
    df_group = data.groupby(['CREDIT', 'BUY'])
    try:
        c = df_group.size()["excellent", "yes"]
    except:
        c = 0
    likelihood['yes']['excellent'] = c / count['yes']

    try:
        c = df_group.size()["excellent", "no"]
    except:
        c = 0
    likelihood['no']['excellent'] = c / count['no']

    try:
        c = df_group.size()["fair", "yes"]
    except:
        c = 0
    likelihood['yes']['fair'] = c / count['yes']

    try:
        c = df_group.size()["fair", "no"]
    except:
        c = 0
    likelihood['no']['fair'] = c / count['no']

    return likelihood


# 训练
def train(train_data):
    # 获取各类数量和训练样本总数
    count, total = count_total(train_data)
    # 获取先验概率
    priori_prob = cal_base_rates(count, total)
    # 保存先验概率
    np.save("priori_prob.npy", priori_prob)
    # 获取各特征的条件概率
    feature_prob = f_prob(train_data, count)
    # 保存条件概率
    np.save("feature_prob.npy", feature_prob)
    print("训练完成")


# 分类器
def NaiveBayesClassifier(AGE=None, INCOME=None, STUDENT=None, CREDIT=None):
    res = {
    
    }
    priori_prob = np.load('priori_prob.npy', allow_pickle=True).item()
    feature_prob = np.load('feature_prob.npy', allow_pickle=True).item()
    # 根据特征计算各类的概率
    for label in ['yes', 'no']:
        prob = priori_prob[label]
        prob *= feature_prob[label][AGE] * feature_prob[label][INCOME] * feature_prob[label][STUDENT] \
                * feature_prob[label][CREDIT]
        res[label] = prob
    print("预测概率:", res)
    # 选择概率最高的类作为分类结果
    res = sorted(res.items(), key=lambda kv: kv[1], reverse=True)
    return res[0][0]


# 测试
def test(test_data):
    correct = 0
    for idx, row in test_data.iterrows():
        prob = NaiveBayesClassifier(row["AGE"], row["INCOME"], row["STUDENT"], row["CREDIT"])
        if prob == row["BUY"]:
            correct = correct + 1
    return correct / test_data.shape[0]


# 启用k-折交叉验证
def KFoldEnabled():
    kf = KFold(n_splits=args.k)
    data_set = loadDataset("date.txt")
    corr = 0
    for train_idx, test_idx in kf.split(data_set):
        train_data = data_set.loc[train_idx]
        test_data = data_set.loc[test_idx]
        train(train_data)
        corr = corr + test(test_data)

    print("k折交叉验证正确率: ", corr / 7)


if __name__ == '__main__':
    if args.mode == "KFold":
        KFoldEnabled()
    if args.mode == "train":
        train_data = loadDataset("date.txt")
        train(train_data)
    if args.mode == "test":
        '''priori_prob = np.load('priori_prob.npy', allow_pickle=True).item()
        print("先验概率: ", priori_prob)
        feature_prob = np.load('feature_prob.npy', allow_pickle=True).item()
        print("类条件概率: ", feature_prob)'''
        ret = NaiveBayesClassifier(args.AGE, args.INCOME, args.STUDENT, args.CREDIT)
        print("预测结果: ", ret)

4. Resultados experimentales

Insertar descripción de la imagen aquí
Utilice validación cruzada k-fold para entrenamiento y prueba, predicción
Insertar descripción de la imagen aquí
del modelo de entrenamiento k = 7
Insertar descripción de la imagen aquí

5. Análisis experimental

Este experimento implementa principalmente el algoritmo de clasificación Naive Bayes.

El método bayesiano se basa en el principio de Bayes y utiliza el conocimiento de la probabilidad y la estadística para clasificar conjuntos de datos de muestra. Debido a su sólida base matemática, la tasa de falsos positivos del algoritmo de clasificación bayesiano es muy baja. La característica del método bayesiano es combinar la probabilidad previa y la probabilidad posterior, lo que evita el sesgo subjetivo de usar solo la probabilidad previa y el fenómeno de sobreajuste de usar solo información de muestra. El algoritmo de clasificación bayesiano muestra una alta precisión cuando el conjunto de datos es grande y el algoritmo en sí es relativamente simple.
El algoritmo bayesiano ingenuo se simplifica basándose en el algoritmo bayesiano, es decir, se supone que los atributos son condicionalmente independientes entre sí cuando se proporciona el valor objetivo. Es decir, ninguna variable de atributo tiene una proporción mayor con el resultado de la decisión, y ninguna variable de atributo tiene una proporción menor con el resultado de la decisión. Aunque esta simplificación reduce en cierta medida el efecto de clasificación del algoritmo de clasificación bayesiano, en escenarios de aplicación reales, simplifica enormemente la complejidad del método bayesiano.

Esto mejora la solidez de la clasificación Naive Bayes, pero, de hecho, su suposición de independencia entre atributos también limita su rendimiento de clasificación.

No hay distinción entre el conjunto de entrenamiento y el conjunto de validación en estos datos experimentales. Para verificar el rendimiento del clasificador Naive Bayes en este conjunto de datos, utilicé el algoritmo de validación cruzada K-fold. La precisión de la clasificación final fue solo del 50%, lo que creo que se puede atribuir a la pequeña cantidad de conjuntos de datos, lo que provocó que el ingenuo clasificador de Bayes no estuviera suficientemente capacitado para esta tarea.

Guardo los datos de entrenamiento como un archivo .npy para poder leer directamente los parámetros y realizar la clasificación al aplicar la clasificación.

Supongo que te gusta

Origin blog.csdn.net/d33332/article/details/127462258
Recomendado
Clasificación