日撸java三百行day58-59

news2024/10/5 13:05:39

文章目录

  • 说明
  • Day58 符号型数据的 NB 算法
    • 1.基础理论知识
      • 1.1 条件概率
      • 1.2 独立性假设
      • 1.3 Laplacian 平滑
    • 2. 符号型数据的预测算法跟踪
      • 2.1 testNominal()方法
        • 2.1.1 NaiveBayes 构造函数
        • 2.1.2 calculateClassDistribution()
        • 2.1.3 calculateConditionalProbabilities()方法
        • 2.1.4 classify()方法
        • 2.1.5 computeAccuracy() 计算精确性
  • Day59 数值型数据的 NB 算法
    • 1.基础理论知识
      • 1.1 数值型和符号型NB 对比
      • 1.2高斯分布(正态分布)
    • 2.符号型数据的预测算法跟踪
      • 2.1 testNumerical()方法
        • 2.1.1 构造方法NaiveBayes
        • 2.1.2 calculateClassDistribution()
        • 2.1.3 calculateGausssianParameters()方法
        • 2.1.4 classify()方法

说明

闵老师的文章链接: 日撸 Java 三百行(总述)_minfanphd的博客-CSDN博客
自己也把手敲的代码放在了github上维护:https://github.com/fulisha-ok/sampledata

Day58 符号型数据的 NB 算法

1.基础理论知识

(对老师这篇文章的翻译,以方便自己的理解)

1.1 条件概率

在给定某个条件下,事件发生的概率。它表示为 P(A|B),表示在事件 B 发生的条件下事件 A 发生的概率。
P(AB) 表示事件 A和B同时发生的概率;
p ( A ∣ B ) = p ( A B ) p ( B ) = p ( B ∣ A ) ∗ p ( A ) p ( B ) p(A|B) = \frac{p(AB)}{p(B)} = \frac{p(B|A)*p(A)}{p(B)} p(AB)=p(B)p(AB)=p(B)p(BA)p(A)

1.2 独立性假设

假设特征之间是相互独立的,在计算概率时,我们可以假设每个特征的出现与其他特征无关,这样可以简化计算过程(虽然这个假设在现实中并不总是成立)

  • 在x发生的条件下Di发生的概率,且假设各个特征之间是相互独立的(直接可以展开连乘)。
    x 条件组合,如outlook=sunny∧temperature=hot; Di 表示一个事件, 如: play = No不出去玩
    p ( D i ∣ x ) = p ( x D i ) p ( x ) = p ( D i ) p ( x ∣ D i ) p ( x ) = p ( D i ) ∏ j = 1 m p ( x j ∣ D i ) p ( x ) p(D_{i}|x)= \frac{p(xD_{i})}{p(x)}=\frac{p(D_{i})p(x|D_{i})}{p(x)}=\frac{p(D_{i})\prod_{j=1}^{m}p(x_{j}|D_{i})}{p(x)} p(Dix)=p(x)p(xDi)=p(x)p(Di)p(xDi)=p(x)p(Di)j=1mp(xjDi)

  • 计算P(x)还是很有困难的, 想想如果特征值多了,那这个P(x)计算难度难以想象呀。我们的真正的目标是预测 p ( D i ∣ x ) p(D_{i}|x) p(Dix)属于那个类别最大,其实他们的分母都是一样的,我们当然就可以忽略了,去关注他的分子 p ( D i ) ∏ j = 1 m p ( x j ∣ D i ) p(D_{i})\prod_{j=1}^{m}p(x_{j}|D_{i}) p(Di)j=1mp(xjDi)

  • 我们对未知样本进行分类时,对 p ( D i ∣ x ) p(D_{i}|x) p(Dix)的计算我们就忽略调分母,只考虑分子,并对等式两边取对数,这样乘法就变为加法,则预测方案就如下:在这里插入图片描述

1.3 Laplacian 平滑

假设我们中有 p ( x j ∣ D i ) = 0 p(x_{j}|D_{i})=0 p(xjDi)=0我们 p ( D i ∣ x ) = 0 p(D_{i}|x) = 0 p(Dix)=0, 进入文章中所说 如果出现 p ( x j ∣ D i ) = 0 p(x_{j}|D_{i})=0 p(xjDi)=0 就有一票否决权了。所以引入Laplacian 平滑用于处理零概率问题。我通过一个简单的例子结合文章来理解:
假设下面是我们训练集数据:

outlooktemperaturepaly
SunnyHotNo
OvercastMildYes
RainyMildYes
RainyCoolYes
OvercasthotYes
  • Di​表示一个事件, 如: play = No

  • x就表示一个条件的组合。如outlook=sunny∧temperature=hot; xj就是某个特征取值。如outlook=sunny

  • 我们根据上面训练数据集得:P(Play = Yes) = 4/5; P(Play = No) = 1/5
    P(xj | Di) 如上:P(outlook = sunny | play = yes) = 0;P(temperature=hot∣play=yes) = 0,正因为有0的出现,我不管什么天气和温度,我打球的概率都变为0了,这样显然是不合理。加入Laplacian 平滑,在计算条件概率时,可以让训练数据中没有观察到某个特征时,它不是0概率。

  • Laplacian 平滑
    结合文章中我们知道:在分子上,都加了1,分母加上特征取值类别个数,分子分母的概率都乘了n(测试样本数量)

