10万元奖金“智源工业检测赛”激战正酣!高分Baseline合辑带你入门智能制造

2020 年 3 月 6 日 PaperWeekly


百年德企博世放出真实独家生产场景脱敏数据,邀你为工业 4.0 制造练就 AI 大脑。


目前,由北京智源人工智能研究院联合博世和 biendata 共同发布的“INSPEC 工业大数据质量预测赛”(2019 年 12 月 — 2020 年 4 月)正在火热进行中,总奖金为 10 万元。
比赛发布了博世某系列产品近年来的质量检测相关数据,要求选手根据已有产品质检环节记录的相关参数,使用机器学习算法对正在测试的产品进行质量预测,提前判断次品,节省整体检测时间。 比赛和数据可于下方链接查看,或点击“阅读原文”,欢迎所有感兴趣的报名读者参赛
目前,赛事已接近半程,为帮助选手进一步提升模型预测结果,biendata 邀请的四名活跃选手: pinlan(2019 数字中国混泥土砼活塞故障预警冠军)、bestIteration(JData 亚军、2019 KDD Top 10)、sijinabc、hh_neuq 分享四个分数在 0.6 左右的 baseline ,希望可以为大家在数据探索、特征工程、模型选择、参数调优等方面提供参考和思路。

比赛地址:

https://www.biendata.com/competition/bosch/ 



1

Baseline 概览


(一) 选手 pinlan 首先根据题意将赛题归为二分类问题,在样本构造方面,该选手建议样本应和官方提供 validation 相似,并认为样本构造方法可能是上分关键。
在特征工程上,选手 pinlan: 1)针对产品实例 Product_ID 构造统计特征: 最值,均值; 2)对类别特征进行编码; 3)构思一些具有背景意义的特征; 4)提示工业数据一般暗含很多规则,一些数据探索分析可以帮助发现规则,有助于分数提升。
pinlan 采用 5 fold 划分数据集,并选用 LightGBM 模型。 该 Baseline 最终线上成绩为 0.6,具体代码实现欢迎访问以下页面查看或浏览下文。
https://biendata.com/models/category/4063/L_notebook/
(二)选手 bestIteration 首先分析了目标变量分布、缺失值比例、类别变量分布差异等,总结出两种建模思路: 1)构造产品实例(ID_F_PROCESS)的特征,预测其最终是否合格; 2)构造产品中检测步骤的特征,预测该检测步骤结果是否合格,再进一步得到对应产品实例最终是否合格。
关于特征工程,bestIteration 主要聚焦于对连续值的统计特征(如 RESULT_VALUE)、每个检测步骤中 RESULT_VALUE 的统计特征、对类别变量的 TFIDF 特征(如 ID_F_PARAMETER_S)。 该选手选用 LightGBM 模型,并使用 5 折交叉验证。 该 Baseline 最终线上成绩为 0.61+,具体代码实现欢迎以下访问页面查看。
https://biendata.com/models/category/4239/L_notebook/
(三)选手 sijinabc 经过对数据的理解,其分类模型将在以下几点假设的基础上建立: 1)对于产品检测的过程数据,不同检测步骤之间互不影响,因此认为检测数据不存在时间序列关系; 2)对于各检测序列中正常的检测数据,不同产品之间的数值差别可以体现产品的不同质量; 3)不同产品的检测序列长度、检测顺序、检测内容不同,模型需有较好的泛化性,注意防止过拟合。
其主要思路为:
1)简化数据表,减小数据维度;
2)建立训练集,其中包括将检测参数序列号(ID_F_PARAMETER_S )顺序排列作为特征名; 对应的数值型检测结果(RESULT_VALUE)或参数检测结果(PARAMETER_RESULT_STATE)作为模型特征; 产品实例的最终检测结果(PROCESS_RESULT_STATE)作为样本标签; 分别取前四个、前十个检测步骤的序列 ID(ID_F_PHASE_S)0~9 对应的检测参数序列及检测结果用于训练模型; 识别并删除异常数据。
3)建立二分类模型。 该 Baseline 最终线上成绩为 0.6,具体代码实现欢迎访问以下页面查看。
https://biendata.com/models/category/4224/L_notebook/
(四)选手 hh_neuq 首先读取 Excel 格式数据,将小文件合并成三个大文件,并转为 csv 格式文件存储。 然后对数据进行筛选,并提取特征,用 LightGBM 建模。 该选手认为,可以深入可视化,进而提取特征,并对模型进行调参。
该 Baseline 最终线上成绩为 0.57,具体代码实现欢迎访问以下页面查看。
https://biendata.com/models/category/4298/L_notebook/
2

Baseline 详情


pinlan 版 


本 baseline 线上成绩为 0.6。
1. 赛题引入与问题分析
本次比赛的任务为产品质量预测,所使用数据为“INSPEC 工业检测大数据“,其中包含博世某产品家族的工厂生产环节的检测参数,要求选手根据训练集中产品的相关数据(如子家族名称、检测流程、检测结果)建立和优化模型,并参照目标产品中已完工序的检测结果,预测最终产品检测的结果为合格或不合格。
赛题线上验证集已经由官方提取完毕,训练数据需要自行提取。 官方提供了以产品类型-子家族(TYPE_NUMBER-PRODUCTGROUP_NAME)命名的 excel 表格,每个表格下包含产品实例表,检测步骤表和步骤参数表三个表。
整体思路
1. 根据官方发布的题目,明确题目含义:参照目标产品中已完工序的检测结果,预测 "最终产品" 检测的结果为合格或不合格。
  • 根据题意,作者将题目定义为二分类问题;

  • 先建立 valid_4 模型,再建立 valid_11 模型,建模流程相同。
2. 训练样本构造,样本应和官方提供 validation 相似,这里样本构造方法可能是上分关键,这里提供本人样本构建方法(get_data 函数),以及部分思考。
  • 样本越多,效果越好;

  • 官方验证集未包含全部子家族以及产品类型,在提取训练集时是否删去官方验证集未包含的子家族;

  • 对于 validation_predict_4 而言,提取训练数据应包含产品实例前三步检测数据,这里进行了数据筛选,剔除了前三部已经检测出问题的产品。


3. 特征工程:
  • 针对产品实例 Product_ID 构造统计特征:最值,均值;

  • 对类别特征进行编码;

  • 构思一些具有背景意义的特征;

  • 工业数据一般暗含很多规则,一些 EDA 可以帮助发现规则,有助于分数提升。

4. 采用 5 fold 划分数据集。
5. lightgbm 模型,模型可自选:
  • 正负样本极不平衡;

  • 主要在于不平衡样本的处理,如使用采样,is_unbalance 参数;

  • 模型方面小数据集分类问题 Catboost 可能更具有优势。

6. 评价指标 F1。
  • F1 需要设置阈值,阈值对结果影响很大,概率、排序或者搜索算法等都可以;

  • F1 不单考虑某一类样本的准确性,需要正负样本预测准确性都高。

7. 划重点:
  • 训练样本构造以及筛选方式,十分重要;

  • 特征工程。

2. 数据提取与探索性分析


import numpy as np
import pandas as pd
import gc
import os
import math
import lightgbm as lgb
from sklearn.metrics import f1_score,accuracy_score,roc_auc_score
from sklearn.model_selection import StratifiedKFold,KFold,train_test_split
import matplotlib.pyplot as plt
%matplotlib inline
import seaborn as sns
color = sns.color_palette()
sns.set_style("whitegrid")
import warnings
warnings.filterwarnings('ignore')
path='./INSPEC_train/'
test_path='./INSPEC_validation/'
filename=os.listdir('./INSPEC_train/')
data_cols = ['Product_ID', 'TYPE_NUMBER', 'PRODUCTGROUP_NAME', 'ID_F_PHASE','PHASE_RESULT_STATE', 'PHASE_NAME', 'ID_F_PHASE_S',
'RESULT_STRING','RESULT_VALUE', 'PARAMETER_RESULT_STATE', 'LOWER_LIMIT', 'UPPER_LIMIT','AXIS', 'SIDE', 'ID_F_PARAMETER_S']


2.1 数据提取


2.1.1 数据组成
a)  产品实例表: 产品实例的 ID,产品实例的最终检测结果(1 为合格、2 为不合格),产品类型名,产品类型所在子家族。
b)  检测步骤表: 产品实例的 ID,检测步骤的 ID,检测步骤的结果,检测步骤的名称,检测步骤的序列 ID。
c)  步骤参数表: 检测步骤 ID,字符串类型检测结果(表示产品等级),数值型检测结果,该参数检测结果,数值型检测可供参考的上下限,产品的轴、产品的面,检测步骤的序列 ID,检测参数的序列号。
2.1.2 对单个产品类型表格提取数据(get_data 函数)
a)  以每个产品类型 excel 为基础,包括产品实例表、检测步骤表和步骤参数表三个表。
b)  将三个数据表合并,对于验证集 4 提取检测步骤 ID_F_PHASE_S<3 的数据。
c)  将训练数据与验证数据比较,删除多余字段,使训练集与验证集具有相同形式。
2.1.3 将单个表提取数据合并为训练数据,其中 Product_ID 为样本编号,label 为标签 (get_train4)。

def get_data(path, data_cols, file_dir, num):
process = pd.read_excel(path+file_dir, sheet_name='Process_Table')
phase = pd.read_excel(path+file_dir, sheet_name='Phase_Table')
parameters = pd.read_excel(path+file_dir, sheet_name='Parameters_Table')
del parameters['ID_F_PHASE_S'];gc.collect()
df = process.merge(phase, on = 'ID_F_PROCESS', how = 'left')
df = df.merge(parameters, on = 'ID_F_PHASE', how = 'left')
df.rename(columns={'ID_F_PROCESS':'Product_ID','PROCESS_RESULT_STATE':'label'}, inplace=True)
df = df[data_cols+['label']]
bad_id = df[(df['ID_F_PHASE_S'] < num)&(df['PHASE_RESULT_STATE'] == 2)]['Product_ID'].unique()
df = df[~df['Product_ID'].isin(bad_id)]
df = df[df['ID_F_PHASE_S'] < num].reset_index(drop=True)
del process, phase, parameters;gc.collect()
return df

def get_train4(path, data_cols, filename):try:
train_4 = pd.read_csv('train_4.csv')
except:
train_4 = pd.DataFrame()
for dir_file in tqdm(filename):
temp_df = get_data(path, data_cols, dir_file, 3)
train_4 = train_4.append(temp_df)
train_4 = train_4.reset_index(drop=True)
train_4.to_csv('train_4.csv', index=False)
return train_4


2 .2 探索性分析
主要特征: 
1)检测方面: 产品的轴、产品的面;
2)检测结果: RESULT_STRING,RESULT_VALUE,LOWER_LIMIT,UPPER_LIMI;

3)其他描述性类别特征。

train_4 = get_train4(path, data_cols, filename)
train_4.head()
train_4.describe()
plt.rcParams['font.sans-serif']=['SimHei']
train_4.drop_duplicates(subset=['Product_ID'])['label'].value_counts().plot.pie(autopct='%1.1f%%',title = '正负样本比例')
<matplotlib.axes._subplots.AxesSubplot at 0x2375cb20f98>


train_4.nunique().plot.bar(title='类别个数')
<matplotlib.axes._subplots.AxesSubplot at 0x2375cbbfb70>



(train_4.isnull().sum()/len(train_4)).plot.bar(title='缺失值比例')
<matplotlib.axes._subplots.AxesSubplot at 0x2375cc6b9b0>


标签在检测参数的序列号 ID_F_PARAMETER_S 上面变化大,可以看出说明检测步骤越多,产品越紧密,制作难度越大。
train_4.groupby('label')['ID_F_PARAMETER_S'].agg(['min', 'max', 'median','mean', 'std']) 



train_4.groupby(['label'])['RESULT_VALUE'].describe()


正常来说,产品尺寸好坏要通过尺寸与公差上下极限关系来判断,因此可以考虑 RESULT_VALUE 和 LOWER_LIMIT 以及 UPPER_LIMIT 关系,构造特征:做差。可以看出距离上下限差值越大,产品越容易在制作时损坏。  
temp = train_4[['Product_ID','RESULT_VALUE', 'LOWER_LIMIT', 'UPPER_LIMIT','label']].dropna()
temp.head(10)


temp['差值'] = temp['RESULT_VALUE'] - temp['LOWER_LIMIT'] / (temp['UPPER_LIMIT'] - temp['LOWER_LIMIT'])
temp.groupby('label')['差值'].describe()


3

代码分析


import numpy as np
import pandas as pd
import gc
import os
import math
import lightgbm as lgb
from sklearn.metrics import f1_score,accuracy_score,roc_auc_score
from sklearn.model_selection import StratifiedKFold,KFold,train_test_split
path='./INSPEC_train/'
test_path='./INSPEC_validation/'
filename=os.listdir('./INSPEC_train/')
data_cols = ['Product_ID', 'TYPE_NUMBER', 'PRODUCTGROUP_NAME', 'ID_F_PHASE','PHASE_RESULT_STATE', 'PHASE_NAME', 'ID_F_PHASE_S',
'RESULT_STRING','RESULT_VALUE', 'PARAMETER_RESULT_STATE', 'LOWER_LIMIT', 'UPPER_LIMIT','AXIS', 'SIDE', 'ID_F_PARAMETER_S']

