Implementación manual de la clasificación bayesiana ingenua basada en la plataforma weka

1. Teorema de Bayes

Después de que ocurra el evento B, la probabilidad de que ocurra el evento A se puede expresar de la siguiente manera:

pags ( UN ∣ segundo ) = pags ( UN ∩ segundo ) PAGS ( segundo ) (1) p(A|B)=\frac{p(A\cap B)}{P(B)}\tag{1}pags ( UN B )=PAG ( B )pag ( unb )( 1 )

Después de que ocurra el evento A, la probabilidad de que ocurra el evento B se puede expresar de la siguiente manera:

pags ( segundo ∣ UN ) = pags ( UN ∩ segundo ) PAGS ( UN ) (2) p(B|A)=\frac{p(A\cap B)}{P(A)}\tag{2}pags ( segundo la )=P ( A )pag ( unb )( 2 )

Compara los dos:

PAGS ( UN ∣ segundo ) PAGS ( segundo ∣ UN ) = PAGS ( UN ) PAGS ( segundo ) (3) \frac{P(A|B)}{P(B|A)}=\frac{P(A) {P(B)}\etiqueta{3}PAG ( segundo UN )PAG ( UN B )=PAG ( B )P ( A )( 3 )

AgarreP ( B ∣ A ) P(B|A)Después de multiplicar P ( B A ) al lado derecho de la ecuación, tenemos el siguiente teorema de Bayes:

PAGS ( UN ∣ segundo ) = PAGS ( segundo ∣ UN ) PAGS ( UN ) PAGS ( segundo ) (4) P(A|B)=\frac{P(B|A)P(A)}{P(B) }\etiqueta{4}PAG ( UN B )=PAG ( B )PAGS ( segundo UN ) PAGS ( UN )( 4 )

2. Clasificación bayesiana

Cambiando ligeramente los nombres de las variables del teorema de Bayes, obtenemos la fórmula bayesiana:

PAGS ( C ∣ X ) = PAGS ( X ∣ C ) PAGS ( C ) PAGS ( X ) (5) PAGS(c|\bm{x})=\frac{P(\bm{x}|c)P( c)}{P(\bm{x})}\etiqueta{5}PAGS ( C X )=pag ( x )PAGS ( xc ) PAGS ( c )( 5 )

donde P( c ) P(c)P ( c ) indicala etiqueta de la etiquetala etiqueta es cc __La probabilidad de muestras tipo c ,x \bm{x}x es el atributo de entrada,P ( x ) P(\bm{x})P ( x ) significa entradax \bm{x}La probabilidad de que suceda x ,P ( x ∣ c ) P(\bm{x}|c)PAG ( xc ) esccc condición de ocurrenciax \bm{x}La probabilidad de que suceda x .

Usamos la fórmula 5 para expresar que ingresamos x \bm{x}x se divide enccLa probabilidad de clase c , esta esla clasificación bayesiana.

Mayor comprensión, P ( c ) P(c)P ( c ) se llamala probabilidad previa,P ( x ∣ c ) P(x|c)P ( x c ) se llamaprobabilidad de verosimilitudCuando los dos se multiplican, el resultado final bien puede representar la posibilidad de que la muestra sea de cierta categoría.

3. Bayesiano ingenuo

Como se puede ver en la Ecuación 5 anterior, si queremos predecir una entrada x \bm{x}La categoría de x , solo necesitamos obtener P ( c ) P(c)en el conjunto de datos de entrenamientoPAGS ( c )PAGS ( x ∣ c ) PAGS(\bm{x}|c)P ( xc ) servirá,P ( x ) P(x)P ( x ) no es necesario.

Debido a que nuestro proceso de predicción es, dada una entrada de muestra xxx , asumiendo que la posible categoría de esta muestra esC = { c ∣ c 0 , c 1 , . . . , cn } C=\{c|c_0,c_1,...,c_n\}C={ do do0,C1,... ,Cn} ;

Calculamos P ( c 0 ) P(c_0) según la fórmula bayesianapag _ _0)PAG ( c 1 ) PAG (c_1)pag _ _1),……,P ( cn ) P(c_n)pag _ _n)

Finalmente, elegimos un máximo P ( c ) P(c)P ( c ) como nuestra clase final predichac′c'C , finaliza la predicción del modelo.

Y en este proceso, nuestra entrada xxx es igual, entoncesP ( x ) P(\bm{x})P ( x ) también es el mismo, por lo que no debemos preocuparnos por eso, solo elija el que tenga la molécula más grande.

3.1 Calcular P(c) P(c)P ( c )

Esto es fácil de calcular. Podemos contar directamente la frecuencia de diferentes tipos de datos en el conjunto de datos. La ley de los grandes números nos dice que cuando el conjunto de datos es lo suficientemente grande, podemos usar la frecuencia para aproximar la probabilidad.

