摘要:學(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ù)集][1] [1]: https://pan.baidu.com/s/1ivQmo-04fCa3qVG0SAiUtQ1. 首先查看數(shù)據(jù)集
郵件中有很多中特征值,有些是有用的有些卻無法幫助我們判斷是否是垃圾郵件,所以這里我們選取其中4個(gè)特征值(From,To,Data,Content)。 (1、郵件的內(nèi)容分析——主要包含:發(fā)件人、收件人、發(fā)件時(shí)間以及郵件的內(nèi)容) ![分類][3] (2、是否為垃圾郵件的標(biāo)簽,spam——是垃圾郵件;ham——不是垃圾郵件)2. 分析數(shù)據(jù)集
分析:垃圾郵件處理問題是一個(gè)**監(jiān)督學(xué)習(xí)**,僅用來分類郵件好壞固為**二分類**問題,分類內(nèi)容為**長文本**。 所有非向量形式的特征工程,首先要轉(zhuǎn)換成向量的形式 該數(shù)據(jù)集適合很多種模型(貝葉斯,KNN),在這里我用SVM來解決3. 開始進(jìn)行數(shù)據(jù)清洗的工作
引入模塊常用功能
import os
索引文件(分類標(biāo)簽)讀取,該文件中分為兩列
第一列:分類標(biāo)簽是否為垃圾郵件(是:spam、否:ham);
第二列:存放郵件對(duì)應(yīng)文件夾路徑,兩列之間通過空格分割
def read_index_file(file_path): type_dict={"spam":"1","ham":"0"} #用字典存放分類的垃圾郵件(0/1) index_file=open(file_path) index_dict={} #存儲(chǔ)分類后得到的結(jié)構(gòu)字典 try: for line in index_file: #按照行來讀取 arr=line.split(" ") #從每行的第一個(gè)空格分開 if len(arr) == 2: key,value = arr #將key和value分別賦值前后兩段 #將value中的數(shù)據(jù)規(guī)整,將../data去掉 value=value.replace("../data","").replace(" ","") #將每一個(gè)值是1/0對(duì)應(yīng)加入數(shù)據(jù)字典中 index_dict[value]=type_dict[key.lower()] #將spam/ham中可能出現(xiàn)的大寫字母換成小寫 finally: index_file.close() return index_dict
郵件的文件內(nèi)容數(shù)據(jù)讀取
def read_file(file_path): #打開郵件只讀r,編碼方式gb2312,錯(cuò)誤忽略 file=open(file_path,"r",encoding="gb2312",errors="ignore") content_dict={} try: is_content = False for line in file: #按行讀取 line = line.strip() #去掉每行的空格 if line.startswith("From:"): #將From:后的內(nèi)容加入數(shù)據(jù)字典,將key="from:",value=line[5:]5以后的內(nèi)容 content_dict["from:"]=line[5:] elif line.startswith("To:"): content_dict["to:"]=line[3:] elif line.startswith("Date:"): content_dict["date:"]=line[5:] elif not line: # 郵件內(nèi)容與上面信息存在著第一個(gè)空行,遇到空行時(shí),這里標(biāo)記為True以便進(jìn)行下面的郵件內(nèi)容處理 # line文件的行為空時(shí)是False,不為空時(shí)是True is_content = True #如果這一行是空行表明下一行開始是具體的內(nèi)容(content),則開始處理郵件 if is_content: if "content" in content_dict: #如果這一行有內(nèi)容則加入字典 content_dict["content"] += line else: #如果這一行沒有內(nèi)容則不加入,繼續(xù)下一行 content_dict["content"] = line finally: file.close() return content_dict
3、郵件數(shù)據(jù)處理(內(nèi)容的拼接,并用逗號(hào)進(jìn)行分割)
def process_file(file_path): content_dict = read_file(file_path) #進(jìn)行處理(拼接),get()函數(shù)返回指定鍵的值,指定鍵的值不存在用指定的默認(rèn)值unkown代替 #2,是將需要是數(shù)據(jù)特征取出來放在鍵值對(duì)中保存,3,則是將所有的特征值合并成,進(jìn)行拼接 result_str = content_dict.get("from","unkown").replace(",","").strip()+"," result_str += content_dict.get("to:","unkown").replace(",","").strip()+"," result_str += content_dict.get("date:","unkown").replace(",","").strip()+"," result_str += content_dict.get("content","unkown").replace(",","").strip() return result_str
4、開始進(jìn)行數(shù)據(jù)處理——函數(shù)調(diào)用
## os.listdir 返回指定的文件夾包含的文件或文件夾包含的名稱列表 index_dict = read_index_file("../data/full/index") #調(diào)用第一個(gè)函數(shù) list0 = os.listdir("../data/data") #開始打印list0 for l1 in list0: #循環(huán)000-299 l1_path = "../data/data/" + l1 #l1_path ../data/data/(215) print("開始處理文件夾:"+l1_path) list1 = os.listdir(l1_path) #list1:["000", "001", "002", "003"...."299"] #將list1打印出來 write_file_path = "../data/process01_" + l1 #用這個(gè)來存放 with open(write_file_path,"w",encoding="utf-8") as writer: for l2 in list1: #l2循環(huán)000-299 l2_path = l1_path + "/" + l2 #l2_path = ../data/data/(000-215)/(000-299) #這就得到了具體的文件內(nèi)容,然后進(jìn)行文件數(shù)據(jù)的讀取 index_key = "/" + l1 + "/" + l2 #index_key = /(000-215)/(000-299) if index_key in index_dict: #讀取數(shù)據(jù) content_str = process_file(l2_path) #3的函數(shù),用來拼接數(shù)據(jù)元素,及特征值的合并 #添加分類標(biāo)簽(0/1),可用逗號(hào)隔開 content_str += "," + index_dict[index_key] + " " #進(jìn)行數(shù)據(jù)的輸出 writer.writelines(content_str)
將所有構(gòu)建好的內(nèi)容進(jìn)行合并
with open("../data/result_process01","w",encoding="utf-8") as writer: #將所有內(nèi)容合并到result_process01中 for l1 in list0: file_path = "../data/process01_" + l1 print("開始合并文件:" + file_path) with open(file_path, encoding="utf-8") as file: for line in file: writer.writelines(line)清洗結(jié)果
到這一步數(shù)據(jù)的清洗就完成了,所有我們需要的特征值都被整合到了一起,并且為郵件做了加上了是否為垃圾郵件的標(biāo)記。
推薦使用jupyter,注意文件的路徑問題,特征工程和后面的分類會(huì)在下一篇。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/44016.html
摘要:基于大量的數(shù)據(jù)統(tǒng)計(jì),網(wǎng)球是一種很好的預(yù)測類體育項(xiàng)目。數(shù)據(jù)科學(xué)家根據(jù)歷史數(shù)據(jù)和玩家信息來構(gòu)建預(yù)測模型,并將結(jié)果與博彩公司的評(píng)估進(jìn)行比較。目標(biāo)是找出機(jī)器學(xué)習(xí)模型與博彩公司評(píng)估之間的差距,從而有機(jī)會(huì)獲勝。這是一個(gè)很好的實(shí)際數(shù)據(jù)科學(xué)項(xiàng)目。 作者:chen_h微信號(hào) & QQ:862251340微信公眾號(hào):coderpai簡書地址:https://www.jianshu.com/p/56c......
摘要:幾乎所有大型電子郵箱服務(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ì)通過...
閱讀 3124·2021-11-19 11:31
閱讀 3259·2021-09-02 15:15
閱讀 1055·2019-08-29 17:22
閱讀 1125·2019-08-29 16:38
閱讀 2518·2019-08-26 13:56
閱讀 925·2019-08-26 12:16
閱讀 1492·2019-08-26 11:29
閱讀 1019·2019-08-26 10:12