title: 4 - caret - PLS-DA and SVM
tags: 數(shù)據(jù)挖掘與機器學(xué)習(xí)
今天才發(fā)現(xiàn),上次寫得博客旭绒,其自己進行了編號。由驹。募疮。炫惩。
“#” 一個最大, 隨著數(shù)目增多阿浓,逐漸減小他嚷。。芭毙。
對于公式的寫法筋蓖,還是不了解怎么搞,等慢慢使用退敦,應(yīng)該會有解決辦法粘咖, “實踐才是硬道理”
這次先寫下caret包的一個總的使用,其真的是太好用了侈百,而后就是PLS-DA和SVM了
一瓮下、caret 包(非常好)
install.packages("caret", dependencies = c("Depends", "Suggests"))
其主要的函數(shù)之一為: train()函數(shù)
其主要有三方面作用:
1. 使用重采樣來估計模型,調(diào)整參數(shù)
2 .在這些參數(shù)中選擇最佳模型
3. 從訓(xùn)練集中估計模型性能
一般形式為:
設(shè)定一系列的參數(shù)
for 參數(shù)設(shè)定集 do
for 每次從采樣的數(shù)據(jù) do
在特殊樣本下進行
對數(shù)據(jù)預(yù)處理(optional)
將模型預(yù)測剩余樣本
對特殊樣本進行預(yù)測
end
根據(jù)特殊樣本的額預(yù)測值計算平均值
end
決定最佳參數(shù)
使用最優(yōu)參數(shù)預(yù)測整個訓(xùn)練集的數(shù)據(jù)
caret 包使用代碼例子(R code)
library(caret)
library(mlbench)
data(Sonar)
set.seed(107)
inTrain <- createDataPartition(
y = Sonar$Class,
##the outcome data are needed
p = .75,
##The percentage of data in the
## training set
list = FALSE
)
##The format of the results
str(inTrain)
注意: createDataPartition是隨機分層抽取
training <- Sonar[ inTrain,]
testing <- Sonar[-inTrain,]
nrow(training)
二钝域、 PLS-DA (partial least squares discriminant analysis)
plsFit <- train(
Class ~ .,
data = training,
method = "pls",
preProc = c("center", "scale"),
##added:
tuneLength = 15
)
添加的參數(shù)tuneLength意思為前15個主成分都要做一遍讽坏, tuneGrid是會為模型賦予特殊值
trainControl()函數(shù)
ctrl <- trainControl(method = "repeatedcv",number= 10, repeats = 3)
method參數(shù)有: boot, boot632, cv, repeatedcv, LOOCV, LGOCV
number: K=10
repeats: 重復(fù)運作的測試
plsFit <- train(
Class ~ .,
data = training,
method = "pls",
preProc = c("center", "scale"),
tuneLength = 15,
## added:
trControl = ctrl
)
ctrl <- trainControl(
method = "repeatedcv", #默認K=10,
repeats = 3, #重復(fù)3次
classProbs = TRUE, 為計算ROC值
summaryFunction = twoClassSummary ##只針對2分類例证,還可以寫defaultSummary(多分類)
)
set.seed(123)
plsFit <- train(
Class ~ .,
data = training,
method = "pls",
preProc = c("center", "scale"),
tuneLength = 15,
trControl = ctrl,
metric = "ROC"
)
plsFit
這樣會給出最佳LVs值路呜,作為參數(shù)可以預(yù)測未來新數(shù)據(jù)
ggplot(plsFit) #圖示出選擇最佳LVs數(shù)的依據(jù), 是選擇ROC值最大的LVs
模型預(yù)測新數(shù)據(jù)
plsClasses <- predict(plsFit, newdata = testing)
str(plsClasses)
### 給出具體每個個體的分類概率
plsProbs <- predict(plsFit, newdata = testing, type = "prob")
head(plsProbs)
### 混淆矩陣
confusionMatrix(data = plsClasses, testing$Class)
正則化判別模型(regularized discriminant model)
## To illustrate, a custom grid is used
rdaGrid = data.frame(gamma = (0:4)/4, lambda = 3/4)
set.seed(123)
rdaFit <- train(
Class ~ .,
data = training,
method = "rda",
tuneGrid = rdaGrid,
trControl = ctrl,
metric = "ROC"
)
rdaFit
預(yù)測and混淆矩陣
rdaClasses <- predict(rdaFit, newdata = testing)
confusionMatrix(rdaClasses, testing$Class)
不同算法的結(jié)果比較
這些模型如何比較其重采樣結(jié)果织咧? resamples()功能可用于收集胀葱,匯總和對比重采樣結(jié)果。 由于在調(diào)用train之前將隨機數(shù)種子初始化為相同的值笙蒙,因此對每個模型使用相同的倍數(shù)
resamps <- resamples(list(pls = plsFit, rda = rdaFit))
summary(resamps)
xyplot(resamps, what = "BlandAltman") #可視化結(jié)果
模型結(jié)果之間差異性檢驗(t-test)
diffs <- diff(resamps)
summary(diffs)
三巡社、 SVM(support vector machine)
建模型SVM
ctrl <- trainControl(method = "repeatedcv", number=10, repeats = 3)
set.seed(123)
svm_Linear <- train(
Class ~ .,
data = training,
method = "svmLinear",
preProc = c("center", "scale"), ##(nean=0, sd=1)
tuneLength = 10,
trControl = ctrl,
)
svm_Linear##cost = 1
SVM模型預(yù)測
test_pred <- predict(svm_Linear, newdata = testing)
confusionMatrix(data = test_pred, testing$Class)
調(diào)整C值
grid <- expand.grd(C= c(0, 0.01, 0.05, 0.1, 0.25, 0.75, 1))
set.seed(123)
svm_Linear_Grid <- train(
Class ~ .,
data = training,
method = "svmLinear",
preProc = c("center", "scale"), ##(nean=0, sd=1)
trControl = ctrl,
##added
tuneGrid = grid
)
svm_Linear_Grid
plot(svm_Linear_Grid)
test_pred_Grid <- predict(svm_Linear_Grid, newdata = testing)
test_pred_Grid
confusionMatrix(data = test_pred_Grid , testing$Class)
SVM的非線性核
我們將使用Radial Basis function, "svmRadial", 此算法需要選擇參數(shù)C(Cost)和sigma
ctrl <- trainControl(method = "repeatedcv", number=10, repeats = 3)
set.seed(123)
svm_Radial <- train(
Class ~ .,
data = training,
method = "svmRadial",
preProc = c("center", "scale"), ##(nean=0, sd=1)
tuneLength = 10,
trControl = ctrl,
##added
##tuneGrid = grid
)
ggplot(svm_Radial)
SVM的非線性核預(yù)測
test_pred_Radial <- predict(svm_Radial, newdata = testing)
test_pred_Grid
confusionMatrix(data = test_pred_Radial , testing$Class)
調(diào)參數(shù)
gird_radial <- expand.grid(C=c(0, 0.05, 0.1, 0.25, 0.5, 0.75,1,1.5,2,5, 10手趣, 15晌该, 20),
sigma =c(0, 0.01:2) )
# 0.25,0.5,0.75,0.9
set.seed(123)
svm_Radial_Grid <- train(
Class ~ .,
data = training,
method = "svmRadial",
preProc = c("center", "scale"), ##(nean=0, sd=1)
tuneLength = 10,
trControl = ctrl,
##added
tuneGrid = gird_radial
)
svm_Radial_Grid
ggplot(svm_Radial_Grid)
test_pred_Radial_Grid <- predict(svm_Radial_Grid, newdata = testing)
confusionMatrix(data = test_pred_Radial_Grid , testing$Class)
四、 理論部分
4.1 PLS-DA
和PLS一樣绿渣,都可以在變量多于樣本數(shù)時使用朝群。同時其也是基于PLS, 加了轉(zhuǎn)換函數(shù)中符。
這里從新簡寫下PLS:
分解: X = TP‘ + E , Y = UQ' + F
再 U = TC姜胖, or這里求出C
最后: Y = TCQ' + F, 與 X = TP' + E, 聯(lián)合得D = Tβ + H(OLS法)淀散, 求出β右莱,即為系數(shù)
需要返回原函數(shù)蚜锨,B = W(P'W)-1CQ', 其中W: 先對X與Y標準化慢蜓, 再求x對Y的相關(guān)性R亚再, 根據(jù)相關(guān)性求出x對y的貢獻w
以上y為連續(xù)性變量的求解, 當(dāng)為分類時晨抡, 也可以先按連續(xù)性變量氛悬, 對于得到的Yp,可以使用閾值對其劃分耘柱,如Y為A與B分類如捅,閾值可以是0.5, Yp>0.5為A類调煎, <則為B類
當(dāng)然镜遣,可以看到閾值設(shè)定不同,會有不同的結(jié)果士袄,需要找到最合適的閾值設(shè)定(以前的文獻有報道烈涮,這里不具體寫)
我們認為PLS-DA為雙線性模型(bilinear model), 因為其基于PLS窖剑, 也需要選擇最佳的LVs數(shù),
這里的可以根據(jù)戈稿,在交叉驗證集中最小錯分率得出西土。錯分率:= 錯誤分類樣本數(shù)/總樣本數(shù)
當(dāng)Y為多分類時,是和上面相同步驟鞍盗,先求出Y的實際一個值需了,再根據(jù)設(shè)定的閾值,進行判別般甲。
如果需要Strict肋乍, 需要估計每個樣本劃分到這一類的概率,且概率需要>0.5敷存,
Most probable: 則可以根據(jù)樣本劃分到某一類的最大概率來決定。
如某一樣本屬于A:0.4锚烦,B與類都為0.3觅闽, 則這個樣本按strict來說,不能分離涮俄,而Most probable則認為其屬于A類
4.2 SVM
其是可以進行分類和回歸的蛉拙,和RF類似
邊界法(boundary methods)
假設(shè)只有兩類,需要在平面上找出能夠很好劃分兩個的一個超平面彻亲,建議在訓(xùn)練集中找出到所有樣本的最大margin的線(假設(shè)為線性分類器)
線性的分類器: f(x) = w'x + b , w為超平面的
y = sign{f(x)} = [ +1 f(x) ≥ 0
-1 f(x) < 0]
計算最大的margin是計算 2/||w||, ||w||2 = <w, w>
即轉(zhuǎn)化為求最小的1/2*||w||2, 目標為: y(<w, x> + b)≥1孕锄, Vi =1,...,m
這里需要引起拉格朗日(Lagrangian):
L(w, b, λ) = 1/2*||w||2 - sum(λ{y(<w,x>+b>)-1}), Vi, λ≥0, i=1,..m, λ為拉格朗日乘數(shù)(Lagrangian multipliers)
L(w, b, λ)需要最小化w.r.t., w和b; 最大化w.r.t.(λ),
再對w,b 求偏導(dǎo)后吮廉, w=sum(λyx)
再后就出現(xiàn)雙重問題(dual problem),按上述要求小化三個變量,則會出雙重問題:
[maximise sum(λi) - 1/2sumsumλi λj yi yj <xi, xj>
subject to λi≥0, Vi
and sum(λiyi) = 0, (雙重問題)] (1)
凸優(yōu)化問題
需要決策功能解決f(x) = sign(sum(yi λi) <x, xi> +b), 公式意思: 把y的點映射到support vector上面畸肆,然后通過sign函數(shù)來做判斷
其中λi不能為0宦芦,為少量的學(xué)習(xí)向量,如果在margin上的我們成為支持向量(support vector)
所以我們只考慮支持向量的函數(shù): f(x) = sign(sum(yi λi) <x, xisv> +b)
但是在現(xiàn)實中恼除,很多分類都是非線性的
可以加入error cost(C),新的懲罰系數(shù)踪旷, 具有較好的一般性并且承認預(yù)測誤差。
[minimse{1/2||w||2 + Csum(βi)}
maegin最大 分類器最小誤差
subject to y(<w,x> + b ) ≥ 1 - βi豁辉, V1]
松弛變量(slack variable): 從決策功能導(dǎo)出令野, βi = |1-yif(xi)|, 由拉格朗日乘數(shù)法得出在線性分類解徽级,但是0 ≤ λi ≤ C
所以找到最佳超平面和閾值(w, b), 在最大的margin 和懲罰系數(shù)C气破, 需要對一般性和復(fù)雜性進行中和。
如果將數(shù)據(jù)映射到高緯度空間(也確實這么做的)餐抢, 可能會使數(shù)據(jù)更好地劃分
即一個函數(shù)f(q)可以使R→R’(高維空間)现使,即x→f(qx)
上式中的(1)式改為
[maximise sum(λi) - 1/2sumsumλi λj yi yj < f(qxi), f(qxj) >
subject to λi≥0, Vi
and sum(λiyi) = 0, (對偶問題)]
The kernel trick,是 k(xi, xj) = < f(qxi), f(qxj) >
kernel trick 就是核心技巧旷痕,從線性到非線性碳锈, 并且可以在低緯度計算高緯度的數(shù)據(jù),所以就會使上述的公式欺抗,能夠在實際中應(yīng)用售碳,
主要包括: 線性核, 多項式核绞呈, 高斯核贸人, 拉普拉斯核, sigmoid核(此函數(shù)在其ANN算法中也有應(yīng)用)
高斯核應(yīng)用較多: 簡單佃声, 需要計算強度低艺智, 只有一個參數(shù),具有任意復(fù)雜度的數(shù)據(jù)建模能力
在上述中的額主要參數(shù)為: C 懲罰系數(shù)圾亏,確定最大邊界與錯誤率十拣, C值越大, 就不能容忍錯誤志鹃,需要每個樣本都正確分類父晶; C值越小,則相反弄跌,但是邊界會更復(fù)雜甲喝,除非是線性
現(xiàn)在沒有統(tǒng)一說哪種好,需要交叉驗證铛只。
在對多分類時埠胖, 可以采用兩種形式糠溜,
1) One VS. rest 會有K個分類器
2) One VS. one 會有K(K-1)/2
推薦再去看看下面的博客,寫的非常好直撤,但是我還得寫出來自己的理解非竿,就有了這篇不好的博客了
:https://blog.csdn.net/zjuPeco/article/details/77890660
其中的軟間隔,KKT條件(拉格朗日算法發(fā)展)谋竖,我自己沒有寫
最后: 需要注意SVM只有少量的支持向量(在邊界線上的點)為模型的關(guān)鍵红柱,其數(shù)量越少,會使模型更具有一般性和簡單(計算上)
所有其找到一種綜合在最小誤差(Kernel函數(shù))和一般性(最大的w)之間蓖乘。