成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

機(jī)器學(xué)習(xí)項(xiàng)目:構(gòu)建垃圾郵件分類

xcc3641 / 3294人閱讀

摘要:幾乎所有大型電子郵箱服務(wù)提供商都內(nèi)置了垃圾郵件檢測系統(tǒng),能夠自動(dòng)將此類郵件分類為垃圾郵件。大多數(shù)機(jī)器學(xué)習(xí)算法都要求傳入的輸入是數(shù)字?jǐn)?shù)據(jù),而電子郵件信息通常都是文本。

我們的任務(wù)

垃圾郵件檢測是機(jī)器學(xué)習(xí)在現(xiàn)今互聯(lián)網(wǎng)領(lǐng)域的主要應(yīng)用之一。幾乎所有大型電子郵箱服務(wù)提供商都內(nèi)置了垃圾郵件檢測系統(tǒng),能夠自動(dòng)將此類郵件分類為“垃圾郵件”。

在此項(xiàng)目中,我們將使用樸素貝葉斯算法創(chuàng)建一個(gè)模型,該模型會(huì)通過我們對模型的訓(xùn)練將信息數(shù)據(jù)集分類為垃圾信息或非垃圾信息。對垃圾文本信息進(jìn)行大致了解十分重要。通常它們都包含“免費(fèi)”、“贏取”、“獲獎(jiǎng)?wù)摺?、“現(xiàn)金”、“獎(jiǎng)品”等字眼,因?yàn)檫@些它們專門用來吸引你的注意力,誘惑你打開信息。此外,垃圾信息的文字一般都使用大寫形式和大量感嘆號。收信人能輕易辨認(rèn)垃圾信息,而我們的目標(biāo)是訓(xùn)練模型幫助我們識別垃圾信息!

能夠識別垃圾信息是一種二元分類問題,因?yàn)榇颂幮畔⒅挥小袄畔ⅰ被颉胺抢畔ⅰ边@兩種分類。此外,這是一種監(jiān)督式學(xué)習(xí)問題,因?yàn)槲覀儠?huì)向模型中提供帶標(biāo)簽數(shù)據(jù)集,模型能夠從中學(xué)習(xí)規(guī)律并在日后做出預(yù)測。

第 0 步:樸素貝葉斯定理簡介

貝葉斯定理是最早的概率推理算法之一,由 Reverend Bayes 提出(他用來推理上帝是否存在),該定理在某些用例中依然很有用。

理解該定理的最佳方式是通過一個(gè)例子來講解。假設(shè)你是一名特勤人員,你接到任務(wù),需要在共和黨總統(tǒng)候選人的某次競選演說中保護(hù)他/她的安全。這場競選演說是所有人都可以參加的公開活動(dòng),你的任務(wù)并不簡單,需要時(shí)刻注意危險(xiǎn)是否存在。一種方式是對每個(gè)人都設(shè)定一個(gè)威脅因子,根據(jù)人的特征(例如年齡、性別,是否隨身帶包以及緊張程度等等),你可以判斷此人是否存在威脅。

如果某人符合所有這些特征,已經(jīng)超出了你內(nèi)心中的疑慮閾值,你可以采取措施并將此人帶離活動(dòng)現(xiàn)場。貝葉斯定理的原理也是如此,我們將根據(jù)某些相關(guān)事件(某人的年齡、性別、是否帶包了、緊張程度等)的發(fā)生概率計(jì)算某個(gè)事件(某人存在威脅)的概率。

你還需要考慮這些特征之間的獨(dú)立性。例如,如果在活動(dòng)現(xiàn)場,有個(gè)孩子看起來很緊張,那么與緊張的成人相比,孩子存在威脅的可能性會(huì)更低。為了深入講解這一點(diǎn),看看下面兩個(gè)特征:年齡和緊張程度。假設(shè)我們多帶帶研究這些特征,我們可以設(shè)計(jì)一個(gè)將所有緊張的人視作潛在威脅人士的模型。但是,很有可能會(huì)有很多假正例,因?yàn)楝F(xiàn)場的未成年人很有可能會(huì)緊張。因此同時(shí)考慮年齡和“緊張程度”特征肯定會(huì)更準(zhǔn)確地反映哪些人存在威脅。

這就是該定理的“樸素”一詞的含義,該定理會(huì)認(rèn)為每個(gè)特征相互之間都保持獨(dú)立,但實(shí)際上并非始終是這樣,因此會(huì)影響到最終的結(jié)論。

簡而言之,貝葉斯定理根據(jù)某些其他事件(在此例中是信息被分類為垃圾信息)的聯(lián)合概率分布計(jì)算某個(gè)事件(在此例中是信息為垃圾信息)的發(fā)生概率。稍后我們將深入了解貝葉斯定理的原理,但首先了解下我們將處理的數(shù)據(jù)。

第 1.1 步:了解我們的數(shù)據(jù)集

我們將使用來自 UCI 機(jī)器學(xué)習(xí)資源庫中的數(shù)據(jù)集,該資源庫有大量供實(shí)驗(yàn)性研究的精彩數(shù)據(jù)集。這是直接數(shù)據(jù)鏈接。

下面是該數(shù)據(jù)的預(yù)覽:

數(shù)據(jù)集中的列目前沒有命名,可以看出有 2 列。

第一列有兩個(gè)值:“ham”,表示信息不是垃圾信息,以及“spam”,表示信息是垃圾信息。

第二列是被分類的信息的文本內(nèi)容。

 說明:

使用 read_table 方法可以將數(shù)據(jù)集導(dǎo)入 pandas 數(shù)據(jù)幀。因?yàn)檫@是一個(gè)用制表符分隔的數(shù)據(jù)集,因此我們將使用“t”作為“sep”參數(shù)的值,表示這種分隔格式。

此外,通過為 read_table() 的“names”參數(shù)指定列表 ["label", "sms_message"],重命名列。

用新的列名輸出數(shù)據(jù)幀的前五個(gè)值。

