Alice支持中文

源碼下載地址:http://download.csdn.net/detail/zhanghui_hn/7126195


一、   爲什麼Alice不支持中文

因爲Alicequestion都會被bitoflife.chatterbean.text.Transformations類中的fit函數過濾,而過濾的表達式就是:

private finalPattern fitting = Pattern.compile("[^A-Z0-9]+");

只會保留英文字符和數字字符。順帶說一句,因爲Alice會將question全部轉爲大寫,所以上面的表達式中沒有a-z區間。

爲了讓中文不被過濾掉,就將上面的過濾式中添加中文字符。

         privatefinal Pattern fitting = Pattern.compile("[^A-Z0-9\u4e00-\u9FA5]+")

 

二、   Alice支持中文的原理

先解釋一下,Alice對英文支持的原理:

簡而言之:在語料庫中,找出匹配的用戶questionpattern,再返回pattern對應的template內容作爲answer

詳細點就是:Alice初始化時,將AIML文件中的<pattern>標籤的內容根據空格切分,組成一個Graphmaster對象;用戶的question也根據空格切分,根據匹配算法在Graphmaster對象中找到匹配的pattern標籤,再返回該pattern對應的template內容。

Graphmaster參考:http://www.alicebot.org/documentation/matching.html

 

Alice支持英文中的關鍵一點就是:英文輸入有空格,而中文輸入沒有空格,Alice就不會切分中文字符,只會把整個中文語句當做英文中一個單詞。

所以支持中文的關鍵一點就是:爲中文語句加空格

馬上想到了中文分詞器,我用的是IK分詞器.接下來問題就轉化爲:怎麼爲中文語句加空格?在什麼地方加空格?

有兩個地方要處理:

² 讀取AIML文件中的pattern標籤時,需要加空格。

² 讀取用戶question時,要加空格。


三、   代碼實踐

IK分詞器封裝函數

         這是就不多說了,csdn博客多得是IK分詞器用法。

     public static StringIKAnalysis(String str) {
 
       if(str.getBytes().length == str.length()) {
           //如果不包含中文,就直接返回。
           return str;
        }else {
           //由於IK分詞器,不支持特殊字符,所以將 * 改爲中文字符“這是星號”,中文分詞以後再將“這是星號”修正爲爲 *
           //同理將 _改爲中文字符串“這是下劃線”,中文分詞以後再將“這是下劃線”修正爲 _
            str= str.replaceAll("\\*","這是星號").replaceAll("_","這是下劃線");
        }
 
        StringBuffersb =new StringBuffer();
       try {
           byte[] bt =str.getBytes();
            InputStreamip =new ByteArrayInputStream(bt);
            Readerread =new InputStreamReader(ip);
           //設置爲智能分詞
            IKSegmenteriks =new IKSegmenter(read,true);
            Lexemet;
           while ((t =iks.next()) !=null) {
               //在每個分詞元之後添加空格
                sb.append(t.getLexemeText()+" ");
            }
           //sb.delete(sb.length() - 1, sb.length());
        }catch (IOException e) {
           //TODOAuto-generated catch block
        }
 
       returnsb.toString().replaceAll("這是星號","*").replaceAll("這是下劃線","_");
    }

讀取AIML文件的pattern標籤時加空格

         AIML的讀取解析工作由bitoflife.chatterbean.aiml.AIMLHandler類完成的。

修改pushTextNode函數,根據參數來判斷是否調用中文分詞器。

   /**
     *將一個節點的文本信息壓入棧中,並根據參數決定是否調用中文分詞器。
     *@param isToSegment 標識是否調用中文分詞器
     */
   privatevoidpushTextNode(Boolean isToSegment) {
        Stringpushed =text.toString();
       text.delete(0,text.length());
       if (ignoreWhitespace)
            pushed= pushed.replaceAll("^[\\s\n]+|[\\s\n]{2,}|\n","");
 
       if (!"".equals(pushed.trim())){
           if(!isToSegment) {
               stack.push(newText(pushed));
            }else {
                pushed= pushed.toUpperCase();
               stack.push(newText(cn.edu.scut.cs.IKAnalyzer.ChineseSegmenter.IKAnalysis(pushed)));
            }
        }
    }

startElementendElement函數中爲patternthat標籤內的中文字符添加空格。將pushTextNode()函數的調用語句改爲:

pushTextNode(qname.toLowerCase().equals("pattern")

                ||qname.toLowerCase().equals("that"));

順帶說一句that標籤也可能需要中文分詞的。


讀取用戶question時加空格

         這個很簡單,在public void normalization(Sentencesentence)函數中第二行添加調用中文分詞函數:

input =cn.edu.scut.cs.IKAnalyzer.ChineseSegmenter.IKAnalysis(input);

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章