1. 程式人生 > >最大熵開源——openNLP MaxEnt

最大熵開源——openNLP MaxEnt

opennlp.maxent package是一個比較成熟的Java package,用來訓練和使用最大熵模型。
本文描述最大熵和使用opennlp.maxent package的一些相關細節。


一、最大熵是什麼?
參考:http://www-nlp.stanford.edu/~manning/
以免翻譯有誤,還是上原文吧~~~~~
Maximum entropy modeling is a framework for integrating information from many heterogeneous information sources for classification.  The data for a  classification problem is described as a (potentially large) number of features.  These features can be quite complex and allow the experimenter to make use of prior knowledge about what types of informations are expected to be important for classification. Each feature corresponds to a constraint on the model.  We then compute the maximum entropy model, the model with the maximum entropy of all the models that satisfy the constraints.  This term may seem perverse, since we have spent most of the book trying to minimize the (cross) entropy of models, but the idea is that we do not want to go beyond the data.  If we chose a model with less entropy, we would add `information' constraints to the model that are not justified by the empirical evidence available to us. Choosing the maximum entropy model is motivated by the desire to preserve as much uncertainty as possible.


概括:最大熵模型基本思想是除了你能觀察到的知識以外,對概率分佈不要作任何額外假設。
應用:詞性標註、句子發現、命名實體識別等自然語言處理領域及其他更多領域。
優點:不需要關注特徵之間的相互依賴,專注event空間即可。
由來:統計物理學。


二、最大熵模型的使用
1、概念

必備技能:
     1.An understanding of feature selection for maxent modeling.
     2.Java skills or the ability to read some example Java code and turn it into what you need.

特徵函式對映關係:
     outcomes (classes) and contexts -> true/false ,舉例:
     feature (outcome, context)  = { 1   if  outcome=DETERMINER &&  currentword(context) = "that"
                                                { 0   otherwise
注意:
     建模就是要選擇對於分類決策有用的特徵。
     特徵的理論表示和實現表示不一樣,如上面的例子
     理論表示 currentword(context)="that"
     實現表示 current=that" or even just "that"

2、model的使用
 現要做這麼一件事情:使用MaxEnt找出下面句子中的名字
 He succeeds Terrence D. Daniels, formerly a W.R. Grace vice chairman, who resigned.

 假如現在看到了單詞“Terrence”,你試圖去判斷它是否是名字,你可能會選擇如下特徵:
 "previous=succeeds", "current=Terrence", "next=D.", and "currentWordIsCapitalized". 甚至再加一個特徵 "Terrence" was seen as a name before


  那麼怎麼把這資訊變為實現呢?假設已經有了一個查詢名字的model,而且也已經使用這個模型建好了MaxEntModel介面的例項,至此可以使用openNLP maxent來判斷,流程如下:
   1.model的輸入準備
     特徵陣列String[],如上面定義。
   2.呼叫方法
      public double[] eval(String[] context);傳遞特徵String[]給model
      返回值:model賦給每個類別結果的概率值陣列。如結果可能是“TRUE”(索引為0)和“FALSE”(索引為1)。
  3.找到結果索引對應的名字
     呼叫public String getOutcome(int i);
  4.返回概率值最高的結果
     呼叫public String getBestOutcome(double[] outcomes);


3、model的訓練
   資料準備:event集合,實現EventStream物件。一個event包括outcome和context,如:
          outcome: T 
          context: previous=succeeds current=Terrence next=D. currentWordIsCapitalized
   model訓練
          opennlp.maxent實現了GIS(Generalized Iterative Scaling )演算法,實現方法呼叫GIS.trainModel
           public static MaxentModel trainModel(DataIndexer di, int iterations) {  ...  }
           引數:iterations 迭代次數(不要超過100)
   資料格式化:
          DataIndexer是一個abstract objec,用來將EventStream收集的event資料格式化,以便更有效的訓練它們。用下面方法建立一個DataIndexer例項
          public OnePassDataIndexer(EventStream es, int cutoff){ ... }  cutoff為閾值,特徵在model裡出現的最少次數
          也可以呼叫建構函式 OnePassDataIndexer(EventStream events)  閾值為0

   model輸出:
         將返回的model寫到disk
          File outputFile = new File(modelFileName+".bin.gz"); 
          GISModelWriter writer = new SuffixSensiiveGISModelWriter(model, outputFile); 
          writer.persist();

  二進位制格式儲存:

         使用BinaryGISModelWriter類

4、model載入:
     GISModel m = new SuffixSensitiveGISModelReader(new File(modelFileName)).getModel();

5、自帶例子

     samples/sports