基于美国群众收入数据做相关分析与挖掘
目录
3.2:计算体重、教育年限、工作时长它们之间的皮尔森相关性 7
1:引言
研究目的与意义
本文将基于一份外国3万多的人群数的相关收入信息数据,建立机器学习来预测人群收入的多少,其中预测因变量就是年收入是否大于50K美元。如今是大数据和云计算时代,在海量高维数据环境下,再通过人工或者机械行的方法来处理相关数据问题,变得不可行,而且结果也不太客观。然而基于大数据技术来做这些事,将会变得更加有意义。本文就是基于机器学习技术来预测和分析我们所需要的人群收入内在价值信息,通过内在信息做到对人群信息的掌握,从而统筹好社会发展。
研究背景
人群收入是大众关心的非常重要的经济生活话题,然而人群收入受很多方面的因素影响,有年龄因素、工作性质因素、国家来源因素以及每周工作时长因素等等。根据统计和经济学知识,这些因素确实是跟收入有一定关系的,所以我们这里涉及的预测自变量有15个相关的指标,当然为了保护人群的隐私数据,很大部分数据值都存在脱敏处理,但这并不代表我们不能运用这些信息,重新运用这些信息是需要相应的转换和数据分析的。
2:数据的预处理
数据预处理是建模非常重要的组成部分,良好的预处理能对后续建模起到事半功倍的效果。在工程实践中,我们得到的数据会存在有缺失值、重复值等,在使用之前需要进行数据预处理。数据预处理没有标准的流程,通常针对不同的任务和数据集属性的不同而不同。数据预处理的常用流程为:去除唯一属性、处理缺失值、属性编码、数据标准化正则化等。
2.1:字段数据转换
先对数据的缺失值进行删除(缺失值不是很多),由于本身数据很多字段对应的值为字符串数据,但是字符串数据是不能参与运算的,可是我们还非常想充分利用此数据集,所以将字符串数据改写为类别数值数据,因为涉及的数据很多,所以我们必须通过编程自动化处理以上过程(但“教育程度”有个等级存在,跟“教育年限”有关,我们直接取“教育年限”数据即可),原始数据集如下:
2.2:异常值处理
由于数据集数目过多,往往会存在异常的情况,为了高效和有效地检测出每个变量时候存在异常值,我们将采用多项式拟合+统计方法来处理,但不处理类别数据,只对连续型数据(排除“年龄”和“教育年限”,这两列数据非常常规不做处理)做处理。
由上图“资本收益”数据的异常值明显过于多,异常数据将会被其他数据替换。
2.3:稀疏值处理
我们还明显地发现,“资本收益”序列数数存在明显的稀疏情况(0的个数占比92%),“资本损失”也是(0的个数占比95%),稀疏数据的大量存在一方面导致运算复杂,另一方面会对模型造成过拟合现象,我们建议去除这两列数据。最终处理结果如下:
3:数据的特征工程与可视化
特征工程是机器学习,甚至是深度学习中最为重要的一部分特征工程主要是对特征进行筛选,构造与降维等等,可以选择主要特征和构造新的特征,从而增加模型泛化能力。
可视化更是让我们清楚了解数据组成部分,为深度分析做准备。
3.1:计算体重、教育年限、工作时长的相关特征值
体重 | 教育年限 | 一周工作时长 | |
计数 | 30162.000000 | 30162.000000 | 30162.000000 |
均值 | 189097.509767 | 10.121312 | 40.931238 |
标准差 | 102371.063921 | 2.549995 | 11.979984 |
最小值 | 13769.000000 | 1.000000 | 1.000000 |
25%分位值 | 117627.250000 | 9.000000 | 40.000000 |
50%分位值 | 178425.000000 | 10.000000 | 40.000000 |
75%分位值 | 237628.500000 | 13.000000 | 45.000000 |
最大值 | 767403.000000 | 16.000000 | 99.000000 |
上表就是相关数据的描述性统计特征值,由此我们发现,这些数据的分布范围和数量级都是不同的,尤其体重(脱敏后信息)的数量级是非常大的,所以在后面的建模中,我们要主要有些变量的取值不同带来的负面效果。
3.2:计算体重、教育年限、工作时长它们之间的皮尔森相关性
为了减少共线性变量带来的运算资源的浪费,接下来,通过变量之间的相关性分析来筛选变量,根据相关系数理论,当两变量之间的相关系数绝对值大于0.8时,可以认为两变量相关性非常强烈,取之一即可,具体见下表展示:
斯皮曼尔相关系数等级
相关系数绝对值 | 0.0-0.2 | 0.2-0.4 | 0.4-0.6 | 0.6-0.8 | 0.8-1.0 |
相关等级 | 极弱相关或无相关 | 弱相关 | 中等程度相关 | 强相关 | 极强相关 |
体重 | 教育年限 | 每周工作时长 | |
体重 | 1.000000 | -0.046247 | -0.022791 |
教育年限 | -0.046247 | 1.000000 | -0.152522 |
每周工作时长 | -0.022791 | 0.152522 | 1.000000 |
由于上述三种数据本身就是连续型数值数据,所以我们选择这些数据做特征分析和相关性分析,由上述相关系数值的计算,我们发现这三则的两两之间,并没有什么太大关系,甚至还有点负相关关系。
3.3:变量分布的可视化
上述3幅图就是这三个变量对应的概率密度分布图,我们发现,这些变量的分布并不是很标准的正态分布,但也都有非常突出的区间段数据,尤其是教育年限达到13年左右,也是个人数非常集中的区间段落。每周工作时长集中在40小时左右,看来非常符合8小时工作日的平常制度。
3.4:其他分析可视化
接下来将通过其他图形类型来更多维度展示数据结构。
由上图的扇形图发现,此数据集的人种分布很明显是白人和黑人组成,占了95%以上,这是比较符合美国国情的。
由上述分布柱状图我们发现男性和女性的教育年限基本都分布在9-13年这区域,这点是相同的,但不同的是男性的教育年限在第9年的人数比例是非常大的,比女性要大很多。
此图中的“1”代表的是收入大于50K的,“2”是收入小于50K的,我们发现在大于50K的人数分布比例上,男性是明显大于女性的(女性比值大约是8.1,男性大约是2.3),这侧面说明高收入人群还是男性居多,男性更多是创造社会财富,女性也许更多的是照顾家庭。
4:数据建模与挖掘
数据建模是数据挖掘的重点也是难点,只有在充分理解数据集和模型的基础上,建立的模型才是有效客观的。
4.1:建模前提
我们主要是利用逻辑回归做预测,因为这种模型在处理二分类上有很好的效果,泛化能力强,过拟合概率低。我们开始先对数据集进行训练集:测试集=7:3的比例的随机选取,然后确定好模型的随机种子、其它相关参数等,多次调整取最优,最终给出评价指标来综合评价预测模型的效果。
评价指标我们主要给出六种,一是模型的准确率指标,二是混淆矩阵可视化图,三是ROC修正后的评价指标,四是召回率,五是精准率,六是F1值。
但是为了最终客观评价模型的性能,一次随机实验是不够的,我们将多次实验,取各个指标的平均结果,最为最后的评价指标。
4.2:逻辑回归模型原理回顾
逻辑回归模型中的因变量为0或者取值1的概率,取0的概率是,我们建立逻辑回归变换:
对(1)式在独立个独立自变量下建立回归:
(2)式中的为干扰项,因为取值范围为,所以取值为任意。我们把实际中的数值和计算的值待入(2)中,通过建立方程组结合最小二乘法或者梯度下降算法等,就可以估算出和值来。
4.3:一次随机建模结果
*************一次实验随机种子为211的准确率汇总**************
随机种子是211时,<=50K (6375/6838)准确率:93.229%
随机种子是211时,>50K (992/2211)准确率:44.867%
随机种子是211时,总预测(7367/9049)准确率:81.412%
由于数据存在明显的倾斜现象,所以只看准确率会有逻辑上的不妥,所以我们给出修正指标ROC的可视化图:
由ROC图我们发现,模型的敏感性和特异性还是蛮均衡的,整体来看,我们的模型性能总体还是良好的。
4.4:多次平均建模结果
指标 | 平均准确率 | 平均f1值 | 平均召回率值 | 平均精准率值 | 平均ROC值 |
值 | 81.533% | 0.719 | 0.765 | 0.697 | 0.847 |
以上就是我们模型的综合性能,从平均f1值和ROC值发现,我们的模型鲁棒性和准确性还是蛮优良的,有一定的泛化能力,这得力于开始的数据清洗阶段处理的科学有效。
5:总结与展望
本文主要先对数据预处理清洗,然后进行一些可视化分析,再然后我们对逻辑回归模型底层逻辑进行了一些回顾,并选择此机器学习模型,实际建模时,我们设置好模型参数,对数据进行建模和分析,最终我们给出模型的综合评价指标,做到客观科学的评价模型。
通过一系列方法运用,我们客观且科学地建立了基于人群特征数据的人群收入分类器,而且准确率还不错,这很有效地帮助我们解决在实际人群不知道是高收入还是低收入的情况下,通过模型来给出判别结果,在可视化分析阶段,我们也总结了很多人群内在信息的相关特点。
但是方法是多样的,我们可以建立深度学习模型如LSTM、CNN或者其他机器学习如支持向量机模型SVM、随机森林RF模型等等,我们同时可以对特征进行相关建模,比如更高级的特征筛选或者特征降维,这都是我们需要努力的方向!
6:参考文献
[1]刘莹.基于数据挖掘的商品销售预测分析[J].科技通报.2014(07)
[2]李欣海.随机森林模型在分类与回归分析中的应用[J].应用昆虫学报.2013(04)
[3]涂继亮.基于数据挖掘的智能客户关系管理系统研究[D].哈尔滨理工大学2005
[4]岳雪.基于海量数据挖掘关联测度工具的设计[D].西安财经学院2014
[5]冯军.数据挖掘在自动外呼系统中的应用[D].北京邮电大学2009
附录1
数据清洗代码程序
- # -*- coding: utf-8 -*-
- ##一定要注意自身电脑的环境和文件路径,再次提醒一定要注意!!!!
- import matplotlib.pyplot as plt
- import pandas as pd
- import numpy as np
- import warnings
- import time
- warnings.filterwarnings('ignore')
- start_time = time.time()
- plt.rcParams['font.sans-serif']=['SimHei']##中文乱码问题!
- plt.rcParams['axes.unicode_minus']=False#横坐标负号显示问题!
- path = ''###请正确填写自己的文件路径!!!
- data = pd.read_excel(path + 'income.xlsx',index_col=0)
- # print(data)
- colstr = ['workclass','education','marital-status','occupation','relationship','race','sex',
- 'native-country','income']
- def transform_type(data,col):##转换数据类型
- print('original:',data.shape)
- data = data.dropna()
- print('now:',data.shape)
- for i in col:
- datatemp = data[i]
- msg = set(datatemp)
- for j,k in zip(msg,[l for l in range(1,len(msg) + 1)]):
- data[i][data[i]==j] = k
- return data
- res = transform_type(data,colstr)
- res.index = [i for i in range(res.shape[0])]
- index_ls = res.index
- print(res)
- def substitute_outliner(data,original_ls,yl,tit,mul1,mul2,num_ls):
- print('\033[1;34m{0:*^80}\033[1;0m'.format('特征数据“%s”异常值处理'%yl))
- copydata = original_ls.copy()
- for i in data[5]:##获取异常值位置
- del original_ls[i]##按照位置删除最最保险
- upvalue = data[2][i]
- downvalue = data[3][i]
- originalvalue = copydata[i]
- if originalvalue <= downvalue:
- changevaluetemp = downvalue * 0.5 + upvalue * 0.25
- if changevaluetemp >= upvalue:
- changevalue = upvalue
- else:
- changevalue = max(changevaluetemp,downvalue)##最小不低于downvalue,防止upvalue过小
- original_ls.insert(i,round(changevalue,1))
- print('\033[1;31m异常数据编号为(原始值%s):%s,替换的修正值为:%s,downvalue:%s\033[0m' % (originalvalue, num_ls[i], round(changevalue,2),round(downvalue,2)))
- if originalvalue >= upvalue:
- changevaluetemp = upvalue * 0.5 + downvalue * 0.25
- if changevaluetemp <= downvalue:
- changevalue = downvalue
- else:
- changevalue = min(changevaluetemp,upvalue)##最大不超过upvalue,防止downvalue过大
- original_ls.insert(i,round(changevalue,1))
- print('\033[1;31m异常数据编号为(原始值%s):%s,替换的修正值为:%s,upvalue:%s\033[0m'%(originalvalue,num_ls[i],round(changevalue,2),round(upvalue,2)))
- plt.figure(figsize=(15, 8))
- plt.plot(list(copydata), 'y', label='原始数值')
- plt.plot(data[1], 'r', label='拟合曲线')
- plt.plot(data[2], 'purple', label='拟合上限(%ssigm)曲线'%mul1)
- plt.plot(data[3], 'b', label='拟合下限(%ssigm)曲线'%mul2)
- plt.plot(original_ls, 'g', label='处理完后的数据')
- plt.legend(fontsize=15)
- plt.tick_params(labelsize=15)
- plt.xlabel('编号',fontsize=18)
- plt.ylabel(yl,fontsize=18)
- plt.title(tit,fontsize=20)
- plt.show()
- return original_ls
- def check_outlier(value,mul1,mul2,yl):
- print('\033[1;34m{0:*^80}\033[1;0m'.format('特征数据“%s”预处理'%yl))
- x = [j for j in range(len(value))]
- coeffs = np.polyfit(x, value, 10) ##专门求多项式估计参数的函数,根据实际数据波动取相应的阶数
- p = np.poly1d(coeffs) # 一元估计参数
- sigm = p(x).std()
- sigm_up = p(x) + mul1 * sigm
- sigm_down = p(x) - mul2 * sigm
- outliner = value[(value < sigm_down) | (value > sigm_up)]#条件筛选
- print('\033[1;31m原数据长度:%s,异常数据:%s\033[0m'%(len(value),len(outliner)))
- print(outliner)
- return list(outliner),p(x),sigm_up,sigm_down,x,list(outliner.index)
- col = list(res)
- remove_ls = colstr + ['age','education-num']
- for i in remove_ls:
- col.remove(i)##类别数据不作处理
- for i in col:##性别和编号不做计算
- mul1 = 500
- mul2 = 500##由于数据很大是人为的,这里mul1和mul2参数慎改
- res1 = check_outlier(res[i],mul1,mul2,i)
- res2 = substitute_outliner(res1,list(res[i]),i,'“%s”数据预处理图'%i,mul1,mul2,index_ls)
- res[i] = res2##数据替换
- del res['capital-gain']
- del res['capital-loss']
- del res['education']
- # res.to_excel(path + '处理好的数据.xlsx')
数据可视化代码程序
- # -*- coding: utf-8 -*-
- ##一定要注意自身电脑的环境和文件路径,再次提醒一定要注意!!!!
- import matplotlib.pyplot as plt
- import seaborn as sns
- import pandas as pd
- import time
- import warnings
- warnings.filterwarnings('ignore')
- start_time = time.time()
- plt.rcParams['font.sans-serif']=['SimHei']##中文乱码问题!
- plt.rcParams['axes.unicode_minus']=False#横坐标负号显示问题!
- path = ''###请正确填写自己的文件路径!!!
- data = pd.read_excel(path + '处理好的数据.xlsx',index_col=0)
- newdf1 = data[['fnlwgt','education-num','hours-per-week']].dropna()
- print(newdf1.describe())
- print(newdf1.corr())
- sns.heatmap(newdf1.corr(),square = True, vmax=0.8)
- plt.show()
- ##循环绘制概率密度图
- for i in ['fnlwgt','education-num','hours-per-week']:
- plt.figure(figsize=(15, 8))
- lstemp = data[i]
- sns.distplot(lstemp, rug=False, hist=True, bins=15)
- plt.tick_params(labelsize=18)
- plt.ylabel('概率密度', fontsize=18)
- plt.xlabel(i, fontsize=18)
- plt.title('%s的概率密度分布图'%i,fontsize=20)
- plt.show()
- plt.show()
- # 生成数据
- datat = pd.read_excel(path + 'income.xlsx',index_col=0)
- datat = list(datat['race'])
- set_ls = set(datat)
- count_ls = []
- for i in set_ls:
- count_ls.append(round(datat.count(i) / len(datat),2))
- labels = list(set_ls)
- share = count_ls
- # 设置分裂属性
- explode = [0 for i in range(len(set_ls))]
- # 分裂饼图
- plt.figure(figsize=(15, 8))
- plt.pie(share, explode = explode,
- labels = labels, autopct = '%3.1f%%',
- startangle = 180, shadow = True,)
- plt.tick_params(labelsize=20)
- # 标题
- plt.title('人种分布扇形图',fontsize=20)
- plt.show()
- def makefigure(xname,yname):
- plt.figure(figsize=(15, 8))
- sns.countplot(x=xname,hue=yname, data=data)
- plt.legend(fontsize=18)
- plt.ylabel(yname,fontsize=18)
- plt.xlabel(xname,fontsize=18)
- plt.title('%s与%s关联的柱状图'%(xname,yname),fontsize=20)
- plt.xticks((0,1),('male','female'))
- plt.tick_params(labelsize=15)
- plt.show()
- makefigure('sex','education-num')
- makefigure('sex','income')
数据建模代码程序
- # -*- coding: utf-8 -*-
- ##一定要注意自身电脑的环境和文件路径,再次提醒一定要注意!!!!
- from sklearn.metrics import roc_curve, auc,confusion_matrix,f1_score, precision_score, recall_score
- from sklearn.linear_model import LogisticRegression as LR
- from sklearn.model_selection import train_test_split
- import matplotlib.pyplot as plt
- import pandas as pd
- import numpy as np
- import warnings
- warnings.filterwarnings('ignore')
- plt.rcParams['font.sans-serif']=['SimHei']##中文乱码问题!
- plt.rcParams['axes.unicode_minus']=False#横坐标负号显示问题!
- path = ''###请正确填写自己的文件路径!!!
- data = pd.read_excel(path + '处理好的数据.xlsx',index_col=0)
- print(data)
- # del data['fnlwgt']##去除“体重”变量
- data.iloc[:,1:data.shape[1]-1] = (data.iloc[:,1:data.shape[1]-1] - data.iloc[:,1:data.shape[1]-1].min()) \
- / (data.iloc[:,1:data.shape[1]-1].max() - data.iloc[:,1:data.shape[1]-1].min())
- X = np.array(data.iloc[:,1:data.shape[1]-1])##自变量的读取
- Y = np.array(data.iloc[:,data.shape[1]-1])##因变量的读取
- dis_name = [1,2]
- rd = 211
- ##绘制roc图
- def make_figure_auc_roc(true_label,score,class_):
- plt.figure(figsize=(15, 8))
- fpr, tpr, thresholds = roc_curve(true_label,score,pos_label=class_,drop_intermediate=False)
- ###返回的是一系列thresholds阈值
- roc_auc = auc(fpr, tpr)
- roc_result = pd.DataFrame({'fpr' : fpr,'tpr' : tpr, 'tf' : tpr - (1-fpr),'thresholds' : thresholds})
- # roc_result.iloc[(roc_result.tf-0).abs().argsort()[:1]]
- optimal_idx = np.argmax(tpr - fpr)
- optimal_threshold = thresholds[optimal_idx]
- y = tpr[optimal_idx]
- x = fpr[optimal_idx]
- plt.figure(figsize=(8,5))
- plt.plot(fpr, tpr, color='navy',label='AUC=%.3f' % roc_auc)
- plt.plot([-0.005, 1.005], [-0.005, 1.005], color='orange',linestyle='--')
- plt.xlabel('1-特异度',fontsize=10)
- plt.ylabel('敏感度',fontsize=10)
- plt.scatter(x, y, c='red',s=15)
- plt.tick_params(labelsize=12,rotation=10)
- plt.title('ROC曲线',fontsize=12)
- plt.legend(loc='best',fontsize=18)
- plt.text(x+0.05,y-0.05,s='('+str(round(1-x, 3))+', '+str(round(y, 3))+')',fontsize=15)
- plt.show()
- return roc_auc
- def cm_plot(yp, y):##混淆矩阵
- plt.figure(figsize=(15, 8))
- cm = confusion_matrix(yp, y) # 混淆矩阵
- plt.matshow(cm, cmap=plt.cm.Greens) # 画混淆矩阵图,配色风格使用cm.Greens,更多风格请参考官网。
- plt.colorbar() # 颜色标签
- for x in range(len(cm)): # 数据标签
- for y in range(len(cm)):
- plt.annotate(cm[x, y], xy=(x, y), horizontalalignment='center', verticalalignment='center')
- plt.ylabel('真实标签',fontsize=10) # 坐标轴标签
- plt.xlabel('预测标签',fontsize=10) # 坐标轴标签
- plt.title('预测混淆矩阵图', fontsize=12)
- plt.show()
- ##自定义准确率计算
- def show_result(dis_name, pre_ls, real_ls,rd):##准确率
- ls_r = []
- ls_c = []
- for d in dis_name:
- res_ls = []
- for i, j in zip(pre_ls, list(real_ls)):
- if i == j == d:
- res_ls.append('正确')
- ls_r.append(len(res_ls) / list(real_ls).count(d))
- ls_c.append((len(res_ls),list(real_ls).count(d)))
- print('\033[1;32m随机种子是%s时,%s(%s/%s)准确率:%.3f%%\033[0m' % (rd,d, len(res_ls), list(real_ls).count(d), len(res_ls) / list(real_ls).count(d) * 100))
- res_ls = []
- for i, j in zip(pre_ls, list(real_ls)):
- if i == j:
- res_ls.append('正确')
- else:
- res_ls.append('错误')
- print('\033[1;31m随机种子是%s时,总预测(%s/%s)准确率:%.3f%%\033[0m' % (rd,res_ls.count('正确'), len(res_ls), res_ls.count('正确') / len(res_ls) * 100))
- df = pd.DataFrame([list(real_ls), pre_ls, res_ls], index=['真实', '预测', '预测结果']).T
- allcorretrate = res_ls.count('正确') / len(res_ls) * 100
- return df,allcorretrate
- ##建立LR模型
- def model(x,y,rd=rd):
- xtrain, xtest, ytrain, ytest = train_test_split(x, y, test_size=0.3, random_state=rd)
- lr = LR(solver='liblinear') # 建立逻辑回归模型
- lr.fit(xtrain, ytrain) # 用特征数据来训练模型
- pre_lr = lr.predict(xtest)
- pro_lr = lr.predict_proba(xtest)
- return pre_lr,ytest,pro_lr,lr.classes_[0]
- print('\033[1;38m{0:*^80}\033[0m'.format('一次实验随机种子为%s的准确率汇总'%rd))
- res = model(X,Y)
- make_figure_auc_roc(res[1], res[2][:, 0], res[3])
- cm_plot(res[0],res[1])
- show_result(dis_name,res[0],res[1],rd)
- f1 = round(f1_score(res[1], res[0], average='macro'),3)##F计算
- p = round(precision_score(res[1], res[0], average='macro'),3)##精准率计算
- r = round(recall_score(res[1], res[0], average='macro'),3)##召回率计算
- print(f1,p,r)
- ##循环调用LR模型并可视化结果
- def makefigure(rdls,x,y,func,dn):
- plt.figure(figsize=(15, 8))
- print('\033[1;38m{0:*^80}\033[0m'.format('多次实验的准确率汇总'))
- lsr = []
- f1_ls = []
- p_ls = []
- r_ls = []
- rou_ls = []
- for k in rdls:
- R = func(x,y,k)##循环调用模型
- rr = show_result(dn, R[0], R[1],k)
- f1 = f1_score(R[1], R[0], average='macro')
- p = precision_score(R[1], R[0], average='macro')
- r = recall_score(R[1], R[0], average='macro')
- roc = make_figure_auc_roc(R[1], R[2][:, 0], R[3])
- f1_ls.append(f1)
- p_ls.append(p)
- r_ls.append(r)
- lsr.append(rr[1])
- rou_ls.append(roc)
- plt.figure(figsize=(15, 8))
- print('\033[1;38m平均准确率:%.3f%%\033[0m'%(pd.Series(lsr).mean()))
- print('\033[1;38m平均f1值:%.3f\033[0m' % (pd.Series(f1_ls).mean()))
- print('\033[1;38m平均召回率值:%.3f\033[0m' % (pd.Series(p_ls).mean()))
- print('\033[1;38m平均精准率值:%.3f\033[0m' % (pd.Series(r_ls).mean()))
- print('\033[1;38m平均ROC值:%.3f\033[0m' % (pd.Series(rou_ls).mean()))
- plt.plot(lsr,label='决策树多次计算结果',marker='*')
- plt.legend(loc='best',fontsize=15)
- plt.tick_params(labelsize=15)
- plt.xticks([j for j in range(len(rdls))],[str(j) for j in rdls])
- plt.xlabel('随机种子数(%s次计算)'%len(rdls),fontsize=18)
- plt.ylabel('准确率(%)',fontsize=18)
- plt.show()
- rand_ls = np.random.randint(0,1000,20)
- makefigure(rand_ls,X,Y,model,dis_name)###调用函数