"""
Solution
"""
import pandas as pd
# Dataset from - https://archive.ics.uci.edu/ml/datasets/SMS+Spam+Collection
df = pd.read_table("smsspamcollection/SMSSpamCollection", sep="	", names=["label", "sms_message"])

# Output printing out first 5 columns
df.head()
label sms_message
0 ham Go until jurong point, crazy.. Available only ...
1 ham Ok lar... Joking wif u oni...
2 spam Free entry in 2 a wkly comp to win FA Cup fina...
3 ham U dun say so early hor... U c already then say...
4 ham Nah I don"t think he goes to usf, he lives aro...
第 1.2 步:數(shù)據(jù)預(yù)處理

我們已經(jīng)大概了解數(shù)據(jù)集的結(jié)構(gòu),現(xiàn)在將標(biāo)簽轉(zhuǎn)換為二元變量,0 表示“ham”(即非垃圾信息),1表示“spam”,這樣比較方便計(jì)算。

你可能會(huì)疑問,為何要執(zhí)行這一步?答案在于 scikit-learn 處理輸入的方式。Scikit-learn 只處理數(shù)字值,因此如果標(biāo)簽值保留為字符串,scikit-learn 會(huì)自己進(jìn)行轉(zhuǎn)換(更確切地說,字符串標(biāo)簽將轉(zhuǎn)型為未知浮點(diǎn)值)。

如果標(biāo)簽保留為字符串,模型依然能夠做出預(yù)測,但是稍后計(jì)算效果指標(biāo)(例如計(jì)算精確率和召回率分?jǐn)?shù))時(shí)可能會(huì)遇到問題。因此,為了避免稍后出現(xiàn)意外的陷阱,最好將分類值轉(zhuǎn)換為整數(shù),再傳入模型中。

說明:

使用映射方法將“標(biāo)簽”列中的值轉(zhuǎn)換為數(shù)字值,如下所示:

{"ham":0, "spam":1} 這樣會(huì)將“ham”值映射為 0,將“spam”值映射為 1。

此外,為了知道我們正在處理的數(shù)據(jù)集有多大,使用“shape”輸出行數(shù)和列數(shù)

"""
Solution
"""
print(df.shape)
df["label"] = df.label.map({"ham":0, "spam":1})
(5572, 2)


df["label"].head()
0    0
1    0
2    1
3    0
4    0
Name: label, dtype: int64


第 2.1 步:Bag of words

我們的數(shù)據(jù)集中有大量文本數(shù)據(jù)(5,572 行數(shù)據(jù))。大多數(shù)機(jī)器學(xué)習(xí)算法都要求傳入的輸入是數(shù)字?jǐn)?shù)據(jù),而電子郵件/信息通常都是文本。

現(xiàn)在我們要介紹 Bag of Words (BoW) 這個(gè)概念,它用來表示要處理的問題具有“大量單詞”或很多文本數(shù)據(jù)。BoW 的基本概念是拿出一段文本,計(jì)算該文本中單詞的出現(xiàn)頻率。注意:BoW 平等地對待每個(gè)單詞,單詞的出現(xiàn)順序并不重要。

利用我們將介紹的流程,我們可以將文檔集合轉(zhuǎn)換成矩陣,每個(gè)文檔是一行,每個(gè)單詞(令牌)是一列,對應(yīng)的(行,列)值是每個(gè)單詞或令牌在此文檔中出現(xiàn)的頻率。

例如:

假設(shè)有四個(gè)如下所示的文檔:

`["Hello, how are you!",
"Win money, win from home.",
"Call me now",
"Hello, Call you tomorrow?"]`

我們的目標(biāo)是將這組文本轉(zhuǎn)換為頻率分布矩陣,如下所示:

從圖中可以看出,文檔在行中進(jìn)行了編號,每個(gè)單詞是一個(gè)列名稱,相應(yīng)的值是該單詞在文檔中出現(xiàn)的頻率。

我們詳細(xì)講解下,看看如何使用一小組文檔進(jìn)行轉(zhuǎn)換。

要處理這一步,我們將使用 sklearns
count vectorizer 方法,該方法的作用如下所示:

它會(huì)令牌化字符串(將字符串劃分為單個(gè)單詞)并為每個(gè)令牌設(shè)定一個(gè)整型 ID。

它會(huì)計(jì)算每個(gè)令牌的出現(xiàn)次數(shù)。

請注意:

CountVectorizer 方法會(huì)自動(dòng)將所有令牌化單詞轉(zhuǎn)換為小寫形式,避免區(qū)分“He”和“he”等單詞。為此,它會(huì)使用參數(shù) lowercase,該參數(shù)默認(rèn)設(shè)為 True。

它還會(huì)忽略所有標(biāo)點(diǎn)符號,避免區(qū)分后面有標(biāo)點(diǎn)的單詞(例如“hello!”)和前后沒有標(biāo)點(diǎn)的同一單詞(例如“hello”)。為此,它會(huì)使用參數(shù) token_pattern,該參數(shù)使用默認(rèn)正則表達(dá)式選擇具有 2 個(gè)或多個(gè)字母數(shù)字字符的令牌。

要注意的第三個(gè)參數(shù)是 stop_words。停用詞是指某個(gè)語言中最常用的字詞,包括“am”、“an”、“and”、“the”等。 通過將此參數(shù)值設(shè)為 english,CountVectorizer 將自動(dòng)忽略(輸入文本中)出現(xiàn)在 scikit-learn 中的內(nèi)置英語停用詞列表中的所有單詞。這非常有用,因?yàn)楫?dāng)我們嘗試查找表明是垃圾內(nèi)容的某些單詞時(shí),停用詞會(huì)使我們的結(jié)論出現(xiàn)偏差。

我們將在之后的步驟中深入講解在模型中應(yīng)用每種預(yù)處理技巧的效果,暫時(shí)先知道在處理文本數(shù)據(jù)時(shí),有這些預(yù)處理技巧可采用。

第 2.2 步:從頭實(shí)現(xiàn) Bag of Words

