Day3多元线性回归100天搞定机器学习|Day4-6逻辑回归100天搞定机器学习|Day7K-NN100天搞定机器学习|Day8逻辑的数学原理regression100天搞定机器学习|Day9-12supportVectormachine100天搞定机器学习|Day11KNN100天搞定机器学习|Day13-14SVM100天搞定机器学习|Day15NaiveBayesian100天搞定机器学习|Day16通过核技术实现SVM先说需求,你需要对svm算法熟悉到什么程度?这里引用七月在线创始人七月的微博:对SVM有一定的了解后,确实可以从头到尾在脑海中推导出相关公式。初始分类函数,最大分类Interval,max1/||w||,min1/2||w||^2,凸二次规划,拉格朗日函数,转化为对偶问题,SMO算法,都是为了求一个最优解决方案,一个最佳的优秀分类平面。一步步梳理,为什么是这个为什么是那个,太多的东西可以追寻,最终实现。sklearn.svmSklearn中包含的常用算法介绍了常用的算法。scikit-learn中学习模式的调用具有很强的统一性。调用机器学习的方法是一样的。该算法是一个类,包含了fit()、predict()等多种方法,我们只需要输入训练样本和标签,以及模型可能的一些参数,就可以直接得到分类结果。可以概括为8个字:Import-Modeling-Training-Prediction先看一个小例子,再详细解释。将numpy导入为npX=np.array([[-1,-1],[-2,-1],[1,1],[2,1]])y=np.array([1,1,2,2])fromsklearn.svmimportNuSVCclf=NuSVC()clf.fit(X,y)print(clf.fit(X,y))NuSVC(cache_size=200,class_weight=无,coef0=0.0,decision_function_shape='ovr',degree=3,gamma='auto',kernel='rbf',max_iter=-1,nu=0.5,probability=False,random_state=None,shrinking=True,tol=0.001,verbose=False)print(clf.predict([[-0.8,-1]]))[1]更多情况可以移步scikit-learn官网https://scikit-learn.org/stab...scikit-learnSVM中SVM的算法库分为两大类,一类是分类算法库,包括SVC、NuSVC、LinearSVC。另一个是回归算法库,包括SVR、NuSVR、LinearSVR3类。相关类包含在sklearn.svm模块中。对于SVC、NuSVC、LinearSVC这三个类别,SVC与NuSVC类似,唯一不同的是loss的度量方式不同,而LinearSVC从名字就可以看出,它是一种线性分类,即对不支持各种低维、高维核函数,只支持线性核函数,不能用于线性不可分的数据。同理,对于SVR、NuSVR、LinearSVR这三个回归类,SVR和NuSVR也很相似,区别只是loss的度量方式不同。LinearSVR是线性回归,只能使用线性核函数。简单说一下SVC的详细用法。NuSVC和LinearSVC建议大家看一下刘建平Pinard@cnblogs的统计表https://www.cnblogs.com/pinar...SVC函数中有14个参数:SVC参数解释(一)C:目标函数的惩罚系数C,用于平衡分类区间的margin和误分类的样本,默认C=1.0;(2)kernel:参数选择包括RBF,Linear,Poly,Sigmoid,默认为"RBF";(3)degree:如果参数2选择'Poly',这个有效,degree决定了最高次幂多项式;(4)gamma:核函数('Poly','RBF'and'Sigmoid')的系数,默认gamma=1/n_features;(5)coef0:核函数中的独立项,'RBF'和'Poly'有效;(6)probablity:是否使用概率估计(trueorfalse);(7)shrinking:是否进行启发式;(8)tol(default=1e-3):svm端标准的精度;(9)cache_size:训练所需的内存(以MB为单位);(10)class_weight:每个类所占的权重,不同的类设置不同的惩罚参数C,默认是自适应的;(11)verbose:与多线程有关;(12)max_iter:最大迭代次数,默认=1,如果max_iter=-1,不限制;(13)decision_function_shape:'ovo'一对一,'ovr'多对多或无,默认=无。(14)random_state:用于概率估计种子的数据重排的伪随机数生成器。如何选择核函数1)线性核函数(LinearKernel)的表达式为:K(x,z)=x?z,即普通内积,只能用于LinearSVC和LinearSVR。2)多项式核函数(PolynomialKernel)是线性不可分SVM常用的核函数之一。3)高斯核(GaussianKernel),在SVM中也称为径向基函数(RBF),是libsvm默认的核函数,当然也是scikit-learn的默认核函数。表达式为:其中,γ大于0,需要通过调整参数来定义。4)Sigmoid核函数(SigmoidKernel)也是线性不可分SVM常用的核函数之一,表达式为:其中,γ和r需要自己定义参数。更多案例可以去scikit-learn官网查看。最常用的核函数是Linear和RBF。应该注意的是数据是标准化的。1.线性:主要用于线性可分的场合。参数少,速度快。对于一般数据,分类效果已经很理想了。2.RBF:主要用于线性不可分的情况。参数很多,分类结果对参数的依赖性很大。吴恩达也给出了选择核函数的方法:1、如果特征个数较多,与样本个数相近,则选择LR或LinearKernelSVM。2.如果特征个数比较少,样本个数一般,不是太大也不是太小,选择SVM+GaussianKernel3.如果特征个数比较少,但样本个数很大,需要手动添加一些特征,成为第一种情况。KernelTrick实现svm04的主要思想和算法流程来自李航和之前推荐的《理解SVM的三重境界》(PDF在文末)#coding=utf-8importtimeimportrandomimportnumpyasnpimportmathimportcopya=np。矩阵([[1.2,3.1,3.1]])#printa.astype(int)#printa.AclassSVM:def__init__(self,data,kernel,maxIter,C,epsilon):self.trainData=dataself.C=C#惩罚因子self.kernel=kernelself.maxIter=maxIterself.epsilon=epsilonself.a=[0foriinrange(len(self.trainData))]self.w=[0foriinrange(len(self.trainData[0][0]))]self.eCache=[[0,0]foriinrange(len(self.trainData))]self.b=0self.xL=[self.trainData[i][0]foriinrange(len(self.trainData))]self.yL=[self.trainData[i][1]foriinrange(len(self.trainData))]deftrain(self):#support_Vector=self.__SMO()self.__SMO()self.__update()def__kernel(self,A,B):#核函数将输入向量从低维转化为高维res=0ifself.kernel=='Line':res=self.__Tdot(A,B)elifself.kernel[0]=='Gauss':K=0forminrange(len(A)):K+=(A[m]-B[m])**2res=math.exp(-0.5*K/(self.kernel[1]**2))返回resdef__Tdot(self,A,B):res=0forkinrange(len(A)):res+=A[k]*B[k]returnresdef__SMO(self):#SMO是一种基于KKT条件迭代求解优化问题的算法#SMO是SVM核心算法support_Vector=[]self.a=[0foriinrange(len(self.trainData))]pre_a=copy.deepcopy(self.a)foritinrange(self.maxIter):flag=1为范围内的我(len(self.xL)):#printself.a#更新self.a实战中使用机器学习的求解思路#计算jupdatediff=0self.__update()#选择误差最大的j丹麦技术大学的算法是在数据上循环setforj,随便选i显然效率不高#机器学习实战币书表达式普通代码乱码,有错误。启发式搜索Ei=self.__calE(self.xL[i],self.yL[i])j,Ej=self.__chooseJ(i,Ei)#计算LH(L,H)=self.__calLH(pre_a,j,i)#思路是先表示self.a[j]唯一变量的函数然后求导(一阶导数=0更新)kij=self.__kernel(self.xL[i],self.xL[i])+self.__kernel(self.xL[j],self.xL[j])-2*self.__kernel(self.xL[i],self.xL[j])#printkij,"aa"if(kij==0):继续self.a[j]=pre_a[j]+float(1.0*self.yL[j]*(Ei-Ej))/kij#下一个session为L,也就是截距,小于0时为0#上一个session为H,最大值,大于H时为Hself.a[j]=min(self.a[j],H)self.a[j]=max(self.a[j],L)#self.a[j]=min(self.a[j],H)#printL,Hself.eCache[j]=[1,self.__calE(self.xL[j],self.yL[j])]self.a[i]=pre_a[i]+self.yL[i]*self.yL[j]*(pre_a[j]-self.a[j])self.eCache[i]=[1,self.__calE(self.xL[i],self.yL[i])]diff=sum([abs(pre_a[m]-self.a[m])forminrange(len(self.a))])#printdiff,pre_a,self.a如果diff
