如何使用 MATLAB 从 WEKA 检索类值
我正在尝试使用 MATLAB 和 WEKA API 从 WEKA 检索类。一切看起来都很好,但类始终为 0。有什么想法吗?
我的数据集有 241 个属性,将 WEKA 应用于该数据集我得到了正确的结果。
创建第一个训练和测试对象,然后构建分类器并执行分类实例。但这给出了错误的结果
train = [xtrain ytrain];
test = [xtest];
save ('train.txt','train','-ASCII');
save ('test.txt','test','-ASCII');
%## paths
WEKA_HOME = 'C:\Program Files\Weka-3-7';
javaaddpath([WEKA_HOME '\weka.jar']);
fName = 'train.txt';
%## read file
loader = weka.core.converters.MatlabLoader();
loader.setFile( java.io.File(fName) );
train = loader.getDataSet();
train.setClassIndex( train.numAttributes()-1 );
% setting class as nominal
v(1) = java.lang.String('-R');
v(2) = java.lang.String('242');
options = cat(1,v(1:end));
filter = weka.filters.unsupervised.attribute.NumericToNominal();
filter.setOptions(options);
filter.setInputFormat(train);
train = filter.useFilter(train, filter);
fName = 'test.txt';
%## read file
loader = weka.core.converters.MatlabLoader();
loader.setFile( java.io.File(fName) );
test = loader.getDataSet();
%## dataset
relationName = char(test.relationName);
numAttr = test.numAttributes;
numInst = test.numInstances;
%## classification
classifier = weka.classifiers.trees.J48();
classifier.buildClassifier( train );
fprintf('Classifier: %s %s\n%s', ...
char(classifier.getClass().getName()), ...
char(weka.core.Utils.joinOptions(classifier.getOptions())), ...
char(classifier.toString()) )
classes =[];
for i=1:numInst
classes(i) = classifier.classifyInstance(test.instance(i-1));
end
这是一个新代码,但仍然不起作用 - 类 = 0。Weka 对于相同算法和数据集的输出是 OK
=== 按类详细准确度 ===
TP Rate FP Rate Precision Recall F-Measure ROC Area Class 0.99 0.015 0.985 0.99 0.988 0.991 0 0.985 0.01 0.99 0.985 0.988 0.991 1 Weighted Avg. 0.988 0.012 0.988 0.988 0.988 0.991
=== 混淆矩阵 ===
a b <-- classified as 1012 10 | a = 0 15 1003 | b = 1
;
ytest1 = ones(size(xtest,1),1);
train = [xtrain ytrain];
test = [xtest ytest1];
save ('train.txt','train','-ASCII');
save ('test.txt','test','-ASCII');
%## paths
WEKA_HOME = 'C:\Program Files\Weka-3-7';
javaaddpath([WEKA_HOME '\weka.jar']);
fName = 'train.txt';
%## read file
loader = weka.core.converters.MatlabLoader();
loader.setFile( java.io.File(fName) );
train = loader.getDataSet();
train.setClassIndex( train.numAttributes()-1 );
v(1) = java.lang.String('-R');
v(2) = java.lang.String('242');
options = cat(1,v(1:end));
filter = weka.filters.unsupervised.attribute.NumericToNominal();
filter.setOptions(options);
filter.setInputFormat(train);
train = filter.useFilter(train, filter);
fName = 'test.txt';
%## read file
loader = weka.core.converters.MatlabLoader();
loader.setFile( java.io.File(fName) );
test = loader.getDataSet();
filter = weka.filters.unsupervised.attribute.NumericToNominal();
filter.setOptions( weka.core.Utils.splitOptions('-R last') );
filter.setInputFormat(test);
test = filter.useFilter(test, filter);
%## dataset
relationName = char(test.relationName);
numAttr = test.numAttributes;
numInst = test.numInstances;
%## classification
classifier = weka.classifiers.trees.J48();
classifier.buildClassifier( train );
fprintf('Classifier: %s %s\n%s', ...
char(classifier.getClass().getName()), ...
char(weka.core.Utils.joinOptions(classifier.getOptions())), ...
char(classifier.toString()) )
classes = zeros(numInst,1);
for i=1:numInst
classes(i) = classifier.classifyInstance(test.instance(i-1));
end
这是 Java 中类分发的代码片段,
// output predictions
System.out.println("# - actual - predicted - error - distribution");
for (int i = 0; i < test.numInstances(); i++) {
double pred = cls.classifyInstance(test.instance(i));
double[] dist = cls.distributionForInstance(test.instance(i));
System.out.print((i+1));
System.out.print(" - ");
System.out.print(test.instance(i).toString(test.classIndex()));
System.out.print(" - ");
System.out.print(test.classAttribute().value((int) pred));
System.out.print(" - ");
if (pred != test.instance(i).classValue())
System.out.print("yes");
else
System.out.print("no");
System.out.print(" - ");
System.out.print(Utils.arrayToString(dist));
System.out.println();
我将其转换为 MATLAB 代码,如下所示
classes = zeros(numInst,1);
for i=1:numInst
pred = classifier.classifyInstance(test.instance(i-1));
classes(i) = str2num(char(test.classAttribute().value(( pred))));
end
,但类输出不正确。
在你的答案中,你没有表明 pred 包含类和 predProb 概率。只需打印即可!
I'm trying to retrieve classes from WEKA using MATLAB and WEKA API. All looks fine but classes are always 0. Any idea ??
My data set has 241 atributes, applying WEKA to this dataset I'm obtaining correct results.
1st train and test objects are created than classifier is build and classifyInstance performed. But this give wrong result
train = [xtrain ytrain];
test = [xtest];
save ('train.txt','train','-ASCII');
save ('test.txt','test','-ASCII');
%## paths
WEKA_HOME = 'C:\Program Files\Weka-3-7';
javaaddpath([WEKA_HOME '\weka.jar']);
fName = 'train.txt';
%## read file
loader = weka.core.converters.MatlabLoader();
loader.setFile( java.io.File(fName) );
train = loader.getDataSet();
train.setClassIndex( train.numAttributes()-1 );
% setting class as nominal
v(1) = java.lang.String('-R');
v(2) = java.lang.String('242');
options = cat(1,v(1:end));
filter = weka.filters.unsupervised.attribute.NumericToNominal();
filter.setOptions(options);
filter.setInputFormat(train);
train = filter.useFilter(train, filter);
fName = 'test.txt';
%## read file
loader = weka.core.converters.MatlabLoader();
loader.setFile( java.io.File(fName) );
test = loader.getDataSet();
%## dataset
relationName = char(test.relationName);
numAttr = test.numAttributes;
numInst = test.numInstances;
%## classification
classifier = weka.classifiers.trees.J48();
classifier.buildClassifier( train );
fprintf('Classifier: %s %s\n%s', ...
char(classifier.getClass().getName()), ...
char(weka.core.Utils.joinOptions(classifier.getOptions())), ...
char(classifier.toString()) )
classes =[];
for i=1:numInst
classes(i) = classifier.classifyInstance(test.instance(i-1));
end
Here is a new code but still not working - classes = 0. Output from Weka for the same algo and data set is OK
=== Detailed Accuracy By Class ===
TP Rate FP Rate Precision Recall F-Measure ROC Area Class 0.99 0.015 0.985 0.99 0.988 0.991 0 0.985 0.01 0.99 0.985 0.988 0.991 1 Weighted Avg. 0.988 0.012 0.988 0.988 0.988 0.991
=== Confusion Matrix ===
a b <-- classified as 1012 10 | a = 0 15 1003 | b = 1
ytest1 = ones(size(xtest,1),1);
train = [xtrain ytrain];
test = [xtest ytest1];
save ('train.txt','train','-ASCII');
save ('test.txt','test','-ASCII');
%## paths
WEKA_HOME = 'C:\Program Files\Weka-3-7';
javaaddpath([WEKA_HOME '\weka.jar']);
fName = 'train.txt';
%## read file
loader = weka.core.converters.MatlabLoader();
loader.setFile( java.io.File(fName) );
train = loader.getDataSet();
train.setClassIndex( train.numAttributes()-1 );
v(1) = java.lang.String('-R');
v(2) = java.lang.String('242');
options = cat(1,v(1:end));
filter = weka.filters.unsupervised.attribute.NumericToNominal();
filter.setOptions(options);
filter.setInputFormat(train);
train = filter.useFilter(train, filter);
fName = 'test.txt';
%## read file
loader = weka.core.converters.MatlabLoader();
loader.setFile( java.io.File(fName) );
test = loader.getDataSet();
filter = weka.filters.unsupervised.attribute.NumericToNominal();
filter.setOptions( weka.core.Utils.splitOptions('-R last') );
filter.setInputFormat(test);
test = filter.useFilter(test, filter);
%## dataset
relationName = char(test.relationName);
numAttr = test.numAttributes;
numInst = test.numInstances;
%## classification
classifier = weka.classifiers.trees.J48();
classifier.buildClassifier( train );
fprintf('Classifier: %s %s\n%s', ...
char(classifier.getClass().getName()), ...
char(weka.core.Utils.joinOptions(classifier.getOptions())), ...
char(classifier.toString()) )
classes = zeros(numInst,1);
for i=1:numInst
classes(i) = classifier.classifyInstance(test.instance(i-1));
end
here is a code snippet for class distribution in Java
// output predictions
System.out.println("# - actual - predicted - error - distribution");
for (int i = 0; i < test.numInstances(); i++) {
double pred = cls.classifyInstance(test.instance(i));
double[] dist = cls.distributionForInstance(test.instance(i));
System.out.print((i+1));
System.out.print(" - ");
System.out.print(test.instance(i).toString(test.classIndex()));
System.out.print(" - ");
System.out.print(test.classAttribute().value((int) pred));
System.out.print(" - ");
if (pred != test.instance(i).classValue())
System.out.print("yes");
else
System.out.print("no");
System.out.print(" - ");
System.out.print(Utils.arrayToString(dist));
System.out.println();
I converted it to MATLAB code like this
classes = zeros(numInst,1);
for i=1:numInst
pred = classifier.classifyInstance(test.instance(i-1));
classes(i) = str2num(char(test.classAttribute().value(( pred))));
end
but classes are output incorrectly.
In your answer you dont show that pred contains classes and predProb probabilities. Just print it !!!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
训练和测试数据必须具有相同数量的属性。因此,在您的情况下,即使您不知道测试数据的实际类别,也只需使用虚拟值:
加载测试数据集时不要忘记将其转换为名义属性(就像您对训练数据集所做的那样) ):
最后,您可以调用经过训练的 J48 分类器来预测测试实例的类值:
编辑
如果不知道您正在使用的数据,则很难判断。
所以让我用一个完整的示例来说明。我将在 MATLAB 中根据 Fisher Iris 数据创建数据集(4 个属性、150 个实例、3 个类)。
我应该在这里提到,在使用 NumericToNominal 过滤器之前,确保两个数据集中的每个数据集中都完全表示类值非常重要。否则,训练集和测试集可能不兼容。我的意思是,每个类中的每个类值都必须至少有一个实例。因此,如果您使用虚拟值,也许我们可以这样做:
接下来,让我们使用 Weka API 读取新创建的文件。我们将最后一个属性从数字转换为名义属性(以启用分类):
现在我们训练 J48 分类器并用它来预测测试实例的类别:
最后,我们根据测试数据评估训练模型的性能(这应该看起来类似)到您在 Weka Explorer 中看到的内容)。显然,只有当测试实例具有真实的类值(而不是虚拟值)时,这才有意义:
上面示例的 MATLAB 输出:
Training and testing data must have the same number of attributes. So in your case, even if you don't know the actual class of the test data, just use dummy values:
Don't forget to convert it to a nominal attribute when you load the test dataset (like you did for the training dataset):
Finally, you can call the trained J48 classifier to predict the class values for the test instances:
EDIT
It is difficult to tell without knowing the data you are working with..
So let me illustrate with a complete example. I am going to be creating the datasets in MATLAB out of the Fisher Iris data (4 attributes, 150 instances, 3 classes).
I should mention here that it is important to make sure that the class values are fully represented in each of the two datasets before using the
NumericToNominal
filter. Otherwise, the train and test sets could be incompatible. What I mean is that you must have at least one instance from every class value in each. Thus if you are using dummy values, maybe we can do this:Next, lets read the newly created files using Weka API. We convert the last attribute from numeric to nominal (to enable classification):
Now we train a J48 classifier and use it to predict the class of the test instances:
Finally, we evaluate the trained model performance over the test data (this should look similar to what you see in Weka Explorer). Obviously this only makes sense if the test instances have the true class value (not dummy values):
The output in MATLAB for the example above: