贝叶斯算法Java实现

前言:朴素贝叶斯分类算法是一种基于贝叶斯定理的简单概率分类算法。贝叶斯分类的基础是概率推理,就是在各种条件的存在不确定,仅知其出现概率的情况下,如何完成推理和决策任务。概率推理是与确定性推理相对应的。而朴素贝叶斯分类器是基于独立假设的,即假设样本每个特征与其他特征都不相关。

朴素贝叶斯分类器依靠精确的自然概率模型,在有监督学习的样本集中能获取得非常好的分类效果。在许多实际应用中,朴素贝叶斯模型参数估计使用最大似然估计方法,换言之朴素贝叶斯模型能工作并没有用到贝叶斯概率或者任何贝叶斯模型。

尽管是带着这些朴素思想和过于简单化的假设,但朴素贝叶斯分类器在很多复杂的现实情形中仍能够取得相当好的效果。

贝叶斯算法基础讲解:http://www.cnblogs.com/skyme/p/3564391.html

package Bayes;

import java.util.ArrayList;  
import java.util.HashMap;  
import java.util.Map;  
import java.math.BigDecimal;
public class Bayes {  

    //将训练集按巡逻集合的最后一个值进行分类  
    Map<String, ArrayList<ArrayList<String>>> datasOfClass(ArrayList<ArrayList<String>> datas){  
        Map<String, ArrayList<ArrayList<String>>> map = new HashMap<String, ArrayList<ArrayList<String>>>();  
        ArrayList<String> t = null;  
        String c = "";  
        for (int i = 0; i < datas.size(); i++) {  
            t = datas.get(i);  
            c = t.get(t.size() - 1);  
            if (map.containsKey(c)) {  
                map.get(c).add(t);  
            } else {  
                ArrayList<ArrayList<String>> nt = new ArrayList<ArrayList<String>>();  
                nt.add(t);  
                map.put(c, nt);  
            }  
        }  
        return map;  
    }  

    //在训练数据的基础上预测测试元组的类别 ,testT的各个属性在结果集里面出现的概率相乘最高的,即是结果
    public String predictClass(ArrayList<ArrayList<String>> datas, ArrayList<String> testT) {  
        Map<String, ArrayList<ArrayList<String>>> doc = this.datasOfClass(datas);  
        //将训练集元素划分保存在数据里
        Object classes[] = doc.keySet().toArray();  
        double maxP = 0.00;  
        int maxPIndex = -1;  
      //testT的各个属性在结果集里面出现的概率相乘最高的,即使结果集
        for (int i = 0; i < doc.size(); i++) {  
            String c = classes[i].toString();   
            ArrayList<ArrayList<String>> d = doc.get(c);  
            BigDecimal b1 = new BigDecimal(Double.toString(d.size()));
            BigDecimal b2 = new BigDecimal(Double.toString(datas.size()));
            //b1除以b2得到一个精度为3的双浮点数
            double pOfC = b1.divide(b2,3,BigDecimal.ROUND_HALF_UP).doubleValue(); 
            for (int j = 0; j < testT.size(); j++) {  
                double pv = this.pOfV(d, testT.get(j), j);
                BigDecimal b3 = new BigDecimal(Double.toString(pOfC));   
                BigDecimal b4 = new BigDecimal(Double.toString(pv));
                //b3乘以b4得到一个浮点数
                pOfC=b3.multiply(b4).doubleValue(); 
            }  
            if(pOfC > maxP){  
                maxP = pOfC;  
                maxPIndex = i;  
            }  
        }  
        return classes[maxPIndex].toString();  
    } 

    // 计算指定属性到训练集出现的频率  
    private double pOfV(ArrayList<ArrayList<String>> d, String value, int index) {  
        double p = 0.00;  
        int count = 0;  
        int total = d.size();  
        for (int i = 0; i < total; i++) {  
            if(d.get(i).get(index).equals(value)){  
                count++;  
            }  
        }  
        BigDecimal b1 = new BigDecimal(Double.toString(count));
        BigDecimal b2 = new BigDecimal(Double.toString(total));
        //b1除以b2得到一个精度为3的双浮点数
        p = b1.divide(b2,3,BigDecimal.ROUND_HALF_UP).doubleValue(); 
        return p;  
    }  
}  
package Bayes;

import java.io.BufferedReader;  
import java.io.IOException;  
import java.io.InputStreamReader;  
import java.util.ArrayList;  

public class TestBayes {  