例如:对条件概率P(xj | Di)进行平滑
p ( o u t l o o k = s u n n y ∣ p l a y = y e s ) = n ∗ p ( o u t l o o k = s u n n y ∧ p l a y = y e s ) + 1 n ∗ p ( p l a y = y e s ) + 3 p(outlook = sunny|play = yes) = \frac{n*p(outlook = sunny∧play = yes) + 1}{n*p(play = yes) + 3} p(outlook=sunnyplay=yes)=np(play=yes)+3np(outlook=sunnyplay=yes)+1

p ( o u t l o o k = s u n n y ∣ p l a y = y e s ) = 5 ∗ 0 + 1 5 ∗ 4 5 + 3 = 1 7 p(outlook = sunny|play = yes) = \frac{5*0 + 1}{5*\frac{4}{5} + 3} = \frac{1}{7} p(outlook=sunnyplay=yes)=554+350+1=71
p ( o u t l o o k = o v e r c a s t ∣ p l a y = y e s ) = 5 ∗ 2 5 + 1 5 ∗ 4 5 + 3 = 3 7 p(outlook = overcast|play = yes) = \frac{5*\frac{2}{5} + 1}{5*\frac{4}{5} + 3} = \frac{3}{7} p(outlook=overcastplay=yes)=554+3552+1=73
p ( o u t l o o k = R a i n y ∣ p l a y = y e s ) = 5 ∗ 2 5 + 1 5 ∗ 4 5 + 3 = 3 7 p(outlook = Rainy|play = yes) = \frac{5*\frac{2}{5} + 1}{5*\frac{4}{5} + 3}= \frac{3}{7} p(outlook=Rainyplay=yes)=554+3552+1=73

2. 符号型数据的预测算法跟踪

我带着上面的思路去理解代码(从main方法开始看起)我主要通过debug来看各个变量数据的变化结果,用截图的方式展示。(变量太多了…,用debug理解更快)

2.1 testNominal()方法

在这里插入图片描述

2.1.1 NaiveBayes 构造函数

构造函数主要是读文本内容,初始化数据。可知mushroom.arff文件有8124条数据集,22个特征,2中类别选择。
在这里插入图片描述

2.1.2 calculateClassDistribution()

计算类别分布概率。

  • classDistribution 根据数据集计算不同类别的概率(就像上面我出去玩的概率是0.482028,不出去玩的概率是0.51797类似)
  • classDistributionLaplacian 是对classDistribution 进行拉普拉斯平滑后的类别分布
    在这里插入图片描述

2.1.3 calculateConditionalProbabilities()方法

  • 进行空间分配(conditionalCounts和conditionalProbabilitiesLaplacian变量在初始分配都一样)
    一共有22个特征,其实对比文件和代码的赋值就一目了然了
    在这里插入图片描述
    在这里插入图片描述
  • conditionalCounts赋值
    我也是看了好一会儿才明白这个取值。就如我们以conditionalCounts[0][0][tempValue]来理解,这个的含义就是我们第一行的数据中的第一个特征值即值为x,x所在的索引为2,conditionalCounts[0][0][2] 就累加一个1。同理conditionalCounts[0][1][tempValue]就是看他第2个特征值所在的索引位置是多少,以此类推
    在这里插入图片描述
    结合原数据来看
    在这里插入图片描述
  • 统计8124个数据样本出现在每个特征的次数(目的是为了方便计算后面的条件概率)
    在这里插入图片描述
  • 计算条件概率(conditionalProbabilitiesLaplacian赋值)(用Laplacian平滑)
    结合上面Laplacian平滑基础知识即可,计算每个特征值出现的条件概率
    在这里插入图片描述
    在这里插入图片描述

2.1.4 classify()方法

预测类别。在之前的代码中,已经把所有数据都准备好了,现在是结合这个公式去预测类别
在这里插入图片描述

就如我们预测文本中这个数据行:x,s,n,t,p,f,c,n,k,e,e,s,s,w,w,p,w,o,p,k,s,u,p,我们根据上面这个公式预测出的结果是他类别为e即1(实际上他类别为p即0)
在这里插入图片描述

2.1.5 computeAccuracy() 计算精确性

    /**
     * Compute accuracy.
     * @return
     */
    public double computeAccuracy() {
        double tempCorrect = 0;
        for (int i = 0; i < numInstances; i++) {
            if (predicts[i] == (int) dataset.instance(i).classValue()) {
                tempCorrect++;
            }
        }

        double resultAccuracy = tempCorrect / numInstances;
        return resultAccuracy;
    }

