《深度学习》课件-第3章线性模型_第1页
《深度学习》课件-第3章线性模型_第2页
《深度学习》课件-第3章线性模型_第3页
《深度学习》课件-第3章线性模型_第4页
《深度学习》课件-第3章线性模型_第5页
已阅读5页,还剩80页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

深度学习基础与实例教程线性模型第三章目录02梯度下降算法Gradientdescent01线性回归算法linearregressionalgorithm04逻辑回归logisticregression05SVM算法SupportVectorMachine03过拟合overfitting线性回归算法linearregressionalgorithm3013.1.1线性回归简介4我们将机器学习算法定义为,通过经验以提高计算机程序在某些任务上性能的算法。为了使这个定义更加具体,我们展示一个简单的机器学习示例:线性回归(linearregression)。当我们介绍更多有助于理解机器学习特性的概念时,我们会反复回顾这个示例。3.1.1线性回归简介5

3.1.1线性回归简介6

3.1.1线性回归简介7

3.1.1线性回归简介8通过最后的式子给出解的系统方程被称为正规方程(normalequation),构成了一个简单的机器学习算法。下图展示了线性回归算法的使用示例。其中训练集包括十个数据点,每个数据点包含一个特征。因为只有一个特征,权重向量w也只有一个要学习的参数w1(右图)。左图我们可以观察到线性回归学习w1,从而使得直线y=w1x1能够尽量接近穿过所有的训练点。(右图)标注的点表示由正规方程学习到的w1的值,我们发现它可以最小化训练集上的均方误差。3.1.1线性回归简介9

3.1.2回归算法的评价指标10

梯度下降算法Gradientdescent11023.2梯度下降算法12梯度下降法(Gradientdescent)是一个一阶最优化算法,通常也称为最陡下降法,要使用梯度下降法找到一个函数的局部极小值,必须向函数上当前点对应梯度(或者是近似梯度)的反方向的规定步长距离点进行迭代搜索。如果相反地向梯度正方向迭代进行搜索,则会接近函数的局部极大值点;这个过程则被称为梯度上升法,相反则称之为梯度下降法。机器学习中回归算法的种类很多,例如神经网络回归算法、蚁群回归算法、支持向量机回归算法等,这些都可以在一定程度上达成回归拟合的目的。随机梯度下降算法通过不停地判断和选择当前目标下的最优路径,从而在最短路径下达到最优的结果,继而提高大数据的计算效率。3.2.1算法理解13在机器学习中,随机梯度下降算法的概念类似于这个下山的故事。如图所示。假设你和朋友在一座陌生的山上,突然下起了雨,需要尽快下山。为了快速到达山脚,你们会选择沿着每段路程中坡度最陡的地方下山。朋友因为对地形不熟悉,每走一段路程都会停下来,观察周围的情况,并选择下山的最陡路径。这种方法可以确保在最短的时间内到达山脚,即使途中可能会有些波折和停顿。3.2.1算法理解14类比到随机梯度下降算法,我们希望通过梯度的方向找到损失函数的最小值点,就像选择下山的最陡路径一样。虽然每一步可能不完全准确(朋友停下来观察),但整体上沿着梯度方向前进,可以在迭代中逐渐接近最优解(山脚)。其中,每个点代表每次停顿的地点。在每个停顿点,你们只需选择当前坡度最陡峭的下山路线即可。随机梯度下降算法(StochasticGradientDescent,SGD)与其类似。如果希望使用最快捷的下山方法,那么最直接的办法就是在每下降一个梯度步骤后,找到当前获得的最大坡度继续下降。这正是随机梯度下降算法的基本原理。SGD是一种简单但非常有效的方法,广泛用于支持向量机、逻辑回归等凸损失函数下的线性分类器的学习。此外,SGD已成功应用于文本分类和自然语言处理中常见的大规模和稀疏机器学习问题。值得注意的是,SGD是梯度下降的一种变形形式,既可以用于分类计算,也可以用于回归计算。我们还需注意标准梯度下降法和随机梯度下降法之间的区别。标准梯度下降是在权值更新前汇总所有样本得到的标准梯度,而随机梯度下降则是通过考察每次训练实例来进行权值更新。因为标准梯度下降使用的是准确的梯度,就像是理直气壮地一路走下去;而随机梯度下降使用的是近似的梯度,需要小心翼翼地前行。随机梯度下降算法的优点在于其计算速度快,但缺点是收敛性能相对较差。3.2.2SGD算法理论15

