<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          垃圾郵件識別:用機器學(xué)習(xí)做中文郵件內(nèi)容分類

          共 7929字,需瀏覽 16分鐘

           ·

          2022-02-20 10:06


          隨著微信的迅速發(fā)展,工作和生活中的交流也更多依賴于此,但是由于郵件的正式性和規(guī)范性,其仍然不可被取代。但是不管是企業(yè)內(nèi)部工作郵箱,還是個人郵箱,總是收到各種各樣的垃圾郵件,包括商家的廣告、打折促銷信息、澳門博彩郵件、理財推廣信息等等,不管如何進行垃圾郵件分類,總有漏網(wǎng)之魚。最重要的是,不同用戶對于垃圾郵件的定義并不一致。

          而且大部分用戶網(wǎng)絡(luò)安全意識比較一般,萬一誤點垃圾郵件上鉤,或者因為垃圾郵件淹沒了工作中的關(guān)鍵信件,則會給個人或者企業(yè)造成損失。

          垃圾郵件識別一直以來都是痛點難點,雖然方法無非是基于貝葉斯學(xué)習(xí)或者是概率統(tǒng)計還是深度學(xué)習(xí)的方法,但是由于業(yè)務(wù)場景的多樣化,垃圾郵件花樣實在太多了,所以傳統(tǒng)垃圾郵件攔截器總是有點跟不上。

          因此打算針對同一數(shù)據(jù)集,逐步嘗試各種方法,來進行垃圾郵件的識別分類——希望假以時日,這種定制化的垃圾郵件識別工具能大幅提升用戶的郵箱使用體驗。

          一、整體思路

          總的來說,一封郵件可以分為發(fā)送人、接收人、抄送人、主題、時間、內(nèi)容等要素,所以很自然的可以認(rèn)為主要通過上述要素中的發(fā)送方、主題以及內(nèi)容來進行垃圾郵件判斷。

          因此我們依次對上述要素進行分析:

          • 垃圾郵件內(nèi)容分類(通過提取垃圾郵件內(nèi)容進行判斷)

            • - 中文垃圾郵件分類- 英文垃圾郵件分類 最終,我們可以根據(jù)這三個維度進行綜合評判,從而實現(xiàn)垃圾郵件的準(zhǔn)確分類。本文將根據(jù)**郵件內(nèi)容**進行垃圾郵件分類。

          二、中文郵件內(nèi)容分類實現(xiàn)步驟

          1.數(shù)據(jù)集介紹

          首先我們選擇這一個公開的垃圾郵件語料庫。該語料庫由國際文本檢索會議提供,分為英文數(shù)據(jù)集(trec06p)和中文數(shù)據(jù)集(trec06c),其中所含的郵件均來源于真實郵件保留了郵件的原有格式和內(nèi)容。

          文件目錄形式:delay和full分別是一種垃圾郵件過濾器的過濾機制,full目錄下,是理想的郵件分類結(jié)果,我們可以視為研究的標(biāo)簽。

          trec06c │ └───data │ ? │ ? 000 │ ? │ ? 001 │ ? │ ? ... │ ? └───215 └───delay │ ? │ ? index └───full │ ? │ ? index

          2.數(shù)據(jù)加載

          2.1 從eml格式中提取郵件要素并且存儲成csv

          由于目前數(shù)據(jù)集是存儲成郵件的形式,并且通過索引進行垃圾郵件標(biāo)注,所以我們先提取每一封郵件的發(fā)件人、收件人、抄送人、主題、發(fā)送時間、內(nèi)容以及是否垃圾郵件標(biāo)簽。

          mailTable=pd.DataFrame(columns=('Sender','Receiver','CarbonCopy','Subject','Date','Body','isSpam'))
          #?path='trec06p/full/../data/000/004'
          #?emlContent=?emlAnayalyse(path)
          #?print(emlContent)
          f?=?open('trec06c/full/index',?'r')
          csvfile=open('mailChinese.csv','w',newline='',encoding='utf-8')
          writer=csv.writer(csvfile)
          for?line?in?f:
          ????str_list?=?line.split("?")
          ????print(str_list[1])

          ????#?設(shè)置垃圾郵件的標(biāo)簽為0
          ????if?str_list[0]?==?'spam':
          ????????label?=?'0'
          ????#?設(shè)置正常郵件標(biāo)簽為1
          ????elif?str_list[0]?==?'ham':
          ????????label?=?'1'
          ????emlContent=?emlAnayalyse('trec06c/full/'?+?str(str_list[1].split("\n")[0]))
          ????if?emlContent?is?not?None:
          ????????writer.writerow([emlContent[0],emlContent[1],emlContent[2],emlContent[3],emlContent[4],emlContent[5],label])

          其中emlAnayalyze函數(shù)利用flanker庫中的mime,可以將郵件中的發(fā)件人、收件人、抄送人、主題、發(fā)送時間、內(nèi)容等要素提取出來,具體可以參考我的這篇文章,然后存成csv,方便后續(xù)郵件分析。

          2.2 從csv中提取郵件內(nèi)容進行分類

          def?get_data(path):
          ????'''
          ????獲取數(shù)據(jù)
          ????:return:?文本數(shù)據(jù),對應(yīng)的labels
          ????'
          ''
          ????maildf?=?pd.read_csv(path,header=None,?names=['Sender','Receiver','“CarbonCopy','Subject','Date','Body','isSpam'])
          ????filteredmaildf=maildf[maildf['Body'].notnull()]
          ????corpus=filteredmaildf['Body']
          ????
          ????labels=filteredmaildf['isSpam']
          ????corpus=list(corpus)
          ????labels=list(labels)
          ????return?corpus,?labels

          通過get_data函數(shù)讀取csv格式數(shù)據(jù),并且提取出內(nèi)容不為空的數(shù)據(jù),和對應(yīng)的標(biāo)簽。

          88f5e513503b9742d761e1cc49e6ee11.webp

          可以看到一共有40348個數(shù)據(jù)。

          from?sklearn.model_selection?import?train_test_split
          #?對數(shù)據(jù)進行劃分
          train_corpus,?test_corpus,?train_labels,?test_labels?=?train_test_split(corpus,?labels,
          ??????????????????????????????????????????????????test_size=0.3,?random_state=0)

          然后通過 sklearn.model_selection庫中的train_test_split函數(shù)劃分訓(xùn)練集、驗證集。

          #?進行歸一化
          norm_train_corpus?=?normalize_corpus(train_corpus)
          norm_test_corpus?=?normalize_corpus(test_corpus)

          然后通過normalize_corpus函數(shù)對數(shù)據(jù)進行預(yù)處理。

          def?textParse(text):
          ????listOfTokens=jieba.lcut(text)
          ????newList=[re.sub(r'\W*','',s)?for?s?in?listOfTokens]
          ????filtered_text=[tok?for?tok?in?newList?if?len(tok)>0]
          ????return?filtered_text


          def?remove_stopwords(tokens):
          ????filtered_tokens?=?[token?for?token?in?tokens?if?token?not?in?stopword_list]
          ????filtered_text?=?'?'.join(filtered_tokens)
          ????return?filtered_text


          def?normalize_corpus(corpus,?tokenize=False):
          ????normalized_corpus?=?[]
          ????for?text?in?corpus:
          ????????filtered_text?=?textParse(filtered_text)
          ????????filtered_text?=?remove_stopwords(filtered_text)
          ????????
          ????????normalized_corpus.append(filtered_text)

          ????return?normalized_corpus

          里面包括textParse、remove_stopwords這兩個數(shù)據(jù)預(yù)處理操作。

          textParse函數(shù)先通過jieba進行分詞,然后去除無用字符。

          remove_stopwords函數(shù)先是加載stop_words.txt停用詞表,然后去除停用詞。

          從而實現(xiàn)數(shù)據(jù)預(yù)處理。

          2.3?構(gòu)建詞向量

          #?詞袋模型特征
          bow_vectorizer,?bow_train_features?=?bow_extractor(norm_train_corpus)
          bow_test_features?=?bow_vectorizer.transform(norm_test_corpus)

          #?tfidf?特征
          tfidf_vectorizer,?tfidf_train_features?=?tfidf_extractor(norm_train_corpus)
          tfidf_test_features?=?tfidf_vectorizer.transform(norm_test_corpus)

          其中bow_extractor,tfidf_extractor兩個函數(shù)分別將訓(xùn)練集轉(zhuǎn)化為詞袋模型特征和tfidf特征。

          from?sklearn.feature_extraction.text?import?CountVectorizer


          def?bow_extractor(corpus,?ngram_range=(1,?1)):
          ????vectorizer?=?CountVectorizer(min_df=1,?ngram_range=ngram_range)
          ????features?=?vectorizer.fit_transform(corpus)
          ????return?vectorizer,?features


          from?sklearn.feature_extraction.text?import?TfidfTransformer


          def?tfidf_transformer(bow_matrix):
          ????transformer?=?TfidfTransformer(norm='l2',
          ???????????????????????????????????smooth_idf=True,
          ???????????????????????????????????use_idf=True)
          ????tfidf_matrix?=?transformer.fit_transform(bow_matrix)
          ????return?transformer,?tfidf_matrix


          from?sklearn.feature_extraction.text?import?TfidfVectorizer


          def?tfidf_extractor(corpus,?ngram_range=(1,?1)):
          ????vectorizer?=?TfidfVectorizer(min_df=1,
          ?????????????????????????????????norm='l2',
          ?????????????????????????????????smooth_idf=True,
          ?????????????????????????????????use_idf=True,
          ?????????????????????????????????ngram_range=ngram_range)
          ????features?=?vectorizer.fit_transform(corpus)
          ????return?vectorizer,?features

          2.4 訓(xùn)練模型以及評估

          對如上兩種不同的向量表示法,分別訓(xùn)練貝葉斯分類器、邏輯回歸分類器、支持向量機分類器,從而驗證效果。

          from?sklearn.naive_bayes?import?MultinomialNB
          from?sklearn.linear_model?import?SGDClassifier
          from?sklearn.linear_model?import?LogisticRegression
          mnb?=?MultinomialNB()
          svm?=?SGDClassifier(loss='hinge',?n_iter_no_change=100)
          lr?=?LogisticRegression()

          #?基于詞袋模型的多項樸素貝葉斯
          print("基于詞袋模型特征的貝葉斯分類器")
          mnb_bow_predictions?=?train_predict_evaluate_model(classifier=mnb,
          ???????????????????????????????????????????????????train_features=bow_train_features,
          ???????????????????????????????????????????????????train_labels=train_labels,
          ???????????????????????????????????????????????????test_features=bow_test_features,
          ???????????????????????????????????????????????????test_labels=test_labels)

          #?基于詞袋模型特征的邏輯回歸
          print("基于詞袋模型特征的邏輯回歸")
          lr_bow_predictions?=?train_predict_evaluate_model(classifier=lr,
          ??????????????????????????????????????????????????train_features=bow_train_features,
          ??????????????????????????????????????????????????train_labels=train_labels,
          ??????????????????????????????????????????????????test_features=bow_test_features,
          ??????????????????????????????????????????????????test_labels=test_labels)

          #?基于詞袋模型的支持向量機方法
          print("基于詞袋模型的支持向量機")
          svm_bow_predictions?=?train_predict_evaluate_model(classifier=svm,
          ???????????????????????????????????????????????????train_features=bow_train_features,
          ???????????????????????????????????????????????????train_labels=train_labels,
          ???????????????????????????????????????????????????test_features=bow_test_features,
          ???????????????????????????????????????????????????test_labels=test_labels)
          joblib.dump(svm,?'svm_bow.pkl')


          #?基于tfidf的多項式樸素貝葉斯模型
          print("基于tfidf的貝葉斯模型")
          mnb_tfidf_predictions?=?train_predict_evaluate_model(classifier=mnb,
          ?????????????????????????????????????????????????????train_features=tfidf_train_features,
          ?????????????????????????????????????????????????????train_labels=train_labels,
          ?????????????????????????????????????????????????????test_features=tfidf_test_features,
          ?????????????????????????????????????????????????????test_labels=test_labels)
          #?基于tfidf的邏輯回歸模型
          print("基于tfidf的邏輯回歸模型")
          lr_tfidf_predictions=train_predict_evaluate_model(classifier=lr,
          ?????????????????????????????????????????????????????train_features=tfidf_train_features,
          ?????????????????????????????????????????????????????train_labels=train_labels,
          ?????????????????????????????????????????????????????test_features=tfidf_test_features,
          ?????????????????????????????????????????????????????test_labels=test_labels)


          #?基于tfidf的支持向量機模型
          print("基于tfidf的支持向量機模型")
          svm_tfidf_predictions?=?train_predict_evaluate_model(classifier=svm,
          ?????????????????????????????????????????????????????train_features=tfidf_train_features,
          ?????????????????????????????????????????????????????train_labels=train_labels,
          ?????????????????????????????????????????????????????test_features=tfidf_test_features,
          ?????????????????????????????????????????????????????test_labels=test_labels)

          輸出結(jié)果如下所示

          04eaf16b3cf79c6ce1eae6d177b95b85.webp總結(jié)

          通過針對郵件內(nèi)容,并且轉(zhuǎn)化為兩種不同的詞向量進行不同模型的訓(xùn)練,從而得到基于tfidf的支持向量機模型效果最好,可以達到98%的準(zhǔn)確率。

          原文:https://blog.csdn.net/kobepaul123/article/details/122868530

          瀏覽 94
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美性夜黄A片爽爽免费视频 | 亚洲无码免费观看高清 | 精品久久中文字幕 | 天天日日天天 | 免费在线观看无码视频 |