How to fix the false positives rate of a linear SVM?

python, scikit-learn, svm

Solution

The predict method for `LinearSVC` in sklearn looks like this

def predict(self, X):
    """Predict class labels for samples in X.

    Parameters
    ----------
    X : {array-like, sparse matrix}, shape = [n_samples, n_features]
        Samples.

    Returns
    -------
    C : array, shape = [n_samples]
        Predicted class label per sample.
    """
    scores = self.decision_function(X)
    if len(scores.shape) == 1:
        indices = (scores > 0).astype(np.int)
    else:
        indices = scores.argmax(axis=1)
    return self.classes_[indices]

So in addition to what `mbatchkarov` suggested you can change the decisions made by the classifier (any classifier really) by changing the boundary at which the classifier says something is of one class or the other.

from collections import Counter
import numpy as np
from sklearn.datasets import load_iris
from sklearn.svm import LinearSVC

data = load_iris()

# remove a feature to make the problem harder
# remove the third class for simplicity
X = data.data[:100, 0:1] 
y = data.target[:100] 
# shuffle data
indices = np.arange(y.shape[0])
np.random.shuffle(indices)
X = X[indices, :]
y = y[indices]

decision_boundary = 0
print Counter((clf.decision_function(X[50:]) > decision_boundary).astype(np.int8))
Counter({1: 27, 0: 23})

decision_boundary = 0.5
print Counter((clf.decision_function(X[50:]) > decision_boundary).astype(np.int8))
Counter({0: 39, 1: 11})

You can optimize the decision boundary to be anything depending on your needs.

Problem

I am an SVM newbie and this is my use case: I have a lot of unbalanced data to be binary classified using a linear SVM. I need to fix the false positives rate at certain values and measure the corresponding false negatives for each value. I am using something like the following code making use of scikit-learn svm implementation: ``` # define training data X = [[0, 0], [1, 1]] y = [0, 1] # define and train the SVM clf = svm.LinearSVC(C=0.01, class_weight='auto') #auto for unbalanced distributions clf.fit(X, y) # compute false positives and false negatives predictions = [clf.predict(ex) for ex in X] false_positives = [(a, b) for (a, b) in zip(predictions,y) if a != b and b == 0] false_negatives = [(a, b) for (a, b) in zip(predictions,y) if a != b and b == 1] ``` Is there a way to play with a parameter (or a few parameters) of the classifier such that one the measurement metrics is effectively fixed?

Original source