Skip to content

Commit

Permalink
Merge pull request #4166 from durovo/feature/platt
Browse files Browse the repository at this point in the history
Fix platt scaling
  • Loading branch information
vigsterkr committed Feb 26, 2018
2 parents c785fdf + d679103 commit 0a2c468
Show file tree
Hide file tree
Showing 12 changed files with 837 additions and 87 deletions.
95 changes: 52 additions & 43 deletions examples/undocumented/libshogun/classifier_libsvm_probabilities.cpp
@@ -1,9 +1,10 @@
#include <iostream>
#include <shogun/base/init.h>
#include <shogun/classifier/svm/LibSVM.h>
#include <shogun/evaluation/SigmoidCalibration.h>
#include <shogun/features/DenseFeatures.h>
#include <shogun/kernel/LinearKernel.h>
#include <shogun/labels/BinaryLabels.h>
#include <shogun/classifier/svm/LibSVM.h>
#include <iostream>

using namespace shogun;

Expand Down Expand Up @@ -50,45 +51,53 @@ int main(int argc, char** argv)

//create train labels
CLabels* labels=new CBinaryLabels(labelVector);

//create train features
CDenseFeatures<float64_t>* features=new CDenseFeatures<float64_t>();
SG_REF(features);
features->set_feature_matrix(featureMatrix);

//create linear kernel
CLinearKernel* kernel=new CLinearKernel();
SG_REF(kernel);
kernel->init(features, features);

//create svm classifier by LibSVM
CLibSVM* svm=new CLibSVM(svm_C,kernel, labels);
SG_REF(svm);
svm->train();

//classify data points
CBinaryLabels* out_labels=CLabelsFactory::to_binary(svm->apply());

/*convert scores to calibrated probabilities by fitting a sigmoid function
using the method described in Lin, H., Lin, C., and Weng, R. (2007). A note
on Platt's probabilistic outputs for support vector machines.
See BinaryLabels documentation for details*/
out_labels->scores_to_probabilities();

//display output labels and probabilities
for (int32_t i=0; i<num_samples; i++)
{
SG_SPRINT("out[%d]=%f (%f)\n", i, out_labels->get_label(i),
out_labels->get_value(i));
}

//clean up
SG_UNREF(out_labels);
SG_UNREF(kernel);
SG_UNREF(features);
SG_UNREF(svm);

exit_shogun();

return 0;
SG_REF(labels);

// create train features
CDenseFeatures<float64_t>* features = new CDenseFeatures<float64_t>();
SG_REF(features);
features->set_feature_matrix(featureMatrix);

// create linear kernel
CLinearKernel* kernel = new CLinearKernel();
SG_REF(kernel);
kernel->init(features, features);

// create svm classifier by LibSVM
CLibSVM* svm = new CLibSVM(svm_C, kernel, labels);
SG_REF(svm);
svm->train();

// classify data points
CBinaryLabels* out_labels = CLabelsFactory::to_binary(svm->apply());

/*convert scores to calibrated probabilities by fitting a sigmoid function
using the method described in Lin, H., Lin, C., and Weng, R. (2007). A note
on Platt's probabilistic outputs for support vector machines.
See BinaryLabels documentation for details*/
CSigmoidCalibration* sigmoid_calibration = new CSigmoidCalibration();
sigmoid_calibration->fit_binary(
out_labels, CLabelsFactory::to_binary(labels));
CBinaryLabels* calibrated_labels =
sigmoid_calibration->calibrate_binary(out_labels);

// display output labels and probabilities
for (int32_t i = 0; i < num_samples; i++)
{
SG_SPRINT(
"out[%d]=%f (%f)\n", i, out_labels->get_label(i),
calibrated_labels->get_value(i));
}

// clean up
SG_UNREF(sigmoid_calibration);
SG_UNREF(calibrated_labels);
SG_UNREF(out_labels);
SG_UNREF(kernel);
SG_UNREF(features);
SG_UNREF(svm);

exit_shogun();

return 0;
}
23 changes: 16 additions & 7 deletions examples/undocumented/libshogun/labels_binary_fit_sigmoid.cpp
Expand Up @@ -5,23 +5,32 @@
*/

#include <shogun/base/init.h>
#include <shogun/evaluation/SigmoidCalibration.h>
#include <shogun/labels/BinaryLabels.h>

using namespace shogun;

void test_sigmoid_fitting()
{
CBinaryLabels* labels=new CBinaryLabels(10);
CBinaryLabels* predictions = new CBinaryLabels(10);
labels->set_values(SGVector<float64_t>(labels->get_num_labels()));

for (index_t i=0; i<labels->get_num_labels(); ++i)
labels->set_value(i%2==0 ? 1 : -1, i);

labels->get_values().display_vector("scores");
labels->scores_to_probabilities();
labels->get_values().display_vector("probabilities");


{
predictions->set_value(i % 2 == 0 ? 1 : -1, i);
labels->set_value(i % 4 == 0 ? 1 : -1, i);
}
predictions->get_values().display_vector("scores");
CSigmoidCalibration* sigmoid_calibration = new CSigmoidCalibration();
sigmoid_calibration->fit_binary(predictions, labels);
CBinaryLabels* calibrated_labels =
sigmoid_calibration->calibrate_binary(predictions);
calibrated_labels->get_values().display_vector("probabilities");

SG_UNREF(predictions);
SG_UNREF(sigmoid_calibration);
SG_UNREF(calibrated_labels);
SG_UNREF(labels);
}

Expand Down
69 changes: 69 additions & 0 deletions src/shogun/evaluation/Calibration.h
@@ -0,0 +1,69 @@
/*
* This software is distributed under BSD 3-clause license (see LICENSE file).
*
* Authors: Heiko Strathmann, Dhruv Arya
*/

#ifndef _CALIBRATION_H__
#define _CALIBRATION_H__

#include <shogun/lib/config.h>

#include <shogun/machine/Machine.h>

namespace shogun
{
/** @brief Base class for all calibration methods. Call fit_binary() or
fit_multiclass() to
fit the parameters on the predictions and the true labels. Call calibrate to
calibrate predictions. **/
class CCalibration : public CSGObject
{
public:
/** Constructor. */
CCalibration()
{
}
/** Destructor. */
virtual ~CCalibration()
{
}

virtual const char* get_name() const
{
return "Calibration";
}

/** Fit calibration parameters for binary labels.
* @param predictions The predictions outputted by the machine
* @param targets The true labels corresponding to the predictions
* @return Indicates whether the calibration was succesful
**/
virtual bool
fit_binary(CBinaryLabels* predictions, CBinaryLabels* targets) = 0;

/** Calibrate binary predictions based on parameters learned by calling
*fit.
* @param predictions The predictions outputted by the machine
* @return Calibrated binary labels
**/
virtual CBinaryLabels* calibrate_binary(CBinaryLabels* predictions) = 0;

/** Fit calibration parameters for multiclass labels.
* @param predictions The predictions outputted by the machine
* @param targets The true labels corresponding to the predictions
* @return Indicates whether the calibration was succesful
**/
virtual bool fit_multiclass(
CMulticlassLabels* predictions, CMulticlassLabels* targets) = 0;

/** Calibrate multiclass predictions based on parameters learned by
*calling fit.
* @param predictions The predictions outputted by the machine
* @return Calibrated binary labels
**/
virtual CMulticlassLabels*
calibrate_multiclass(CMulticlassLabels* predictions) = 0;
};
}
#endif

0 comments on commit 0a2c468

Please sign in to comment.