天池工业AI大赛-智能制造质量预测(Baseline)

/ Algorithm / No comments yet / 1127 browses

背景

昨天写毕业论文写得有点烦,所以去天池看了看有没有什么有意思的比赛,这个比赛貌似是人最多的,所以点进去了看看,然后花了一晚上做了个baseline,然后水了这篇博客,可能没有什么帮助,但还是希望能够给诸位一点点小启发吧,哈哈

这是我做的简单的baseline

赛题介绍

评价方法为MSE,我做的baseline为

2018-01-04 15:00:22 0.04961

排行榜其他大神目前成绩最好为0.03721

数据简介

出题方提供了500条训练集,每条样本为8000+维度的特征,连续性label,测试集有100条样本。归为回归类数据挖掘。

My Solution

  1. 数据预处理
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
#读取数据
train = pd.read_excel("/home/hadoop/2018/train.xlsx")
testA = pd.read_excel("/home/hadoop/2018/testA.xlsx")
train_test = pd.concat([train, testA], axis=0, ignore_index=True)
# 对dataFrame进行数据类型转换函数,缺失值填0,数值型转换为float,str非数值不转换
def func(x):
    try:
        return float(x)
    except:
        if x == None:
            return 0
        else:
            return x
# 获取标签
label = train_test["Y"][:500]
train_test = train_test.fillna(0)
train_test.applymap(func)
feat_columns = list(train_test.columns.values)
feat_columns.remove("ID")
feat_columns.remove("Y")
# data 为除去ID和label后所有的特征
data = train_test[feat_columns]

特征处理

# 类别型特征
cate_columns = data.select_dtypes(include=["object"]).columns
# 数值型特征
num_columns = data.select_dtypes(exclude=["object"]).columns
print("cate feat num: ",len(cate_columns),"num feat num: ", len(num_columns))
feat_cate = data[cate_columns]
feat_nume = data[num_columns]
# 类别型特征独热编码
feat_cate_dummies = pd.get_dummies(feat_cate)
# 数值型特征最值归一化
feat_nume_scale = pd.DataFrame(MinMaxScaler().fit_transform(feat_nume))
# 拼接上述两种特征
feat_all = pd.concat([feat_nume_scale, feat_cate_dummies], axis=1)

降维

这里我们利用简单的自编码器进行降维,这里我把维度降到100维,validation_loss为0.33,效果很一般,感觉对自编器做些工作还能往下降,这个自编码器利用了test里的特征数据(这里之所以用了自编码器是因为这是我前几天刚看到的东西,恰好能用用试试效果怎么样,哈哈)

import keras
from keras.layers import Dense,Activation,Input
from keras.models import Sequential,Model
# 数据切分
x_train, x_test, y_train, y_test = train_test_split(feat_all, feat_all, test_size=0.2, random_state=42)
# 自编码维度
encoding_dim = 100  
# 输入层
input_ = Input(shape=(8051,))
# 编码层
encoded = Dense(encoding_dim, activation='relu')(input_)
# 解码层
decoded = Dense(8051, activation='sigmoid')(encoded)
# 自编码器模型
autoencoder = Model(input=input_, output=decoded)
autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy')
autoencoder.fit(x_train, 
                x_train,
                nb_epoch=500,
                batch_size=10,
                shuffle=True,
                validation_data=(x_test, x_test))

计算编码后的特征

# 根据上面我们训练的自编码器,截取其中编码部分定义为编码模型
encoder = Model(input=input_, output=encoded)
# 对特征进行编码降维
feat_dim_100 = encoder.predict(feat_all)

GBDT训练及预测

# 数据划分,训练集,验证集,测试集为后100条(测试集用来生成提交结果)
x_tr, x_te, y_tr, y_te = train_test_split(feat_dim_100[:500], label, test_size=0.2, random_state=42)
# GBDT模型
import numpy as np
from sklearn.ensemble import GradientBoostingRegressor
# 这里用的参数没有调过,都是随便取的,结果还有上升空间
gbdt=GradientBoostingRegressor(
      loss='ls'
    , learning_rate=0.01
    , n_estimators=50
    , subsample=1
    , min_samples_split=2
    , min_samples_leaf=1
    , max_depth=4
    , init=None
    , random_state=None
    , max_features=None
    , alpha=0.9
    , verbose=0
    , max_leaf_nodes=None
    , warm_start=False
    )
gbdt.fit(x_tr,y_tr)

验证GBDT模型

# 懒得找MSE的API,自己随便写了一个,反正只有500条不用管效率
def loss(list1, list2):
    import math
    _sum = 0
    for k, v in zip(list1, list2):
     _sum += math.pow(k-v, 2)
    return _sum / len(list1)
# 预测验证集label
label_test = gbdt.predict(x_te)
# 计算线下误差,线下误差0.04192
loss(label_test, y_te)

提交结果生成

线上得分为0.04961,线下得分为0.04192,感觉相差不是很大,哈哈

# 测试集特征为feat_all的后一百条
result = gbdt.predict(feat_dim_100[500:])
ret = pd.DataFrame()
ret["ID"] = testA["ID"]
ret["Y"] = result
ret.to_csv("/home/hadoop/2018/result.csv", index=False, header=False)

上面所有的参数都是临时设置的,都没有调过,这是一个很粗糙很粗糙很粗糙的baseline