二进制分类器在libsvm中给出错误的结果 [英] binary classifier giving wrong results in libsvm

查看:42
本文介绍了二进制分类器在libsvm中给出错误的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个584乘100的数据集,每个数据有584个特征向量(总共100个训练向量)。我用Java实现了Libsvm。 ((1).trainX大小为584 x 100,(2).biny是第1类为+1,第2类为-1的数组,(3).LinearSVMNormVector是模型的结果w(权重向量) )。下面是我的代码 -

< pre lang =   java>  //   0到1之间的比例训练数据 
double [] [] trainX_scale = new double [trainX.length] [trainX [ 0 ]。length];
for int i = 0 ; i< trainX.length; i ++){
double min = Double.MAX_VALUE;
double max = Double.MIN_VALUE;
for int inner = 0 ; inner< trainX [i] .length; inner ++){
if (trainX [i] [inner]< min)
min = trainX [i] [inner];
if (trainX [i] [inner]> max)
max = trainX [i] [inner];
}
double difference = max - min;
for int inner = 0 ; inner< trainX [i] .length; inner ++){
trainX_scale [i] [inner] =(trainX [i] [inner] - min)/ difference;
}
}

// 准备svm节点
svm_node [] [] SVM_node_Train = new svm_node [trainX [ 0 ]。 ] [trainX.length];

for int p = 0 ; p< trainX [ 0 ] .length; p ++){
for int q = 0 ; q< trainX.length; q ++){
SVM_node_Train [p] [q] = new svm_node();
SVM_node_Train [p] [q] .index = q;
SVM_node_Train [p] [q] .value = trainX_scale [q] [p];
}
}

double [] biny_SVM = new double [biny.length]; // for svm compatible
for int p = 0 ; p< biny.length; p ++){
biny_SVM [p] = biny [p];
}

svm_problem SVM_Prob = new svm_problem();
SVM_Prob.l = trainX [ 0 ]。length;
SVM_Prob.x = SVM_node_Train;
SVM_Prob.y = biny_SVM;

svm_parameter SVM_Param = new svm_parameter();
SVM_Param.svm_type = 0 ;
SVM_Param.kernel_type = 2 ;
SVM_Param.cache_size = 100 ;
SVM_Param.eps = 0 0000001 ;
SVM_Param.C = 1 0 ;
SVM_Param.gamma = 0 5 ;

svm_model SVM_Model = new svm_model();
SVM_Model.param = SVM_Param;
SVM_Model.l = trainX [ 0 ]。length;
SVM_Model.nr_class = 2 ;
SVM_Model.SV = SVM_node_Train;
// SVM_Model.label = biny;

// String check = svm.svm_check_parameter(SVM_Prob,SVM_Param); //
// System.out.println(check);

double [] target = new double [biny.length]; // for svm compatible
Arrays .fill(target, 0 0 );
svm.svm_cross_validation(SVM_Prob,SVM_Param, 2 ,target);

// 训练分类器
svm_model test_model = svm。 svm_train(SVM_Prob,SVM_Param);

/ * *********获取libsvm *的培训结果********* /

// double [ ] [] weights1 = test_model.sv_coef;

double 偏差= test_model.rho [ 0 ];
double NumberOfSupportVectors = svm.svm_get_nr_sv(test_model);

double [] SupportVectorIDs = new INT [NumberOfSupportVectors];
svm.svm_get_sv_indices(test_model,SupportVectorIDs);
svm_node [] [] SV = test_model.SV;
double [] [] SupportVectors = new double [SV.length] [SV [< span class =code-digit> 0
] .length];
for int ii = 0; ii< SV.length; ii ++){
for int jj = 0; jj< SV [ 0 ]。长度; jj ++){
SupportVectors [ii] [jj] = SV [ii] [jj] .value;
}
}
double [] SupportVectorWeights = test_model.sv_coef [ 0 ];
double [] LinearSVMNormVector = new double [SupportVectors [ 0 ]。length];
for int ii = 0; ii< msvm [ 0 ]。SupportVectors [ 0 ] .length; ii ++){
for int jj = 0; jj< SupportVectors.length; jj ++){
LinearSVMNormVector [ii] + =(SupportVectors [jj] [ii] * SupportVectorWeights [jj]);
}

}





我的测试数据上的这个型号我得到的超过90 %错误分类。我有点困惑。有人可以告诉我,如果分类器设置有什么问题吗?



谢谢!

解决方案

你是如何获得C和gamma值的?

尝试使用网格搜索方法找到它

http://scikit-learn.org/stable/modules/grid_search .html

结果可能会有所改善



还可以尝试像weka这样的工具来验证功能是否足够好

http://www.cs.waikato.ac.nz/ml/weka/


这是我的理解



每个特征代表一行,每列代表训练样本的实例

584行和100列

