当前位置: 首页 > news >正文

Python数据分析案例49——基于机器学习的垃圾邮件分类系统构建(朴素贝叶斯,支持向量机)

案例背景

trec06c是非常经典的邮件分类的数据,还是难能可贵的中文数据集。
这个数据集从一堆txt压缩包里面提取出来整理为excel文件还真不容不易,肯定要做一下文本分类。
虽然现在文本分类基本都是深度学习了,但是传统的机器学习也能做。本案例就演示传统的贝叶斯,向量机,k近邻,这种传统模型怎么做邮件分类。


数据介绍

数据前3行,label是标签,spam是垃圾邮件,ham是正常邮件。content就是纯文字,中文的,还是很整洁的。

当然,需要本次案例演示数据和全部代码文件的可以参考:邮件分类


代码实现

导入需要的包、

import glob,random,re,math
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
plt.rcParams['font.sans-serif'] = ['KaiTi']  #指定默认字体 SimHei黑体
plt.rcParams['axes.unicode_minus'] = False   #解决保存图像是负号'from collections import Counter
from wordcloud import WordCloud
from matplotlib import colors
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.model_selection import train_test_split

读取数据

展示前3行

df1=pd.read_csv('email_data.csv')
df1.head(3)

统计一下数量

df1['Label'].value_counts() #统计

4w多的垃圾邮件,2w多的正常邮件,不平衡,我们抽取5k的正常邮件和5k的垃圾邮件合并作为数据。

数据量有点多,我正负样本都抽取5k条。

# 从 DataFrame 中分别抽取 5k条垃圾邮件和 5k 条正常邮件,并合并
number=5000
df = pd.concat([df1[df1['Label'] == 'spam'].sample(n=number, random_state=7),  # 抽取 5k 条垃圾邮件df1[df1['Label'] == 'ham'].sample(n=number, random_state=7)    # 抽取 5k 条正常邮件
]).reset_index(drop=True)  # 重置索引
df['Label'].value_counts()

画图查看:

plt.figure(figsize=(4,3),dpi=128)
sns.countplot(x=df['Label'])
#显示图像
plt.show()


分词

中文文本都需要进行分词,需要把里面的标点符号,通用词去一下,然后变成一个个切割开的单词。

import jieba     #过滤停用词,分词
stop_list  = pd.read_csv("停用词.txt",index_col=False,quoting=3,sep="\t",names=['stopword'], encoding='utf-8')
def txt_cut(juzi):         #Jieba分词函数lis=[w for w in jieba.lcut(juzi) if w not in stop_list.values]return (" ").join(lis)
df['text']=df['Content'].astype('str').apply(txt_cut)

查看前五行、

df.head()

后面的文本中间都像英文的空格一样分开了。

然后,再把漏掉的标点符号,占位符,去一下

df['text']=df['text'].apply(lambda x: x.replace(')','').replace('( ','').replace('-','').replace('/','').replace('( ',''))


下面进行文本的分析

正常邮件

词频分析

这里用tf-idf的词袋方法

from sklearn.feature_extraction.text import  CountVectorizer,TfidfVectorizer
from sklearn.decomposition import LatentDirichletAllocation
from sklearn.preprocessing import MinMaxScaler

将文本转为数值矩阵

df_ham=df[df['Label']=='ham']  #取出正常邮件
tf_vectorizer =TfidfVectorizer()  #tf-idf词袋
#tf_vectorizer = TfidfVectorizer(ngram_range=(2,2)) #2元词袋
X = tf_vectorizer.fit_transform(df_ham['text'])
print(X.shape)feature_names = tf_vectorizer.get_feature_names_out()
tfidf_values = X.toarray()
print(feature_names.shape,tfidf_values.shape)

查看对应的词汇名称,tf-idf的值,权重等

# 从转换器中提取词汇和对应的 TF-IDF 值
data1 = {'word': tf_vectorizer.get_feature_names_out(),'frequency':np.count_nonzero(X.toarray(), axis=0),'weight': X.mean(axis=0).A.flatten(),}
df1 = pd.DataFrame(data1).sort_values(by="frequency" ,ascending=False,ignore_index=True) 
df1.head()

可以储存一下

#储存
df1.to_excel('正常邮件词频.xlsx', index=False)

查看评率最高前20的词汇

#前20个频率最高的词汇
df2=pd.DataFrame(data1).sort_values(by="frequency" ,ascending=False,ignore_index=True) 
plt.figure(figsize=(7,3),dpi=256)
sns.barplot(x=df2['word'][:20],y=df2['frequency'][:20])
plt.xticks(rotation=70,fontsize=9) 
plt.ylabel('频率')
plt.xlabel('')
#plt.title('前20个频率最高的词汇')
plt.show()


词云图 

画出对应的词云图

#定义随机生成颜色函数
def randomcolor():colorArr = ['1','2','3','4','5','6','7','8','9','A','B','C','D','E','F']color ="#"+''.join([random.choice(colorArr) for i in range(6)])return color#from imageio import imread    #形状设置
#mask = imread('爱心.png')  
all_titles = ' '.join(df_ham['text'])
# Word segmentation
seg_list = jieba.cut(all_titles, cut_all=False)
seg_text = ' '.join(seg_list)     
#对分词文本做高频词统计
word_counts = Counter(seg_text.split())
word_counts_updated=word_counts.most_common()
#过滤标点符号
non_chinese_pattern = re.compile(r'[^\u4e00-\u9fa5]')
# 过滤掉非中文字符的词汇
filtered_word_counts_regex = [item for item in word_counts_updated if not non_chinese_pattern.match(item[0])]
filtered_word_counts_regex[:5]

