数学建模——支持向量机模型详解Python代码

from numpy import *
import random
import matplotlib.pyplot as plt
import numpydef kernelTrans(X,A,kTup):                    # 核函数(此例未使用)m,n=shape(X)K = mat(zeros((m,1)))if kTup[0] =='lin':K=X*A.Telif kTup[0]=='rbf':for j in range(m):deltaRow = X[j,:]-AK[j]=deltaRow*deltaRow.T           # ||w||^2 = w^T * wK =exp(K/(-1*kTup[1]**2))              # K = e^(||x-y||^2 / (-2*sigma^2))else:raise NameError("Houston we Have a problem --")return Kclass optStruct:def __init__(self,dataMain,classLabel,C,toler,kTup):self.X = dataMain                     # 样本矩阵self.labelMat = classLabelself.C = C                            # 惩罚因子self.tol = toler                      # 容错率self.m = shape(dataMain)[0]           # 样本点个数self.alphas = mat(zeros((self.m,1)))  # 产生m个拉格郎日乘子,组成一个m×1的矩阵self.b =0                             # 决策面的截距self.eCache = mat(zeros((self.m,2)))    # 产生m个误差 E=f(x)-y ,设置成m×2的矩阵,矩阵第一列是标志位,标志为1就是E计算好了,第二列是误差E# self.K = mat(zeros((self.m,self.m)))# for i in range(self.m):               # K[,]保存的是任意样本之间的相似度(用高斯核函数表示的相似度)#     self.K[:,i]=kernelTrans(self.X,self.X[i,:],kTup)def loadDataSet(filename):                 # 加载数据dataMat = []labelMat = []fr = open(filename)for line in fr.readlines():lineArr = line.split()dataMat.append([float(lineArr[0]),float(lineArr[1])])labelMat.append(float(lineArr[2]))     # 一维列表return dataMat, labelMatdef selectJrand(i, m):       # 随机选择一个不等于i的下标j =iwhile(j==i):j = int(random.uniform(0,m))return jdef clipAlpha(aj, H,L):if aj>H:                      # 如果a^new 大于上限值,那么就把上限赋给它aj = Hif L>aj:                      # 如果a^new 小于下限值,那么就把下限赋给它aj = Lreturn ajdef calcEk(oS, k):           # 计算误差E, k代表第k个样本点,它是下标,oS是optStruct类的实例# fXk = float(multiply(oS.alphas,oS.labelMat).T * oS.K[:,k] + oS.b)   # 公式f(x)=sum(ai*yi*xi^T*x)+bfXk = float(multiply(oS.alphas,oS.labelMat).T * (oS.X*oS.X[k,:].T)) +oS.bEk = fXk - float(oS.labelMat[k])          # 计算误差 E=f(x)-yreturn Ekdef selectJ(i, oS, Ei):      # 选择两个拉格郎日乘子,在所有样本点的误差计算完毕之后,寻找误差变化最大的那个样本点及其误差maxK = -1                # 最大步长的因子的下标maxDeltaE = 0            # 最大步长Ej = 0                   # 最大步长的因子的误差oS.eCache[i] = [1,Ei]valiEcacheList = nonzero(oS.eCache[:,0].A)[0]    # nonzero结果是两个array数组,第一个数组是不为0的元素的x坐标,第二个数组是该位置的y坐标# 此处寻找误差矩阵第一列不为0的数的下标print("valiEcacheList is {}".format(valiEcacheList))if (len(valiEcacheList))>1:for k in valiEcacheList:          # 遍历所有计算好的Ei的下标,valiEcacheLIst保存了所有样本点的E,计算好的有效位置是1,没计算好的是0if k == i:continueEk = calcEk(oS,k)deltaE = abs(Ei-Ek)          # 距离第一个拉格朗日乘子a1绝对值最远的作为第二个朗格朗日乘子a2if deltaE>maxDeltaE:maxK = k                 # 记录选中的这个乘子a2的下标maxDeltaE = deltaE       # 记录他俩的绝对值Ej = Ek                  # 记录a2此时的误差return maxK, Ejelse:                             # 如果是第一次循环,随机选择一个alphasj = selectJrand(i, oS.m)# j = 72Ej = calcEk(oS, j)return j,Ejdef updateEk(oS, k):Ek = calcEk(oS, k)oS.eCache[k] = [1,Ek]        # 把第k个样本点的误差计算出来,并存入误差矩阵,有效位置设为1def innerL(i, oS):Ei = calcEk(oS, i)           # KKT条件, 若yi*(w^T * x +b)-1<0 则 ai=C  若yi*(w^T * x +b)-1>0 则 ai=0print("i is {0},Ei is {1}".format(i,Ei))if ((oS.labelMat[i]*Ei < -oS.tol) and (oS.alphas[i] < oS.C)) or ((oS.labelMat[i]*Ei > oS.tol) and (oS.alphas[i] > 0)):j,Ej = selectJ(i,oS,Ei)print("第二个因子的坐标{}".format(j))alphaIold = oS.alphas[i].copy()       # 用了浅拷贝, alphaIold 就是old a1,对应公式alphaJold = oS.alphas[j].copy()if oS.labelMat[i] != oS.labelMat[j]:  # 也是根据公式来的,y1 不等于 y2时L = max(0,oS.alphas[j] - oS.alphas[i])H = min(oS.C, oS.C+oS.alphas[j]-oS.alphas[i])else:L = max(0,oS.alphas[j]+oS.alphas[i]-oS.C)H = min(oS.C,oS.alphas[j]+oS.alphas[i])if L==H:         # 如果这个j让L=H,i和j这两个样本是同一类别,且ai=aj=0或ai=aj=C,或者不同类别,aj=C且ai=0# 当同类别时 ai+aj = 常数 ai是不满足KKT的,假设ai=0,需增大它,那么就得减少aj,aj已经是0了,不能最小了,所以此情况不允许发生# 当不同类别时 ai-aj=常数,ai是不满足KKT的,ai=0,aj=C,ai需增大,它则aj也会变大,但是aj已经是C的不能再大了,故此情况不允许print("L=H")return 0# eta = 2.0*oS.K[i,j]-oS.K[i,i]-oS.K[j,j]   # eta=K11+K22-2*K12eta = 2.0*oS.X[i,:]*oS.X[j,:].T - oS.X[i,:]*oS.X[i,:].T - oS.X[j,:]*oS.X[j,:].Tif eta >= 0:                 # 这里跟公式正好差了一个负号,所以对应公式里的 K11+K22-2*K12 <=0,即开口向下,或为0成一条直线的情况不考虑print("eta>=0")return 0oS.alphas[j]-=oS.labelMat[j]*(Ei-Ej)/eta     # a2^new = a2^old+y2(E1-E2)/etaprint("a2 归约之前是{}".format(oS.alphas[j]))oS.alphas[j]=clipAlpha(oS.alphas[j],H,L)     # 根据公式,看看得到的a2^new是否在上下限之内print("a2 归约之后is {}".format(oS.alphas[j]))# updateEk(oS,j)               # 把更新后的a2^new的E更新一下if abs(oS.alphas[j]-alphaJold)<0.00001:print("j not moving enough")return 0oS.alphas[i] +=oS.labelMat[j]*oS.labelMat[i]*(alphaJold-oS.alphas[j])   # 根据公式a1^new = a1^old+y1*y2*(a2^old-a2^new)print("a1更新之后是{}".format(oS.alphas[i]))# updateEk(oS,i)# b1^new = b1^old+(a1^old-a1^new)y1*K11+(a2^old-a2^new)y2*K12-E1# b1 = oS.b-Ei-oS.labelMat[i]*(oS.alphas[i]-alphaIold)*oS.K[i,i]-oS.labelMat[j]*\#      (oS.alphas[j]-alphaJold)*oS.K[i,j]b1 = oS.b-Ei-oS.labelMat[i]*(oS.alphas[i]-alphaIold)*oS.X[i,:]*oS.X[i,:].T-oS.labelMat[j]* \(oS.alphas[j]-alphaJold)*oS.X[i,:]*oS.X[j,:].T# b2 = oS.b-Ej-oS.labelMat[i]*(oS.alphas[i]-alphaIold)*oS.K[i,j]-oS.labelMat[j]* \#      (oS.alphas[j]-alphaJold)*oS.K[j,j]b2 = oS.b-Ej-oS.labelMat[i]*(oS.alphas[i]-alphaIold)*oS.X[i,:]*oS.X[j,:].T-oS.labelMat[j]* \(oS.alphas[j]-alphaJold)*oS.X[j,:]*oS.X[j,:].TupdateEk(oS,j)          # 个人认为更新误差应在更新b之后,因为公式算出的b的公式使用的是以前的EiupdateEk(oS,i)# b2^new=b2^old+(a1^old-a1^new)y1*K12+(a2^old-a2^new)y2*K22-E2if (0 < oS.alphas[i]) and (oS.C > oS.alphas[i]):oS.b = b1.A[0][0]elif (0<oS.alphas[j]) and (oS.C > oS.alphas[j]):oS.b = b2.A[0][0]else:oS.b = (b1+b2)/2.0print("b is {}".format(oS.b))return 1else:return 0def smoP(dataMatIn, classLabels, C,toler,maxIter,kTup=('lin',)):oS = optStruct(mat(dataMatIn), mat(classLabels).transpose(),C,toler,kTup)iter = 0entireSet = True              # 两种遍历方式交替alphaPairsChanged = 0while (iter<maxIter) and ((alphaPairsChanged>0) or (entireSet)):alphaPairsChanged = 0if entireSet:for i in range(oS.m):alphaPairsChanged += innerL(i,oS)print("fullSet, iter:%d i: %d pairs changed %d"%(iter,i ,alphaPairsChanged))iter+=1print("第一种遍历alphaRairChanged is {}".format(alphaPairsChanged))print("-----------eCache is {}".format(oS.eCache))print("***********alphas is {}".format(oS.alphas))print("---------------------------------------")else:nonBoundIs = nonzero((oS.alphas.A > 0) * (oS.alphas.A < C))[0]  # 这时数组相乘,里面其实是True 和False的数组,得出来的是# 大于0并且小于C的alpha的下标for i in nonBoundIs:alphaPairsChanged += innerL(i,oS)print("non-bound, iter: %d i:%d, pairs changed %d"%(iter,i,alphaPairsChanged))print("第二种遍历alphaPairChanged is {}".format(alphaPairsChanged))iter+=1if entireSet:entireSet = False  # 当第二种遍历方式alpha不再变化,那么继续第一种方式扫描,第一种方式不再变化,此时alphachanged为0且entireSet为false,退出循环elif (alphaPairsChanged==0):entireSet=Trueprint("iteration number: %d"%iter)return oS.b,oS.alphasdef calcWs(alphas,dataArr,classLabels):                # 通过alpha来计算wX = mat(dataArr)labelMat = mat(classLabels).transpose()m,n = shape(X)w = zeros((n,1))for i in range(m):w += multiply(alphas[i]*labelMat[i], X[i,:].T)        # w = sum(ai*yi*xi)return wdef draw_points(dataArr,classlabel, w,b,alphas):myfont = FontProperties(fname='/usr/share/fonts/simhei.ttf')    # 显示中文plt.rcParams['axes.unicode_minus'] = False     # 防止坐标轴的‘-’变为方块m = len(classlabel)red_points_x=[]red_points_y =[]blue_points_x=[]blue_points_y =[]svc_points_x =[]svc_points_y =[]# print(type(alphas))svc_point_index = nonzero((alphas.A>0) * (alphas.A <0.8))[0]svc_points = array(dataArr)[svc_point_index]svc_points_x = [x[0] for x in list(svc_points)]svc_points_y = [x[1] for x in list(svc_points)]print("svc_points_x",svc_points_x)print("svc_points_y",svc_points_y)for i in range(m):if classlabel[i] ==1:red_points_x.append(dataArr[i][0])red_points_y.append(dataArr[i][1])else:blue_points_x.append(dataArr[i][0])blue_points_y.append(dataArr[i][1])fig = plt.figure()                     # 创建画布ax = fig.add_subplot(111)ax.set_title("SVM-Classify")           # 设置图片标题ax.set_xlabel("x")                     # 设置坐标名称ax.set_ylabel("y")ax1=ax.scatter(red_points_x, red_points_y, s=30,c='red', marker='s')   #s是shape大小,c是颜色,marker是形状,'s'代表是正方形,默认'o'是圆圈ax2=ax.scatter(blue_points_x, blue_points_y, s=40,c='green')# ax.set_ylim([-6,5])print("b",b)print("w",w)x = arange(-4.0, 4.0, 0.1)                   # 分界线x范围,步长为0.1# x = arange(-2.0,10.0)if isinstance(b,numpy.matrixlib.defmatrix.matrix):b = b.A[0][0]y = (-b-w[0][0]*x)/w[1][0]    # 直线方程 Ax + By + C = 0ax3,=plt.plot(x,y, 'k')ax4=plt.scatter(svc_points_x,svc_points_y,s=50,c='orange',marker='p')plt.legend([ax1, ax2,ax3,ax4], ["red points","blue points", "decision boundary","support vector"], loc='lower right')         # 标注plt.show()dataArr,labelArr = loadDataSet('/home/zhangqingfeng/test/svm_test_data')
b,alphas = smoP(dataArr,labelArr,0.8,0.001,40)
w=calcWs(alphas,dataArr,labelArr)
draw_points(dataArr,labelArr,w,b,alphas)

