背景

 

自杀是一项公认的全球性的重大社会问题和公共卫生问题,严重影响社会和经济的发展。据世界卫生组织估计,每年全世界有大约78.6万人自杀,其比例约为每年每10万人中有10.7人,也就是说每隔40秒就有人自杀。据联合国新闻,世卫组织发布的“2019年全球自杀状况”报告中的最新估计显示,自杀仍是全球主要死因之一。高收入国家的自杀率最高,美洲是唯一一个自杀率上升的地区。根据近年来世界各国的自杀率,可以发现:自杀率在性别上的差异在各国之间非常明显,一般的自杀率会男性高于女性,目前男性自杀率最高的国家为前苏联解体后的立陶宛、俄罗斯联邦、拉托维亚和爱沙尼亚等国家(年自杀率>60/10万),而女性自杀率最高的国家依次为斯里兰卡、中国、匈牙利和爱沙尼亚等(年自杀率>14/10万)。而在部分非洲和拉丁美洲国家自杀率却非常低,如埃及、秘鲁等(年自杀率<1/10万)。国际上习惯上将年自杀率>20/10万的国家称为高自杀率国家,年自杀率<10/10万的国家称为低自杀率国家,李振涛说,在1993年以前的统计中,中国属于低自杀率国家。 根据世界卫生组织在2019年发布的报告,全球每40秒钟就有一个人自杀身亡,自杀已经成为导致人类死亡的主要原因之一。一些国家的自杀人数增长迅速,甚至达60%。中国93%有自杀行为的人没有看过心理医生,在每年8万自杀未遂者中,被进行心理评估的还不到1%。中国的自杀防御工作缺乏一个全国性的计划来协调,政府机构对这一问题的重视不够,缺乏财力支持,也缺乏有效的评估心理因素的工具,更缺少高素质的研究人。

 

数据集来源

 

分析思路

 

 

 

本次分析基于Kaggle数据集对自杀行文进行分析,探索自杀行为影响因素,并对自杀因素进行可视化,直观的表现影响自杀率的行为,并使用logistic回归、决策树、随机森林三种机器学习算法建立自杀行为分类模型,评估自杀结果,预测自杀率。

 

 1 import pandas as pd
 2 import numpy as np
 3 import matplotlib.pyplot as plt
 4 import seaborn as sns
 5 #import scikitplot as skplt
 6 import sklearn as sk
 7 from sklearn.model_selection import train_test_split
 8 from sklearn.preprocessing import StandardScaler
 9 plt.rcParams['font.sans-serif']='SimHei'
10 plt.rcParams['axes.unicode_minus']=False
11 
12 import warnings
13 warnings.filterwarnings("ignore")

数据读取

 1 # 导入原始自杀数据集并重新命名列:
 2 originaldata = pd.read_csv('./master.csv')
 3 # 国家,  年份,  性别,  年龄,  自杀人数,  人口数量,  自杀人数/总人口*100000(自杀率),
 4 # 国家-年份,     人类发展指数(用以衡量联合国各成员国经济社会发展水平的指标,是对传统的GNP指标挑战的结果。)
 5 # 年度国内生产总值(衡量经济发展的指标),      年人均国内生产总值:国内生产总值/人口 ,         世代
 6 originaldata.columns = ['country', 'year', 'sex', 'age', 'suicides_no', 'population','suicidesper100k',
 7                       'country-year', 'yearlyHDI', 
 8                         'GDPpyear', 'GDPpcapita', 'generation']
 9 
10 originaldata.head()

 

1 originaldata.shape

 

1 originaldata.info()

 

1 (originaldata=="male").sum()

 

1 a = 13910/27820
2 a

 

1 df3 = originaldata.groupby("country").agg({"country":"count"})
2 df3.columns = ["count"]
3 df3

 

1 # 修复和清理原始数据
2 # 将 年度国内生产总值 数据中 ','分割去除掉(比如2,156,624,900),并且转换成float的数字类型
3 originaldata['GDPpyear'] = originaldata.apply(lambda x: float(x['GDPpyear'].replace(',', '')), axis=1)
4 originaldata['GDPpyear'].head(10)
5 
6 # sex 转换为category类型
7 # Categoricals 是 pandas 的一种数据类型,对应着被统计的变量。Categoricals 是由固定的且有限数量的变量组成的。
8 originaldata.sex.astype('category')

 

1 df = originaldata.copy()#复制一份数据
2 df

 

1 df.suicidesper100k.mean()
2 df.suicidesper100k.std()
3 min(df.suicidesper100k)
4 max(df.suicidesper100k)

 

1 import seaborn as sns
2 sns.distplot(df.suicidesper100k)
3 plt.xticks(fontsize=10)
4 plt.yticks(fontsize=20)
5 plt.show()

 

探索性分析

 1 col = plt.cm.Spectral(np.linspace(0, 1, 20))
 2 
 3 plt.figure(figsize=(8, 6))
 4 agedistf = pd.DataFrame(df.groupby('sex').get_group('female').groupby('age').suicides_no.sum())
 5 agedistm = pd.DataFrame(df.groupby('sex').get_group('male').groupby('age').suicides_no.sum())
 6 plt.bar(agedistm.index, agedistm.suicides_no, color=col[18])
 7 plt.bar(agedistf.index, agedistf.suicides_no, color=col[8])
 8 plt.legend(['male', 'female'], fontsize=16)
 9 plt.ylabel('Count', fontsize=14)
10 plt.xlabel('Suicides per 100K', fontsize=14)
11 plt.xticks(fontsize=10)
12 plt.yticks(fontsize=20)
13 plt.show()

 

 1 col = plt.cm.Spectral(np.linspace(0, 1, 22))
 2 plt.figure(figsize=(12, 15))
 3 
 4 plt.subplot(211)
 5 #自杀率(放大1000倍)的平均值最高的前10个国家
 6 df.groupby(['country']).suicidesper100k.mean().nlargest(10).plot(kind='bar', color=col, fontsize=20)
 7 plt.xlabel('Average Suicides/100k', size=20)
 8 plt.ylabel('Country', fontsize=20)
 9 plt.title('Top 10 countries', fontsize=30)
10 
11 plt.figure(figsize=(12, 15))
12 plt.subplot(212)
13 #自杀人数的平均值最高的前10个国家
14 df.groupby(['country']).suicides_no.mean().nlargest(10).plot(kind='bar', color=col, fontsize=20)
15 plt.xlabel('Average Suicides_no', size=20)
16 plt.ylabel('Country', fontsize=20);
17 plt.title('Top 10 countries', fontsize=30)
18 plt.show()

 

 

 1 plt.figure(figsize=(10, 16))
 2 
 3 #总人口的各个年龄段的性别分布
 4 plt.subplot(311)
 5 sns.barplot(x='sex', y='population', hue='age', data=df, palette="Greens")  #hue按年龄分组
 6 plt.xticks(ha='right', fontsize=20)
 7 plt.ylabel('Population', fontsize=20)
 8 plt.xlabel('Sex', fontsize=20)
 9 plt.title("不同年龄段的男、女总人口数")
10 plt.legend(fontsize=14, loc='best')
11 
12 #自杀人数的各个年龄段的性别分布
13 plt.subplot(312)
14 sns.barplot(x='sex', y='suicides_no', hue='age', data=df, palette="Greens")
15 plt.xticks(ha='right', fontsize=20)
16 plt.ylabel('suicides incidences', fontsize=20)
17 plt.xlabel('Sex', fontsize=20)
18 plt.title("不同年龄段的男、女自杀人口数")
19 plt.legend(fontsize=14)
20 
21 #自杀率(放大1000倍)的各个年龄段的性别分布
22 plt.subplot(313)
23 sns.barplot(x='sex', y='suicidesper100k', hue='age', data=df,palette="Greens")
24 plt.xticks(ha='right', fontsize=20);
25 plt.ylabel('suicidesper100k',fontsize=20);
26 plt.xlabel('Sex',fontsize=20);
27 plt.title("不同年龄段的男、女自杀率")
28 plt.legend(fontsize=14);
29 
30 plt.subplots_adjust(top=1.2)
31 plt.show()

 

 1 plt.figure(figsize=(12, 16))
 2 
 3 # 具体按性别和年份 来看 男女的自杀率
 4 plt.subplot(311)
 5 sns.lineplot(x='year', y='suicidesper100k', hue='sex', data=df, palette="hot")  #hue按年龄分组
 6 plt.xticks(ha='right', fontsize=20)
 7 plt.ylabel('suicidesper100k', fontsize=20)
 8 plt.xlabel('year', fontsize=20)
 9 plt.legend(fontsize=14, loc='best')  
10 plt.title("性别年份与自杀率关系图")
11 plt.show()

 

 1 plt.figure(figsize=(8, 6))
 2 
 3 #选出year列并且去除重复的年份
 4 year = originaldata.groupby('year').year.unique()
 5 
 6 #各个年份的自杀人数汇总
 7 #使用seaborn进行可视化,输入的数据必须为dataframe
 8 totalpyear = pd.DataFrame(originaldata.groupby('year').suicides_no.sum())   
 9 
10 plt.plot(year.index[0:31], totalpyear[0:31], color=col[18])  #选取范围为[0:31]  1985年到2015年
11 plt.xlabel('year', fontsize=15)
12 plt.ylabel('Total number of suicides in the world', fontsize=15)
13 plt.show()

 

 1 plt.figure(figsize=(20, 8))
 2 
 3 # 自杀率(放大1000倍)的分布情况,y轴为个数
 4 plt.subplot(121)
 5 plt.hist(df.suicidesper100k, bins=30, color=col[18])   #bins:条形数
 6 plt.xlabel('Suicides per 100K of population', fontsize=25)
 7 plt.xticks(rotation = 0,                 fontsize = 20)  
 8 plt.ylabel('count', fontsize=25)
 9 plt.yticks(                              fontsize = 20)   
10 
11 # 年人均国内生产总值的分布情况,y轴为个数
12 plt.subplot(122)
13 plt.hist(df.GDPpcapita, bins=30, color=col[7])
14 plt.xlabel('GDP', fontsize=25)
15 plt.xticks(rotation = 0,fontsize = 20)  
16 plt.ylabel('count', fontsize=25)
17 plt.yticks(fontsize = 20)   
18 plt.show()

 

 1 corr = df.corr() #相关系数矩阵,即给出了任意两个变量之间的相关系数
 2 
 3 # 相关矩阵的上三角部分与下三角对称。因此,热图不需要显示整个矩阵。在下一步隐藏上三角形。
 4 # 设置mask隐藏上三角
 5 # np.zeros_like() 返回一个零数组,其形状和类型与给定的数组相同。
 6 # 该 dtype=np.bool 参数会覆盖数据类型,因此我们的数组是一个布尔数组。
 7 # np.triu_indices_from(mask) 返回数组上三角形的索引。
 8 # 现在,我们将上三角形设置为True。 mask[np.triu_indices_from(mask)]= True
 9 mask = np.zeros_like(corr, dtype=np.bool)
10 mask[np.triu_indices_from(mask)] = True
11 
12 # 在Seaborn中创建热图
13 f, ax = plt.subplots(figsize=(10, 8))
14 # 生成自定义发散颜色图
15 cmap = sns.diverging_palette(220, 10, as_cmap=True)
16 
17 # 绘制热图
18 # 数据为 corr
19 # vmax,vmin:分别是热力图的颜色取值最大和最小范围
20 # center:数据表取值有差异时,设置热力图的色彩中心对齐值;通过设置center值,可以调整生成的图像颜色的整体深浅
21 # square:设置热力图矩阵小块形状,默认值是False
22 # linewidths(矩阵小块的间隔),
23 # cbar_kws:热力图侧边绘制颜色刻度条时,相关字体设置,默认值是None
24 sns.heatmap(corr, mask=mask, cmap=cmap, vmax=1, vmin=-1, center=0,  
25             square=True, linewidths=0.2, cbar_kws={"shrink": 0.8},annot=True)
26 plt.xticks(fontsize=20)
27 plt.yticks(fontsize=20)
28 plt.show()

 

数据预处理

 1 #复制数据
 2 total = df.copy()
 3 # 对总人口用均值填充
 4 total.population.fillna(total.population.mean(), inplace=True)
 5 # 小于平均值的为低风险,大于平均值的为高风险
 6 total['risk'] = np.where(total.suicidesper100k < total.suicidesper100k.mean(), 0, 1)
 7 
 8 plt.figure(figsize=(16, 5))
 9 plt.subplot(121)
10 plt.hist(total.risk, color=col[8])
11 plt.ylabel('counts', fontsize=20)
12 plt.xlabel('Suicide risk', fontsize=20)
13 plt.title("自杀高低风险数量")
14 
15 plt.subplot(122)
16 sns.distplot(total.suicidesper100k[total.risk == 0], bins=10)
17 sns.distplot(total.suicidesper100k[total.risk == 1], bins=20)  
18 plt.xlabel('Suicides', fontsize=20)
19 plt.title("自杀高低风险分布情况")
20 plt.show()

 