valid4 建模


#提取训练数据def get_data(path, data_cols, file_dir, num):
process = pd.read_excel(path+file_dir, sheet_name='Process_Table')
phase = pd.read_excel(path+file_dir, sheet_name='Phase_Table')
parameters = pd.read_excel(path+file_dir, sheet_name='Parameters_Table')
del parameters['ID_F_PHASE_S'];gc.collect()
df = process.merge(phase, on = 'ID_F_PROCESS', how = 'left')
df = df.merge(parameters, on = 'ID_F_PHASE', how = 'left')
df.rename(columns={'ID_F_PROCESS':'Product_ID','PROCESS_RESULT_STATE':'label'}, inplace=True)
df = df[data_cols+['label']]
bad_id = df[(df['ID_F_PHASE_S'] < num)&(df['PHASE_RESULT_STATE'] == 2)]['Product_ID'].unique()
df = df[~df['Product_ID'].isin(bad_id)]
df = df[df['ID_F_PHASE_S'] < num].reset_index(drop=True)
del process, phase, parameters;gc.collect()
return df
#合并数据def get_train4(path, data_cols, filename):try:
train_4 = pd.read_csv('train_4.csv')
except:
train_4 = pd.DataFrame()
for dir_file in tqdm(filename):
temp_df = get_data(path, data_cols, dir_file, 3)
train_4 = train_4.append(temp_df)
train_4 = train_4.reset_index(drop=True)
train_4.to_csv('train_4.csv', index=False)
return train_4
#构造统计特征def make_feature(data,aggs,name,data_id):
agg_df = data.groupby(data_id).agg(aggs)
agg_df.columns = agg_df.columns = ['_'.join(col).strip()+name for col in agg_df.columns.values]
agg_df.reset_index(drop=False, inplace=True)
return agg_df
#产品实例统计特征def get_4_fe(data,cate_cols):
dd_cols = ['PHASE_RESULT_STATE', 'RESULT_STRING','PARAMETER_RESULT_STATE']
data.drop(columns=dd_cols, inplace=True)
data['ID_F_PHASE_S'] = data['ID_F_PHASE_S'].astype('int8')
df = data[['Product_ID', 'label'] + cate_cols].drop_duplicates()

aggs = {}
for i in ['RESULT_VALUE']:
aggs[i] = ['min', 'max', 'mean', 'std', 'median']
for i in ['PHASE_NAME', 'AXIS']:
aggs[i] = ['nunique']
aggs['ID_F_PARAMETER_S'] = ['max', 'std', 'mean', 'median', 'count']
temp = make_feature(data, aggs, "_product", 'Product_ID')
df = df.merge(temp, on = 'Product_ID', how='left')
return df
#根据数值检测结果上下限构造统计def get_limit_4(data,df):
temp = data[['Product_ID','RESULT_VALUE', 'LOWER_LIMIT', 'UPPER_LIMIT']].dropna()
temp['差值'] = temp['RESULT_VALUE'] - temp['LOWER_LIMIT'] / (temp['UPPER_LIMIT'] - temp['LOWER_LIMIT'])
aggs = {}
aggs['差值'] = ['min', 'max', 'mean']
temp_df = make_feature(temp, aggs, "_limit", 'Product_ID')
df = df.merge(temp_df, on = 'Product_ID', how='left')
return df
#目标编码def get_target_mean_4(df, cate_cols):for i in cate_cols:
df[f'{i}_label_mean'] = df.groupby(i)['label'].transform('mean')
return df
#建模数据def get_training_data(df, name):
train_4 = df[~df['label'].isnull()].reset_index(drop=True)
test_4 = df[df['label'].isnull()].reset_index(drop=True)

col = [i for i in train_4.columns if i notin ['Product_ID', 'label']]
X_train = train_4[col]
y_train = (train_4['label']-1).astype(int)
X_test = test_4[col]
sub = test_4[['Product_ID']].copy()
print('{} train shape {} and test shape {}'.format(name, X_train.shape, X_test.shape))
return X_train, y_train, X_test, sub


1. 提取数据


