WEKA 分类器返回一个分类而不考虑值

Posted

技术标签:

【中文标题】WEKA 分类器返回一个分类而不考虑值【英文标题】:WEKA classifier returns one classification regardless of value 【发布时间】:2019-03-26 07:16:46 【问题描述】:

我正在尝试在 android 应用程序中使用/导入在 WEKA 3.8.3(GUI 之一)中制作的 J48 分类器,但无论传入的值如何,生成的类都只返回一个分类结果。

原始数据集looks like this,所以我能在 SO 上找到的第一个答案是使用 SMOTE 来弥补这一点。我找不到 SMOTE,但从我可以看到 ClassBalancer 过滤器实现了相同的结果。结果数据looks like this。

These 是原始数据的结果,these 是过滤数据的结果。

使用原始数据的 J48 类仅返回 2.0 的值,这与步行相对应,我猜这是因为步行是迄今为止训练集中最常见的分类。使用过滤后的数据的 J48 类只返回一个值 1.0,我不太能解释。

我已经尝试将以前项目中的工作分类器加载到应用程序中;这个(J48)分类器确实返回了不同的值。我还尝试手动删除数据行,直到所有活动都有相同数量的条目,但这并没有解决问题。我也试过输入一个我知道应该手动对应“坐”的值,但这也不起作用。

当我将值打印到日志时,发送到分类器的实例看起来非常好,所以我认为这与输入无关。以防万一我遗漏了一些明显的东西,我将包含以下代码:

    public double createInstances(double x, double y, double z)

    double result = 0;

    Instances dataRaw = new Instances("TestInstances", atts, 3);
    dataRaw.setClassIndex(dataRaw.numAttributes()-1);

    Log.d(TAG,"Rawdata:" + dataRaw);

    Instance inst = new DenseInstance(3);
    inst.setDataset(dataRaw);
    inst.setValue(accel_x,x);
    inst.setValue(accel_y,y);
    inst.setValue(accel_z,z);

    Log.d(TAG,"NEWDATARAW:" + inst);

    try 
        result = weka.classifyInstance(inst);
        Log.d(TAG,"RESULT:" + result);

    

    catch (Exception e)
        Log.e(TAG,"DID NOT WORK:" + e);
    

    return result;

我还确保将属性添加到 Attributes ArrayList“atts”中。

我能想到的唯一剩下的选择是数据格式有问题,但我想在创建算法时它已经显示出问题的迹象。 This 是包含数据的 ARFF 文件示例。

我尝试在默认的 J48 算法中输入两个数据集(原始/过滤),一个禁用所有修剪选项以防它修剪其他活动,但这些分类器都没有返回一个以上的活动。

我认为这就是所有相关信息,但如果我遗漏了什么,请告诉我,以便我补充。我很确定问题出在分类器本身的某个地方,但我不知道它到底是什么。

【问题讨论】:

我怀疑您对数据不平衡的问题是正确的。在 Weka GUI 中,您可以可视化学习到的树 link。这可能有助于您进一步调试问题。 感谢您的提示!据我所知,这棵树看起来 fine。此外,即使我手动为活动提供相同数量的条目,问题仍然存在,这让我认为除了不平衡的数据之外,可能还有其他因素在起作用。 【参考方案1】:

原来WEKA在classifyInstance方法中放置了如下代码:

// set class value to missing
   s[i.classIndex()] = null;

这导致数组中的最后一个值(在本例中为 accel_z 值)设置为 null,导致分类器始终返回相同的值,因为这是分类器中的第一次检查(注意“if( i[2] == null" 语句):

static double N69cd8e58128(Object []i) 
    double p = Double.NaN;
    if (i[2] == null) 
        p = 1;
     else if (((Double) i[2]).doubleValue() <= 6.43) 
        p = WekaClassifier.Nad3034129(i);
     else if (((Double) i[2]).doubleValue() > 6.43) 
        p = WekaClassifier.N26ef16ed242(i);
    
    return p;

我不确定这条线通常有什么用途,但删除它似乎已经解决了问题。

【讨论】:

以上是关于WEKA 分类器返回一个分类而不考虑值的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Weka 中构建 SVM 分类器以仅考虑数据集中的某些特征?

Weka:分类器和 ReplaceMissingValues

Weka 逻辑分类器不可用

Weka中的分类器选项变灰[关闭]

使用测试集中的缺失值评估 weka 分类器 J48,R RWeka

Weka机器学习:如何解释朴素贝叶斯分类器?