参考链接:吴恩达|机器学习作业6.1.SVM建立垃圾邮件分类器_学吧学吧终成学霸的博客-CSDN博客
重点是文本处理
第一步:预处理邮件
1.将所有大写字母都转换成小写字母。
2.删除html标记,带有“< >”符号的元素被称为HTML标记,也称为HTML标签或HTML元素。
3.规范化URL:所有URL都替换为文本“httpaddr”。
4.规范电子邮件地址:所有电子邮件地址都被替换为文本“emailaddr”。
5.规范化数字:所有数字均替换为文本"number"。
6.标准化美元:所有美元符号($)均替换为文本“dollar”。
7.词干提取:单词被简化为词干形式。 “discount”, “discounts”, “discounted” 和“discounting” 都会被替换为 “discount”。
8.删除非单词:已删除非单词和标点符号。所有空白(制表符、换行符、空格)都已修剪为单个空格字符。
第二步:将处理后的文本中的单词转换为字典中对应的数字
第三步:抽取特征:将每封邮件映射成为对应的向量
第四步:训练SVM
第五步:找出预测是垃圾邮件的关键词
import numpy as np
from sklearn import svm
from scipy import io
import re
import nltk
#1.邮件预处理--------------------------------------------------------------------------------------
sample = open("E:\机器学习\吴恩达\data_sets\emailSample1.txt","r").read()
#<class 'str'>
#第一步:规范化邮件------------------------------------------------------------------------------------
"""
1.将所有大写字母都转换成小写字母。
2.删除html标记,带有“< >”符号的元素被称为HTML标记,也称为HTML标签或HTML元素。
3.规范化URL:所有URL都替换为文本“httpaddr”。
4.规范电子邮件地址:所有电子邮件地址都被替换为文本“emailaddr”。
5.规范化数字:所有数字均替换为文本"number"。
6.标准化美元:所有美元符号($)均替换为文本“dollar”。
7.词干提取:单词被简化为词干形式。 “discount”, “discounts”, “discounted” 和“discounting” 都会被替换为 “discount”。
8.删除非单词:已删除非单词和标点符号。所有空白(制表符、换行符、空格)都已修剪为单个空格字符。"""
#可以使用正则表达式
def preProcess(email):
#1.将所有大写字母都转换成小写字母。
email = email.lower()
#2.删除html标记
email = re.sub(pattern = "<[^<>]>", repl = "",string = email)
#3.规范化URL:所有URL都替换为文本“httpaddr”。
#URL 的一般形式是:<URL的访问方式>://<主机>:<端口>/<路径>
email = re.sub(pattern = "[\S]+://[^\s]*", repl = "httpaddr",string = email)
#4.规范电子邮件地址:所有电子邮件地址都被替换为文本“emailaddr”。
email = re.sub(pattern = "[\S]+@[^\s]+", repl = "emailaddr", string = email)
#5.规范化数字:所有数字均替换为文本"number"。
email = re.sub(pattern = "\d+", repl = "number", string = email)
#6.标准化美元:所有美元符号($)均替换为文本“dollar”。
email = re.sub(pattern = "[$]+", repl = "dollar" , string = email)
#7.词干提取:单词被简化为词干形式。
#8.删除非单词:已删除非单词和标点符号。
stemmer = nltk.stem.PorterStemmer()
tokens = re.split("[ @$/#.-:&*+=\[\]?!()\{\},\'\">_<;%]",email)
tokenlist = []
for token in tokens:
token = re.sub(pattern = "[^a-zA-Z0-9]", repl = "", string = token)
try:
#若提取词根的时候发生异常则直接删除该单词
token = stemmer.stem(token)
except:
token = ""
if len(token) >= 1:
tokenlist.append(token)
return tokenlist
# sample_str = preProcess(sample)
# for i in sample_str:
# print(i,end=" ")
#第二步:将规范化的字符串类型的列表转化为数字列表--------------------------------------------------------------
voca = np.loadtxt(fname = r"E:\机器学习\吴恩达\data_sets\vocab.txt",dtype = "str",usecols = 1) #(1899,) ['aa' 'ab' 'abil' ... 'zdnet' 'zero' 'zip']
#usecols表明只读第一列(列的索引从0开始)
#将字符串数据转换成表中对应的数字
def strVocToNumVoc(sample_str,vocaArray):
sample_temp = []
for strContent in sample_str:
for j in range(len(vocaArray)):
if strContent == vocaArray[j]:
sample_temp.append(j+1)
return sample_temp
# sample_number = strVocToNumVoc(sample_str,voca)
# for i in sample_number:
# print(i,end = " ")
#2.抽取特征,将每一封邮件变成一个向量-------------------------------------------------------------------
def feature_mapping(email,vocaArray):
length = vocaArray.size
vec = np.zeros(length)
for i in email:
vec[i-1] = 1
return vec
# sample_vector = feature_mapping(sample_number,voca) #(1899,) 有45个特征值为1
#3.训练SVM分类器----------------------------------------------------------------------------------
dt_train = io.loadmat("E:\机器学习\吴恩达\data_sets\spamTrain.mat")
dt_test = io.loadmat("E:\机器学习\吴恩达\data_sets\spamTest.mat")
x_train = dt_train["X"] #(4000, 1899)
y_train = dt_train["y"] #(4000, 1)
y_train = y_train.ravel()
x_test = dt_test["Xtest"] #(1000, 1899)
y_test = dt_test["ytest"] #(1000, 1)
def calculateError(predictY,y):
length = y.size
count = 0
for i in range(length):
if predictY[i] != y[i]:
count += 1
return count/length
clf = svm.SVC(kernel = "linear",C=0.1)
clf.fit(x_train,y_train)
# predict_ytrain = clf.predict(x_train)
# predict_ytest = clf.predict(x_test)
# accuracy_train = 1-calculateError(predict_ytrain,y_train) #0.99825
# accuracy_test = 1-calculateError(predict_ytest,y_test) #0.989
#4.垃圾邮件的主要预测因素----------------------------------------------------------------------------
"""i = (clf.coef_).size-1
while i >1880:
#返回从小到大排序的索引,然后再打印
print(voca[np.argsort(clf.coef_).flatten()[i]], end=' ')
i = i-1"""
#our click remov guarante visit basenumb dollar will price pleas most nbsp lo ga hour al da se
#5.测试给出的四封邮件
# y0 = clf.predict(sample_vector.reshape((1,1899))) #0
"""sample2 = open("E:\机器学习\吴恩达\data_sets\emailSample2.txt","r").read()
sample2_str = preProcess(sample2)
sample2_number = strVocToNumVoc(sample2_str,voca)
sample2_vec = feature_mapping(sample2_number,voca)
y1 = clf.predict(sample2_vec.reshape((1,1899))) #0
print(y1)"""
"""sample3 = open("E:\机器学习\吴恩达\data_sets\spamSample1.txt","r").read()
sample3_str = preProcess(sample3)
sample3_number = strVocToNumVoc(sample3_str,voca)
sample3_vec = feature_mapping(sample3_number,voca)
y3 = clf.predict(sample3_vec.reshape((1,1899))) #1
print(y3)"""
"""sample4 = open("E:\机器学习\吴恩达\data_sets\spamSample2.txt","r").read()
sample4_str = preProcess(sample4)
sample4_number = strVocToNumVoc(sample4_str,voca)
sample4_vec = feature_mapping(sample4_number,voca)
y4 = clf.predict(sample4_vec.reshape((1,1899))) #1
print(y4)"""