import numpy as np
import matplotlib.pyplot as plt
#创造数据
x = [-2,6,-2,7,-3,3,0,8,1,10,2,12,2,5,3,6,4,5,2,15,1,10,4,7,4,11,0,3,-1,4,1,5,3,11,4,6]
x = np.mat(x).reshape(-1,2)
y = [1,1,-1,1,1,1,-1,-1,-1,1,1,-1,1,-1,-1,-1,1,1]
y = np.mat(y).reshape(-1,1)
datamat = x
labelmat = y
#求a2的范围
def setrange(a1,a2,y1,y2,C):
if (y1 != y2):
##print('y1!=y2')
L = max(0,a2 - a1)
H = min(C,C + a2 - a1)
else:
L = max(0, a2 + a1 - C)
H = min(C, a2 + a1)
#print('L:',L)
#print('H:',H)
return L,H #在定义域选择最小值
def choosemin(L,H,a2):
#print('a2导数等于0:a2:',a2)
if a2 > H:
#print('a选择的值为:',H)
return H
if a2 < L:
#print('a选择的值为:',L)
return L
else:
#print('a选择的值为:',a2)
return a2 #根据公式和定义域算newa2
def getnewa2(Ex,index1,index2,a,labelmat,datamat,C):
K11 = K(datamat,index1,index1)
K22 = K(datamat,index2,index2)
K12 = K(datamat,index1,index2)
E1 = Ex[index1,0]
E2 = Ex[index2,0]
a1 = a[index1,0]
a2 = a[index2,0]
y1 = labelmat[index1,0]
y2 = labelmat[index2,0]
L,H = setrange(a1,a2,y1,y2,C)
if K11 + K22 - 2*K12==0:
print('gfhhhfgggggggggg函数里的除0错误index:',index1,index2)
newa2 = a2 + (y2 * (E1 - E2)) / (K11 + K22 - 2*K12) #根据偏导求出最小值a2
newa2 = choosemin(L,H,newa2) #让a2满足定义域中取值
return newa2 #检验是否目标函数在下降 L = L + ... 需要要求...<0
def ifdown(a,index1,index2,newa1,newa2,datamat): # L = L + x 要想L下降,则x<0 下降则返回flag = 1
flag = 0
a1 = a[index1,0]
a2 = a[index2,0]
x = a1 - newa1 + a2 - newa2 + 0.5 * ((newa1**2 - a1**2) * K(datamat,index1,index1)+ 2*labelmat[index1,0] * labelmat[index2,0] * K(datamat,index1,index2)*(newa1*newa2-a1*a2) + (newa2**2 - a2**2)*K(datamat,index2,index2))
# print('x是否小于0:',x)
if x < 0:
flag = 1
return flag #K11 = x1 * x1.T
def K(datamat,index1,index2):
return datamat[index1,:] * datamat[index2,:].T #主函数SVM
def mySVM(datamat,labelmat,C,times):
m, n = np.shape(datamat)
a = np.zeros((m,1))
b = 0 # wx+b 那个b
gx = np.zeros((m, 1)) # 原公式g(x) = wx + b 有m行数据就有m行给g(x)
w = np.zeros((1,2)) # wx+b 的 w ,例:w = (0,0) 二维
Ex = gx - labelmat
#训练次数大循环
for i in range(times):
flag = 0 #用于选取第一个α时是否不满足第一个条件
flagdown = 0
index1 = 0 #选取α1的序号
for a1 in a: #取第一个α
E1 = Ex[index1]
a1 = a1[0] #a1原来是[5]的格式,取第0个取出其数值5
distence1 = labelmat[index1,0] * gx[index1,0] # y*g(x)
index2 = 0
if 0 < a1 < C and distence1 != 1: #优先选择支持向量违反kkt条件
# print('第一条件a1', index1)
flag = 1 #是否经过第一层支持向量的检验
listEx = list(Ex)
del (listEx[index1]) #listEx为去除了index1的数据的Ex 方便a2的筛选
for a2 in a:
# print()
if index1 == index2:
index2 += 1
continue
#print('第一条件内循环a2:index1:{},index2:{}'.format(index1,index2))
Ex2 = Ex[index2]
minEx = min(listEx)
maxEx = max(listEx)
# 满足条件则继续往下 不满足则continue
if E1 <= 0 and Ex2 == maxEx:
# print('a2满足第一条')
index2 = index2
elif E1 > 0 and Ex2 == minEx:
# print('a2满足第二条')
index2 = index2
# 防止除0错误
else:
# print('都不满足继续循环找a2')
index2 += 1
continue
k = labelmat[index1,0] * a1 + labelmat[index2,0] * a2 # 即y1a1 + y2a2 = k 为后面求newa1做铺垫
if K(datamat, index1, index1) + K(datamat, index2, index2) - 2 * K(datamat, index1, index2) == 0:
# print('第一种除0错误', index1, index2)
index2 += 1
continue
newa2 = getnewa2(Ex,index1,index2,a,labelmat,datamat,C)
newa1 = labelmat[index1,0] * k - labelmat[index1,0] * labelmat[index2,0] * newa2 #即a1 = y1k - y1y2a2
flagdown = ifdown(a,index1,index2,newa1,newa2,datamat)
if flagdown == 1: #如果下降,改变原来的a集合中的对应两个a1 a2
print('第一种外循环的下降')
print('newa1:{},newa2:{},index1:{},index2:{}'.format(newa1, newa2, index1, index2))
a[index1] = newa1
a[index2] = newa2
w = np.multiply(a, labelmat).T * datamat
if newa1 < C and newa1 > 0:
if newa2 < C and newa2 > 0:
b = (labelmat[index1] - w * datamat[index1,:].T) + (labelmat[index2] - w * datamat[index2,:].T)
b = 0.5 * b #两个都是支持向量就取平均值
else:
b = (labelmat[index1] - w * datamat[index1,:].T)
else:
if newa2 < C and newa2 > 0:
b = labelmat[index2] - w * datamat[index2,:].T
else:
b = b
gx[index1] = w * datamat[index1, :].T + b
gx[index2] = w * datamat[index2, :].T + b
Ex[index1] = gx[index1] - labelmat[index1]
Ex[index2] = gx[index2] - labelmat[index2]
break
else:
del (listEx[listEx.index(Ex2)])
index2 += 1
if flagdown == 1: #下降成功,a1循环也停止,重新开始选两个a1进行
break
index1 +=1
#a1的第二种选取条件
if flag == 0:
index1 = 0 # 上面改变了 在这里重新初始化
for a1 in a: # 取第一个α
index2 = 0
E1 = Ex[index1]
a1 = a1[0] # a1原来是[5]的格式,取第0个取出其数值5
distence1 = labelmat[index1, 0] * gx[index1, 0] # y*g(x)
# print('第二条件外循环a1,index1:{},distence:{}'.format(index1,distence1))
if (a1==0 and distence1 <= 1) or (a1==C and distence1 >=1): # 优先选择支持向量违反kkt条件
flagdown = 0
listEx = list(Ex)
del (listEx[index1]) # listEx为去除了index1的数据的Ex 方便a2的筛选
for a2 in a:
# print()
if index1 == index2:
index2 += 1
continue
# print('第二条件内循环a2:index1:{},index2:{}'.format(index1, index2))
Ex2 = Ex[index2]
minEx = min(listEx)
maxEx = max(listEx)
# print('Ex2:{},minEx:{},maxEx:{}'.format(Ex2,minEx,maxEx))
# 满足条件则继续往下 不满足则continue
if E1 <= 0 and Ex2 == maxEx:
# print('a2满足第一条')
index2 = index2
elif E1 > 0 and Ex2 == minEx:
# print('a2满足第二条')
index2 = index2
# 防止除0错误
else:
# print('都不满足继续循环找a2')
index2 += 1
continue
k = labelmat[index1, 0] * a1 + labelmat[index2, 0] * a2 # 即y1a1 + y2a2 = k 为后面求newa1做铺垫
if K(datamat, index1, index1) + K(datamat, index2, index2) - 2 * K(datamat, index1,
index2) == 0:
# print('第一种除0错误', index1, index2)
index2 += 1
continue
newa2 = getnewa2(Ex, index1, index2, a, labelmat, datamat, C)
newa1 = labelmat[index1, 0] * k - labelmat[index1, 0] * labelmat[
index2, 0] * newa2 # 即a1 = y1k - y1y2a2
flagdown = ifdown(a, index1, index2, newa1, newa2, datamat)
if flagdown == 1: # 如果下降,改变原来的a集合中的对应两个a1 a2
print('第二种外循环的下降')
print('newa1:{},newa2:{},index1:{},index2:{}'.format(newa1,newa2,index1,index2))
a[index1] = newa1
a[index2] = newa2
w = np.multiply(a, labelmat).T * datamat
if newa1 < C and newa1 > 0:
if newa2 < C and newa2 > 0:
b = (labelmat[index1] - w * datamat[index1, :].T) + (
labelmat[index2] - w * datamat[index2, :].T)
b = 0.5 * b # 两个都是支持向量就取平均值
else:
b = (labelmat[index1] - w * datamat[index1, :].T)
else:
if newa2 < C and newa2 > 0:
b = labelmat[index2] - w * datamat[index2, :].T
else:
b = b
gx[index1] = w * datamat[index1, :].T + b
gx[index2] = w * datamat[index2, :].T + b
Ex[index1] = gx[index1] - labelmat[index1]
Ex[index2] = gx[index2] - labelmat[index2]
break
else:
del(listEx[listEx.index(Ex2)])
index2 += 1
if flagdown == 1: # 下降成功,a1循环也停止,重新开始选两个a1进行
break
index1 += 1
return w,b,a
print()
myW,myB,myA= mySVM(datamat,labelmat,0.0229,50)
print('W',myW)
print('B:',myB)
print('a.T',myA.T) # 画图 展示数据
fig = plt.figure()
ax2 = fig.add_subplot(121)
ax2.scatter(list(datamat[:,0]),list(datamat[:,1]),list(10*(labelmat+2)),list(10*(labelmat+2)))
x = np.linspace(-3,5,50)
y = (-myB - myW[0,0] * x) / myW[0,1]
plt.plot(x,y.T,'r-')
plt.plot(x,y.T+1/myW[0,1],'b--')
plt.plot(x,y.T-1/myW[0,1],'y--')
plt.show()

    

