(3.1)用ictclas4j進行中文分詞,並去除停用詞


酒店評論情感分析系統——用ictclas4j進行中文分詞,並去除停用詞

  ictclas4j是中科院計算所開發的中文分詞工具ICTCLAS的Java版本,因其分詞准確率較高,而備受青睞。

  注:ictclas4j缺點:

      a.在eclipse里的java文件一定要保存為gbk編碼才可以正常運行,utf-8是不能運行的

      b.ictclas4j目前不支持用戶自定義字典

1.  下載ictclas4j

  后面的附件中,我有放上ictclas4j的源碼包ictclas4j.zip

2.  在Eclipse中新建項目並進行相關配置

  首先把 ictclas4j解壓縮,然后把 Data文件夾整個拷貝到 Eclipse項目的文件夾下, 而 bin目錄下的 org文件夾整個拷貝到你Eclipse項目的 bin目錄下,把src目錄下的org文件夾整個拷貝到 Eclipse項目 的src目錄下。

3.  導入外部包commons-lang-2.0.jar

4.  測試ictclas4j的分詞效果

 

 1 import org.ictclas4j.bean.SegResult;  
 2 import org.ictclas4j.segment.SegTag;  
 3   
 4 public class TextSegmentation {  
 5   
 6     public static void main(String[] args) {  
 7         String fileContent = "中國科學院計算技術研究所在多年研究基礎上," +  
 8                 "耗時一年研制出了ICTCLAS漢語詞法分析系統";  
 9         SegTag segTag = new SegTag(1);// 分詞路徑的數目          
10         SegResult segResult = segTag.split(fileContent.trim());  
11         String classifyContent = segResult.getFinalResult();  
12         System.out.println("分詞結果\n"+classifyContent);  
13     }  
14 }  

輸出帶有詞性的標注結果:

1 分詞結果    
2 中國科學院/n 計算/n 技術/n 研究所/n 在/c 多年/m 研究/n 基礎/a 上/f ,/w 耗時/v 一/d 年/a 研制/v 出/q 了/u ICTCLAS/nx 漢語/n 詞法/n 分析/v 系統/a 

 

5.  用ictclas4j進行中文分詞,並去除停用詞

1)   在Eclipse中新建一個java project(如:sentence)

2)   按照上述第1,2,3的步驟配置好ictclas4j

3)   在sentence文件目錄中新建destFile目錄(用於存放分詞和去停用詞后的結果)和srcFile目錄(用於存放需要分詞的文本文件和停用詞表)

 

    srcFile目錄下:

 

    destFile目錄下:

 

4)   新建一個class(如:FileExcludeStopWord.java)

 

 1 import java.io.BufferedReader;
 2 import java.io.BufferedWriter;
 3 import java.io.File;
 4 import java.io.FileInputStream;
 5 import java.io.FileNotFoundException;
 6 import java.io.FileOutputStream;
 7 import java.io.InputStreamReader;
 8 import java.io.OutputStreamWriter;
 9 import java.util.*;
10 
11 import org.ictclas4j.bean.SegResult;  
12 import org.ictclas4j.segment.SegTag;
13 //import ICTCLAS.I3S.AC.ICTCLAS50;
14 
15 public class FileExcludeStopWord {
16     //停用詞詞表
17     public static final String stopWordTable = "." + File.separator + "srcFile" + File.separator + "StopWordTable.txt";
18 
19     public static void main(String[] args) {
20 
21         //源文件和目的文件
22         String srcFile = "." + File.separator + "srcFile" + File.separator + "酒店評論.txt";
23         String destFile = "." + File.separator + "destFile" + File.separator + "酒店評論.txt";
24         new FileExcludeStopWord().fileExcludeStopWord(srcFile, destFile);
25     }
26     
27     public void fileExcludeStopWord(String srcFile,String destFile){
28         try {
29             //讀取原文件和停用詞表
30             BufferedReader srcFileBr = new BufferedReader(new InputStreamReader(new FileInputStream(new File(srcFile))));
31             BufferedReader StopWordFileBr = new BufferedReader(new InputStreamReader(new FileInputStream(new File(stopWordTable))));
32             
33             //將去除停用詞的文本信息存入輸出文件
34             BufferedWriter destFileBw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(destFile))));
35             
36             //用來存放停用詞的集合
37             Set<String> stopWordSet = new HashSet<String>();
38             
39             //初始化停用詞集
40             String stopWord = null;
41             for(; (stopWord = StopWordFileBr.readLine()) != null;){
42                 stopWordSet.add(stopWord);        
43             }            
44             
45             String paragraph = null;
46             for(; (paragraph = srcFileBr.readLine()) != null;){
47                 //對讀入的文本進行分詞
48                 SegTag segTag = new SegTag(1);// 分詞路徑的數目          
49                 SegResult segResult = segTag.split(paragraph);
50                 String spiltResultStr = segResult.getFinalResult();    
51                 //得到分詞后的詞匯數組,以便后續比較
52                 String[] resultArray = spiltResultStr.split(" ");
53                                 
54                 //過濾停用詞            
55                 for(int i = 0; i< resultArray.length; i++){
56                     //System.out.println(resultArray[i]);
57                     if(stopWordSet.contains(resultArray[i])){
58                         resultArray[i] = null;
59                     }
60                     //System.out.println(resultArray[i]);    
61                 }
62                 
63                 //把過濾后的字符串數組存入到一個字符串中
64                 StringBuffer finalStr = new StringBuffer();
65                 for(int i = 0; i< resultArray.length; i++){
66                     if(resultArray[i] != null){
67                         finalStr = finalStr.append(resultArray[i]).append(" ");
68                     }
69                 }
70                 
71                 //將過濾后的文本信息寫入到指定文件中
72                 destFileBw.write(finalStr.toString());
73                 destFileBw.newLine();
74                 //輸出最后的去停用詞之后的結果
75                 System.out.println(finalStr);
76             }
77             
78             //關閉輸入流
79             destFileBw.close();
80             StopWordFileBr.close();
81             srcFileBr.close();            
82             
83         } catch (FileNotFoundException e) {
84             // TODO Auto-generated catch block
85             e.printStackTrace();
86         } catch(Exception e){
87             e.printStackTrace();
88         }
89     }
90 }

酒店評論.txt中的內容:

總體評價:性價比很高,交通便利,周邊吃喝玩樂設施齊全,對面就是家樂福。但是前台男客服服務態度很一般,酒店光線太暗看不清,總感覺臟臟的,並且隔音效果一般,有一點點吵,導致晚上睡覺不踏實。對於價錢,三星級價格有點高,一次性用品要收費。

上述代碼輸出結果:

總體 評價 性 價 高 交通 便利 周邊 吃喝玩樂 設施 齊全 對面 家樂福 前台 男客 服 服務 態度 酒店 光線 太 暗 清 總 感覺 臟臟 隔音 效果 一點點 吵 導致 晚上 睡覺 踏實 價錢 三星級 價格 點 高 一次性 用品 收費

注:

  ictclas4j的分詞結果中本來是帶有詞性標注的,但是停用詞表中是沒有詞性標注,故要從分詞結果中除去停用詞,則原本的分詞詞性結果不應該出現,所以為了讓分詞的結果中不進行詞性的標注,進行了如下更改:

打開.../src/org/ictclas4j/segment中的SegTag.java文件,修改outputResult()函數,將:

result += sn.getSrcWord() + "/" + temp + " ";

改為:

result += sn.getSrcWord() + "  "; 

 

【補充】

6.  ictclas4j分詞過程中可能遇到的問題和解決方案

①   分詞的結果中不需要進行詞性的標注
打開.../src/org/ictclas4j/segment中的SegTag.java文件,修改outputResult()函數,將:

result += sn.getSrcWord() + "/" + temp + " ";

改為:

result += sn.getSrcWord() + "  "; 

②   “org.apache”

  這個新建的測試類可能會提示錯誤:"The import org.apache cannot be resolved",這是由於系統需要一個Apache的commons的jar包(如:commons-lang-2.0.jar)。

③ 在讀取外部文件的內容進行分詞時出現錯誤,如下所示:
 Exception in thread "main" java.lang.NullPointerException at org.ictclas4j.bean.Dictionary.getMaxMatch
 打開../src/org/ictclas4j/bean中的Dictionary.java文件,修改getMaxMatch()函數,在:

for (int j = 0; j < wis.size(); j++) {

之前加上如下語句,判斷為空條件:

if (wis == null) { return null; }

④ 讀取外部文件時由於編碼問題引起的錯誤

  注意文件的讀取方式,在打開文件的同時注意指定文件的編碼:

InputStreamReader read = new InputStreamReader (new FileInputStream(f),"UTF-8");  

  舉例如下:

 1 import java.io.BufferedReader;
 2 import java.io.File;
 3 import java.io.FileInputStream;
 4 import java.io.FileReader;
 5 import java.io.InputStreamReader;
 6 
 7 import org.ictclas4j.bean.SegResult;
 8 import org.ictclas4j.segment.SegTag;
 9 
10 public class Test {
11     public static void main(String[] args) throws Exception{
12         SegTag st = new SegTag(1);
13         String str = "";
14         int n = 0;
15         File f = new File("E:/corpus/traindatas/train_uy2ch.ch.txt");
16         InputStreamReader read = new InputStreamReader (new FileInputStream(f),"UTF-8");
17         BufferedReader reader=new BufferedReader(read);
18         String line;
19         while ((line = reader.readLine()) != null&&n<20) {
20             SegResult sr = st.split(line);
21             System.out.println(sr.getFinalResult());
22             n ++;
23             }
24         }
25     }

⑤ 在對大文件進行中文分詞時,出現了以下的錯誤信息:

java.lang.ArrayIndexOutOfBoundsException: -39
       at java.util.ArrayList.get(ArrayList.java:324)
       at org.ictclas4j.bean.Dictionary.findInOriginalTable(Dictionary.java:
422)
       at org.ictclas4j.bean.Dictionary.getFreq(Dictionary.java:632)
       at org.ictclas4j.segment.GraphGenerate.biGenerate(GraphGenerate.java:
170)
       at org.ictclas4j.segment.Segment.split(Segment.java:81)
       at com.ictclas4j.test.MyTest.main(MyTest.java:19)

可能的出錯原因:

分詞過程中出現了未能識別的字,如繁體字等

改錯方法:在Dictionary.java文件中找到findInOriginalTable()方法,將其中的:

if (res != null && wts != null) { 

改為:

if (res != null && wts != null &&index>=0 &&index<wts.size()) {

 

感謝如下博客:

1.使用ictclas4j進行中文分詞

2.使用ictclas4j進行中文分詞(續)

3.使用繼續完善前人寫的文章:使用ICTCLAS JAVA版(ictclas4j)進行中文分詞

4.Java過濾停用詞源碼

 

附件:ictclas4j+commons-lang-2.4.jar+stopword


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM