文章整理自 baiziyu 的知乎專欄,感興趣的朋友能夠去關注下這位大神的專欄,不少關於天然語言處理的文章寫的很不錯。昨天看到他的分享的兩篇關於樸素貝葉斯分類預測的文章,整理了一下分享給給你們,文章已作部分修改!ide
樸素貝葉斯分類時,最好取對數變相乘爲相加,防止預測結果溢出。可能出現的badcase就是明明訓練語料X類目下沒有詞語t,而系統就將文本預測爲X類目。解決方法就時改相乘爲取對數相加。HanLP的樸素貝葉斯分類計算沒有用對數相加的方法,而是直接用的機率相乘,頗有可能溢出。spa
對上述內容作一些更正,HanLP的樸素貝葉斯是按照機率取對數相加作的。.net
看一下下邊的代碼orm
public double[] categorize(Document document) throws IllegalArgumentException, IllegalStateException文檔
{get
Integer category;it
Integer feature;io
Integer occurrences;class
Double logprob;
double[] predictionScores = new double[model.catalog.length];
for (Map.Entry<Integer, Double> entry1 : model.logPriors.entrySet())
{
category = entry1.getKey();
logprob = entry1.getValue(); //用類目的對數似然初始化機率
//對文檔中的每一個特徵
for (Map.Entry<Integer, int[]> entry2 : document.tfMap.entrySet())
{
feature = entry2.getKey();
if (!model.logLikelihoods.containsKey(feature))
{
continue; //若是在模型中找不到就跳過了
}
occurrences = entry2.getValue()[0]; //獲取其在文檔中的頻次
logprob += occurrences * model.logLikelihoods.get(feature).get(category); //將對數似然乘上頻次
}
predictionScores[category] = logprob;
}
if (configProbabilityEnabled) MathUtility.normalizeExp(predictionScores);
return predictionScores;
}
這麼看來,以前遇到的下邊的這個badcase就還要再分析
[1] 化驗指標一變化患者就魂飛魄散,看醫生怎麼講解
核心詞:患者 看醫生
這裏「患者」和「看醫生」兩個詞都沒在「藝術」類訓練語料中出現,可是預測機率最大的反卻是「藝術」。
因爲用PyHanLP無法看到預測機率的計算過程,因此仍是把Python的分類預測代碼改成Java代碼調式看一下。今天移植了預處理,資源加載,人工干預部分的代碼,明天把剩餘預測部分移植爲Java再來看這個badcase。這就是樸素貝葉斯的優點,分析起來很是清晰容易。不過從PyHanLP的預測輸出機率值來看,不太像是取了對數相加獲得的,由於都是0-1之間的數值,這一看就是機率值