零基础入门数据挖掘 - 二手车交易价格预测学习笔记

描述
销售ID交易ID,唯一编码
名字汽车交易名称,已脱敏
regDate(注册日期)汽车注册日期,例如20160101,2016年01月01日
车型编码,已脱敏
品牌汽车品牌,已脱敏
bodyType车身类型:豪华轿车:0,微型车:1,厢型车:2,大巴车:3,敞篷车:4,双门汽车:5,商务车:6,搅拌车:7
燃料类型燃油类型:汽油:0,柴油:1,液化石油气:2,天然气:3,混合动力:4,其他:5,电动:6
变速器变速箱:手动:0,自动:1
权力发动机功率:范围 [ 0, 600 ]
公里汽车已行驶公里,单位万km
notRepaired损坏汽车有尚未修复的损坏:是:0,否:1
regionCode地区编码,已脱敏
卖方销售方:个体:0,非个体:1
offerType报价类型:提供:0,请求:1
creatDate汽车上线时间,即开始售卖时间
价格二手车交易价格(预测目标)
v系列特征匿名特征,包含v0-14在内15个匿名特征

一、导入数据

import pandas as pd
import numpy as np
from torch import nn, optim
import torch
import matplotlib.pyplot as plt
config = {
    #超参数
    'epoch': 10, #训练轮数
    'batch_size': 512, 
    'learning_rate': 8e-3, #学习率
    'device': 'cuda',
    "num_cols": ['regDate', 'creatDate', 'power', 'kilometer', 'v_0', 'v_1', 'v_2', 'v_3', 'v_4', 'v_5', 'v_6', 'v_7', 'v_8', 'v_9', 'v_10',
                 'v_11', 'v_12', 'v_13', 'v_14'],
    "cate_cols": ['model', 'brand', 'bodyType', 'fuelType', 'gearbox', 'seller', 'notRepairedDamage']
}
test_data = pd.read_csv('/gemini/data-1/used_car_testB_20200421.csv', sep=' ')
test_data.shape

(50000, 30)

# 导入数据
train_data = pd.read_csv('/gemini/data-1/used_car_train_20200313.csv', sep=' ')
train_data.shape

(150000, 31)

二、数据处理

1、 合并数据
data = pd.concat([train_data, test_data])
data.shape
/opt/conda/lib/python3.6/site-packages/ipykernel_launcher.py:2: FutureWarning: Sorting because non-concatenation axis is not aligned. A future version
of pandas will change to not sort by default.

To accept the future behavior, pass 'sort=False'.

To retain the current behavior and silence the warning, pass 'sort=True'.

  

(200000, 31)
2、定义One-Hot编码函数

one-hot编码:每个唯一的分类值都被赋予一个唯一的二进制向量,也被称为‘独热’向量,因为在这个向量中,只有一个位置的元素是1(表示该类别的存在),其余所有位置的元素都是0

如, 猫,狗,鸟三分类中,猫为[1,0,0] 狗为[0,1,0] 鸟为[0,0,1]

def oneHotEncode(df, colNames):
    for col in colNames:
        dummies = pd.get_dummies(df[col], prefix=col)
        df = pd.concat([df, dummies],axis=1)
        df.drop([col], axis=1, inplace=True)
    return df
data.columns
Index(['SaleID', 'bodyType', 'brand', 'creatDate', 'fuelType', 'gearbox',
       'kilometer', 'model', 'name', 'notRepairedDamage', 'offerType', 'power',
       'price', 'regDate', 'regionCode', 'seller', 'v_0', 'v_1', 'v_10',
       'v_11', 'v_12', 'v_13', 'v_14', 'v_2', 'v_3', 'v_4', 'v_5', 'v_6',
       'v_7', 'v_8', 'v_9'],
      dtype='object')
data = data.replace('-', '-1')
data.notRepairedDamage = data.notRepairedDamage.astype('float32')
data.loc[data['power']>600,'power'] = 600
3、深度学习-梯度下降

 y =(x-3)**2+1 ,求y的最小值

给个任意初始值x,如 x = -1,我们想要找到x = 3,如何做呢。根据导数dy/dx,我们可以对x迭代。x = x - dy/dx ,由于我们 dy/dx 计算的值比较大,就相当于我们每次迭代 x 一步跨的很长。所以我们设定一个参数 lr (learning rate)也就是我们所说的"学习率"或者"步长"。

  x = x-lr*dy/dx 
                        
