PAKDD 是机器学习、数据挖掘领域顶会,除了聚焦于此的学术出版和讨论,每年PAKDD都有组织以解决现实问题为背景的机器学习算法大赛,而且影响力巨大。
今年的 PAKDD 2021 大赛内容是内存故障预测,在天池平台举行,业界之前对此的研究很少,但在业务复杂的大规模生产环境中提前准确预测内存故障已经成为大规模数据中心和云计算时代工业界需要研究和解决的重要问题之一。
之前向大家介绍过这一比赛:
机房里的未卜先知!PAKDD2021 第二届阿里云智能运维算法大赛启动
总奖池3万美元,目前还在初赛中,3月25日报名截止。
问题描述
给定一段时间的内存系统日志,内存故障地址数据以及故障标签数据,参赛者应提出自己的解决方案,以预测每台服务器是否会发生DRAM故障。具体来说,参赛者需要从组委会提供的数据中挖掘出和DRAM故障相关的特征,并采用合适的机器学习算法予以训练,最终得到可以预测DRAM故障的最优模型。数据处理方法和算法不限,但选手应该综合考虑算法的效果和复杂度,以构建相对高效的解决方案。
baseline主要思路
为帮助大家上手该比赛,CV君联系了一位小伙伴,写了这个baseline。
主要思路是以5分钟为一个聚合窗口,计算kernel_log每列的和作为特征,如果机器在5分钟内故障,则标为正样本,剩下的作为负样本,做适量的负样本下采样,训练svm分类模型,输出结果。
为不对大家探索自己的方案造成限制,这份baseline 代码已经尽量保持结构简单、代码清晰、功能完整,使用的机器学习算法也是最常见的SVM,目前这份baseline代码的 score 为 17.1429 ,相信在此基础上你一定可以修改得到更好的分数。
代码整体过程即处理数据、构造特征、机器学习模型训练、预测结果、保存提交文件。
完整代码:
import pandas as pd
import numpy as np
import os
from sklearn import svm
kernel_log_data_path = 'memory_sample_kernel_log_round1_a_train.csv'
failure_tag_data_path = 'memory_sample_failure_tag_round1_a_train.csv'
PARENT_FOLDER = 'data' # 数据存放目录
# 计算每个agg_time区间的和
def etl(path, agg_time):
data = pd.read_csv(os.path.join(PARENT_FOLDER, path))
# 降低时间精度 向上取整
data['collect_time'] = pd.to_datetime(data['collect_time']).dt.ceil(agg_time)
group_data = data.groupby(['serial_number','collect_time'],as_index=False).agg('sum')
return group_data
# 设置聚合时间粒度
AGG_VALUE = 5
AGG_UNIT = 'min'
AGG_TIME = str(AGG_VALUE)+AGG_UNIT
# 示例仅使用了kernel数据
group_min = etl(kernel_log_data_path, AGG_TIME)
failure_tag = pd.read_csv(os.path.join(PARENT_FOLDER,failure_tag_data_path))
failure_tag['failure_time']= pd.to_datetime(failure_tag['failure_time'])
# 为数据打标
merged_data = pd.merge(group_min,failure_tag[['serial_number','failure_time']],how='left',on=['serial_number'])
merged_data['failure_tag']=(merged_data['failure_time'].notnull()) & ((merged_data['failure_time']
-merged_data['collect_time']).dt.seconds <= AGG_VALUE*60)
merged_data['failure_tag']= merged_data['failure_tag']+0
feature_data = merged_data.drop(['serial_number', 'collect_time','manufacturer','vendor','failure_time'], axis=1)
# 负样本下采样
sample_0 = feature_data[feature_data['failure_tag']==0].sample(frac=0.1)
sample = sample_0.append(feature_data[feature_data['failure_tag']==1])
# svm模型训练
clf = svm.SVC()
clf.fit(sample.iloc[:,:-1],sample['failure_tag'])
# 测试数据
group_data_test = etl('memory_sample_kernel_log_round1_a_test.csv', AGG_TIME)
group_min_sn_test = pd.DataFrame(group_data_test[['serial_number','collect_time']])
group_min_test = group_data_test.drop(['serial_number', 'collect_time','manufacturer','vendor'], axis=1)
# 模型预测
res = clf.predict(group_min_test)
group_min_sn_test['predict']=res
# 保存结果
group_min_sn_test=group_min_sn_test[group_min_sn_test['predict']==1]
group_min_sn_res = group_min_sn_test.drop('predict',axis=1)
group_min_sn_res.to_csv('memory_predit_res_svm.csv', header=False, index=False)
另外,上述代码也发布在了天池大赛的论坛notebook:
优化建议
在此baseline上的改进并不难,以下列出一些可以做的方向:
1. 相关参数调优
2. 打标方法改进
3. 目前只用了kernel数据,增加mce和address的特征
4. 更多算法,loss等的尝试
5. 复杂/衍生特征挖掘
希望对大家有帮助!Enjoy!