R语言实现 朴素贝叶斯分类
用R進行樸素貝葉斯分類
- 原理介紹
- 應用領域
- 基于貝葉斯定理的條件概率
- 樸素貝葉斯算法
- Example: Filtering spam SMS messages ----
- Step 1: Exploring and preparing the data ----
- read the sms data into the sms data frame
- examine the structure of the sms data
- convert spam/ham to factor.
- examine the type variable more carefully
- build a corpus using the text mining ('tm') package
- examine the sms corpus
- clean up the corpus using tm_map()
- show the difference between sms_corpus and corpus_clean
- 所有短信字母變成小寫字母&刪除數字
- 刪除停用詞
- 刪除標點符號
- 刪除多于空格
- 觀察一些變換前后的結果
- create a document-term sparse matrix
- creating training and test datasets
- also save the labels
- check that the proportion of spam is similar
- word cloud visualization
- subset the training data into spam and ham groups
- 剔除訓練數據中出現次數少于記錄總數0.1%的單詞
- indicator features for frequent words
- create DTMs with only the frequent terms
- convert counts to a factor
- apply() convert_counts() to columns of train/test data
- Step 2: Training a model on the data ----
- 分類模型建立
- Step 3: Evaluating model performance ----
- Step 4: Improving model performance ----
原理介紹
應用領域
基于貝葉斯方法的分類器是利用訓練數據并根據特征的取值來計算每個類別被觀察到的概率。當分類器之后被應用到無標簽數據時,分類器就會根據觀測到的概率來預測新的特征最有可能屬于哪個類。這是簡單的想法,但根據這種想法就產生了一種方法,這種方法得到的結果與很多復雜算法得到的結果是等價的。事實上,貝葉斯分類器已用于以下方面:
- 文本分類,比如垃圾郵件過濾、作者識別和主題分類等。
- 在計算機網絡中進行入侵檢測或者異常檢測。
- 根據一組觀察到的癥狀,診斷身體狀況。
通常情況下,貝葉斯分類器最適用于解決這樣一類問題:在這類問題中,為了估計一個結果的概率,從眾多屬性中提取的信息應該被同時考慮。盡管很多算法忽略了具有弱影響的一些特征,但是貝葉斯方法利用了所有可以獲得的證據來巧妙地修正預測。如果有大量特征產生的影響較小,但將它們放在一起,它們的組合影響可能會相當大。
基于貝葉斯定理的條件概率
相關事件之間的關系可以用貝葉斯定理來描述,如下面的公式所示。符號P(A|B)表示在事件B已經發生的條件下,事件A發生的概率。這就是條件概率,因為事件A發生的概率依賴于事件B的發生(即條件)。
為了理解貝葉斯定理在實際中的應用,可以假設你的任務是估算收到的電子郵件是垃圾郵件的概率。在沒有任何附加證據的條件下,最合理的猜測就是事先收到垃圾郵件的概率,即前面例子中的20%,這個估計稱為先驗概率。
現在,假設你獲得了一條額外的證據,你被告知收到的電子郵件使用了單詞Viagra,在先前的垃圾郵件中出現單詞Viagra的概率稱為似然概率(likelihood),而單詞Viagra出現在任何一封郵件中的概率稱為邊際似然概率(marginal likelihood)。
將貝葉斯定理應用到這條額外的證據上,我們可以計算后驗概率(posterior),這個概率用來衡量該郵件是垃圾郵件的可能性。如果計算出的后驗概率遠大于50%,則該信息更可能是垃圾信息,應該過濾掉。下面的公式就是對于給定證據的貝葉斯定理:
樸素貝葉斯算法
樸素貝葉斯(Naive Bayes,NB)算法描述應用貝葉斯定理進行分類的一個簡單應用。盡管這不是唯一應用貝葉斯方法的機器學習方法,但它是最常見的,尤其在文本分類應用中已經成為一種準則。該算法的優缺點如下表所示。
樸素貝葉斯算法之所以這樣命名是因為關于數據有一對“簡單”的假設。特別地,樸素貝葉斯假設數據集的所有特征都具有相同的重要性和獨立性,而在大多數的實際應用中,這些假設是鮮有成立的。
舉個例子,假設你試圖通過監控電子郵件來識別垃圾郵件,那么幾乎可以肯定,郵件中的某些特征比其他特征更重要。比如,相對郵件內容來說,電子郵件的發件人是判別垃圾郵件的一個更重要的指標。而且,出現在郵件主體中的詞和主體中的其他詞并不是相互獨立的,因為有些詞的出現正好暗示著其他詞很可能出現。一封含有單詞Viagra的郵件有極大的可能包含單詞prescription 或者drug。
然而,在大多數情況下,當違背這些假設時,樸素貝葉斯依然可以很好地應用,甚至在極端事件中,特征之間具有很強的依賴性時,樸素貝葉斯也可以用。由于該算法的通用性和準確性,適用于很多類型的條件,所以在分類學習任務中,樸素貝葉斯算法往往是很強大的,排在候選算法的第一位。
Example: Filtering spam SMS messages ----
Step 1: Exploring and preparing the data ----
read the sms data into the sms data frame
sms_raw <- read.csv("F:\\rwork\\Machine Learning with R (2nd Ed.)\\Chapter 04\\sms_spam.csv", stringsAsFactors = FALSE)examine the structure of the sms data
str(sms_raw)convert spam/ham to factor.
sms_raw$type <- factor( sms_raw$type )examine the type variable more carefully
str(sms_raw$type) table(sms_raw$type)build a corpus using the text mining (‘tm’) package
library('tm') sms_corpus <- VCorpus(VectorSource(sms_raw$text))#建立語料庫(短信內容)examine the sms corpus
print(sms_corpus) inspect(sms_corpus[1:2])#觀察第一條和第二條短信的概要as.character(sms_corpus[[1]])#觀看第一條短信內容 lapply(sms_corpus[1:2], as.character)clean up the corpus using tm_map()
sms_corpus_clean <- tm_map(sms_corpus, content_transformer(tolower))#全部小寫show the difference between sms_corpus and corpus_clean
as.character(sms_corpus[[1]]) as.character(sms_corpus_clean[[1]])所有短信字母變成小寫字母&刪除數字
corpus_clean <-tm_map(sms_corpus,tolower) sms_corpus_clean <- tm_map(sms_corpus_clean, removeNumbers)刪除停用詞
sms_corpus_clean <- tm_map(sms_corpus_clean, removeWords, stopwords())stopwords里面是to,and,but等一些自帶的一些詞
刪除標點符號
sms_corpus_clean <- tm_map(sms_corpus_clean, removePunctuation)刪除多于空格
sms_corpus_clean <- tm_map(sms_corpus_clean, stripWhitespace)
觀察一些變換前后的結果
lapply(sms_corpus[1:3], as.character) lapply(sms_corpus_clean[1:3], as.character)create a document-term sparse matrix
sms_dtm <- DocumentTermMatrix(sms_corpus_clean)這條命令將語料庫標記化,并返回一個名為sms_dtm的稀疏矩陣。從這里,我們就可以對包括詞頻在內的信息進行分析。
creating training and test datasets
一部分作為訓練數據,一部分作為測試數據
sms_dtm_train <- sms_dtm[1:4169, ] sms_dtm_test <- sms_dtm[4170:5559, ]also save the labels
sms_train_labels <- sms_raw[1:4169, ]$type sms_test_labels <- sms_raw[4170:5559, ]$typecheck that the proportion of spam is similar
prop.table(table(sms_train_labels)) prop.table(table(sms_test_labels))#計算所占比例word cloud visualization
library(wordcloud) wordcloud(sms_corpus_clean, min.freq = 50, random.order = FALSE)
在語料庫最小次數50次;不隨機排列
subset the training data into spam and ham groups
#獲得子集
spam <- subset(sms_raw, type == "spam") ham <- subset(sms_raw, type == "ham")wordcloud(spam$text, max.words = 40, scale = c(3, 0.5))#最常見的40個單詞 wordcloud(ham$text, max.words = 40, scale = c(3, 0.5))剔除訓練數據中出現次數少于記錄總數0.1%的單詞
sms_dtm_freq_train <- removeSparseTerms(sms_dtm_train, 0.999)indicator features for frequent words
找出最少出現5次的單詞
sms_freq_words <- findFreqTerms(sms_dtm_train, 5)create DTMs with only the frequent terms
查看上面篩選過后的詞的頻率
sms_dtm_freq_train <- sms_dtm_train[ , sms_freq_words] sms_dtm_freq_test <- sms_dtm_test[ , sms_freq_words]convert counts to a factor
如果大于1就是Yes
convert_counts <- function(x) {x <- ifelse(x > 0, "Yes", "No")}apply() convert_counts() to columns of train/test data
將語料中不是0的全部換為Yes
sms_train <- apply(sms_dtm_freq_train, MARGIN = 2, convert_counts) sms_test <- apply(sms_dtm_freq_test, MARGIN = 2, convert_counts)Step 2: Training a model on the data ----
分類模型建立
library(e1071) sms_classifier <- naiveBayes(sms_train, sms_train_labels)Step 3: Evaluating model performance ----
sms_test_pred <- predict(sms_classifier, sms_test) library(gmodels) CrossTable(sms_test_pred, sms_test_labels,prop.chisq = FALSE, prop.t = FALSE, prop.r = FALSE,dnn = c('predicted', 'actual'))
發現有6+34=40條短信未被正確分類
Step 4: Improving model performance ----
sms_classifier2 <- naiveBayes(sms_train, sms_train_labels, laplace = 1) sms_test_pred2 <- predict(sms_classifier2, sms_test) CrossTable(sms_test_pred2, sms_test_labels,prop.chisq = FALSE, prop.t = FALSE, prop.r = FALSE,dnn = c('predicted', 'actual'))
改善模型,將拉普拉斯(laplace)值設為1,發現有6+32=38條短信未被正確分類。
雖然從40到38看上去是一個很小的變化,考慮到模型的準確性已經相當好了,這其實是很大的提高。
最終該模型將超過97%的短信正確分成垃圾短信和非垃圾短信。
總結
以上是生活随笔為你收集整理的R语言实现 朴素贝叶斯分类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JavaScript(WebAPI)
- 下一篇: 在UE4中完美导入MMD的动作,表情;基