(原文链接:https://blog.csdn.net/qq_49560248/article/details/123918044)

4、特征缩放(归一化)


使用原因:

使用单一指标对某事物进行评价并不合理,因此需要多指标综合评价方法。多指标综合评价方法,就是把描述某事物不同方面的多个指标综合起来得到一个综合指标,并通过它评价、比较该事物。 
由于性质不同,不同评价指标通常具有不同的量纲和数量级。当各指标相差很大时,如果直接使用原始指标值计算综合指标,就会突出数值较大的指标在分析中的作用、削弱数值较小的指标在分析中的作用。 
为消除各评价指标间量纲和数量级的差异、保证结果的可靠性,就需要对各指标的原始数据进行特征缩放(也有数据标准化、数据归一化的说法,但这些叫法不准确,所以不推荐). 
由于量纲和数量级不同,所以需要特征缩放。特征缩放可以显著提升部分机器学习算法的性能,但它对部分算法没有帮助。 
不使用特征缩放的缺点:
假如特征x1的数值是100左右,特征x2的数值是1左右,方程为y=w1x1 + w2x2 + b,那w1对y 
的影响就更大,对Loss的影响也更大,损失函数关于w1的梯度也更大,而损函教关于u2的梯度却
很小,因此两个特征就不能使用相同的学习率。 
不进行特征缩放的话,Error Surface就是一个椭圆,梯度下降时不一定是朝着最优点(圆心)速度
就慢。 
如果进行了特征缩放,Error Surface会尽可能趋近于圆,因此梯度下降时会一直朝着最优点(圆
心),所以速度快。 
特征缩放优点
提高模型的数值稳定性
缩放后,输入的x会变得较小,X较小会带来较小梯度

# 处理离散数据
for col in config['cate_cols']:
    data[col] = data[col].fillna('-1')
data = oneHotEncode(data, config['cate_cols'])

# 处理连续数据
for col in config['num_cols']:
    data[col] = data[col].fillna(0)
    data[col] = (data[col]-data[col].min()) / (data[col].max()-data[col].min())

# 处理(可能)无关数据 
data.drop(['name', 'regionCode'], axis=1, inplace=True)

data.columns
5、删除分离
Index(['SaleID', 'creatDate', 'kilometer', 'offerType', 'power', 'price',
       'regDate', 'v_0', 'v_1', 'v_10',
       ...
       'fuelType_6.0', 'fuelType_-1', 'gearbox_0.0', 'gearbox_1.0',
       'gearbox_-1', 'seller_0', 'seller_1', 'notRepairedDamage_-1.0',
       'notRepairedDamage_0.0', 'notRepairedDamage_1.0'],
      dtype='object', length=336)

# 暂存处理后的test数据集
test_data = data[pd.isna(data.price)]
test_data.to_csv('./one_hot_testB.csv')

# 删除test数据(price is nan)
data.reset_index(inplace=True)
train_data = data
train_data = train_data.drop(data[pd.isna(data.price)].index)
train_data.shape

(150000, 337)

# 删除ID
train_data.drop(['SaleID'], axis=1, inplace=True)
# 打乱
train_data = train_data.sample(frac=1)

train_data.shape
Out [38]:
(150000, 336)

# 分离目标
train_target = train_data['price']
train_data.drop(['price', 'index'], axis=1, inplace=True)

# 分离出验证集,用于观察拟合情况
validation_data = train_data[:10000]
train_data = train_data[10000:]
validation_target = train_target[:10000]
train_target = train_target[10000:]

validation_data.shape, train_data.shape, validation_target.shape, train_target.shape

((10000, 334), (140000, 334), (10000,), (140000,))

train_data.columns

Index(['creatDate', 'kilometer', 'offerType', 'power', 'regDate', 'v_0', 'v_1',
       'v_10', 'v_11', 'v_12',
       ...
       'fuelType_6.0', 'fuelType_-1', 'gearbox_0.0', 'gearbox_1.0',
       'gearbox_-1', 'seller_0', 'seller_1', 'notRepairedDamage_-1.0',
       'notRepairedDamage_0.0', 'notRepairedDamage_1.0'],
      dtype='object', length=334)

三、训练

1、训练集

更新参数

class Network(nn.Module):
    def __init__(self, in_dim, hidden_1, hidden_2, hidden_3, hidden_4):
        super().__init__()
        self.layers = nn.Sequential(
            nn.Linear(in_dim, hidden_1),
            nn.BatchNorm1d(hidden_1),
            nn.ReLU(),
            nn.Linear(hidden_1, hidden_2),
            nn.BatchNorm1d(hidden_2),
            nn.ReLU(),
            nn.Linear(hidden_2, hidden_3),
            nn.BatchNorm1d(hidden_3),
            nn.ReLU(),
            nn.Linear(hidden_3, hidden_4),
            nn.BatchNorm1d(hidden_4),
            nn.ReLU(),
            nn.Linear(hidden_4, 1)
        )

    def forward(self, x):
        y = self.layers(x)
        return y
2、验证集

选择训练出的参数中合适的

mae_list = []

for epoch in range(config['epoch']):
    losses = []
    model.train()
    for i in range(0, train_num, config['batch_size']):
        end = i + config['batch_size']
        if i + config['batch_size'] > train_num-1:
            end = train_num-1
        mini_batch = train_features[i: end]
        mini_batch_label = train_labels[i: end]
        pred = model(mini_batch)
        pred = pred.squeeze()
        loss = criterion(pred, mini_batch_label)

        if torch.isnan(loss):
            break
        mae = torch.abs(mini_batch_label-pred).sum()/(end-i)
        losses.append(mae.item())
        
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
    
    model.eval()
    pred = model(validation_features)
    validation_mae = torch.abs(validation_labels-pred.squeeze()).sum().item()/validation_num
    
    mae_list.append((sum(losses)/len(losses), validation_mae))
        
    print(f"epoch:{epoch + 1} MAE: {sum(losses)/len(losses)}, Validation_MAE: {validation_mae}")
    torch.save(model, 'model.pth')
3、测试集

测试性能

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值