日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

SVM原理与实战

發布時間:2024/7/23 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SVM原理与实战 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

先看線性可分問題。對于線性可分,其實感知機就可以解決。但是感知機只是找到一個超平面將數據分開,而這樣的超平面可能是平行的無限多個,我們需要在這其中找到最優的一個。怎么衡量一個超平面是不是最優的呢,直觀上講,它應該是處于臨界狀態,到兩類樣本的距離都是最遠的。那么怎么表示這個距離呢?以二維平面中的二分類為例:

距離

首先,在這里超平面退化為直線,將其表示為:。等于0是表示位于該直線上的點代入直線后結果是0(表示一個點,而不是坐標x)。那么其他不處于該直線的點代入之后很明顯不等于0,那么這個不等于0的值是什么呢。數學上稱為函數間隔,我理解它就是一個相對量,相對于該直線的一個“距離”。更準確地,該直線兩側的點是有符號的,那么就是點的函數距離。

https://www.zhihu.com/question/64568136/answer/257874428

很明顯,一對可以唯一地表示一條直線,但是這個關系不是一一對應的,當同比例變化時,和表示的是同一個平面。這會帶來兩個問題,一個問題是我們希望通過更新來更新超平面,現在很可能更新半天還是那個超平面,造成一些無效的計算;第二個問題是明明是同一個超平面,但是如果使用函數距離的話卻發生了變化。第二個問題卻會把第一個問題放大,讓我們錯以為超平面已經更新了。解決辦法首先是使用幾何距離替換函數距離。幾何距離是通過幾何關系方程組求出來的,同時幾何距離也可以看作是函數距離的歸一化:。使用幾何距離解決了第二個問題,但是第一個問題仍然存在,解決辦法是將使得函數距離等于1,這樣除非,只要變化,距離也會變化。注意這里的函數距離是針對支持向量而言的,其他更遠的點的函數距離>1,所以SVM的約束條件:;目標函數:

為了求導時方便,將目標函數重寫為

拉格朗日函數

這是含不等式約束的凸二次規劃問題,首先轉換為無約束的拉格朗日函數:


提到拉格朗日函數,構造方法很簡單,但這個是什么來的呢,有什么意義呢?以等式約束為例,極值的情況很顯然是約束函數與等高線相切的點,相切的位置有什么特點呢?就是等高線處的梯度方向和約束函數處的梯度反向是同向或者反向的:

這個方程和約束等式聯立,就可以推導出我們常見的對拉格朗日函數求偏導使其為0的解法。

當約束條件是不等式約束時,.根據無約束時本身的最小值點與約束區域的相對位置有兩種情況:一種情況是真實的最小值正好處于約束區域中,那么約束條件其實沒起作用,;另一種是真實最小值處于約束區域之外,那么和等式約束一樣,約束可行解也落在約束區域的邊界上,。兩種情況可以一起表示為:(松弛互補條件)。需要注意的是的選取,雖然第二種情況中和等式約束一樣都處于邊界,但是方向是不同的。真正的等式約束只需要在等式上,不關心梯度方向;而不等式約束不再是一條線,而是一個圈(區域),滿足這個約束的點的梯度方向一定是向外的(梯度是增長最快的方向,約束區域內是小于0的,外面才是大于0的)。而真正的最小值點也在外面,意味著在處的梯度方向和在處的梯度方向是反向的。所以.https://www.cnblogs.com/ooon/p/5721119.html

以上所有約束共同構成了KKT條件,滿足了KKT條件就可以直接使用拉格朗日乘子法進行求解。

剛才提到SVM的問題是凸二次規劃問題,即便使用拉格朗日求解也比較低效。一般先將其轉換為對偶問題,再使用SMO算法求解。

對偶問題

第二,第三項分別為等式約束和不等式約束。,所以原目標函數可以寫為最小最大化形式:

所謂對偶,就是交換最小最大化的順序。通過對偶性,為原始問題引入一個下界,。而當優化問題是凸優化問題并且滿足KKT條件時,強對偶成立,這個不等式中的等號成立,即對偶問題與原問題的解相等。在SVM中,? ,對和分別求導并使其等于0,可以得到,

最終的分類函數

優化目標函數

