欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

第一次参加DC比赛总结

程序员文章站 2022-05-17 08:25:32
...

第一次参加DC比赛,选择一个不太难的“游戏玩家付费金额预测大赛”进行,虽说看了各种’top 1%’、’top 10%’、’top 5%’等文章,成绩依然还是不理想。总结原因发现还是在对数据的了解和特征工程技巧上没有下足功夫或者没有足够的经验,下面就细节问题和环节作简要总结。

对于数据的了解

数据的第一映像非常重要,决定了下一步数据处理和特征工程的方向,所以一定要详细充分的查看数据后再下手。
熟悉数据分为两步:
1. 数据形态(均值、最值、分布等),数据某些特征的有哪些有意思的信息(时间、坐标)
2. 数据有哪些特征(高维度、稀疏),是否需要预处理(nan、inf、离群点)
这里有个浅显的例子,适合初学者入门:

【半程彩蛋】选手分享,思路解答!

感兴趣的特征都有哪些信息,几个特征放一起能够发现什么,特征之间有无关联,最好能画张图,更加清晰直观些。这些都是需要在了解数据时有一个初步分认识。

特征工程的技巧

对于时间特征的处理技巧:

  1. 熟悉数据类型转换
    float转datatime,datatime转string,string转float
  2. 特征切片,一转多

创建特征常用方法小结

  1. 经纬度坐标转极坐标(以某一点为圆心)
  2. 统计某一特征在参考下的数量,作为新特征。以‘>某阈值’得到布尔型数据,再用values_counts()合成新特征。
  3. 特征之间通过运算得到新的特征,比如资源获取量除以在线时长得到单位时间获取速率。在特征作除法容易产生NAN\INF,要注意作筛选:
data['pve_win_percent']=data.apply(lambda x:x['pve_win_count']/x['pve_lanch_count'] if x['pve_lanch_count']!=0 else 0, axis=1)

特征选择

利用模型自带的feature_importance_,写出一个特征选择函数:

#alg:模型,columns:特征集合
def select_important_features(alg,columns): 
    importances=zip(map(lambda x: round(x, 4), alg.feature_importances_), columns)
    importance=[]
    sum=0
    for i in importances:
        if i[0]>0.008:
            importance.append(i[1]) 
            sum=sum+i[0]
    print("Num : %f | Sum: %3f" % (len(importance), sum))
    return importance
importance=select_important_features(rfr,x_train.columns)

利用r2找出各个特征与自变量y值相关性大小

# 模型挑选随机森林,参数默认
rfr=RandomForestRegressor() 
#将特征按评分排序,存入scores中
scores = []
for i in range(x_train.shape[1]):#分别让每个特征与响应变量做模型分析并得到误差率
    #R2_score 
    score = cross_val_score(rfr, x_train.values[:, i:i+1], y_train, scoring="r2",cv=ShuffleSplit(len(x_train), 3, .3))
    scores.append((round(np.mean(score), 3), x_train.columns[i]))
print(sorted(scores, reverse=True))#对每个特征的分数排序

关于特征选择,方法还有很多,这里有比较全面的总结:
结合Scikit-learn介绍几种常用的特征选择方法

模型的评价指标

模型按照分类和回归不同,评价指标不同。
分类:混合矩阵、f1_score
回归:rmse、rmae、r2_score
sklearn库里有专门计算评价指标的函数:
from sklearn.metrics import r2_score, mean_squared_error, mean_absolute_error用法也很简单,就是将预测值和真实值两个数组作为参数传入函数中,就能得到对应的指标值。

针对数据选择模型

稀疏数据——稀疏模型Lasso

线性模型试水:high bias,low variance

参数解释: alpha:正则化强度; 必须是正浮点数

  1. 套索(适合稀疏数据集)

Lasso:使用结构风险最小化=损失函数(平方损失)+正则化(L1范数)

alpha在调参时,可以使用LassoCV尝试尽可能多的值,因为在其他条件不变的情况下,alpha与loss变化是一条凹曲线,存在一个极值点。如图:

第一次参加DC比赛总结
缺点:
L1正则化像非正则化线性模型一样也是不稳定的,如果特征集合中具有相关联的特征,当数据发生细微变化时也有可能导致很大的模型差异。

  1. 岭回归:Ridge

L2惩罚项中系数是二次方的,L2正则化会让系数的取值变得平均。
对于关联特征,这意味着他们能够获得更相近的对应系数,对于特征选择来说一种稳定的模型,不像L1正则化那样,系数会因为细微的数据变化而波动。
L2正则化对于特征理解来说更加有用:表示能力强的特征对应的系数是非零。

  1. 使用结构风险最小化=损失函数(平方损失)+正则化(L2范数)
  2. Ridge:固定阿尔法,求出最佳w,阿尔法与w的范数成反比
  3. RidgeCV:多个阿尔法,得出多个对应最佳的w,然后得到最佳的w及对应的阿尔法

带CV和不带CV

带CV的模型(留一交叉验证)形如RidgeCV、LassoCV,使用非常简单直观,但是之前一直不确定带CV为什么能调参,通过阅读发现,带CV的可以快速找到最佳参数,不像gridSearchCV那样可以同时调多个参数,但是速度上占优明显。

这里有一篇将CV训练过程可视化的文章:
优化岭回归参数alpha优化

随机森林试水

随机森林固有缺陷
1. 随机森林在解决回归问题时并没有像它在分类中表现的那么好,这是因为它并不能给出一个连续型的输出。当进行回归时,随机森林不能够作出超越训练集数据范围的预测,这可能导致在对某些还有特定噪声的数据进行建模时出现过度拟合。
2. 对于许多统计建模者来说,随机森林给人的感觉像是一个黑盒子——你几乎无法控制模型内部的运行,只能在不同的参数和随机种子之间进行尝试。

stacking最终要用到

先前多试验几种模型,其目的有三,一是熟悉模型,二来可以进一步加深对数据的理解,三是为最后的模型堆叠做准备工作。

stacking的基模型、目标模型的选择?
mlxtend库,stackingCVRegressor方法,调参时目标模型参数前加’meta-‘

工作环境比较

spyder的布局、使用方法习惯都是模仿的matlab,几乎继承了MATLAB的“工作空间”的功能所有优点:可以很方便地观察变量的值,可以开多个consoles同时执行。
Jupyternotebook嵌入了markdown\Raw NBconvert\Heading不同的编写文档类型,他的核心竞争力在于“文学编程”的思想。用之可以很方便、快捷地写一份说明文档,将说明文字、代码、图表、公式、结论都整合在一个文档中。
这次的比赛,我的工作环境是从notebook转到Spyder的,我觉得从生产效率的角度出发,Spyder要明显更胜一筹,用之一鼓作气的完成数据挖掘,一直使用编程思维而不用担心思维切换和跳转不适等问题。