去年九月份(应该是上一届比赛结束的时候吧),学校(那时)研一的学长简单讲了这个比赛,但是觉得机器学习很高大上很牛的感觉,听说了这个比赛当时就决定冲一冲,拿不拿奖是其次了,多少能学点东西吧哈哈哈哈~
当时是根据学长的建议入门的,边看吴恩达老师的机器学习入门边稍微看了点廖雪峰老师的python就开始做学生成绩预测以及泰坦尼克生存预测了(进程和线程那块没看,还是偷懒了)。
刚开始学还是很痛苦的,那时候疫情在家,身边也找不到一起入门学习打比赛的同学,就自己一个人硬啃。对着视频一行行敲代码,然后运行调试,查一个个函数的用法,写注释…
整个学习加上比赛的过程大概是二月到六月吧,完成了四个项目(完整的处理数据和预测,当然不是最优的),学生成绩预测、泰坦尼克生存预测、华为大数据挑战赛热身赛、华为大数据挑战赛正式赛。准备在这里记录一下自己的学习历程,要是忘了我也太亏了(没拿到奖总不能到最后还把学的那点皮毛给忘了)哈哈哈哈。
先大概理一理解题的步骤:
学生成绩预测这个项目是跟着视频做的,附链接康奈尔小鲜肉带你用notebook学数据分析,算是根据这个视频入门juypter notebook了哈哈,内容比较简单下文就不赘述了。
泰坦尼克号生存预测是跟着大树先生的博客做的,真的好强,写得很详细,附链接Kaggle_Titanic生存预测 – 详细流程吐血梳理
从整个比赛过程来看,我在模型调参方面做得十分不到位,因为属于速成机器学习,在算法调参等等,比如更换激活函数,更换损失函数这块感觉无从下手。比赛时更多的在特征工程方向努力。
赛题要求预测五和张衡交叉路口周一(2019年2月11日)和周四(2019年2月14日)两天的5:00-21:00通过wuhe_zhangheng路口4个方向的车流量总和,然后主办方是给出了一共六个路口1.12-2.08的数据,但是五和张衡路口13号和15号的数据是确实的,只有0:00-3:05的数据,而14号的诗句是完全缺失的。
总的来说这次热身赛,就是利用这六个路口四个星期的数据来过 拟合2019.2.11(年后开工第一天)和2.14(情人节)这两天五和张衡路口左转和直行的车流量之和。
热身赛前期我并没有清洗数据的想法,但是与榜单前几的大佬沟通之后了解到了他们的处理方法。他们基本都是通过已提交的result的得分来找到接近2.10和2.14这两天实际车流量的验证集,在线下通过验证集得到分数较高的模型再提交。这样确实节省了很多提交次数,而像我这样的萌新则是在前期浪费了许多提交次数在一些对结果影响不大的修改上(这就是大佬吗,我哭了)。某大佬还曾经对我明示,挑出训练集中年前趋势类似的日期训练,其他路口不管,数据不全的日期不管(1.13、1.14、1.15),年后数据不管,调休日期不管。可惜这份“嗟来之食”我也没有参透o(╥﹏╥)o
简单梳理一下我清洗数据的思路:
可能是我清洗不到位或者方法有问题吧,以上我排列组合了N次都没有太好的效果,分数大概在60出头吧。
df_dt = to_datetime(raw_data.loc[:, "time"], format="%Y/%m/%d %H:%M:%S")
all_data = pd.DataFrame({
"weekday": df_dt.dt.weekday/6.0,
"timeindex": (df_dt.dt.hour * 60 + df_dt.dt.minute)/(24*60.0),
"sum":raw_data["sum"]]})
热身赛我没有进行模型融合,因为在线上跑模型,当时在推理代码这块卡住了(还是很不方便啊对于初学者),所以没有试过效果怎么样。
我裂开了,我突然想到了为什么以上操作都没有什么效果,应该是我划分训练集和验证集的方式有问题。我一直都是直接使用train_test_split()来对整个训练集划分的。
既然是为了过拟合,针对这道题我觉得应该选定一个或者两个接近的日期作为验证集俩训练模型。对!就是这样,为什么我现在才想明白o(╥﹏╥)o
重心全在特征工程了o(╥﹏╥)o
可是这个破 题还真不用什么狗屁特征工程o(╥﹏╥)o
算法这块我一直用的是GBR算法
后期向大佬建议我使用LGB,但是ModelArts上的JuyPterNoteBook用不了LGB…我裂开,又吃了不知道可以线下跑模型的亏o(╥﹏╥)o
虽然好像也提不了多少分
调参使用的是model_selection.GridSearchCV(),应该是我损失函数的选择有问题,效果也不明显。
最后就是用训练好的模型predict测试集得到结果了。
贴一下最高得分(66.2228)代码
# read data of one day and one direction
def read_file(path, filename):
calfile = os.path.join(path, filename)#路径拼接
original = pd.read_csv(calfile, header=None)
data = pd.DataFrame(columns=["time","sum"])
data["time"] = original[0]
data["sum"]=original[3]+original[4]
return data
# read data of one day
def read_data_day(path, date,chuxihou):
#day_data = pd.DataFrame(columns=["time","cross","direction" ,"sum"])
day_data = pd.DataFrame(columns=["time","sum"])
day_data_= pd.DataFrame(columns=["time","sum"])
caldir = os.path.join(path, date)
i=1
# read data of one day
for f in os.listdir(caldir):
if (re.match(r'wuhe_zhangheng.*\.csv', f)) and i==1:
day_data = day_data.append(read_file(caldir, f), ignore_index=True)
i=0
else:
day_data_=day_data_.append(read_file(caldir, f), ignore_index=True)
day_data["sum"]=day_data_["sum"]+day_data["sum"]
if chuxihou==1:
day_data["chuxihou"]=1
else:
day_data["chuxihou"]=0
return day_data
def train_model(local_data_X,local_data_Y):
X_train, X_test, y_train, y_test = train_test_split(local_data_X, local_data_Y, test_size=0.2, random_state=42)
print("X_train shape is: " + str(X_train.shape))
print("X_test shape is: " + str(X_test.shape))
gbr=GradientBoostingRegressor(**best_params)
gbr.fit(local_data_X, local_data_Y)
joblib.dump(gbr, LOCAL_MODEL_PATH)
#y_predict = gbr.predict(X_test)
#mse = mean_squared_error(y_test, y_predict)
#print("MSE: %.4f" % mse)
def create_config():
schema_model=json.loads('{"model_algorithm":"gbtree_classification","model_type":"Scikit-learn","runtime":"python3.6","metrics":{},"apis":[{"procotol":"http","url":"/","method":"post","request":{"Content-type":"applicaton/json","data":{"type":"object","properties":{"req_data":{"type":"array","items":[{"type":"string"}]}}}},"response":{"Content-type":"applicaton/json","data":{"type":"object","properties":{"resp_data":{"type":"array","items":[{"type":"number"}]}}}}}]}',object_pairs_hook=OrderedDict)
schema_model['model_algorithm'] = "gbtree_regression"
schema_model['model_type'] = "Scikit_Learn"
with open(LOCAL_CONFIG_PATH, 'w') as f:
json.dump(schema_model, f)
if __name__ == "__main__":
# copy data from obs to local
mox.file.copy_parallel(OBS_DATA_PATH, LOCAL_DATA_PATH)
raw_data = pd.DataFrame(columns=["time","chuxihou","sum"])
for day in os.listdir(LOCAL_DATA_PATH):
if day in['02-03','02-02']:
continue
if day in ['02-04','02-05','02--06','02-07','02-08'] :
chuxihou=1
raw_data = raw_data.append(read_data_day(LOCAL_DATA_PATH, day,chuxihou))#https://blog.csdn.net/tz_zs/article/details/81238085
else:
chuxihou=0
raw_data = raw_data.append(read_data_day(LOCAL_DATA_PATH, day,chuxihou))
# encode time in raw data to weekday and timeindex(the n minutes of the day)
df_dt = to_datetime(raw_data.loc[:, "time"], format="%Y/%m/%d %H:%M:%S")
all_data = pd.DataFrame({
"weekday": df_dt.dt.weekday/6.0,
"timeindex": (df_dt.dt.hour * 60 + df_dt.dt.minute)/(24*60.0),
"sum":raw_data["sum"],"chuxihou":raw_data["chuxihou"]})
all_data.dropna(subset=['timeindex'],inplace=True)
all_data["sum"]=all_data["sum"].astype(int)
# read and preprocess data
local_data_X= all_data.drop(['sum'],axis=1)
local_data_Y=all_data['sum']
train_model(local_data_X,local_data_Y)
create_config()
mox.file.copy(LOCAL_MODEL_PATH, OBS_MODEL_PATH)
mox.file.copy(LOCAL_CONFIG_PATH, OBS_CONFIG_PATH)
print("Model training has been completed!")
好吧其实没有什么技术含量。。。