如果trainX [0] .length = 100且trainX.length = 584

然后节点看起来没问题



svm模型看起来像

带有rbf内核的CSVM看起来不错

I have a 584 by 100 data set with each data having 584 feature vectors(total 100 training vectors). I have implemented Libsvm in Java. ((1). trainX size is 584 x 100, (2). biny is the array which has +1 for class one and -1 for class 2, (3). LinearSVMNormVector is the resultant w (weight vector) of the model). Below is my code -

<pre lang="java">// scale train data between 0 and 1
        double[][] trainX_scale = new double[trainX.length][trainX[0].length];
        for (int i = 0; i < trainX.length; i++) {
            double min = Double.MAX_VALUE;
            double max = Double.MIN_VALUE;
            for (int inner = 0; inner < trainX[i].length; inner++) {
                if (trainX[i][inner] < min)
                    min = trainX[i][inner];
                if (trainX[i][inner] > max)
                    max = trainX[i][inner];
            }
            double difference = max - min;
            for (int inner = 0; inner < trainX[i].length; inner++) {
                trainX_scale[i][inner] = (trainX[i][inner] - min)/ difference;
            }
        }

    // prepare the svm node
        svm_node[][] SVM_node_Train = new svm_node[trainX[0].length][trainX.length];

        for (int p = 0; p < trainX[0].length; p++) {
            for (int q = 0; q < trainX.length; q++) {
                SVM_node_Train[p][q] = new svm_node();
                SVM_node_Train[p][q].index = q;
                SVM_node_Train[p][q].value = trainX_scale[q][p];
            }
        }

        double[] biny_SVM = new double[biny.length];// for svm compatible
        for (int p = 0; p < biny.length; p++) {
            biny_SVM[p] = biny[p];
        }

        svm_problem SVM_Prob = new svm_problem();
        SVM_Prob.l = trainX[0].length;
        SVM_Prob.x = SVM_node_Train;
        SVM_Prob.y = biny_SVM;

        svm_parameter SVM_Param = new svm_parameter();
        SVM_Param.svm_type = 0;
        SVM_Param.kernel_type = 2;
        SVM_Param.cache_size = 100;
        SVM_Param.eps = 0.0000001;
        SVM_Param.C = 1.0;
        SVM_Param.gamma = 0.5;

        svm_model SVM_Model = new svm_model();
        SVM_Model.param = SVM_Param;
        SVM_Model.l = trainX[0].length;
        SVM_Model.nr_class = 2;
        SVM_Model.SV = SVM_node_Train;
        //SVM_Model.label = biny;

        // String check =svm.svm_check_parameter(SVM_Prob, SVM_Param); //
        // System.out.println(check);

        double[] target = new double[biny.length];// for svm compatible
        Arrays.fill(target, 0.0);
        svm.svm_cross_validation(SVM_Prob, SVM_Param, 2, target);

        // train the classifier
        svm_model test_model = svm.svm_train(SVM_Prob, SVM_Param);

        /********** get the training results of libsvm **********/

        //double[][] weights1 = test_model.sv_coef;

        double Bias = test_model.rho[0];
        double NumberOfSupportVectors = svm.svm_get_nr_sv(test_model);

        double [] SupportVectorIDs = new int[NumberOfSupportVectors];
        svm.svm_get_sv_indices(test_model, SupportVectorIDs);
        svm_node[][] SV= test_model.SV;
        double [][]SupportVectors=new double [SV.length][SV[0].length];
        for(int ii=0;ii<SV.length;ii++){
            for(int jj=0;jj<SV[0].length;jj++){
                SupportVectors[ii][jj]=SV[ii][jj].value;
            }
        }
        double [] SupportVectorWeights=test_model.sv_coef[0];
        double[] LinearSVMNormVector = new double [SupportVectors[0].length];
        for (int ii=0;ii<msvm[0].SupportVectors[0].length;ii++){
            for (int jj=0;jj<SupportVectors.length;jj++){
                LinearSVMNormVector[ii] += (SupportVectors[jj][ii] * SupportVectorWeights[jj]);
            }

        }



with this model on my test data I am getting more than 90% mis-classification. I am a little confused. Can someone please tell me if there is anything wrong in the classifier set up?

Thanks!

解决方案

How did you obtain the C and gamma values
try using a grid search approach to find it
http://scikit-learn.org/stable/modules/grid_search.html
The result might improve

Also try a tool like weka to verify if the features are good enough
http://www.cs.waikato.ac.nz/ml/weka/


This is my understanding

Each feature represents a row and each column an instance of the training samples
584 rows and 100 columns
If trainX[0].length = 100 and trainX.length = 584
then nodes looks ok

The svm model looks like
A CSVM with rbf kernel which looks ok


这篇关于二进制分类器在libsvm中给出错误的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