3.2.3案例:波士顿房价预测实战16波士顿房价数据集统计的是20世纪70年代中期波士顿郊区房价的中位数,统计了城镇人均犯罪率、不动产税等共计13个指标,统计出房价,试图能找到那些指标与房价的关系。数据集中一共有506个样本,每个样本包含13个特征信息和实际房价,波士顿房价预测问题目标是给定某地区的特征信息,预测该地区房价,是典型的回归问题(房价是一个连续值)。波士顿房价数据集中主要的指标名称及其含义如表所示。3.2.3案例:波士顿房价预测实战17机器学习库scikit-learn中自带了波士顿房价数据集,可直接加载。房价预测可采用线性回归算法。以下分别采用正规方程和梯度下降两种方法来解决线性回归问题。正规方程和梯度下降的区别如表所示。3.2.3案例:波士顿房价预测实战18fromsklearn.linear_modelimportLinearRegression,SGDRegressorfromsklearn.preprocessingimportStandardScalerfromsklearn.model_selectionimporttrain_test_splitfromsklearn.metricsimportmean_squared_errorimportnumpyasnpimportpandasaspd#加载数据raw_df=pd.read_csv('boston_housing_data.csv').dropna()data=np.array(raw_df.iloc[:,:-1])target=np.array(raw_df.iloc[:,-1])#训练集,测试集拆分X_train,X_test,y_train,y_test=train_test_split(data,target,test_size=0.25)#数据标准化处理#特征值标准化std_x=StandardScaler()X_train=std_x.fit_transform(X_train)X_test=std_x.transform(X_test)#目标值标准化std_y=StandardScaler()y_train=std_y.fit_transform(y_train.reshape(-1,1))y_test=std_y.transform(y_test.reshape(-1,1))#正规方程线性回归预测lr=LinearRegression()lr.fit(X_train,y_train)print(lr.coef_)y_lr_predict=std_y.inverse_transform(lr.predict(X_test))print(y_lr_predict)#梯度下降线性回归预测sgd=SGDRegressor()sgd.fit(X_train,y_train)print(sgd.coef_)y_sgd_predict=std_y.inverse_transform(sgd.predict(X_test).reshape(-1,1))print(y_sgd_predict)#性能评估均方误差lr_mse=mean_squared_error(std_y.inverse_transform(y_test),y_lr_predict)sgd_mse=mean_squared_error(std_y.inverse_transform(y_test),y_sgd_predict)print(lr_mse)#28.97print(sgd_mse)#31.36对应的线性回归程序如下所示。3.2.3案例:波士顿房价预测实战19其中,LinearRegression,SGDRegressor为sklearn库中的两个模型算法,分别对相同的数据集进行训练,mean_squared_error是均方误差,能够反映预测的准确率。通过scikit-learn中的train_test_split函数将数据集随机拆分成训练集与测试集。注意掌握train_test_split函数的参数含义及返回值定义。过拟合ArtificialIntelligenceReferenceFramework20033.3.1过拟合产生的原因21过拟合的主要原因是模型过度复杂或训练数据量不足,导致在训练数据上表现良好但在测试数据上泛化能力不佳。过拟合现象如图所示。3.3.1过拟合产生的原因22

3.3.1过拟合产生的原因23

3.3.2常见线性回归正则化方法24

3.3.2常见线性回归正则化方法25

3.3.3案例:波士顿房价预测正则化实战26

