这节和上一节很像,不同的是,上一篇的是通过支持向量和待分类数据內积进行分类的,只是这里不同的是,在计算內积时使用核函数进行代替,这里参考的是机器学习实战中的核函数,如果前面理解的比较深入,读代码还是很简单的,这里的代码建议不要刚开始就去读核函数定义,建议先从测试核函数的代码读,然后搞清楚核函数的参数都代表什么,同时想想作者为什么这样使用,刚开始理解这些可能有点难,多读几遍,在读代码时建议时刻想着前面的理论,因为代码就是按照前面的理论思路进行写的,最后就是尝试自己写一下,下面的代码关键的地方均已注释,上代码:

先把结果贴出来:

fullSet, iter: 8 i:97, pairs changed 0
fullSet, iter: 8 i:98, pairs changed 0
fullSet, iter: 8 i:99, pairs changed 0
iteration number: 9
there are 18 Support Vectors
the training error rate is: 0.000000
the test error rate is: 0.050000

源码:

#!/usr/bin/env/python
# -*- coding: utf-8 -*-
# Author: 赵守风
# File name: kernelfunction.py
# Time:2018/10/25
# Email:1583769112@qq.com
from numpy import *
import numpy as np
from SMO_simplify import *# 其实这里看定义函数有点不好理解,虽然理论大家都知道,但是实现方式可以由很多种,大家可以先看看这个函数是
# 如何调用的即核函数测试,就知道这个函数的参数的意义,下面我把测试关键代码拿过来便于分析
'''
dataArr,labelArr = loadDataSet('testSetRBF.txt')
b,alphas = smoP(dataArr, labelArr, 200, 0.0001, 10000, ('rbf', k1)) #C=200 important
datMat=mat(dataArr); labelMat = mat(labelArr).transpose()
svInd=nonzero(alphas.A>0)[0]
sVs=datMat[svInd] #get matrix of only support vectors
labelSV = labelMat[svInd];
for i in range(m):kernelEval = kernelTrans(sVs,datMat[i,:],('rbf', k1))predict=kernelEval.T * multiply(labelSV,alphas[svInd]) + bif sign(predict)!=sign(labelArr[i]): errorCount += 1
'''
# kernelEval = kernelTrans(sVs,datMat[i,:],('rbf', k1))
# 从这一句我们看到传入的第一个参数X就是sVs,往上追溯可知这是参与內积的训练数据点即支持向量
# 第二个参数A,传入的是datMat[i:0],传入的是一条数据,即待分类的一个数据,原因是每个待分类的数据都需要和支持向量相內积
# kTup[0]第一个元素是选择核函数类型的参数,第二个kTup[1]就更简单了,其实就是径向基的那个参数,大家看这个就懂了
#   K = exp(K / (-1 * kTup[1] ** 2))
def kernelTrans(X, A, kTup):  # calc the kernel or transform data to a higher dimensional spacem, n = np.shape(X)K = np.mat(np.zeros((m, 1)))if kTup[0] == 'lin':K = X * A.T  # linear kernelelif kTup[0] == 'rbf':for j in range(m):deltaRow = X[j, :] - AK[j] = deltaRow * deltaRow.TK = np.exp(K / (-1 * kTup[1] ** 2))  # divide in NumPy is element-wise not matrix like Matlabelse:raise NameError('Houston We Have a Problem -- \That Kernel is not recognized')return Kclass optStruct:def __init__(self, dataMatIn, classLabels, C, toler, kTup):  # Initialize the structure with the parametersself.X = dataMatInself.labelMat = classLabelsself.C = Cself.tol = tolerself.m = np.shape(dataMatIn)[0]self.alphas = np.mat(zeros((self.m, 1)))self.b = 0self.eCache = np.mat(zeros((self.m, 2)))  # first column is valid flagself.K = np.mat(zeros((self.m, self.m)))for i in range(self.m):  # 调用核函数处理self.K[:, i] = kernelTrans(self.X, self.X[i, :], kTup)def calcEk(oS, k):fXk = float(np.multiply(oS.alphas, oS.labelMat).T * oS.K[:, k] + oS.b)Ek = fXk - float(oS.labelMat[k])return Ek# 内循环调选第二个alpha的策略
def selectJ(i, oS, Ei):  # this is the second choice -heurstic, and calcs EjmaxK = -1;maxDeltaE = 0;Ej = 0oS.eCache[i] = [1, Ei]  # set valid #choose the alpha that gives the maximum delta EvalidEcacheList = np.nonzero(oS.eCache[:, 0].A)[0] # 这个大家还记的啥意思吧,不解释了,不会的翻看前面的看if (len(validEcacheList)) > 1:for k in validEcacheList:  # loop through valid Ecache values and find the one that maximizes delta Eif k == i: continue  # don't calc for i, waste of timeEk = calcEk(oS, k)deltaE = np.abs(Ei - Ek)if (deltaE > maxDeltaE):maxK = kmaxDeltaE = deltaEEj = Ekreturn maxK, Ejelse:  # in this case (first time around) we don't have any valid eCache valuesj = selectJrand(i, oS.m)Ej = calcEk(oS, j)return j, Ejdef updateEk(oS, k):  # after any alpha has changed update the new value in the cacheEk = calcEk(oS, k)oS.eCache[k] = [1, Ek]# 内循环
def innerL(i, oS):Ei = calcEk(oS, i)  # 和前面的一样,Ei为第一个alpha的差值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)  # 调选第二个参数alphaIold = oS.alphas[i].copy()alphaJold = oS.alphas[j].copy()# 加入约束if (oS.labelMat[i] != oS.labelMat[j]):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:print("L==H")return 0# 这里就开始使用核函数了,2K12-K11-K22,这些都是核函数,在这里他就是通过调用核函数,而以前的是直接数据內积eta = 2.0 * oS.K[i, j] - oS.K[i, i] - oS.K[j, j]  # changed for kernelif eta >= 0:print("eta>=0")return 0# 更新alpha值oS.alphas[j] -= oS.labelMat[j] * (Ei - Ej) / etaoS.alphas[j] = clipAlpha(oS.alphas[j], H, L)updateEk(oS, j)  # 更新缓存if (abs(oS.alphas[j] - alphaJold) < 0.00001):print("j not moving enough")return 0# 更新另外一个alphaoS.alphas[i] += oS.labelMat[j] * oS.labelMat[i] * (alphaJold - oS.alphas[j])  # update i by the same amount as jupdateEk(oS, i)  # 更新缓存                    #the update is in the oppostie direction# 计算b值,同时计算b值也使用到了核函数,大家看代码的时候,时刻回忆前面的理论分析过程,每一句代码都和理论保持同步# 这样多看,多理解几次,思路就顺了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]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]if (0 < oS.alphas[i]) and (oS.C > oS.alphas[i]):oS.b = b1elif (0 < oS.alphas[j]) and (oS.C > oS.alphas[j]):oS.b = b2else:oS.b = (b1 + b2) / 2.0return 1else:return 0# 参数大多数和线性一样的,只是增加了一个kTup即可以选择线性lin也可以选择核函数rbf
def smoP(dataMatIn, classLabels, C, toler, maxIter, kTup=('lin', 0)):  # full Platt SMO# kTup参数主要是传给自定义的类,后面使用oS = optStruct(np.mat(dataMatIn), np.mat(classLabels).transpose(), C, toler, kTup)iter = 0entireSet = TruealphaPairsChanged = 0while (iter < maxIter) and ((alphaPairsChanged > 0) or (entireSet)):alphaPairsChanged = 0if entireSet:  # go over allfor i in range(oS.m):  # 外循环,遍历所有alppha参数即第一个alpha参数alphaPairsChanged += innerL(i, oS)  # 调用内循环,寻找是Ei-Ej差值最大的E,同时在inner使用核函数print("fullSet, iter: %d i:%d, pairs changed %d" % (iter, i, alphaPairsChanged))iter += 1else:  # go over non-bound (railed) alphasnonBoundIs = np.nonzero((oS.alphas.A > 0) * (oS.alphas.A < C))[0]for i in nonBoundIs:alphaPairsChanged += innerL(i, oS)print("non-bound, iter: %d i:%d, pairs changed %d" % (iter, i, alphaPairsChanged))iter += 1if entireSet:entireSet = False  # toggle entire set loopelif (alphaPairsChanged == 0):entireSet = Trueprint("iteration number: %d" % iter)return oS.b, oS.alphas# 这个和前面是一样的,其实就是计算w
def calcWs(alphas, dataArr, classLabels):X = np.mat(dataArr)labelMat = np.mat(classLabels).transpose()m, n = np.shape(X)w = np.zeros((n, 1))for i in range(m):w += np.multiply(alphas[i] * labelMat[i], X[i, :].T)return wdef testRbf(k1=1.3):dataArr, labelArr = loadDataSet('testSetRBF.txt')  # 读取数据# 计算 b和alphab, alphas = smoP(dataArr, labelArr, 200, 0.0001, 10000, ('rbf', k1))  # C=200 importantdatMat = np.mat(dataArr);labelMat = np.mat(labelArr).transpose()svInd = np.nonzero(alphas.A > 0)[0]sVs = datMat[svInd]  # get matrix of only support vectorslabelSV = labelMat[svInd];print("there are %d Support Vectors" % np.shape(sVs)[0])m, n = np.shape(datMat)errorCount = 0for i in range(m):kernelEval = kernelTrans(sVs, datMat[i, :], ('rbf', k1))predict = kernelEval.T * multiply(labelSV, alphas[svInd]) + bif sign(predict) != sign(labelArr[i]): errorCount += 1print("the training error rate is: %f" % (float(errorCount) / m))dataArr, labelArr = loadDataSet('testSetRBF2.txt')errorCount = 0datMat = np.mat(dataArr);labelMat = np.mat(labelArr).transpose()m, n = np.shape(datMat)for i in range(m):kernelEval = kernelTrans(sVs, datMat[i, :], ('rbf', k1))predict = kernelEval.T * np.multiply(labelSV, alphas[svInd]) + bif np.sign(predict) != np.sign(labelArr[i]): errorCount += 1print("the test error rate is: %f" % (float(errorCount) / m))