train_4 = get_train4(path, data_cols, filename)
test_4 = pd.read_csv(test_path + 'validation_predict_4.csv')
train_4 = train_4[train_4['PRODUCTGROUP_NAME'].isin(test_4['PRODUCTGROUP_NAME'].unique())]
data_4 = train_4.append(test_4).reset_index(drop=True)
data_4.loc[data_4['AXIS'] == -9.223372036854776e+18, 'AXIS'] = np.nan
print('val_4 train sample {} and test sample {}'.format(train_4['Product_ID'].nunique(), test_4['Product_ID'].nunique()))


val_4 train sample 16441 and test sample 3721 


2. 特征工程


cate_cols = ['TYPE_NUMBER', 'PRODUCTGROUP_NAME']
df4 = get_4_fe(data_4,cate_cols)
df4 = get_limit_4(data_4,df4)
df4 = get_target_mean_4(df4,cate_cols)
df4['TYPE_NUMBER'] = df4['TYPE_NUMBER'].astype('category')
df4['PRODUCTGROUP_NAME'] = df4['PRODUCTGROUP_NAME'].astype('category')
#构建标签
X_train, y_train, X_test, sub1 = get_training_data(df4, 'val_4')

val_4 train shape (16441, 19) and test shape (3721, 19) 


3. 模型训练


lgb 自定义评测 f1 评测:


def lgb_f1_score(y_hat, data):
y_true = data.get_label()
y_hat = np.round(y_hat)
return'f1', f1_score(y_true, y_hat), True

五折划分数据,lgb 参数设置:


K = 5
seed = 2020
skf = StratifiedKFold(n_splits=K, shuffle=True, random_state=seed)
lgb_params = {
'boosting_type': 'gbdt',
'objective': 'binary',
'metric': 'None',
'num_leaves': 63,
'subsample': 0.8,
'colsample_bytree': 0.8,
'learning_rate': 0.05,
'lambda_l2':2,
'nthread': -1,
'silent': True
}
f1_scores = []
oof = np.zeros(len(X_train))
predictions = np.zeros(len(X_test))
feature_importance_df = pd.DataFrame()

for i, (train_index, val_index) in enumerate(skf.split(X_train,y_train)):
print("fold{}".format(i))
X_tr, X_val = X_train.iloc[train_index], X_train.iloc[val_index]
y_tr, y_val = y_train.iloc[train_index], y_train.iloc[val_index]

lgb_train = lgb.Dataset(X_tr,y_tr)
lgb_val = lgb.Dataset(X_val,y_val)
num_round = 3000
clf = lgb.train(lgb_params, lgb_train, num_round, valid_sets = [lgb_train, lgb_val], feval=lgb_f1_score,
categorical_feature=['TYPE_NUMBER', 'PRODUCTGROUP_NAME'],
verbose_eval=100, early_stopping_rounds = 100)
oof[val_index] = clf.predict(X_val, num_iteration=clf.best_iteration)
pred = clf.predict(X_val, num_iteration=clf.best_iteration)
sc = f1_score(y_val, np.round(pred))
f1_scores.append(sc)
print(f'fold{i} f1 score = ',sc)
print('best iteration = ',clf.best_iteration)
fold_importance_df = pd.DataFrame()
fold_importance_df["Feature"] = clf.feature_name()
fold_importance_df["importance"] = clf.feature_importance()
fold_importance_df["fold"] = i + 1
feature_importance_df = pd.concat([feature_importance_df, fold_importance_df], axis=0)
predictions += clf.predict(X_test, num_iteration=clf.best_iteration) / skf.n_splits
print('val_4 训练f1均值: {},波动: {}.'.format(np.mean(f1_scores), np.std(f1_scores)))
print('val_4 macro F1 score: ',f1_score(y_train, np.round(oof),average='macro'))

4. 特征重要性


plt.figure(figsize=(12,8))
sns.barplot(y='Feature', x='importance',data=feature_importance_df)
plt.title('val_4特征重要性')

Text (0.5,1,'val_4特征重要性')



5. 生成 val4 结果


sub1['label'] = predictions
sub1['label'] = sub1['label'].rank()
sub1['label'] = (sub1['label']>=sub1.shape[0] * 0.93).astype(int)
sub1['label'] = (sub1['label'] + 1).astype(int)
sub1.rename(columns={'Product_ID':'id'}, inplace=True)
print('val_4正负样本比例:\n', sub1['label'].value_counts())

val_4 正负样本比例:


1 3460 

2 261 

Name: label, dtype: int64 


这里结合数据和结果发现规则:结果中发现一个产品实例只有三条检测记录的正常样本居多,直接全部赋值 1,大概有百分位提升,但更换数据集后效果未知。


rule = test_4['Product_ID'].value_counts()
rule = rule[rule==3].index.values
sub1.loc[sub1['id'].isin(rule), 'label'] = 1
print('val_4正负样本比例:\n', sub1['label'].value_counts())


val_4 正负样本比例:


1 3609 

2 112 

Name: label, dtype: int64 


valid11 建模


#合并数据def get_train11(path, data_cols, filename):try:
train_11 = pd.read_csv('train_11.csv')
except:
train_11 = pd.DataFrame()
for dir_file in tqdm(filename):
temp_df = get_data(path, data_cols, dir_file, 10)
train_11 = train_11.append(temp_df)
train_11 = train_11.reset_index(drop=True)
train_11.to_csv('train_11.csv', index=False)
return train_11
#产品实例统计特征def get_11_fe(data_11, cate_cols):
dd_cols = ['PHASE_RESULT_STATE', 'PARAMETER_RESULT_STATE']
data_11.drop(columns=dd_cols, inplace=True)
data_11['ID_F_PHASE_S'] = data_11['ID_F_PHASE_S'].astype('int8')
df = data_11[['Product_ID', 'label'] + cate_cols].drop_duplicates()

aggs = {}
for i in ['RESULT_VALUE']:
aggs[i] = ['min', 'max', 'mean', 'std', 'median']
for i in ['PHASE_NAME', 'AXIS', 'SIDE', 'RESULT_STRING']:
aggs[i] = ['nunique']
aggs['ID_F_PARAMETER_S'] = ['max', 'std', 'mean', 'count']
temp = make_feature(data_11, aggs, "_product", 'Product_ID')
df = df.merge(temp, on = 'Product_ID', how='left')
return df
#根据数值检测检测上下限构造统计def get_limit_11(data,df):
temp = data[['Product_ID','RESULT_VALUE', 'LOWER_LIMIT', 'UPPER_LIMIT']].dropna()
temp['差值'] = temp['RESULT_VALUE'] - temp['LOWER_LIMIT'] / (temp['UPPER_LIMIT'] - temp['LOWER_LIMIT'])
aggs = {}
aggs['差值'] = ['min', 'max', 'mean']
temp_df = make_feature(temp, aggs, "_limit", 'Product_ID')
df = df.merge(temp_df, on = 'Product_ID', how='left')
return df
#类别特征def get_cate_11(data, df, cate_cols):
df['TYPE_NUMBER'] = df['TYPE_NUMBER'].astype('category')
df['PRODUCTGROUP_NAME'] = df['PRODUCTGROUP_NAME'].astype('category')

temp = pd.pivot_table(data=data, index='Product_ID',values='RESULT_VALUE',columns='SIDE',aggfunc='min').reset_index()
df = df.merge(temp, on = 'Product_ID', how='left')

temp = pd.pivot_table(data=data, index='Product_ID',values='RESULT_VALUE',columns='AXIS',aggfunc='min').reset_index()
df = df.merge(temp, on = 'Product_ID', how='left')

temp = pd.pivot_table(data=data, index='Product_ID',values='RESULT_VALUE',columns='RESULT_STRING',aggfunc='count').reset_index()
df = df.merge(temp, on = 'Product_ID', how='left')

for i in cate_cols:
df[f'{i}_label_mean'] = df.groupby(i)['label'].transform('mean')

return df

1. 提取数据


train_11 = get_train11(path, data_cols, filename)
test_11 = pd.read_csv(test_path + 'validation_predict_11.csv')
train_11 = train_11[train_11['PRODUCTGROUP_NAME'].isin(test_11['PRODUCTGROUP_NAME'].unique())]
data_11 = train_11.append(test_11).reset_index(drop=True)
data_11.loc[data_11['AXIS'] == -9.223372036854776e+18, 'AXIS'] = np.nan
print('val_11 train sample {} and test sample {}'.format(train_11['Product_ID'].nunique(), test_11['Product_ID'].nunique()))


val_11 train sample 13051 and test sample 3784


2. 特征工程


cate_cols = ['TYPE_NUMBER', 'PRODUCTGROUP_NAME']
df11 = get_11_fe(data_11, cate_cols)
df11 = get_limit_11(data_11, df11)
df11 = get_cate_11(data_11, df11, cate_cols)

