基于tensroflow的svm算法实现:svm的简介以及线性svm的使用

内容均整理自《tensorflow机器学习实战指南》。

支持向量机算法是一种二值分类算法,基本观点是找到两类之间得一个线性可分得直线(或者超平面)。而上一篇所说得逻辑回归算法也是二值预测。一半来说,如果训练集中有大量特征,建议使用逻辑回归或者线性支持向量机算法;如果训练集数量更大,或者数据集是非线性可分得,建议使用带高斯核得支持向量机算法。

我们知道对于线性可分的二值问题,有许多直线可以分割两类目标,我们定义分割两类目标有最大距离的直线为最佳线性分类器,线性支持向量机算法就是找到这个最佳线性分类器。

我们仍然使用iris数据集,创建一个线性二值分类器来预测是否山鸢尾花。

代码如下:

import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
from sklearn import datasets

# 设置随机种子
np.random.seed(5) #seed( ) 用于指定随机数生成时所用算法开始的整数值,如果使用相同的seed( )值, 
                  #则每次生成的随即数都相同,如果不设置这个值,则系统根据时间来自己选择这个值, 
                  #此时每次生成的随机数因时间差异而不同。
tf.set_random_seed(5)
sess = tf.Session()
iris = datasets.load_iris()
x_vals = np.array([[x[0],x[3]] for x in iris.data]) #选取iris.data中的两类特征
y_vals = np.array([1 if y==0 else -1 for y in iris.target]) # 分别-1和1标记
#分割数据集,因为我们知道这个数据集是线性可分的
train_indices = np.random.choice(len(x_vals),int(round(len(x_vals)*0.9)),replace=False) #round() 近似取值函数 np.random.choice() 随机抽取训练样本,大小是第二个参数的值,#replace=False的意思是抽取的值没有重复,注意这里抽取的是索引值
test_indices = np.array(list(set(range(len(x_vals)))-set(train_indices)))# 剩下的便是测试
                                                                         # 集索引
x_vals_train = x_vals[train_indices]
y_vals_train = y_vals[train_indices]
x_vals_test = x_vals[test_indices]
y_vals_test = y_vals[test_indices]
#设置批量大小,占位符和模型变量
batch_size  = 50
# # Initialize placeholders
x_data = tf.placeholder(shape=[None, 2], dtype=tf.float32) #占位,选取两个特征
y_target = tf.placeholder(shape=[None, 1], dtype=tf.float32) # 输出一个分类结果
#
# # Create variables for linear regression
A = tf.Variable(tf.random_normal(shape=[2, 1])) 
b = tf.Variable(tf.random_normal(shape=[1, 1]))
#声明模型输出
model_output = tf.subtract(tf.matmul(x_data,A),b)
#声明最大间隔损失函数
l2_norm = tf.reduce_sum(tf.square(A)) #求和
alpha = tf.constant([0.01])
classification_term = tf.reduce_mean(tf.maximum(0.,tf.subtract(1.,tf.multiply(model_output,y_target))))
loss = tf.add(classification_term,tf.multiply(alpha,l2_norm)) #求平均
#声明预测函数和准确度函数
prediction = tf.sign(model_output)
accuracy = tf.reduce_mean(tf.cast(tf.equal(prediction,y_target),tf.float32))# 整数形式转为 
                                                                            # 浮点形式
#声明优化器函数,并初始化模型变量
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(loss)
init = tf.global_variables_initializer()
sess.run(init)
#开始遍历迭代训练模型,记录训练集和测试集训练损失和准确度
loss_vec = []
train_accuracy = []
test_accuracy = []
for i in range(2000):
    rand_index = np.random.choice(len(x_vals_train), size=batch_size)
    rand_x = x_vals_train[rand_index]
    rand_y = np.transpose([y_vals_train[rand_index]])
    sess.run(train_step, feed_dict={x_data: rand_x, y_target: rand_y})
    temp_loss = sess.run(loss,feed_dict={x_data:rand_x,y_target:rand_y})
    loss_vec.append(temp_loss)
    train_acc_temp = sess.run(accuracy,feed_dict={x_data:x_vals_train,y_target:np.transpose([y_vals_train])})
    train_accuracy.append(train_acc_temp)
    test_acc_temp = sess.run(accuracy,feed_dict={x_data:x_vals_test,y_target:np.transpose([y_vals_test])})
    test_accuracy.append(test_acc_temp)
    if(i+1)%100 ==0:
        print('step#'+str(i+1)+'A='+str(sess.run(A))+'b='+str(sess.run(b)))
        print('loss='+str(temp_loss))
#绘制结果图
[[a1],[a2]] = sess.run(A)
[[b]] = sess.run(b)
slope = -a2/a1
y_intercept = b/a1
x1_vals = [d[1]for d in x_vals]
best_fit = []
for i in x1_vals:
    best_fit.append(slope*i+y_intercept)
setosa_x = [d[1] for i,d in enumerate(x_vals) if y_vals[i]==1]
setosa_y = [d[0] for i,d in enumerate(x_vals) if y_vals[i]==1]
not_setosa_x = [d[1]for i,d in enumerate(x_vals) if y_vals[i]==-1]
not_setosa_y = [d[0]for i,d in enumerate(x_vals) if y_vals[i]==-1]
#线性分类器,准确度和损失图
plt.plot(setosa_x, setosa_y, 'o', label='I. setosa')
plt.plot(not_setosa_x, not_setosa_y, 'x', label='Non-setosa')
plt.plot(x1_vals, best_fit, 'r-', label='Linear Separator', linewidth=3)
plt.ylim([0,10])
plt.legend(loc = 'lower right')
plt.title('sepal length vs pedal width')
plt.xlabel('pedal width')
plt.ylabel('sepal length')
plt.show()
plt.plot(train_accuracy,'k-',label = 'training accuracy')
plt.plot(test_accuracy,'r--',label = 'test accuracy')
plt.title('train and test set accuracy')
plt.xlabel('generation')
plt.ylabel('accuracy')
plt.legend(loc = 'lower right')
plt.show()
plt.plot(loss_vec,'k-')
plt.title('loss per generation')
plt.xlabel('generation')
plt.ylabel('loss')
plt.show()

实验结果:

书本中得代码大部分没问题,不过有些小地方有问题,需要自己取调试,或者直接找一下源码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值