【问题标题】:J48 decision tree in Matlab using Weka for APIMatlab中使用Weka for API的J48决策树
【发布时间】:2018-03-19 15:26:35
【问题描述】:

我在 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个数据,每个数据有两个属性和一个类。

我的数据集类包含三个值:“0”或“1”或“2”。只有 4 个数据属于 '2' 类,其他 27 个数据属于 '0' 或 '1' 类。

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

但其余的(6 折)都会显示错误消息: “下标分配尺寸不匹配。” 跑步时

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

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

【问题讨论】:

    标签: matlab filter attributes weka


    【解决方案1】:

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

    我认为您想在 Weka 中构建模型之前在 MATLAB 中进行交叉验证分区是有原因的,而不是让 Weka 构建一个交叉验证模型?

    【讨论】:

    • 好的,我去实验室试试。嗯,我在Matlab中对训练数据和测试数据进行交叉验证的原因是我认为如果我运行10折,每次折叠的数据应该不同,10折的预测准确率的平均值会有点不同.而且我使用 Weka 构建了一个交叉验证模型,每次都得到完全相同的结果。很奇怪。
    • @Claire Weka 通常会在您每次运行时使用默认值初始化随机数生成器 - 例如,这可以方便验证您的代码在更改后是否仍在执行相同的操作。要为每个模型构建运行使用一组不同的交叉验证分区,请尝试每次使用不同的值调用分类器的 setRandomSeed 方法。
    • 天啊!!!!!!!!!!!!!有用!!!太感谢了:) ;我用 setRandomSeed 找到了这个页面mathworks.com/matlabcentral/fileexchange/…。下次我试试!
    【解决方案2】:

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

    %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
    

    【讨论】:

    • 这有帮助吗?
    • 我不太明白你上面的代码.. umm 只是不知道我需要替换哪个部分..:(
    • 请更新您的问题,详细说明您遇到的错误。
    • 好的,我想我应该更详细地告诉你我的问题。我正在做作业对 31 个数据进行分类并使用 j48 决策树。我必须在 Matlab 中使用 Weka 作为 API。我参考了“stackoverflow.com/questions/7535689/…”这个页面。我稍后会在我的问题中添加我的代码。
    • YourAttributeName = 'att_3';你的属性值 =2; fvWekaAttribute=javaObject('weka.core.FastVector'); fvWekaAttribute.addElement(Attribute(YourAttributeName));你是这个意思吗 ?这样的命令?我得到“'char'类型的输入参数的未定义函数'属性'。” .
    猜你喜欢
    • 2016-03-14
    • 2013-08-29
    • 2016-04-24
    • 2014-08-29
    • 2015-07-22
    • 2015-02-06
    • 2015-06-17
    • 2014-09-18
    • 2021-05-16
    相关资源
    最近更新 更多