2012-03-08 87 views
0

我想在我的C#应用​​程序中使用Weka。我已经使用IKVM将Java部件引入到我的.NET应用程序中。这似乎工作得很好。但是,当谈到Weka的API时,我感到茫然。如何如果它们以编程方式在我的应用程序中传递并且不可用作为ARFF文件,我将对它们进行分类。Weka中的实例分类

基本上,我试图使用Weka的分类器来整合一个简单的共同参考分析。我已经在Weka中直接创建了分类模型并将其保存到磁盘中,从.NET应用程序打开它并使用Weka的IKVM端口预测类值。

这里是我到目前为止有:

// This is the "entry" method for the classification method 
    public IEnumerable<AttributedTokenDecorator> Execute(IEnumerable<TokenPair> items) 
    { 
     TokenPair[] pairs = items.ToArray(); 
     Classifier model = ReadModel(); // reads the Weka generated model 
     FastVector fv = CreateFastVector(pairs); 

     Instances instances = new Instances("licora", fv, pairs.Length); 
     CreateInstances(instances, pairs); 

     for(int i = 0; i < instances.numInstances(); i++) 
     { 
      Instance instance = instances.instance(i); 
      double classification = model.classifyInstance(instance); // array index out of bounds? 

      if(AsBoolean(classification)) 
       MakeCoreferent(pairs[i]); 
     } 

     throw new NotImplementedException(); // TODO 
    } 

    // This is a helper method to create instances from the internal model files 
    private static void CreateInstances(Instances instances, IEnumerable<TokenPair> pairs) 
    { 
     instances.setClassIndex(instances.numAttributes() - 1); 
     foreach(var pair in pairs) 
     { 
      var instance = new Instance(instances.numAttributes()); 
      instance.setDataset(instances); 
      for (int i = 0; i < instances.numAttributes(); i++) 
      { 
       var attribute = instances.attribute(i); 
       if (pair.Features.ContainsKey(attribute.name()) && pair.Features[attribute.name()] != null) 
       { 
        var value = pair.Features[attribute.name()]; 
        if (attribute.isNumeric()) instance.setValue(attribute, Convert.ToDouble(value)); 
        else instance.setValue(attribute, value.ToString()); 
       } 
       else 
       { 
        instance.setMissing(attribute); 
       } 
      } 
      //instance.setClassMissing(); 
      instances.add(instance); 
     } 
    } 

    // This creates the data set's attributes vector 
    private FastVector CreateFastVector(TokenPair[] pairs) 
    { 
     var fv = new FastVector(); 

     foreach (var attribute in _features) 
     { 
      Attribute att; 
      if (attribute.Type.Equals(ArffType.Nominal)) 
      { 
       var values = new FastVector(); 
       ExtractValues(values, pairs, attribute.FeatureName); 
       att = new Attribute(attribute.FeatureName, values); 
      } 
      else 
       att = new Attribute(attribute.FeatureName); 

      fv.addElement(att); 
     } 

     { 
      var classValues = new FastVector(2); 
      classValues.addElement("0"); 
      classValues.addElement("1"); 
      var classAttribute = new Attribute("isCoref", classValues); 
      fv.addElement(classAttribute); 
     } 

     return fv; 
    } 

    // This extracts observed values for nominal attributes 
    private static void ExtractValues(FastVector values, IEnumerable<TokenPair> pairs, string featureName) 
    { 
     var strings = (from x in pairs 
         where x.Features.ContainsKey(featureName) && x.Features[featureName] != null 
         select x.Features[featureName].ToString()) 
      .Distinct().ToArray(); 

     foreach (var s in strings) 
      values.addElement(s); 
    } 

    private Classifier ReadModel() 
    { 
     return (Classifier) SerializationHelper.read(_model); 
    } 

    private static bool AsBoolean(double classifyInstance) 
    { 
     return classifyInstance >= 0.5; 
    } 

出于某种原因,Weka的抛出IndexOutOfRangeException当我打电话model.classifyInstance(instance)。我不知道为什么,也不知道如何解决这个问题。

我希望有人可能知道我出错的地方。我唯一发现的Weka文档依赖于ARFF文件进行预测,而我并不想去那里。

回答

0

由于某种奇怪的原因,这个异常是由DTNB分类器引发的(我在多数投票分类模型中使用了三个)。显然,不使用DTNB“固定”的问题。