3.2 Calcular P ( x ∣ c ) P(\bm{x}|c)PAGS ( XC )

Esta idea también es muy simple, las mismas estadísticas, conjunto de datos estadísticos, la etiqueta pertenece a ccc , y el atributo de entrada esx \bm{x}La frecuencia de los datos de x , en el caso de una cantidad relativamente grande de datos, también usa la frecuencia para aproximar la probabilidad.

Sin embargo, aquí x \bm{x}x finalmente se sintetiza combinando diferentes atributos de entrada. Tiene muchas situaciones, y es un problema de combinación. Este tipo de problema explotará en complejidad estadísticamente, y el programa no se puede completar en tiempo polinomial. La operación, en otras palabras, es unNPproblema dificil.

3.3 Suposición de independencia de atributos

Para resolver este NPdifícil problema, adoptamos la suposición independiente de las condiciones de los atributos, y así nació Naive Bayes .

La clasificación bayesiana ingenua se aproxima a P ( x ∣ c ) P(\bm{x}|c) a través de suposiciones de independencia de atributosP ( xc ) es un problema NP-difícil, y el efecto de aproximación es muy bueno, lo que puede lograr excelentes resultados de clasificación.

Suponiendo que todos los atributos se distribuyen de forma independiente, podemos obtener la siguiente fórmula:

PAGS ( x ∣ c ) = ∏ yo = 0 re PAGS ( xi ∣ c ) (6) P(\bm{x}|c)=\prod_{i=0}^dP(x_i|c)\tag{6 }PAGS ( XC )=yo = 0repag ( xyoc )( 6 )

Donde d es el número de atributos, xi x_iXyopara x \bm{x}x presenteiiEl valor en el atributo i .

Poner la fórmula (6) en la fórmula (5) puede obtener el siguiente resultado:

PAGS ( C ∣ X ) = PAGS ( X ∣ C ) PAGS ( C ) PAGS ( X ) = PAGS ( C ) PAGS ( X ) ∏ yo = 0 re PAGS ( xi ∣ C ) (7) PAGS(c|\bm {x})=\frac{P(\bm{x}|c)P(c)}{P(\bm{x})}=\frac{P(c)}{P(\bm{x} )}\prod_{i=0}^dP(x_i|c)\tag{7}PAGS ( C X )=pag ( x )PAGS ( xc ) PAGS ( c )=pag ( x )P ( c )yo = 0repag ( xyoc )( 7 )

Aquí P ( xi ∣ c ) P(x_i|c)pag ( xyoc ) es muy limitado, su número se puede expresar como∑ i = 1 nnum A atributos V alores ( i ) × num C lass V alores \sum_{i=1}^n numAttributesValues(i)\times numClassValuesyo = 1nn u m A t r i b u t o s V a lo re s ( i )×n u m C a s V l u es . En el diseño de programas, podemos usar una matriz List bidimensional, una matriz doble tridimensional o una matriz bidimensional para representar una matriz tridimensional para almacenar esta variable. (Para obtener detalles, consulte el siguiente código. Para facilitar la lectura y la simplicidad del código, utilizo una lista bidimensional para representarlo)

donde nn significa entradax \bm{x}x的属性数量,num A ttributes V alores ( i ) numAttributesValues(i)n u m A tt r i b u t es V l u es ( i ) indica el número de valores posibles del i-ésimo atributo,num Class Values ​​numClassValuesn u m C a ss V l u es indicalabelcuántas categorías hay.

También se puede ver de lo anterior que los clasificadores bayesianos se usan naturalmente para procesar atributos nominales.Si encontramos atributos numéricos, necesitamos realizar la discretización de datos antes de que se pueda usar el bayesiano para la clasificación. Existen muchos métodos para la discretización de datos, tales como: agrupamiento de igual altura, distribución de igual ancho y división basada en la distribución de probabilidad.

Cuarta implementación de código basada en weka

package weka.classifiers.myf;

import weka.classifiers.Classifier;
import weka.core.*;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

/**
 * @author YFMan
 * @Description 朴素贝叶斯 分类器
 * @Date 2023/5/14 18:48
 */
public class myNaiveBayes extends Classifier {
    
    

    // 用于存储 朴素贝叶斯 属性参数
    protected List<Integer>[][] m_Distributions;

    // 用于存储 朴素贝叶斯 类别参数
    protected List<Integer> m_ClassDistribution;

    // 类别参数 的 种类数量
    protected int m_NumClasses;

    // 存储训练数据
    protected Instances m_Instances;

