Классификация экземпляров в Weka - PullRequest
0 голосов
/ 08 марта 2012

Я пытаюсь использовать Weka в своем приложении на C #.Я использовал IKVM для переноса частей Java в мое приложение .NET.Кажется, это работает довольно хорошо.Однако, когда дело доходит до API Weka, я в растерянности.Как именно делать Я классифицирую экземпляры, если они программно передаются в моем приложении и недоступны как файлы ARFF.

По сути, я пытаюсь интегрировать простой анализ параллельных ссылок с использованием классификаторов Weka.,Я построил модель классификации в Weka напрямую и сохранил ее на диск, откуда мое приложение .NET открывает ее и использует IKVM-порт Weka для прогнозирования значения класса.

Вот что я получилдо сих пор:

    // 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;
    }

По какой-то причине Века бросает IndexOutOfRangeException, когда я звоню model.classifyInstance(instance).Я понятия не имею, почему, и не могу придумать, как исправить эту проблему.

Я надеюсь, что кто-то может знать, где я ошибся.Единственная документация для Weka, которую я нашел, основана на ARFF-файлах для предсказания, и я не очень хочу туда идти.

1 Ответ

0 голосов
/ 09 марта 2012

По какой-то странной причине это исключение было поднято классификатором DTNB (я использовал три в модели классификации с большинством голосов). По-видимому, не используя DTNB «исправили» проблему.

...