表示所有樣本的個數(不等式的個數),因為,所以很明顯只有當大于0時才會對超平面的參數產生影響,這些大于0的樣本點被稱作支持向量。支持向量的個數是求解得到的(非零的數目),而這個數目最小為1,因為可以由反證法,如果所有等于0,則=0,這顯然是不可能的。而當,這意味著對應的點處于不等式約束的邊界上,所以

松弛變量

有些情況不是完全線性可分的,那么我們可以允許一些樣本點“近似滿足”約束條件。約束減輕,變成,。,這就是我們常見的hingle損失函數,通過損失函數,每個樣本會對應一個松弛變量,在最優化時,所有松弛變量的和會以C加權,作為懲罰項。

如何從損失函數的角度理解SVM呢?看SVM的目標函數,目的是盡量讓 超平面和兩類樣本點的距離最遠,如果距離越近,就認為損失越大,對超平面的影響也越大。這也可以解釋為什么只有支持向量對超平面的確定起作用,而其余樣本點對應的為0,本質原因就是其余樣本點離超平面足夠遠,loss為0。所以保證了支持向量機解的稀疏性。

具體到合頁損失。特點1:最大值為1,這對應了我們之前的約定,函數間隔為1。那么什么時候取最大值呢,就是樣本點落在超平面上,這時候當然最難分類。特點2:函數間隔大于0時損失函數為0。這也解釋了稀疏性。當完成優化,樣本點的函數距離最近為1,損失函數為0。特點3:損失函數大小在一個區間內線性增長,函數距離越接近0,損失函數越大。

每一個樣本會對應一個松弛變量,不同樣本的松弛變量應該是不同的,如果本來函數間隔已經大于等于1,那么它其實不需要添加松弛變量,所以對應的松弛變量為0;如果小于1,那么松弛變量就等于。可以看到,松弛變量正好就是每個樣本對應的hinge損失。

損失函數的優化其實是通過約束條件來表示的,當超平面不斷調整到滿足約束條件,損失函數達到最小。當使用合頁損失作為松弛變量后,會直接使得每個樣本滿足約束條件,這樣太極端了,會使得超平面無法迭代優化。所以在添加松弛變量后,需要在目標函數中增加一個懲罰項,該懲罰項由松弛變量和或者和平方組成,并且有一個懲罰因子作系數,從而約束松弛變量的大小和離群點的個數。

核函數

對于松弛變量也無法解決的非線性可分問題,可以使用非線性映射,本質是通過坐標變換到另外一個坐標空間,在新的坐標空間中會是線性可分的。從的表達式,進而到最終的目標函數和分類函數,都出現了樣本點的內積。所以可以不顯式地進行非線性映射,而是使用核函數代替內積。https://zhuanlan.zhihu.com/p/31886934

高斯核是最常見的一種核函數。一般當特征數目比較小(1~1000),樣本數目適中時(10~10000),都是使用高斯核函數效果更好、

可以證明高斯核可以寫成的形式,而因為e指數的泰勒展開,其實是映射到了無窮維https://www.cnblogs.com/makefile/p/taylor-expand.html

判斷一個函數是否可以作核函數,可以參考Merce's theorem,它要求該函數是半正定函數。

除了高斯核函數,還經常見的是線性核函數。可能會有些奇怪,線性核函數的作用是什么,經過線性核函數映射之后坐標空間沒有發生變化啊。確實線性核函數沒有升維的功能,它更多是為了統一線性與非線性問題,使得目標函數都使用核函數的形式代替內積。

越小,則高斯函數越集中,集中在哪個位置呢:看最終的決策函數,高斯函數以當前的測試樣本為中心。所以高斯核的一個作用其實是對支持向量進行加權,離測試樣本更近的支持向量會有更大的權重。

再看優化目標函數,當很小,高斯函數接近0,那么,在SVM中,支持向量個數會更小,而在SVDD中,每一個樣本都會是支持向量,因為,

當核函數是標準高斯函數時,是不是意味著樣本數據就不用歸一化了呢?貌似是這樣的,因為高斯核映射之后的結果只和樣本間的距離有關,特別地,,所以實際上在映射之后的新空間中,每個樣本的模都是1.

https://blog.csdn.net/lujiandong1/article/details/46386201

代碼實戰C++(OpenCV)

在opencv的安裝路徑中可以找到示例:opencv\sources\samples\cpp\tutorial_code\ml.關鍵代碼其實只有幾行,其中一個結構體是CvSVMParams,現在介紹幾個關鍵的成員變量。

svm_type=C_SVC