代码结果:全部代码可以看文章链接。
在这里插入图片描述

Day59 数值型数据的 NB 算法

1.基础理论知识

1.1 数值型和符号型NB 对比

  • 符号型的NB算法适用于处理离散型的符号特征,概率分布是离散的,并且通过计算特征在给定类别下的频率来估计条件概率
  • 数值型的NB算法适用于处理连续性的数值特征,假设特征的概率分布符合某个已知的概率分布(通常是高斯分布,高斯分布是连续型随机变量最常见的概率分布),通过计算给定类别下特征的概率密度函数,进而计算条件概率(会涉及计算均值和标准差)
    例如:针对符号性,我们假设天气的状况是:晴朗,阴天,下雨等;而对数值型我们假设天气是根据温度具体是多少度。
    • 我们计算符号型的NB算法:我们可以计算每个天气状况下出去玩或不出去玩的概率,对于给定的天气状况,我们可以计算该状况在每个类别下的条件概率。
    • 我们计算数值型NB算法:我们可以计算出去玩和不出去玩下温度的均值和方差,对于给定的温度,我们可以使用高斯分布的概率密度函数计算该温度在每个类别下的条件概率

1.2高斯分布(正态分布)

  • 概率密度函数
    随机变量X服从一个位置参数为 μ \mu μ、尺度参数为 σ \sigma σ 的概率分布,且其概率密度函数
    p ( x ) = 1 2 π σ e x p ( − ( x − u ) 2 2 σ 2 ) p(x)=\frac{1}{\sqrt{2\pi\sigma}}exp({-\frac{(x-u)^{2}}{2\sigma ^{2}}}) p(x)=2πσ 1exp(2σ2(xu)2)
    均值 μ \mu μ的计算方法:对于已有的数据集,均值表示数据的平均值μ = (x₁ + x₂ + … + xₙ) / n
    标准差 σ \sigma σ,数据集的离散程度,是观测值与均值之间的平均差异. σ = Σ ( x − u ) 2 n \sigma =\sqrt{\frac{\Sigma(x-u) ^{2}}{n}} σ=nΣ(xu)2
  • 预测方案修改
    我们预测某个特征值下,Di发生的概率,公式如下
    p ( D i ∣ x ) = p ( x D i ) p ( x ) = p ( D i ) p ( x ∣ D i ) p ( x ) = p ( D i ) ∏ j = 1 m p ( x j ∣ D i ) p ( x ) p(D_{i}|x)= \frac{p(xD_{i})}{p(x)}=\frac{p(D_{i})p(x|D_{i})}{p(x)}=\frac{p(D_{i})\prod_{j=1}^{m}p(x_{j}|D_{i})}{p(x)} p(Dix)=p(x)p(xDi)=p(x)p(Di)p(xDi)=p(x)p(Di)j=1mp(xjDi) 在符号型NB算法下,我们的预测方案中 p ( x j ∣ D i ) p(x_{j}|D_{i}) p(xjDi)我们可以求出来,其中现在对连续性数值, p ( x j ∣ D i ) p(x_{j}|D_{i}) p(xjDi)的计算很显然计算不出来,所以引入高斯分布替换调 p ( x j ∣ D i ) p(x_{j}|D_{i}) p(xjDi),而用相应的概率密度函数。所以对符号型NB算法中的预测方案d(x)进行修改,并对等式两边同样是取对数,则预测方案如下
    在这里插入图片描述

2.符号型数据的预测算法跟踪

同样我也debug看一下

2.1 testNumerical()方法

在这里插入图片描述

2.1.1 构造方法NaiveBayes

与符号型代码无差 目前给出的样本是有150个数据集,4个特征,2个类别。
在这里插入图片描述

2.1.2 calculateClassDistribution()

与符号型代码无差

2.1.3 calculateGausssianParameters()方法

计算条件概率(采用高斯分布)

  • gaussianParameters变量
    存储每个类别下,不同特征值的高斯参数,包含均值,标准差。如下是这个方法执行完存储的值。
    在这里插入图片描述
  • 方法中的循环则是对gaussianParameters中赋值
    计算不同类别下,不同特征值的均值和标准差。
 public void calculateGausssianParameters() {
        gaussianParameters = new GaussianParamters[numClasses][numConditions];

        double[] tempValuesArray = new double[numInstances];
        int tempNumValues = 0;
        double tempSum = 0;

        for (int i = 0; i < numClasses; i++) {
            for (int j = 0; j < numConditions; j++) {
                tempSum = 0;

                // Obtain values for this class.
                tempNumValues = 0;
                for (int k = 0; k < numInstances; k++) {
                    if ((int) dataset.instance(k).classValue() != i) {
                        continue;
                    }

                    tempValuesArray[tempNumValues] = dataset.instance(k).value(j);
                    tempSum += tempValuesArray[tempNumValues];
                    tempNumValues++;
                }

                // Obtain parameters.
                double tempMu = tempSum / tempNumValues;

                double tempSigma = 0;
                for (int k = 0; k < tempNumValues; k++) {
                    tempSigma += (tempValuesArray[k] - tempMu) * (tempValuesArray[k] - tempMu);
                }
                tempSigma /= tempNumValues;
                tempSigma = Math.sqrt(tempSigma);

                gaussianParameters[i][j] = new GaussianParamters(tempMu, tempSigma);
            }
        }

        System.out.println(Arrays.deepToString(gaussianParameters));
    }