在深入了解幫助我們處理繁重工作的 scikit-learn 的 Bag of Words(BoW) 庫之前,首先我們自己實(shí)現(xiàn)該步驟,以便了解該庫的背后原理。

第 1 步:將所有字符串轉(zhuǎn)換成小寫形式。

假設(shè)有一個(gè)文檔集合:

documents = ["Hello, how are you!",
             "Win money, win from home.",
             "Call me now.",
             "Hello, Call hello you tomorrow?"]
 說明:

將文檔集合中的所有字符串轉(zhuǎn)換成小寫形式。將它們保存到叫做“l(fā)ower_case_documents”的列表中。你可以使用 lower() 方法在 python 中將字符串轉(zhuǎn)換成小寫形式。

"""
Solution:
"""
documents = ["Hello, how are you!",
             "Win money, win from home.",
             "Call me now.",
             "Hello, Call hello you tomorrow?"]

lower_case_documents = []
for i in documents:
    i = i.lower()
    lower_case_documents.append(i)
print(lower_case_documents)
["hello, how are you!", "win money, win from home.", "call me now.", "hello, call hello you tomorrow?"]

第 2 步:刪除所有標(biāo)點(diǎn)符號

說明:
刪除文檔集合中的字符串中的所有標(biāo)點(diǎn)。將它們保存在叫做“sans_punctuation_documents”的列表中。
"""
Solution:
"""
sans_punctuation_documents = []
import string

for i in lower_case_documents:
    # TODO
    i = i.translate(str.maketrans("", "", string.punctuation))
    sans_punctuation_documents.append(i)
    
print(sans_punctuation_documents)
["hello how are you", "win money win from home", "call me now", "hello call hello you tomorrow"]

第 3 步:令牌化

令牌化文檔集合中的句子是指使用分隔符將句子拆分成單個(gè)單詞。分隔符指定了我們將使用哪個(gè)字符來表示單詞的開始和結(jié)束位置(例如,我們可以使用一個(gè)空格作為我們的文檔集合的單詞分隔符。)

說明:
使用 split() 方法令牌化“sans_punctuation_documents”中存儲(chǔ)的字符串,并將最終文檔集合存儲(chǔ)在叫做“preprocessed_documents”的列表中。
"""
Solution:
"""
preprocessed_documents = []
for i in sans_punctuation_documents:
    i = i.split(" ")
    preprocessed_documents.append(i)
print(preprocessed_documents)
[["hello", "how", "are", "you"], ["win", "money", "win", "from", "home"], ["call", "me", "now"], ["hello", "call", "hello", "you", "tomorrow"]]

第 4 步:計(jì)算頻率

我們已經(jīng)獲得所需格式的文檔集合,現(xiàn)在可以數(shù)出每個(gè)單詞在文檔集合的每個(gè)文檔中出現(xiàn)的次數(shù)了。為此,我們將使用 Python collections 庫中的 Counter 方法。

Counter 會(huì)數(shù)出列表中每項(xiàng)的出現(xiàn)次數(shù),并返回一個(gè)字典,鍵是被數(shù)的項(xiàng)目,相應(yīng)的值是該項(xiàng)目在列表中的計(jì)數(shù)。

說明:
使用 Counter() 方法和作為輸入的 preprocessed_documents 創(chuàng)建一個(gè)字典,鍵是每個(gè)文檔中的每個(gè)單詞,相應(yīng)的值是該單詞的出現(xiàn)頻率。將每個(gè) Counter 字典當(dāng)做項(xiàng)目另存到一個(gè)叫做“frequency_list”的列表中。
"""
Solution
"""
frequency_list = []
import pprint
from collections import Counter

for i in preprocessed_documents:
    #TODO
    frequency_list.append(Counter(i))
    
pprint.pprint(frequency_list)
[Counter({"hello": 1, "how": 1, "are": 1, "you": 1}),
 Counter({"win": 2, "money": 1, "from": 1, "home": 1}),
 Counter({"call": 1, "me": 1, "now": 1}),
 Counter({"hello": 2, "call": 1, "you": 1, "tomorrow": 1})]

恭喜!你從頭實(shí)現(xiàn)了 Bag of Words 流程!正如在上一個(gè)輸出中看到的,我們有一個(gè)頻率分布字典,清晰地顯示了我們正在處理的文本。

我們現(xiàn)在應(yīng)該充分理解 scikit-learn 中的 sklearn.feature_extraction.text.CountVectorizer 方法的背后原理了。

我們將在下一步實(shí)現(xiàn) sklearn.feature_extraction.text.CountVectorizer 方法。

第 2.3 步:在 scikit-learn 中實(shí)現(xiàn) Bag of Words

我們已經(jīng)從頭實(shí)現(xiàn)了 BoW 概念,并使用 scikit-learn 以簡潔的方式實(shí)現(xiàn)這一流程。我們將使用在上一步用到的相同文檔集合。

"""
Here we will look to create a frequency matrix on a smaller document set to make sure we understand how the 
document-term matrix generation happens. We have created a sample document set "documents".
"""
documents = ["Hello, how are you!",
                "Win money, win from home.",
                "Call me now.",
                "Hello, Call hello you tomorrow?"]
說明:
導(dǎo)入 sklearn.feature_extraction.text.CountVectorizer 方法并創(chuàng)建一個(gè)實(shí)例,命名為 "count_vector"。
"""
Solution
"""
from sklearn.feature_extraction.text import CountVectorizer
count_vector = CountVectorizer()

使用 CountVectorizer() 預(yù)處理數(shù)據(jù)

在第 2.2 步,我們從頭實(shí)現(xiàn)了可以首先清理數(shù)據(jù)的 CountVectorizer() 方法。清理過程包括將所有數(shù)據(jù)轉(zhuǎn)換為小寫形式,并刪除所有標(biāo)點(diǎn)符號。CountVectorizer() 具有某些可以幫助我們完成這些步驟的參數(shù),這些參數(shù)包括:

lowercase = True

lowercase 參數(shù)的默認(rèn)值為 True,它會(huì)將所有文本都轉(zhuǎn)換為小寫形式。

token_pattern = (?u)ww+

token_pattern 參數(shù)具有默認(rèn)正則表達(dá)式值 (?u)ww+,它會(huì)忽略所有標(biāo)點(diǎn)符號并將它們當(dāng)做分隔符,并將長度大于等于 2 的字母數(shù)字字符串當(dāng)做單個(gè)令牌或單詞。

stop_words

stop_words 參數(shù)如果設(shè)為 english,將從文檔集合中刪除與 scikit-learn 中定義的英語停用詞列表匹配的所有單詞??紤]到我們的數(shù)據(jù)集規(guī)模不大,并且我們處理的是信息,并不是電子郵件這樣的更龐大文本來源,因此我們將不設(shè)置此參數(shù)值。

你可以通過如下所示輸出 count_vector 對象,查看該對象的所有參數(shù)值:

"""
Practice node:
Print the "count_vector" object which is an instance of "CountVectorizer()"
"""
print(count_vector)
CountVectorizer(analyzer="word", binary=False, decode_error="strict",
        dtype=, encoding="utf-8", input="content",
        lowercase=True, max_df=1.0, max_features=None, min_df=1,
        ngram_range=(1, 1), preprocessor=None, stop_words=None,
        strip_accents=None, token_pattern="(?u)ww+",
        tokenizer=None, vocabulary=None)

說明:
使用 fit() 將你的文檔數(shù)據(jù)集與 CountVectorizer 對象進(jìn)行擬合,并使用 get_feature_names() 方法獲得被歸類為特征的單詞列表。
"""
Solution:
"""
count_vector.fit(documents)
count_vector.get_feature_names()
["are",
 "call",
 "from",
 "hello",
 "home",
 "how",
 "me",
 "money",
 "now",
 "tomorrow",
 "win",
 "you"]


get_feature_names() 方法會(huì)返回此數(shù)據(jù)集的特征名稱,即組成 "documents" 詞匯表的單詞集合。

**
說明:**
創(chuàng)建一個(gè)矩陣,行是 4 個(gè)文檔中每個(gè)文檔的行,列是每個(gè)單詞。對應(yīng)的值(行,列)是該單詞(在列中)在特定文檔(在行中)中出現(xiàn)的頻率。為此,你可以使用 transform() 方法并傳入文檔數(shù)據(jù)集作為參數(shù)。transform() 方法會(huì)返回一個(gè) numpy 整數(shù)矩陣,你可以使用 toarray() 將其轉(zhuǎn)換為數(shù)組,稱之為 "doc_array"
"""
Solution
"""
doc_array = count_vector.transform(documents).toarray()
doc_array
array([[1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1],
       [0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 2, 0],
       [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0],
       [0, 1, 0, 2, 0, 0, 0, 0, 0, 1, 0, 1]])


現(xiàn)在,對于單詞在文檔中的出現(xiàn)頻率,我們已經(jīng)獲得了整潔的文檔表示形式。為了方便理解,下一步我們會(huì)將此數(shù)組轉(zhuǎn)換為數(shù)據(jù)幀,并相應(yīng)地為列命名。

說明:
將我們獲得并加載到 "doc_array" 中的數(shù)組轉(zhuǎn)換為數(shù)據(jù)幀,并將列名設(shè)為單詞名稱(你之前使用 get_feature_names() 計(jì)算了名稱)。將該數(shù)據(jù)幀命名為 "frequency_matrix"。
"""
Solution
"""
frequency_matrix = pd.DataFrame(doc_array, columns = count_vector.get_feature_names())
frequency_matrix
are call from hello home how me money now tomorrow win you
0 1 0 0 1 0 1 0 0 0 0 0 1
1 0 0 1 0 1 0 0 1 0 0 2 0
2 0 1 0 0 0 0 1 0 1 0 0 0
3 0 1 0 2 0 0 0 0 0 1 0 1

恭喜!你為我們創(chuàng)建的文檔數(shù)據(jù)集成功地實(shí)現(xiàn)了 Bag of Words 問題。

直接使用該方法的一個(gè)潛在問題是如果我們的文本數(shù)據(jù)集非常龐大(假設(shè)有一大批新聞文章或電子郵件數(shù)據(jù)),由于語言本身的原因,肯定有某些值比其他值更常見。例如“is”、“the”、“an”等單詞、代詞、語法結(jié)構(gòu)等會(huì)使矩陣出現(xiàn)偏斜并影響到分析結(jié)果。

有幾種方式可以減輕這種情況。一種方式是使用 stop_words 參數(shù)并將其值設(shè)為 english。這樣會(huì)自動(dòng)忽略 scikit-learn 中的內(nèi)置英語停用詞列表中出現(xiàn)的所有單詞(來自輸入文本)。

另一種方式是使用 tfidf 方法。該方法已經(jīng)超出了這門課程的講解范疇。

第 3.1 步:訓(xùn)練集和測試集

我們已經(jīng)知道如何處理 Bag of Words 問題,現(xiàn)在回到我們的數(shù)據(jù)集并繼續(xù)我們的分析工作。第一步是將數(shù)據(jù)集拆分為訓(xùn)練集和測試集,以便稍后測試我們的模型。

說明:
通過在 sklearn 中使用 train_test_split 方法,將數(shù)據(jù)集拆分為訓(xùn)練集和測試集。使用以下變量拆分?jǐn)?shù)據(jù):

X_train 是 "sms_message" 列的訓(xùn)練數(shù)據(jù)。

y_train 是 "label" 列的訓(xùn)練數(shù)據(jù)

X_test 是 "sms_message" 列的測試數(shù)據(jù)。

y_test 是 "label" 列的測試數(shù)據(jù)。

輸出每個(gè)訓(xùn)練數(shù)據(jù)和測試數(shù)據(jù)的行數(shù)。