3.3.3案例:波士顿房价预测正则化实战27fromsklearn.model_selectionimporttrain_test_split#引入数据集拆分函数fromsklearn.linear_modelimportRidge#引入Ridge模型importpandasaspdimportnumpyasnp#加载boston数据集raw_df=pd.read_csv('boston_housing_data.csv').dropna()data=np.array(raw_df.iloc[:,:-1])target=np.array(raw_df.iloc[:,-1])#拆分数据集X_train,X_test,y_train,y_test=train_test_split(data,target,test_size=0.25,random_state=66)#构建模型model=Ridge(alpha=10).fit(X_train,y_train)#评估模型train_score=model.score(X_train,y_train)test_score=model.score(X_test,y_test)print('trainscore:{:.2f}'.format(train_score),'\ntestscore:{:.2f}'.format(test_score))trainscore:0.74testscore:0.69Ridge和Lasso回归是在标准线性回归函数中加入正则化项,以降低过拟合现象。Scikit-learn中,模型的评估使用score函数,参数1为输入特征数据,参数2为标签(即实际房价)。score函数是评估模型在数据集上的R2决定系数。R2决定系数越接近于1,表示模型性能越好,通过查看R2系数,可以评估模型在数据集上的拟合效果。如果训练集得分明显高于测试集得分,这可能说明模型过拟合了训练数据。如果两个得分都很低,这可能表明模型欠拟合。理想情况下,训练得分和测试得分都应该较高且接近。运行结果如下所示:逻辑回归logisticregression28043.4.1逻辑回归算法29Logistic回归虽然名字叫回归,但却是一种分类学习方法。使用场景可概括为两方面:第一用来预测,第二寻找因变量的影响因素。逻辑回归(LogisticRegression,LR)又称为逻辑回归分析,是分类和预测算法中的一种。通过历史数据的表现对未来结果发生的概率进行预测。例如,可以将购买的概率设置为因变量,将用户的特征属性,例如性别,年龄,注册时间等设置为自变量。根据特征属性预测购买的概率。逻辑回归与回归分析有很多相似之处,在开始介绍逻辑回归之前我们先来看下回归分析。回归分析用来描述自变量X和因变量Y之间的关系,或者说自变量X对因变量Y的影响程度,并对因变量Y进行预测。其中因变量是我们希望获得的结果,自变量是影响结果的潜在因素,自变量可以有一个,也可以有多个。一个自变量的叫做一元回归分析,超过一个自变量的叫做多元回归分析。3.4.1逻辑回归算法301|21|31|41|51|60|70|80|90|100|11

逻辑回归实际上就是对已有数据进行分析从而判断其结果可能是多少,它可以通过数学公式来表达。假设已有样本数据集如下:3.4.1逻辑回归算法31

3.4.1逻辑回归算法32

3.4.1逻辑回归算法33

3.4.2案例:求职录用情况回归实战34:在熟悉逻辑回归算法的原理上,进行逻辑回归算法的实践。建立一个逻辑回归的模型来预测求职者是否被公司录用。假设现在有一个负责招聘的人,根据两次笔试的结果来决定每个求职人员的录取机会。将之前所有人的笔试成绩的历史数据,用来作为逻辑回归的训练集。对于每个训练例子,包含三个数据,两个笔试成绩和录用决定。因此,需要建立一个分类模型,根据笔试成绩估计录用的概率。1.查看分析数据查看分析数据首先要观察数据的特性,如图所示,一行有两个数据,对应的是两次笔试的成绩。最后的1、0,对应的是录用和未被录用,而中间的几列数据在此次的实验中是无用数据。所有我们需要提取前两列数据和最后一列的数据,用于模型的训练。需求如下实验步骤如下3.4.2案例:求职录用情况回归实战353.4.2案例:求职录用情况回归实战362.数据简单处理importnumpyasnpimportpandasaspdimportmatplotlib.pyplotasplt%matplotlibinline导入本次实验所需要的Numpy、Pandas、Matplotlib三个库,并导入数据,提取前两列和最后一列并且指定新的列名。代码如下:importospath='LogiReg.txt'pdData=pd.read_csv(path,header=None,names=['Exam1','Exam2','Admitted'])pdData.head()目前为止实验结果如图所示:3.4.2案例:求职录用情况回归实战37查看提取后的数据散点分布,根据是否录用作为区分,横轴、竖轴分别对应着两次笔试的成绩,如下所示:positive=pdData[pdData['Admitted']==1]negative=pdData[pdData['Admitted']==0]fig,ax=plt.subplots(figsize=(10,5))ax.scatter(positive['Exam1'],positive["Exam2"],s=30,c='b',marker='o',label="Admitted")ax.scatter(negative['Exam1'],negative["Exam2"],s=30,c='r',marker='x',label="Admitted")ax.legend()ax.set_xlabel("Exam1Score")ax.set_xlabel("Exam2Score")运行结果如图所示:3.4.2案例:求职录用情况回归实战383.Sigmoid函数通过Sigmoid函数,完成数据到概率的映射。创建一个Sigmoid函数,将参数x传入到函数中,通过画图展示来查看函数是否创建完成,如图所示。代码如下:

