Java利用樸素貝葉斯分類算法實(shí)現(xiàn)信息分類
貝葉斯分類算法
貝葉斯分類算法是統(tǒng)計(jì)學(xué)的一種分類方法,它是一類利用概率統(tǒng)計(jì)知識(shí)進(jìn)行分類的算法。在許多場(chǎng)合,樸素貝葉斯(Naïve Bayes,NB)分類算法可以與決策樹和神經(jīng)網(wǎng)絡(luò)分類算法相媲美,該算法能運(yùn)用到大型數(shù)據(jù)庫(kù)中,而且方法簡(jiǎn)單、分類準(zhǔn)確率高、速度快。
由于貝葉斯定理假設(shè)一個(gè)屬性值對(duì)給定類的影響?yīng)毩⒂谄渌鼘傩缘闹?,而此假設(shè)在實(shí)際情況中經(jīng)常是不成立的,因此其分類準(zhǔn)確率可能會(huì)下降。為此,就衍生出許多降低獨(dú)立性假設(shè)的貝葉斯分類算法,如TAN(tree augmented Bayes network)算法。
那么既然是樸素貝葉斯分類算法,它的核心算法又是什么呢?
是下面這個(gè)貝葉斯公式:

換個(gè)表達(dá)形式就會(huì)明朗很多,如下:

我們最終求的p(類別|特征)即可!就相當(dāng)于完成了我們的任務(wù)。
代碼實(shí)例
下面以女生找對(duì)象舉例,提取除女生找對(duì)象的幾個(gè)關(guān)鍵特征,比如顏值,性格,身高,上進(jìn)心,資產(chǎn)情況為擇偶特征,通過(guò)事先調(diào)研等手段,獲取一部分?jǐn)?shù)據(jù)樣本,即各類特征以及擇偶結(jié)果(分類)數(shù)據(jù)集。根據(jù)數(shù)據(jù)集利用樸素貝葉斯函數(shù)計(jì)算出個(gè)各個(gè)特征集合在該分類下的值,結(jié)果值最大的分類,認(rèn)為該數(shù)據(jù)屬于這個(gè)分類。由于這個(gè)是利用概率學(xué)去計(jì)算得出的,不一定十分準(zhǔn)確,數(shù)據(jù)集樣本數(shù)據(jù)越大,準(zhǔn)確率就越高。
數(shù)據(jù)集data.txt
下面數(shù)據(jù)集每行代碼一條樣本數(shù)據(jù),每條數(shù)據(jù)中的具體特征用逗號(hào)“,” 分割,特征順尋依次為
顏值,性格,身高,上進(jìn)心,資產(chǎn)情況,女生中意結(jié)果
帥,好,高,上進(jìn),有錢,中意
不帥,好,高,上進(jìn),有錢,中意
帥,不好,高,上進(jìn),有錢,中意
帥,好,不高,上進(jìn),有錢,中意
帥,好,高,不上進(jìn),有錢,中意
帥,好,高,上進(jìn),不有錢,中意
帥,好,不高,不上進(jìn),有錢,不中意
不帥,不好,不高,上進(jìn),有錢,中意
不帥,不好,不高,上進(jìn),不有錢,不中意
帥,好,不高,上進(jìn),不有錢,中意
不帥,好,高,不上進(jìn),有錢,不中意
帥,不好,高,上進(jìn),有錢,不中意
不帥,好,高,上進(jìn),有錢,不中意
帥,不好,高,上進(jìn),不有錢,中意
帥,不好,高,不上進(jìn),有錢,中意
帥,好,高,上進(jìn),不有錢,不中意
帥,不好,不高,不上進(jìn),不有錢,不中意
不帥,不好,不高,不上進(jìn),不有錢,不中意
帥,好,不高,上進(jìn),有錢,中意
不帥,不好,不高,不上進(jìn),有錢,不中意
帥,好,高,上進(jìn),不有錢,中意
帥,好,不高,不上進(jìn),有錢,中意
帥,好,高,不上進(jìn),不有錢,不中意
帥,不好,高,不上進(jìn),有錢,不中意
代碼實(shí)現(xiàn)
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author liuya
*/
public class NaiveBayesModel {
//樣本數(shù)據(jù)
private static List<List<String>> data = new ArrayList<>();
//樣本數(shù)據(jù)
private static Set<List<String>> dataSet = new HashSet<>();
//分類模型
public static Map<String,String> modelMap = new HashMap<>();
//樣本數(shù)據(jù)集
private static String path = "./src/data.txt";
public static void main(String[] args) {
//訓(xùn)練模型
trainingModel();
//識(shí)別
classification("帥","好","高","上進(jìn)","有錢");
classification("不帥","不好","不高","不上進(jìn)","不有錢");
}
/**
* 導(dǎo)入數(shù)據(jù)
* @param path
* @return
*/
public static void readData(String path){
List<String> row = null;
try {
InputStreamReader isr = new InputStreamReader(new FileInputStream(new File(path)));
BufferedReader br = new BufferedReader(isr);
String str = null;
while((str = br.readLine()) != null){
row = new ArrayList<>();
String[] str1 = str.split(",");
for(int i = 0; i < str1.length ; i++) {
row.add(str1[i]);
}
dataSet.add(row);
data.add(row);
}
br.close();
isr.close();
} catch (Exception e) {
e.printStackTrace();
System.out.println("讀取文件內(nèi)容出錯(cuò)!");
}
}
public static void trainingModel() {
readData(path);
String category1="中意";
String category2="不中意";
dataSet.forEach(e->{
double categoryP1= calculateBayesian(e.get(0),e.get(1),e.get(2),e.get(3),e.get(4),category1);
double categoryP2= calculateBayesian(e.get(0),e.get(1),e.get(2),e.get(3),e.get(4),category2);
String result=categoryP1>categoryP2?category1:category2;
modelMap.put(e.get(0)+"-"+e.get(1)+"-"+e.get(2)+"-"+e.get(3)+"-"+e.get(4),result);
});
}
/**
* 分類的識(shí)別
* */
public static void classification(String look, String character, String height, String progresses, String wealthy){
String key=look+"-"+character+"-"+height+"-"+progresses+"-"+wealthy;
String result=modelMap.get(key);
System.out.println("特征為"+look+","+character+","+height+","+progresses+","+wealthy+"的對(duì)象,女生"+result);
}
/**
* 分類的核心是比較樸素貝葉斯的結(jié)果值,結(jié)果值大的認(rèn)為就屬于該分類(會(huì)有誤差,數(shù)據(jù)集量越大,結(jié)果判定的準(zhǔn)確率就會(huì)越高)由于分母相同可以直接比較分子來(lái)確定分類
* */
public static double calculateBayesian(String look, String character, String height, String progresses, String wealthy,String category) {
//獲取P(x|y)的分母
// double denominator = getDenominator(look,character,height,progresses,wealthy);
//獲取P(x|y)的分子
double molecule = getMolecule(look,character,height,progresses,wealthy,category);
return molecule/1;
}
/**
* 獲取p(x|y)分子
* @return
*/
public static double getMolecule(String look, String character, String height, String progresses, String wealthy,String category) {
double resultCP = getProbability(5, category);
double lookCP = getProbability(0, look, category);
double characterCP = getProbability(1, character, category);
double heightCP = getProbability(2, height, category);
double progressesCP = getProbability(3, progresses, category);
double wealthyCP = getProbability(4, wealthy, category);
return lookCP * characterCP * heightCP * progressesCP * wealthyCP * resultCP;
}
/**
* 獲取p(x|y)分母
* @return
*/
public static double getDenominator(String look, String character, String height, String progresses, String wealthy) {
double lookP = getProbability(0, look);
double characterP = getProbability(1, character);
double heightP = getProbability(2, height);
double progressesP = getProbability(3, progresses);
double wealthyP = getProbability(4, wealthy);
return lookP * characterP * heightP * progressesP * wealthyP;
}
/**
* 獲取某特征的概率
* @return
*/
private static double getProbability(int index, String feature) {
int size = data.size();
int num = 0;
for (int i = 0; i < size; i++) {
if (data.get(i).get(index).equals(feature)) {
num++;
}
}
return (double) num / size;
}
/**
* 獲取某類別下某特征的概率
* @return
*/
private static double getProbability(int index, String feature, String category) {
List<List<String>> filterData=data.stream().filter(e -> e.get(e.size() - 1).equals(category)).collect(Collectors.toList());
int size =filterData.size();
int num = 0;
for (int i = 0; i < size; i++) {
if (data.get(i).get(index).equals(feature)) {
num++;
}
}
return (double) num / size;
}
}輸出結(jié)果