"""
Solution

NOTE: sklearn.cross_validation will be deprecated soon to sklearn.model_selection 
"""
# split into training and testing sets
# USE from sklearn.model_selection import train_test_split to avoid seeing deprecation warning.
from sklearn.cross_validation import train_test_split

X_train, X_test, y_train, y_test = train_test_split(df["sms_message"], 
                                                    df["label"], 
                                                    random_state=1)

print("Number of rows in the total set: {}".format(df.shape[0]))
print("Number of rows in the training set: {}".format(X_train.shape[0]))
print("Number of rows in the test set: {}".format(X_test.shape[0]))
Number of rows in the total set: 5572
Number of rows in the training set: 4179
Number of rows in the test set: 1393

第 3.2 步:對數(shù)據(jù)集應(yīng)用 Bag of Words 流程。

我們已經(jīng)拆分了數(shù)據(jù),下個(gè)目標(biāo)是按照第 2 步:Bag of words 中的步驟操作,并將數(shù)據(jù)轉(zhuǎn)換為期望的矩陣格式。為此,我們將像之前一樣使用 CountVectorizer()。我們需要完成兩步:

首先,我們需要對 CountVectorizer()擬合訓(xùn)練數(shù)據(jù) (X_train) 并返回矩陣。

其次,我們需要轉(zhuǎn)換測試數(shù)據(jù) (X_test) 以返回矩陣。

注意:X_train 是數(shù)據(jù)集中 "sms_message" 列的訓(xùn)練數(shù)據(jù),我們將使用此數(shù)據(jù)訓(xùn)練模型。

X_test 是 "sms_message" 列的測試數(shù)據(jù),我們將使用該數(shù)據(jù)(轉(zhuǎn)換為矩陣后)進(jìn)行預(yù)測。然后在后面的步驟中將這些預(yù)測與 y_test 進(jìn)行比較。

我們暫時(shí)為你提供了進(jìn)行矩陣轉(zhuǎn)換的代碼!

"""
[Practice Node]

The code for this segment is in 2 parts. Firstly, we are learning a vocabulary dictionary for the training data 
and then transforming the data into a document-term matrix; secondly, for the testing data we are only 
transforming the data into a document-term matrix.

This is similar to the process we followed in Step 2.3

We will provide the transformed data to students in the variables "training_data" and "testing_data".
"""
"""
Solution
"""
# Instantiate the CountVectorizer method
count_vector = CountVectorizer()

# Fit the training data and then return the matrix
training_data = count_vector.fit_transform(X_train)

# Transform testing data and return the matrix. Note we are not fitting the testing data into the CountVectorizer()
testing_data = count_vector.transform(X_test)
第 4.1 步:從頭實(shí)現(xiàn)貝葉斯定理

我們的數(shù)據(jù)集已經(jīng)是我們希望的格式,現(xiàn)在可以進(jìn)行任務(wù)的下一步了,即研究用來做出預(yù)測并將信息分類為垃圾信息或非垃圾信息的算法。記得在該項(xiàng)目的開頭,我們簡要介紹了貝葉斯定理,現(xiàn)在我們將深入講解該定理。通俗地說,貝葉斯定理根據(jù)與相關(guān)事件有關(guān)的其他事件的概率計(jì)算該事件的發(fā)生概率。它由先驗(yàn)概率(我們知道的概率或提供給我們的概率)和后驗(yàn)概率(我們希望用先驗(yàn)部分計(jì)算的概率)組成。

我們用一個(gè)簡單的示例從頭實(shí)現(xiàn)貝葉斯定理。假設(shè)我們要根據(jù)某人接受糖尿病檢測后獲得陽性結(jié)果計(jì)算此人有糖尿病的概率。
在醫(yī)學(xué)領(lǐng)域,此類概率非常重要,因?yàn)樗鼈兩婕暗氖巧狼闆r。

我們假設(shè):

P(D) 是某人患有糖尿病的概率。值為 0.01,換句話說,普通人群中有 1% 的人患有糖尿?。庳?zé)聲明:這些值只是假設(shè),并非任何醫(yī)學(xué)研究的結(jié)論)。

P(Pos):是獲得陽性測試結(jié)果的概率。

P(Neg):是獲得陰性測試結(jié)果的概率。

P(Pos|D):是本身有糖尿病并且獲得陽性測試結(jié)果的概率,值為 0.9,換句話說,該測試在 90% 的情況下是正確的。亦稱為敏感性或真正例率。

P(Neg|~D):是本身沒有糖尿病并且獲得陰性測試結(jié)果的概率,值也為 0.9 ,因此在 90% 的情況下是正確的。亦稱為特異性或真負(fù)例率。

貝葉斯公式如下所示:

P(A):A 獨(dú)立發(fā)生的先驗(yàn)概率。在我們的示例中為 P(D),該值已經(jīng)提供給我們了 。

P(B):B 獨(dú)立發(fā)生的先驗(yàn)概率。在我們的示例中為 P(Pos)。

P(A|B):在給定 B 的情況下 A 發(fā)生的后驗(yàn)概率,在我們的示例中為 P(D|Pos),即某人的測試結(jié)果為陽性時(shí)患有糖尿病的概率。這是我們要計(jì)算的值。

P(B|A):在給定 A 的情況下 B 可能發(fā)生的概率。在我們的示例中為 P(Pos|D),該值已經(jīng)提供給我們了 。

將這些值代入貝葉斯定理公式中:

P(D|Pos) = P(D) * P(Pos|D) / P(Pos)

獲得陽性測試結(jié)果 P(Pos) 的概率可以使用敏感性和特異性來計(jì)算,如下所示:

P(Pos) = [P(D) * Sensitivity] + [P(~D) * (1-Specificity))]

"""
Instructions:
Calculate probability of getting a positive test result, P(Pos)
"""
"""
Solution (skeleton code will be provided)
"""
# P(D)
p_diabetes = 0.01

# P(~D)
p_no_diabetes = 0.99

# Sensitivity or P(Pos|D)
p_pos_diabetes = 0.9

