Datawhale零基础入门数据挖掘-Task4建模调参
前提回顾
赛题以二手车市场为背景,要求选手预测二手汽车的交易价格,这是一个典型的回归问题。通过这道赛题来引导大家走进AI数据竞赛的世界,主要针对于于竞赛新人进行自我练习、自我提高。
“零基础入门数据挖掘 - 二手车交易价格预测”是阿里天池的一个入门比赛,这个比赛问题是一个回归问题,评价标准为平均绝对值误差——MAE(Mean Absolute Error)。
题目给出的测试集有15万条二手汽车信息,验证集有5万条。一条二手车信息中包含31项变量信息,其中15项匿名变量,其余16项变量(含价格变量)。实际上划分变量就是30项自变量(包含数字型变量、类别型变量、文本型变量和时间型变量),1项因变量(整数形式的二手车交易价格)。
经过了之前的数据分析和特征工程,整理了现有的一波特征,不包括已经做了log(1+x)处理的“price”。目前使用这些特征并做好筛选,线上可以<500。
有效变量名 | 描述 | 类型 |
---|---|---|
v系列特征 | 匿名特征,包含v0-14在内15个匿名特征 | 数字 |
power | 发动机功率 | 数字 |
power_ | 发动机功率(修正) | 数字 |
kilometer | 汽车已行驶公里,单位万km | 数字 |
i_price_j | 自行构造的特征(统计每个类别变量下各个target比例) i in [‘model’, ‘brand’, ‘regionCode’]; j in [‘max’, ‘median’, ‘min’, ‘std’, ‘average’] | 数字 |
used_time | 自行构造的特征(使用时间) | 数字 |
used_time_ | 自行构造的特征(使用时间修正) | 数字 |
交叉特征 | ‘model____in____brand____prop’,‘regionCode____in____brand____prop’ ‘brand____in____model____prop’,‘model____in____regionCode____prop’, ‘regionCode____in____model____prop’,‘brand____in____regionCode____prop’ | 数字 |
regYear | 自行构造的特征(出场年份) | 类别 |
city | 自行构造的特征(城市),这里暂时还是放进来了 | 类别 |
area | 自行构造的特征(类别),这里暂时还是放进来了 | 类别 |
name | 汽车交易名称,已脱敏 | 类别 |
model | 车型编码,已脱敏 | 类别 |
brand | 汽车品牌,已脱敏 | 类别 |
bodyType | 车身类型:豪华轿车:0,微型车:1,厢型车:2,大巴车:3,敞篷车:4,双门汽车:5,商务车:6,搅拌车:7 | 类别 |
fuelType | 燃油类型:汽油:0,柴油:1,液化石油气:2,天然气:3,混合动力:4,其他:5,电动:6 | 类别 |
gearbox | 变速箱:手动:0,自动:1 | 类别 |
notRepairedDamage | 汽车有尚未修复的损坏:是:0,否:1 | 类别 |
regionCode | 地区编码,已脱敏 | 类别 |
建模
建模就是建立模型,就是为了理解事物而对事物做出的一种抽象,是对事物的一种无歧义的书面描述。
建立系统模型的过程,又称模型化。建模是研究系统的重要手段和前提。凡是用模型描述系统的因果关系或相互关系的过程都属于建模。因描述的关系各异,所以实现这一过程的手段和方法也是多种多样的。可以通过对系统本身运动规律的分析,根据事物的机理来建模;也可以通过对系统的实验或统计数据的处理,并根据关于系统的已有的知识和经验来建模。还可以同时使用几种方法。
我所理解的建模包括了前面特征工程的内容又包括了算法的内容。而此次使用的是一个大佬们已经做好的集成的算法。
LightGBM
LightGBM是个快速的、分布式的、高性能的基于决策树算法的梯度提升框架。可用于排序、分类、回归以及很多其他的机器学习任务中。
lgb具体的背景和逻辑、算法实现等等有兴趣的话大家都可以去了解、学习。
Welcome to LightGBM’s documentation!
这里就不赘述了。只是向大家推荐这一个算法而已。在如何看待微软新开源的LightGBM?问题下,有大佬的出现
数据分析竞赛常用函数整理
列举了几个常用小方法
// 记录运行所耗时间
def timer(start_time=None):
if not start_time:
start_time = datetime.now()
return start_time
elif start_time:
thour, temp_sec = divmod(
(datetime.now() - start_time).total_seconds(), 3600)
tmin, tsec = divmod(temp_sec, 60)
print('\n Time taken: %i hours %i minutes and %s seconds.' % (thour, tmin, round(tsec, 2)))
// 降低数据文件的大小
def reduce_mem_usage(df, verbose=True):
numerics = ['int16', 'int32', 'int64', 'float16', 'float32', 'float64']
start_mem = df.memory_usage().sum() / 1024**2
for col in df.columns:
col_type = df[col].dtypes
if col_type in numerics:
c_min = df[col].min()
c_max = df[col].max()
if str(col_type)[:3] == 'int':
if c_min > np.iinfo(np.int8).min and c_max < np.iinfo(np.int8).max:
df[col] = df[col].astype(np.int8)
elif c_min > np.iinfo(np.int16).min and c_max < np.iinfo(np.int16).max:
df[col] = df[col].astype(np.int16)<