如何使用libsvm正确训练数据?

时间:2014-01-22 05:11:42

标签: java svm libsvm

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

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

我在做什么:

认为我们有5个文件(数字只是一个例子),其中3个在第一类,其他(其中2个)在第二类,我将类别合并到一起(这意味着3第一类中的doc将合并到一个文档中),之后我创建了一个这样的火车数组:

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

3 个答案:

答案 0 :(得分:2)

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

  

认为我们有5个文档,其中3个属于第一类,其他(其中2个)属于第二类,我将这些类别相互合并(这意味着第一类中的3个文档将会合并在一个文件中),之后我制作了像这样的火车阵列

所以:

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

答案 1 :(得分:2)

问题可能是您没有在索引为-1的训练示例中终止每组功能,您应该根据我的阅读...

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

Index[0]: 0
Value[0]: 22
Index[1]: 1
Value[1]: 53
Index[2]: -1
祝你好运!

答案 2 :(得分:2)

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

基本上你必须:

  1. 对您的文档进行标记
  2. 删除停用词
  3. 应用词干技术
  4. 应用特征选择技术(参见[2])
  5. 使用4.)中实现的功能转换文档。(简单的是二进制(0:功能不存在,1:功能存在)或其他措施,如TFC)
  6. 训练你的SVM并开心:)
  7. [1] T. Joachims:支持向量机的文本分类:学习许多相关功能;施普林格:海德堡,德国,1998,doi:10.1007 / BFb0026683。

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