美文网首页
[Stay Sharp]SVM Python实现

[Stay Sharp]SVM Python实现

作者: 三千雨点 | 来源:发表于2018-12-24 22:49 被阅读7次

svm代码实现

# -*- coding: utf-8 -*-
"""
-------------------------------------------------
   File Name:     svm
   Description :   
   Author :        Tingur
   date:          2018/11/27
   Ref:  https://github.com/Madhu009/Deep-math-machine-learning.ai/blob/master/SVM-FromScratch.ipynb
-------------------------------------------------
"""

import numpy as np
import matplotlib.pyplot as plt
import math

from sklearn.datasets.samples_generator import make_blobs

# step 1: generate data
(X, y) = make_blobs(n_samples=50,
                    n_features=2,
                    centers=2,
                    cluster_std=1.05,
                    random_state=40)
# print(X.shape)
# print(X) #[[  7.12731332  -4.4394424 ] [  6.68873898  -2.44840134]
# print(y) # 1 1 0 1 0 0 1 0 1 0 1 1 0 ...

X1 = np.c_[np.ones((X.shape[0])), X]
# print(X1)

# display data
# plt.scatter(X1[:,1], X1[:,2],marker='o', c=y)
# plt.axis([-5,10,-12,-1])
# plt.show()

# step 2: cluster the data
# for svm, we set the data cluster value to -1 and 1
positive_data = list()
negative_data = list()
for i, v in enumerate(y):
    if v == 0:
        negative_data.append(X[i])
    else:
        positive_data.append(X[i])

data_dict = {1: np.array(positive_data), -1: np.array(negative_data)}
print(data_dict)

# step 3: svm training

w = []  # weights 2 dimesional vector
b = []  # bias
max_feature_value = float('-inf')
min_feature_value = float('+inf')

for yi in data_dict:
    if np.amax(data_dict[yi]) > max_feature_value:
        max_feature_value = np.amax(data_dict[yi])

    if np.amin(data_dict[yi]) < min_feature_value:
        min_feature_value = np.amin(data_dict[yi])

print(max_feature_value, min_feature_value)
learning_rates = [max_feature_value * 0.1,
                  max_feature_value * 0.01,
                  max_feature_value * 0.001]


def svm_training(data_dict):
    i = 1
    global w
    global b

    length_w_vector = {}
    transforms = [[1, 1], [-1, 1], [-1, -1], [1, -1]]
    b_step_size = 2
    b_multiple = 5
    w_optimum = max_feature_value * 0.5

    for rate in learning_rates:
        w = np.array([w_optimum, w_optimum])
        optimized = False

        while not optimized:
            for b in np.arange(-1 * (max_feature_value * b_step_size), max_feature_value * b_step_size,
                               rate * b_multiple):
                for transformation in transforms:
                    w_t = w * transformation
                    correctly_classified = True

                    for yi in data_dict:
                        for xi in data_dict[yi]:
                            if yi * (np.dot(w_t, xi) + b) < 1:
                                correctly_classified = False

                    if correctly_classified:
                        length_w_vector[np.linalg.norm(w_t)] = [w_t, b]
            if w[0] < 0:
                optimized = True
            else:
                w = w - rate

        norms = sorted([n for n in length_w_vector])

        minimum_w_length = length_w_vector[norms[0]]
        w = minimum_w_length[0]
        b = minimum_w_length[1]

        w_optimum = w[0] + rate * 2

svm_training(data_dict)

print("w: ", w)
print("b: ", b)

# step 4: plot the svm result
colors = {1:'r',-1:'b'}
fig = plt.figure()
ax = fig.add_subplot(1,1,1)

def visualize(data_dict):
    # [[ax.scatter(x[0],x[1],s=100,color=colors[i]) for x in data_dict[i]] for i in data_dict]

    plt.scatter(X1[:, 1], X1[:, 2], marker='o', c=y)

    # hyperplane = x.w+b
    # v = x.w+b
    # psv = 1
    # nsv = -1
    # dec = 0
    def hyperplane_value(x, w, b, v):
        return (-w[0] * x - b + v) / w[1]

    datarange = (min_feature_value * 0.9, max_feature_value * 1.)
    hyp_x_min = datarange[0]
    hyp_x_max = datarange[1]

    # (w.x+b) = 1
    # positive support vector hyperplane
    psv1 = hyperplane_value(hyp_x_min, w, b, 1)
    psv2 = hyperplane_value(hyp_x_max, w, b, 1)
    ax.plot([hyp_x_min, hyp_x_max], [psv1, psv2], 'k')

    # (w.x+b) = -1
    # negative support vector hyperplane
    nsv1 = hyperplane_value(hyp_x_min, w, b, -1)
    nsv2 = hyperplane_value(hyp_x_max, w, b, -1)
    ax.plot([hyp_x_min, hyp_x_max], [nsv1, nsv2], 'k')

    # (w.x+b) = 0
    # positive support vector hyperplane
    db1 = hyperplane_value(hyp_x_min, w, b, 0)
    db2 = hyperplane_value(hyp_x_max, w, b, 0)
    ax.plot([hyp_x_min, hyp_x_max], [db1, db2], 'y--')

    plt.axis([-5, 10, -12, -1])
    plt.show()

visualize(data_dict)

源码地址

Yalye Github
原始代码地址

效果

image.png

相关文章

网友评论

      本文标题:[Stay Sharp]SVM Python实现

      本文链接:https://www.haomeiwen.com/subject/ajwtlqtx.html