# 构建标签
X_train, y_train, X_test, sub2 = get_training_data(df11, 'val_11')


val_11 train shape (13051, 36) and test shape (3784, 36) 


3. 模型训练 


五折划分数据,lgb 参数设置:


K = 5
seed = 2020
skf = StratifiedKFold(n_splits=K, shuffle=True, random_state=seed)
lgb_params = {
'boosting_type': 'gbdt',
'objective': 'binary',
'metric': 'None',
'num_leaves': 32,
# 'is_unbalance': True,'subsample': 0.9,
'colsample_bytree': 0.9,
'learning_rate': 0.05,
'lambda_l2':1,
# 'min_data_in_leaf':10,'nthread': -1,
'silent': True
}
f1_score2 = []
oof = np.zeros(len(X_train))
predictions2 = np.zeros(len(X_test))
feature_importance_df = pd.DataFrame()

for i, (train_index, val_index) in enumerate(skf.split(X_train,y_train)):
print("fold_{}".format(i))
X_tr, X_val = X_train.iloc[train_index], X_train.iloc[val_index]
y_tr, y_val = y_train.iloc[train_index], y_train.iloc[val_index]

lgb_train = lgb.Dataset(X_tr,y_tr)
lgb_val = lgb.Dataset(X_val,y_val)
num_round = 3000
clf = lgb.train(lgb_params, lgb_train, num_round, valid_sets = [lgb_train, lgb_val], feval=lgb_f1_score,
categorical_feature=['TYPE_NUMBER', 'PRODUCTGROUP_NAME'],
verbose_eval=100, early_stopping_rounds = 100)
oof[val_index] = clf.predict(X_val, num_iteration=clf.best_iteration)
pred = clf.predict(X_val, num_iteration=clf.best_iteration)
sc = f1_score(y_val, np.round(pred))
f1_score2.append(sc)
print(f'fold{i} f1 score = ',sc)
print('best iteration = ',clf.best_iteration)
fold_importance_df = pd.DataFrame()
fold_importance_df["Feature"] = clf.feature_name()
fold_importance_df["importance"] = clf.feature_importance()
fold_importance_df["fold"] = i + 1
feature_importance_df = pd.concat([feature_importance_df, fold_importance_df], axis=0)
predictions2 += clf.predict(X_test, num_iteration=clf.best_iteration) / skf.n_splits

print('val_11训练f1均值:{},波动:{}.'.format(np.mean(f1_score2), np.std(f1_score2)))
print('val_11 macro F1 score: ',f1_score(y_train, np.round(oof),average='macro'))


4. 特征重要性


plt.figure(figsize=(12,8))
sns.barplot(y='Feature', x='importance',data=feature_importance_df)
plt.title('val_11特征重要性')

Text (0.5,1,'val_11特征重要性')



5. 生成 val_11 结果


sub2['label'] = predictions2
sub2['label'] = sub2['label'].rank()
sub2['label'] = (sub2['label']>=sub2.shape[0] * 0.97).astype(int)
sub2['label'] = (sub2['label'] + 1).astype(int)
sub2.rename(columns={'Product_ID':'id'}, inplace=True)
print('正负样本比例:\n', sub2['label'].value_counts())

正负样本比例:


1 3703 

2 81 

Name: label, dtype: int64


生成提交文件


sub = sub1.append(sub2)
print('正负样本比例:\n', sub['label'].value_counts())
sub.to_csv(f'sub_val4_{np.round(np.mean(f1_scores),3)}_val11_{np.round(np.mean(f1_score2),3)}.csv', index=False)


正负样本比例: 


1 7312 

2 193 

Name: label, dtype: int64


sub.head()



由于文章篇幅限制,其他选手 Baseline 请扫码查看。


▲ bestIteration版


▲ sijinabc版


▲ hh_neuq版


4

参赛方式


点击阅读原文链接或扫描下图中的二维码直达赛事页面,注册网站-下载数据,即可参赛。


biendata 是知名的国际性大数据竞赛平台,面向全球在校学生、科研人员、企业以及自由职业者开放,期待对人工智能感兴趣的小伙伴能在平台上众多比赛中大展身手,在思维与技术的交流碰撞中激发创新和突破。 
友情提示,因涉及到数据下载,强烈建议大家登录 PC 页面报名参加。
5

INSPEC 工业检测大数据


