准备数据

链接:https://pan.baidu.com/s/1DcyiUgFT1T3PSZRh-t1kxQ
提取码:egt5

部分数据如下:ham为正常邮件,spam为垃圾邮件
type,text
ham,you are having a good week. Just checking in
ham,K…give back my thanks.
ham,Am also doing in cbe only. But have to pay.
spam,"complimentary 4 STAR Ibiza Holiday or £10,000 cash needs

def get_data():
    """
        prepare mail data and labels
    """
    #open file
    f = open("sms_spam.txt","r",encoding="utf-8")
    
    data = []
    labels = []
    
    while True:
        #read a line
        l = f.readline()
        
        #got data
        if l:
            #ignore lines that is  not label + data
            if not l.startswith(("ham","spam")):
                continue
            
            #normal data
            label,mail = l.split(",",maxsplit=1)
            data.append(mail)
            if label == "ham":
                #正常邮件表示为0
                labels.append(0)
            else:
                #垃圾邮件表示为1
                labels.append(1)
        
        #no data any more 
        else:
            break
        
    return data,labels
    

抽取特征数据

方式1. 使用sklearn.feature_extraction.text.CountVectorizer
原理:从所有的邮件中提取出关键字,作为词袋,统计词袋中每个关键字在每个邮件中出现的次数,得到一个稀疏矩阵,即为特征空间数据

方式2. 使用sklearn.feature_extraction.text.TfidfVectorizer
原理:统计每个邮件中词语的逆向文档频率指数,过滤掉常用的词语
具体计算方式如下,
词频 (TF) 是一词语出现的次数除以该文件的总词语数。假如一篇文件的总词语数是100,“你好”出现了3次,那么“你好”的词频就是3/100=0.03

逆向文档频率 (IDF) 是文件集里文件总数除以包含“你好”一词的文件数,在取对数。如果“你好”一词在10份文件出现过,而文件总数是1000份的话,idf = lg(1000 / 10)=2, 以10为底取对数,为防止分母为0,常将分母加1
过滤常见词语
最后的TF-IDF的指数为0.03 * 2=0.06

TF-IDF值越大,越能代表文档的中心思想

此处采用方式1

	#组织数据
    x,y = get_data()
    
    print("邮件列表:\n",x,"\n","标记列表:\n",y)
    
    #词袋模型,抽取特征
    vector = CountVectorizer()
    x_ = vector.fit_transform(x)
    
    #x_ is a sparse matrix
    x_data = x_.toarray()

划分训练集,验证集,训练模型

	#划分训练集,验证集
    x_train,x_validate,y_train,y_validate = train_test_split(x_data,y,test_size=0.1,random_state=3,shuffle=True)
    
    #实例化分类模型
    clf = MultinomialNB(alpha=1)
    
    #训练模型
    clf.fit(x_train,y_train)

评估模型

	#评估模型
    y_pred = clf.predict(x_validate)
    y_pred_proba = clf.predict_proba(x_validate)[:,1]
    #准确率
    acc = accuracy_score(y_validate,y_pred)
    #roc 曲线
    fpr,tpr,threshold = roc_curve(y_validate,y_pred_proba,pos_label=1)
    auc = roc_auc_score(y_validate,y_pred_proba)
    
    #可视化
    plt.figure()
    #plt.rcParams["font"]
    plt.plot(fpr,tpr,"ro-",label="roc curve")
    plt.title("auc %.1f,acc %f.1"%(auc,acc))
    plt.xlabel("FPR")
    plt.ylabel("TPR")
    plt.grid()
    plt.legend(loc="best")

在这里插入图片描述

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