可参考数据集

-0.397822   8.058397    -1
0.824839    13.730343   -1
1.507278    5.027866    1
0.099671    6.835839    1
-0.344008   10.717485   -1
1.785928    7.718645    1
-0.918801   11.560217   -1
-0.364009   4.747300    1
-0.841722   4.119083    1
0.490426    1.960539    1
-0.007194   9.075792    -1
0.356107    12.447863   -1
0.342578    12.281162   -1
-0.810823   -1.466018   1
2.530777    6.476801    1
1.296683    11.607559   -1
0.475487    12.040035   -1
-0.783277   11.009725   -1
0.074798    11.023650   -1
-1.337472   0.468339    1
-0.102781   13.763651   -1
-0.147324   2.874846    1
0.518389    9.887035    -1
1.015399    7.571882    -1
-1.658086   -0.027255   1
1.319944    2.171228    1
2.056216    5.019981    1
-0.851633   4.375691    1
-1.510047   6.061992    -1
-1.076637   -3.181888   1
1.821096    10.283990   -1
3.010150    8.401766    1
-1.099458   1.688274    1
-0.834872   -1.733869   1
-0.846637   3.849075    1
1.400102    12.628781   -1
1.752842    5.468166    1
0.078557    0.059736    1
0.089392    -0.715300   1
1.825662    12.693808   -1
0.197445    9.744638    -1
0.126117    0.922311    1
-0.679797   1.220530    1
0.677983    2.556666    1
0.761349    10.693862   -1
-2.168791   0.143632    1
1.388610    9.341997    -1
0.317029    14.739025   -1

