自己用python写一个线性支持向量机linearSVM
https://blog.csdn.net/iteapoy/article/details/117814830转自此网址
前言:要修改linearSVM的代码,想在网上找一个能用的代码,结果要么调用sklearn库,要么都复制粘贴同一款代码,写得太复杂了,而且有bug,在bing国际版上搜到了一个没有用SMO和拉格朗日算子求解的linearSVM代码,复制过来Mark一下。
完整代码:
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import preprocessing
from sklearn.preprocessing import StandardScaler
class LinearSVMUsingSoftMargin:
def __init__(self, C=1.0):
self._support_vectors = None
self.C = C
self.beta = None
self.b = None
self.X = None
self.y = None
# n is the number of data points
self.n = 0
# d is the number of dimensions
self.d = 0
def __decision_function(self, X):
return X.dot(self.beta) + self.b
def __cost(self, margin):
return (1 / 2) * self.beta.dot(self.beta) + self.C * np.sum(np.maximum(0, 1 - margin))
def __margin(self, X, y):
return y * self.__decision_function(X)
def fit(self, X, y, lr=1e-3, epochs=500):
# Initialize Beta and b
self.n, self.d = X.shape
self.beta = np.random.randn(self.d)
self.b = 0
# Required only for plotting
self.X = X
self.y = y
loss_array = []
for _ in range(epochs):
margin = self.__margin(X, y)
loss = self.__cost(margin)
loss_array.append(loss)
misclassified_pts_idx = np.where(margin < 1)[0]
d_beta = self.beta - self.C * y[misclassified_pts_idx].dot(X[misclassified_pts_idx])
self.beta = self.beta - lr * d_beta
d_b = - self.C * np.sum(y[misclassified_pts_idx])
self.b = self.b - lr * d_b
self._support_vectors = np.where(self.__margin(X, y) <= 1)[0]
def predict(self, X):
return np.sign(self.__decision_function(X))
def score(self, X, y):
P = self.predict(X)
return np.mean(y