(轉載請注明出處: http://blog.csdn.net/zhazhiqiang/ ?未經允許請勿用于商業用途)
<5-1> 徑向基(RBF)核函數(高斯核函數)?的說明常用的核函數有以下4種:⑴ 線性核函數?
⑵ 多項式核函數
⑶ 徑向基(RBF)核函數(高斯核函數)?
⑷ Sigmoid 核函數(二層神經網絡核函數)![]()
? ? 這個核函數可以將原始空間映射到無窮維空間。對于參數 σ ,如果選的很大, 高次特征上的權重實際上衰減得非??欤詫嶋H上(數值上近似一下)相當于一個低維的子空間;反過來,如果 選得很小,則可以將任意的數據映射為線性可分——當然,這并不一定是好事,因為隨之而來的可能是非常嚴重的過擬合問題。不過,總的來說,通過調控參數 ,高斯核實際上具有相當高的靈活性,也是 使用最廣泛的核函數 之一。
? ? 徑向基( RBF )核函數主要確定 懲罰因子 C 和 參數σ 。其中 C 控制著使間隔 margin 最大且錯誤率最小的折中,就是在確定的特征空間中調節學習機器的置信范圍和經驗風險的比例;而σ 2 是 RBF 核函數參數,主要影響樣本數據在高維特征空間中分布的復雜程度。因此分類器的好壞取決于參數 C 、σ的確定。參數選擇的好壞直接影響到分類器性能的好壞,但這方面目前缺乏理論指導,沒有合適的方法,傳統的參數選取都是通過反復的試驗,人工選取令人滿意的解。這種方法需要人的經驗指導,并且需要付出較高的時間代價。常用的參數選擇方法有:
I、網格法【OpenCV中SVM用到】
? ? 選取
U
個
C
和
V
個σ
2
,就會有
的組合狀態,每種組合狀態對應一種
SVM
分類器,通過測試對比,找出推廣識別率最高的
C
和σ
2
組合。一般取
U=V=15
,
C
取值分別為
,
取值分別為
共
255
個
C
、σ
2
組合。網格法實質上是一種窮舉法,隨著排列組合的可能情況越多,其運算量將急劇增加。
II、雙線性法
利用
RBF
核
SVM
的性能,首先對線性
SVM
求解最佳參數,使之為參數的線性
SVM
推廣識別率最高,稱為
;然后固定
,對滿足
? ? ? ??
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
的
,訓練
SVM
,根據對其推廣識別率的估算,得到最優參數。雖然這種方法對σ
2
有非常明確的公式,但首先要求解
C
,而很難確定最優的
C
。
III、梯度下降搜索法
設泛化誤差為
? ? ? ??
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
核函數為
,
是待定的核參數,基本過程為:
a? 將θ置一個初始值
b? 用一個標準的 SVM 解法(如 SMO ),求出 SVM 的解—— Lagrange 乘子
![]()
c?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
d? 跳轉到 b 直至 T 最小
? ? 其中
是足夠小且最終收斂到零的數列。步驟
c
是一個標準的梯度下降算法。由分類函數公式可以求解
,
的求解較麻煩,需要通過求解一個二次規劃問題得到。
IV、遺傳算法
基本步驟為:
?????? a t=0
?????? b? 隨機選擇初始種群 P(t)
?????? c? 計算個體適應度函數值 F(t)
?????? d? 若種群中最優個體所對應的適應度函數值足夠大或者算法已經連續運行多代,且個體的最佳適應度無明顯改進則轉到第 h 步
?????? e t=t+1
?????? f? 應用選擇算子法從 P(t-1) 中選擇 P(t)
?????? g? 對 P(t) 進行交叉、變異操作,轉到第 c 步
?????? h? 給出最佳的核函數參合和懲罰因子 C ,并用其訓練數據集以獲得全局最優分類面。
??????? 遺傳算法的缺點是收斂很慢,容易受局部極小值干擾。
<5-3>驗證核函數性能的方法(3種)(衡量泛化能力)
I、單一驗證估計
? ? 將大數量的樣本分為兩部分:訓練樣本和測試樣本,此時測試集的錯誤率為:
? ??
式中,
p
為樣本數,
為樣本實際所屬的類別,
為對訓練樣本預測出的類別。這種方法直觀簡單。可以通過理論證明,當樣本數量趨近于無窮大時,該估計為無偏估計,但現實中處理的總是數量有限的樣本問題,所以此方法的應用范圍在一定程度上受到了限制。
II、K 折交叉驗證 【OpenCV中SVM用到】
? ? K
折交叉驗證是一種迭代方式,一共迭代
K
次,每次將所有訓練樣本分為
K
份相等的子集樣本,訓練樣本是選擇其中
K-1
份樣本,測試樣本是剩余的一個樣本。通過
K
次迭代后,可以利用平均值來評估期望泛化誤差,根據期望泛化誤差選擇一組性能最佳的參數。
K
折交叉驗證由
K
折交叉驗證誤差決定,
K
折交叉驗證誤差是算法錯誤率的估計,其計算方式為:假設
為錯分類的樣本個數,經過
K
次迭代后,得到
,那么算法的錯誤率可以近似為錯誤分類數
和總樣本點數
之比
。該方法具有操作簡單的優點,成為
目前應用最廣泛
的方法,但是這種方法容易受樣本劃分方式的影響。
III、留一法
???? 留一法是 K 折交叉驗證的特例,其基本思想是當可用樣本數為 N 時,訓練集由其中 N-1 個樣本構成,測試樣本為剩余的一個樣本,經 N 次重復,使所有的樣本都參加過測試。通過理論證明,這種估計是無偏估計。因此,從實現原理來說,留一法的效果是最佳的;但是,在參數固定的情況下,確定其錯誤率對樣本要訓練 N-1 次,運算量很大。為了解決留一法計算量大的缺陷,目前該方法確定核函數及其參數的常用方法是估計經驗風險的上界,只要上界小,分類器的推廣能力就強。
?
C++:?CvSVMParams:: CvSVMParams ()
C++:?CvSVMParams:: CvSVMParams (int? svm_type ,?
int? kernel_type ,?
double? degree ,?
double? gamma ,?
double? coef0 ,?
double? Cvalue ,?
double? nu , ? ? ? ? ? ? ? ? ??
double? p ,?
CvMat*? class_weights ,
CvTermCriteria? term_crit
)
(3)注釋CvSVMParams :: CvSVMParams() : svm_type(CvSVM :: C_SVC), kernel_type(CvSVM :: RBF), degree( 0 ), gamma( 1 ), coef0( 0 ), C( 1 ), nu( 0 ), p( 0 ), class_weights( 0 ) { term_crit = cvTermCriteria( CV_TERMCRIT_ITER + CV_TERMCRIT_EPS, 1000 , FLT_EPSILON ); }
- CvSVM::C_SVC :? C類支持向量分類機。?n類分組??(n≥2),允許用異常值懲罰因子C進行不完全分類。
-
CvSVM::NU_SVC :?
類支持向量分類機。n類似然不完全分類的分類器。參數為
取代C(其值在區間【0,1】中,nu越大,決策邊界越平滑)。
- CvSVM::ONE_CLASS :? 單分類器,所有的訓練數據提取自同一個類里,然后SVM建立了一個分界線以分割該類在特征空間中所占區域和其它類在特征空間中所占區域。
-
CvSVM::EPS_SVR :?
類支持向量回歸機。訓練集中的特征向量和擬合出來的超平面的距離需要小于p。異常值懲罰因子C被采用。
-
CvSVM::NU_SVR :?
類支持向量回歸機。?
代替了?p。?
<2> kernel_type: SVM的內核類型(4種):
- CvSVM::LINEAR :? 線性內核,沒有任何向映射至高維空間,線性區分(或回歸)在原始特征空間中被完成,這是最快的選擇。

- CvSVM::POLY :? 多項式內核:

- CvSVM::RBF :? 基于徑向的函數,對于大多數情況都是一個較好的選擇:

- CvSVM::SIGMOID :? Sigmoid函數內核:





C++:?CvSVM:: CvSVM ()
C++:?CvSVM:: CvSVM (const Mat&? trainData ,?
const Mat&? responses ,?
const Mat&? varIdx=Mat() ,?
const Mat&? sampleIdx=Mat() ,?
CvSVMParams? params=CvSVMParams()
)
C++:?CvSVM:: CvSVM (const CvMat*? trainData ,?
const CvMat*? responses ,?
const CvMat*? varIdx=0 ,
const CvMat*? sampleIdx=0 ,?
CvSVMParams? params=CvSVMParams()
?)
- trainData : ?訓練數據,必須是CV_32FC1?(32位浮點類型,單通道)。數據必須是CV_ROW_SAMPLE的,即特征向量以行來存儲。
- responses : ?響應數據,通常是1D向量存儲在CV_32SC1?(僅僅用在分類問題上)或者CV_32FC1格式。
- varIdx : ?指定感興趣的特征??梢允钦麛?32sC1)向量,例如以0為開始的索引,或者8位(8uC1)的使用的特征或者樣本的掩碼。用戶也可以傳入NULL指針,用來表示訓練中使用所有變量/樣本。
- sampleIdx : ?指定感興趣的樣本。描述同上。
- params : ?SVM參數。
C++:?bool?CvSVM:: train (const Mat&? trainData ,?
const Mat&? responses ,?
const Mat&? varIdx=Mat() ,?
const Mat&? sampleIdx=Mat() ,?
CvSVMParams? params=CvSVMParams()
?)
C++:?bool?CvSVM:: train (const CvMat*? trainData ,?
const CvMat*? responses ,?
const CvMat*? varIdx=0 ,?
const CvMat*? sampleIdx=0 ,?
CvSVMParams? params=CvSVMParams()?
)
C++:?bool?CvSVM:: train_auto (const Mat & ? trainData ,
const Mat & ? responses ,?
const Mat & ? varIdx ,?
const Mat & ? sampleIdx ,?
CvSVMParams? params ,
int? k_fold=10 ,?
CvParamGrid? Cgrid=CvSVM::get_default_grid(CvSVM::C) ,?
CvParamGrid? gammaGrid=CvSVM::get_default_grid(CvSVM::GAMMA) ,?
CvParamGrid? pGrid=CvSVM::get_default_grid(CvSVM::P) ,?
CvParamGrid? nuGrid=CvSVM::get_default_grid(CvSVM::NU) ,?
CvParamGrid? coeffGrid=CvSVM::get_default_grid(CvSVM::COEF) ,?
CvParamGrid? degreeGrid=CvSVM::get_default_grid(CvSVM::DEGREE) ,?
bool? balanced=false
)
C++:?bool?CvSVM:: train_auto (const CvMat * ? trainData ,
const CvMat * ? responses ,?
const CvMat * ? varIdx ,?
const CvMat * ? sampleIdx ,?
CvSVMParams? params ,?
int? kfold=10 ,?
CvParamGrid? Cgrid=get_default_grid(CvSVM::C) ,
CvParamGrid? gammaGrid=get_default_grid(CvSVM::GAMMA) ,?
CvParamGrid? pGrid=get_default_grid(CvSVM::P) ,
CvParamGrid? nuGrid=get_default_grid(CvSVM::NU) ,?
CvParamGrid? coeffGrid=get_default_grid(CvSVM::COEF) ,
CvParamGrid? degreeGrid=get_default_grid(CvSVM::DEGREE) ,?
bool? balanced=false
)
- 前5個參數參考 構造函數的參數注釋。
- k_fold:? 交叉驗證參數。訓練集被分成k_fold的自子集。其中一個子集是用來測試模型,其他子集則成為訓練集。所以,SVM算法復雜度是執行k_fold的次數。
- *Grid:? (6個) 對應的SVM迭代網格參數。
- balanced:? 如果是true則這是一個2類分類問題。這將會創建更多的平衡交叉驗證子集。
- 這個方法根據CvSVMParams中的最佳參數C,?gamma,?p,?nu,?coef0,?degree自動訓練SVM模型。
- 參數被認為是最佳的交叉驗證,其測試集預估錯誤最小。
- 如果沒有需要優化的參數,相應的網格步驟應該被設置為小于或等于1的值。例如,為了避免gamma的優化,設置gamma_grid.step?=?0,gamma_grid.min_val,?gamma_grid.max_val?為任意數值。所以params.gamma?由gamma得出。
- 最后,如果參數優化是必需的,但是相應的網格卻不確定,你可能需要調用函數CvSVM::get_default_grid(),創建一個網格。例如,對于gamma,調用CvSVM::get_default_grid(CvSVM::GAMMA)。
- 該函數為分類運行 (params.svm_type=CvSVM::C_SVC?或者?params.svm_type=CvSVM::NU_SVC) 和為回歸運行 (params.svm_type=CvSVM::EPS_SVR?或者?params.svm_type=CvSVM::NU_SVR)效果一樣好。如果params.svm_type=CvSVM::ONE_CLASS,沒有優化,并指定執行一般的SVM。
C++:? float? CvSVM:: predict (const Mat&? sample , bool? returnDFVal =false ?)?const
C++:? float? CvSVM:: predict (const CvMat*? sample , bool? returnDFVal =false ?)?const
C++:? float? CvSVM:: predict (const CvMat*? samples , CvMat*? results )?const
<3>預測函數的參數注釋
- sample:? 需要預測的輸入樣本。
- samples:? 需要預測的輸入樣本們。
- returnDFVal:? 指定返回值類型。如果值是true,則是一個2類分類問題,該方法返回的決策函數值是邊緣的符號距離。
- results:? 相應的樣本輸出預測的響應。
- 這個函數用來預測一個新樣本的響應數據(response)。
- 在分類問題中,這個函數返回類別編號;在回歸問題中,返回函數值。
- 輸入的樣本必須與傳給trainData的訓練樣本同樣大小。
- 如果訓練中使用了varIdx參數,一定記住在predict函數中使用跟訓練特征一致的特征。
- 后綴const是說預測不會影響模型的內部狀態,所以這個函數可以很安全地從不同的線程調用。
- param_id:? SVM參數的IDs必須是下列中的一個:(網格參數將根據這個ID生成?)
- CvSVM::C
- CvSVM::GAMMA
- CvSVM::P
- CvSVM::NU
- CvSVM::COEF
- CvSVM::DEGREE
C++:? int? CvSVM:: get_support_vector_count ()?const ?//獲取支持向量的數量
C++:?const? float* ?CvSVM:: get_support_vector (int? i )?const ? ?//獲取支持向量
? ? ? ? 參數: i ?– 指定支持向量的索引。
?
(8)獲取所用特征的數量的函數
<1>作用 :獲取所用特征的數量
<2>函數原型:
- C比較大時:分類錯誤率較小,但是間隔也較小。 在這種情形下, 錯分類對模型函數產生較大的影響,既然優化的目的是為了最小化這個模型函數,那么錯分類的情形必然會受到抑制。
- C比較小時:間隔較大,但是分類錯誤率也較大。 在這種情形下,模型函數中錯分類之和這一項對優化過程的影響變小,優化過程將更加關注于尋找到一個能產生較大間隔的超平面。
四、SVM處理流程總結:
? ?? a. ?訓練的目的得到參數和支持向量(存儲在xml文件中),得到參數就能得到支持向量,帶進算式計算SVM分類的準確度,以準確度最高的一組參數作為最終的結果,沒有絕對線性可分的,都有一個誤差,參數就是把那個誤差降到最低。
? ?? b.? 這里的準確性是指將訓練集的每個樣本的向量與支持向量做運算,將運算結果與標記值比較,判斷是否屬于這個類,統計這個類的正確的樣本數,最高的那一組參數準確性最高。
? ?? c.? 最終訓練得到分類器。SVM只能分兩類,所以這里的分類器是兩個類組成一個分類器,如果有K類,就有k(k-1)/2個分類器。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
