自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Java實(shí)現(xiàn)基于樸素貝葉斯的情感詞分析

開發(fā) 后端
本文我們就來介紹一下樸素貝葉斯分類的理論基礎(chǔ)和它的實(shí)際使用。在學(xué)習(xí)樸素貝葉斯分類以及正式開始情感詞分析之前,我們首先需要了解一下貝葉斯定理的數(shù)學(xué)基礎(chǔ)。

[[393788]]

樸素貝葉斯(Naive Bayesian)是一種基于貝葉斯定理和特征條件獨(dú)立假設(shè)的分類方法,它是基于概率論的一種有監(jiān)督學(xué)習(xí)方法,被廣泛應(yīng)用于自然語言處理,并在機(jī)器學(xué)習(xí)領(lǐng)域中占據(jù)了非常重要的地位。在之前做過的一個(gè)項(xiàng)目中,就用到了樸素貝葉斯分類器,將它應(yīng)用于情感詞的分析處理,并取得了不錯(cuò)的效果,本文我們就來介紹一下樸素貝葉斯分類的理論基礎(chǔ)和它的實(shí)際使用。

在學(xué)習(xí)樸素貝葉斯分類以及正式開始情感詞分析之前,我們首先需要了解一下貝葉斯定理的數(shù)學(xué)基礎(chǔ)。

貝葉斯定理

貝葉斯定理是關(guān)于隨機(jī)事件A和B的條件概率的定理,公式如下:

在上面的公式中,每一項(xiàng)表示的意義如下:

  • P(A):先驗(yàn)概率(prior probability),是在沒有任何條件限制下事件A發(fā)生的概率,也叫基礎(chǔ)概率,是對(duì)A事件概率的一個(gè)主觀判斷
  • P(A|B):在B發(fā)生的情況下A發(fā)生的可能性,也被稱為A的后驗(yàn)概率(posterior probability)
  • P(B|A):似然性,也被稱為條件似然(conditional likelihood)
  • P(B):不論A是否發(fā)生,在所有情況下B發(fā)生的概率,它被稱為整體似然或歸一化常量(normalizing constant)

按照上面的解釋,貝葉斯定理可以表述為:

  • 后驗(yàn)概率 = 先驗(yàn)概率 * 似然性 / 歸一化常量

通俗的來說,可以理解為當(dāng)我們不能確定某一個(gè)事件發(fā)生的概率時(shí),可以依靠與該事件本質(zhì)屬性相關(guān)的事件發(fā)生的概率去推測該事件發(fā)生的概率。用數(shù)學(xué)語言來表達(dá)就是,支持某項(xiàng)屬性的事件發(fā)生得愈多,則該事件發(fā)生的的可能性就愈大,這個(gè)推理過程也被叫做貝葉斯推理。

在查閱的一些文檔中,P(B|A)/P(B) 可以被稱為可能性函數(shù),它作為一個(gè)調(diào)整因子,表示新信息B對(duì)事件A帶來的調(diào)整,作用是將先驗(yàn)概率(主觀判斷)調(diào)整到更接近真實(shí)的概率。那么,貝葉斯定理也可以理解為:

  • 新信息出現(xiàn)后A的概率 = A的先驗(yàn)概率 * 新信息帶來的調(diào)整

舉一個(gè)例子,方便大家更直觀的理解這一過程。假設(shè)統(tǒng)計(jì)了一段時(shí)間內(nèi)天氣和氣溫對(duì)于運(yùn)動(dòng)情況的影響,如下所示:

  1. 天氣  氣溫      運(yùn)動(dòng) 
  2. 晴天  非常高     游泳 
  3. 晴天  高       足球       
  4. 陰天  中       釣魚 
  5. 陰天  中       游泳 
  6. 晴天  低       游泳       
  7. 陰天  低       釣魚 