# Specificity or P(Neg|~D)
p_neg_no_diabetes = 0.9

# P(Pos)
p_pos = p_pos_diabetes*p_diabetes + (1 - p_neg_no_diabetes)*p_no_diabetes
print("The probability of getting a positive test result P(Pos) is: {}".format(p_pos))
The probability of getting a positive test result P(Pos) is: 0.10799999999999998

我們可以利用所有這些信息計(jì)算后驗(yàn)概率,如下所示:
?
某人測試結(jié)果為陽性時(shí)患有糖尿病的概率為:

P(D|Pos) = (P(D) * Sensitivity)) / P(Pos)

某人測試結(jié)果為陽性時(shí)沒有糖尿病的概率為:

P(~D|Pos) = (P(~D) * (1-Specificity)) / P(Pos)

后驗(yàn)概率的和將始終為 1

"""
Instructions:
Compute the probability of an individual having diabetes, given that, that individual got a positive test result.
In other words, compute P(D|Pos).

The formula is: P(D|Pos) = (P(D) * P(Pos|D) / P(Pos)
"""
"""
Solution
"""
# P(D|Pos)
p_diabetes_pos = (p_pos_diabetes*p_diabetes)/p_pos
print("Probability of an individual having diabetes, given that that individual got a positive test result is:
",format(p_diabetes_pos)) 
Probability of an individual having diabetes, given that that individual got a positive test result is: 0.08333333333333336


"""
Instructions:
Compute the probability of an individual not having diabetes, given that, that individual got a positive test result.
In other words, compute P(~D|Pos).

The formula is: P(~D|Pos) = P(~D) * P(Pos|~D) / P(Pos)

Note that P(Pos|~D) can be computed as 1 - P(Neg|~D). 

Therefore:
P(Pos|~D) = p_pos_no_diabetes = 1 - 0.9 = 0.1
"""
"""
Solution
"""
# P(Pos|~D)
p_pos_no_diabetes = 0.1

# P(~D|Pos)
p_no_diabetes_pos = (p_pos_no_diabetes*p_no_diabetes) / p_pos
print("Probability of an individual not having diabetes, given that that individual got a positive test result is:"
,p_no_diabetes_pos)
Probability of an individual not having diabetes, given that that individual got a positive test result is: 0.9166666666666669

恭喜!你從頭實(shí)現(xiàn)了貝葉斯定理。你的分析表明即使某人的測試結(jié)果為陽性,他/她也有 8.3% 的概率實(shí)際上患有糖尿病,以及 91.67% 的概率沒有糖尿病。當(dāng)然前提是全球只有 1% 的人群患有糖尿病,這只是個(gè)假設(shè)。

“樸素貝葉斯”中的“樸素”一詞是什么意思?

樸素貝葉斯中的“樸素”一詞實(shí)際上是指,算法在進(jìn)行預(yù)測時(shí)使用的特征相互之間是獨(dú)立的,但實(shí)際上并非始終這樣。在我們的糖尿病示例中,我們只考慮了一個(gè)特征,即測試結(jié)果。假設(shè)我們添加了另一個(gè)特征“鍛煉”。假設(shè)此特征具有二元值 01,0 表示某人一周的鍛煉時(shí)間不超過 2 天,1 表示某人一周的鍛煉時(shí)間超過 2 天。如果我們要同時(shí)使用這兩個(gè)特征(即測試結(jié)果和“鍛煉”特征的值)計(jì)算最終概率,貝葉斯定理將不可行。樸素貝葉斯是貝葉斯定理的一種延伸,假設(shè)所有特征相互之間是獨(dú)立的。

第 4.2 步:從頭實(shí)現(xiàn)樸素貝葉斯

你已經(jīng)知道貝葉斯定理的詳細(xì)原理,現(xiàn)在我們將用它來考慮有多個(gè)特征的情況。

假設(shè)有兩個(gè)政黨的候選人,“Jill Stein”是綠黨候選人,“Gary Johnson”是自由黨的候選人,兩位候選人在演講中提到“自由”、“移民”和“環(huán)境”這些字眼的概率為:

Jill Stein 提到“自由”的概率:0.1 ---------> P(F|J)

Jill Stein 提到“移民”的概率:0.1 -----> P(I|J)

Jill Stein 提到“環(huán)境”的概率:0.8 -----> P(E|J)

Gary Johnson 提到“自由”的概率:0.7 -------> P(F|G)

Gary Johnson 提到“移民”的概率:0.2 ---> P(I|G)

Gary Johnson 提到“環(huán)境”的概率:0.1 ---> P(E|G)

假設(shè) Jill Stein 發(fā)表演講的概率 P(J)0.5,Gary Johnson 也是 P(G) = 0.5。

了解這些信息后,如果我們要計(jì)算 Jill Stein 提到“自由”和“移民”的概率,該怎么做呢?這時(shí)候樸素貝葉斯定理就派上用場了,我們將考慮兩個(gè)特征:“自由”和“移民”。

現(xiàn)在我們可以定義樸素貝葉斯定理的公式:

在該公式中,y 是分類變量,即候選人的姓名,x1xn 是特征向量,即單個(gè)單詞。該定理假設(shè)每個(gè)特征向量或單詞 (xi) 相互之間是獨(dú)立的。

為了詳細(xì)講解該公式,我們需要計(jì)算以下后驗(yàn)概率:

P(J|F,I):Jill Stein 提到“自由”和“移民”的概率。

根據(jù)上述公式和貝葉斯定理,我們可以進(jìn)行以下計(jì)算:P(J|F,I) = (P(J) * P(F|J) * P(I|J)) / P(F,I)。在此等式中,P(F,I) 是在研究中提到“自由”和“移民”的概率。

P(G|F,I):Gary Johnson 提到“自由”和“移民”的概率。

根據(jù)上述公式,我們可以進(jìn)行以下計(jì)算:P(G|F,I) = (P(G) * P(F|G) * P(I|G)) / P(F,I)

"""
Instructions: Compute the probability of the words "freedom" and "immigration" being said in a speech, or
P(F,I).

The first step is multiplying the probabilities of Jill Stein giving a speech with her individual 
probabilities of saying the words "freedom" and "immigration". Store this in a variable called p_j_text

The second step is multiplying the probabilities of Gary Johnson giving a speech with his individual 
probabilities of saying the words "freedom" and "immigration". Store this in a variable called p_g_text

The third step is to add both of these probabilities and you will get P(F,I).
"""
"""
Solution: Step 1
"""
# P(J)
p_j = 0.5

# P(F/J)
p_j_f = 0.1

# P(I/J)
p_j_i = 0.1

p_j_text = p_j * p_j_f * p_j_i 
print(p_j_text)
0.005000000000000001


"""
Solution: Step 2
"""
# P(G)
p_g = 0.5

# P(F/G)
p_g_f = 0.7

# P(I/G)
p_g_i = 0.2

p_g_text = p_g * p_g_f * p_g_i
print(p_g_text)
0.06999999999999999


"""
Solution: Step 3: Compute P(F,I) and store in p_f_i
"""
p_f_i = p_j_text + p_g_text
print("Probability of words freedom and immigration being said are: ", format(p_f_i))
Probability of words freedom and immigration being said are:  0.075

現(xiàn)在可以計(jì)算 P(J|F,I) 的概率,即 Jill Stein 提到“自由”和“移民”的概率,以及 P(G|F,I),即 Gary Johnson 提到“自由”和“移民”的概率。

"""
Instructions:
Compute P(J|F,I) using the formula P(J|F,I) = (P(J) * P(F|J) * P(I|J)) / P(F,I) and store it in a variable p_j_fi
"""
"""
Solution
"""
p_j_fi = p_j_text / p_f_i
print("The probability of Jill Stein saying the words Freedom and Immigration: ", format(p_j_fi))
The probability of Jill Stein saying the words Freedom and Immigration:  0.06666666666666668


"""
Instructions:
Compute P(G|F,I) using the formula P(G|F,I) = (P(G) * P(F|G) * P(I|G)) / P(F,I) and store it in a variable p_g_fi
"""
"""
Solution
"""
p_g_fi = p_g_text / p_f_i
print("The probability of Gary Johnson saying the words Freedom and Immigration: ", format(p_g_fi))
The probability of Gary Johnson saying the words Freedom and Immigration:  0.9333333333333332

可以看出,和貝葉斯定理一樣,后驗(yàn)概率之和等于 1。恭喜!你從頭實(shí)現(xiàn)了樸素貝葉斯定理。分析表明,綠黨的 Jill Stein 在演講中提到“自由”和“移民”的概率只有 6.6%,而自由黨的 Gary Johnson 有 93.3% 的可能性會(huì)提到這兩個(gè)詞。

另一個(gè)比較常見的樸素貝葉斯定理應(yīng)用示例是在搜索引擎中搜索“薩克拉門托國王”。為了使我們能夠獲得與薩克拉門托國王隊(duì) NBA 籃球隊(duì)相關(guān)的結(jié)果,搜索引擎需要將這兩個(gè)單詞關(guān)聯(lián)到一起,而不是多帶帶處理它們,否則就會(huì)獲得標(biāo)有“薩克拉門托”的圖片(例如風(fēng)光圖片)以及關(guān)于“國王”的圖片(可能是歷史上的國王),而實(shí)際上我們想要搜索的是關(guān)于籃球隊(duì)的圖片。這是一種搜索引擎將單詞當(dāng)做非獨(dú)立個(gè)體(因此采用的是“樸素”方式)的經(jīng)典示例。

將此方法應(yīng)用到我們的垃圾信息分類問題上,樸素貝葉斯算法會(huì)查看每個(gè)單詞,而不是將它們當(dāng)做有任何聯(lián)系的關(guān)聯(lián)體。對于垃圾內(nèi)容檢測器來說,這么做通常都可行,因?yàn)橛行┙迷~幾乎肯定會(huì)被分類為垃圾內(nèi)容,例如包含“偉哥”的電子郵件通常都被歸類為垃圾郵件。

