Support Vector Machine é outro algoritmo simples que executa relativamente bem com menos custo computacional. Na regressão, o SVM funciona encontrando um hiperplano em um espaço N-dimensional (número N de recursos) que se ajusta aos dados multidimensionais enquanto considera uma margem. Na classificação, o mesmo hiperplano é calculado, mas para classificar distintamente os pontos de dados novamente, considerando uma margem. Pode haver muitos hiperplanos possíveis que podem ser selecionados. No entanto, o objetivo é encontrar o hiperplano com a margem máxima, ou seja, a distância máxima entre as classes alvo.
O SVM pode ser usado tanto para problemas de regressão quanto para classificação, mas é amplamente usado para classificação.
Vamos explicar alguns termos antes de prosseguirmos.
Kernel é a função usada para converter dados em dimensão superior.
O hiperplano é a linha que separa as classes (para problemas de classificação). Para regressão, é a linha que ajustamos aos nossos dados para prever valores de resultados contínuos.
Linhas de contorno são as linhas que formam a área com o erro que mencionamos anteriormente. São as duas linhas ao redor do hiperplano que representam a margem.
Os vetores de suporte são os pontos de dados mais próximos dessas linhas de limite.
Mencionamos que o kernel é a função para converter nossos dados em dimensões superiores. Bem, como isso é útil para nós?
Às vezes, os dados são distribuídos de forma que é impossível obter um ajuste preciso usando uma linha linear (separador). O SVR pode lidar com dados altamente não lineares usando a função kernel. A função mapeia implicitamente os recursos para dimensões mais altas, o que significa maior espaço de recursos. Isso nos permite descrevê-lo também usando um hiperplano linear.
Os três kernels mais usados são:
Semelhante aos modelos de regressão linear, o SVR também tenta encontrar uma curva que melhor se ajuste ao conjunto de dados. Lembrando nossa equação para conjunto de dados com um recurso de regressão linear:
y=w1x1+c
Considerando o SVR para um conjunto de dados também com uma característica, a equação parece semelhante, mas com a consideração de um erro.
−e≤y−(w1x1+c)≤e
Olhando para a equação, fica claro que apenas os pontos fora da área de erro e serão considerados no cálculo do custo.
É claro que o SVR também pode ser usado para conjuntos de dados complicados com mais recursos, usando termos de recursos dimensionais superiores semelhantes aos da regressão polinomial.
O hiperplano é o melhor ajuste aos dados quando coincide com o número máximo de pontos possível. Determinamos as linhas de fronteira (o valor de e que é a distância do hiperplano) de modo que os pontos mais próximos do hiperplano estejam dentro das linhas de fronteira.
Lembre-se de que a margem (entre as linhas de limite) será tolerada, não será calculada como erro. Acho que você já pode imaginar como esse termo nos permitirá ajustar a complexidade do nosso modelo (underfitting/overfitting).
import numpy as np from sklearn.svm import SVR import matplotlib.pyplot as plt np.random.seed(5) X = np.sort(5 * np.random.rand(40, 1), axis=0) T = np.linspace(0, 5, 5)[:, np.newaxis] y = np.sin(X).ravel() # Add noise to targets y[::5] += 1 * (0.5 - np.random.rand(8)) # Fit regression model SVR_rbf = SVR(kernel='rbf' ) SVR_lin = SVR(kernel='linear') SVR_poly = SVR(kernel='poly') y_rbf = SVR_rbf.fit(X, y).predict(X) y_lin = SVR_lin.fit(X, y).predict(X) y_poly = SVR_poly.fit(X, y).predict(X) # look at the results plt.scatter(X, y, c='k', label='data') plt.plot(X, y_rbf, c='b', label='RBF') plt.plot(X, y_lin, c='r',label='Linear') plt.plot(X, y_poly, c='g',label='Polynomial') plt.xlabel('data') plt.ylabel('outcome') plt.title('Support Vector Regression') plt.legend() plt.show()
Já vimos como o algoritmo “Support Vector Machines (SVM)” funciona para regressão. Para a classificação, a ideia é quase a mesma. Na verdade, o SVM é usado principalmente para problemas de classificação. Acredito que você já pode imaginar o porquê…
Para regressão, mencionamos que o SVM tenta encontrar uma curva que melhor se ajuste ao conjunto de dados e, em seguida, faz uma previsão para um novo ponto usando essa curva. Bem, a mesma curva pode ser facilmente usada para classificar os dados em duas classes diferentes. Para um espaço multidimensional com n dimensões (ou seja, dados com n número de recursos), o modelo ajusta um hiperplano (também chamado de limite de decisão) que melhor diferencia as duas classes. Lembrando a imagem da seção de regressão onde explicamos o kernel…
A margem é o intervalo entre os dois pontos mais próximos de cada classe, que é a distância do hiperplano aos pontos mais próximos (vetores de suporte). O hiperplano que melhor se ajusta aos dados, ou seja, que melhor separa as duas classes, é o hiperplano com a margem máxima possível. Portanto, o algoritmo SVM busca o hiperplano com a margem máxima (distância aos pontos mais próximos).
Como já mencionamos na seção de regressão, alguns conjuntos de dados simplesmente não são adequados para serem classificados por um hiperplano linear… os dados a serem classificados por um hiperplano linear. Como já discutimos os tipos de Kernel e como ele funciona, continuarei com um exemplo de implementação…
Vamos continuar usando o conjunto de dados de câncer da biblioteca scikit learn:
from sklearn.datasets import load_breast_cancer from sklearn.model_selection import train_test_split X, y = load_breast_cancer(return_X_y = True) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) X_sub = X[:, 0:2] # create a mesh to plot in x_min, x_max = X_sub[:, 0].min() - 1, X_sub[:, 0].max() + 1 y_min, y_max = X_sub[:, 1].min() - 1, X_sub[:, 1].max() + 1 h = (x_max / x_min)/100 xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h)) #import the SVM model from sklearn import svm C = 1.0 # SVM regularization parameter svc = svm.SVC(kernel='linear').fit(X_sub, y) #play with this, change kernel to rbf plt.subplot(1, 1, 1) Z = svc.predict(np.c_[xx.ravel(), yy.ravel()]) Z = Z.reshape(xx.shape) plt.contourf(xx, yy, Z, cmap=plt.cm.Paired, alpha=0.8) plt.scatter(X_sub[:, 0], X_sub[:, 1], c=y, cmap=plt.cm.Paired) plt.scatter(X_sub[svc.support_, 0], X_sub[svc.support_, 1],c='k', cmap=plt.cm.Paired) plt.xlabel('Sepal length') plt.ylabel('Sepal width') plt.xlim(xx.min(), xx.max()) plt.title('SVC with linear kernel') plt.show()
#Create and instance of the classifier model with a linear kernel lsvm = svm.SVC(kernel="linear") #fit the model to our train split from previous example lsvm.fit(X_train,y_train) #Make predictions using the test split so we can evaluate its performance y_pred = lsvm.predict(X_test)
Vamos comparar o desempenho do modelo comparando as previsões com os valores reais do conjunto de teste…
from sklearn import metrics print("Accuracy:",metrics.accuracy_score(y_test, y_pred)) print("Precision:",metrics.precision_score(y_test, y_pred)) print("Recall:",metrics.recall_score(y_test, y_pred))
Conseguimos uma precisão de 95,6%, o que é muito bom. Vamos comparar as pontuações do treinamento e do teste para verificar se há overfitting…
print("training set score: %f" % lsvm.score(X_train, y_train)) print("test set score: %f" % lsvm.score(X_test, y_test))
A pontuação do treinamento parece ser um pouco maior do que a pontuação do teste. Podemos dizer que o modelo está superajustado, embora não muito.
Se você gosta disso, sinta-se à vontade para me seguir para mais tutoriais e cursos gratuitos de aprendizado de máquina!