1 (total['risk']==1).sum()
2 (total['risk']==0).sum()
3 total.head(5)
4 total['yearlyHDI'].isnull().sum()
5 a = 19456/27820
6 a

 

1 total['yearlyHDI'].describe()
2 total['yearlyHDI'].isnull().sum()
3 total

 

1 fill_1 = total['yearlyHDI']
2 fill_1 = pd.DataFrame(fill_1)
3 fill_1

 

 1 from scipy.interpolate import lagrange #导入拉格朗日函数
 2 def ployinterp_column(s,n,k=2,result_type='broadcast'): # k=2表示用空值的前后两个数值来拟合曲线,从而预测空值
 3     y = s[list(range(n+2-k,n+2)) + list(range(n+3,n+3-k))] # 取值,range函数返回一个左闭右开([left,right))的序列数
 4     y = y[y.notnull()] # 取上一行中取出数值列表中的非空值,保证y的每行都有数值,便于拟合函数
 5     return lagrange(y.index,list(y))(n) # 调用拉格朗日函数,并添加索引
 6 for i in fill_1.columns: # 如果i在data的列名中,data.columns生成的是data的全部列名
 7     for j in range(len(fill_1)): # len(data)返回了data的长度,若此长度为5,则range(5)会产生从0开始计数的整数列表
 8         if (fill_1[i].isnull())[j]: # 如果data[i][j]为空,则调用函数ployinterp_column为其插值
 9             fill_1[i][j] = ployinterp_column(fill_1[i],j,result_type='broadcast')  
10 fill_1

 

 1 # 对国家进行 标准化标签,将标签值统一转换成range(标签值个数-1)范围内
 2 # 相当于fit(X).transform(X),意思就是先进行fit(),进行数据拟合,然后在进行transform() 进行标准化处理
 3 
 4 from sklearn.preprocessing import LabelEncoder
 5 le = LabelEncoder()
 6 total.country = le.fit_transform(total.country)
 7 total.country.unique()
 8 
 9 # 为建立模型准备数据
10 X = total.drop(['suicidesper100k','risk','country-year'],axis = 1)
11 #用0进行填补
12 X['yearlyHDI'] = fill_1['yearlyHDI']
13 y = total['risk']
14 #对X进行独热编码处理
15 XS = pd.get_dummies(X)

 

1 #GDP和人口的分布
2 ax1 = total[total['risk'] == 1][0:200].plot(kind='scatter', x='GDPpcapita', y='population', color='DarkRed',
3                                             label='high risk', figsize=(6, 5), fontsize=12)
4 total[total['risk'] == 0][0:200].plot(kind='scatter', x='GDPpcapita', y='population', color='DarkBlue',
5                                             label='low risk', ax=ax1)
6 
7 plt.ylabel('population', fontsize=16)
8 plt.xlabel('GDP per capita', fontsize=16)
9 plt.legend(fontsize=14)

 

1 #GDP和人类发展指数的分布
2 ax1 = total[total['risk'] == 1][0:200].plot(kind='scatter', x='GDPpcapita', y='yearlyHDI', color='DarkRed',
3                                             label='high risk', figsize=(6, 5), fontsize=12)
4 total[total['risk'] == 0][0:200].plot(kind='scatter', x='GDPpcapita', y='yearlyHDI', color='DarkBlue',
5                                             label='low risk', ax=ax1)
6 
7 plt.ylabel('yearlyHDI', fontsize=16)
8 plt.xlabel('GDP per capita', fontsize=16)
9 plt.legend(fontsize=14)

 

1 # 关于年份的高低自杀风险
2 fig = plt.figure(figsize=(30, 30))
3 
4 plt.subplot(4, 3, 1)
5 sns.distplot(total[total.columns[0]][total.risk == 0], label='low risk')
6 sns.distplot(total[total.columns[0]][total.risk == 1], label='high risk')       
7 plt.legend(loc='best', fontsize=18)  
8 plt.xlabel(total.columns[0], fontsize=18)
9 plt.show()

 

建模

1 from sklearn.model_selection import train_test_split
2 # 将数据集拆分为训练集和测试集
3 # 首先将该数据3/4作为训练集,1/4作为测试集;再由训练集划分1/5作为验证集
4 X_train, X_test, y_train, y_test = train_test_split(XS, y, test_size=0.25, random_state=4)
5 X_train,X_valid,y_train,y_valid=train_test_split(X_train,y_train,test_size=0.2,random_state=4)
6 print('Train set:', X_train.shape, y_train.shape)
7 print('Test set:', X_test.shape, y_test.shape)
8 print('Test set:', X_valid.shape, y_valid.shape)

 

 1 from sklearn.linear_model import LogisticRegression
 2 from sklearn.metrics import recall_score,accuracy_score
 3 from sklearn.metrics import precision_recall_fscore_support
 4 from sklearn.metrics import confusion_matrix, classification_report
 5 
 6 LR = LogisticRegression(C=0.001, solver='liblinear')
 7 LR.fit(X_train, y_train)
 8 
 9 # 预测类别:0还是1
10 yLRhat = LR.predict(X_valid)
11  
12 # 预测 0或1的概率(例如 [0.54689436, 0.45310564] 预测出来为0)
13 yLRhat_prob = LR.predict_proba(X_valid)
14 
15 cm = confusion_matrix(y_valid, yLRhat)
16 print('\n confusion matrix:混淆矩阵 \n', cm)
17 print('此时模型准确率为:',accuracy_score(y_valid, yLRhat))
18 print('********************************************************')
19 print('\n')
20 print('逻辑回归模型的分类报告\n', classification_report(y_valid, yLRhat))
21 #skplt.metrics.plot_confusion_matrix(y_valid,yLRhat,normalize=True)

 

1 X_train.head()

 

 1 from sklearn.model_selection import GridSearchCV
 2 
 3 param={"tol":[1e-4, 1e-3,1e-2], "C":[0.4, 0.6, 0.8]}
 4 grid = GridSearchCV(LogisticRegression(),param_grid=param, cv=5)#这里是5折交叉验证
 5 grid.fit(X_train,y_train)
 6 print(grid.best_params_)
 7 print(grid.best_score_)
 8 
 9 #得到最好的逻辑回归分类器