第 5 步:使用 scikit-learn 實(shí)現(xiàn)樸素貝葉斯

幸運(yùn)的是,sklearn 具有多個(gè)樸素貝葉斯實(shí)現(xiàn),這樣我們就不用從頭進(jìn)行計(jì)算。我們將使用 sklearns 的 sklearn.naive_bayes 方法對我們的數(shù)據(jù)集做出預(yù)測。

具體而言,我們將使用多項(xiàng)式樸素貝葉斯實(shí)現(xiàn)。這個(gè)分類器適合分類離散特征(例如我們的單詞計(jì)數(shù)文本分類)。它會(huì)將整數(shù)單詞計(jì)數(shù)作為輸入。另一方面,高斯樸素貝葉斯更適合連續(xù)數(shù)據(jù),因?yàn)樗僭O(shè)輸入數(shù)據(jù)是高斯(正態(tài))分布。

"""
Instructions:

We have loaded the training data into the variable "training_data" and the testing data into the 
variable "testing_data".

Import the MultinomialNB classifier and fit the training data into the classifier using fit(). Name your classifier
"naive_bayes". You will be training the classifier using "training_data" and y_train" from our split earlier. 
"""
"""
Solution
"""
from sklearn.naive_bayes import MultinomialNB
naive_bayes = MultinomialNB()
naive_bayes.fit(training_data, y_train)
MultinomialNB(alpha=1.0, class_prior=None, fit_prior=True)



"""
Instructions:
Now that our algorithm has been trained using the training data set we can now make some predictions on the test data
stored in "testing_data" using predict(). Save your predictions into the "predictions" variable.
"""
"""
Solution
"""
predictions = naive_bayes.predict(testing_data)

我們已經(jīng)對測試集進(jìn)行預(yù)測,現(xiàn)在需要檢查預(yù)測的準(zhǔn)確率了。