由于opencv中的svm分類算法是根據libsvm改寫而來的,libsvm是臺灣一學者編寫的matlab版本的svm算法,所以參數的設定的也大致相同。svm類型除了C_SVC之外,還有NU_SVC,ONE_CLASS,EPS_SVR,NU_SVR.

C_SVC和NU_SVC其實是一種,只不過參數不同。SVM通過超平面劃分樣本,二維時超平面可以使用解析式表達,高維時其實是使用支持向量表示的,而支持向量的數目就是一個超參數,C_SVC中的超參數C就表示支持向量數目,取值范圍是任意正整數,而NU_SVC中超參數用NU表示,取值范圍在[0,1],A nice property of nu is that it is related to the ratio of support vectors and the ratio of the training error.還有一個單分類器,顧名思義,將樣本分為類別A和不屬于A,訓練數據只有一種數據,分類器學習這種類別的特征,只要和這一類A差別較大,不管是B~Z中的任何一個,都認為是另外一類。

SVM一般用來分類,SVR則可以實現回歸。因為分類和回歸本質上只是數據類型不一樣,一個是離散的,一個是連續的,表現在編程中就是分類可以使用CV_32FC1或者CV_32SC1,而回歸只能使用CV_32FC1

kernel_type=SVM::LINEAR

核函數的類型,SVM能處理線性不可分的情況就依賴于核函數。SVM::LINEAR,默認就是最簡單的線性分類器,枚舉定義為0;SVM::POLY,枚舉定義為1;SVM::RBF徑向基核函數: ,枚舉定義為2;SIGMOD核函數,枚舉定義為3

term_crit=TermCriteria(CV_TERMCRIT_ITER,(int)le7,1e-6)

迭代的終止條件,可以通過函數cvTermCriteria確定迭代次數和誤差。這里迭代的算法就是著名的SMO

訓練很簡單,使用train函數,前兩個參數是Mat型的訓練數據和標簽,第三四個參數是mask,當需要將所有的訓練樣本應用到訓練中時,可以傳入NULL或者Mat()表示應用所有數據,最后一個參數是剛才定義的參數。

對應的還有一個train_auto函數,前幾個參數可以和train函數一樣,后面都可以使用缺省值。但是要注意的是自動訓練過程中對于參數的選擇其實是k折交叉驗證的一個過程,默認定義是10折交叉驗證,如果訓練樣本數目太小,就會報錯:badargument。折數和所需訓練樣本的數目的對應關系我還沒有搞清楚,有的地方說10折的話每類最少兩個樣本。

預測則使用predict函數,將待預測的Mat類型樣本傳入,得到預測的標簽。如果我們將(512,512)范圍內的點依次傳入,就可以得到每個點的預測標簽,如果分別顯示成不同的顏色,就會看到一個分界線。剛才說過,這個分界線其實可以通過支持向量確定,那么我們可以看看支持向量是什么個情況,有多少個支持向量,支持向量的分布。get_support_vector_count返回支持向量的數目,get_support_vector(i)就可以返回每個支持向量的指針。問題是我的代碼中支持向量數目一直等于1,畫出的位置也一直在坐標原點的位置,懷疑是OpenCV2.4.9版本的問題,因為同樣的代碼其他人的支持向量就是正常的。

svm.save("svmModel.xml")就可以保存SVM模型,保存成xml直接用瀏覽器就可以打開,也可以保存成.mat格式,但是使用matlab不能直接打開。那么我們看看SVM模型保存了什么。像深度學習一樣,SVM保存了一些超參數,就是我們最開始初始化的那些,SVM的類型,核函數類型,迭代次數和終止時的誤差,C值等。包括樣本的維度,分類的數目。SVM的分類本質是找到超平面,這個超平面就是由支持向量決定的,所以xml文件里面保存了支持向量,sv_count就是支持向量的數目,每個支持向量都是訓練樣本的其中之一,坐標都被保存下來。此外還保存了一個rho值(判決函數的常數項),還有若干個alpha值和index值。

二維平面中,超平面退化為一個線段,線性可分時是直線,rho在這里就是截距,wx+b=0中的b。二分類時,rho的個數是1,分類類別數目是n時,rho的數目m=n*(n-1)/2.