defsigmoid(z):return1/(1+np.exp(-z))nums=np.arange(-10,10,step=1)fig,ax=plt.subplots(figsize=(12,4))ax.plot(nums,sigmoid(nums),'r')3.4.2案例:求职录用情况回归实战394.Model的建立defmodel(x,w):returnsigmoid(np.dot(x,w.T))pdData.insert(0,"Ones",1)

orig_data=pdData.valuescols=orig_data.shape[1]X=orig_data[:,0:cols-1]y=orig_data[:,cols-1:cols]

theta=np.zeros([1,3])

3.4.2案例:求职录用情况回归实战405.损失函数defcost(x,y,w):left=np.multiply(-y,np.log(model(x,w)))right=np.multiply(1-y,np.log(1-model(x,w)))returnnp.sum(left-right)/(len(x))输出结果为:0.6931471805599453

3.4.2案例:求职录用情况回归实战416.计算梯度计算逻辑回归模型的梯度。代码如下:defgradient(x,y,w):grad=np.zeros(w.shape)error=(model(x,w)-y).ravel()forjinrange(len(w.ravel())):#foreachparmeterterm=np.multiply(error,x[:,j])grad[0,j]=np.sum(term)/len(x)

returngrad3.4.2案例:求职录用情况回归实战427.不同的迭代方式比较接下来进行三种不同梯度下降方法的比较,STOP_ITER根据迭代次数来停止迭代;STOP_COST根据损失值目标函数的变化,如果变化很小则可以停止;STOP_GRAD根据梯度的变化,如果梯度几乎没有变化,则可以停止。代码如下:STOP_ITER=0STOP_COST=1STOP_GRAD=2defstopCriterion(type,value,threshold):iftype==STOP_ITER:returnvalue>thresholdeliftype==STOP_COST:returnabs(value[-1]-value[-2])<thresholdeliftype==STOP_GRAD:returnnp.linalg.norm(value)<threshold对数据进行乱序处理,重新制定x、y的标签,通过Numpy中的random模块实现。代码如下:importnumpy.random#洗牌defshuffleData(data):np.random.shuffle(data)cols=data.shape[1]X=data[:,0:cols-1]y=data[:,cols-1:]returnX,y3.4.2案例:求职录用情况回归实战43向梯度下降传入六个参数,data对应数据;theta对应参数;batchSize指定为1,就是随机梯度下降,指定为总的样本数,就是批量梯度下降,指定为1到总体之间,就是小批量梯度下降;stopType对应停止策略;thresh为策略对应的阈值;alpha为学习率。先对指定的参数进行初始化,再进行计算。求出梯度后,进行梯度下降,对原有的参数进行更新。参数更新后,计算新的损失。通过循环判断是否应该停止。为了显示方便,添加了一个功能形runExpe函数。对值进行初始化,然后进行求解。通过循环判断选择停止策略,最后通过图形输出。3.4.2案例:求职录用情况回归实战44defrunExpe(data,w,batchSize,stopType,thresh,alpha):#importpdb;pdb.set_trace();theta,iter,costs,grad,dur=descent(data,w,batchSize,stopType,thresh,alpha)name="Original"if(data[:,1]>2).sum()>1else"Scaled"name+="data-learningrate:{}-".format(alpha)ifbatchSize==n:strDescType="Gradient"elifbatchSize==1:strDescType="Stochastic"else:strDescType="Mini-batch({})".format(batchSize)name+=strDescType+"descent-Stop:"ifstopType==STOP_ITER:strStop="{}iterations".format(thresh)elifstopType==STOP_COST:strStop="costschange<{}".format(thresh)else:strStop="gradientnorm<{}".format(thresh)name+=strStopprint("***{}\nTheta:{}-Iter:{}-Lastcost:{:03.2f}-Duration:{:03.2f}s".format(name,theta,iter,costs[-1],dur))fig,ax=plt.subplots(figsize=(12,4))ax.plot(np.arange(len(costs)),costs,'r')ax.set_xlabel('Iterations')ax.set_ylabel('Cost')ax.set_title(name.upper()+'-Errorvs.Iteration')returnw指定n值为100的时候,相当于就是基于所有的样本进行梯度下降,指定迭代次数为5000,根据迭代次数来停止。随着迭代次数的增多,Cost逼近于0.63。如图所示。in=100runExpe(orig_data,theta,n,STOP_ITER,thresh=5000,alpha=0.000001)3.4.2案例:求职录用情况回归实战45图形化运行结果为:3.4.2案例:求职录用情况回归实战46runExpe(orig_data,theta,n,STOP_COST,thresh=0.000001,alpha=0.001)根据损失函数,来判断是否停止迭代。如果两次更新之间小于0.000001,则停止迭代。结果显示迭代次数接近11万次,结果更加精确。如图所示。代码如下:3.4.2案例:求职录用情况回归实战478.不同梯度下降方法的比较随机梯度下降,每次只迭代一个样本,速度快,但结果不确定性高,收敛的结果也不是很好。如图所示runExpe(orig_data,theta,1,STOP_ITER,thresh=15000,alpha=0.000002)结果为:Theta:[[-0.002023980.009854630.00075138]]-Iter:15000-Lastcost:0.63-Duration:0.73s3.4.2案例:求职录用情况回归实战48