第 6 步:評估模型

我們已經(jīng)對測試集進(jìn)行了預(yù)測,下一個(gè)目標(biāo)是評估模型的效果。我們可以采用各種衡量指標(biāo),但首先快速總結(jié)下這些指標(biāo)。

準(zhǔn)確率 衡量的是分類器做出正確預(yù)測的概率,即正確預(yù)測的數(shù)量與預(yù)測總數(shù)(測試數(shù)據(jù)點(diǎn)的數(shù)量)之比。

精確率 指的是分類為垃圾信息的信息實(shí)際上是垃圾信息的概率,即真正例(分類為垃圾內(nèi)容并且實(shí)際上是垃圾內(nèi)容的單詞)與所有正例(所有分類為垃圾內(nèi)容的單詞,無論是否分類正確)之比,換句話說,是以下公式的比值結(jié)果:

[True Positives/(True Positives + False Positives)]

召回率(敏感性)表示實(shí)際上為垃圾信息并且被分類為垃圾信息的信息所占比例,即真正例(分類為垃圾內(nèi)容并且實(shí)際上是垃圾內(nèi)容的單詞)與所有為垃圾內(nèi)容的單詞之比,換句話說,是以下公式的比值結(jié)果:

[True Positives/(True Positives + False Negatives)]

對于偏態(tài)分類分布問題(我們的數(shù)據(jù)集就屬于偏態(tài)分類),例如如果有 100 條信息,只有 2 條是垃圾信息,剩下的 98 條不是,則準(zhǔn)確率本身并不是很好的指標(biāo)。我們將 90 條信息分類為非垃圾信息(包括 2 條垃圾信息,但是我們將其分類為非垃圾信息,因此它們屬于假負(fù)例),并將 10 條信息分類為垃圾信息(所有 10 條都是假正例),依然會(huì)獲得比較高的準(zhǔn)確率分?jǐn)?shù)。對于此類情形,精確率和召回率非常實(shí)用。可以通過這兩個(gè)指標(biāo)獲得 F1 分?jǐn)?shù),即精確率和召回率分?jǐn)?shù)的加權(quán)平均值。該分?jǐn)?shù)的范圍是 0 到 1,1 表示最佳潛在 F1 分?jǐn)?shù)。

我們將使用所有四個(gè)指標(biāo)確保我們的模型效果很好。這四個(gè)指標(biāo)的值范圍都在 0 到 1 之間,分?jǐn)?shù)盡量接近 1 可以很好地表示模型的效果如何。

"""
Instructions:
Compute the accuracy, precision, recall and F1 scores of your model using your test data "y_test" and the predictions
you made earlier stored in the "predictions" variable.
"""
"""
Solution
"""
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
print("Accuracy score: ", format(accuracy_score(y_test, predictions)))
print("Precision score: ", format(precision_score(y_test, predictions)))
print("Recall score: ", format(recall_score(y_test, predictions)))
print("F1 score: ", format(f1_score(y_test, predictions)))
Accuracy score:  0.9885139985642498
Precision score:  0.9720670391061452
Recall score:  0.9405405405405406
F1 score:  0.9560439560439562

第 7 步:總結(jié)

和其他分類算法相比,樸素貝葉斯具有的一大主要優(yōu)勢是能夠處理大量特征。在我們的示例中,有數(shù)千個(gè)不同的單詞,每個(gè)單詞都被當(dāng)做一個(gè)特征。此外,即使存在不相關(guān)的特征也有很好的效果,不容易受到這種特征的影響。另一個(gè)主要優(yōu)勢是相對比較簡單。樸素貝葉斯完全可以直接使用,很少需要調(diào)整參數(shù),除非通常分布數(shù)據(jù)已知的情況需要調(diào)整。
它很少會(huì)過擬合數(shù)據(jù)。另一個(gè)重要優(yōu)勢是相對于它能處理的數(shù)據(jù)量來說,訓(xùn)練和預(yù)測速度很快??傊瑯闼刎惾~斯是非常實(shí)用的算法!

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/43493.html

相關(guān)文章

  • 成為數(shù)據(jù)科學(xué)家的入門項(xiàng)目

    摘要:基于大量的數(shù)據(jù)統(tǒng)計(jì),網(wǎng)球是一種很好的預(yù)測類體育項(xiàng)目。數(shù)據(jù)科學(xué)家根據(jù)歷史數(shù)據(jù)和玩家信息來構(gòu)建預(yù)測模型,并將結(jié)果與博彩公司的評估進(jìn)行比較。目標(biāo)是找出機(jī)器學(xué)習(xí)模型與博彩公司評估之間的差距,從而有機(jī)會(huì)獲勝。這是一個(gè)很好的實(shí)際數(shù)據(jù)科學(xué)項(xiàng)目。 作者:chen_h微信號 & QQ:862251340微信公眾號:coderpai簡書地址:https://www.jianshu.com/p/56c......

    Julylovin 評論0 收藏0
  • 機(jī)器學(xué)習(xí)項(xiàng)目之實(shí)現(xiàn)垃圾郵件處理(1)——數(shù)據(jù)清洗

    摘要:學(xué)習(xí)了支持向量機(jī)算法后想自己用一些數(shù)據(jù)集來嘗試一下,在網(wǎng)絡(luò)上找了一個(gè)垃圾郵件處理的數(shù)據(jù)集正好適用于支持向量算法,所以在這里不講算法內(nèi)容,而是分享我是如何用來實(shí)現(xiàn)的。 學(xué)習(xí)了支持向量機(jī)算法后(SVM)想自己用一些數(shù)據(jù)集來嘗試一下,在網(wǎng)絡(luò)上找了一個(gè)垃圾郵件處理的數(shù)據(jù)集正好適用于SVM支持向量算法,所以在這里不講SVM算法內(nèi)容,而是分享我是如何用Python來實(shí)現(xiàn)的。 具體數(shù)據(jù)集:[郵件數(shù)據(jù)...

    fantix 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<