一文掌握SVM用法(基於R語言)

2021-02-13 生信技能樹

這是生信技能樹 一文 系列推文,前面的目錄:

一文學會WGCNA分析

一文看懂主成分分析

SVM 背景知識

支持向量機,因其英文名為support vector machine,故一般簡稱SVM,就是一種二類分類模型,其基本模型定義為特徵空間上的間隔最大的線性分類器,其學習策略便是間隔最大化,最終可轉化為一個凸二次規劃問題的求解。

看起來這個定義是不是專有名詞太多呀!其實還有要完全理解SVM原理及算法,還需要理解 線性回歸,最小二乘法,邏輯回歸,線性分類器,線性可分,核函數,損失函數,

但是不要怕,不具體理解SVM原理及算法,我們仍然是可以使用它,左右不過是一個分類器罷了,就是根據一堆自變量來預測因變量,所以就是變量預測,值得一提的是,SVM通常應用於二元分類變量預測,但是經過一些改進也可以勉強對多元分類變量預測,同時基於SVM的SVR也可以預測連續變量。

通俗的理解,我們想根據年收入來預測某家庭是貧窮還是富有,可以簡單的按照年收入50萬來進行分類,這個時候就只有一個自變量,就是收入的金額這個數值,因變量也很簡單,就是二元分類情況。只不過通常我們要使用SVM的場景,因變量肯定不止一個,閾值也沒有那麼簡單找到。

SVM示例二元分類變量預測

毫無疑問,生物學領域最經典的二元分類變量就是病人的生死問題啦!

load('~/Documents/Rdata/TCGA-LUAD-survival_input.Rdata')
#

# 首先你會有一個表達矩陣如下,每個病人的每個基因都有表達量。
exprSet[1:4,1:2]
#
#
#
#
#
# 然後你會有這些病人的臨床信息
head(phe)
#
#
#
#
#
#
#
#
#
#
#
#
#
#
# 當然,我這裡舉例就只關心 生死這個情況。
table(phe$event)
#
#
#
# 125個病人去世了,有388活著的。

#
exprSet=mean(colSums(exprSet))*exprSet/colSums(exprSet)
exprSet=log2(exprSet+1)
data=cbind(t(exprSet),phe$event)
colnames(data)[ncol(data)]='event'
data=as.data.frame(data)
data$event=as.factor(data$event)
# 最後得到的data這個變量就可以進入SVM啦。

我們可以先把上面的TCGA-LUAD的miRNA數據集分成50%的訓練集(Train),50%的測試集(Test):

#
require("mlbench")
#
library(e1071)
#
smp.size = floor(0.5*nrow(data)) 
set.seed(123456789)                     
train.ind = sample(seq_len(nrow(data)), smp.size)
train = data[train.ind, ] # 50%
test = data[-train.ind, ] # 50%
table(test$event)
#
#
#
table(train$event)
#
#
#

然後就可以使用svm()訓練分類模型

model = svm(formula = event ~ .,  # 這裡的待預測的變量event是二分類變量,生與死。
            data = train,kernel = "linear")
#
#
summary(model) 
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#

共有9 種核函數,常用的為其中的前四個:linear,Polynomial,RBF,Sigmoid 其中 RBF 適用於因變量比較少,而 linear適用於因變量非常多,也就是本例子裡面的基因非常多,所以我們現在linear。

訓練好的模型,就可以使用predict()函數去測試集裡面看看效果。

train.pred = predict(model, train)
test.pred = predict(model, test)

#
table(real=train$event, predict=train.pred) 
#
#
#
#
confus.matrix = table(real=train$event, predict=train.pred)
sum(diag(confus.matrix))/sum(confus.matrix)
#
# 可以很明顯的看到過擬合現象,在訓練集預測100%。

#
table(real=test$event, predict=test.pred)
#
#
#
#
confus.matrix = table(real=test$event, predict=test.pred)
sum(diag(confus.matrix))/sum(confus.matrix)
#
# 可以看到準確率並不高。

關於模型的各種其它檢驗指標,建議直接閱讀我在生信技能樹分享的文章:https://vip.biotrainee.com/d/812-

多元分類變量預測

