# 基于机器学习 LR逻辑回归 SVM 决策树 随机森林的 英文垃 圾邮件分类 完整代码分析+结果出图 直接运行 代码有注释
# spam 标签表示垃圾邮件 ham 表示非垃圾邮件
# 导入工具包
import pandas as pd
sms = pd.read_csv("./datasets/spam.csv", encoding='latin-1')
sms.dropna(how="any", inplace=True, axis=1)
sms.columns = ['label', 'message']
print(sms.head(10))
print("利用groupby()方法来组合ham类和spam类的数据,然后通过describe()方法来查看基本统计数据;可以看到ham类一共有4825条数据,非重复数据有4516条;spam类一共有747条数据,非重复数据一共有653条")
print(sms.groupby('label').describe())
sms['label_num'] = sms.label.map({'ham':0, 'spam':1})
print(sms.head())
# 导入matplotlib工具包
import matplotlib.pyplot as plt
import nltk
nltk.download('stopwords')
from nltk.corpus import stopwords
stopword = stopwords.words('english')
print(len(stopword))
import string
from nltk.corpus import stopwords
def text_process(mess):
"""
Takes in a string of text, then performs the following:
1. Remove all punctuation
2. Remove all stopwords
3. Returns a list of the cleaned text
"""
STOPWORDS = stopwords.words('english') + ['u', 'ü', 'ur', '4', '2', 'im', 'dont', 'doin', 'ure']
# 检查字符是否在里面
nopunc = [char for char in mess if char not in string.punctuation]
# 将所有的list中的数据集进行拼接.
nopunc = ''.join(nopunc)
# 将文本中包含的停用词进行去除
return ' '.join([word for word in nopunc.split() if word.lower() not in STOPWORDS])
sms['clean_msg'] = sms.message.apply(text_process)
print(sms.head())
print(stopwords.words('english')[:20] )#停用词中前20个词语
# 利用sklearn工具中的train_test_split方法将数据划分为训练集和测试集。
# 利用该方法划分可以保证训练集和测试集有一致的分布(不同类别的数据比例相近)。
# 其中random_state用来指定随机种子,保证每次划分的训练集和测试集都是一样的。test_size参数这里未指定,默认划分训练测试比例是3:1。
from sklearn.model_selection import train_test_split
X = sms.clean_msg
y = sms.label_num
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=1)
print(X_train.shape)
print(X_test.shape)
print(y_train.shape)
print(y_test.shape)
# 面我们介绍到我们使用了一个词矩阵,每条message使用词的特征表示,上述表示方法称为词袋模型。通过统计每个词在文本中出现的次数,我们就可以得到该文本基于词的特征,下面具体说明。
# CountVectorizer统计词频矩阵¶在词袋模型统计词频的时候,可以使用sklearn中的CountVectorizer来完成。
# CountVectorizer类会将文本中的词语转换为词频矩阵,例如矩阵中包含一个元素a[i][j],它表示j词在i类文本下的词频。
# 它通过fit_transform函数首先统计有多少词语出现,然后计算词语出现的次数,形成词频矩阵。训练集用fit_transform方法,测试集用transfrom方法。
from sklearn.feature_extraction.text import CountVectorizer
# 实例化矢量化器
vect = CountVectorizer()
# 等效地:将拟合和变换合并为一个步骤
X_train_dtm = vect.fit_transform(X_train)
# 检查文档术语矩阵
print(X_train_dtm)
# 将测试数据(使用适合的词汇表)转换为文档术语矩阵
X_test_dtm = vect.transform(X_test)
print(X_test_dtm)
from sklearn.feature_extraction.text import TfidfTransformer
tfidf_transformer = TfidfTransformer()
X_train_dtm = tfidf_transformer.fit_transform(X_train_dtm)
X_test_dtm = tfidf_transformer.transform(X_test_dtm)
print(X_test_dtm)
# 本教程中使用的模型是逻辑回归模型,逻辑回归模型是分类任务中的常用模型。
# 使用sklearn中的LogisticRegression加载逻辑回归模型。solver参数决定了我们对逻辑回归损失函数的优化方法。
# liblinear使用了开源的liblinear库实现,内部使用了坐标轴下降法来迭代优化损失函数。
# 这里我们可以使用到之前我们学习过的机器学习方法进行建模。
# 比如:决策树、随机森林、SVM
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import SVC
logreg = LogisticRegression(solver='liblinear')
svc = SVC(kernel='sigmoid', gamma=1.0)
dtc = DecisionTreeClassifier(min_samples_split=7)
rfc = RandomForestClassifier(n_estimators=31)
# 使用LR模型训练
logreg.fit(X_train_dtm, y_train)
# 使用SVM模型训练
svc.fit(X_train_dtm, y_train)
# 使用决策树模型训练
dtc.fit(X_train_dtm, y_train)
# 使用随机森林模型训练
rfc.fit(X_train_dtm, y_train)
# 对X_test_dtm进行类预测
y_pred_class = logreg.predict(X_test_dtm)
y_pred_prob = logreg.predict_proba(X_test_dtm)
# 输出前10条样本输出概率
print(y_pred_prob[0:10])
# 使用SVM模型预测
svc_y_pred_class = svc.predict(X_test_dtm)
# 使用决策树预测
dtc_y_pred_class = dtc.predict(X_test_dtm)
# 使用SVM模型预测
rfc_y_pred_class = rfc.predict(X_test_dtm)
from sklearn import metrics
# 逻辑回归准确率
logreg_acc = metrics.accuracy_score(y_test, y_pred_class)
print("逻辑回归准确率:",logreg_acc)
# SVM模型准确率
svm_acc = metrics.roc_auc_score(y_test, svc_y_pred_class)
print("SVM模型准确率:",svm_acc)
# 决策树模型准确率
dtc_acc = metrics.roc_auc_score(y_test, dtc_y_pred_class)
print("决策树模型准确率:",dtc_acc)
# 随机森林模型准确率
rfc_acc = metrics.roc_auc_score(y_test, rfc_y_pred_class)
print("随机森林模型准确率:",rfc_acc)
import numpy as np
# 将不同算法的结果准确率可视化
pred_scores = [('LogisticRegression', [logreg_acc]),
('SVM', [svm_acc]),
('DecisionTree', [dtc_acc]),
('RandomFroest', [rfc_acc])]
df = pd.DataFrame.from_dict(dict(pred_scores),orient='index', columns=['Score'])
df.plot(kind='bar', ylim=(0.7,1.0), figsize=(8,6), align='center', colormap="Accent")
plt.xticks(np.arange(4), df.index)
plt.ylabel('Accuracy Score')
plt.title('Distribution by Classifier')
plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)
plt.show()
test_case = X_test[40:50]
print(X_test[40:50])
case_test_dtm = tfidf_transformer.transform(vect.transform(test_case))
# 使用逻辑回归模型进行预测
y_pred_class = logreg.predict(case_test_dtm)
print(y_pred_class)