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

DATAWHALE-数据挖掘竞赛入门-task4-建模调参

程序员文章站 2022-07-14 23:08:01
...

背景

在这次Datawhale的组队学习中,我们主要学习数据竞赛的相关知识,其中task4是有关于建模调参的知识。

建立模型

1.主要模型

       线性回归是一种被广泛应用的回归技术,也是机器学习里面最简单的一个模型,它有很多种推广形式,本质上它是一系列特征的线性组合,在二维空间中,你可以把它视作一条直线,在三维空间中可以视作是一个平面。

GBDT是一个集成模型,可以看做是很多个基模型的线性相加,其中的基模型就是CART回归树。

2.模型性能验证

  • 评价函数与目标函数
  • 交叉验证方法
  • 留一验证方法
  • 引入时间序列验证
  • 绘制学习率曲线
  • 绘制验证曲线

调参方法

  • 贪心调参方法
  • 网格调参方法

Grid Serach CSDN博客

  • 贝叶斯调参方法

贝叶斯调参CSDN博客

相关代码

代码的Notebooks链接 : 点击这里查看jupyter notebook

本章的学习手册由小雨姑娘编写,首先小雨写了一个优化内存占用的函数,主要是优化各种变量的数据类型。具体代码如下:

def reduce_mem_usage(df):
    """ iterate through all the columns of a dataframe and modify the data type
    to reduce memory usage.
    """
    start_mem = df.memory_usage().sum()
    print('Memory usage of dataframe is {:.2f} MB'.format(start_mem/(1024*1024)))
    for col in df.columns:
        col_type = df[col].dtype
        if col_type != object:
            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)
                elif c_min > np.iinfo(np.int32).min and c_max < np.iinfo(np.int32).max:
                    df[col] = df[col].astype(np.int32)
                elif c_min > np.iinfo(np.int64).min and c_max < np.iinfo(np.int64).max:
                    df[col] = df[col].astype(np.int64)
            elif str(col_type)[:5] == 'float':
                if c_min > np.finfo(np.float16).min and c_max < np.finfo(np.float16).max:
                    df[col] = df[col].astype(np.float16)
                elif c_min > np.finfo(np.float32).min and c_max < np.finfo(np.float32).max:
                    df[col] = df[col].astype(np.float32)
                else:
                    df[col] = df[col].astype(np.float64)
        else:
            df[col] = df[col].astype('category')
    end_mem = df.memory_usage().sum()
    print('Memory usage after optimization is: {:.2f} MB'.format(end_mem/(1024*1024)))
    print('Decreased by {:.1f}%'.format(100 * (start_mem - end_mem) / start_mem))
    return df

用这个函数处理一下这次二手车的训练集,缩小了72.6%的内存占用,效果不错。

Memory usage of dataframe is 35.48 MB
Memory usage after optimization is: 9.73 MB
Decreased by 72.6%

接着,小雨建立了一个连续型变量列表,剔除了一些离散变量,具体剔除依据不太清楚,我感觉还有一些变量也是离散的,这个还要再研究一下。

continuous_feature_names = [x for x in train.columns if x not in ['price','brand','model','brand']]

然后,小雨简单做了做数据清洗(精细的话还得用特征工程的知识,参考上一章),并最终确定了用于训练的训练集与标签。

sample_feature = train.dropna().replace('-', 0).reset_index(drop=True) # dropna 只要有一个null就删除,how参数可以设置any默认或all
sample_feature['notRepairedDamage'] = sample_feature['notRepairedDamage'].astype(np.float32)
train_data = sample_feature[continuous_feature_names + ['price']]
train_X = train_data[continuous_feature_names]
train_y = train_data['price']

做好上述准备后,可以用一个最基本的模型——线型回归模型来试一试效果。这里调用了sklearn的库函数进行拟合。

from sklearn.linear_model import LinearRegression
model = LinearRegression(normalize=True)
model = model.fit(train_X, train_y)

通过model.intercept_可以查看截距,而model.coef_可以查看各个变量前的权重(斜率)。

但是直接这么回归效果并不好,它的MAE高达2600。因此小雨通过研究预测值的分布推断出训练前最好对预测值进行log变换,“因为预测值是长尾分布,很多模型都假设数据误差项符合正态分布,而长尾分布的数据违背了这一假设”。在这里我有个疑问,数据误差项的分布与预测值分布之间具体有什么联系,我不太清楚,还需要研究一下。

那么如果按照小雨所说作log变换后

train_y_ln = np.log(train_y + 1)

训练一下

model = model.fit(train_X, train_y_ln)

最后得出来的MAE是987.6,可见降低了很多。然后我抱着试一试的态度,向天池提交了一下这个模型的预测结果,最后得出来的MAE是974,更训练集差别也不多。

总结

由于时间原因,目前这篇文章代码部分只展示了一部分成果,还待进一步更新。

 

相关标签: Datawhale