SVM算法最初是為二值分類問題設計的,當處理多類問題時,就需要構造合適的多類分類器。目前,構造SVM多類分類器的方法主要有兩類:一類是直接法,直接在目標函數上進行修改,將多個分類面的參數求解合併到一個最優化問題中,通過求解該最優化問題「一次性」實現多類分類。這種方法看似簡單,但其計算複雜度比較高,實現起來比較困難,只適合用於小型問題中;另一類是間接法,主要是通過組合多個二分類器來實現多分類器的構造,常見的方法有one-against-one和one-against-all兩種。

a.一對多法(one-versus-rest,簡稱1-v-r SVMs)。訓練時依次把某個類別的樣本歸為一類,其他剩餘的樣本歸為另一類,這樣k個類別的樣本就構造出了k個SVM。分類時將未知樣本分類為具有最大分類函數值的那類。

b.一對一法(one-versus-one,簡稱1-v-1 SVMs)。其做法是在任意兩類樣本之間設計一個SVM,因此k個類別的樣本就需要設計k(k-1)/2個SVM。當對一個未知樣本進行分類時,最後得 票最多的類別即為該未知樣本的類別。Libsvm中的多類分類就是根據這個方法實現的。

c.層次支持向量機(H-SVMs)。層次分類法首先將所有類別分成兩個子類,再將子類進一步劃分成兩個次級子類,如此循環,直到得到一個單獨的類別為止。


參考:http://www.matlabsky.com/thread-9471-1-1.html 

對於多元分類變量預測例子,我們可以使用mlbench中的數據集Glass來簡單演示,數據集裡面的type變量是6個分類,看下面代碼及輸出結果。

簡單探索一下數據集Glass,裡面記錄著214個觀測值,10個變量。

require("mlbench")
library(e1071)
data(Glass, package="mlbench")
data = Glass

在e1071的包裡面,我們可以直接使用svm()這個函數建模。

同樣的我們可以先把Glass數據集分成80%的訓練集(Train),20%的測試集(Test):

smp.size = floor(0.8*nrow(data)) 
set.seed(123456789)                     
train.ind = sample(seq_len(nrow(data)), smp.size)
train = data[train.ind, ] 
test = data[-train.ind, ] 

然後就可以使用svm()訓練分類模型

model = svm(formula = Type ~ .,  # 這裡的待預測的變量Type必須是Factor
            data = train)
#
summary(model) 
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#
#

訓練好的模型,就可以使用predict()函數去測試集裡面看看效果。

train.pred = predict(model, train)
test.pred = predict(model, test)

#
table(real=train$Type, predict=train.pred) 
#
#
#
#
#
#
#
#
confus.matrix = table(real=train$Type, predict=train.pred)
sum(diag(confus.matrix))/sum(confus.matrix)
#
#
table(real=test$Type, predict=test.pred)
#
#
#
#
#
#
#
#
confus.matrix = table(real=test$Type, predict=test.pred)
sum(diag(confus.matrix))/sum(confus.matrix)
#

SVR預測連續變量

這裡直接摘抄:https://rpubs.com/skydome20/R-Note14-SVM-SVR 的筆記,他講解的非常好!

SVR是本來SVM的延伸型態,能夠處理連續的預測問題。

在e1071套件裡面,並沒有一個函式叫做svr(),而是一樣用svm()。

差別只在於:

這裡簡單手動建立一筆資料:

data = data.frame(x=1:20,
                  y=c(3,4,8,2,6,10,12,13,15,14,17,18,20,17,21,22,25,30,29,31))


plot(data$x, data$y, pch=16, xlab="X", ylab="Y")

img

我們可以先拉一條簡單的線性迴歸:

model <- lm(y ~ x , data) 


lm.pred = predict(model, data)


plot(data$x, data$y, pch=16, xlab="X", ylab="Y")

points(lm.pred, pch=2, col="red")
abline(model, col="red")

img

我們可以直接用SVR來建模、預測:

model <- svm(y ~ x , data) 


svr.pred = predict(model, data)


plot(data$x, data$y, pch=16, xlab="X", ylab="Y")

points(svr.pred, pch=4, col="blue")

img

最後比較一下線性迴歸和SVR的表現,同時計算RMSE(root mean square error):


plot(data$x, data$y, pch=16, xlab="X", ylab="Y")