10 best_LR=grid.best_estimator_ 
11 
12 #进行训练、预测
13 best_LR.fit(X_train,y_train)
14 pred=best_LR.predict(X_valid)
15 
16 cm = confusion_matrix(y_valid, pred)
17 print('\n confusion matrix:混淆矩阵 \n', cm)
18 print('最好的逻辑回归模型准确率为:',accuracy_score(y_valid, pred))
19 print('********************************************************')
20 print('\n')
21 print('最好的逻辑回归模型的分类报告\n', classification_report(y_valid, pred))

 

 1 from sklearn.tree import DecisionTreeClassifier
 2 from sklearn.metrics import accuracy_score
 3 from sklearn.metrics import confusion_matrix, classification_report
 4 
 5 # 决策树学习
 6 # 函数为创建一个决策树模型
 7 # criterion:gini或者entropy,前者是基尼系数,后者是信息熵。
 8 # max_depth:  int or None, optional (default=None) 设置决策随机森林中的决策树的最大深度,深度越大,越容易过拟合,推荐树的深度为:5-20之间。
 9 # max_leaf_nodes: 通过限制最大叶子节点数,可以防止过拟合,默认是"None”,即不限制最大的叶子节点数。
10 DT = DecisionTreeClassifier(criterion="entropy", max_depth=7, max_leaf_nodes=30)
11 DT.fit(X_train, y_train)
12 ydthat = DT.predict(X_valid)
13 
14 print('***决策树模型***')
15 
16 #决策树模型性能评估
17 print('验证集上的准确率:', DT.score(X_valid, y_valid))
18 print('训练集上的准确率:', DT.score(X_train, y_train))
19 
20 # 混淆矩阵
21 print('CM\n', confusion_matrix(y_valid, ydthat))
22 print('********************************************************')
23 
24 print('决策树模型的分类报告\n', classification_report(y_valid, ydthat))
25 
26 DTfeat_importance = DT.feature_importances_
27 DTfeat_importance = pd.DataFrame([X_train.columns, DT.feature_importances_]).T
28 
29 # 特征重要性排序
30 print("特征重要性排名如下:")
31 print(DTfeat_importance.sort_values(by=1, ascending=False))

 

 1 # 通过cv_results观察过程并做图
 2 max_depth=np.arange(0,20,3)
 3 max_leaf_nodes=np.arange(0,30,3)
 4 min_samples_leaf =np.arange(0,20,2)
 5 param1= {'criterion':['entropy'],'max_depth':max_depth}
 6 param2= {'criterion':['entropy'],'min_samples_leaf':min_samples_leaf}
 7 param3= {'criterion':['entropy'],'max_leaf_nodes':max_leaf_nodes}
 8 
 9 
10 clf1 = GridSearchCV(DecisionTreeClassifier(),param_grid=param1,cv=6)
11 clf1.fit(X_train,y_train)
12 
13 clf2 = GridSearchCV(DecisionTreeClassifier(),param_grid=param2,cv=6)
14 clf2.fit(X_train,y_train)
15 
16 
17 clf3 = GridSearchCV(DecisionTreeClassifier(),param_grid=param3,cv=6)
18 clf3.fit(X_train,y_train)

 

 1 fig = plt.figure(figsize=(20,10), dpi=100)
 2 ax = fig.add_subplot(311)
 3 ax.plot(min_samples_leaf,clf2.cv_results_['mean_test_score'],'g*-',)
 4 plt.title('决策树模型网格搜索的训练过程',fontsize=20)
 5 plt.xticks(fontsize=20)
 6 plt.yticks(fontsize=20)
 7 
 8 ax = fig.add_subplot(312)
 9 ax.plot(max_depth,clf1.cv_results_['mean_test_score'],'g*-')
10 plt.xticks(fontsize=20)
11 plt.yticks(fontsize=20)
12 ax = fig.add_subplot(313)
13 ax.plot(max_leaf_nodes,clf3.cv_results_['mean_test_score'],'g*-')
14 plt.xticks(fontsize=20)
15 plt.yticks(fontsize=20)
16 plt.show()

 

 1 best_DT = DecisionTreeClassifier(criterion="entropy", max_depth=15, max_leaf_nodes=25,min_samples_leaf=2)
 2 best_DT.fit(X_train, y_train)
 3 ydthat =best_DT.predict(X_valid)
 4 
 5 print('***决策树模型***')
 6 
 7 #决策树模型性能评估
 8 print('验证集上的准确率:',best_DT.score(X_valid, y_valid))
 9 print('训练集上的准确率:',best_DT.score(X_train, y_train))
10 
11 # 混淆矩阵
12 print('CM\n', confusion_matrix(y_valid, ydthat))
13 print('********************************************************')
14 
15 print('决策树模型的分类报告\n', classification_report(y_valid, ydthat))
16 
17 DTfeat_importance = best_DT.feature_importances_
18 DTfeat_importance = pd.DataFrame([X_train.columns, DT.feature_importances_]).T
19 
20 # 特征重要性排序
21 print("特征重要性排名如下:")
22 print(DTfeat_importance.sort_values(by=1, ascending=False))

 

 1 # 随机森林可以视为多颗决策树的集成,鲁棒性更强,泛化能力更好,不易产生过拟合现象。但是噪声比较大的情况下会过拟合。
 2 
 3 from sklearn.ensemble import RandomForestClassifier
 4 
 5 random_forest = RandomForestClassifier(n_estimators=20, max_depth=10, min_samples_split=2, min_samples_leaf=5,
 6                                        max_leaf_nodes=20, max_features=len(X_train.columns)) 
 7 
 8 random_forest.fit(X_train, y_train)
 9 
10 yrfhat = random_forest.predict(X_valid)
11 feat_importance = random_forest.feature_importances_
12 rffeat_importance = pd.DataFrame([X_train.columns, random_forest.feature_importances_]).T
13 
14 print('******************Random forest classifier**************')
15 print('训练集上的准确率', random_forest.score(X_train, y_train))
16 print('验证集上的准确率', random_forest.score(X_valid,y_valid))
17 print('混淆矩阵\n', confusion_matrix(y_valid, yrfhat))
18 print('********************************************************')
19 print('随机森林的分类报告\n', classification_report(y_valid, yrfhat))
20 print(rffeat_importance.sort_values(by=1, ascending=False))

 

 1 #我们首先对n_estimators进行网格搜索:
 2 param_test1 = {'n_estimators':[50,120,160,200,250]}
 3 gsearch1 = GridSearchCV(estimator = RandomForestClassifier(), param_grid = param_test1,cv=5)
 4 gsearch1.fit(X_train,y_train)
 5 print( gsearch1.best_params_, gsearch1.best_score_)
 6 #接着我们对决策树最大深度max_depth和内部节点再划分所需最小样本数min_samples_split进行网格搜索。
 7 param_test2 = {'max_depth':[1,2,3,5,7,9,11,13,20],'min_samples_split':[5,10,25,50,100,120,150]}
 8 gsearch2 = GridSearchCV(estimator = RandomForestClassifier(n_estimators=160),param_grid = param_test2, cv=5)
 9 gsearch2.fit(X_train,y_train)