預測SVM中有預測函數predict,因為SVM有不同類型(分類回歸等 ),predict的實現方式也不盡相同。對分類來說,典型的分類是二分類,為了實現多分類,其實也在拆分成兩兩一對進行比較,再在全局選出一個投票得分最多的作為最后的分類。對于其中的二分類,需要遍歷所有的支持向量,sum += df->alpha[k]*buffer[df->sv_index[k]],df是決策函數,buffer是核函數,sum初始化為-rho,所以這句代碼的意思就是在與支持向量個數相同的維度上把核函數代入決策函數計算。對于回歸則比較簡單,只有一層對于支持向量的循環。for( i = 0; i < sv_count; i++ ),sum += buffer[i]*df->alpha[i];

核函數將低維數據映射到高維空間,使得原來線性不可分的數據線性可分,同時找到了一種等價的方法,原始數據代入核函數的結果等價于映射到高維之后的內積,低維的計算結果等價于高維的計算結果,避免高維空間中內積的巨大計算量。以多項式核函數為例,其實是將原始數據進行擴展,增加了一些平方,或者交叉相乘x1x2,不僅會有升維時增加的乘法加法,計算內積時同樣增加了乘法加法的次數。而我們可以調整原始數據求內積時的系數和偏置量得到近似的效果。而我們最經常使用的是高斯核函數,也叫徑向基函數RBF。高斯核函數的形式和高斯函數一樣,為什么映射到的維度是無窮維呢?主要是因為e指數函數,因為e指數的泰勒展開是無窮維的。雖然高斯核對應的映射之后是無窮維的,但是我們可以控制gamma控制維度,gamma大時衰減大,維度就是一定的,這也反而成為了高斯核的優勢,可以通過這一超參防止過擬合。同時還有線性核,其實本質上沒有升維,還是線性分類,只不過這也就把線性核非線性通過核函數統一起來了。

高維空間中的決策超平面和二維中的決策線其實是差不多的,都是斜率+截距的形式:f(x0=Ogima.inv()x+b,Omiga是拉格朗日參數和標簽yi與支持向量xi的乘積求和,從而轉為內積的形式,內積又可以使用核函數近似求得。

代碼實戰Python(Sklearn)

class?sklearn.svm.SVC(C=1.0,?kernel='rbf',?degree=3,?gamma='auto',?coef0=0.0,?shrinking=True,?probability=False,?tol=0.001,?cache_size=200,?class_weight=None,?verbose=False,?max_iter=-1,?decision_function_shape='ovr',?random_state=None)

C表示懲罰因子,就是松弛變量的權重。C越小,對松弛的容忍度越強,允許更多的離群點,泛化能力越強,但可能欠擬合。

gamma=1/(2*sigma^2),gamma越大,sigma越小,高斯函數越集中分布,支持向量的影響范圍越小,可能過擬合。C和Gamma都是越大越容易過擬合。https://www.cnblogs.com/solong1989/p/9620170.html

opencv實現svm的方法保存的模型可以直接看到支持向量等參數,sklearn的模型是十六進制文件,不過我們可以使用函數保存各種參數。clf.support_vectors_,clf.dual_coef,保存alpha和類別標簽的乘積,clf.intercept,保存截距b。

使用GridSearch可以在給定的范圍內尋找最優的超參數。高斯核函數對超參數的選擇比較敏感,所以二者可以結合。pd.Dataframe.from_dict(clf.cv_results_)就可以保存不同參數組合的情況,這里cv指的是交叉驗證,評價標準和clf分類器選擇的標準一樣。具體而言,選擇文件中mean_test_score最大的那個組合作為最優解。

注意要歸一化。涉及到求距離一般都要歸一化,防止哪個維度取值過大造成的影響。具體表現就是訓練出來的模型輸出值全1或者全0.

http://blog.sina.com.cn/s/blog_6e32babb0102xpip.html

https://www.cnblogs.com/denny402/p/5019233.html

https://www.cnblogs.com/chenzhefan/p/7662315.html

https://www.cnblogs.com/chenzhefan/p/7662315.html

三層境界https://blog.csdn.net/v_JULY_v/article/details/7624837?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control

源碼分析https://blog.csdn.net/zhaocj/article/details/51297907

bad argumenthttps://answers.opencv.org/question/26711/opencv-error-bad-argument/

任毅http://www.uml.org.cn/ai/202002144.asp?artid=22949

核函數內積https://www.jianshu.com/p/028d1883ad93

總結

以上是生活随笔為你收集整理的SVM原理与实战的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。