机器学习--支持向量机实战(四)核函数实现相关推荐

  1. 机器学习--支持向量机(四)SMO算法详解

    上篇我们讲到,线性和非线性都转化为求解的问题即: 求解的方法就是SMO算法,下面详细介绍SMO算法: 在讲解SMO算法之前先说明一下讲解思路,首先先帮助大家理解这个式子,说明推倒的过程细节,然后和原论 ...

  2. 机器学习--支持向量机实战(三)完整版SMO算法实现

    完整版和简化版的smo不通之处在于alpha的选择方式上,alpha的更改和代数运算和简化版本,完整版的alpha的选择方式采用了启发式进行选择,前面文章已经详解了,这里再简单的叙述一下: Platt ...

  3. 机器学习--支持向量机实战(二)简易SMO算法实现

    该简易算法其实完成的任务很简单,就是违反KKT条件的alpha进行符合KKT条件,然后通过不在边界的点进行迭代,然后使其alpha稳定下来下面的代码基本每一句都进行了详细的解释,具体看代码,但是建议没 ...

  4. 【机器学习】支持向量机实战项目:水果分类器优化

    支持向量机实战项目:水果分类器优化 利用支持向量机水果分类的完善 手动反爬虫: 原博地址 https://blog.csdn.net/lys_828/article/details/122648245 ...

  5. 机器学习算法 08 —— 支持向量机SVM算法(核函数、手写数字识别案例)

    文章目录 系列文章 支持向量机SVM算法 1 SVM算法简介 1.1 引入 1.2 算法定义 2 SVM算法原理 2.1 线性可分支持向量机 2.2 SVM计算过程与算法步骤(有点难,我也没理解透,建 ...

  6. 【机器学习PAI实战】—— 玩转人工智能之综述

    摘要: 基于人工智能火热的大背景下,通过阿里云的机器学习平台PAI在真实场景中的应用,详细阐述相关算法及使用方法,力求能够让读者读后能够马上动手利用PAI搭建属于自己的机器学习实用方案,真正利用PAI ...

  7. 【机器学习】实战系列五——天文数据挖掘实验(天池比赛)

    系列文章目录 学习笔记: [机器学习]第一章--机器学习分类和性能度量 [机器学习]第二章--EM(期望最大化)算法 [机器学习]第六章--概率无向图模型 实战系列: [机器学习]实战系列一--波士顿 ...

  8. python机器学习——支持向量机回归与波士顿房价案例

    支持向量机回归与波士顿房价案例 一.从传统回归模型到支持向量回归模型 二.核函数 三.常用的几种核函数 四.SVM 算法的优缺点 五.建模实例 (1)导入数据 (2)划分训练集测试集 (3)数据标准化 ...

  9. 周志华机器学习-支持向量机

    周志华机器学习-支持向量机 第一章 绪论 第二章 模型评估与选择 第三章 线性模型 第四章 决策树 第五章 支持向量机 第六章 神经网络 第七章 贝叶斯分类器 第八章 集成学习和聚类 – 文章目录 周 ...

最新文章

  1. mysql整理碎片和显示语句错误
  2. 测试openstack neutron的网络连通性
  3. 【自动化__持续集成】___java___重载
  4. C语言断言assert()函数
  5. SAP Spartacus 从 Ngrx 里获取 navigation 的实时状态
  6. java课程之团队开发第一阶段评论
  7. 宝藏好物gRPCurl
  8. [转]宝文!Apple Push Notification Service (APNS)原理与实现方案
  9. Madagascar编程的Makefile文件配置
  10. Javascript ES6 Set、Map、Proxy、Symbol
  11. html监控服务器状态,HTML5-WebSocket实现对服务器CPU实时监控
  12. matlab 散点图 对数,matlab – 对数 – 对数散点图上的半透明标记
  13. mysql统计姓名为_MySQL统计所有成绩都在90分的姓名
  14. 记录Windows11系统出现的一次蓝屏收集错误信息重启的问题
  15. xson 1.0.2 发布,新增byte[] buffer,支持XCO
  16. 五、 Usb setting 中tethering 设置流程
  17. JavaWeb酒店管理系统
  18. 输入数值n,计算并输出下列多项式的值:S = 1 + 1/1! + 1/2! + 1/3! + 1/4! + ... + 1/n!
  19. 可视化展示——论文相似度分析页面设计
  20. 微信分享到朋友圈的链接没有图片。开发工具中正常没有报错-解决方案

热门文章

  1. Q80:平坦着色(Flat Shading)和平滑着色(Smooth Shading)——“Q79:怎么用三角形网格(Triangle Mesh)细分曲面”(补充)
  2. vue 同步加载_vue axios同步请求解决方案
  3. 大数据分析是如何工作
  4. 大数据分析需备哪些技能
  5. 物联网大数据平台具备哪些功能
  6. 使用大数据分析需要注意什么因素
  7. 移动物联卡资费标准是如何的
  8. 二手轻型载货车报价图片_业主坐地提价, 新房抢客, 10月广州二手房成交跌了24%...
  9. mysql 多表并列查询_Mysql多表查询(两张独立表,一张关系表)
  10. Spark提交代码的两种方式