2.1.4 classify()方法

预测类别。在之前的代码中,已经把所有数据都准备好了,现在是结合这个公式去预测类别
在这里插入图片描述
代码运行结果。
我想说这个的预测的精准率有点高呀~直接100%了
在这里插入图片描述
如果我将读入文本换为之前的iris.arff,结果如下
在这里插入图片描述
全部代码:

package machinelearing;

import weka.core.Instance;
import weka.core.Instances;

import java.io.FileReader;
import java.util.Arrays;
import java.util.Random;

/**
 * @author: fulisha
 * @date: 2023/6/2 9:22
 * @description:
 */
public class NaiveBayes {
    /**
     * An inner class to store parameters.
     */
    private class GaussianParamters {
        double mu;
        double sigma;

        public GaussianParamters(double paraMu, double paraSigma) {
            mu = paraMu;
            sigma = paraSigma;
        }

        @Override
        public String toString() {
            return "(" + mu + ", " + sigma + ")";
        }
    }

    /**
     * The data.
     */
    Instances dataset;

    /**
     * The number of classes. For binary classification it is 2.
     */
    int numClasses;

    /**
     * The number of instances.
     */
    int numInstances;

    /**
     * The number of conditional attributes.
     */
    int numConditions;

    /**
     * The prediction, including queried and predicted labels.
     */
    int[] predicts;

    /**
     * Class distribution.
     */
    double[] classDistribution;

    /**
     * Class distribution with Laplacian smooth.
     */
    double[] classDistributionLaplacian;

    /**
     * To calculate the conditional probabilities for all classes over all
     * attributes on all values.
     */
    double[][][] conditionalCounts;

    /**
     * The conditional probabilities with Laplacian smooth.
     */
    double[][][] conditionalProbabilitiesLaplacian;

    /**
     * The Guassian parameters.
     */
    GaussianParamters[][] gaussianParameters;

    /**
     * Data type.
     */
    int dataType;

    /**
     * Nominal.
     */
    public static final int NOMINAL = 0;

    /**
     * Numerical.
     */
    public static final int NUMERICAL = 1;


    /**
     * The constructor
     * @param paraFileName The given file.
     */
    public NaiveBayes(String paraFileName) {
        dataset = null;
        try {
            FileReader reader = new FileReader(paraFileName);
            dataset = new Instances(reader);
            reader.close();
        }catch (Exception e) {
            System.out.println("Cannot read the file: " + paraFileName + "\r\n" + e);
            System.exit(0);
        }

        dataset.setClassIndex(dataset.numAttributes() - 1);
        numConditions = dataset.numAttributes() - 1;
        numInstances = dataset.numInstances();
        numClasses = dataset.attribute(numConditions).numValues();
    }

    /**
     * The constructor
     * @param paraInstances  The given file.
     */
    public NaiveBayes(Instances paraInstances) {
        dataset = paraInstances;

        dataset.setClassIndex(dataset.numAttributes() - 1);
        numConditions = dataset.numAttributes() - 1;
        numInstances = dataset.numInstances();
        numClasses = dataset.attribute(numConditions).numValues();
    }

    /**
     * Set the data type.
     * @param paraDataType
     */
    public void setDataType(int paraDataType) {
        dataType = paraDataType;
    }

    /**
     * Calculate the class distribution with Laplacian smooth.
     */
    public void calculateClassDistribution() {
        classDistribution = new double[numClasses];
        classDistributionLaplacian = new double[numClasses];

        double[] tempCounts = new double[numClasses];
        for (int i = 0; i < numInstances; i++) {
            int tempClassValue = (int) dataset.instance(i).classValue();
            tempCounts[tempClassValue]++;
        }

        for (int i = 0; i < numClasses; i++) {
            classDistribution[i] = tempCounts[i] / numInstances;
            classDistributionLaplacian[i] = (tempCounts[i] + 1) / (numInstances + numClasses);
        }

        System.out.println("Class distribution: " + Arrays.toString(classDistribution));
        System.out.println("Class distribution Laplacian: " + Arrays.toString(classDistributionLaplacian));
    }


