天池新人赛-天池新人实战赛o2o优惠券使用预测
Posted 冷幽篁
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了天池新人赛-天池新人实战赛o2o优惠券使用预测相关的知识,希望对你有一定的参考价值。
第一次参加天池新人赛,主要目的还是想考察下自己对机器学习上的成果,以及系统化的实现一下所学的东西。看看自己的掌握度如何,能否顺利的完成一个分析工作。为之后的学习奠定基础。
这次成绩并不好,只是把整个机器学习的流程熟悉了下。我本人总结如下:
步骤一:读懂题目含义,分析赛题的数据
步骤二:特征工程的设计,这部分非常重要,好的特征工程能大大提高模型的准确率
步骤三:训练算法。区分训练集、测试集等。
步骤四:测试模型,看效果如何。
赛题可以去天池的官网查看,里面有赛题说明,赛题数据等等
https://tianchi.aliyun.com/getStart/introduction.htm?spm=5176.11165418.333.1.3c2e613cd1CCDk&raceId=231593
以下是代码部分:
1 import numpy as np 2 import pandas as pd 3 4 #导入数据 5 train_online = pd.read_csv(\'ccf_online_stage1_train.csv\') 6 train_offline = pd.read_csv(\'ccf_offline_stage1_train.csv\') 7 test = pd.read_csv(\'ccf_offline_stage1_test_revised.csv\')
1 #将数据合并,以便统一对数据进行处理。都是线下数据 2 all_offline = pd.concat([train_offline,test])
1 #查看每一列的异常值 2 f = lambda x:sum(x.isnull()) 3 all_offline.apply(f)
1 #Data的空值 赋值为null,统一空值的格式 2 all_offline[\'Date\'] = all_offline[\'Date\'].fillna(\'null\') 3 4 #将online与offline的数据合并 5 pd.merge(all_offline,train_online,on=[\'Merchant_id\',\'User_id\']) 6 7 #通过合并数据,发现两者并无交集,题目要求只用线下预测,故排除线上online数据, 8 #只用offline数据 9 10 #根据赛题的要求,把正负样本标注出来 11 def is_used(column): 12 if column[\'Date\']!=\'null\' and column[\'Coupon_id\']!=\'null\': 13 return 1 14 elif column[\'Date\']==\'null\' and column[\'Coupon_id\']!=\'null\': 15 return -1 16 else: 17 return 0 18 19 all_offline[\'is_used\'] = all_offline.apply(is_used,axis=1)
1 #Coupon_id 优惠券ID的具体数值意义不大,因此我们把他转换成:是否有优惠券 2 def has_coup(x): 3 if x[\'Coupon_id\'] != \'null\': 4 return 1 5 else: 6 return 0 7 8 all_offline[\'has_coup\']=all_offline.apply(has_coup,axis=1)
1 #由于Discount_rate优惠率的特殊格式:"150:20",很难使用算法来计算使用 2 #根据实际情况,优惠力度是能够影响优惠券的使用频率的。因此需要对Discount_rate进行转化 3 #根据Discount_rate标识出折扣率 4 import re 5 regex=re.compile(\'^\\d+:\\d+$\') 6 7 def discount_percent(y): 8 if y[\'Discount_rate\'] == \'null\' and y[\'Date_received\'] == \'null\': 9 return \'null\' 10 elif re.match(regex,y[\'Discount_rate\']): 11 num_min,num_max=y[\'Discount_rate\'].split(\':\') 12 return float(num_max)/float(num_min) 13 else: 14 return y[\'Discount_rate\'] 15 16 all_offline[\'discount_percent\'] = all_offline.apply(discount_percent,axis=1)
1 #在进一步想,优惠力度会影响优惠券使用的概率,x:y这种满减的类型,x具体是多少,势必也会影响优惠券使用率 2 #讲满x元的标出x元 3 def discount_limit(y): 4 if y[\'Discount_rate\'] == \'null\' and y[\'Date_received\'] == \'null\': 5 return \'null\' 6 elif re.match(regex,y[\'Discount_rate\']): 7 num_min,num_max=y[\'Discount_rate\'].split(\':\') 8 return num_min 9 else: 10 return 0 11 12 all_offline[\'discount_limit\'] = all_offline.apply(discount_limit,axis=1) 13 all_offline.head(10)
1 #由于赛题需要的是,优惠券领取后15天的使用概率 2 #因此,我们在is_used的基础上,在对领券时间 Date_received 和使用时间Date,进行比较,判断是否在15天内使用 3 #时间比较 4 import datetime 5 #标注15天内使用优惠券的情况 6 def used_in_15days(z): 7 if z[\'is_used\'] == 1 and z[\'Date\'] != \'null\' and z[\'Date_received\'] != \'null\': 8 days= (datetime.datetime.strptime(z[\'Date\'],"%Y%m%d")-datetime.datetime.strptime(z[\'Date_received\'],"%Y%m%d")) 9 if days.days < 15: 10 return 1 11 else: 12 return 0 13 else: 14 return 0 15 16 all_offline[\'used_in_15days\']=all_offline.apply(used_in_15days,axis=1)
1 #再来观察discount_percent,discount_limit这2个特征,看数据的分布情况。 2 all_offline[\'discount_percent\'].value_counts()
1 all_offline[\'discount_limit\'].value_counts()
#将discount_percent分段 def discount_percent_layer(columns): if columns[\'discount_percent\']==\'null\': return \'null\' columns[\'discount_percent\']=float(columns[\'discount_percent\']) if columns[\'discount_percent\'] <= 0.1: return 0.1 elif columns[\'discount_percent\'] <= 0.2: return 0.2 elif columns[\'discount_percent\'] <= 0.3: return 0.3 elif columns[\'discount_percent\'] <= 0.4: return 0.4 else: return 0.5 all_offline[\'discount_percent_layer\']=all_offline.apply(discount_percent_layer,axis=1) all_offline[\'discount_percent_layer\'].value_counts()
·
1 #将discount_limit分段 2 def discount_limit_layer(columns): 3 if columns ==\'null\': 4 return \'null\' 5 6 columns=int(columns) 7 if columns <= 10: 8 return 10 9 elif columns <= 20: 10 return 20 11 elif columns <= 30: 12 return 30 13 elif columns <= 50: 14 return 50 15 elif columns <= 100: 16 return 100 17 elif columns <= 200: 18 return 200 19 else: 20 return 300 21 22 all_offline[\'discount_limit_layer\']=all_offline[\'discount_limit\'].apply(discount_limit_layer) 23 all_offline[\'discount_limit_layer\'].value_counts()
总结:
此时 Coupon_id 被处理成 has_coup(1代表领取优惠券,0代表没有领取优惠券)
Date,Date_received 被处理成 used_in_15days。表示是否在15天内使用过优惠券
Discount_rate 被处理成 discount_percent(折扣率),discount_limit(满多少)
Merchant_id,User_id 是unicode值,不需要进行处理
1 #剩下Distance,看下Distance的分布情况 2 all_offline[\'Distance\'].value_counts()
1 #保存数据,以便后期使用起来方便 2 train_finall,test_finall = all_offline[:train_offline.shape[0]],all_offline[train_offline.shape[0]:] 3 all_offline.to_csv(r\'output\\all_offline.csv\') 4 train_finall.to_csv(r\'output\\train_finall.csv\') 5 test_finall.to_csv(r\'output\\test_finall.csv\')
1 #one_hot处理 2 all_offline_new=all_offline.drop( 3 [\'Coupon_id\',\'Date\',\'Date_received\',\'Discount_rate\',\'Merchant_id\', 4 \'User_id\',\'discount_percent\',\'discount_limit\'],axis=1) 5 all_offline_new=pd.get_dummies(all_offline_new)
1 #把测试集跟验证集分开 2 train01,test01=all_offline_new[:len(train_offline)],all_offline_new[len(train_offline):] 3 4 #把没有领券的去掉 5 train02=train01[train01[\'has_coup\']==1] 6 7 #由于特征集 都是领券的人,故把 has_coup 字段删掉 8 train02=train02.drop([\'has_coup\'],axis=1) 9 test01=test01.drop([\'has_coup\'],axis=1) 10 11 x_train=train02.drop([\'used_in_15days\'],axis=1) 12 y_train=pd.DataFrame({"used_in_15days":train02[\'used_in_15days\']}) 13 x_text=test01.drop([\'used_in_15days\'],axis=1)
1 #建模 2 from sklearn.linear_model import LinearRegression 3 4 clf=LinearRegression() 5 clf.fit(x_train,y_train) 6 7 #用模型进行预测 8 predict=clf.predict(x_text) 9 10 11 result=pd.read_csv(\'ccf_offline_stage1_test_revised.csv\') 12 result[\'probability\']=predict 13 14 result=result.drop([\'Merchant_id\',\'Discount_rate\',\'Distance\'],axis=1) 15 16 17 #发现最终预测有负值,直接归为0 18 result[\'probability\']=result[\'probability\'].apply(lambda x: 0 if x<0 else x) 19 20 result.to_csv(r\'output/sample_submission.csv\',index=False)
以上是关于天池新人赛-天池新人实战赛o2o优惠券使用预测的主要内容,如果未能解决你的问题,请参考以下文章