代码之家  ›  专栏  ›  技术社区  ›  Claire

Matlab中的J48决策树,使用Weka作为API

  •  1
  • Claire  · 技术社区  · 8 年前

    我在Matlab中使用Weka for API,遇到了一个问题。。

    @relation test.txt-weka.filters.unsupervised.attribute.NumericToNominal-Rlast
    
    @attribute att_2 numeric
    @attribute att_2 numeric
    @attribute att_3 {0,1}
    
    @data
    

    我想在att_3中添加“2”这个值,如: @attribute att_3 {0,1,2}

    我试着指挥:

    test.attribute(2).addStringValue(2) test.attribute(2).addStringValue('2')

    这两个人都出了问题。。 有人能帮我吗(


    下面是我的代码 提到 How to retrieve class values from WEKA using MATLAB

    %# Set paths
    WEKA_HOME = 'C:\Program Files\Weka-3-8';
    javaaddpath([WEKA_HOME '\weka.jar']);
    import weka.cores.meta.MatlabLoader.*;
    
    %# load dataset 
    load mydata
    X = feas;
    Y = grp2idx(species);
    
    %# 10-fold crossvalidation
    k=10;
    cvFolds = crossvalind('Kfold', species, k);   %# get indices of 10-fold CV
    cp = classperf(species);   
    
    for i = 1:k  
    testIdx = (cvFolds == i); 
    trainIdx = ~testIdx;   
    xtrain = feas(trainIdx,:);
    ytrain = species(trainIdx);
    xtest = feas(testIdx,:);
    ytest = species(testIdx);
    
    train = [xtrain ytrain];
    test =  [xtest ytest];
    save train.txt train -ascii
    save test.txt test -ascii
    
    fName = 'train.txt';
    loader = weka.core.converters.MatlabLoader();
    loader.setFile( java.io.File(fName) );
    train = loader.getDataSet();
    train.setClassIndex( train.numAttributes()-1 );
    
    fName = 'test.txt';
    loader = weka.core.converters.MatlabLoader();
    loader.setFile( java.io.File(fName) );
    test = loader.getDataSet();
    test.setClassIndex( test.numAttributes()-1 );
    
    %# convert last attribute (class) from numeric to nominal
    filter = weka.filters.unsupervised.attribute.NumericToNominal();
    filter.setOptions( weka.core.Utils.splitOptions('-R last') );
    filter.setInputFormat(train); 
    train = filter.useFilter(train, filter);
    
    filter = weka.filters.unsupervised.attribute.NumericToNominal();
    filter.setOptions( weka.core.Utils.splitOptions('-R last') );
    filter.setInputFormat(test);   
    test = filter.useFilter(test, filter);
    
    %# train J48 tree
    classifier = weka.classifiers.trees.J48();
    classifier.setOptions( weka.core.Utils.splitOptions('-O -B -J -A -S -M 1') );
    classifier.buildClassifier( train );
    
    %# classify test instances
    numInst = test.numInstances();
    pred = zeros(numInst,1);
    predProbs = zeros(numInst, train.numClasses());
    
    for i=1:numInst
    pred(i) = classifier.classifyInstance( test.instance(i-1) );
    end
    
    for i=1:numInst
    predProbs(i,:) = classifier.distributionForInstance( test.instance(i-1) );
    end
    
    eval = weka.classifiers.Evaluation(train);
    eval.evaluateModel(classifier, test, javaArray('java.lang.Object',1));
    
    disp( char(eval.toSummaryString()) )
    
    end
    

    我的数据集包含31个数据,每个数据有两个属性和一个类。

    当我使用10倍交叉验证时,当我运行代码时,只有几倍(大约4倍)不会出错。

    “订阅的分配维度不匹配。”

    for i=1:numInst
    predProbs(i,:) = classifier.distributionForInstance( test.instance(i-1) );
    end
    

    首先我不知道为什么,然后我发现这6个折叠不包含在“测试数据”中的类“2”中的数据。它们的“测试数据”中只有类“0”或“1”中的数据,而“列车数据”中只有类“0”、“1”和“2”中的数据。

    可以成功运行的折叠在其“测试数据”中包含类“2”中的数据。


    那些在“测试”节目中不包含类“2”的节目

    @relation test.txt-weka.filters.unsupervised.attribute.NumericToNominal-Rlast
    
    @attribute att_1 numeric
    @attribute att_2 numeric
    @attribute att_3 {0,1}
    
    @data
    864.86315,40.15,0
    1396.0296,36.263158,0
    249.6065,71.5,1
    

    所以,我想知道我是否应该在@属性att_3{0,1}中添加“2”来解决这个问题。。或者问题不是这个?

    2 回复  |  直到 8 年前
        1
  •  0
  •   nekomatic    8 年前

    我认为你需要申请 weka.filters.unsupervised.attribute.AddValues 具有选项 -C last -L 0,1,2 在将class属性转换为nominal之后,但在尝试使用测试数据进行预测之前。这将确保测试数据中的类属性与训练数据中的类属性相匹配,即使测试数据集不包含任何具有给定类值的实例。

        2
  •  0
  •   Marcus    8 年前

    这需要更多的步骤。请在下面找到我的示例:

    %nAttributes is number of Attributes
    YourAttributeName = 'MyFavoriteAttributeName';
    YourAttributeValue = 123.456;
    
    fvWekaAttribute=javaObject('weka.core.FastVector');
    fvWekaAttribute.addElement(Attribute(YourAttributeName));
    DataSet=javaObject('weka.core.Instances','Rel',fvWekaAttribute,10);
    DataSet.setClassIndex(nAttributes-1);
    iExample=javaObject('weka.core.DenseInstance',nAttributes);
    iExample.setValue(fvWekaAttribute.elementAt(0),YourAttributeValue);
    DataSet.add(iExample);
    

    或者如果属性是标称属性

    %nAttributes is number of Attributes
    YourAttributeName = 'MyFavoriteAttributeName';
    YourAttributeValue = 123.456;
    
    nominalEgotypeFastVector=javaObject('weka.core.FastVector');
    nominalEgotypeFastVector.addElement('YourType1');
    nominalEgotypeFastVector.addElement('YourType2');
    nominalEgotypeFastVector.addElement('SomeMoreType');
    fvWekaAttribute.addElement(Attribute(YourAttributeName,nominalEgotypeFastVector));
    DataSet=javaObject('weka.core.Instances','Rel',fvWekaAttribute,10);
    DataSet.setClassIndex(nAttributes-1);
    iExample=javaObject('weka.core.DenseInstance',nAttributes);
    iExample.setValue(fvWekaAttribute.elementAt(0),YourAttributeValue);
    DataSet.add(iExample); % continue with DataSet