用python语言编写实现支持向量机算法的代码(要求提供至少5类核函数)
时间: 2024-02-21 13:59:19 浏览: 67
好的,以下是用 Python 语言实现支持向量机算法的代码,并提供了五种常见的核函数:
```python
import numpy as np
from cvxopt import matrix, solvers
class SVM:
def __init__(self, kernel='linear', C=1.0, degree=3, gamma='scale', coef0=0.0):
self.kernel = kernel
self.C = C
self.degree = degree
self.gamma = gamma
self.coef0 = coef0
def fit(self, X, y):
n_samples, n_features = X.shape
if self.gamma == 'scale':
self.gamma = 1 / (n_features * X.var())
elif self.gamma == 'auto':
self.gamma = 1 / n_features
if self.kernel == 'linear':
K = np.dot(X, X.T)
elif self.kernel == 'poly':
K = (self.gamma * np.dot(X, X.T) + self.coef0)**self.degree
elif self.kernel == 'rbf':
X2 = np.sum(X**2, axis=1).reshape(-1, 1)
K = np.exp(-self.gamma * (X2 - 2 * np.dot(X, X.T) + X2.T))
elif self.kernel == 'sigmoid':
K = np.tanh(self.gamma * np.dot(X, X.T) + self.coef0)
elif self.kernel == 'laplacian':
X2 = np.sum(X**2, axis=1).reshape(-1, 1)
K = np.exp(-self.gamma * np.sqrt(X2 - 2 * np.dot(X, X.T) + X2.T))
else:
raise ValueError('Invalid kernel')
P = matrix(np.outer(y, y) * K)
q = matrix(-1 * np.ones(n_samples))
G = matrix(np.vstack((np.eye(n_samples)*-1, np.eye(n_samples))))
h = matrix(np.hstack((np.zeros(n_samples), np.ones(n_samples) * self.C)))
A = matrix(y.reshape(1, -1))
b = matrix(np.zeros(1))
solvers.options['show_progress'] = False
solution = solvers.qp(P, q, G, h, A, b)
self.alpha = np.array(solution['x']).reshape(-1)
self.sv_idx = self.alpha > 1e-5
self.support_vectors = X[self.sv_idx]
self.support_vectors_y = y[self.sv_idx]
self.alpha = self.alpha[self.sv_idx]
if self.kernel == 'linear':
self.w = np.dot(self.alpha * self.support_vectors_y, self.support_vectors)
self.b = np.mean(self.support_vectors_y - np.dot(self.support_vectors, self.w))
else:
self.b = np.mean([self.support_vectors_y[i] - np.sum(self.alpha * self.support_vectors_y * K[self.sv_idx[i], self.sv_idx]) for i in range(len(self.alpha))])
def predict(self, X):
if self.kernel == 'linear':
return np.sign(np.dot(X, self.w) + self.b)
else:
y_pred = np.zeros(len(X))
for i in range(len(X)):
s = 0
for alpha, sv_y, sv in zip(self.alpha, self.support_vectors_y, self.support_vectors):
if self.kernel == 'linear':
kernel = np.dot(X[i], sv)
elif self.kernel == 'poly':
kernel = (self.gamma * np.dot(X[i], sv) + self.coef0)**self.degree
elif self.kernel == 'rbf':
kernel = np.exp(-self.gamma * np.linalg.norm(X[i] - sv)**2)
elif self.kernel == 'sigmoid':
kernel = np.tanh(self.gamma * np.dot(X[i], sv) + self.coef0)
elif self.kernel == 'laplacian':
kernel = np.exp(-self.gamma * np.abs(np.linalg.norm(X[i] - sv)))
else:
raise ValueError('Invalid kernel')
s += alpha * sv_y * kernel
y_pred[i] = s
return np.sign(y_pred + self.b)
```
这里提供了五种核函数:
1. 线性核函数:$K(x_i, x_j) = x_i^T x_j$
2. 多项式核函数:$K(x_i, x_j) = (\gamma x_i^T x_j + r)^d$
3. 高斯核函数(RBF核函数):$K(x_i, x_j) = \exp(-\gamma ||x_i - x_j||^2)$
4. sigmoid核函数:$K(x_i, x_j) = \tanh(\gamma x_i^T x_j + r)$
5. 拉普拉斯核函数:$K(x_i, x_j) = \exp(-\gamma ||x_i - x_j||)$
其中,$\gamma$、$d$和$r$为超参数,分别代表高斯核函数的带宽、多项式核函数的阶数和常数项、sigmoid核函数的斜率和常数项。在实际使用中,可以通过交叉验证等方法确定这些超参数的值。
阅读全文