机器学习教程 之 支持向量机:代码篇(二分类、非线性、软间隔)
来源:互联网 发布:计算机的算法都有哪些 编辑:程序博客网 时间:2024/06/07 01:59
这里是支持向量机的python3代码,考虑了非线性分类与软间隔问题,支持二分类数据集,关于支持向量机的原理,等有空再整理写出
#!/usr/bin/env python3# -*-coding: utf-8-*-# Author : LiangjunFeng# Blog : http://my.csdn.net/Liangjun_Feng# GitHub : https://www.github.com/LiangjunFeng# File : support_vector_machine.py# Date : 2017/09/21 11:12# Version: 0.1# Description: support_vector_machineimport numpyimport cvxoptimport matplotlib.pyplot as pltdef linearKernel(x1,x2): #线性核函数 return numpy.dot(x1,x2)def gaussianKernel(x1,x2,sigma = 3): #高斯核函数 return numpy.exp(-numpy.linalg.norm(x1-x2)**2/(2*(sigma ** 2)))def makeKernelMatrix(input_,kernel,par = 3): #根据核函数核输入数据,创建核矩阵 num = input_.shape[0] K = numpy.zeros((num,num)) for i in range(num): for j in range(num): if kernel == 'linearKernel': K[i,j] = linearKernel(input_[i],input_[j]) else: K[i,j] = gaussianKernel(input_[i],input_[j],par) return Kdef calculateA(input_,label,C,K): #利用cvxopt求解拉格朗日乘法子 num = input_.shape[0] P = cvxopt.matrix(numpy.outer(label,label)*K) q = cvxopt.matrix(numpy.ones(num)*-1) A = cvxopt.matrix(label,(1,num)) b = cvxopt.matrix(0.0) if C is None: G = cvxopt.matrix(numpy.diag(numpy.ones(num)*-1)) h = cvxopt.matrix(numpy.zeros(num)) else: temp1 = numpy.diag(numpy.ones(num)*-1) temp2 = bp.identity(num) G = cvxopt.matrix(numpy.vstack(temp1,temp2)) temp1 = numpy.zeros(num) temp2 = numpy.ones(num)*self.C h = cvxopt.matrix(numpy.hstack(temp1,temp2)) #P\q\A\b\G\h均为规划参数 solution = cvxopt.solvers.qp(P,q,G,h,A,b) #解模型 a = numpy.ravel(solution['x']) #利用ravel函数将a转化为1维向量 return adef calculateB(a,supportVectorLabel,supportVector,K,indexis): #计算模型偏置b b = 0 for i in range(len(a)): b += supportVectorLabel[i] b -= numpy.sum(a*supportVectorLabel*K[indexis[i],supportVector]) b /= len(a) #求解所有输入例的偏差均值为b return bdef calculateWeight(kernel,features,a,supportVector,supportVectorLabel): #计算模型权重w if kernel == linearKernel: #线性核时按线性方式计算w w = numpy.zeros(features) for i in range(len(a)): w += a[i]*supportVectorLabel[i]*supportVector[i] else: #非线性核无需计算后面会直接根据核矩阵算出结果 w = None return wclass SVM: def __init__(self,kernel = linearKernel,C = None): #初始化 self.kernel = kernel self.C = C self.a = None self.b = 0 self.w = [] self.supportVector = [] self.supportVectorLabel = [] if self.C is not None: self.C = float(self.C) def fit(self,input_,label): #拟合函数 samples,features = input_.shape K = makeKernelMatrix(input_,self.kernel) #计算核矩阵 a = calculateA(input_,label,self.C,K) #计算拉格朗日乘法子 supportVector = a > 1e-5 #小于1e-5的a判定为0,supportVector为一个boolen型列表,记录哪些数据支持向量 indexis = numpy.arange(len(a))[supportVector] #支持向量的下标 self.a = a[supportVector] #支持向量的a self.supportVector = input_[supportVector] #支持向量 self.supportVectorLabel = label[supportVector] #支持向量的标签 print(len(self.a),' support vectors out of ',samples,' points') self.b = calculateB(self.a,self.supportVectorLabel,supportVector,K,indexis) #计算模型偏置b self.w = calculateWeight(self.kernel,features,self.a,self.supportVector,self.supportVectorLabel) #计算权重w def predict(self,input_): #预测分类函数 if self.w is not None: return numpy.dot(inpt_,self.w) + self.b else: predictLabel = numpy.zeros(len(input_)) for i in range(len(input_)): s = 0 for a,sv_y,sv in zip(self.a,self.supportVectorLabel,self.supportVector): s += a * sv_y * self.kernel(input_[i],sv) predictLabel[i] = s return numpy.sign(predictLabel+self.b)def gen_non_lin_separable_data(): #产生一组数据 mean1 = [-1, 2] mean2 = [1, -1] mean3 = [4, -4] mean4 = [-4, 4] cov = [[1.0,0.8], [0.8, 1.0]] X1 = numpy.random.multivariate_normal(mean1, cov, 60) X1 = numpy.vstack((X1, numpy.random.multivariate_normal(mean3, cov, 60))) y1 = numpy.ones(len(X1)) X2 = numpy.random.multivariate_normal(mean2, cov, 60) X2 = numpy.vstack((X2, numpy.random.multivariate_normal(mean4, cov, 60))) y2 = numpy.ones(len(X2)) * -1 return X1, y1, X2, y2 def split_train(X1, y1, X2, y2): #从产生的数据中分出训练集 X1_train = X1[:90] y1_train = y1[:90] X2_train = X2[:90] y2_train = y2[:90] X_train = numpy.vstack((X1_train, X2_train)) y_train = numpy.hstack((y1_train, y2_train)) return X_train, y_traindef split_test(X1, y1, X2, y2): #从产生的数据中分出测试集 X1_test = X1[90:] y1_test = y1[90:] X2_test = X2[90:] y2_test = y2[90:] X_test = numpy.vstack((X1_test, X2_test)) y_test = numpy.hstack((y1_test, y2_test)) return X_test, y_test def test_non_linear(): #测试非线性分类,gauss核 X1, y1, X2, y2 = gen_non_lin_separable_data() X_train, y_train = split_train(X1, y1, X2, y2) print(y_train,'$$$') X_test, y_test = split_test(X1, y1, X2, y2) clf = SVM(gaussianKernel) X_train = numpy.array(X_train) y_train = numpy.array(y_train) print(y_train,'$$$') clf.fit(X_train, y_train) y_predict = clf.predict(X_test) plt.title('scatter diagram') for i in range(len(X_test)): if y_predict[i] == 1: plt.plot(X_test[i,0],X_test[i,1],'ro') else: plt.plot(X_test[i,0],X_test[i,1],'go') plt.show()if __name__ == "__main__": test_non_linear()
测试结果
有什么不明白的地方欢迎打扰
阅读全文
0 0
- 机器学习教程 之 支持向量机:代码篇(二分类、非线性、软间隔)
- 机器学习教程 之 支持向量机:模型篇1—支持向量与间隔
- 公开课机器学习笔记(12)支持向量机二 最优间隔分类器
- Python3《机器学习实战》学习笔记(九):支持向量机实战篇之再撕非线性SVM
- 学习SVM(二) 如何理解支持向量机的最大分类间隔
- 【机器学习】机器学习(七、八):SVM(支持向量机)【最优间隔分类、顺序最小优化算法】
- 【机器学习基础】软间隔支持向量机
- 【机器学习基础】软间隔支持向量机
- 机器学习之支持向量机SVM Support Vector Machine (二) 非线性SVM模型与核函数
- 机器学习(7)——支持向量机(二):线性可分支持向量机到非线性支持向量机
- 机器学习——支持向量机SVM之软间隔与正则化
- 【机器学习】推导支持向量机SVM二分类
- 机器学习(7)——支持向量机(三):线性支持向量机和软间隔最大化
- 公开课机器学习笔记(14)支持向量机四 软间隔松弛变量
- 机器学习----支持向量机(软间隔与正则化)
- 支持向量机之非线性支持向量机(四)
- 支持向量机系列之最大间隔分类器
- 机器学习分类篇-支持向量机SVM上
- 《C++ Concurrency in Action》笔记12 boost::shared_mutex
- 欢迎使用CSDN-markdown编辑器
- HDU 1495 BFS+模拟
- c++面试经验
- 安装plsqldeveloper遇到的问题
- 机器学习教程 之 支持向量机:代码篇(二分类、非线性、软间隔)
- ENIAC的历程
- 移动端身份证扫描识别说明
- Jquery对ajax的支持
- vue-cli 配置路由>>跳转传递参数
- OTcl和C++的区别
- Linux下文件删除的原理
- 基础问题积累
- 文章标题