SVM python代码自实践的更多相关文章

  1. Redis的Python实践,以及四中常用应用场景详解——学习董伟明老师的《Python Web开发实践》

    首先,简单介绍:Redis是一个基于内存的键值对存储系统,常用作数据库.缓存和消息代理. 支持:字符串,字典,列表,集合,有序集合,位图(bitmaps),地理位置,HyperLogLog等多种数据结 ...

  2. 一个 11 行 Python 代码实现的神经网络

    一个 11 行 Python 代码实现的神经网络 2015/12/02 · 实践项目 · 15 评论· 神经网络 分享到:18 本文由 伯乐在线 - 耶鲁怕冷 翻译,Namco 校稿.未经许可,禁止转 ...

  3. Python应用与实践【转】

    转自:http://www.cnblogs.com/skynet/archive/2013/05/06/3063245.html 目录 1.      Python是什么? 1.1.      Pyt ...

  4. 翻译文章“AST 模块:用 Python 修改 Python 代码”---!!注意ironpathyon未实现此功能

    https://github.com/upsuper/blog/commit/0214fdd084c4adf2de2ed9912d644fb59ce13a1c +Title: [翻译] AST 模块: ...

  5. 200行Python代码实现2048

    200行Python代码实现2048 一.实验说明 1. 环境登录 无需密码自动登录,系统用户名shiyanlou 2. 环境介绍 本实验环境采用带桌面的Ubuntu Linux环境,实验中会用到桌面 ...

  6. 15行python代码,帮你理解令牌桶算法

    本文转载自: http://www.tuicool.com/articles/aEBNRnU   在网络中传输数据时,为了防止网络拥塞,需限制流出网络的流量,使流量以比较均匀的速度向外发送,令牌桶算法 ...

  7. 决策树原理实例(python代码实现)

    决策数(Decision Tree)在机器学习中也是比较常见的一种算法,属于监督学习中的一种.看字面意思应该也比较容易理解,相比其他算法比如支持向量机(SVM)或神经网络,似乎决策树感觉“亲切”许多. ...

  8. Python 的 pandas 实践

    Python 的 pandas 实践: # !/usr/bin/env python # encoding: utf-8 __author__ = 'Administrator' import pan ...

  9. 【Python】远离 Python 最差实践,避免挖坑

    原文链接:http://blog.guoyb.com/2016/12/03/bad-py-style/ 最近在看一些陈年老系统,其中有一些不好的代码习惯遗留下来的坑:加上最近自己也写了一段烂代码导致服 ...