智源联合博世发布了 INSPEC 工业检测大数据,该数据集包括某系列产品近年来的质量检测相关数据,其中主要为每个产品质量检测环节各个步骤记录的相关参数,每个步骤都标注检测判定结果,整体数据量在 3w 条左右。相比于类似数据集,本比赛数据具有显著优势和特点。 


首先,该数据集来自世界顶尖制造企业真实的工厂生产数据,已经过脱敏处理,尽量还原现实环境中产品检测的工序和流程。其次,INSPEC 工业检测大数据详细记录了检测环节生成的具体产品参数,涵盖产品子家族 ID、实例 ID、检测环节 ID、检测环节结果、检测规格和数值等。丰富的数据维度一方面增强了比赛的难度,另一方面有助于选手打造更加鲁棒的模型。


6

智源算法大赛


2019 年 9 月,智源人工智能算法大赛正式启动。本次比赛由北京智源人工智能研究院主办,清华大学、北京大学、中科院计算所、旷视、知乎、博世、爱数智慧、国家天文台、晶泰等协办,总奖金超过 100 万元,旨在以全球领先的科研数据集与算法竞赛为平台,选拔培育人工智能创新人才。 


研究院副院长刘江也表示:“我们希望不拘一格来支持人工智能真正的标志性突破,即使是本科生,如果真的是好苗子,我们也一定支持。”而人工智能大赛就是发现有潜力的年轻学者的重要途径。 


本次智源人工智能算法大赛有两个重要的目的,一是通过发布数据集和数据竞赛的方式,推动基础研究的进展。特别是可以让计算机领域的学者参与到其它学科的基础科学研究中。二是可以通过比赛筛选、锻炼相关领域的人才。智源算法大赛已发布全部的 10 个数据集,目前仍有 5 个比赛(奖金 50 万)尚未结束。


7

正在角逐的比赛


智源小分子化合物性质预测挑战赛 

https://www.biendata.com/competition/molecule/ 


智源杯天文数据算法挑战赛 

https://www.biendata.com/competition/astrodata2019/


智源-INSPEC 工业大数据质量预测赛 

https://www.biendata.com/competition/bosch/


智源-MagicSpeechNet 家庭场景中文语音数据集挑战赛

https://www.biendata.com/competition/magicdata/ 

智源-高能对撞粒子分类挑战赛  

https://www.biendata.com/competition/jet/



🔍


现在,在「知乎」也能找到我们了

进入知乎首页搜索「PaperWeekly」

点击「关注」订阅我们的专栏吧



关于PaperWeekly


PaperWeekly 是一个推荐、解读、讨论、报道人工智能前沿论文成果的学术平台。如果你研究或从事 AI 领域,欢迎在公众号后台点击「交流群」,小助手将把你带入 PaperWeekly 的交流群里。



登录查看更多
0

相关内容

【新书册】贝叶斯神经网络,41页pdf
专知会员服务
174+阅读 · 2020年6月3日
商业数据分析,39页ppt
专知会员服务
157+阅读 · 2020年6月2日
【CVPR2020-旷视】DPGN:分布传播图网络的小样本学习
专知会员服务
26+阅读 · 2020年4月1日
【干货】用BRET进行多标签文本分类(附代码)
专知会员服务
84+阅读 · 2019年12月27日
【综述】关键词生成,附10页pdf论文下载
专知会员服务
52+阅读 · 2019年11月20日
2019腾讯广告算法大赛方案分享(冠军)
大数据技术
12+阅读 · 2019年8月26日
竞赛推荐 | 奖金池20万:钢筋数量AI识别比赛
极市平台
3+阅读 · 2019年1月12日
进入 kaggle 竞赛前 2% 的秘诀
AI研习社
4+阅读 · 2018年11月13日
Xgboost算法——Kaggle案例
R语言中文社区
13+阅读 · 2018年3月13日
Arxiv
6+阅读 · 2017年12月2日
VIP会员
相关资讯
2019腾讯广告算法大赛方案分享(冠军)
大数据技术
12+阅读 · 2019年8月26日
竞赛推荐 | 奖金池20万:钢筋数量AI识别比赛
极市平台
3+阅读 · 2019年1月12日
进入 kaggle 竞赛前 2% 的秘诀
AI研习社
4+阅读 · 2018年11月13日
Xgboost算法——Kaggle案例
R语言中文社区
13+阅读 · 2018年3月13日
Top
微信扫码咨询专知VIP会员