現(xiàn)在請計(jì)算在晴天,氣溫適中的情況下,去游泳的概率是多少?根據(jù)貝葉斯定理,計(jì)算過程如下:

  1. P(游泳|晴天,中溫)=P(晴天,中溫|游泳)*P(游泳)/P(晴天,中溫) 
  2.         =P(晴天|游泳)*P(中溫|游泳)*P(游泳)/[P(晴天)*P(中溫)] 
  3.         =2/3 * 1/3 *1/2 / (1/2 *1/3 ) 
  4.         =2/3 

最終得出去游泳的概率是2/3,上面就是基于貝葉斯定理,根據(jù)給定的特征,計(jì)算事件發(fā)生概率大小的過程。

貝葉斯分析的思路對(duì)于由證據(jù)的積累來推測一個(gè)事物的發(fā)生的概率具有重大作用,當(dāng)我們要預(yù)測一個(gè)事物,首先會(huì)根據(jù)已有的經(jīng)驗(yàn)和知識(shí)推斷一個(gè)先驗(yàn)概率,然后在新證據(jù)不斷的積累的情況下調(diào)整這個(gè)概率。整個(gè)通過累積證據(jù)來得到一個(gè)事件發(fā)生概率的過程我們稱為貝葉斯分析。這樣,貝葉斯底層的思想就可以概括為,如果能夠掌握一個(gè)事情的全部信息,就能夠計(jì)算出它的一個(gè)客觀概率。

另外,在貝葉斯公式的基礎(chǔ)上進(jìn)行變形,可以得到下面的公式:

其中B1,B2,…,Bj是一個(gè)完備事件組,上面的公式可以表示在事件A已經(jīng)發(fā)生的條件下,尋找導(dǎo)致A發(fā)生的各種“原因”的Bi的概率。

樸素貝葉斯

在學(xué)習(xí)樸素貝葉斯之前,首先需要對(duì)貝葉斯分類進(jìn)行一下了解,貝葉斯分類通過預(yù)測一個(gè)對(duì)象屬于某個(gè)類別的概率,通過比較不同類別概率的大小預(yù)測其最可能從屬的類別,是基于貝葉斯定理而構(gòu)成出來的。在處理大規(guī)模數(shù)據(jù)集時(shí),貝葉斯分類器表現(xiàn)出較高的分類準(zhǔn)確性。

貝葉斯分類在處理一個(gè)未知類型的樣本X時(shí),可以先算出X屬于每一個(gè)類別Ci的概率 P(Ci|X),然后選擇其中概率最大的類別。假設(shè)有兩個(gè)特征變量x和y,并且存在兩個(gè)分類類別C1和C2,結(jié)合貝葉斯定理:

  • 如果P(C1|x,y) > P(C2|x,y),說明在x和y發(fā)生的條件下,C1比C2發(fā)生的概率要大,那么它應(yīng)該屬于類別C1
  • 反之如果P(C1|x,y) < P(C2|x,y),那么它應(yīng)該屬于類別C2

而樸素貝葉斯模型(Naive Bayesian Model)作為一種強(qiáng)大的預(yù)測建模算法,它在貝葉斯定理的基礎(chǔ)上進(jìn)行了簡化,假定了目標(biāo)的特征屬性之間相互獨(dú)立,這也是它被形容為“樸素”的原因。在實(shí)際情況中如果屬性之間存在關(guān)聯(lián),那么分類準(zhǔn)確率會(huì)降低,不過對(duì)于解決絕大部分的復(fù)雜問題非常有效。

設(shè)在樣本數(shù)據(jù)集D上,樣本數(shù)據(jù)的特征屬性集為,類變量可被分為,即數(shù)據(jù)集D可以被分為個(gè)類別。我們假設(shè)相互獨(dú)立,那么由貝葉斯定理可得:

對(duì)于相同的測試樣本,分母P(X)的大小是固定不變的,因此在比較后驗(yàn)概率時(shí),我們可以只比較分子的大小即可。