    /**
     *  Calculate the conditional probabilities with Laplacian smooth. ONLY scan the dataset once.
     *  There was a simpler one, I have removed it because the time complexity is higher.
     */
    public void calculateConditionalProbabilities() {
        conditionalCounts = new double[numClasses][numConditions][];
        conditionalProbabilitiesLaplacian = new double[numClasses][numConditions][];

        // Allocate space
        for (int i = 0; i < numClasses; i++) {
            for (int j = 0; j < numConditions; j++) {
                int tempNumValues = (int) dataset.attribute(j).numValues();
                conditionalCounts[i][j] = new double[tempNumValues];
                conditionalProbabilitiesLaplacian[i][j] = new double[tempNumValues];
            }
        }

        // Count the numbers
        int[] tempClassCounts = new int[numClasses];
        for (int i = 0; i < numInstances; i++) {
            int tempClass = (int) dataset.instance(i).classValue();
            tempClassCounts[tempClass]++;
            for (int j = 0; j < numConditions; j++) {
                int tempValue = (int) dataset.instance(i).value(j);
                conditionalCounts[tempClass][j][tempValue]++;
            }
        }

        // Now for the real probability with Laplacian
        for (int i = 0; i < numClasses; i++) {
            for (int j = 0; j < numConditions; j++) {
                int tempNumValues = (int) dataset.attribute(j).numValues();
                for (int k = 0; k < tempNumValues; k++) {
                    conditionalProbabilitiesLaplacian[i][j][k] = (conditionalCounts[i][j][k] + 1)
                            / (tempClassCounts[i] + tempNumValues);
                    // I wrote a bug here. This is an alternative approach,
                    // however its performance is better in the mushroom dataset.
                    // conditionalProbabilitiesLaplacian[i][j][k] =
                    // (numInstances * conditionalCounts[i][j][k] + 1)
                    // / (numInstances * tempClassCounts[i] + tempNumValues);
                }
            }
        }

        System.out.println("Conditional probabilities: " + Arrays.deepToString(conditionalCounts));
    }

    /**
     *  Calculate the conditional probabilities with Laplacian smooth.
     */
    public void calculateGausssianParameters() {
        gaussianParameters = new GaussianParamters[numClasses][numConditions];

        double[] tempValuesArray = new double[numInstances];
        int tempNumValues = 0;
        double tempSum = 0;

        for (int i = 0; i < numClasses; i++) {
            for (int j = 0; j < numConditions; j++) {
                tempSum = 0;

                // Obtain values for this class.
                tempNumValues = 0;
                for (int k = 0; k < numInstances; k++) {
                    if ((int) dataset.instance(k).classValue() != i) {
                        continue;
                    }

                    tempValuesArray[tempNumValues] = dataset.instance(k).value(j);
                    tempSum += tempValuesArray[tempNumValues];
                    tempNumValues++;
                }

                // Obtain parameters.
                double tempMu = tempSum / tempNumValues;

                double tempSigma = 0;
                for (int k = 0; k < tempNumValues; k++) {
                    tempSigma += (tempValuesArray[k] - tempMu) * (tempValuesArray[k] - tempMu);
                }
                tempSigma /= tempNumValues;
                tempSigma = Math.sqrt(tempSigma);

                gaussianParameters[i][j] = new GaussianParamters(tempMu, tempSigma);
            }
        }

        System.out.println(Arrays.deepToString(gaussianParameters));
    }

    /**
     *  Classify all instances, the results are stored in predicts[].
     */
    public void classify() {
        predicts = new int[numInstances];
        for (int i = 0; i < numInstances; i++) {
            predicts[i] = classify(dataset.instance(i));
        }
    }

    public int classify(Instance paraInstance) {
        if (dataType == NOMINAL) {
            return classifyNominal(paraInstance);
        } else if (dataType == NUMERICAL) {
            return classifyNumerical(paraInstance);
        } // Of if

        return -1;
    }

    /**
     * Classify an instances with nominal data.
     * @param paraInstance
     * @return
     */
    public int classifyNominal(Instance paraInstance) {
        // Find the biggest one
        double tempBiggest = -10000;
        int resultBestIndex = 0;
        for (int i = 0; i < numClasses; i++) {
            double tempPseudoProbability = Math.log(classDistributionLaplacian[i]);
            for (int j = 0; j < numConditions; j++) {
                int tempAttributeValue = (int) paraInstance.value(j);

                tempPseudoProbability += Math.log(conditionalProbabilitiesLaplacian[i][j][tempAttributeValue]);
            }

            if (tempBiggest < tempPseudoProbability) {
                tempBiggest = tempPseudoProbability;
                resultBestIndex = i;
            }
        }

        return resultBestIndex;
    }

