天天看點

HanLP-樸素貝葉斯分類預測缺陷

文章整理自 baiziyu 的知乎專欄,感興趣的朋友可以去關注下這位大神的專欄,很多關于自然語言處理的文章寫的很不錯。昨天看到他的分享的兩篇關于樸素貝葉斯分類預測的文章,整理了一下分享給給大家,文章已做部分修改!

HanLP-樸素貝葉斯分類預測缺陷

樸素貝葉斯分類時,最好取對數變相乘為相加,防止預測結果溢出。可能出現的badcase就是明明訓練語料X類目下沒有詞語t,而系統就将文本預測為X類目。解決方法就時改相乘為取對數相加。HanLP的樸素貝葉斯分類計算沒有用對數相加的方法,而是直接用的機率相乘,很有可能溢出。

對上述内容做一些更正,HanLP的樸素貝葉斯是按照機率取對數相加做的。

看一下下邊的代碼

@Override

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之間的數值,這一看就是機率值。

繼續閱讀