A Support Vector Machine (SVM) is a very powerful and versatile Machine Learning model that is capable of performing linear or nonlinear classification, regression, and even outlier detection.
SVMs are particularly well-suited for classification of complex but small- or medium-sized datasets.
Here are a few ways to customize more advanced versions of them.
Although linear SVM classifiers are efficient and work well in many cases, many datasets are not even close to being linearly separable.
One approach to handling nonlinear datasets is to add more features, such as polynomial features, which may result in a linearly separable dataset.
To implement this in Scikit-Learn, we simply create a Pipeline containing a PolynomialFeatures transformer, followed by a StandardScaler and a LinearSVC.
Note: If your SVM model is overfitting, you can try regularizing it by reducing C.
The LinearSVC class regularizes the bias term, so you should center the training set first by subtracting its mean. This is automatic if you scale the data using the StandardScaler.
Also make sure that you set the loss hyperparameter to "hinge" as it is not the default value (the default value is "squared_hinge").
Finally, for better performance, you should set the dual hyperparameter to False, especially when n_samples > n_features.
As we have seen previously, adding polynomial features via the PolynomialFeatures transformer is simple and straightforward to implement. However, the polynomial degree should not be too high as this will create a huge number of features, making the model too slow.
An alternative is to perform the kernel trick. It makes it possible to get the same result as if you added many polynomial features, even with very high-degree polynomials, without actually having to add them.
The LinearSVC class is based on the liblinear library, which implements an optimized algorithm for linear SVMs. It does not support the kernel trick, but it scales almost linearly with the number of training instances and the number of features — its training time complexity is roughly O(m × n).
On the other hand, the SVC class is based on the libsvm library, which implements an algorithm that supports the kernel trick. The training time complexity is usually between O(m^2 × n) and O(m^3 × n). Unfortunately, this means that it gets dreadfully slow when the number of training instances gets large.
With so many kernels to choose from, how can you decide which one to use?
As a rule of thumb, you should always try the linear kernel first (remember that LinearSVC is much faster than SVC(kernel="linear")), especially if the training set is very large or if it has plenty of features.
And if the training set is not too large, you should try the Gaussian RBF kernel as well; it works well in most cases.
Finally, should you have spare time and computing power, you can also experiment with a few other kernels using cross-validation and grid search, especially if there are kernels specialized for your training set’s data structure.