    /**
     * Classify an instances with numerical data.
     * @param paraInstance
     * @return
     */
    public int classifyNumerical(Instance paraInstance) {
        // Find the biggest one
        double tempBiggest = -10000;
        int resultBestIndex = 0;

        for (int i = 0; i < numClasses; i++) {
            double tempPseudoProbability = Math.log(classDistributionLaplacian[i]);
            for (int j = 0; j < numConditions; j++) {
                double tempAttributeValue = paraInstance.value(j);
                double tempSigma = gaussianParameters[i][j].sigma;
                double tempMu = gaussianParameters[i][j].mu;

                tempPseudoProbability += -Math.log(tempSigma)
                        - (tempAttributeValue - tempMu) * (tempAttributeValue - tempMu) / (2 * tempSigma * tempSigma);
            }

            if (tempBiggest < tempPseudoProbability) {
                tempBiggest = tempPseudoProbability;
                resultBestIndex = i;
            }
        }

        return resultBestIndex;
    }

    /**
     * Compute accuracy.
     * @return
     */
    public double computeAccuracy() {
        double tempCorrect = 0;
        for (int i = 0; i < numInstances; i++) {
            if (predicts[i] == (int) dataset.instance(i).classValue()) {
                tempCorrect++;
            }
        }

        double resultAccuracy = tempCorrect / numInstances;
        return resultAccuracy;
    }

    /**
     *  Test nominal data.
     */
    public static void testNominal() {
        System.out.println("Hello, Naive Bayes. I only want to test the nominal data.");
        String tempFilename = "C:/Users/fls/Desktop/mushroom.arff";

        NaiveBayes tempLearner = new NaiveBayes(tempFilename);
        tempLearner.setDataType(NOMINAL);
        tempLearner.calculateClassDistribution();
        tempLearner.calculateConditionalProbabilities();
        tempLearner.classify();

        System.out.println("The accuracy is: " + tempLearner.computeAccuracy());
    }

    /**
     * Test numerical data.
     */
    public static void testNumerical() {
        System.out.println("Hello, Naive Bayes. I only want to test the numerical data with Gaussian assumption.");
        // String tempFilename = "D:/data/iris.arff";
        String tempFilename = "C:/Users/fls/Desktop/iris.arff";

        NaiveBayes tempLearner = new NaiveBayes(tempFilename);
        tempLearner.setDataType(NUMERICAL);
        tempLearner.calculateClassDistribution();
        tempLearner.calculateGausssianParameters();
        tempLearner.classify();

        System.out.println("The accuracy is: " + tempLearner.computeAccuracy());
    }

    /**
     * Test this class.
     * @param args
     */
    public static void main(String[] args) {
        testNominal();
        testNumerical();
        // testNominal(0.8);
    }

    /**
     * Get a random indices for data randomization.
     * @param paraLength  The length of the sequence.
     * @return An array of indices, e.g., {4, 3, 1, 5, 0, 2} with length 6.
     */
    public static int[] getRandomIndices(int paraLength) {
        Random random = new Random();
        int[] resultIndices = new int[paraLength];

        // Step 1. Initialize.
        for (int i = 0; i < paraLength; i++) {
            resultIndices[i] = i;
        } // Of for i

        // Step 2. Randomly swap.
        int tempFirst, tempSecond, tempValue;
        for (int i = 0; i < paraLength; i++) {
            // Generate two random indices.
            tempFirst = random.nextInt(paraLength);
            tempSecond = random.nextInt(paraLength);

            // Swap.
            tempValue = resultIndices[tempFirst];
            resultIndices[tempFirst] = resultIndices[tempSecond];
            resultIndices[tempSecond] = tempValue;
        } // Of for i

        return resultIndices;
    }

    /**
     * Split the data into training and testing parts.
     * @param paraDataset
     * @param paraTrainingFraction The fraction of the training set.
     * @return
     */
    public static Instances[] splitTrainingTesting(Instances paraDataset, double paraTrainingFraction) {
        int tempSize = paraDataset.numInstances();
        int[] tempIndices = getRandomIndices(tempSize);
        int tempTrainingSize = (int) (tempSize * paraTrainingFraction);

        // Empty datasets.
        Instances tempTrainingSet = new Instances(paraDataset);
        tempTrainingSet.delete();
        Instances tempTestingSet = new Instances(tempTrainingSet);

        for (int i = 0; i < tempTrainingSize; i++) {
            tempTrainingSet.add(paraDataset.instance(tempIndices[i]));
        } // Of for i

        for (int i = 0; i < tempSize - tempTrainingSize; i++) {
            tempTestingSet.add(paraDataset.instance(tempIndices[tempTrainingSize + i]));
        } // Of for i

        tempTrainingSet.setClassIndex(tempTrainingSet.numAttributes() - 1);
        tempTestingSet.setClassIndex(tempTestingSet.numAttributes() - 1);
        Instances[] resultInstanesArray = new Instances[2];
        resultInstanesArray[0] = tempTrainingSet;
        resultInstanesArray[1] = tempTestingSet;

        return resultInstanesArray;
    }