在這里解釋一下貝葉斯定理、貝葉斯分類和樸素貝葉斯之間的區(qū)別,貝葉斯定理作為理論基礎(chǔ),解決了概率論中的逆概率問題,在這個(gè)基礎(chǔ)上人們設(shè)計(jì)出了貝葉斯分類器,而樸素貝葉斯是貝葉斯分類器中的一種,也是最簡單和常用的分類器,可以使用下面的圖來表示它們之間的關(guān)系:

在實(shí)際應(yīng)用中,樸素貝葉斯有廣泛的應(yīng)用,在文本分類、垃圾郵件過濾、情感預(yù)測及釣魚網(wǎng)站的檢測方面都能夠起到良好的效果。為了訓(xùn)練樸素貝葉斯模型,我們需要先在訓(xùn)練集的基礎(chǔ)上對(duì)分類好的數(shù)據(jù)進(jìn)行訓(xùn)練,計(jì)算出先驗(yàn)概率和每個(gè)屬性的條件概率,計(jì)算完成后,概率模型就可以使用貝葉斯原理對(duì)新數(shù)據(jù)進(jìn)行預(yù)測。

貝葉斯推斷與人腦的工作機(jī)制很像,這也是它為什么能夠成為機(jī)器學(xué)習(xí)的基礎(chǔ),大腦的決策過程就是先對(duì)事物進(jìn)行主觀判斷,然后搜集新的信息,優(yōu)化主觀判斷,如果新的信息符合這個(gè)主觀判斷,那就提高主觀判斷的可信度,如果不符合,就降低主觀判斷的可信度。

代碼實(shí)現(xiàn)

在對(duì)理論有了基本的了解后,我們開始分析怎樣將樸素貝葉斯應(yīng)用于我們文本處理的情感詞分析中。主要步驟如下:

  • 對(duì)訓(xùn)練集和測試集完成文本分詞,并通過主觀判斷標(biāo)注所屬的分類
  • 對(duì)訓(xùn)練集進(jìn)行訓(xùn)練,統(tǒng)計(jì)每個(gè)詞匯出現(xiàn)在分類下的次數(shù),計(jì)算每個(gè)類別在訓(xùn)練樣本中的出現(xiàn)頻率、及每個(gè)特征屬性對(duì)每個(gè)類別的條件概率(即似然概率)
  • 將訓(xùn)練好的模型應(yīng)用于測試集的樣本上,根據(jù)貝葉斯分類計(jì)算樣本在每個(gè)分類下的概率大小
  • 比較在各個(gè)分類情況下的概率大小,推測文本最可能屬于的情感分類

使用流程圖表示:

1、準(zhǔn)備階段

首先準(zhǔn)備數(shù)據(jù)集,這里使用了對(duì)某酒店的評(píng)論數(shù)據(jù),根據(jù)主觀態(tài)度將其分為“好評(píng)”或“差評(píng)”這兩類待分類項(xiàng),對(duì)每行分詞后的語句打好了情感標(biāo)簽,并且已經(jīng)提前對(duì)完整語句完成了對(duì)分詞,數(shù)據(jù)格式如下:

在每行的數(shù)據(jù)的頭部,是添加的“好評(píng)”或“差評(píng)”標(biāo)簽,標(biāo)簽與分詞采用tab分割,詞語之間使用空格分割。按照比例,將數(shù)據(jù)集的80%作為訓(xùn)練集,剩余20%作為測試集,分配過程盡量保證隨機(jī)原則。

2、訓(xùn)練階段