    /*
     * @Author YFMan
     * @Description 训练分类器,初始化 属性参数 和 类别参数
     * @Date 2023/5/14 21:42
     * @Param [instances 训练数据]
     * @return void
     **/
    public void buildClassifier(Instances instances) throws Exception {
    
    
        // 初始化训练数据
        m_Instances = instances;
        // 初始化类别参数 的 种类数量
        m_NumClasses = instances.numClasses();

        // 初始化 属性参数
        m_Distributions = new List[instances.numAttributes() - 1][m_NumClasses];
        for(int i=0;i<instances.numAttributes() - 1;i++){
    
    
            for(int j=0;j<m_NumClasses;j++){
    
    
                m_Distributions[i][j] = new ArrayList<>();
            }
        }
        // 初始化 类别参数
        m_ClassDistribution = new ArrayList<>();
        for(int i=0;i<m_NumClasses;i++){
    
    
            m_ClassDistribution.add(0);
        }

        // 获取属性参数的枚举类型
        Enumeration attributeEnumeration = instances.enumerateAttributes();
        // 遍历属性参数
        while (attributeEnumeration.hasMoreElements()) {
    
    
            // 获取属性参数
            Attribute attribute = (Attribute) attributeEnumeration.nextElement();
            // 获取属性参数的索引
            int attributeIndex = attribute.index();
            // 获取属性参数的值的枚举类型
            Enumeration attributeValueEnumeration = attribute.enumerateValues();
            // 遍历属性参数的值
            while (attributeValueEnumeration.hasMoreElements()) {
    
    
                // 获取属性参数的值
                String attributeValue = (String) attributeValueEnumeration.nextElement();
                // 遍历类别参数
                for (int classIndex = 0; classIndex < m_NumClasses; classIndex++) {
    
    
                    // 初始化 属性参数 的 某个值 的 某个类别参数 的 计数
                    m_Distributions[attributeIndex][classIndex].add(0);
                }
            }
        }

        // 遍历训练数据
        for (int instanceIndex = 0; instanceIndex < instances.numInstances(); instanceIndex++) {
    
    
            // 获取训练数据的实例
            Instance instance = instances.instance(instanceIndex);
            // 获取训练数据的类别参数的值
            int classValue = (int) instance.classValue();
            // 遍历属性参数
            for (int attributeIndex = 0; attributeIndex < instances.numAttributes() - 1; attributeIndex++) {
    
    
                // 获取训练数据的属性参数的值
                int attributeValue = (int) instance.value(attributeIndex);
                // 计数
                m_Distributions[attributeIndex][classValue].set(attributeValue,
                        m_Distributions[attributeIndex][classValue].get(attributeValue) + 1);
            }
            // 计数
            m_ClassDistribution.set(classValue, m_ClassDistribution.get(classValue) + 1);
        }
    }

    /*
     * @Author YFMan
     * @Description 根据给定的实例,预测其类别
     * @Date 2023/5/14 21:43
     * @Param [instance 给定的实例]
     * @return double[]
     **/
    public double[] distributionForInstance(Instance instance)
            throws Exception {
    
    
        // 初始化预测概率数组
        double[] predictionProbability = new double[m_NumClasses];
        // 遍历类别参数
        for (int classIndex = 0; classIndex < m_NumClasses; classIndex++) {
    
    
            // 初始化预测概率
            double prediction = 1;
            // 遍历属性参数
            for (int attributeIndex = 0; attributeIndex < m_Instances.numAttributes() - 1; attributeIndex++) {
    
    
                // 获取属性参数的值
                int attributeValue = (int) instance.value(attributeIndex);
                // 获取 当前属性 可能的取值数
                int attributeValueCount = m_Distributions[attributeIndex][classIndex].size();
                // 计算条件概率P(x|c) (当前属性值在当前类别下占的比例) (拉普拉斯平滑)
                double p_x_c =  (double) (m_Distributions[attributeIndex][classIndex].get(attributeValue) + 1) /
                        (m_ClassDistribution.get(classIndex) + attributeValueCount);
                // 计算预测概率
                prediction *= p_x_c;
            }
            // 计算先验概率P(c) (当前类别占总类别的比例) (拉普拉斯平滑)
            double p_c = (double) (m_ClassDistribution.get(classIndex) + 1) /
                    (m_Instances.numInstances() + m_NumClasses);
            // 计算预测概率
            predictionProbability[classIndex] = prediction * p_c;
        }
        // 归一化
        Utils.normalize(predictionProbability);
        // 返回预测概率数组
        return predictionProbability;
    }

    /*
     * @Author YFMan
     * @Description 主函数
     * @Date 2023/5/14 21:54
     * @Param [argv 命令行参数]
     * @return void
     **/
    public static void main(String[] argv) {
    
    
        runClassifier(new myNaiveBayes(), argv);
    }
}

Supongo que te gusta

Origin blog.csdn.net/myf_666/article/details/130674476
Recomendado
Clasificación