使用python实现非线性SVM算法
时间: 2023-06-16 10:07:55 浏览: 167
非线性SVM算法可以使用核函数来解决非线性分类问题。下面是使用Python实现非线性SVM算法的步骤:
1. 导入需要的库和数据集
```python
from sklearn.datasets import make_circles
import matplotlib.pyplot as plt
import numpy as np
X, y = make_circles(n_samples=100, noise=0.1, factor=0.1, random_state=42)
```
2. 可视化数据集
```python
plt.scatter(X[:, 0], X[:, 1], c=y)
plt.show()
```
3. 定义核函数
这里我们使用径向基函数(RBF)作为核函数。
```python
def rbf_kernel(x1, x2, gamma):
return np.exp(-gamma * np.linalg.norm(x1 - x2) ** 2)
```
4. 定义非线性SVM分类器
```python
class NonlinearSVM:
def __init__(self, gamma=1.0):
self.gamma = gamma
def fit(self, X, y):
n_samples, n_features = X.shape
# 计算Gram矩阵
K = np.zeros((n_samples, n_samples))
for i in range(n_samples):
for j in range(n_samples):
K[i, j] = rbf_kernel(X[i], X[j], self.gamma)
# 定义二次规划问题
from cvxopt import matrix, solvers
P = matrix(np.outer(y, y) * K)
q = matrix(np.ones(n_samples) * -1)
A = matrix(y, (1, n_samples))
b = matrix(0.0)
G = matrix(np.diag(np.ones(n_samples) * -1))
h = matrix(np.zeros(n_samples))
# 求解二次规划问题
solvers.options['show_progress'] = False
sol = solvers.qp(P, q, G, h, A, b)
alphas = np.array(sol['x']).reshape(n_samples)
# 提取支持向量
threshold = 1e-5
sv_indices = alphas > threshold
self.support_vectors = X[sv_indices]
self.support_vector_labels = y[sv_indices]
self.support_vector_alphas = alphas[sv_indices]
# 计算偏置项
self.b = np.mean(
[y_k - self.predict(x_k, self.support_vectors, self.support_vector_labels, self.support_vector_alphas)
for (y_k, x_k) in zip(self.support_vector_labels, self.support_vectors)])
def predict(self, x, support_vectors, support_vector_labels, support_vector_alphas):
y_predict = 0
for i in range(len(support_vector_labels)):
y_predict += support_vector_alphas[i] * support_vector_labels[i] * rbf_kernel(x, support_vectors[i], self.gamma)
y_predict += self.b
return np.sign(y_predict)
```
5. 训练模型并可视化决策边界
```python
clf = NonlinearSVM(gamma=1.0)
clf.fit(X, y)
# 可视化决策边界
def plot_contours(ax, clf, xx, yy, **params):
Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
out = ax.contourf(xx, yy, Z, **params)
return out
xx, yy = np.meshgrid(np.linspace(-1.5, 1.5, 100), np.linspace(-1.5, 1.5, 100))
fig, ax = plt.subplots()
plot_contours(ax, clf, xx, yy, cmap=plt.cm.coolwarm, alpha=0.8)
plt.scatter(X[:, 0], X[:, 1], c=y)
plt.show()
```
完整代码如下:
```python
from sklearn.datasets import make_circles
import matplotlib.pyplot as plt
import numpy as np
X, y = make_circles(n_samples=100, noise=0.1, factor=0.1, random_state=42)
plt.scatter(X[:, 0], X[:, 1], c=y)
plt.show()
def rbf_kernel(x1, x2, gamma):
return np.exp(-gamma * np.linalg.norm(x1 - x2) ** 2)
class NonlinearSVM:
def __init__(self, gamma=1.0):
self.gamma = gamma
def fit(self, X, y):
n_samples, n_features = X.shape
# 计算Gram矩阵
K = np.zeros((n_samples, n_samples))
for i in range(n_samples):
for j in range(n_samples):
K[i, j] = rbf_kernel(X[i], X[j], self.gamma)
# 定义二次规划问题
from cvxopt import matrix, solvers
P = matrix(np.outer(y, y) * K)
q = matrix(np.ones(n_samples) * -1)
A = matrix(y, (1, n_samples))
b = matrix(0.0)
G = matrix(np.diag(np.ones(n_samples) * -1))
h = matrix(np.zeros(n_samples))
# 求解二次规划问题
solvers.options['show_progress'] = False
sol = solvers.qp(P, q, G, h, A, b)
alphas = np.array(sol['x']).reshape(n_samples)
# 提取支持向量
threshold = 1e-5
sv_indices = alphas > threshold
self.support_vectors = X[sv_indices]
self.support_vector_labels = y[sv_indices]
self.support_vector_alphas = alphas[sv_indices]
# 计算偏置项
self.b = np.mean(
[y_k - self.predict(x_k, self.support_vectors, self.support_vector_labels, self.support_vector_alphas)
for (y_k, x_k) in zip(self.support_vector_labels, self.support_vectors)])
def predict(self, x, support_vectors, support_vector_labels, support_vector_alphas):
y_predict = 0
for i in range(len(support_vector_labels)):
y_predict += support_vector_alphas[i] * support_vector_labels[i] * rbf_kernel(x, support_vectors[i], self.gamma)
y_predict += self.b
return np.sign(y_predict)
clf = NonlinearSVM(gamma=1.0)
clf.fit(X, y)
# 可视化决策边界
def plot_contours(ax, clf, xx, yy, **params):
Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
out = ax.contourf(xx, yy, Z, **params)
return out
xx, yy = np.meshgrid(np.linspace(-1.5, 1.5, 100), np.linspace(-1.5, 1.5, 100))
fig, ax = plt.subplots()
plot_contours(ax, clf, xx, yy, cmap=plt.cm.coolwarm, alpha=0.8)
plt.scatter(X[:, 0], X[:, 1], c=y)
plt.show()
```
阅读全文