在訓(xùn)練階段,主要完成詞頻的統(tǒng)計(jì)工作。讀取訓(xùn)練集,統(tǒng)計(jì)出每個(gè)詞屬于該分類下出現(xiàn)的次數(shù),用于后續(xù)求解每個(gè)詞出現(xiàn)在各個(gè)類別下的概率,即詞匯與主觀分類情感之間的關(guān)系:

  1. private static void train(){ 
  2.     Map<String,Integer> parameters = new HashMap<>(); 
  3.     try(BufferedReader br = new BufferedReader(new FileReader(trainingData))){  //訓(xùn)練集數(shù)據(jù) 
  4.         String sentence; 
  5.         while(null!=(sentence=br.readLine())){ 
  6.             String[] content = sentence.split("\t| "); //以tab或空格分詞 
  7.             parameters.put(content[0],parameters.getOrDefault(content[0],0)+1); 
  8.             for (int i = 1; i < content.length; i++) { 
  9.                 parameters.put(content[0]+"-"+content[i], parameters.getOrDefault(content[0]+"-"+content[i], 0)+1); 
  10.             } 
  11.         } 
  12.     }catch (IOException e){ 
  13.         e.printStackTrace(); 
  14.     } 
  15.     saveModel(parameters); 

將訓(xùn)練好的模型保存到文件中,可以方便在下次使用時(shí)不用重復(fù)進(jìn)行模型的訓(xùn)練:

  1. private static void saveModel(Map<String,Integer> parameters){ 
  2.     try(BufferedWriter bw =new BufferedWriter(new FileWriter(modelFilePath))){ 
  3.         parameters.keySet().stream().forEach(key->{ 
  4.             try { 
  5.                 bw.append(key+"\t"+parameters.get(key)+"\r\n"); 
  6.             } catch (IOException e) { 
  7.                 e.printStackTrace(); 
  8.             } 
  9.         }); 
  10.         bw.flush(); 
  11.     }catch (IOException e){ 
  12.         e.printStackTrace(); 
  13.     } 

查看保存好的模型,數(shù)據(jù)的格式如下:

  1. 好評(píng)-免費(fèi)送 3 
  2. 差評(píng)-真煩 1 
  3. 好評(píng)-禮品 3 
  4. 差評(píng)-臟亂差 6 
  5. 好評(píng)-解決 15 
  6. 差評(píng)-挨宰 1 
  7. …… 

這里對(duì)訓(xùn)練的模型進(jìn)行保存,所以如果后續(xù)有同樣的分類任務(wù)時(shí),可以直接在訓(xùn)練集的基礎(chǔ)上進(jìn)行計(jì)算,對(duì)于分類速度要求較高的任務(wù),能夠有效的提高計(jì)算的速度。

3、加載模型

加載訓(xùn)練好的模型:

  1. private static HashMap<String, Integer> parameters = null;  //用于存放模型 
  2. private static Map<String, Double> catagory=null
  3. private static String[] labels = {"好評(píng)""差評(píng)""總數(shù)","priorGood","priorBad"}; 
  4.  
  5. private static void loadModel() throws IOException { 
  6.     parameters = new HashMap<>(); 
  7.     List<String> parameterData = Files.readAllLines(Paths.get(modelFilePath)); 
  8.     parameterData.stream().forEach(parameter -> { 
  9.         String[] split = parameter.split("\t"); 
  10.         String key = split[0]; 
  11.         int value = Integer.parseInt(split[1]); 
  12.         parameters.put(key, value); 
  13.     }); 
  14.  
  15.     calculateCatagory(); //分類 

對(duì)詞進(jìn)行分類,統(tǒng)計(jì)出好評(píng)及差評(píng)的詞頻總數(shù),并基于它們先計(jì)算得出先驗(yàn)概率:

  1. //計(jì)算模型中類別的總數(shù) 
  2. public static void calculateCatagory() { 
  3.     catagory = new HashMap<>(); 
  4.     double good = 0.0; //好評(píng)詞頻總數(shù) 
  5.     double bad = 0.0;   //差評(píng)的詞頻總數(shù) 
  6.     double total;   //總詞頻 
  7.  
  8.     for (String key : parameters.keySet()) { 
  9.         Integer value = parameters.get(key); 
  10.         if (key.contains("好評(píng)-")) { 
  11.             good += value; 
  12.         } else if (key.contains("差評(píng)-")) { 
  13.             bad += value; 
  14.         } 
  15.     } 
  16.     total = good + bad; 
  17.     catagory.put(labels[0], good); 
  18.     catagory.put(labels[1], bad); 
  19.     catagory.put(labels[2], total); 
  20.     catagory.put(labels[3],good/total); //好評(píng)先驗(yàn)概率 
  21.     catagory.put(labels[4],bad/total); //差評(píng)先驗(yàn)概率 

查看執(zhí)行完后的統(tǒng)計(jì)值:

“好評(píng)”對(duì)應(yīng)的詞匯出現(xiàn)的總次數(shù)是46316個(gè),“差評(píng)”對(duì)應(yīng)的詞匯出現(xiàn)的總次數(shù)是77292個(gè),訓(xùn)練集詞頻總數(shù)為123608個(gè),并可基于它們計(jì)算出它們的先驗(yàn)概率:

  1. 該文檔屬于某個(gè)類別的條件概率= 該類別的所有詞條詞頻總數(shù) / 所有詞條的詞頻總數(shù) 

4、測試階段

測試階段,加載我們提前準(zhǔn)備好的測試集,對(duì)每一行分詞后的評(píng)論語句進(jìn)行主觀情感的預(yù)測:

  1. private static void predictAll() { 
  2.     double accuracyCount = 0.;//準(zhǔn)確個(gè)數(shù) 
  3.     int amount = 0;    //測試集數(shù)據(jù)總量 
  4.  
  5.     try (BufferedWriter bw = new BufferedWriter(new FileWriter(outputFilePath))) { 
  6.         List<String> testData = Files.readAllLines(Paths.get(testFilePath));    //測試集數(shù)據(jù) 
  7.         for (String instance : testData) { 
  8.             String conclusion = instance.substring(0, instance.indexOf("\t"));  //已經(jīng)打好的標(biāo)簽 
  9.             String sentence = instance.substring(instance.indexOf("\t") + 1); 
  10.             String prediction = predict(sentence);  //預(yù)測結(jié)果 
  11.  
  12.             bw.append(conclusion + " : " + prediction + "\r\n"); 
  13.             if (conclusion.equals(prediction)) { 
  14.                 accuracyCount += 1.; 
  15.             } 
  16.             amount += 1; 
  17.         } 
  18.         //計(jì)算準(zhǔn)確率 
  19.         System.out.println("accuracyCount: " + accuracyCount / amount); 
  20.     } catch (Exception e) { 
  21.         e.printStackTrace(); 
  22.     } 

在測試中,調(diào)用下面的predict方法進(jìn)行分類判斷。在計(jì)算前,再來回顧一下上面的公式,在程序中進(jìn)行簡化運(yùn)算:

對(duì)于同一個(gè)預(yù)測樣本,分母相同,所以我們可以只比較分子的大小。對(duì)分子部分進(jìn)行進(jìn)一步簡化,對(duì)于連乘預(yù)算,我們可以對(duì)其進(jìn)行對(duì)數(shù)操作,變成各部分相加:

這樣對(duì)于概率的大小比較,就可以簡化為比較 先驗(yàn)概率和各個(gè)似然概率分別取對(duì)數(shù)后相加的和。先驗(yàn)概率我們在之前的步驟中已經(jīng)計(jì)算完成并保存,所以這里只計(jì)算各詞匯在分類條件下的似然概率即可。predict方法的實(shí)現(xiàn)如下:

  1. private static String predict(String sentence) { 
  2.     String[] features = sentence.split(" "); 
  3.     String prediction; 
  4.  
  5.     //分別預(yù)測好評(píng)和差評(píng) 
  6.     double good = likelihoodSum(labels[0], features) + Math.log(catagory.get(labels[3])); 
  7.     double bad = likelihoodSum(labels[1], features) + Math.log(catagory.get(labels[4])); 
  8.     return good >= bad?labels[0]:labels[1]; 

在其中調(diào)用likelihood方法計(jì)算似然概率的對(duì)數(shù)和:

  1. //似然概率的計(jì)算 
  2. public static double likelihoodSum(String label, String[] features) { 
  3.     double p = 0.0; 
  4.     Double total = catagory.get(label) + 1;//分母平滑處理 
  5.     for (String word : features) { 
  6.         Integer count = parameters.getOrDefault(label + "-" + word, 0) + 1;//分子平滑處理 
  7.         //計(jì)算在該類別的情況下是該詞的概率,用該詞的詞頻除以類別的總詞頻 
  8.         p += Math.log(count / total); 
  9.     } 
  10.     return p; 

在計(jì)算似然概率的方法中,如果出現(xiàn)在訓(xùn)練集中沒有包括的詞匯,那么會(huì)出現(xiàn)它的似然概率為0的情況,為了防止這種情況,對(duì)分子分母進(jìn)行了分別加1的平滑操作。

最后在主函數(shù)中調(diào)用上面的步驟,最終如果計(jì)算出基于樣本的好評(píng)概率大于等于差評(píng)概率,那么將它分類劃入“好評(píng)”,反之劃入“差評(píng)”類別,到此就完成了訓(xùn)練和測試的全過程:

  1. public static void main(String[] args) throws IOException { 
  2.     train(); 
  3.     loadModel(); 
  4.     predictAll(); 

執(zhí)行全部代碼,結(jié)果如下,可以看到獲取了93.35%的準(zhǔn)確率。


對(duì)比最后輸出的文檔中的標(biāo)簽與預(yù)測結(jié)果,可以看到,預(yù)測結(jié)果的準(zhǔn)確度還是非常高的。

5、總結(jié)

在上面的例子中,還有一些可以進(jìn)行改進(jìn)的地方,例如可以在前期建立情感詞庫,在特征值提取的過程中只提取情感詞,去除其余無用詞匯(如介詞等)對(duì)分類的影響,只選取關(guān)鍵的代表詞作為特征提取,達(dá)到更高的分類效率。另外,可以在建立詞庫時(shí),將測試集的情感詞也放入詞庫,避免出現(xiàn)在某個(gè)分類條件下似然概率為零的情況,簡化平滑步驟。

此外,樸素貝葉斯的分類對(duì)于追加訓(xùn)練集的情況有很好的應(yīng)用,如果訓(xùn)練集不斷的增加,可以在現(xiàn)有訓(xùn)練模型的基礎(chǔ)上添加新的樣本值、或?qū)σ延械臉颖局档膶傩赃M(jìn)行修改,在此基礎(chǔ)上,可以實(shí)現(xiàn)增量的模型修改。

 

責(zé)任編輯:姜華 來源: 碼農(nóng)參上
相關(guān)推薦

2017-07-12 11:27:05

樸素貝葉斯情感分析Python

2012-09-24 10:13:35

貝葉斯

2017-03-29 14:50:18

2017-07-24 10:36:37

Python機(jī)器學(xué)習(xí)樸素貝葉斯

2017-11-07 11:17:40

樸素貝葉斯畫像數(shù)據(jù)數(shù)據(jù)挖掘

2022-01-03 20:18:37

定理應(yīng)用貝葉斯

2021-08-30 11:53:36

機(jī)器學(xué)習(xí)人工智能計(jì)算機(jī)

2022-09-28 08:00:00

Python機(jī)器學(xué)習(xí)算法

2021-07-29 13:06:29

Python機(jī)器學(xué)習(xí)編程語言

2017-08-07 13:02:32

全棧必備貝葉斯

2018-09-13 12:51:58

數(shù)據(jù)挖掘算法樸素貝葉斯

2017-03-21 09:17:37

2023-01-31 15:49:51

機(jī)器學(xué)習(xí)函數(shù)評(píng)分函數(shù)

2013-05-08 09:05:48

狐貍貝葉斯大數(shù)據(jù)

2017-06-22 09:53:01

機(jī)器學(xué)習(xí)Python樸素貝葉斯

2018-07-27 13:55:12

貝葉斯分析線性回歸數(shù)據(jù)

2019-03-20 07:50:47

機(jī)器學(xué)習(xí)算法線性回歸

2016-08-30 00:14:09

大數(shù)據(jù)貝葉斯

2016-08-30 00:19:30

2024-10-11 16:53:16

貝葉斯人工智能網(wǎng)絡(luò)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)