小批量梯度下降方法,每次只更新选择的一小部分数据。通过数据标准化,将数据按照其属性减去其均值,然后除以其方差。最后得到的结果是,对每个属性来说所有数据都聚集在0附近,方差值为1。fromsklearnimportpreprocessingasppscaled_data=orig_data.copy()scaled_data[:,1:3]=pp.scale(orig_data[:,1:3])runExpe(scaled_data,theta,n,STOP_ITER,thresh=5000,alpha=0.001)相对于之前的梯度下降,这次的结果较好。如图所示:3.4.2案例:求职录用情况回归实战49通过调整迭代方法,增加迭代次数,损失值会下降的更多。代码如下:runExpe(scaled_data,theta,16,STOP_GRAD,thresh=0.002*2,alpha=0.001)3.4.2案例:求职录用情况回归实战50结果已经趋近与0.22。如图所示:3.4.2案例:求职录用情况回归实战519.精度对逻辑回归得到的概率值,转化为类别值。设定阈值为0.5,大于0.5则为1,则被录用,其余为0,则不被录用。将预测值与数据的是否录用进行对比,最后得到逻辑回归的精度。#设定阈值defpredict(x,w):return[1ifx>=0.5else0forxinmodel(x,w)]scaled_X=scaled_data[:,:3]y=scaled_data[:,3]predictions=predict(scaled_x,w)correct=[1if((a==1andb==1)or(a==0andb==0))else0for(a,b)inzip(predictions,y)]accuracy=(sum(map(int,correct))%len(correct))print('accuracy={0}%'.format(accuracy))结果为:accuracy=60%3.4.2案例:求职录用情况回归实战5210.测试输出将数据中的最后十条数据挑选出来,用作输出测试,如图所示:添加一个读取数据的函数,再添加一个测试函数,读入数据后,使用回归系数预测结果。代码如下:3.4.2案例:求职录用情况回归实战53defloadDataSet(df):dataMat=df.values[:,:3]labelMat=df.values[:,3:]returndataMat,labelMattesting_sample=pdData[-10:]defpredict_test():A=[1.17355763,2.84433525,2.61890506]dataArr,labelMat=loadDataSet(testing_sample)h_test=sigmoid(np.mat(dataArr)*np.mat(A).transpose())print(h_test)

predict_test()[[1.][1.][1.][1.][1.][1.][1.][1.][1.][1.]]运行结果为:与原始的数据进行对比后,仅有一个出错,正确率达到90%,远高于之前的测试结果。SVM算法

SupportVectorMachine54053.5.1SVM算法55支持向量机(SVM)是由VladimirN.Vapnik和AlexeyYa.Chervonenkis在1963年提出的。SVM的提出解决了当时在机器学习领域的“维数灾难”,“过学习”等问题。它在机器学习领域可以用于分类和回归。SVM在回归可以解决股票价格回归等问题,但是在回归上SVM还是较为局限,SVM大部分会和分类放在一起。本节主要讲解分类。SVM最初是为二值分类问题设计的,可以非常成功地处理回归(时间序列分析)和模式识别(分类问题、判别分析)等诸多问题,并可推广到预测和综合评价等领域,因此可应用于理科、工科和管理工程等多种学科。3.5.1SVM算法561.线性可分在支持向量机中,希望找到一个超平面来将两类数据分开。对于二维样本,这个超平面是一条直线。我们希望这条直线不仅能分开两类数据,而且能最大化到两类数据中最近点的距离,即最大化“间隔”。比如对于二维样本,分布在二维平面上,此时超平面实际上是一条直线,直线上面是一类,下面是另一类。定义超平面公式为:w为法向量,b为截距,这样的超平面可以有很多个,规定超平面应该是距离两类的最近距离之和最大,因为只有这样才是最优的分类。首先定义样本点x到超平面的距离D:

3.5.1SVM算法57通过最大化这个距离,可以找到一个具有最大间隔的超平面,而SVM的优化目标是找到一个使得间隔最大的超平面,这可以通过最小化实现。假设分类任务共有两个类别,记作,即两个类别分别为y=-1与y=1。在得到f(x)后,可以通过符号函数sng将其映射为分类结果,可表示为:对于正确分类,如果y=1,则需要f(x)>0;如果y=-1,则需要f(x)<0。因此可以将正确分类的情况统一概括为:3.5.1SVM算法58即:为了最大化最小间隔,定义函数间隔(FunctionalMargin)为:定义几何间隔(GeometryMargin)为:为了最大化几何间隔,我们将函数间隔标准化,使得最靠近超平面的点(支持向量)的函数间隔为1,即

:3.5.1SVM算法59为了最大化几何间隔,需要最小化,为了使得算法更稳定,也可最小化,这个优化问题是一个凸二次规划问题,可以通过拉格朗日乘子法和KKT条件求解。通过引入拉格朗日乘子,可以将原始优化问题转化为对偶问题:其中n为样本数量。在约束条件下:通过求解对偶问题,可以得到最优的拉格朗日乘子,进而计算出模型的参数w和b。3.5.1SVM算法602.线性不可分对于线性不可分的情况,可以引入非线性核函数将数据映射到高维空间,使得在该空间中数据线性可分,实现SVM中的非线性分类,此时超平面公式可定义为:其中为映射函数,由于映射函数具有复杂的形式,难以计算其内积,因此可使用核方法,即定义映射函数的内积为核函数(KernelFunction)以回避内积的显式计算,核函数定义为:常见的核函数有:(1)多项式核(PolynomialKernel)其中,c是一个常数,d是多项式的次数,二者都是超参数。3.5.1SVM算法61(2)高斯径向基核(RBFKernel)其中是核宽度参数,用于控制函数复杂度,是超参数。(3)Sigmoid核(SigmoidKernel)其中,ɑ与c都是常数,二者都是超参数。下面通过一个例子来帮助理解SVM。三角和圆是一个二维平面图中被区分的两个不同类别,其分布如图所示。问题是找到分类的决策边界3.5.1SVM算法62从图中可以看出,a线和b线分别是可以满足划分的边界线,它们都可以将三角和圆正确划分出来。除此之外,还有无数条直线可以将其分开。如果要选择一条能够完全反映三角和圆的最优化边界,就需要使用支持向量机。3.5.1SVM算法63所谓最优化边界,指的是能够最公平划分上下区间的线段。正常理解,如果能够找到一条在a线和b线正中间的那条线,就可以将其划分,如图所示。3.5.1SVM算法64公平线(c线)是由a线和b线共同确定的,即a线和b线给定后,c线就可以确定。此种方法的好处在于,只要a线和b线确定,则分类平面确定,其中的改变不受任何数据和噪声的干扰。在图中标明了4个点,据此可以确定a线和b线。这4个关键的点在支持向量机中被称为支持向量。只要确定了支持向量,分类平面即可唯一确定,如图所示。3.5.1SVM算法65这里人为地将图形分成三部分:当f(x)=0时,可以将x认为属于分割面上的点;当f(x)>0时,可以近似地认为f(x)=1,从而将其确定为三角形的分类;当f(x)<0时,可以认为f(x)=-1,将其归为圆形的类。通过上述方法,支持向量机模型最终转化为一般的代数计算问题。将x的值带入公式计算f(x)的值,从而判断x所属的位置。接下来问题就转化为求解方程系数的问题,即如何求得公式中w和b的大小,从而确定公式。此类方法和线性回归求极值的方法类似。这种通过找到支持向量从而获得分类平面的方法称为支持向量机。支持向量机的目的就是通过划分最优平面使不同的类别分开。用图形的形式表示如图所示。3.5.2案例:面部识别应用实战661.训练一个基本的SVM首先导入sklearn,使用datasets中的数据点生成器,自定义数据。设置50个样本点,2个区域,随机状态种子,以及离散程度。离散程度越大越分散,越小越集中。该步骤代码如下:importnumpyasnpimportpandasaspdimportmatplotlib.pyplotaspltfromscipyimportstatsimportseabornassnssns.set()fromsklearn.datasetsimportmake_blobsX,y=make_blobs(n_samples=50,centers=2,random_state=0,cluster_std=0.60)plt.scatter(X[:,0],X[:,1],c=y,s=50,cmap="autumn")plt.show()运行结果如图所示:3.5.2案例:面部识别应用实战67

