<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      全文檢索、數(shù)據(jù)挖掘、推薦引擎系列---去除停止詞添加同義詞

      Lucene對文本解析是作為全文索引及全文檢索的預處理形式出現(xiàn)的,因此在一般的Lucene文檔中,這一部分都不是重點,往往一帶而過,但是對于要建立基于文本的內容推薦引擎來說,卻是相當關鍵的一步,因此有必要認真研究一下Lucene對文解析的過程。
      Lucene對文本的解析對用戶的接口是Analyzer的某個子類,Lucene內置了幾個子類,但是對于英文來說StandardAnalyzer是最常用的一個子類,可以處理一般英文的文解析功能。但是對于漢字而言,Lucene提供了兩個擴展包,一個是CJKAnalyzer和SmartChineseAnalyzer,其中SmartAnalyzer對處理中文分詞非常適合,但是遺憾的是,該類將詞典利用隱馬可夫過程算法,集成在了算法里,這樣的優(yōu)點是減小了體積,并且安裝方便,但是如果想向詞庫中添加單詞就需要重新學習,不太方便。因此我們選擇了MMSeg4j,這個開源的中文分詞模塊,這個開源軟件的最大優(yōu)點就可用戶可擴展中文詞庫,非常方便,缺點是體積大加載慢。
      首先通過一個簡單的程序來看中文分詞的使用:
      Analyzer analyzer = null;
      //analyzer = new StandardAnalyzer(Version.LUCENE_33);
      //analyzer = new SimpleAnalyzer(Version.LUCENE_33);
      analyzer = new MMSegAnalyzer();
      TokenStream tokenStrm = analyzer.tokenStream("content", new StringReader(examples));
      OffsetAttribute offsetAttr = tokenStrm.getAttribute(OffsetAttribute.class);
      CharTermAttribute charTermAttr = tokenStrm.getAttribute(CharTermAttribute.class);
      PositionIncrementAttribute posIncrAttr =
      tokenStrm.addAttribute(PositionIncrementAttribute.class);
      TypeAttribute typeAttr = tokenStrm.addAttribute(TypeAttribute.class);
      String term = null;
      int i = 0;
      int len = 0;
      char[] charBuf = null;
      int termPos = 0;
      int termIncr = 0;
      try {
      while (tokenStrm.incrementToken()) {
      charBuf = charTermAttr.buffer();
      termIncr = posIncrAttr.getPositionIncrement();
      if (termIncr > 0) {
      termPos += termIncr;
      }
      for (i=(charBuf.length - 1); i>=0; i--) {
      if (charBuf[i] > 0) {
      len = i + 1;
      break;
      }
      }
      //term = new String(charBuf, offsetAttr.startOffset(), offsetAttr.endOffset());
      term = new String(charBuf, 0, offsetAttr.endOffset() - offsetAttr.startOffset());
      System.out.print("[" + term + ":" + termPos + "/" + termIncr + ":" +
      typeAttr.type() + ";" + offsetAttr.startOffset() + "-" + offsetAttr.endOffset() + "] ");
      }
      } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
      }
      這里需要注意的是:
      TermAttribute已經在Lucene的新版本中被標為過期,所以程序中使用CharTermAttribute來提取每個中文分詞的信息
      MMSegAnalyzer的分詞效果在英文的條件下基本與Lucene內置的StandardAnalyzer相同
      可以進行初步的中文分詞之后,我們還需處理停止詞去除,例如的、地、得、了、呀等語氣詞,還有就是添加同義詞:第一種是完全意義上的同義詞,如手機和移動電話,第二種是縮寫與全稱,如中國和中華人民共和國,第三種是中文和英文,如計算機和PC,第四種是各種專業(yè)詞匯同義詞,如藥品名和學名,最后可能還有一些網(wǎng)絡詞語如神馬和什么等。
      在Lucene架構下,有兩種實現(xiàn)方式,第一種是編寫TokenFilter類來實現(xiàn)轉換和添加,還有一種就是直接集成在相應的Analyzer中實現(xiàn)這些功能。如果像Lucene這樣的開源軟件,講求系統(tǒng)的可擴展性的話,選擇開發(fā)獨立的TokenFilter較好,但是對于我們自己的項目,選擇集成在Analyzer中將是更好的選擇,這樣可以提高程序執(zhí)行效率,因為TokenFilter需要重新逐個過一遍所有的單詞,效率比較低,而集成在Analyzer中可以保證在分解出單詞的過程中就完成了各種分詞操作,效率當然會提高了。
      Lucene在文本解析中,首先會在Analyzer中調用Tokenizer,將文本分拆能最基本的單位,英文是單詞,中文是單字或詞組,我們的去除停止詞和添加同義詞可以放入Tokenizer中,將每個新拆分的單詞進行處理,具體到我們所選用的MMSeg4j中文分詞模塊來說,就是需要在MMSegTokenizer類的incrementToken方法中,添加去除停止詞和添加同義詞:
      public boolean incrementToken() throws IOException {
      if (0 == synonymCnt) {
      clearAttributes();
      Word word = mmSeg.next();
      currWord = word;
      if(word != null) {
      // 去除截止詞如的、地、得、了等
      String wordStr = word.getString();
      if (stopWords.contains(wordStr)) {
      return incrementToken();
      }
      if (synonymKeyDict.get(wordStr) != null) { // 如果具有同義詞則需要先添加本身這個詞,然后依次添加同義詞
      synonymCnt = synonymDict.get(synonymKeyDict.get(wordStr)).size(); // 求出同義詞,作為結束條件控制
      }
      //termAtt.setTermBuffer(word.getSen(), word.getWordOffset(), word.getLength());
      offsetAtt.setOffset(word.getStartOffset(), word.getEndOffset());
      charTermAttr.copyBuffer(word.getSen(), word.getWordOffset(), word.getLength());
      posIncrAttr.setPositionIncrement(1);
      typeAtt.setType(word.getType());
      return true;
      } else {
      end();
      return false;
      }
      } else {
      char[] charArray = null;
      String orgWord = currWord.getString();
      int i = 0;
      Vector<String> synonyms = (Vector<String>)synonymDict.get(synonymKeyDict.get(orgWord));
      if (orgWord.equals(synonyms.elementAt(synonymCnt - 1))) { // 如果是原文中出現(xiàn)的那個詞則不作任何處理
      synonymCnt--;
      return incrementToken();
      }

      // 添加同意詞
      charArray = synonyms.elementAt(synonymCnt - 1).toCharArray();//termAtt.setTermBuffer(t1, 0, t1.length);
      offsetAtt.setOffset(currWord.getStartOffset(), currWord.getStartOffset() + charArray.length); // currWord.getEndOffset());
      typeAtt.setType(currWord.getType());
      charTermAttr.copyBuffer(charArray, 0, charArray.length);
      posIncrAttr.setPositionIncrement(0);
      synonymCnt--;

      return true;
      }
      }

      停止詞實現(xiàn)方式:

      private static String[] stopWordsArray = {"的", "地", "得", "了", "呀", "嗎", "啊",
      "a", "the", "in", "on"};

      在構造函數(shù)中進行初始化:

      if (null == stopWords) {
      int i = 0;
      stopWords = new Vector<String>();
      for (i=0; i<stopWordsArray.length; i++) {
      stopWords.add(stopWordsArray[i]);
      }
      }

      同義詞的實現(xiàn)方式:
      private static Collection<String> stopWords = null;
      private static Hashtable<String, String> synonymKeyDict = null;
      private static Hashtable<String, Collection<String>> synonymDict = null;

      同樣在初始化函數(shù)中進行初始化:注意這里只是簡單的初始化示例

      // 先找出一個詞的同義詞詞組key值,然后可以通過該key值從
      // 最終本部分內容將通過數(shù)據(jù)庫驅動方式進行初始化
      if (null == synonymDict) {
      synonymKeyDict = new Hashtable<String, String>();
      synonymDict = new Hashtable<String, Collection<String>>();
      synonymKeyDict.put("獵人", "0");
      synonymKeyDict.put("獵戶", "0");
      synonymKeyDict.put("獵手", "0");
      synonymKeyDict.put("狩獵者", "0");
      Collection<String> syn1 = new Vector<String>();
      syn1.add("獵人");
      syn1.add("獵戶");
      syn1.add("獵手");
      syn1.add("狩獵者");
      synonymDict.put("0", syn1);
      // 添加狗和犬
      synonymKeyDict.put("狗", "1");
      synonymKeyDict.put("犬", "1");
      Collection<String> syn2 = new Vector<String>();
      syn2.add("狗");
      syn2.add("犬");
      synonymDict.put("1", syn2);
      }

      在經過上述程序后,再對如下中文進行解析:咬死獵人的狗

      解析結果為:

      [咬:1/1:word;0-1] [死:2/1:word;1-2] [獵人:3/1:word;2-4] [狩獵者:3/0:word;2-5] [獵手:3/0:word;2-4] [獵戶:3/0:word;2-4] [狗:4/1:word;5-6] [犬:4/0:word;5-6]

      由上面結果可以看出,已經成功將獵人和狗的同義詞加入到分詞的結果中,這個工具就可以作為下面全文內容推薦引擎的實現(xiàn)基礎了。

      posted on 2011-08-19 17:13  最老程序員閆濤  閱讀(2538)  評論(2)    收藏  舉報

      導航

      主站蜘蛛池模板: 日韩中文字幕有码午夜美女| 普陀区| 国产av丝袜旗袍无码网站| 亚洲天堂一区二区三区四区 | 国产成人一区二区免av| 中文字幕亚洲无线码一区女同| 国内不卡不区二区三区| 国产成人精品国内自产色| 日韩精品无码一区二区视频| 国产成人一区二区三区影院动漫 | 无码人妻斩一区二区三区| 悠悠人体艺术视频在线播放| 日本精品一区二区不卡| 久久中文骚妇内射| 亚洲欧洲久久激情久av| 欧美白妞大战非洲大炮| 天天做天天爱夜夜爽| 无码国产精品一区二区av| 亚洲性日韩一区二区三区| 国产精品久久毛片| 99热成人精品热久久66| 国产午夜福利在线观看播放| 毛片免费观看天天干天天爽| 国产超碰无码最新上传| 精品国产亚洲区久久露脸| 好吊视频在线一区二区三区| 亚洲鸥美日韩精品久久| 亚洲 日韩 国产 制服 在线| 亚洲国产另类久久久精品黑人| 极品尤物被啪到呻吟喷水| 1区2区3区4区产品不卡码网站 | 丰满少妇高潮惨叫久久久| 色先锋av影音先锋在线| 日本午夜精品一区二区三区电影 | 人妻激情文学| 精品精品久久宅男的天堂| 97欧美精品系列一区二区| 红河县| 99国产精品欧美一区二区三区| 欧美成人一卡二卡三卡四卡| 精品人妻一区二区三区四区在线 |