数学建模——支持向量机模型详解Python代码相关推荐

  1. 数学建模——线性规划模型详解Python代码

    数学建模--线性规划模型详解Python代码 标准形式为: min z=2X1+3X2+x s.t x1+4x2+2x3>=8 3x1+2x2>=6 x1,x2,x3>=0 上述线性 ...

  2. 数学建模——主成分分析算法详解Python代码

    数学建模--主成分分析算法详解Python代码 import matplotlib.pyplot as plt #加载matplotlib用于数据的可视化 from sklearn.decomposi ...

  3. 数学建模——智能优化之模拟退火模型详解Python代码

    数学建模--智能优化之模拟退火模型详解Python代码 #本功能实现最小值的求解#from matplotlib import pyplot as plt import numpy as np imp ...

  4. 数学建模——智能优化之粒子群模型详解Python代码

    数学建模--智能优化之粒子群模型详解Python代码 import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplo ...

  5. 数学建模——一维、二维插值模型详解Python代码

    数学建模--一维.二维插值模型详解Python代码 一.一维插值 # -*-coding:utf-8 -*- import numpy as np from scipy import interpol ...

  6. 数学建模_随机森林分类模型详解Python代码

    数学建模_随机森林分类模型详解Python代码 随机森林需要调整的参数有: (1) 决策树的个数 (2) 特征属性的个数 (3) 递归次数(即决策树的深度)''' from numpy import ...

  7. 【自然语言处理】Word2Vec 词向量模型详解 + Python代码实战

    文章目录 一.词向量引入 二.词向量模型 三.训练数据构建 四.不同模型对比 4.1 CBOW 4.2 Skip-gram 模型 4.3 CBOW 和 Skip-gram 对比 五.词向量训练过程 5 ...

  8. 数学建模——智能优化之遗传算法详解Python代码

    数学建模--智能优化之遗传算法详解Python代码 import numpy as np import matplotlib.pyplot as plt from matplotlib import ...

  9. 一文速学数模-时序预测模型(四)二次指数平滑法和三次指数平滑法详解+Python代码实现

    目录 前言 二次指数平滑法(Holt's linear trend method) 1.定义 2.公式 二次指数平滑值: 二次指数平滑数学模型: 3.案例实现 三次指数平滑法(Holt-Winters ...

最新文章

  1. 基于LODOP的打印
  2. 继续昨日计划: 2022-2-16
  3. 如何从命令行重新加载.bash_profile?
  4. 基础二(格式化字符串、运算符和编码)
  5. 华为 connect大会2020_英诺森ProcessGo机器人亮相2019华为CONNECT大会
  6. MAT之NN:实现BP神经网络的回归拟合,基于近红外光谱的汽油辛烷值含量预测结果对比
  7. [BUUCTF-pwn]——ciscn_2019_es_2(内涵peak小知识)
  8. CSS之media Query
  9. HTTP系列学习(笔记三):HTTP的发展历程思维导图
  10. (33)SystemVerilog语言编写二分频
  11. ISE_FIFO_IP核接口测试(二)
  12. android 删除wifi文件,如何删除无线配置文件
  13. Telepresence修改完善心得
  14. speedoffice(Excel)如何隐藏编辑栏
  15. 4.3-python爬虫之图形验证码识别
  16. steam怎么共享计算机游戏,steam怎么共享游戏给好友?steam向好友共享游戏教程
  17. C/C++ EasyX 立方体与超立方体的投影 与 伸缩和旋转变换
  18. android手机电池寿命,手机电池寿命检测
  19. 依赖计算机英语作文,过度依赖电脑的危害的英文作文
  20. c语言编程TLC2543AD采集,51单片机驱动12位AD转换TLC2543电路图+程序

热门文章

  1. 重磅|施耐德电气O2O数字化咨询服务强势来袭
  2. 上海临港新片区:新建数据中心CPUE值≤1.25 正建国际互联网数据专用通道
  3. UPS不间断电源常见故障及如何排除故障
  4. android 数组赋值字符串_c++数组使用
  5. 成功解决源路径太长,源文件名长度大于文件系统支持的长度。请尝试将其移动到具有较短路径名称的位置,或者在执行此操作前尝试将其重命名为较短的名称
  6. Matlab:成功解决The option is not valid. The options must be'double','native','default','omitnan', or'inc
  7. Python:Python多种集成开发环境(IDE,编译器)的简介、安装、入门、使用方法之详细攻略
  8. ML之回归预测:以某个数据集为例从0到1深入理解科学预测之回归(实数值年龄预测)问题的思路框架
  9. Dataset之Cityscapes:Cityscapes数据集的简介、安装、使用方法之详细攻略
  10. NLP之TM:基于gensim库调用20newsgr学习doc-topic分布并保存为train-svm-lda.txt、test-svm-lda.txt