SVM的目标就是找一条线,使得离这条线最近的样本点,到这条线的距离越远越好。按照如下代码绘制几条直线。xfit=np.linspace(-1,3.5)plt.scatter(X[:,0],X[:,1],c=y,s=50,cmap='autumn')form,b,din[(1,0.65,0.33),(0.5,1.6,0.55),(-0.2,2.9,0.2)]:yfit=m*xfit+bplt.plot(xfit,yfit,'-k')plt.fill_between(xfit,yfit-d,yfit+d,edgecolor='none',color='#AAAAAA',alpha=0.4)plt.xlim(-1,3.5)直线如图所示:3.5.2案例:面部识别应用实战68接下来进行SVM的训练,导入sklearn下的SVC模块,该模块为支持向量机的分类器,代码如下:fromsklearn.svmimportSVCmodel=SVC(kernel='linear')model.fit(X,y)通过绘图函数绘制图表,中间那条线就是决策边界,图中的虚线上有是两个红点和一个黄点,这三个点都是恰好在边界上的点,就是支持向量。绘制图表代码如下:#绘图函数defplot_svc_decision_function(model,ax=None,plot_support=True):"""Plotthedecisionfunctionfora2DSVC"""ifaxisNone:ax=plt.gca()xlim=ax.get_xlim()ylim=ax.get_ylim()

#creategridtoevaluatemodelx=np.linspace(xlim[0],xlim[1],30)y=np.linspace(ylim[0],ylim[1],30)Y,X=np.meshgrid(y,x)xy=np.vstack([X.ravel(),Y.ravel()]).TP=model.decision_function(xy).reshape(X.shape)3.5.2案例:面部识别应用实战69#plotdecisionboundaryandmarginsax.contour(X,Y,P,colors='k',levels=[-1,0,1],alpha=0.5,linestyles=['--','-','--'])

#plotsupportvectorsifplot_support:ax.scatter(model.support_vectors_[:,0],model.support_vectors_[:,1],s=300,linewidth=1,facecolors='none');ax.set_xlim(xlim)ax.set_ylim(ylim)plt.scatter(X[:,0],X[:,1],c=y,s=50,cmap='autumn')plot_svc_decision_function(model);绘制图表效果如图所示:3.5.2案例:面部识别应用实战70在sklearn中,支持向量储存在support_vectors_中。可以调用,把支持向量的坐标显示,如图所示:接下来通过增加样本的数量,来证明决策边界只受支持向量的影响。结果证明,只要支持向量不变,其他数据证明修改都没关系。代码如下所示:3.5.2案例:面部识别应用实战71defplot_svm(N=10,ax=None):X,y=make_blobs(n_samples=200,centers=2,random_state=0,cluster_std=0.60)X=X[:N]y=y[:N]model=SVC(kernel='linear',C=1E10)model.fit(X,y)

