【问题标题】:How to train data correctly using libsvm?如何使用 libsvm 正确训练数据?
【发布时间】:2014-02-12 00:35:06
【问题描述】:

我想在我的程序中使用 SVM(支持向量机),但我无法得到真正的结果。

我想知道我们必须如何为 SVM 训练数据。

我在做什么:

假设我们有 5 个文档(数字只是一个示例),其中 3 个属于第一类,其他(其中 2 个)属于第二类,我将这些类别相互合并(这意味着 3属于第一类的文档将合并到一个文档中),之后我制作了一个这样的火车数组:

double[][] train = new double[cat1.getDocument().getAttributes().size() + cat2.getDocument().getAttributes().size()][];

我会像这样填充数组:

int i = 0;
    Iterator<String> iteraitor = cat1.getDocument().getAttributes().keySet().iterator();
    Iterator<String> iteraitor2 = cat2.getDocument().getAttributes().keySet().iterator();
    while (i < train.length) {
        if (i < cat2.getDocument().getAttributes().size()) {
            while (iteraitor2.hasNext()) {
                String key = (String) iteraitor2.next();
                Long value = cat2.getDocument().getAttributes().get(key);
                double[] vals = { 0, value };
                train[i] = vals;
                i++;
                System.out.println(vals[0] + "," + vals[1]);
            }
        } else {
            while (iteraitor.hasNext()) {
                String key = (String) iteraitor.next();
                Long value = cat1.getDocument().getAttributes().get(key);
                double[] vals = { 1, value };
                train[i] = vals;
                i++;
                System.out.println(vals[0] + "," + vals[1]);
            }
            i++;
        }

所以我会继续这样获取模型:

svm_problem prob = new svm_problem();
    int dataCount = train.length;
    prob.y = new double[dataCount];
    prob.l = dataCount;
    prob.x = new svm_node[dataCount][];

    for (int k = 0; k < dataCount; k++) {
        double[] features = train[k];
        prob.x[k] = new svm_node[features.length - 1];
        for (int j = 1; j < features.length; j++) {
            svm_node node = new svm_node();
            node.index = j;
            node.value = features[j];
            prob.x[k][j - 1] = node;
        }
        prob.y[k] = features[0];
    }
    svm_parameter param = new svm_parameter();
    param.probability = 1;
    param.gamma = 0.5;
    param.nu = 0.5;
    param.C = 1;
    param.svm_type = svm_parameter.C_SVC;
    param.kernel_type = svm_parameter.LINEAR;
    param.cache_size = 20000;
    param.eps = 0.001;
    svm_model model =  svm.svm_train(prob, param);

这种方式正确吗?如果不是,请帮助我实现它。


这两个答案都是正确的:answer oneanswer two

【问题讨论】:

    标签: java svm libsvm


    【解决方案1】:

    使用 SVM 对文本进行分类是一项常见任务。您可以查看 Joachims [1] 关于 SVM 文本分类的研究论文。

    基本上你必须:

    1. 标记您的文档
    2. 删除停用词
    3. 应用词干技术
    4. 应用特征选择技术(参见 [2])
    5. 使用 4.) 中实现的功能转换您的文档(简单将是二进制(0:不存在功能,1:存在功能)或其他措施,如 TFC)
    6. 训练您的 SVM 并获得快乐 :)

    [1] T. Joachims:支持向量机的文本分类:使用许多相关特征进行学习;施普林格:德国海德堡,1998,doi:10.1007/BFb0026683。

    [2] Y. Yang, J. O. Pedersen:文本分类中特征选择的比较研究。机器学习国际会议,1997,412-420。

    【讨论】:

      【解决方案2】:

      一个问题可能是您没有终止训练示例中的每组特征,索引为 -1,您应该根据自述文件...

      即如果您有一个具有两个功能的示例,我认为您应该这样做:

      Index[0]: 0
      Value[0]: 22
      Index[1]: 1
      Value[1]: 53
      Index[2]: -1
      

      祝你好运!

      【讨论】:

      • 不需要终止“-1”(如果您在线查看示例数据集)...
      【解决方案3】:

      即使不检查代码也可以发现概念性错误:

      认为我们有 5 个文档,其中 3 个属于第一类,其他(其中 2 个)属于第二类,我将这些类别相互合并(这意味着属于第一类的 3 个文档将合并到一个文档中),然后我制作了一个这样的火车数组

      所以:

      • 对 5 个文档的训练不会产生任何合理的效果,使用任何机器学习模型......这些是 统计 模型,在 R^n 中的 5 个点没有合理的统计数据,其中n~10,000
      • 合并任何内容。这种方法适用于朴素贝叶斯,它并不真正将文档视为“整体”,而是将文档视为特征和类之间的概率依赖关系。在 SVM 中,每个文档都应该是 R^n 空间中的单独点,其中 n 可以是不同单词的数量(对于单词袋/单词集表示)。

      【讨论】:

      • 谢谢@lejlot,这些数字只是为了描述,实际数字比这些数字要多,这意味着我应该将每个文档分别放在我的火车数组中吗?如果可以的话,请给我一个例子
      • 是的,每个文档都是一个单独的元素。网上有 数百万 个示例,要求此类事物的代码表明完全缺乏参与度。将 SVM 与文档和任何其他类型的数据一起使用没有区别。使用矢量化,您可以将每个文档翻译成 vectors。完成后,任何 SVM 示例都可以工作。
      猜你喜欢
      • 2011-07-04
      • 2014-06-12
      • 2015-10-18
      • 2013-10-18
      • 2014-05-31
      • 2013-08-17
      • 2014-06-11
      • 2012-02-27
      • 2013-06-11
      相关资源
      最近更新 更多