# Generate word cloud
wordcloud = WordCloud(font_path='simhei.ttf', background_color='white', max_words=80,        # Limits the number of words to 100max_font_size=50)   #.generate(seg_text)    #文本可以直接生成,但是不好看
wordcloud = wordcloud.generate_from_frequencies(dict(filtered_word_counts_regex))
# Display the word cloud
plt.figure(figsize=(8, 5),dpi=256)
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis('off')
plt.show()


上面都是正常邮件的词汇分析,下面就是垃圾邮件的分析

垃圾邮件

词频分析

转为tf-idf的词矩阵

df_spam=df[df['Label']=='spam']
tf_vectorizer =TfidfVectorizer()
#tf_vectorizer = TfidfVectorizer(ngram_range=(2,2)) #2元词袋
X = tf_vectorizer.fit_transform(df_spam['text'])
#print(tf_vectorizer.get_feature_names_out())
print(X.shape)feature_names = tf_vectorizer.get_feature_names_out()
tfidf_values = X.toarray()
print(feature_names.shape,tfidf_values.shape)

# 从转换器中提取词汇和对应的 TF-IDF 值


data1 = {'word': tf_vectorizer.get_feature_names_out(),'frequency':np.count_nonzero(X.toarray(), axis=0),'weight': X.mean(axis=0).A.flatten(),}
df1 = pd.DataFrame(data1).sort_values(by="frequency" ,ascending=False,ignore_index=True) 
df1.head()

储存一下,可以看到com较多,说明垃圾邮件里面的很多网址链接

也可以储存一下

#储存
df1.to_excel('垃圾邮件词频.xlsx', index=False)

前20个词汇

#前20个频率最高的词汇
df2=pd.DataFrame(data1).sort_values(by="frequency" ,ascending=False,ignore_index=True) 
plt.figure(figsize=(7,3),dpi=256)
sns.barplot(x=df2['word'][:20],y=df2['frequency'][:20])
plt.xticks(rotation=70,fontsize=9) 
plt.ylabel('频率')
plt.xlabel('')
#plt.title('前20个频率最高的词汇')
plt.show()


词云图

#from imageio import imread    #形状设置
#mask = imread('爱心.png')  
all_titles = ' '.join(df_spam['text'])
# Word segmentation
seg_list = jieba.cut(all_titles, cut_all=False)
seg_text = ' '.join(seg_list)     
#对分词文本做高频词统计
word_counts = Counter(seg_text.split())
word_counts_updated=word_counts.most_common()
#过滤标点符号
non_chinese_pattern = re.compile(r'[^\u4e00-\u9fa5]')
# 过滤掉非中文字符的词汇
filtered_word_counts_regex = [item for item in word_counts_updated if not non_chinese_pattern.match(item[0])]
filtered_word_counts_regex[:5]

# Generate word cloud
wordcloud = WordCloud(font_path='simhei.ttf', background_color='white', max_words=80,        # Limits the number of words to 100max_font_size=50)   #.generate(seg_text)    #文本可以直接生成,但是不好看
wordcloud = wordcloud.generate_from_frequencies(dict(filtered_word_counts_regex))
# Display the word cloud
plt.figure(figsize=(8, 5),dpi=256)
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis('off')
plt.show()


机器学习

#准备X和y,还是一样的tf-idf的词表矩阵,这里限制一下矩阵的维度为5000,免得数据维度太大了训练时间很长。

#取出X和y
X = df['text']
y = df['Label']
#创建一个TfidfVectorizer的实例
vectorizer = TfidfVectorizer(max_features=5000,max_df=0.1,min_df=3)
#使用Tfidf将文本转化为向量
X = vectorizer.fit_transform(X)
#看看特征形状
X.shape

查看词汇频率

data1 = {'word': vectorizer.get_feature_names_out(),'tfidf': X.toarray().sum(axis=0).tolist()}
df1 = pd.DataFrame(data1).sort_values(by="tfidf" ,ascending=False,ignore_index=True) 
df1.head(10)


划分训练集和测试集

y映射一下,变成数值型

y1=y.map({'spam':1,'ham':0})
X_train, X_test, y_train, y_test =train_test_split(X,y,test_size=0.2,stratify=y,random_state = 0)
#可以检查一下划分后数据形状
X_train.shape,X_test.shape, y_train.shape, y_test.shape


模型对比

#采用三种模型,对比测试集精度
from sklearn.naive_bayes import MultinomialNB
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC

实例化模型

#朴素贝叶斯
model1 = MultinomialNB()
#K近邻
model2 = KNeighborsClassifier(n_neighbors=100)
#支持向量机
model3 = SVC(kernel="rbf", random_state=77, probability=True)model_list=[model1,model2,model3]
model_name=['朴素贝叶斯','K近邻','支持向量机']

自定义一下训练和评价函数

from sklearn.metrics import confusion_matrix, roc_curve, auc
from sklearn.metrics import ConfusionMatrixDisplaydef evaluate_model(model, X_train, X_test, y_train, y_test, model_name):# 训练模型model.fit(X_train, y_train)# 计算准确率accuracy = model.score(X_test, y_test)print(f'{model_name}方法在测试集的准确率为{round(accuracy, 3)}')# 计算混淆矩阵cm = confusion_matrix(y_test, model.predict(X_test))print(f'混淆矩阵:\n{cm}')# 绘制混淆矩阵热力图disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=['spam', 'ham'])disp.plot(cmap=plt.cm.Blues)plt.title(f'Confusion Matrix - {model_name}')plt.show()# 计算 ROC 曲线fpr, tpr, thresholds = roc_curve(y_test, model.predict_proba(X_test)[:, 1], pos_label='spam')roc_auc = auc(fpr, tpr)# 绘制 ROC 曲线plt.plot(fpr, tpr, label=f'{model_name} (AUC = {roc_auc:.6f})')plt.xlabel('False Positive Rate')plt.ylabel('True Positive Rate')plt.title('ROC Curve')plt.legend()plt.show()return accuracy

对三个模型都进行一下训练

accuracys=[]
for model, name in zip(model_list, model_name):accuracy=evaluate_model(model, X_train, X_test, y_train, y_test, name)accuracys.append(accuracy)

这个函数会画出很多图,混淆矩阵,ROC的图,评价指标等。

查看三个模型的准确率

accuracys

准确率进行可视化

plt.figure(figsize=(7,3),dpi=128)
sns.barplot(y=model_name,x=accuracys,orient="h")
plt.xlabel('模型准确率')
plt.ylabel('模型名称')
plt.xticks(fontsize=10,rotation=45)
plt.title("不同模型文本分类准确率对比")
plt.show()

支持向量机准确率最高!

ROC对比

plt.figure(figsize=(8, 6),dpi=128)# 遍历每个模型,绘制其 ROC 曲线
for model, name in zip(model_list, model_name):model.fit(X_train, y_train)  # 训练模型fpr, tpr, _ = roc_curve(y_test, model.predict_proba(X_test)[:, 1], pos_label='spam')  # 计算 ROC 曲线的参数roc_auc = auc(fpr, tpr)  # 计算 AUCplt.plot(fpr, tpr, label=f'{name} (AUC = {roc_auc:.6f})')  # 绘制 ROC 曲线# 绘制对角线
plt.plot([0, 1], [0, 1], linestyle='--', color='grey', label='Random')
# 设置图形属性
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('ROC Curve')
plt.legend()
plt.show()

支持向量机的auc最高。


四个评价指标

模型再实例化一下,我们计算分类问题常用的四个评价指标,准确率,精准度,召回率,F1值

from sklearn.metrics import confusion_matrix
from sklearn.metrics import classification_report
from sklearn.metrics import cohen_kappa_score
#朴素贝叶斯
model1 = MultinomialNB()
#K近邻
model2 = KNeighborsClassifier(n_neighbors=100)
#支持向量机
model3 = SVC(kernel="rbf", random_state=77, probability=True)model_list=[model1,model2,model3]
#model_name=['朴素贝叶斯','K近邻','支持向量机']

自定义评价指标

def evaluation(y_test, y_predict):accuracy=classification_report(y_test, y_predict,output_dict=True)['accuracy']s=classification_report(y_test, y_predict,output_dict=True)['weighted avg']precision=s['precision']recall=s['recall']f1_score=s['f1-score']#kappa=cohen_kappa_score(y_test, y_predict)return accuracy,precision,recall,f1_score #, kappa
def evaluation2(lis):array=np.array(lis)return array.mean() , array.std()

循环,遍历,预测,计算评价指标

df_eval=pd.DataFrame(columns=['Accuracy','Precision','Recall','F1_score'])
for i in range(3):model_C=model_list[i]name=model_name[i]model_C.fit(X_train, y_train)pred=model_C.predict(X_test)s=classification_report(y_test, pred)s=evaluation(y_test,pred)df_eval.loc[name,:]=list(s)

查看

df_eval

可视化

bar_width = 0.4
colors = ['c', 'g', 'tomato', 'b', 'm', 'y', 'lime', 'k', 'orange', 'pink', 'grey', 'tan']
fig, axes = plt.subplots(2, 2, figsize=(7, 6), dpi=128)for i, col in enumerate(df_eval.columns):ax = axes[i//2, i%2]  # 这将为每个子图指定一个轴df_col = df_eval[col]m = np.arange(len(df_col))bars = ax.bar(x=m, height=df_col.to_numpy(), width=bar_width, color=colors)# 在柱状图上方显示数值for bar in bars:yval = bar.get_height()ax.text(bar.get_x() + bar.get_width()/2, yval, round(yval, 4), ha='center', va='bottom', fontsize=8)# 设置x轴names = df_col.indexax.set_xticks(range(len(df_col)))ax.set_xticklabels(names, fontsize=10, rotation=40)# 设置y轴ax.set_ylim([0.94, df_col.max() + 0.02]) ax.set_ylabel(col, fontsize=14)plt.tight_layout()
# plt.savefig('柱状图.jpg', dpi=512)  # 如果需要保存图片取消注释这行
plt.show()

很明显支持向量机 效果最好


交叉验证

自定义交叉验证评价指标和函数

def evaluation(y_test, y_predict):accuracy=classification_report(y_test, y_predict,output_dict=True)['accuracy']s=classification_report(y_test, y_predict,output_dict=True)['weighted avg']precision=s['precision']recall=s['recall']f1_score=s['f1-score']#kappa=cohen_kappa_score(y_test, y_predict)return accuracy,precision,recall,f1_score #, kappa
def evaluation2(lis):array=np.array(lis)return array.mean() , array.std()
from sklearn.model_selection import KFold
def cross_val(model=None,X=None,Y=None,K=5,repeated=1,show_confusion_matrix=True):df_mean=pd.DataFrame(columns=['Accuracy','Precision','Recall','F1_score']) df_std=pd.DataFrame(columns=['Accuracy','Precision','Recall','F1_score'])for n in range(repeated):print(f'正在进行第{n+1}次重复K折.....随机数种子为{n}\n')kf = KFold(n_splits=K, shuffle=True, random_state=n)Accuracy=[]Precision=[]Recall=[]F1_score=[]print(f"    开始本次在{K}折数据上的交叉验证.......\n")i=1for train_index, test_index in kf.split(X):print(f'        正在进行第{i}折的计算')X_train=X[train_index]y_train=np.array(y)[train_index]X_test=X[test_index]y_test=np.array(y)[test_index]model.fit(X_train,y_train)pred=model.predict(X_test)score=list(evaluation(y_test,pred))Accuracy.append(score[0])Precision.append(score[1])Recall.append(score[2])F1_score.append(score[3])if show_confusion_matrix:#数据透视表,混淆矩阵print("混淆矩阵:")table = pd.crosstab(y_test, pred, rownames=['Actual'], colnames=['Predicted'])#print(table)plt.figure(figsize=(4,3))sns.heatmap(table,cmap='Blues',fmt='.20g', annot=True)plt.tight_layout()plt.show()#计算混淆矩阵的各项指标print('混淆矩阵的各项指标为:')print(classification_report(y_test, pred))print(f'        第{i}折的准确率为:{round(score[0],4)},Precision为{round(score[1],4)},Recall为{round(score[2],4)},F1_score为{round(score[3],4)}')i+=1print(f'    ———————————————完成本次的{K}折交叉验证———————————————————\n')Accuracy_mean,Accuracy_std=evaluation2(Accuracy)Precision_mean,Precision_std=evaluation2(Precision)Recall_mean,Recall_std=evaluation2(Recall)F1_score_mean,F1_score_std=evaluation2(F1_score)print(f'第{n+1}次重复K折,本次{K}折交叉验证的总体准确率均值为{Accuracy_mean},方差为{Accuracy_std}')print(f'                               总体Precision均值为{Precision_mean},方差为{Precision_std}')print(f'                               总体Recall均值为{Recall_mean},方差为{Recall_std}')print(f'                               总体F1_score均值为{F1_score_mean},方差为{F1_score_std}')print("\n====================================================================================================================\n")df1=pd.DataFrame(dict(zip(['Accuracy','Precision','Recall','F1_score'],[Accuracy_mean,Precision_mean,Recall_mean,F1_score_mean])),index=[n])df_mean=pd.concat([df_mean,df1])df2=pd.DataFrame(dict(zip(['Accuracy','Precision','Recall','F1_score'],[Accuracy_std,Precision_std,Recall_std,F1_score_std])),index=[n])df_std=pd.concat([df_std,df2])return df_mean,df_std

实例化三个模型

model1 = MultinomialNB()
#K近邻
model2 = KNeighborsClassifier(n_neighbors=100)
#支持向量机
model3 = SVC(kernel="rbf", random_state=77, probability=True)

贝叶斯: 

model =MultinomialNB()
nb_crosseval,nb_crosseval2=cross_val(model=model,X=X,Y=y,K=5,repeated=6)

结果都打印出来的。

朴素贝叶斯的评价指标

nb_crosseval

K近邻

model =KNeighborsClassifier(n_neighbors=100)
knn_crosseval,knn_crosseval2=cross_val(model=model,X=X,Y=y,K=5,repeated=6,show_confusion_matrix=False)

不放过程了,直接上结果

knn_crosseval

支持向量机

model = SVC(kernel="rbf", random_state=77, probability=True)
svc_crosseval,svc_crosseval2=cross_val(model=model,X=X,Y=y,K=5,repeated=6,show_confusion_matrix=False)

评价指标

svc_crosseval


均值的可视化

plt.subplots(1,4,figsize=(16,3),dpi=128)
for i,col in enumerate(nb_crosseval.columns):n=int(str('14')+str(i+1))plt.subplot(n)plt.plot(nb_crosseval[col], 'k', label='NB')plt.plot(knn_crosseval[col], 'b-.', label='KNN')plt.plot(svc_crosseval[col], 'r-^', label='SVC')plt.title(f'不同模型的{col}对比')plt.xlabel('重复交叉验证次数')plt.ylabel(col,fontsize=16)plt.legend()
plt.tight_layout()
plt.show()

 

方差的可视化

plt.subplots(1,4,figsize=(16,3),dpi=128)
for i,col in enumerate(nb_crosseval2.columns):n=int(str('14')+str(i+1))plt.subplot(n)plt.plot(nb_crosseval2[col], 'k', label='NB')plt.plot(knn_crosseval2[col], 'b-.', label='KNN')plt.plot(svc_crosseval2[col], 'r-^', label='SVC')plt.title(f'不同模型的{col}方差对比')plt.xlabel('重复交叉验证次数')plt.ylabel(col,fontsize=16)plt.legend()
plt.tight_layout()
plt.show()

结论:

我们将进行三种机器学习模型的性能分析:朴素贝叶斯(Naive Bayes)、k近邻(k-Nearest Neighbors)和支持向量机(Support Vector Machine)。

### 1. 朴素贝叶斯模型分析:

朴素贝叶斯模型在数据集上表现出了相对较高的性能。具体来说,它在准确率(Accuracy)、精确率(Precision)、召回率(Recall)和F1分数(F1-score)方面均取得了稳定的表现,分别达到了约96%的水平。这表明朴素贝叶斯模型在数据分类方面具有较高的效果,并且不易受到数据波动的影响。

### 2. k近邻模型分析:

与朴素贝叶斯相比,k近邻模型在性能上稍显不及。尽管其在准确率和F1分数方面表现相当,但在精确率和召回率方面略有下降,分别在95%左右。这可能表明k近邻模型在处理数据集中的某些特征时存在一定的困难,导致了一些分类错误。

### 3. 支持向量机模型分析:

支持向量机(SVM)模型在这份数据集上展现了最佳的性能。其在所有评估指标上均表现出了接近98%的高水平,包括准确率、精确率、召回率和F1分数。这表明支持向量机模型在数据分类任务中具有较强的鲁棒性和泛化能力,能够有效地捕捉数据之间的复杂关系,并进行准确的分类。

综上所述,支持向量机模型在这份数据集上表现最佳,其稳定性和高性能使其成为首选模型。朴素贝叶斯模型在某些情况下也是一个可行的选择,而k近邻模型可能需要进一步优化以提高其性能。

支持向量机的准确率最高,模型波动的方差小,效果最好,下面对它进行超参数搜索。


超参数搜索

#利用K折交叉验证搜索最优超参数
from sklearn.model_selection import KFold, StratifiedKFold
from sklearn.model_selection import GridSearchCV,RandomizedSearchCV

参数范围

param_grid = {'C': [0.1, 1, 10],'gamma': [ 0.01, 0.1, 1, 10]}model = GridSearchCV(estimator=SVC(kernel="rbf"), param_grid=param_grid, cv=3)
model.fit(X_train, y_train)

参数

model.best_params_

 

评估

model = model.best_estimator_
pred=model.predict(X_test)
evaluation(y_test,pred)

对这个区间再度细化搜索

param_grid = {'C': [6,7,8,9,10,11,12,13,14],'gamma': [ 0.08,0.09,0.1,0.15,0.2,0.3]}model = GridSearchCV(estimator=SVC(kernel="rbf"), param_grid=param_grid, cv=3)
model.fit(X_train, y_train)

model.best_params_

 

model = model.best_estimator_
pred=model.predict(X_test)
evaluation(y_test,pred)

能达到99%准确率了。

画图:

import itertools
def plot_confusion_matrix(cm, classes,title='Confusion matrix',cmap=plt.cm.Blues):plt.imshow(cm, interpolation='nearest', cmap=cmap)plt.title(title)plt.colorbar()tick_marks = np.arange(len(classes))plt.xticks(tick_marks, classes, rotation=0)plt.yticks(tick_marks, classes)thresh = cm.max() / 2.for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):plt.text(j, i, cm[i, j],horizontalalignment="center",color="white" if cm[i, j] > thresh else "black")plt.tight_layout()plt.ylabel('True label')plt.xlabel('Predicted label')

 最好的模型:

import time 
svc=SVC(kernel="rbf",C=6  , gamma=0.09)
startTime = time.time()
svc.fit(X_train, y_train)
print('svc分类器训练用时%.2f秒' %(time.time()-startTime))
pred=svc.predict(X_test)
print(f"准确率,精确度,召回率,F1值:{np.round(evaluation(y_test,pred),6)}")
plot_confusion_matrix(confusion_matrix(y_test,pred),[0,1])
plt.show()

模型保存

import joblib
# 模型已经选取了最佳估计器,存储在变量 model 中
# 保存模型到文件
joblib.dump(model, 'best_model.pkl')

加载模型,然后预测

# 加载模型
loaded_model = joblib.load('best_model.pkl')
# 使用加载的模型进行预测
loaded_model.predict(X_test)
evaluation(y_test, pred)

 基本是99%的准确率,还是很好用的。


创作不易,看官觉得写得还不错的话点个关注和赞吧,本人会持续更新python数据分析领域的代码文章~(需要定制类似的代码可私信)

相关文章:

Python数据分析案例49——基于机器学习的垃圾邮件分类系统构建(朴素贝叶斯,支持向量机)

案例背景 trec06c是非常经典的邮件分类的数据,还是难能可贵的中文数据集。 这个数据集从一堆txt压缩包里面提取出来整理为excel文件还真不容不易,肯定要做一下文本分类。 虽然现在文本分类基本都是深度学习了,但是传统的机器学习也能做。本案…...

贪心算法-以学籍管理系统为例

1.贪心算法介绍 1.算法思路 贪心算法的基本思路是从问题的某一个初始解出发一步一步地进行,根据某个优化测度,每一 步都要确保能获得局部最优解。每一步只考虑一 个数据,其选取应该满足局部优化的条件。若下 一个数据和部分最优解连在一起…...

PyCharm 安装

PyCharm是一种流行的Python集成开发环境(IDE),由JetBrains公司开发。它提供了丰富的功能,如智能代码补全、实时错误检查、项目导航、调试工具以及版本控制等,极大地提高了Python开发人员的工作效率。以下是PyCharm安装…...

C++:对象指针访问成员函数

使用箭头操作符 (->):ptr->function() 是最常用和推荐的方式,因为它更简洁、更直观。箭头操作符 (->) 被设计为与点操作符 (.) 配合指针一起使用,以便通过指针访问对象的成员。 先解引用指针,然后使用点操作符 (.)&…...

Linux 防火墙配置指南:firewalld 端口管理应用案例(二十个实列)

🏡作者主页:点击! 🐧Linux基础知识(初学):点击! 🐧🐧Linux高级管理专栏:点击! 🔐Linux中firewalld防火墙:点击! ⏰️…...

推荐Bulk Image Downloader插件下载网页中图片链接很好用

推荐:Bulk Image Downloader chome浏览器插件下载图片链接,很好用。 有个网页,上面放了数千的gif的电路图,手工下载会累瘫了不可。想找一个工具分析它的静态链接并下载,找了很多推荐的下载工具,都是不能分…...

详解前缀码与前缀编码

前缀编码是一种数据压缩技术,也被称为可变长度编码。它的基本原理是将频繁出现的字符或字符序列用较短的编码表示,而较少出现的字符或字符序列用较长的编码表示,从而达到压缩数据的目的。 概念定义 前缀码:给定一个编码序列的集合…...

数据库管理工具 -- Navicat Premium v17.0.8 特别版

软件简介 Navicat Premium 是一款功能强大的数据库管理工具,适用于Windows、Mac和Linux平台。它支持多种数据库,包括MySQL、MariaDB、SQL Server、PostgreSQL、Oracle、SQLite等。用户可以通过Navicat Premium轻松地连接到各种数据库服务器,…...

【Linux】进程创建和终止 | slab分配器

进程创建 fork 1.fork 之后发生了什么 将给子进程分配新的内存块和内核数据结构(形成了新的页表映射)将父进程部分数据结构内容拷贝至子进程添加子进程到系统进程列表当中fork 返回,开始调度器调度 这样就可以回答之前返回两个值&#xff1f…...

计算机网络--网络层

一、网络层的服务和功能 网络层主要为应用层提供端对端的数据传输服务 网络层接受运输层的报文段,添加自己的首部,形成网络层分组。分组是网络层的传输单元。网络层分组在各个站点的网络层之间传输,最终到达接收方的网络层。接收方网络层将运…...

【CSS】如何实现分栏布局

在CSS分栏布局中,设置宽度和样式是一个基本且重要的步骤。这可以通过直接应用样式到列元素(通常是div元素)上来实现。以下是一些常用的方法来设置分栏布局的宽度和样式: 1. 使用百分比宽度 使用百分比宽度可以使列的大小相对于其…...

2025湖北武汉智慧教育装备信息化展/智慧校园展/湖北高博会

2025武汉教育装备展,2025武汉智慧教育展,2025武汉智慧校园展,2025武汉教育信息化展,2025武汉智慧教室展,湖北智慧校园展,湖北智慧教室展,武汉教学设备展,湖北高教会,湖北高博会 2025湖北武汉智慧教育装备信息化展/智慧校园展/湖北高博会 2025第10届武汉国际教育装备及智慧校园…...

Android Studio Run窗口中文乱码解决办法

Android Studio Run窗口中文乱码解决办法 问题描述: AndroidStudio 编译项目时Run窗口中文乱码,如图: 解决方法: 依次打开菜单:Help--Edit Custom VM Options,打开studio64.exe.vmoptions编辑框&#xf…...

代码随想录——划分字母区间(Leetcode763)

题目链接 贪心 class Solution {public List<Integer> partitionLabels(String s) {int[] count new int[27];Arrays.fill(count,0);// 统计元素最后一次出现的位置for(int i 0; i < s.length(); i){count[s.charAt(i) - a] i;}List<Integer> res new Ar…...

SQL注入方法

文章目录 前言如何测试与利用注入点手工注入思路工具sqlmap-r-u-m--level--risk-v-p--threads-batch-smart--os-shell--mobiletamper插件获取数据的相关参数 前言 记录一些注入思路和经常使用的工具&#xff0c;后续有用到新的工具和总结新的方法再继续补充。 如何测试与利用注…...

Vue表单输入绑定v-model

表单输入绑定 在前端处理表单时&#xff0c;我们常常需要将表单输入框的内容同步给Javascript中相应的变量。手动连接绑定和更改事件监听器可能会很麻&#xff0c;v-model 指令帮我们简化了这一步骤。 <template><h3>表单输入绑定</h3><hr> <inpu…...

【分布式系统】ELK 企业级日志分析系统

目录 一.ELK概述 1.简介 1.1.可以添加的其他组件 1.2.filebeat 结合 logstash 带来好处 2.为什么使用ELK 3.完整日志系统基本特征 4.工作原理 二.部署ELK日志分析系统 1.初始化环境 2.完成JAVA部署 三. ELK Elasticsearch 集群部署 1.安装 2.修改配置文件 3.es 性…...

vs2019 无法打开项目文件

vs2019 无法打开项目文件&#xff0c;无法找到 .NET SDK。请检查确保已安装此项且 global.json 中指定的版本(如有)与所安装的版本相匹配 原因&#xff1a;缺少组件 解决方案&#xff1a;选择需要的组件进行安装完成...

Elasticsearch:Painless scripting 语言(一)

Painless 是一种高性能、安全的脚本语言&#xff0c;专为 Elasticsearch 设计。你可以使用 Painless 在 Elasticsearch 支持脚本的任何地方安全地编写内联和存储脚本。 Painless 提供众多功能&#xff0c;这些功能围绕以下核心原则&#xff1a; 安全性&#xff1a;确保集群的…...

SpringBoot项目练习

文章目录 SpringBootVue后台管理系统所需软件下载、安装、版本查询Vue搭建一个简单的Vue项目 Spring项目1项目架构 SpringBootVue后台管理系统 学习视频&#xff1a; https://www.bilibili.com/video/BV1U44y1W77D/?spm_id_from333.337.search-card.all.click&vd_sourcec…...

Android Gradle 开发与应用 (七): Gradle 插件开发与发布

目录 一、概述 二、Gradle插件的基础知识 2.1 Gradle插件的定义 2.2 Gradle插件的种类 2.3 Gradle插件的生命周期 三、开发一个Gradle插件 3.1 创建Gradle插件项目 3.2 编写插件实现 3.3 配置插件元数据 3.4 构建和测试插件 3.5 在项目中应用插件 四、发布Gradle插…...

方法引用详解

什么是方法引用&#xff1f;&#xff1a;针对于函数式接口中的抽象方法 为什么用方法引用&#xff1f;&#xff1a;避免代码的重复&#xff0c;简便书写&#xff0c;提高效率 在使用Lambda表达式的时候&#xff0c;我们实际上传递进去的代码就是一种解决方案&#xff1a;拿参数…...

Apache Seata 高可用部署实践

本文来自 Apache Seata官方文档&#xff0c;欢迎访问官网&#xff0c;查看更多深度文章。 本文来自 Apache Seata官方文档&#xff0c;欢迎访问官网&#xff0c;查看更多深度文章。 Apache Seata 高可用部署实践 Seata 高可用部署实践 使用配置中心和数据库来实现 Seata 的高…...

nginx配置尝试

from fastapi import FastAPI, File, UploadFile, HTTPException from fastapi.responses import JSONResponse, FileResponse, HTMLResponse import logging import os from datetime import datetime import uvicorn# 初始化日志 logging.basicConfig(filenamefile_server.lo…...

SAR目标检测

Multi-Stage with Filter Augmentation 多阶段滤波器增强(MSFA) 对SAR合成孔径雷达目标检测性能的改善 MSFA ON SAR 传统方法: 预训练:传统方法开始于在通用数据集上预训练一个基础模型。 微调:这个预训练的模型会被微调以适应特定的SAR图像&#xff0c;试图缩小域间的差距 …...

创新配置,秒级采集,火爆短视频评论抓取

快速采集评论数据的好处 快速采集评论数据是在当今数字信息时代的市场趋势分析和用户反馈分析中至关重要的环节。通过准确获取并分析大量用户评论&#xff0c;您将能够更好地了解消费者的需求、情感和偏好。集蜂云采集平台提供了一种简单配置的方法&#xff0c;使您能够快速采…...

STL—容器—string类【对其结构和使用的了解】【对oj相关练习的训练】

STL—容器—string类 其实string类准确来说并不是容器&#xff0c;因为他出现的时间比STL要早&#xff0c;但是也可以说是容器吧。 1.为什么要学习string类&#xff1f; 1.1C语言当中的字符串 C语言中&#xff0c;字符串是以’\0’结尾的一些字符的集合&#xff0c;为了操作…...

讲个SystemVerilog随机约束小坑

正文 记录个在写SystemVerilog随机约束时遇到的一个小坑&#xff0c;如果没有认真去查看随机结果是否符合预期&#xff0c;还真不容易发现。 为了方便讲述&#xff0c;写了如下示例代码。类cl_a里有个随机变量aa&#xff0c;初始值为222。在module top里对类cl_a例化并进行约…...

mysql在windows下的安装

软件安装 配置环境变量 测试...

uniapp 在手机上导出excel

1.创建excelDev.js文件 export default {exportExcel(fileData, documentName excel) {plus.io.requestFileSystem(plus.io.PUBLIC_DOCUMENTS, function(fs) {let rootObj fs.rootlet fullPath rootObj.fullPathconsole.log("开始导出数据")// 创建文件夹rootObj…...

收银系统源码-收银台副屏广告

1. 功能描述 门店广告&#xff1a;双屏收银机&#xff0c;副屏广告&#xff0c;主屏和副屏同步&#xff0c;总部可统一控制广告位&#xff0c;也可以给门店开放权限&#xff0c;门店独立上传广告位&#xff1b; 2.适用场景 新店开业、门店周年庆、节假日门店活动宣传&#x…...

【TORCH】torch.normal()中的size参数

在 torch.normal() 函数中&#xff0c;size 参数用于指定生成张量的形状。torch.normal() 函数用于从正态&#xff08;高斯&#xff09;分布中生成随机数。函数的基本形式是&#xff1a; torch.normal(mean, std, size)mean&#xff1a;均值&#xff0c;可以是标量或张量。如果…...

【第20章】MyBatis-Plus逻辑删除支持

文章目录 前言一、逻辑删除的工作原理二、支持的数据类型三、使用方法1.配置全局逻辑删除属性2.在实体类中使用 TableLogic 注解 四、常见问题解答1. 如何处理插入操作&#xff1f;2. 删除接口自动填充功能失效怎么办&#xff1f; 五、实战1. 全局配置2. 添加TableLogic3. 自动…...

【IT领域新生必看】 Java编程中的重载(Overloading):初学者轻松掌握的全方位指南

文章目录 引言什么是方法重载&#xff08;Overloading&#xff09;&#xff1f;方法重载的基本示例 方法重载的规则1. 参数列表必须不同示例&#xff1a; 2. 返回类型可以相同也可以不同示例&#xff1a; 3. 访问修饰符可以相同也可以不同示例&#xff1a; 4. 可以抛出不同的异…...

python转文本为语音并播放

python转文本为语音并播放 1、导入库 pip install pyttsx3==2.902、流程 1、初始化tts引擎 2、设置音量(0到1之间) 3、设置语速 4、 设置声音对象,voices[0].id代表男生,voices[1].id代表女生 5、转换文本并播放 6、挂起声音引擎3、代码 # -*- coding: utf-8 -*-"…...

解锁高效软件测试:虚拟机助力提升测试流程的秘诀

众所周知&#xff0c;软件测试在软件开发生命周期中至关重要。它确保软件符合要求&#xff0c;没有漏洞&#xff0c;并帮助开发人员优化性能&#xff0c;验证项目功能。 然而&#xff0c;测试可能既耗时又耗费资源&#xff0c;特别是当需要在不同操作系统和配置上测试软件组件…...

创建vue3项目

npm create vuelatest 编译打包生成报告 yarn add rollup-plugin-visualizer vite.config.ts: import { fileURLToPath, URL } from node:urlimport { defineConfig } from vite import vue from vitejs/plugin-vue import vueJsx from vitejs/plugin-vue-jsx import vueDevTo…...

中国网络安全审查认证和市场监管大数据中心数据合规官CCRC-DCO

关于CCRC-DCO证书的颁发机构&#xff0c;它是由中国网络安全审查认证与市场监管大数据中心&#xff08;简称CCRC&#xff09;负责。 该中心在2006年得到中央机构编制委员会办公室的批准成立&#xff0c;隶属于国家市场监督管理总局&#xff0c;是其直辖的事业单位。 依据《网络…...

Web漏洞扫描工具AppScan与AWVS测评及使用体验

AppScan和AWVS业界知名的Web漏洞扫描工具&#xff0c;你是否也好奇到底哪一个能力更胜一筹呢&#xff1f;接下来跟随博主一探究竟吧。 1. 方案概览 第一步&#xff1a;安装一个用于评测的Web漏洞靶场&#xff08;本文采用最知名和最广泛使用的靶场&#xff0c;即OWASP Benchma…...

瞰景Smart3D使用体验分享

引言 作为一名建筑设计师&#xff0c;我一直在寻找能够提升工作效率和设计质量的软件工具。瞰景Smart3D&#xff08;Smart3D&#xff09;是一款备受推崇的3D建模和设计软件&#xff0c;广泛应用于建筑、工程和施工&#xff08;AEC&#xff09;行业。经过一段时间的使用&#x…...

Android系统adb shell dumpsys activity processes

在Android系统中&#xff0c;adb shell dumpsys activity processes 命令是一个非常强大的工具&#xff0c;用于获取当前系统中所有运行进程的详细信息&#xff0c;包括它们的状态、内存使用情况、任务栈等。这对于开发者来说非常有用&#xff0c;尤其是在调试应用、分析系统性…...

vue侦听器watch()

侦听器watch&#xff08;&#xff09; 侦听器侦听数据变化&#xff0c;我们可以使用watch 选项在每次响应式属性变化时触发一个函数。 <template><h3>侦听器watch</h3><hr> <p>{{nessage}}</p> <button click"exchage">…...

如何用Python向PPT中批量插入图片

办公自动化办公中&#xff0c;Python最大的优势是可以批量操作&#xff0c;省去了用户粘贴、复制、插入等繁琐的操作。经常做PPT的朋友都知道&#xff0c;把图片插入到PPT当中的固定位置是一个非常繁琐的操作&#xff0c;往往调整图片时耗费大量的时间和精力。如何能省时省力插…...

C# Socket

Socket命名空间&#xff1a;创建 Socket&#xff1a;连接到服务器&#xff08;客户端&#xff09;&#xff1a;绑定和监听&#xff08;服务器端&#xff09;&#xff1a;接受连接&#xff08;服务器端&#xff09;&#xff1a;发送和接收数据&#xff1a;关闭 Socket&#xff1…...

node的下载、安装、配置和使用(node.js下载安装和配置、npm命令汇总、cnpm的使用)

天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。 愿将腰下剑,直为斩楼兰。 ——《塞下曲》 文章目录 一、node.js的下载、安装和配置1. node.js下…...

深度卷积神经网络 AlexNet

一、机器学习深度学习的发展 1、机器学习SVM方法 &#xff08;1&#xff09;20世纪90年代&#xff0c;基于统计学习理论的结果&#xff0c;开发了一种新型的学习算法——支持向量机&#xff08;SVM&#xff09;。这就产生了一类新的理论上优雅的学习机器&#xff0c;它们将SVM…...

【刷题汇总--大数加法、 链表相加(二)、大数乘法】

C日常刷题积累 今日刷题汇总 - day0061、大数加法1.1、题目1.2、思路1.3、程序实现 2、 链表相加(二)2.1、题目2.2、思路2.3、程序实现 3、大数乘法3.1、题目3.2、思路3.3、程序实现 4、题目链接 今日刷题汇总 - day006 1、大数加法 1.1、题目 1.2、思路 读完题,明白大数相加…...

基于Java的网上花店系统

目 录 1 网上花店商品销售网站概述 1.1 课题简介 1.2 设计目的 1.3 系统开发所采用的技术 1.4 系统功能模块 2 数据库设计 2.1 建立的数据库名称 2.2 所使用的表 3 网上花店商品销售网站设计与实现 1. 用户注册模块 2. 用户登录模块 3. 鲜花列表模块 4. 用户购物车…...

uniApp 封装VUEX

Vuex Store (index.js) import Vue from vue; import Vuex from vuex; import Cookies from js-cookie;Vue.use(Vuex);const saveStateKeys [vuex_user, vuex_token, vuex_demo];const initialState {vuex_user: { name: 用户信息 },vuex_token: Cookies.get(token) || ,vue…...

最长公共子序列求长度和输出子序列C代码

求两个字符串的公共子序列我们都知道需要使用用动态规划思想 用res[i][j]表示截止到字符串A的第i个字符串和截止到字符串B的第j个字符的最长公共子序列。如两个字符串helloworld和loop&#xff0c;res[5][3]表示子串hello和子串loo的最长公共子序列&#xff0c;为lo&#xff0…...