HanLP-樸素貝葉斯分類預測缺陷
文章整理自 baiziyu 的知乎專欄,感興趣的朋友可以去關注下這位大神的專欄,很多關於自然語言處理的文章寫的很不錯。昨天看到他的分享的兩篇關於樸素貝葉斯分類預測的文章,整理了一下分享給給大家,文章已做部分修改!
樸素貝葉斯分類時,最好取對數變相乘為相加,防止預測結果溢位。可能出現的badcase就是明明訓練語料X類目下沒有詞語t,而系統就將文字預測為X類目。解決方法就時改相乘為取對數相加。HanLP的樸素貝葉斯分類計算沒有用對數相加的方法,而是直接用的概率相乘,很有可能溢位。
對上述內容做一些更正,HanLP的樸素貝葉斯是按照概率取對數相加做的。
看一下下邊的程式碼
public double[] categorize(Document document) throws IllegalArgumentException, IllegalStateException
{
Integer category;
Integer feature;
Integer occurrences;
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之間的數值,這