本学习笔记为阿里云天池龙珠计划金融风控训练营的学习内容,学习链接为:https://tianchi.aliyun.com/specials/activity/promotion/aicampfr
业界广泛流传这样一句话:“数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限而已”,由此可见特征工程在机器学习中的重要性。具体来说,特征越好、灵活性越强,构建的模型越简单、性能越出色。
- 概念:特征工程就是从原始数据提取特征的过程,这些特征可以很好地描述数据,并且利用特征建立的模型在未知数据上的性能表现可以达到最优(或者接近最佳性能)。
- 特征工程一般包括特征使用、特征获取、特征处理处理、特征选择和特征监控。
- 特征工程的处理流程为首先去掉无用特征,接着去除冗余的特征,如共线特征,并利用存在的特征、转换特征、内容中的特征以及其他数据源生成新特征,然后对特征进行转换(数值化、类别转换、归一化等),最后对特征进行处理(异常值、最大值、最小值,缺失值等),以符合模型的使用。
简单来说,特征工程的处理一般包括数据预处理、特征处理、特征选择等工作,而特征选择视情况而定,如果特征数量较多,则可以进行特征选择等操作。
numerical_fea = list(data_train.select_dtypes(exclude=['object']).columns)
category_fea = list(filter(lambda x: x not in numerical_fea,list(data_train.columns)))
label = 'isDefault'
numerical_fea.remove(label)
data_train.isnull().sum()
data_train[numerical_fea].median()
data_train[category_fea].mode()
data_train['employmentLength'].value_counts(dropna=False)
#把所有缺失值替换为指定的值0
data_train = data_train.fillna(0)
#向用缺失值上面的值替换缺失值
data_train = data_train.fillna(axis=0,method='ffill')
#纵向用缺失值下面的值替换缺失值,且设置最多只填充两个连续的缺失值
data_train = data_train.fillna(axis=0,method='bfill',limit=2)
#按照中位数填充数值型特征
data_train[numerical_fea] = data_train[numerical_fea].fillna(data_train[numerical_fea].median())
data_test_a[numerical_fea] = data_test_a[numerical_fea].fillna(data_train[numerical_fea].median())
#按照众数填充类别型特征
data_train[category_fea] = data_train[category_fea].fillna(data_train[category_fea].mode())
data_test_a[category_fea] = data_test_a[category_fea].fillna(data_train[category_fea].mode())
- 当你发现异常值后,一定要先分清是什么原因导致的异常值,然后再考虑如何处理。首先,如果这一异常值并不代表一种规律性的,而是极其偶然的现象,或者说你并不想研究这种偶然的现象,这时可以将其删除。其次,如果异常值存在且代表了一种真实存在的现象,那就不能随便删除。在现有的欺诈场景中很多时候欺诈数据本身相对于正常数据勒说就是异常的,我们要把这些异常点纳入,重新拟合模型,研究其规律。能用监督的用监督模型,不能用的还可以考虑用异常检测的算法来做。
- 注意test的数据不能删
- 均方差
在统计学中,如果一个数据分布近似正态,那么大约 68% 的数据值会在均值的一个标准差范围内,大约 95% 会在两个标准差范围内,大约 99.7% 会在三个标准差范围内。
def find_outliers_by_3segama(data,fea):
data_std = np.std(data[fea])
data_mean = np.mean(data[fea])
outliers_cut_off = data_std * 3
lower_rule = data_mean - outliers_cut_off
upper_rule = data_mean + outliers_cut_off
data[fea+'_outliers'] = data[fea].apply(lambda x:str('异常值') if x > upper_rule or x < lower_rule else '正常值')
return data
data_train = data_train.copy()
for fea in numerical_fea:
data_train = find_outliers_by_3segama(data_train,fea)
print(data_train[fea+'_outliers'].value_counts())
print(data_train.groupby(fea+'_outliers')['isDefault'].sum())
print('*'*10)
#删除异常值
for fea in numerical_fea:
data_train = data_train[data_train[fea+'_outliers']=='正常值']
data_train = data_train.reset_index(drop=True)
我也不会了希望有大佬能指点迷津
在task03的最后,作者简单写了lightgbm、xgboost和catboost的模型训练函数,第一个lgb_model()还是很顺利能出结果的,但是不知道有没有小伙伴跟我一样,在运行xgb_model()时遇到了这样的问题,
在运行cat_model()时遇到了这样的问题,
反正我是遇到了,所幸出现的问题还在我的认知范围内,于是试着把这个bug改过来。同时借着这次机会把自己对遇到bug时的应对经验分享一下,算是贡献自己微薄的知识吧。顺便小声嘀咕原来大佬也犯这种错误
model = clf.train(params, train_matrix, num_boost_round=50000, evals=watchlist, verbose_eval=200, early_stopping_rounds=200)
val_pred = model.predict(valid_matrix, ntree_limit=model.best_ntree_limit)
test_pred = model.predict(test_x , ntree_limit=model.best_ntree_limit)
train_matrix = clf.DMatrix(trn_x , label=trn_y)
valid_matrix = clf.DMatrix(val_x , label=val_y)
test_matrix = clf.DMatrix(test_x)#这里没有test_y,所以不加label参数
.
.
.
#同时把下面的test_x换成test_matrix
test_pred = model.predict(test_matrix , ntree_limit=model.best_ntree_limit)
xgb_train, xgb_test = xgb_model(x_train, y_train, x_test)
(模型训练时间较长)等待30分钟,一般情况下是可以运行通并跑出结果的
def func():
print('龙洞的蚊子也太多了吧,昨天晚上在蚊帐里面打死6只蚊子')
a,b=func()
到此问题就解决了。当然了,如果按着步骤来最后还是没改对,希望能在评论下面说一声,可以看看我还有哪里出现了疏漏
我们模型训练出来的lgb_test、xgb_test、cat_test,如果不严格要求,其实已经可以算是一个比赛结果,具备参赛资格,说人话就是可以试着提交上去看看得分了。但是提交的话需要参照官方给出的格式,在sample_submit.csv文件中给到的格式是这样的
我们的结果显然还不能够,得把它们转换成上面的格式并生成csv文件,出于好奇心理,我写了一段函数将结果转换成对应格式的csv文件,想看看能得到怎样的分数
def to_csv(test,name):
test_copy=test.copy()
test_copy=test_copy.tolist()
n=0
for i in range(800000,1000000):
test_copy.insert(n,i)
n+=2
test=np.array(test_copy)
test=test.reshape(-1,2)
df=pd.DataFrame(test,columns=['id','isDefault'])
df.to_csv(f'{name}_test.csv',index=False)
其中,参数test=模型训练出的结果,参数name=模型名字,例:
to_csv(cat_test,'cat')
然后就可以提交到天池了。