使用場(chǎng)景
比如網(wǎng)站垃圾信息分類,文章自動(dòng)分類,網(wǎng)站垃圾郵件分類,文件分類等。
以反垃圾啊郵件為例說(shuō)明分類算法的使用,先將批量已經(jīng)分類的郵件樣本(如5000封正常的郵件,2000封垃圾郵件),輸入分類算法進(jìn)行訓(xùn)練,得到一個(gè)垃圾郵件分類模型,然后利用分類算法結(jié)合分類模型對(duì)待處理郵件進(jìn)行分類識(shí)別。
根據(jù)已經(jīng)分類的樣本信息提取出一組特征信息的概率,比如郵件中“信用卡”這個(gè)詞出現(xiàn)在垃圾郵件的中的概率為20%,在非垃圾郵件的概率為1%,就得到一個(gè)分類模型。然后從待識(shí)別處理的郵件中提取特征值,結(jié)合分類模型,就可以判斷其分類是不是垃圾郵件。由于貝葉斯算法得到的分類判斷是概率值,所以可能會(huì)出現(xiàn)誤判。

以上就是Java利用樸素貝葉斯分類算法實(shí)現(xiàn)信息分類的詳細(xì)內(nèi)容,更多關(guān)于Java 信息分類的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Spring Cloud Config 使用本地配置文件方式
這篇文章主要介紹了Spring Cloud Config 使用本地配置文件方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
Mybatis中and和循環(huán)or混用操作(or轉(zhuǎn)換成in)
這篇文章主要介紹了Mybatis中and和循環(huán)or混用操作(or轉(zhuǎn)換成in),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
Java語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單FTP軟件 FTP本地文件管理模塊實(shí)現(xiàn)(9)
這篇文章主要為大家詳細(xì)介紹了Java語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單FTP軟件,F(xiàn)TP本地文件管理模塊的實(shí)現(xiàn)方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04
JAVASE精密邏輯控制過(guò)程詳解(分支和循環(huán)語(yǔ)句)
在一個(gè)程序執(zhí)行的過(guò)程中各條語(yǔ)句的執(zhí)行順序?qū)Τ绦虻慕Y(jié)果是有直接影響的,這篇文章主要給大家介紹了關(guān)于JAVASE精密邏輯控制(分支和循環(huán)語(yǔ)句)的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-04-04
Java如何在臨界區(qū)中避免競(jìng)態(tài)條件
這篇文章主要介紹了Java如何在臨界區(qū)中避免競(jìng)態(tài)條件,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10