    //读取测试元组
    public ArrayList<String> readTestData() throws IOException{  
        ArrayList<String> candAttr = new ArrayList<String>();  
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));  
        String str = "";  
        while (!(str = reader.readLine()).equals("")) {
            //string分析器
            String[] tokenizer = str.split(" ");
            for(int i=0;i<tokenizer.length;i++){
                candAttr.add(tokenizer[i]);
            } 
        }  
        return candAttr;  
    }  

    //读取训练集
    public ArrayList<ArrayList<String>> readData() throws IOException {  
        ArrayList<ArrayList<String>> datas = new ArrayList<ArrayList<String>>();  
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));  
        String str = "";  
        while (!(str = reader.readLine()).equals("")) {  
            String[] tokenizer = str.split(" ");  
            ArrayList<String> s = new ArrayList<String>();  
            for(int i=0;i<tokenizer.length;i++){
                s.add(tokenizer[i]);
            } 
            datas.add(s);  
        }  
        return datas;  
    }  

    public static void main(String[] args) {  
        TestBayes tb = new TestBayes();  
        ArrayList<ArrayList<String>> datas = null;  
        ArrayList<String> testT = null;  
        Bayes bayes = new Bayes();  
        try {  
            System.out.println("请输入训练数据");  
            datas = tb.readData();  
            while (true) {  
                System.out.println("请输入测试元组");  
                testT = tb.readTestData();  
                String c = bayes.predictClass(datas, testT);  
                System.out.println("The class is: " + c);  
            }  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  
}  

测试结果:

请输入训练数据
youth high no fair no  
youth high no excellent no  
middle_aged high no fair yes  
senior medium no fair yes  
senior low yes fair yes  
senior low yes excellent no  
middle_aged low yes excellent yes  
youth medium no fair no  
youth low yes fair yes  
senior medium yes fair yes  
youth medium yes excellent yes  
middle_aged medium no excellent yes  
middle_aged high yes fair yes  
senior medium no excellent no  

贝叶斯扩展:
《数学之美》贝叶斯网络http://www.cricode.com/1078.html
《数学之美》贝叶斯分类方法http://www.cricode.com/1098.html

转载于:https://www.cnblogs.com/yankang/p/6399032.html

贝叶斯算法是一种基于统计学的算法,用于分类问题。它的核心思想是根据已知概率来预测未知事件的概率。 Java实现贝叶斯算法的步骤如下: 1. 准备数据集 需要一个已知分类的数据集,其中每个数据都有一个分类标签。可以使用已有的数据集或者自己创建一个数据集。 2. 计算先验概率 先验概率是指在没有任何证据的情况下,某一事件发生的概率。在贝叶斯算法中,需要计算每个分类的先验概率。先验概率可以通过每个分类的样本数量除以总样本数量来计算。 3. 计算条件概率 条件概率是指在已知某些信息的情况下,某一事件发生的概率。在贝叶斯算法中,需要计算每个分类下每个特征的条件概率。条件概率可以通过特征在该分类下的出现次数除以该分类下所有特征出现的总次数来计算。 4. 计算后验概率 后验概率是指在已知某些证据的情况下,某一事件发生的概率。在贝叶斯算法中,需要计算每个分类下每个特征的后验概率。后验概率可以通过先验概率和条件概率的乘积来计算。 5. 预测分类 对于一个未知数据,需要计算它在每个分类下的后验概率,并选择最高概率的分类作为预测结果。 下面是一个简单的Java示例代码: ```java import java.util.HashMap; import java.util.Map; public class NaiveBayesClassifier { private Map<String, Double> priorProbabilities; private Map<String, Map<String, Double>> conditionalProbabilities; public NaiveBayesClassifier() { priorProbabilities = new HashMap<>(); conditionalProbabilities = new HashMap<>(); } public void train(Map<String, Map<String, Integer>> trainingSet) { int totalSamples = 0; for (String label : trainingSet.keySet()) { Map<String, Integer> samples = trainingSet.get(label); int labelSamples = 0; for (int count : samples.values()) { labelSamples += count; totalSamples += count; } priorProbabilities.put(label, (double) labelSamples / totalSamples); Map<String, Double> conditionalProbabilitiesForLabel = new HashMap<>(); for (String feature : samples.keySet()) { int featureCount = samples.get(feature); double conditionalProbability = (double) featureCount / labelSamples; conditionalProbabilitiesForLabel.put(feature, conditionalProbability); } conditionalProbabilities.put(label, conditionalProbabilitiesForLabel); } } public String classify(Map<String, Integer> sample) { String bestLabel = ""; double bestPosterior = 0.0; for (String label : priorProbabilities.keySet()) { double posterior = priorProbabilities.get(label); Map<String, Double> conditionalProbabilitiesForLabel = conditionalProbabilities.get(label); for (String feature : sample.keySet()) { if (conditionalProbabilitiesForLabel.containsKey(feature)) { double conditionalProbability = conditionalProbabilitiesForLabel.get(feature); posterior *= Math.pow(conditionalProbability, sample.get(feature)); } } if (posterior > bestPosterior) { bestPosterior = posterior; bestLabel = label; } } return bestLabel; } } ``` 这个实现是一个简单的朴素贝叶斯分类器,可以用于分类标签为字符串类型的数据。训练集是一个Map,其中每个键是一个分类标签,对应的值是一个Map,其中每个键是一个特征,对应的值是该特征在该分类下的出现次数。对于未知数据,使用classify()方法来预测它的分类标签。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值