随机推荐

  1. DirectX11--HLSL编译着色器的三种方法

    前言 本教程不考虑Effects11(FX11),而是基于原始的HLSL. 目前编译与加载着色器的方法如下: 使用Visual Studio中的HLSL编译器,随项目编译期间一同编译,并生成.cso( ...

  2. 为程序启用 守护进程-- supervisior

    待补充... Add this to your /etc/supervisord.conf: [rpcinterface:supervisor] supervisor.rpcinterface_fac ...

  3. maven项目导入依赖jar包并打包为可运行的jar包

    1.在pom.xml文件中添加插件 <build> <finalName>LeadServer</finalName> <!-- jar包名前缀,如果没有指定 ...

  4. [置顶]Python开发之路

    阅读目录   第一篇:python入门 第二篇:数据类型.字符编码.文件处理 第三篇:函数 第四篇:模块与包 第五篇:常用模块 第六篇:面向对象 第七篇:面向对象高级 第八篇:异常处理 第九篇:网络编 ...

  5. hibernate之一对多,多对一

    配置文件 <!--一对多--><!--name:集合属性名字 column:外键列名 class:与它相关的对象的完整列名 cascade:级联操作:分3种 save-update: ...

  6. 关于JDK1.7+中HashMap对红黑树场景的思考

    背景 在1.7之前的版本,当数组元素较多(几百.几千,或者更多)的时候,在这种前提扩容,涉及全量元素的遍历和坐标的重新定位,这个耗时会比较长.这是之前存在的一个弊端吧.那么引入红黑树之后就解决了问题, ...

  7. 1、Altium Designer 入门

    一.新建工程 File-->new-->Project-->newPCB Project 1.添加原理图 在Project面板选中项目,右键Add New to Project--& ...

  8. 2018-2019-2 20165237《网络对抗技术》Exp2 后门原理与实践

    2018-2019-2 20165237<网络对抗技术>Exp2 后门原理与实践 一.实践目标 使用netcat获取主机操作Shell,cron启动 使用socat获取主机操作Shell, ...

  9. 服务器 隐藏php版本,nginx版本号等

    隐藏php版本号: 打开php.ini配置文件  找到 expose_php 关键修改为 off 即可 重启后 web头部就不会有了 隐藏 nginx 服务器版本号: 打开nginx配置文件,在htt ...

  10. 如何在submit上运行php文件

    一..把php加入到环境变量 二.在sublmie中新建编译系统 三.添加一下代码,修改成php当前的目录地址,保存在默认的路径下,命名为php.sublime-build { "cmd&q ...