Pandas+随机森林数模实战日记

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

记录第一次单人参赛,用Pandas+随机森林实战某数模杯赛预赛记录,并且记录遇到的问题,训练分数提升问题。该赛题为以银行贷前业务场景为切入点,数据为提供的用户基本信息、借贷信息、财务信息等脱敏后的数据(数据中以A1-A8,B1-B24为特征,没有具体细节),实现审贷客户分类(二分类),以0.5*AUC+0.5*F1值作为评分指标。


一、数据预处理

机器学习中经常有这一句话,数据和特征决定了上限,而算法只能逼近这个上限。这次特征工程做的不好,所以评分一直提不上去。这次比赛先根据用户ID将两个表关联处理,可以用head()、info()、describe()等pandas函数对数据进行大概了解。

1.数据表关联

import pandas as pd

#关联数据表
df1 = pd.read_excel(TRAIN_PATH_1)
df2 = pd.read_excel(TRAIN_PATH_2)
df3 = pd.read_excel(TRAIN_PATH_3)
ccl = pd.merge(df1, df2)
ccl = pd.merge(ccl, df3)

2.特征相关性分析

一开始用了相关性分析,发现A6、A8特征相关性为1,并且预测集中两个特征大量数据缺失,因此去掉了这两个特征。

plt.figure(figsize=(12,10)) 
corr= ccl.corr()
corr = corr[~(np.abs(corr) < 0.2)] 
mask = np.triu(np.ones_like(corr, dtype=bool))

heatmap=sns.heatmap(corr,mask=mask, annot=True,cmap ='RdYlGn',linewidths=.5) 
heatmap.set_title('Correlation Heatmap', fontdict={'fontsize':18}, pad=20)

还可以研究各特征分布情况,去掉分布异常状况。

sns.pairplot(ccl, vars=["特征名称"], hue = 'label')

3.数据清洗

 该次数据处理难度低,根据pandas的分析,除了ID以及标签值(0或1),其他特征分布为int和float型,没有文字,因此分别检测离群值、空值填充(mean填充)、标准化。

#离群值替换

dd = pd.DataFrame(X)
columns_list = dd.columns.tolist()
for columns in columns_list:
    kk = dd[columns].mean().astype('int')
    ee = dd[columns].std().astype('int')
    dd[dd[columns] > (kk+3*ee)] = (kk+3*ee)
    dd[dd[columns] < (kk-3*ee)] = (kk-3*ee)
X = dd.iloc[:,:].values

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, 
random_state=700)

#数据均值填充
imputer = SimpleImputer(missing_values=np.nan, strategy='mean')
imputerimputer= imputer.fit(X_train[:, 1:30])  
X_train[:, 1:30] = imputer.transform(X_train[:, 1:30]) 
X_test = imputer.fit_transform(X_test)

#数据标准化
from sklearn.preprocessing import StandardScaler  
from sklearn.model_selection import cross_val_score
from sklearn.metrics import roc_auc_score
st_x= StandardScaler()  
X_train= st_x.fit_transform(X_train)  
X_test =  st_x.transform(X_test)  

二、随机森林训练

本次比赛先是用了KNN(K-近邻)算法训练,得到的分数基本垫底。后来改用了随机森林以及逻辑回归,随机森林效果更好一些。

1.随机森林

可视化调参,随机森林影响程度从高到低的几个参数分别是n_estimators、max_depth、min_samples_split、min_samples_leaf,只能单个训练,反复寻找效果好的,然后训练(其实最后发现,怎么调分数都不高)

# 调n_estimators参数
ScoreAll = []
for i in range(100,130,3):
    DT = RandomForestClassifier(n_estimators=i,random_state=66) #,criterion = 'entropy'
    score = cross_val_score(DT, X_train, y_train,cv=10).mean()
    ScoreAll.append([i,score])
ScoreAll = np.array(ScoreAll)
max_score = np.where(ScoreAll==np.max(ScoreAll[:,1]))[0][0] ##这句话看似很长的,其实就是找出最高得分对应的索引
print("最优参数以及最高得分:",ScoreAll[max_score])
import matplotlib.pyplot as plt
plt.figure(figsize=[20,5])
plt.plot(ScoreAll[:,0],ScoreAll[:,1])
plt.title('n_estimators')
plt.savefig("n_estimators")
plt.show()