    /**
     * Classify all instances, the results are stored in predicts[].
     * @param paraTestingSet
     * @return
     */
    public double classify(Instances paraTestingSet) {
        double tempCorrect = 0;
        int[] tempPredicts = new int[paraTestingSet.numInstances()];
        for (int i = 0; i < tempPredicts.length; i++) {
            tempPredicts[i] = classify(paraTestingSet.instance(i));
            if (tempPredicts[i] == (int) paraTestingSet.instance(i).classValue()) {
                tempCorrect++;
            } // Of if
        } // Of for i

        System.out.println("" + tempCorrect + " correct over " + tempPredicts.length + " instances.");
        double resultAccuracy = tempCorrect / tempPredicts.length;
        return resultAccuracy;
    }

    /**
     * Test nominal data.
     * @param paraTrainingFraction
     */
    public static void testNominal(double paraTrainingFraction) {
        System.out.println("Hello, Naive Bayes. I only want to test the nominal data.");
        String tempFilename = "D:/data/mushroom.arff";
        // String tempFilename = "D:/data/voting.arff";

        Instances tempDataset = null;
        try {
            FileReader fileReader = new FileReader(tempFilename);
            tempDataset = new Instances(fileReader);
            fileReader.close();
        } catch (Exception ee) {
            System.out.println("Cannot read the file: " + tempFilename + "\r\n" + ee);
            System.exit(0);
        } // Of try

        Instances[] tempDatasets = splitTrainingTesting(tempDataset, paraTrainingFraction);
        NaiveBayes tempLearner = new NaiveBayes(tempDatasets[0]);
        tempLearner.setDataType(NOMINAL);
        tempLearner.calculateClassDistribution();
        tempLearner.calculateConditionalProbabilities();

        double tempAccuracy = tempLearner.classify(tempDatasets[1]);

        System.out.println("The accuracy is: " + tempAccuracy);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/613093.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

D*算法详解 (D星算法 / Dynamic A*算法/ Dstar算法)(死循环解决)【编辑中】

所需先验知识&#xff08;没有先验知识可能会有大碍&#xff0c;了解的话会对D*的理解有帮助&#xff09;&#xff1a;A*算法/ Dijkstra算法 何为D*算法 Dijkstra算法是无启发的寻找图中两节点的最短连接路径的算法&#xff0c;A*算法则是在Dijkstra算法的基础上加入了启发函数…

【linux下一次复制cp多个文件】

linux下一次复制cp多个文件 linux cp 参数说明 -a&#xff1a;此选项通常在复制目录时使用&#xff0c;它保留链接、文件属性&#xff0c;并复制目录下的所有内容。其作用等于dpR参数组合。 -d&#xff1a;复制时保留链接。这里所说的链接相当于Windows系统中的快捷方式。 -f&…

使用可上网的服务器作为网关,实现另一台服务器上网

文章目录 物理条件方法一&#xff1a;不使用交换机方法二&#xff1a;使用交换机 配置步骤查看网络状态设置静态IP将服务器A设置成网关重新启动各服务器网卡设置主机名 参考资料 本文的目标是利用一台可以上网的服务器作为网关&#xff0c;使在同一局域网中的所有服务器都可以上…

如何安装多个node版本(不使用nvm)

1、选择node安装的路径 例如&#xff1a;D:\Program Files\nodejs 2、下载要安装的对应版本的zip格式的node安装包 例如&#xff1a;下载16.14.2 和 13.14.0 两个版本的zip格式的node安装包&#xff0c;node版本下载地址https://nodejs.org/dist/ 3、安装包解压到对应文件夹…

遥感云大数据在灾害、水体与湿地领域典型

近年来遥感技术得到了突飞猛进的发展&#xff0c;航天、航空、临近空间等多遥感平台不断增加&#xff0c;数据的空间、时间、光谱分辨率不断提高&#xff0c;数据量猛增&#xff0c;遥感数据已经越来越具有大数据特征。遥感大数据的出现为相关研究提供了前所未有的机遇&#xf…

路径规划算法:基于JAYA优化的路径规划算法- 附代码

路径规划算法&#xff1a;基于JAYA优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于JAYA优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用智能优化算法JAYA…

深入理解深度学习——正则化(Regularization):对抗训练(Adversarial Training)

分类目录&#xff1a;《自然语言处理从入门到应用》总目录 在许多情况下&#xff0c;神经网络在独立同分布的测试集上进行评估已经达到了人类表现。因此&#xff0c;我们自然要怀疑这些模型在这些任务上是否获得了真正的人类层次的理解。为了探索网络对底层任务的理解层次&…

如何理解并使用 park 与 unpark

tip: 作为程序员一定学习编程之道&#xff0c;一定要对代码的编写有追求&#xff0c;不能实现就完事了。我们应该让自己写的代码更加优雅&#xff0c;即使这会费时费力。 文章目录 一、基本介绍二、使用例子三、使用注意事项 一、基本介绍 park和unpark是Java中的两个线程同步…

高性能软件负载OpenResty介绍和安装

目录 1 OpenResty介绍1.1 Nginx 的流程定义1.1.1 流程详解1.1.2 OpenResty处理流程 2 Openresty安装2.1 yum安装2.1.1 添加OpenResty仓库2.1.2 安装OpenResty 2.2 源代码编译安装2.2.1 安装编译环境2.2.2下载最新版源码2.2.3下载缓存插件2.2.4 编译OpenResty2.2.5 安装OpenRest…

《设计模式》之状态模式

文章目录 1、定义2、动机3、类结构4、优点5、总结6、代码实现(C) 1、定义 允许一个对象在其内部改变时改变它的行为&#xff0c;从而使对象看起来改变了其行为。 2、动机 某些对象的状态如果改变&#xff0c;其行为也会随之而发生改变。比如文档的只读状态和读写状态的行为可…

【MySQL】- 04 MVCC实现原理

MVCC的实现原理 隐式字段undo日志Read View(读视图)整体流程例子 MVCC的目的就是多版本并发控制&#xff0c;在数据库中的实现&#xff0c;就是为了解决读写冲突&#xff0c;它的实现原理主要是依赖记录中的 3个隐式字段&#xff0c;undo日志 &#xff0c;Read View 来实现的。…

Linux笔记-so.1和so的区别(三方程序链接Qt的so.1和so)

如下面这个程序使用ldd查看下&#xff1a; 从中可以看到一些so.6和so.1这些&#xff0c;这些其实是版本号&#xff0c;比如这个&#xff1a;/lib64/libstdc.so.6 可见so.版本号其实是个软连接&#xff0c;最终会连接到/lib64/libstdc.so.6.0.19 而CQt框架写的lib如下pro文件会生…

磁盘配额与进阶文件系统管理(一)

磁盘配额Quota 用途 针对www server&#xff0c;例如 每个人网页空间的容量限制&#xff1b;针对mail server&#xff0c;例如 每个人的邮件空间限制&#xff1b;针对file server&#xff0c;例如 每个人最大可用的网络硬盘空间&#xff1b;限制某一群组所能使用的最大磁盘空…

使用zerotier进行内网穿透,外网访问其它电脑上的虚拟机

目标 使用一台电脑&#xff0c;使用vmware创建三台虚拟机&#xff0c;处于同一网段。另一台电脑外网进行访问其虚拟机 用途 学习K8s集群&#xff0c;由于个人财力有限&#xff0c;云服务器买不了几台&#xff0c;而且不同厂家的云服务器无法做到内网互通 完成后缺陷 使用z…

nginx系统优化和内核优化

nginx系统优化 一&#xff1a;隐藏nginx版本号 方法一&#xff1a;修改配置文件 vim /usr/local/nginx/conf/nginx.confnginx -t systemctl restart nginx curl -I http://192.168.52.108方法二&#xff1a;修改源代码 vim /opt/nginx-1.24.0/src/core/nginx.h ##配置文件里…

逆向汇编与反汇编——汇编基础快速入门

一、常用32位寄存器介绍 不同位数的寄存器的名称&#xff1a; eax&#xff1a;累加寄存器。通常用于算数运算&#xff0c;将结果保留在eax当中&#xff0c;当然也可以用于其他用途&#xff0c;比如一般把返回值通过eax传递出去。 ebx&#xff1a;基址寄存器 。有点类似于ebp…

Go语言日志库logrus

Go语言日志库logrus 1、介绍 logrus logrus是目前Github上star数量最多的日志包&#xff0c;功能强大、性能高效、高度灵活&#xff0c;还提供了自定义插件的功能。很 多优秀的开源项目&#xff0c;例如&#xff1a;docker、prometheus等都使用了logrus。logrus除了具有日志…

VMware nat模式配置

使用nat模式&#xff0c;需要配置ip才能做到虚拟机与主机、外网正常通信 步骤 1 选择虚拟机设置&#xff0c;将网络连接改为nat模式 2 查看主机vmware network adpter vmnet8 打开控制面板。选择网络连接&#xff0c;右击vmnet8&#xff0c;打开属性 选择ip4&#xff0c;双击…

kubesphere插件,应用商店,应用仓库

应用商店 参考 步骤 以platform-admin角色的账号(admin)登录kubesphere点击右上角 “平台管理”点击“集群管理”点击 “自定义资源 CRD”搜索 clusterconfiguration点击 ClusterConfiguration点击 ks-installer 右侧的三个点&#xff0c;点击“编辑文件”在YAML 文件中&…

Linux进程间通信【匿名管道】

✨个人主页&#xff1a; 北 海 &#x1f389;所属专栏&#xff1a; Linux学习之旅 &#x1f383;操作环境&#xff1a; CentOS 7.6 阿里云远程服务器 文章目录 &#x1f307;前言&#x1f3d9;️正文1、进程间通信相关概念1.1、目的1.2、发展1.3、分类 2、什么是管道&#xff1…