предисловие
Платформа Alibaba Tianchi имеет очень богатые ресурсы данных, которые играют важную роль в укреплении мышления в области анализа данных. Эта статья углубляет понимание обучения различных моделей путем анализа прогнозирования дефолта по кредиту и предполагает дальнейшую оптимизацию и улучшение концепции анализа данных в практических проектах.
Импорт модуля, конфигурация среды Jupyter и загрузка набора данных
Импортируйте необходимые модули.
import pandas as pd,numpy as np,matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
import sklearn
from sklearn.linear_model import LinearRegression,LogisticRegressionCV
from sklearn.exceptions import ConvergenceWarning
from sklearn.ensemble import RandomForestClassifier
from sklearn.feature_selection import SelectFromModel
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.model_selection import cross_val_score
Некоторые предыдущие настройки.
#设置字体,防止中文乱码。
mpl.rcParams['font.sans-serif'] =[u'simHei']
#防止图片下负号显示为矩形框
mpl.rcParams['axes.unicode_minus'] =False
#拦截警告
warnings.filterwarnings('ignore')
warnings.filterwarnings(action ='ignore',category=ConvergenceWarning)
#seaboen字体设置
sns.set(font='SimHei')
Загрузите набор данных.
data_submit =pd.read_csv('sample_submit.csv ')
data_testA =pd.read_csv('testA.csv')
data_train =pd.read_csv('train.csv')
data_train
______________________________________________________
id loanAmnt term interestRate installment grade subGrade employmentTitle employmentLength homeOwnership ... n5 n6 n7 n8 n9 n10 n11 n12 n13 n14
0 0 35000.0 5 19.52 917.97 E E2 320.0 2 years 2 ... 9.0 8.0 4.0 12.0 2.0 7.0 0.0 0.0 0.0 2.0
1 1 18000.0 5 18.49 461.90 D D2 219843.0 5 years 0 ... NaN NaN NaN NaN NaN 13.0 NaN NaN NaN NaN
2 2 12000.0 5 16.99 298.17 D D3 31698.0 8 years 0 ... 0.0 21.0 4.0 5.0 3.0 11.0 0.0 0.0 0.0 4.0
3 3 11000.0 3 7.26 340.96 A A4 46854.0 10+ years 1 ... 16.0 4.0 7.0 21.0 6.0 9.0 0.0 0.0 0.0 1.0
4 4 3000.0 3 12.99 101.07 C C2 54.0 NaN 1 ... 4.0 9.0 10.0 15.0 7.0 12.0 0.0 0.0 0.0 4.0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
799995 799995 25000.0 3 14.49 860.41 C C4 2659.0 7 years 1 ... 6.0 2.0 12.0 13.0 10.0 14.0 0.0 0.0 0.0 3.0
799996 799996 17000.0 3 7.90 531.94 A A4 29205.0 10+ years 0 ... 15.0 16.0 2.0 19.0 2.0 7.0 0.0 0.0 0.0 0.0
799997 799997 6000.0 3 13.33 203.12 C C3 2582.0 10+ years 1 ... 4.0 26.0 4.0 10.0 4.0 5.0 0.0 0.0 1.0 4.0
799998 799998 19200.0 3 6.92 592.14 A A4 151.0 10+ years 0 ... 10.0 6.0 12.0 22.0 8.0 16.0 0.0 0.0 0.0 5.0
799999 799999 9000.0 3 11.06 294.91 B B3 13.0 5 years 0 ... 3.0 4.0 4.0 8.0 3.0 7.0 0.0 0.0 0.0 2.0
800000 rows × 47 columns
Исследовательский анализ (EDA)
Обзор набора данных
В основном он включает в себя: информацию о типе данных, предварительный просмотр статистического распределения данных и анализ измерений данных.
#查看数据类型
data_train.info()
#查看数据维度
data_train.shape
#查看数据统计学分布情况
data_train.describe()
——————————————————————————————————————————————————————
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 800000 entries, 0 to 799999
Data columns (total 47 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 id 800000 non-null int64
1 loanAmnt 800000 non-null float64
2 term 800000 non-null int64
3 interestRate 800000 non-null float64
4 installment 800000 non-null float64
5 grade 800000 non-null object
6 subGrade 800000 non-null object
7 employmentTitle 799999 non-null float64
8 employmentLength 753201 non-null object
9 homeOwnership 800000 non-null int64
10 annualIncome 800000 non-null float64
11 verificationStatus 800000 non-null int64
12 issueDate 800000 non-null object
13 isDefault 800000 non-null int64
14 purpose 800000 non-null int64
15 postCode 799999 non-null float64
16 regionCode 800000 non-null int64
17 dti 799761 non-null float64
18 delinquency_2years 800000 non-null float64
19 ficoRangeLow 800000 non-null float64
20 ficoRangeHigh 800000 non-null float64
21 openAcc 800000 non-null float64
22 pubRec 800000 non-null float64
23 pubRecBankruptcies 799595 non-null float64
24 revolBal 800000 non-null float64
25 revolUtil 799469 non-null float64
26 totalAcc 800000 non-null float64
27 initialListStatus 800000 non-null int64
28 applicationType 800000 non-null int64
29 earliesCreditLine 800000 non-null object
30 title 799999 non-null float64
31 policyCode 800000 non-null float64
32 n0 759730 non-null float64
33 n1 759730 non-null float64
34 n2 759730 non-null float64
35 n3 759730 non-null float64
36 n4 766761 non-null float64
37 n5 759730 non-null float64
38 n6 759730 non-null float64
39 n7 759730 non-null float64
40 n8 759729 non-null float64
41 n9 759730 non-null float64
42 n10 766761 non-null float64
43 n11 730248 non-null float64
44 n12 759730 non-null float64
45 n13 759730 non-null float64
46 n14 759730 non-null float64
dtypes: float64(33), int64(9), object(5)
memory usage: 286.9+ MB
Просмотр отсутствующих значений
Просмотрите данные с пропущенными значениями и извлеките их для визуализации.
#用DtaFrame存放数据集中缺失值的数量,列名为counts
nan_num = pd.DataFrame(data_train.isnull().sum(),columns=['counts'])
#取出缺失值数量大于1的列和值
data_nan =nan_num[nan_num['counts']>0]
#按照值排序
data_nan.sort_values(by='counts',inplace=True)
————————————————————————————————————————————————————
counts
employmentTitle 1
postCode 1
title 1
dti 239
pubRecBankruptcies 405
revolUtil 531
n10 33239
n4 33239
n12 40270
n9 40270
n7 40270
n6 40270
n3 40270
n13 40270
n2 40270
n1 40270
n0 40270
n5 40270
n14 40270
n8 40271
employmentLength 46799
n11 69752
Визуализируйте пропущенные значения по номеру.
plt.figure(figsize=(30,10))
data_nan.plot.hist()
Поскольку анализ выбросов заключается в наблюдении за тем, находятся ли они в пределах диапазона отклонений, для просмотра распределения данных используется ящичковая диаграмма.
#查看去重后values数量
data_u =data_train.nunique().sort_values()
data_u
______________________________________________________
policyCode 1
term 2
applicationType 2
initialListStatus 2
isDefault 2
verificationStatus 3
n12 5
n11 5
homeOwnership 6
grade 7
pubRecBankruptcies 11
employmentLength 11
purpose 14
n13 28
delinquency_2years 30
n14 31
pubRec 32
n1 33
subGrade 35
n0 39
ficoRangeLow 39
ficoRangeHigh 39
n9 44
n4 46
n2 50
n3 50
regionCode 51
n5 65
n7 70
openAcc 75
n10 76
n8 102
n6 107
totalAcc 134
issueDate 139
interestRate 641
earliesCreditLine 720
postCode 932
revolUtil 1286
loanAmnt 1540
dti 6321
title 39644
annualIncome 44926
revolBal 71116
installment 72360
employmentTitle 248683
id 800000
dtype: int64
анализ типов данных
Из предыдущего анализа видно, что набор данных в основном включает три типа данных: объект, int64 и float64, Далее будут фильтроваться данные в соответствии с типом данных, а затем анализироваться по очереди.
num_type=data_train.select_dtypes(exclude=['object'])
cls_type=data_train.select_dtypes(include=['object'])
num_type.columns ,cls_type.columns
——————————————————————————————————————————————————————
(Index(['id', 'loanAmnt', 'term', 'interestRate', 'installment',
'employmentTitle', 'homeOwnership', 'annualIncome',
'verificationStatus', 'isDefault', 'purpose', 'postCode', 'regionCode',
'dti', 'delinquency_2years', 'ficoRangeLow', 'ficoRangeHigh', 'openAcc',
'pubRec', 'pubRecBankruptcies', 'revolBal', 'revolUtil', 'totalAcc',
'initialListStatus', 'applicationType', 'title', 'policyCode', 'n0',
'n1', 'n2', 'n3', 'n4', 'n5', 'n6', 'n7', 'n8', 'n9', 'n10', 'n11',
'n12', 'n13', 'n14'],
dtype='object'),
Index(['grade', 'subGrade', 'employmentLength', 'issueDate',
'earliesCreditLine'],
dtype='object'))
Числовые данные
Конструктор используется для классификации типов данных.Для отображения регулярности возвращаемое значение устанавливается в тип ndarray для обработки транспонирования.
def classfify_types():
num_continuous=[]
num_discrete=[]
global data_train,num_type
for name in num_type:
counts =data_train[name].nunique()
if counts<= 10:
num_discrete.append(name)
else:
num_continuous.append(name)
return np.array(num_discrete).T,np.array(num_continuous).T
Непрерывно распространяемые данные
array(['id', 'loanAmnt', 'interestRate', 'installment', 'employmentTitle',
'annualIncome', 'purpose', 'postCode', 'regionCode', 'dti',
'delinquency_2years', 'ficoRangeLow', 'ficoRangeHigh', 'openAcc',
'pubRec', 'pubRecBankruptcies', 'revolBal', 'revolUtil',
'totalAcc', 'title', 'n0', 'n1', 'n2', 'n3', 'n4', 'n5', 'n6',
'n7', 'n8', 'n9', 'n10', 'n13', 'n14'], dtype='<U18'))
Дискретные распределенные данные.
array(['term', 'homeOwnership', 'verificationStatus', 'isDefault',
'initialListStatus', 'applicationType', 'policyCode', 'n11', 'n12'],
dtype='<U18'),
Глядя на ситуацию с дискретными данными, данные слишком длинные, и показаны только начальные результаты.
for i in num_discrete:
print(f'{i}:{data_train[i]}')
Распределение непрерывных данных можно проанализировать с помощью визуализации.Поскольку объем данных слишком велик, а время выполнения велико, для визуализации выбираются 5w фрагментов данных, чтобы проверить, нормально ли распределены данные.
data_continuous =data_train[num_continuous]
date_partial=data_continuous.head(50000)
df = pd.melt(date_partial,value_vars=num_continuous)
sp=sns.FacetGrid(df,col='variable',col_wrap=3,sharex=False,sharey=False)
sp=sp.map(sns.distplot,'value',color='r',rug=True)
Типизированные данные
Давайте сначала посмотрим на распределение категорийных данных
Секретные данные можно анализировать путем визуализации, извлекая данные о кредитном рейтинге для построения графиков. Можно обнаружить, что существует множество кредитных рейтингов B/C/A.
plt.figure(figsize=(8,5))
sns.barplot(data_train['grade'].value_counts().index,data_train['grade'].value_counts())
Посмотрим на распределение трудовых лет: больше всего людей, проработавших более десяти лет, а остальные трудовые годы распределены более равномерно.
plt.figure(figsize=(8,5))
sns.barplot(data_train['employmentLength'].value_counts().index,data_train['employmentLength'].value_counts())
Анализ взаимосвязи данных
Давайте сначала посмотрим на распределение целевых прогнозируемых значений.
data_train['isDefault'].value_counts().plot.bar(color='g')
Давайте проанализируем взаимосвязь между дефолтом по кредиту и собственными значениями.
Наборы данных со значением по умолчанию = 0/1 извлекаются отдельно.
data_y = data_train[data_train['isDefault']==1]
data_n = data_train[data_train['isDefault']==0]
Проанализируйте взаимосвязь между занятостьюLength&isDefault и классом&grade для наборов данных по умолчанию и не по умолчанию соответственно.
fig,((ax1,ax2),(ax3,ax4)) =plt.subplots(2,2,figsize=(14,8))
data_y.groupby('employmentLength').size().plot.bar(ax=ax1,color='r',alpha=0.8)
data_n.groupby('employmentLength')['employmentLength'].count().plot.bar(ax=ax2,color='r',alpha=0.85)
data_y.groupby('grade').size().plot.bar(ax=ax3,color='g',alpha=0.8)
data_n.groupby('grade')['grade'].count().plot.bar(ax=ax4,color='g',alpha=0.85)
plt.xticks(rotation=90)
Визуально проанализируйте взаимосвязь между суммой кредита и ситуацией по умолчанию и обнаружите, что ситуация по умолчанию чаще всего возникает у людей с большой суммой кредита.
fig,((ax1,ax2)) =plt.subplots(1,2,figsize=(10,8))
data_train.groupby('isDefault')['loanAmnt'].sum()
sns.countplot(x='isDefault',data=data_train,ax=ax1,color='r',alpha=0.9)
data_train.groupby('isDefault')['loanAmnt'].median()
sns.countplot(x='isDefault',data=data_train,ax=ax2,color='b',alpha=1)
разработка функций
После предыдущего исследовательского анализа у меня есть более полное представление обо всем наборе данных, поэтому ранний анализ очень важен.При разработке признаков в основном анализируются и обрабатываются основные моменты в EDA, в основном в том числе: обработка пропущенных значений, Обработка данных о собственных значениях и выбор признаков.
Обработка пропущенных значений
Анализ типа данных был проведен ранее.После выделения прогнозируемого целевого значения из набора данных среднее значение используется для заполнения пробела для числовых данных, а его мода выбирается в качестве результата для категориальных данных.
num_type=list(data_train.select_dtypes(exclude=['object']).columns)
cls_type=list(data_train.select_dtypes(include=['object']).columns)
e ='isDefault'
num_type.remove(e)
#预测值分离
data_target =data_train['isDefault']
data_train.drop('isDefault',axis=1,inplace=True)
#用平均数填充
data_train[num_type]=data_train[num_type].fillna(data_train[num_type].mean())
#用众数填充
data_train[cls_type]=data_train[cls_type].fillna(data_train[cls_type].mode())
data_train[cls_type].isnull().sum()
data_train['employmentLength'].fillna('10+ years',inplace=True)
_____________________________________________________________
grade subGrade employmentLength issueDate earliesCreditLine
0 E E2 2 years 2014-07-01 Aug-2001
1 D D2 5 years 2012-08-01 May-2002
2 D D3 8 years 2015-10-01 May-2006
3 A A4 10+ years 2015-08-01 May-1999
4 C C2 10+ years 2016-03-01 Aug-1977
... ... ... ... ... ...
799995 C C4 7 years 2016-07-01 Aug-2011
799996 A A4 10+ years 2013-04-01 May-1989
799997 C C3 10+ years 2015-10-01 Jul-2002
799998 A A4 10+ years 2015-02-01 Jan-1994
799999 B B3 5 years 2018-08-01 Feb-2002
800000 rows × 5 columns
Обработка отсутствующих значений в тестовом наборе:
data_testA[num_type]=data_testA[num_type].fillna(data_testA[num_type].mean())
data_testA[cls_type]=data_testA[cls_type].fillna(data_testA[cls_type].mode())
data_testA['employmentLength']=data_testA['employmentLength'].fillna('10+ years')
Поскольку идентификатор не имеет практического значения для обучения модели, выберите его удаление напрямую.
data_train.drop(['id'],axis=1,inplace=True)
data_testA.drop(['id'],1,inplace=True)
Загрузите тестовый набор в обучающий набор. В целях безопасности данных выберите обучающий набор для обучения позже.
combined=data_train.append(data_testA)
Посмотрите, как выглядят объединенные данные. Код политики компании имеет только одно значение, которое не имеет большого значения для общего анализа, поэтому удалите его. Обработанный набор данных содержит 1 миллион фрагментов данных и 44 признака, из которых первые 800 000 — это обучающий набор, а последние 200 000 — тестовый набор, что облегчает разделение более поздних наборов данных, т.е. 'data_train=combined[:800000]' .
combined.drop(['index','id','policyCode'],1,inplace=True)
combined.shape
_______________________________________________________
(1000000, 44)
однократное кодирование
В наборе данных наблюдения по значению значения делается вывод о том, что требуется обработка виртуального кодирования: Срок кредита (term), кредитный рейтинг (grade), кредитный рейтинг subgrade (subgrade), срок занятости (employmentLength), статус проверки (verificationStatus). Комбинированный имеет 97 функций на данный момент.
def dummies_coder():
global combined
for name in ['term','grade','subGrade',
'employmentLength','verificationStatus']:
data_dummies = pd.get_dummies(combined[name],prefix=name)
combined = pd.concat([combined,data_dummies],axis=1)
combined.drop(name,axis=1,inplace=True)
return combined
combined.shape
————————————————————————————————————————————————————————
(1000000, 97)
Комбинация функций
Согласно информации, представленной на официальном сайте, субъективная классификация всех признаков завершена до однократного кодирования, и на этой основе наблюдается корреляция признаков.
借款人信息:
O-employmentLength就业年限(年)
annualIncome 年收入
employmentTitle就业职称
dti 债务收入比
贷款信息:
loanAmnt 贷款金额
O-term 贷款期限(year)
interestRate 贷款利率
O-grade 贷款等级
O-subGrade 贷款等级之子级
issueDate 贷款发放的月份
还款信息:
installment分期付款金额
贷款附加信息:
O-verificationStatus验证状态
postCode 贷款申请邮政编码的前3位数字
purpose 贷款用途类别
delinquency_2years 违约事件数
pubRec贬损公共记录的数量
homeOwnership 房屋所有权状况
revolBal信贷周转余额合计
earliesCreditLine借款人最早报告的信用额度开立的月份
openAcc借款人信用档案中未结信用额度的数量
title 借款人提供的贷款名称
applicationType个人申请还是与两个共同借款人的联合申请
0-initialListStatus
revolUtil循环额度利用率/相对于所有可用循环信贷的信贷金额
totalAcc 借款人信用档案中当前的信用额度总数
ficoRangeLow 贷款发放时的fico所属的下限
ficoRangeHigh贷款发放时的fico所属的上限
pubRecBankruptcies公开记录清除的数量
还款附加信息:
regionCode 地区编码
匿名特征n0-n14,为一些贷款人行为计数特征的处理
n12 5
n11 5
n13 28
n14 31
n1 33
n0 39
n9 44
n4 46
n2 50
n3 50
n5 65
n7 70
n10 76
n8 102
n6 107
- Годовой доход (annualIncome) x отношение долга к доходу (dti) = годовой долг (debt), который указывает на степень финансового стресса кредитора, влияющего на дефолт или нет;
combined['debt']=combined['annualIncome'] *combined['dti']
combined.drop(['annualIncome','dti'],1,inplace=True)
- Сумма кредита (loanAmnt) x процентная ставка по кредиту (interestRate) x количество лет (term) = проценты (interest), а затем общая сумма кредита и проценты (total_loan) / сумма взноса (passment) = количество платежей (этапы), чем больше количество платежей, тем выше количество платежей.Период, в течение которого может произойти дефолт, больше;
combined['stages']=(combined['loanAmnt'] *combined['interestRate']*0.01*combined['term']+combined['loanAmnt'])/combined['installment']
combined.drop(['loanAmnt','interestRate','term','installment'],1,inplace=True)
combined.shape
__________________________________________________________
(1000000, 92)
- (delinquency_2years) количество событий по умолчанию + (pubRec) количество уничижительных публичных записей - ( pubRecBankruptcies ) количество очищенных публичных записей = кредитная запись (Credit_record), плохие записи можно увидеть со стороны истории по умолчанию кредитора;
combined['Credit_record'] = combined['delinquency_2years']+combined['pubRec']-combined['pubRecBankruptcies']
combined.drop(['delinquency_2years','pubRec','pubRecBankruptcies'],1,inplace=True)
- Объединить (openAcc) количество непогашенных кредитных линий в кредитном досье заемщика + (totalAcc) общее количество кредитных линий в настоящее время в кредитном досье заемщика (revolBal) общий баланс кредитного оборота + (revolUtil) использование возобновляемой квоты / относительно все доступные возобновляемые Сумма кредита = общая кредитная линия (credit_line), общая кредитная линия может показать уровень кредита кредитора, чем лучше кредит, тем больше лимит, и лимит также можно использовать, чтобы избежать риски дефолта;
combined['credit_line'] =combined['openAcc']+combined['totalAcc']+combined['revolBal']+combined['revolUtil']
combined.drop(['openAcc','totalAcc','revolBal','revolUtil'],1,inplace=True)
- (ficoRangeLow) нижняя граница фико на момент выдачи кредита + (ficoRangeHigh) верхняя граница фико на момент выдачи кредита = диапазон фико на момент выдачи кредита (ficoRange), добавляем их механически, и получается непонятно;
combined['ficoRange'] = combined['ficoRangeHigh'] +combined['ficoRangeLow']
combined.drop(['ficoRangeHigh','ficoRangeLow'],1,inplace=True)
- Подсчитав поведение кредитора (n)n0+n1…………+n14=total_n, поскольку это поведение кредитора, а значение n очень мало, предполагается, что это плохо, и все они становятся семьей, Убить сразу 15 — это так круто. . . . .
combined['total_n']=combined['n0']+combined['n1']+combined['n2']+combined['n3']+combined['n4']combined['n5']+combined['n6']+combined['n7']+combined['n8']+combined['n9']+combined['n10']+combined['n11']+combined['n12']+combined['n13']+combined['n14']
combined.drop(['n0','n1', 'n2','n3' ,'n4' ,'n5' ,'n6' ,'n7' ,'n8' ,'n9' ,'n10' ,
'n11' ,'n12' ,'n13' , 'n14'],1,inplace=True)
combined.shape
___________________________________________________
(1000000, 72)
После завершения всей обработки в наборе данных осталось 72 объекта. Обучающий набор, тестовый набор и целевое значение возвращаются ниже.
train=combined.iloc[:800000]
test=combined.iloc[800000:]
targets=pd.read_csv('train.csv',usecols=['isDefault'])['isDefault'].values
обучение модели
Выбор функции
После обработки признаков данные содержат до 72 признаков.Теперь требуется выбор признаков для искусственного уменьшения размерности признаков.Следующее будет использовать оценщик случайного леса для расчета важности признаков.
clf=RandomForestClassifier(n_estimators=50,max_features='sqrt')
clf =clf.fit(train,targets)
Визуализируйте каждую функцию.
features =pd.DataFrame()
features['feature'] =train.columns
features['importance']=clf.feature_importances_
features.sort_values(by=['importance'],ascending=True,inplace=True)
features.set_index('feature',inplace=True)
features.plot(kind='barh',figsize=(15,15))
Можно обнаружить, что, как было исследовано в области разработки признаков, этапы, долг, кредитная_линия, общее_n, почтовый индекс, должность - все имеют сильную корреляцию. Ниже мы делаем набор данных более компактным, а функции сразу сильно сокращаем.
model =SelectFromModel(clf,prefit=True)
train_reduce =model.transform(train)
train_reduce.shape
————————————————————————————————————————————————————
(800000, 12)
Настройте функцию оценки для оценки модели:
def compute_score(clf,x,y,cv=5,scoring='accuracy'):
xval =cross_val_score(clf,x,y,cv=5,scoring=scoring)
return np.mean(xval)
базовая модель
Создайте экземпляр классификатора.
logreg_cv = LogisticRegressionCV()
rf = RandomForestClassifier()
gboost = GradientBoostingClassifier()
svc=SVC()
gnb = GaussianNB()
models = [ logreg_cv, rf,svc, gnb,gboost]
Из-за относительно большого набора данных для повышения эффективности для обучения отбираются некоторые данные.
train_partial =train[:80000]
targets_partial =targets[:80000]
for model in models:
print (f'Cross-validation of :{model.__class__}')
score = compute_score(clf=model, x=train_partial, y=targets_partial, scoring='accuracy')
print (f'CV score ={score}')
print ('****')
——————————————————————————————————————————————————————————————————
Cross-validation of :<class 'sklearn.linear_model._logistic.LogisticRegressionCV'>
CV score =0.7982125
****
Cross-validation of :<class 'sklearn.ensemble._forest.RandomForestClassifier'>
CV score =0.7988125
****
Cross-validation of :<class 'sklearn.svm._classes.SVC'>
CV score =0.7984249999999999
****
Cross-validation of :<class 'sklearn.naive_bayes.GaussianNB'>
CV score =0.7983374999999999
****
Cross-validation of :<class 'sklearn.ensemble._gb.GradientBoostingClassifier'>
CV score =0.8005749999999999
****
- logreg_cv CV score =0.7982125
- rf CV score =0.7988125
- svc CV score =0.7984249999999999
- gnb 0.7983374999999999
- gboost 0.8005749999999999
По результатам первоначального обучения rf и gboost показали себя лучше, и было принято решение провести оптимизацию параметров для улучшения модели.
Настройка гиперпараметров
Среди используемых моделей случайные леса и деревья решений с градиентным усилением работают хорошо, поэтому на этой основе продолжайте дальнейшую оптимизацию параметров, и для завершения этого шага будет использоваться поиск по сетке.
model_box= []
rf=RandomForestClassifier(random_state=2021,max_features='auto')
rf_params ={'n_estimators':[50,120,300],'max_depth':[5,8,15],
'min_samples_leaf':[2,5,10],'min_samples_split':[2,5,10]}
model_box.append([rf,rf_params])
gboost=GradientBoostingClassifier(random_state=2021)
gboost_params ={'learning_rate':[0.05,0.1,0.15],'n_estimators':[10,50],
'max_depth':[3,4,6,10],'min_samples_split':[50,10]}
model_box.append([gboost,gboost_params])
for i in range(len(model_box)):
best_model= GridSearchCV(model_box[i][0],param_grid=model_box[i][1],refit=True,cv=5,scoring='roc_auc').fit(train_partial,targets_partial)
print(model_box[i],':')
print('best_parameters:',best_model.best_params_)
————————————————————————————————————————————————————————————————
[RandomForestClassifier(random_state=2021), {'n_estimators': [50, 120, 300], 'max_depth': [5, 8, 15], 'min_samples_leaf': [2, 5, 10], 'min_samples_split': [2, 5, 10]}] :
best_parameters: {'max_depth': 15, 'min_samples_leaf': 10, 'min_samples_split': 2, 'n_estimators': 300}
[GradientBoostingClassifier(random_state=2021), {'learning_rate': [0.05, 0.1, 0.15], 'n_estimators': [10, 50], 'max_depth': [3, 4, 6, 10], 'min_samples_split': [50, 10]}] :
best_parameters: {'learning_rate': 0.15, 'max_depth': 4, 'min_samples_split': 50, 'n_estimators': 50}
Результаты поиска сетки показывают, что оптимальные параметры:
- рф:
best_parameters: 'max_depth': 15, 'min_samples_leaf': 10, 'min_samples_split': 2, 'n_estimators': 300
- gboost:
best_parameters: 'learning_rate': 0.15, 'max_depth': 4, 'min_samples_split': 50, 'n_estimators': 50
Введите эти параметры, чтобы обучить модель, и вычислите значение оценки для оценки модели.
for i in model_best:
model_best[i].fit(train_partial,targets_partial)
score = cross_val_score(model_best[i],train_partial,targets_partial,cv=5,scoring='score')
print('%s的score值为:%.4f' % (i,score.mean()))
__________________________________________________________________
rf的score值为:0.7997
gboost的score值为:0.8005
Выберите оптимальную модель для прогнозирования и выведите файл результатов.
model_final =model_best['gboost']
predictions= model_final.predict(test).astype(int)
df_predictions = pd.DataFrame()
abc = pd.read_csv('/content/drive/MyDrive/Colab Notebooks/testA.csv')
df_predictions['id'] = abc['id']
df_predictions['isDefault'] = predictions
df_predictions[['id','isDefault']].to_csv('/content/drive/MyDrive/Colab Notebooks/submit.csv', index=False)