ax=axorplt.gca()ax.scatter(X[:,0],X[:,1],c=y,s=50,cmap='autumn')ax.set_xlim(-1,4)ax.set_ylim(-1,6)plot_svc_decision_function(model,ax)fig,ax=plt.subplots(1,2,figsize=(16,6))fig.subplots_adjust(left=0.0625,right=0.95,wspace=0.1)foraxi,Ninzip(ax,[60,120]):plot_svm(N,axi)axi.set_title('N={0}'.format(N))结果如图所示:3.5.2案例:面部识别应用实战722.引入核函数的SVM不能通过线性分割的时候解决问题,可以通过映射到高维来进行分割。fromsklearn.datasets.samples_generatorimportmake_circlesX,y=make_circles(100,factor=.1,noise=.1)clf=SVC(kernel='linear').fit(X,y)plt.scatter(X[:,0],X[:,1],c=y,s=50,cmap='autumn')plot_svc_decision_function(clf,plot_support=False);运行结果如图所示:3.5.2案例:面部识别应用实战73发现线性并不能分割红点和黄点,加入新的维度r,代码如下所示:#加入了新的维度rfrommpl_toolkitsimportmplot3dr=np.exp(-(X**2).sum(1))defplot_3D(elev=30,azim=30,X=X,y=y):ax=plt.subplot(projection='3d')ax.scatter3D(X[:,0],X[:,1],r,c=y,s=50,cmap='autumn')ax.view_init(elev=elev,azim=azim)ax.set_xlabel('x')ax.set_ylabel('y')ax.set_zlabel('r')plot_3D(elev=45,azim=45,X=X,y=y)运行结果如图所示:3.5.2案例:面部识别应用实战74对于SVM则为加入径向基函数,应用高斯变化。将原本的线性转换为非线性,就能够得到支持向量机,代码如下:#加入径向基函数clf=SVC(kernel='rbf',C=1E6)clf.fit(X,y)plt.scatter(X[:,0],X[:,1],c=y,s=50,cmap='autumn')plot_svc_decision_function(clf)plt.scatter(clf.support_vectors_[:,0],clf.support_vectors_[:,1],s=300,lw=1,facecolors='none');运行结果如图所示:3.5.2案例:面部识别应用实战753.调节SVM参数SoftMargin软间隔,其就是对于硬间隔严格的要求,引入一个松弛因子,松弛因子通过C参数来进行调节。当C趋近于无穷大时,意味着分类严格不能有错误;当C趋近于很小的时候,意味着可以有更大的错误容忍。首先,调节数据的离散程度,让红色的点和黄色的点贴近。代码如下:X,y=make_blobs(n_samples=100,centers=2,random_state=0,cluster_std=0.8)plt.scatter(X[:,0],X[:,1],c=y,s=50,cmap='autumn');3.5.2案例:面部识别应用实战76结果如图所示:3.5.2案例:面部识别应用实战77调整参数为两个极端值,一个设为10,一个设为0.1,观察松弛因子会对决策边界造成一定影响,C越大,决策边界就越小,C越小,决策边界就越大,代码如下:X,y=make_blobs(n_samples=100,centers=2,random_state=0,cluster_std=0.8)fig,ax=plt.subplots(1,2,figsize=(16,6))fig.subplots_adjust(left=0.0625,right=0.95,wspace=0.1)foraxi,Cinzip(ax,[10.0,0.1]):model=SVC(kernel='linear',C=C).fit(X,y)axi.scatter(X[:,0],X[:,1],c=y,s=50,cmap='autumn')plot_svc_decision_function(model,axi)axi.scatter(model.support_vectors_[:,0],model.support_vectors_[:,1],s=300,lw=1,facecolors='none');axi.set_title('C={0:.1f}'.format(C),size=14)结果如图所示:3.5.2案例:面部识别应用实战78第二个参数为Gamma,这个参数控制模型的复杂程度,Gamma值越大,模型复杂程度越高,精度更高;Gamma值越小,模型会越精简,实用性更强。代码如下:X,y=make_blobs(n_samples=100,centers=2,random_state=0,cluster_std=1.1)fig,ax=plt.subplots(1,2,figsize=(16,6))fig.subplots_adjust(left=0.0625,right=0.95,wspace=0.1)foraxi,gammainzip(ax,[10.0,0.1]):model=SVC(kernel='rbf',gamma=gamma).fit(X,y)axi.scatter(X[:,0],X[:,1],c=y,s=50,cmap='autumn')plot_svc_decision_function(model,axi)axi.scatter(model.support_vectors_[:,0],model.support_vectors_[:,1],s=300,lw=1,facecolors='none');axi.set_title('gamma={0:.1f}'.format(gamma),size=14)运行结果如图所示:3.5.2案例:面部识别应用实战794.面部识别应用面部识别作为支持向量机的一个例子,本次将使用Wild数据集中的LabeledFaces,其中包含数千张各种公众人物的整理照片。Scikit-Learn内置了封装了数据集的提取器,可以直接调用。首先,通过命令下载实验所需要的数据。代码如下:fromsklearn.

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论