points(lm.pred, pch=2, col="red")

points(svr.pred, pch=4, col="blue")

img


c(sqrt(mean((data$y - lm.pred)^2)),
  sqrt(mean((data$y - svr.pred)^2))
)

可以發現到,在這個例子,SVR比lm的效果還要好一些些(1.79 < 1.91)。

其實還有交叉驗證,以及AUV等,不過它們已經算是單獨知識點,就不混在SVM裡面一起講解了。

如果你看到這裡,會發現,使用SVM在你自己的數據是一件很簡單的事情啦,只需要給一個矩陣和一個變量即可,這個變量可以是二元分類或者是多分類,甚至可以是連續變量,其餘的代碼都不需要怎麼修改就能跟著我完成svm的應用。

歡迎大家提出自己的想法,或者發郵件跟作者交流

相關焦點

  • 掌握R語言for循環一文就夠了(認真臉)
    R語言不考慮並行運算下的簡單批處理實現方式就是for循環。所以,今天就來教大家怎樣掌握R語言的for循環o(^▽^)o首先,你需要一個R,百度"R"就行,點擊有官網標識的網站,進去下載就行4列的data.frame每一列依次是某一行的行名、與前者進行相關分析的另一行的行名、pearson相關係數、P值,那麼讓我們開始~N1=c("gene1") #首先把最後4列的data.frame表頭設定好,我這裡用基因1表示,可以隨你換N2=c("gene2
  • R語言:機器學習程序包
    GAMMoost包提供基於boosting的廣義相加模型(generalized additive models)的程序(http://cran.r-project.org/web/packages/GAMMoost/index.html)。
  • R語言向量化運算:apply函數族用法心得
    R語言和Python的忠實擁躉,為成為一名未來的數據科學家而奮鬥終生。個人公眾號:數據科學家養成記 (微信ID:louwill12)當初入坑R語言的時候,就在各種場合看到老司機的忠告,「儘量避免使用循環!」一開始並不明白這其中的奧義,直到後來對R語言有深入接觸後,才領會R語言在向量化運算方面的強大功能。本篇內容就總結小編在使用R語言向量化運算apply函數族的一些心得體會。
  • 【典型算法】SVM算法
    小編說:機器學習算法眾多,全部掌握,一則不可能,二則沒必要。如何靈活掌握和應用機器學習算法呢?
  • 一文讀懂支持向量機SVM(附實現代碼、公式)
    -',x,y+1,'r--');title(['鬆弛變量範圍C = ',num2str(C)]);程序中設置了鬆弛變量前的係數C是事先規定的,表明鬆弛變量項的影響程度大小。基於此,那麼對於上節的SMO算法,如果拿來求解非線性數據的話,我們只需要將其中對應的內積部分改成核函數的形式即可。
  • 使用sklearn-svm進行多分類
    在上一期5分鐘學會使用支持向量機 (Using SVM)的文章中,我們講述了LibSVM的基本用法,那個時候我們針對的分類問題是二分類。
  • R語言從入門到精通:Day16(機器學習)
    其實不然,在R語言和Python語言當中都有專門的包可以直接調用。今天我們就來給大家講講R語言當中的機器學習,我可以保證,如果你能夠學會本節的話,一定會給你的研究帶來極大的助力。-- 測試數據和代碼見文末客服二維碼在上一次教程中,我們介紹了把觀測值凝聚成子組的常見聚類方法。
  • R語言從入門到精通:Day6-R語言數據操作進階及控制結構
    最近經過前面幾次推文的學習,我們的R語言教程已經講解了快1/3的內容,相信大家對R語言已經有了初步的了解,特別是感受了R語言在數據處理領域的強大功能
  • 機器學習 · R語言包大全(共99個包)
    有很多R語言包都可以實現機器學習相關的思想和方法。,可回復「深度學習」查看統計諮詢公眾號前期的文章《Deep Learning in R · R語言深度學習》。deepnet:前饋神經網絡、限制玻爾茲曼機、深度信念網絡、堆疊自動編碼機RcppDL:去噪自動編碼機、堆疊去噪自動編碼機、限制玻爾茲曼機、深度信念網絡h2o:前饋神經網絡、深度自動編碼機  遞歸劃分    Recursive Partitioning  rpart
  • SVM大解密(連載四)
    我們是在樣本上做的文章,我把非線性樣本變成線性樣本,再去把變化後的線性樣本拿去分類,經過這麼一圈,就達到了把非線性樣本分開的目的,所以只看開頭和結尾的話發現,SVM竟然可以分非線性問題,其實呢還是分的線性問題。
  • 基於線性SVM的CIFAR-10圖像集分類
    也就是說儘量讓正負樣本距離分類超平面有足夠寬的間隔,這是基於距離的衡量優化方式。針對上文提到的例子,圖片真實標籤是一隻貓,但是得到的s值卻是最低的,顯然這不是我們希望看到的。最好的情況應該是cat score最高。這樣才能保證預測cat的概率更大。此時,利用SVM的間隔最大化的思想,就要求cat score不僅僅要大於其它類別的s值,而且要達到一定的程度,可以說有個最低閾值。
  • 一堆R語言學習資料
    Regularization paths for SCAD- and MCP-penalized regression modelsnnet - eed-forward Neural Networks and Multinomial Log-Linear Modelsoblique.tree - Oblique Trees for Classification Datapamr
  • 中小學英語必考:一文掌握定冠詞 the 的用法|智學君中小學英語
    今天智學君中小學英語就冠詞裡面的定冠詞the給中小學生朋友做個歸納總結,讓各位中小學生朋友一文掌握定冠詞the的用法 看起來冠詞很簡單,只有a,an,the三個單詞,但由於國人的語言習慣大不相同,要徹底掌握和用好冠詞,還是要仔細花時間去研究學習一下。定冠詞(the)和不定冠詞(a,an)不能離開名詞而單獨存在, 都置於名詞之前,用來說明名詞所表示的人或事物。
  • 【資源】Python實現多種模型(Naive Bayes, SVM, CNN, LSTM, etc)用於推文情感分析
    【導讀】近日,Abdul Fatir 在自己的CS5228課程報告使用不同的方法進行Tweets情感分析(作為二分類問題),並對這些方法的性能進行比較,主要是基於
  • 關注 | R語言從入門到精通:Day4-R語言數據導入測試代碼及數據
    這些數據類型在我們運用R語言解決實際問題的時候都非常有用,在上節的例子中我們是在R裡面直接生成的數據,但是實際數據分析中,如何快速靈活的讀取和處理多種格式的外部數據呢?這節課的主要內容,我們就來講講R語言中數據的讀取。1、本節內容重點內容較多,      務必緊跟紅色標記。2、測試數據及代碼      見文末客服小姐姐二維碼。
  • 關於支持向量機(SVM)的原理,你了解多少?(萬字長文 速收)
    3.6.1、文本分類     一個文本分類系統不僅是一個自然語言處理系統,也是一個典型的模式識別系統,系統的輸入是需要進行分類處理的文本,系統的輸出則是與文本關聯的類別。由於篇幅所限,其它更具體內容本文將不再詳述。
  • 【Matlab】SVM與RBF-NN(下)
    查看模型參數設置使用model.Parameters方法:ans =         0    2.0000    3.0000    2.8000         0對應著-s(svm類型)、-t(核函數類型)、-d(degree參數)、-g(gamma參數設置)、-r(核函數coef0參數設置)的參數值。
  • Python機器學習筆記:SVM-sklearn實現 (4)FlyAI
    上一節我學習了SVM的推導過程,對SVM的概念理清楚後,下面我們對其使用sklearn進行實現。1.
  • 零基礎也教你玩轉SVM
    一 SVM簡介    支持向量機(support vector machines, SVM)是一種二分類模型,它的基本模型是定義在特徵空間上的間隔最大的線性分類器,間隔最大使它有別於感知機;它分類的思想是,給定給一個包含正例和反例的樣本集合,SVM的目的是尋找一個超平面來對樣本根據正例和反例進行分割。
  • R語言做深度學習
    它是RStudio公司開發一個R包,是Keras深度學習框架的R語言接口,利用這個包,就可以在R平臺上面編寫代碼,使用這個高級的神經網絡API。 Keras的開發重點是實現快速實驗,支持基於卷積的網絡和循環網絡(以及兩者的組合),並在CPU和GPU設備上無縫運行。如何用R語言做深度學習?