# 粗调max_depth参数
ScoreAll = []
for i in range(10,30,3):
    DT = RandomForestClassifier(n_estimators = 112,random_state = 66,max_depth =i ) #,criterion = 'entropy'
    score = cross_val_score(DT, X_train, y_train, cv=10).mean()
    ScoreAll.append([i,score])
ScoreAll = np.array(ScoreAll)
max_score = np.where(ScoreAll==np.max(ScoreAll[:,1]))[0][0] ##这句话看似很长的,其实就是找出最高得分对应的索引
print("最优参数以及最高得分:",ScoreAll[max_score])
plt.figure(figsize=[20,5])
plt.plot(ScoreAll[:,0],ScoreAll[:,1])
plt.title('max_depth')
plt.savefig("max_depth")
plt.show()

#调min_samples_split参数
ScoreAll = []
for i in range(2,10):
    RF = RandomForestClassifier(n_estimators =112,random_state = 66,max_depth =16,min_samples_split = i ) #,criterion = 'entropy'
    score = cross_val_score(RF,X_train, y_train,cv=10).mean()
    ScoreAll.append([i,score])
ScoreAll = np.array(ScoreAll)
max_score = np.where(ScoreAll==np.max(ScoreAll[:,1]))[0][0] ##这句话看似很长的,其实就是找出最高得分对应的索引
print("最优参数以及最高得分:",ScoreAll[max_score])
plt.figure(figsize=[20,5])
plt.plot(ScoreAll[:,0],ScoreAll[:,1])
plt.title('min_samples_split')
plt.savefig("min_samples_split")
plt.show()

#调min_samples_leaf参数
ScoreAll = []
for i in range(1,15,2):
    DT = RandomForestClassifier(n_estimators =112,random_state = 66,max_depth =16,min_samples_leaf = i,min_samples_split = 5 )
    score = cross_val_score(DT,X_train ,y_train, cv=10).mean()
    ScoreAll.append([i,score])
ScoreAll = np.array(ScoreAll)
 
max_score = np.where(ScoreAll==np.max(ScoreAll[:,1]))[0][0] ##这句话看似很长的,其实就是找出最高得分对应的索引
print("最优参数以及最高得分:",ScoreAll[max_score])
plt.figure(figsize=[20,5])
plt.plot(ScoreAll[:,0],ScoreAll[:,1])
plt.title('min_samples_leaf')
plt.savefig("min_samples_leaf")
plt.show()

#建立模型,并训练模型
import warnings
warnings.filterwarnings('ignore')
from sklearn.ensemble import RandomForestClassifier#导入分类模块
from sklearn.metrics import accuracy_score#导入评估准确率的模块
from sklearn.metrics import recall_score

rf = RandomForestClassifier(n_estimators=3, random_state = 1, max_depth = 18 )
rf.fit(X_train,y_train)
 
#用测试数据集进行预测
ypredict=rf.predict(X_test)
#评估预测的准确率
score_r = rf.score(X_test, y_test) # 计算准确度
accuracy = accuracy_score(y_test, ypredict)
print("Accuracy: %.2f%%" % (accuracy * 100.0))
print(score_r)
ypredict_proba = rf.predict_proba(X_test)
F1 = sum(y_test * ypredict) / sum(y_test + ypredict)
auc_score = roc_auc_score(y_test, ypredict)
a = F1*0.5+ auc_score*0.5

 最后就是保存为csv提交文件。

总结

本次比赛也是在有一点python基础下第一次完成一个完整的训练过程,中途发现很多问题,例如各种库的使用,特征工程方法,训练方法。大概为以下几点:

1.数据是不是分开训练效果更好呢,一开始不按ID合并可能效果更好,包括特征工程许多知识都不太了解以及数据清洗方法有没有更好的选择

2.模型选择以及各种库的使用不够熟练,不知道什么样的问题更适合什么样的模型

3.不知道怎么提高训练效果,哪些指标更加能针对该问题(用什么指标来训练?)

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值