10 print( gsearch2.best_params_, gsearch2.best_score_)

 

 1 #最好的随机森林模型
 2 best_rf=RandomForestClassifier(n_estimators=160, max_depth=20, min_samples_split=5) 
 3 
 4 best_rf .fit(X_train, y_train)
 5 
 6 yrfhat = best_rf .predict(X_valid)
 7 feat_importance = best_rf.feature_importances_
 8 rffeat_importance = pd.DataFrame([X_train.columns, random_forest.feature_importances_]).T
 9 
10 print('******************随机森林模型**************')
11 print('训练集上的准确率',best_rf.score(X_train, y_train))
12 print('验证集上的准确率',best_rf.score(X_valid,y_valid))
13 print('混淆矩阵\n', confusion_matrix(y_valid, yrfhat))
14 print('********************************************************')
15 print('最好的随机森林模型的分类报告\n', classification_report(y_valid, yrfhat))
16 print(rffeat_importance.sort_values(by=1, ascending=False))

 

 

全代码附上

  1 import pandas as pd
  2 import numpy as np
  3 import matplotlib.pyplot as plt
  4 import seaborn as sns
  5 #import scikitplot as skplt
  6 import sklearn as sk
  7 from sklearn.model_selection import train_test_split
  8 from sklearn.preprocessing import StandardScaler
  9 plt.rcParams['font.sans-serif']='SimHei'
 10 plt.rcParams['axes.unicode_minus']=False
 11 
 12 import warnings
 13 warnings.filterwarnings("ignore")
 14 # 导入原始自杀数据集并重新命名列:
 15 originaldata = pd.read_csv('./master.csv')
 16 # 国家,  年份,  性别,  年龄,  自杀人数,  人口数量,  自杀人数/总人口*100000(自杀率),
 17 # 国家-年份,     人类发展指数(用以衡量联合国各成员国经济社会发展水平的指标,是对传统的GNP指标挑战的结果。)
 18 # 年度国内生产总值(衡量经济发展的指标),      年人均国内生产总值:国内生产总值/人口 ,         世代
 19 originaldata.columns = ['country', 'year', 'sex', 'age', 'suicides_no', 'population','suicidesper100k',
 20                       'country-year', 'yearlyHDI', 
 21                         'GDPpyear', 'GDPpcapita', 'generation']
 22 
 23 originaldata.head()
 24 originaldata.shape
 25 originaldata.info()
 26 (originaldata=="male").sum()
 27 a = 13910/27820
 28 a
 29 df3 = originaldata.groupby("country").agg({"country":"count"})
 30 df3.columns = ["count"]
 31 df3
 32 # 修复和清理原始数据
 33 # 将 年度国内生产总值 数据中 ','分割去除掉(比如2,156,624,900),并且转换成float的数字类型
 34 originaldata['GDPpyear'] = originaldata.apply(lambda x: float(x['GDPpyear'].replace(',', '')), axis=1)
 35 originaldata['GDPpyear'].head(10)
 36 
 37 # sex 转换为category类型
 38 # Categoricals 是 pandas 的一种数据类型,对应着被统计的变量。Categoricals 是由固定的且有限数量的变量组成的。
 39 originaldata.sex.astype('category')
 40 df = originaldata.copy()#复制一份数据
 41 df
 42 df.suicidesper100k.mean()
 43 df.suicidesper100k.std()
 44 min(df.suicidesper100k)
 45 max(df.suicidesper100k)
 46 import seaborn as sns
 47 sns.distplot(df.suicidesper100k)
 48 plt.xticks(fontsize=10)
 49 plt.yticks(fontsize=20)
 50 plt.show()
 51 df.suicidesper100k.isnull().sum()
 52 col = plt.cm.Spectral(np.linspace(0, 1, 20))
 53 
 54 plt.figure(figsize=(8, 6))
 55 agedistf = pd.DataFrame(df.groupby('sex').get_group('female').groupby('age').suicides_no.sum())
 56 agedistm = pd.DataFrame(df.groupby('sex').get_group('male').groupby('age').suicides_no.sum())
 57 plt.bar(agedistm.index, agedistm.suicides_no, color=col[18])
 58 plt.bar(agedistf.index, agedistf.suicides_no, color=col[8])
 59 plt.legend(['male', 'female'], fontsize=16)
 60 plt.ylabel('Count', fontsize=14)
 61 plt.xlabel('Suicides per 100K', fontsize=14)
 62 plt.xticks(fontsize=10)
 63 plt.yticks(fontsize=20)
 64 plt.show()
 65 col = plt.cm.Spectral(np.linspace(0, 1, 22))
 66 plt.figure(figsize=(12, 15))
 67 
 68 plt.subplot(211)
 69 #自杀率(放大1000倍)的平均值最高的前10个国家
 70 df.groupby(['country']).suicidesper100k.mean().nlargest(10).plot(kind='bar', color=col, fontsize=20)
 71 plt.xlabel('Average Suicides/100k', size=20)
 72 plt.ylabel('Country', fontsize=20)
 73 plt.title('Top 10 countries', fontsize=30)
 74 
 75 plt.figure(figsize=(12, 15))
 76 plt.subplot(212)
 77 #自杀人数的平均值最高的前10个国家
 78 df.groupby(['country']).suicides_no.mean().nlargest(10).plot(kind='bar', color=col, fontsize=20)
 79 plt.xlabel('Average Suicides_no', size=20)
 80 plt.ylabel('Country', fontsize=20);
 81 plt.title('Top 10 countries', fontsize=30)
 82 plt.show()
 83 plt.figure(figsize=(10, 16))
 84 
 85 #总人口的各个年龄段的性别分布
 86 plt.subplot(311)
 87 sns.barplot(x='sex', y='population', hue='age', data=df, palette="Greens")  #hue按年龄分组
 88 plt.xticks(ha='right', fontsize=20)
 89 plt.ylabel('Population', fontsize=20)
 90 plt.xlabel('Sex', fontsize=20)
 91 plt.title("不同年龄段的男、女总人口数")
 92 plt.legend(fontsize=14, loc='best')
 93 
 94 #自杀人数的各个年龄段的性别分布
 95 plt.subplot(312)
 96 sns.barplot(x='sex', y='suicides_no', hue='age', data=df, palette="Greens")
 97 plt.xticks(ha='right', fontsize=20)
 98 plt.ylabel('suicides incidences', fontsize=20)
 99 plt.xlabel('Sex', fontsize=20)
100 plt.title("不同年龄段的男、女自杀人口数")
101 plt.legend(fontsize=14)
102 
103 #自杀率(放大1000倍)的各个年龄段的性别分布
104 plt.subplot(313)
105 sns.barplot(x='sex', y='suicidesper100k', hue='age', data=df,palette="Greens")
106 plt.xticks(ha='right', fontsize=20);
107 plt.ylabel('suicidesper100k',fontsize=20);
108 plt.xlabel('Sex',fontsize=20);
109 plt.title("不同年龄段的男、女自杀率")
110 plt.legend(fontsize=14);
111 
112 plt.subplots_adjust(top=1.2)
113 plt.show()
114 plt.figure(figsize=(12, 16))
115 
116 # 具体按性别和年份 来看 男女的自杀率
117 plt.subplot(311)
118 sns.lineplot(x='year', y='suicidesper100k', hue='sex', data=df, palette="hot")  #hue按年龄分组
119 plt.xticks(ha='right', fontsize=20)
120 plt.ylabel('suicidesper100k', fontsize=20)
121 plt.xlabel('year', fontsize=20)
122 plt.legend(fontsize=14, loc='best')  
123 plt.title("性别年份与自杀率关系图")
124 plt.show()
125 plt.figure(figsize=(8, 6))
126 
127 #选出year列并且去除重复的年份
128 year = originaldata.groupby('year').year.unique()
129 
130 #各个年份的自杀人数汇总
131 #使用seaborn进行可视化,输入的数据必须为dataframe
132 totalpyear = pd.DataFrame(originaldata.groupby('year').suicides_no.sum())   
133 
134 plt.plot(year.index[0:31], totalpyear[0:31], color=col[18])  #选取范围为[0:31]  1985年到2015年
135 plt.xlabel('year', fontsize=15)
136 plt.ylabel('Total number of suicides in the world', fontsize=15)
137 plt.show()
138 plt.figure(figsize=(20, 8))
139 
140 # 自杀率(放大1000倍)的分布情况,y轴为个数
141 plt.subplot(121)
142 plt.hist(df.suicidesper100k, bins=30, color=col[18])   #bins:条形数
143 plt.xlabel('Suicides per 100K of population', fontsize=25)
144 plt.xticks(rotation = 0,                 fontsize = 20)  
145 plt.ylabel('count', fontsize=25)
146 plt.yticks(                              fontsize = 20)   
147 
148 # 年人均国内生产总值的分布情况,y轴为个数
149 plt.subplot(122)
150 plt.hist(df.GDPpcapita, bins=30, color=col[7])
151 plt.xlabel('GDP', fontsize=25)
152 plt.xticks(rotation = 0,fontsize = 20)  
153 plt.ylabel('count', fontsize=25)
154 plt.yticks(fontsize = 20)   
155 plt.show()
156 corr = df.corr() #相关系数矩阵,即给出了任意两个变量之间的相关系数
157 
158 # 相关矩阵的上三角部分与下三角对称。因此,热图不需要显示整个矩阵。在下一步隐藏上三角形。
159 # 设置mask隐藏上三角
160 # np.zeros_like() 返回一个零数组,其形状和类型与给定的数组相同。
161 # 该 dtype=np.bool 参数会覆盖数据类型,因此我们的数组是一个布尔数组。
162 # np.triu_indices_from(mask) 返回数组上三角形的索引。
163 # 现在,我们将上三角形设置为True。 mask[np.triu_indices_from(mask)]= True
164 mask = np.zeros_like(corr, dtype=np.bool)
165 mask[np.triu_indices_from(mask)] = True
166 
167 # 在Seaborn中创建热图
168 f, ax = plt.subplots(figsize=(10, 8))
169 # 生成自定义发散颜色图
170 cmap = sns.diverging_palette(220, 10, as_cmap=True)
171 
172 # 绘制热图
173 # 数据为 corr
174 # vmax,vmin:分别是热力图的颜色取值最大和最小范围
175 # center:数据表取值有差异时,设置热力图的色彩中心对齐值;通过设置center值,可以调整生成的图像颜色的整体深浅
176 # square:设置热力图矩阵小块形状,默认值是False
177 # linewidths(矩阵小块的间隔),
178 # cbar_kws:热力图侧边绘制颜色刻度条时,相关字体设置,默认值是None
179 sns.heatmap(corr, mask=mask, cmap=cmap, vmax=1, vmin=-1, center=0,  
180             square=True, linewidths=0.2, cbar_kws={"shrink": 0.8},annot=True)
181 plt.xticks(fontsize=20)
182 plt.yticks(fontsize=20)
183 plt.show()
184 #复制数据
185 total = df.copy()
186 # 对总人口用均值填充
187 total.population.fillna(total.population.mean(), inplace=True)
188 # 小于平均值的为低风险,大于平均值的为高风险
189 total['risk'] = np.where(total.suicidesper100k < total.suicidesper100k.mean(), 0, 1)
190 
191 plt.figure(figsize=(16, 5))
192 plt.subplot(121)
193 plt.hist(total.risk, color=col[8])
194 plt.ylabel('counts', fontsize=20)
195 plt.xlabel('Suicide risk', fontsize=20)
196 plt.title("自杀高低风险数量")
197 
198 plt.subplot(122)
199 sns.distplot(total.suicidesper100k[total.risk == 0], bins=10)
200 sns.distplot(total.suicidesper100k[total.risk == 1], bins=20)  
201 plt.xlabel('Suicides', fontsize=20)
202 plt.title("自杀高低风险分布情况")
203 plt.show()
204 (total['risk']==1).sum()
205 (total['risk']==0).sum()
206 total.head(5)
207 total['yearlyHDI'].isnull().sum()
208 a = 19456/27820
209 a
210 total['yearlyHDI'].describe()
211 total['yearlyHDI'].isnull().sum()
212 total
213 fill_1 = total['yearlyHDI']
214 fill_1 = pd.DataFrame(fill_1)
215 fill_1
216 from scipy.interpolate import lagrange #导入拉格朗日函数
217 def ployinterp_column(s,n,k=2,result_type='broadcast'): # k=2表示用空值的前后两个数值来拟合曲线,从而预测空值
218     y = s[list(range(n+2-k,n+2)) + list(range(n+3,n+3-k))] # 取值,range函数返回一个左闭右开([left,right))的序列数
219     y = y[y.notnull()] # 取上一行中取出数值列表中的非空值,保证y的每行都有数值,便于拟合函数
220     return lagrange(y.index,list(y))(n) # 调用拉格朗日函数,并添加索引
221 for i in fill_1.columns: # 如果i在data的列名中,data.columns生成的是data的全部列名
222     for j in range(len(fill_1)): # len(data)返回了data的长度,若此长度为5,则range(5)会产生从0开始计数的整数列表
223         if (fill_1[i].isnull())[j]: # 如果data[i][j]为空,则调用函数ployinterp_column为其插值
224             fill_1[i][j] = ployinterp_column(fill_1[i],j,result_type='broadcast')  
225 fill_1
226 # 对国家进行 标准化标签,将标签值统一转换成range(标签值个数-1)范围内
227 # 相当于fit(X).transform(X),意思就是先进行fit(),进行数据拟合,然后在进行transform() 进行标准化处理
228 
229 from sklearn.preprocessing import LabelEncoder
230 le = LabelEncoder()
231 total.country = le.fit_transform(total.country)
232 total.country.unique()
233 
234 # 为建立模型准备数据
235 X = total.drop(['suicidesper100k','risk','country-year'],axis = 1)
236 #用0进行填补
237 X['yearlyHDI'] = fill_1['yearlyHDI']
238 y = total['risk']
239 #对X进行独热编码处理
240 XS = pd.get_dummies(X)
241 #GDP和人口的分布
242 ax1 = total[total['risk'] == 1][0:200].plot(kind='scatter', x='GDPpcapita', y='population', color='DarkRed',
243                                             label='high risk', figsize=(6, 5), fontsize=12)
244 total[total['risk'] == 0][0:200].plot(kind='scatter', x='GDPpcapita', y='population', color='DarkBlue',
245                                             label='low risk', ax=ax1)
246 
247 plt.ylabel('population', fontsize=16)
248 plt.xlabel('GDP per capita', fontsize=16)
249 plt.legend(fontsize=14)
250 #GDP和人类发展指数的分布
251 ax1 = total[total['risk'] == 1][0:200].plot(kind='scatter', x='GDPpcapita', y='yearlyHDI', color='DarkRed',
252                                             label='high risk', figsize=(6, 5), fontsize=12)
253 total[total['risk'] == 0][0:200].plot(kind='scatter', x='GDPpcapita', y='yearlyHDI', color='DarkBlue',
254                                             label='low risk', ax=ax1)
255 
256 plt.ylabel('yearlyHDI', fontsize=16)
257 plt.xlabel('GDP per capita', fontsize=16)
258 plt.legend(fontsize=14)
259 # 关于年份的高低自杀风险
260 fig = plt.figure(figsize=(30, 30))
261 
262 plt.subplot(4, 3, 1)
263 sns.distplot(total[total.columns[0]][total.risk == 0], label='low risk')
264 sns.distplot(total[total.columns[0]][total.risk == 1], label='high risk')       
265 plt.legend(loc='best', fontsize=18)  
266 plt.xlabel(total.columns[0], fontsize=18)
267 plt.show()
268 from sklearn.model_selection import train_test_split
269 # 将数据集拆分为训练集和测试集
270 # 首先将该数据3/4作为训练集,1/4作为测试集;再由训练集划分1/5作为验证集
271 X_train, X_test, y_train, y_test = train_test_split(XS, y, test_size=0.25, random_state=4)
272 X_train,X_valid,y_train,y_valid=train_test_split(X_train,y_train,test_size=0.2,random_state=4)
273 print('Train set:', X_train.shape, y_train.shape)
274 print('Test set:', X_test.shape, y_test.shape)
275 print('Test set:', X_valid.shape, y_valid.shape)
276 from sklearn.linear_model import LogisticRegression
277 from sklearn.metrics import recall_score,accuracy_score
278 from sklearn.metrics import precision_recall_fscore_support
279 from sklearn.metrics import confusion_matrix, classification_report
280 
281 LR = LogisticRegression(C=0.001, solver='liblinear')
282 LR.fit(X_train, y_train)
283 
284 # 预测类别:0还是1
285 yLRhat = LR.predict(X_valid)
286  
287 # 预测 0或1的概率(例如 [0.54689436, 0.45310564] 预测出来为0)
288 yLRhat_prob = LR.predict_proba(X_valid)
289 
290 cm = confusion_matrix(y_valid, yLRhat)
291 print('\n confusion matrix:混淆矩阵 \n', cm)
292 print('此时模型准确率为:',accuracy_score(y_valid, yLRhat))
293 print('********************************************************')
294 print('\n')
295 print('逻辑回归模型的分类报告\n', classification_report(y_valid, yLRhat))
296 #skplt.metrics.plot_confusion_matrix(y_valid,yLRhat,normalize=True)
297 X_train.head()
298 from sklearn.model_selection import GridSearchCV
299 
300 param={"tol":[1e-4, 1e-3,1e-2], "C":[0.4, 0.6, 0.8]}
301 grid = GridSearchCV(LogisticRegression(),param_grid=param, cv=5)#这里是5折交叉验证
302 grid.fit(X_train,y_train)
303 print(grid.best_params_)
304 print(grid.best_score_)
305 
306 #得到最好的逻辑回归分类器
307 best_LR=grid.best_estimator_ 
308 
309 #进行训练、预测
310 best_LR.fit(X_train,y_train)
311 pred=best_LR.predict(X_valid)
312 
313 cm = confusion_matrix(y_valid, pred)
314 print('\n confusion matrix:混淆矩阵 \n', cm)
315 print('最好的逻辑回归模型准确率为:',accuracy_score(y_valid, pred))
316 print('********************************************************')
317 print('\n')
318 print('最好的逻辑回归模型的分类报告\n', classification_report(y_valid, pred))
319 from sklearn.tree import DecisionTreeClassifier
320 from sklearn.metrics import accuracy_score
321 from sklearn.metrics import confusion_matrix, classification_report
322 
323 # 决策树学习
324 # 函数为创建一个决策树模型
325 # criterion:gini或者entropy,前者是基尼系数,后者是信息熵。
326 # max_depth:  int or None, optional (default=None) 设置决策随机森林中的决策树的最大深度,深度越大,越容易过拟合,推荐树的深度为:5-20之间。
327 # max_leaf_nodes: 通过限制最大叶子节点数,可以防止过拟合,默认是"None”,即不限制最大的叶子节点数。
328 DT = DecisionTreeClassifier(criterion="entropy", max_depth=7, max_leaf_nodes=30)
329 DT.fit(X_train, y_train)
330 ydthat = DT.predict(X_valid)
331 
332 print('***决策树模型***')
333 
334 #决策树模型性能评估
335 print('验证集上的准确率:', DT.score(X_valid, y_valid))
336 print('训练集上的准确率:', DT.score(X_train, y_train))
337 
338 # 混淆矩阵
339 print('CM\n', confusion_matrix(y_valid, ydthat))
340 print('********************************************************')
341 
342 print('决策树模型的分类报告\n', classification_report(y_valid, ydthat))
343 
344 DTfeat_importance = DT.feature_importances_
345 DTfeat_importance = pd.DataFrame([X_train.columns, DT.feature_importances_]).T
346 
347 # 特征重要性排序
348 print("特征重要性排名如下:")
349 print(DTfeat_importance.sort_values(by=1, ascending=False))
350 # 通过cv_results观察过程并做图
351 max_depth=np.arange(0,20,3)
352 max_leaf_nodes=np.arange(0,30,3)
353 min_samples_leaf =np.arange(0,20,2)
354 param1= {'criterion':['entropy'],'max_depth':max_depth}
355 param2= {'criterion':['entropy'],'min_samples_leaf':min_samples_leaf}
356 param3= {'criterion':['entropy'],'max_leaf_nodes':max_leaf_nodes}
357 
358 
359 clf1 = GridSearchCV(DecisionTreeClassifier(),param_grid=param1,cv=6)
360 clf1.fit(X_train,y_train)
361 
362 clf2 = GridSearchCV(DecisionTreeClassifier(),param_grid=param2,cv=6)
363 clf2.fit(X_train,y_train)
364 
365 
366 clf3 = GridSearchCV(DecisionTreeClassifier(),param_grid=param3,cv=6)
367 clf3.fit(X_train,y_train)
368 
369 fig = plt.figure(figsize=(20,10), dpi=100)
370 ax = fig.add_subplot(311)
371 ax.plot(min_samples_leaf,clf2.cv_results_['mean_test_score'],'g*-',)
372 plt.title('决策树模型网格搜索的训练过程',fontsize=20)
373 plt.xticks(fontsize=20)
374 plt.yticks(fontsize=20)
375 
376 ax = fig.add_subplot(312)
377 ax.plot(max_depth,clf1.cv_results_['mean_test_score'],'g*-')
378 plt.xticks(fontsize=20)
379 plt.yticks(fontsize=20)
380 ax = fig.add_subplot(313)
381 ax.plot(max_leaf_nodes,clf3.cv_results_['mean_test_score'],'g*-')
382 plt.xticks(fontsize=20)
383 plt.yticks(fontsize=20)
384 plt.show()
385 best_DT = DecisionTreeClassifier(criterion="entropy", max_depth=15, max_leaf_nodes=25,min_samples_leaf=2)
386 best_DT.fit(X_train, y_train)
387 ydthat =best_DT.predict(X_valid)
388 
389 print('***决策树模型***')
390 
391 #决策树模型性能评估
392 print('验证集上的准确率:',best_DT.score(X_valid, y_valid))
393 print('训练集上的准确率:',best_DT.score(X_train, y_train))
394 
395 # 混淆矩阵
396 print('CM\n', confusion_matrix(y_valid, ydthat))
397 print('********************************************************')
398 
399 print('决策树模型的分类报告\n', classification_report(y_valid, ydthat))
400 
401 DTfeat_importance = best_DT.feature_importances_
402 DTfeat_importance = pd.DataFrame([X_train.columns, DT.feature_importances_]).T
403 
404 # 特征重要性排序
405 print("特征重要性排名如下:")
406 print(DTfeat_importance.sort_values(by=1, ascending=False))
407 # 随机森林可以视为多颗决策树的集成,鲁棒性更强,泛化能力更好,不易产生过拟合现象。但是噪声比较大的情况下会过拟合。
408 
409 from sklearn.ensemble import RandomForestClassifier
410 
411 random_forest = RandomForestClassifier(n_estimators=20, max_depth=10, min_samples_split=2, min_samples_leaf=5,
412                                        max_leaf_nodes=20, max_features=len(X_train.columns)) 
413 
414 random_forest.fit(X_train, y_train)
415 
416 yrfhat = random_forest.predict(X_valid)
417 feat_importance = random_forest.feature_importances_
418 rffeat_importance = pd.DataFrame([X_train.columns, random_forest.feature_importances_]).T
419 
420 print('******************Random forest classifier**************')
421 print('训练集上的准确率', random_forest.score(X_train, y_train))
422 print('验证集上的准确率', random_forest.score(X_valid,y_valid))
423 print('混淆矩阵\n', confusion_matrix(y_valid, yrfhat))
424 print('********************************************************')
425 print('随机森林的分类报告\n', classification_report(y_valid, yrfhat))
426 print(rffeat_importance.sort_values(by=1, ascending=False))
427 #我们首先对n_estimators进行网格搜索:
428 param_test1 = {'n_estimators':[50,120,160,200,250]}
429 gsearch1 = GridSearchCV(estimator = RandomForestClassifier(), param_grid = param_test1,cv=5)
430 gsearch1.fit(X_train,y_train)
431 print( gsearch1.best_params_, gsearch1.best_score_)
432 #接着我们对决策树最大深度max_depth和内部节点再划分所需最小样本数min_samples_split进行网格搜索。
433 param_test2 = {'max_depth':[1,2,3,5,7,9,11,13,20],'min_samples_split':[5,10,25,50,100,120,150]}
434 gsearch2 = GridSearchCV(estimator = RandomForestClassifier(n_estimators=160),param_grid = param_test2, cv=5)
435 gsearch2.fit(X_train,y_train)
436 print( gsearch2.best_params_, gsearch2.best_score_)
437 #最好的随机森林模型
438 best_rf=RandomForestClassifier(n_estimators=160, max_depth=20, min_samples_split=5) 
439 
440 best_rf .fit(X_train, y_train)
441 
442 yrfhat = best_rf .predict(X_valid)
443 feat_importance = best_rf.feature_importances_
444 rffeat_importance = pd.DataFrame([X_train.columns, random_forest.feature_importances_]).T
445 
446 print('******************随机森林模型**************')
447 print('训练集上的准确率',best_rf.score(X_train, y_train))
448 print('验证集上的准确率',best_rf.score(X_valid,y_valid))
449 print('混淆矩阵\n', confusion_matrix(y_valid, yrfhat))
450 print('********************************************************')
451 print('最好的随机森林模型的分类报告\n', classification_report(y_valid, yrfhat))
452 print(rffeat_importance.sort_values(by=1, ascending=False))

 

posted on 2023-09-09 15:38  3veromca  阅读(245)  评论(0编辑  收藏  举报