呓语 | 杨英明的个人博客

专注于c++、Python,欢迎交流

By

【IJCAI-17 口碑商家客流量预测】使用Pandas计算商家平均客流量

这段时间参加了天池的 IJCAI-17 口碑商家客流量预测 大数据竞赛,初次参加此类竞赛,也是第一次使用pandas,折腾了许久,记录下自己的心得。代码很粗糙,仅作个人记录用。参考价值不大,大神勿喷。

下面出现的代码已经提交检验通过,第一次提交混上了排行榜,400+左右的位置,第二次修改了一下混到了200+的位置,真是没有想到这么水的算法也能上排行榜……

这场比赛 题目大意 是:
给你提供2000家商家的店铺信息,以及他们的历史支付记录(大概7000w条)和浏览记录(大概500w条),你需要预测每个商家未来14天每天的客流量,每家店铺的客流量是指“单位时间内在商家使用支付宝消费的用户人次”,即每天这家店铺的支付次数。

第一次提交

一般来说,这种“预测”问题,需要用到机器学习或者数据挖掘等算法,但由于我是新手,所以打算采用最简单的办法先尝试一下。

最简单的 思路 是:
统计每个商家每周的客流量均值,即统计这个商家每周一、周二、周三……平均每天有多少客流量。

那么解决问题的 步骤 是:
1、统计每个商家历史日期每天的客流量。
2、计算每个商家历史日期分别对应的星期数,累加客流量和出现次数。
3、计算每个商家每周的客流量均值。

代码

# 读取文件
import pandas

user_pay = pandas.read_csv(r'.\dataset\dataset\user_pay.txt',header=None,names=['user_id','shop_id','time_stamp'])

# 分组操作
grouped = user_pay.groupby( [user_pay['shop_id'],user_pay['time_stamp']] )

# 得到每个商家历史日期每天的客流量
groupcnt = grouped.count()

# 将每个商家每天的客流量写入到csv文件中
fp = open('user_pay_3.csv','w')
for i,j in grouped:
    fp.write('%s,%s,%d\n'%(i[0],i[1],j.count()['shop_id']))
    print i
fp.close()

# 提取每位商家的客流量csv文件
shop_cnt = pandas.read_csv(r'user_pay_3.csv', iterator=True,chunksize=1,header=None,names=['shop_id','date','cnt'])

# 统计每个商家一个星期每天的总客流量 和 每天的计数
# shop_cnt是迭代的方式
import time
num_week = [[0 for col in range(7)] for row in range(2000)]
ave_week = [[0 for col in range(7)] for row in range(2000)]
for shop in shop_cnt:
    #print shop
    shop_id = shop.values[0][0]
    date = shop.values[0][1]
    cnt = shop.values[0][2]
    print shop_id
    w = int(time.strftime('%w',time.strptime(date,'%Y-%m-%d')))
    ave_week[shop_id-1][w] += cnt
    num_week[shop_id-1][w] += 1

# 计算均值
for i in range(2000):
    print i+1
    for j in range(7):
        ave_week[i][j] = int( ave_week[i][j] / num_week[i][j] )

# 输出为结果csv
fp = open('answer.csv','w')
for i in range(2000):
    print i+1
    fp.write('%d'%(i+1))
    for j in range(2,7):
        fp.write(',%d'%(ave_week[i][j]))
    for j in range(2):
        fp.write(',%d'%(ave_week[i][j]))
    for j in range(2,7):
        fp.write(',%d'%(ave_week[i][j]))
    for j in range(2):
        fp.write(',%d'%(ave_week[i][j]))
    fp.write('\n')
fp.close()

第二次提交

以上代码提交之后,Loss值是0.16,排名400+,和当时排名第一的0.07相差甚远。我思考了一下,发现其实不必计算全局的均值,只取后四周的均值 可能更接近实际结果。

于是我改进了一下算法,把统计总客流量那里的代码改成:

# 非迭代方式读取
shop_cnt = pandas.read_csv(r'user_pay_3.csv',header=None,names=['shop_id','date','cnt'])

# 统计每个商家一个星期每天的总客流量 和 每天的计数
# shop_cnt是列表
num_week = [[0 for col in range(7)] for row in range(2000)]
ave_week = [[0 for col in range(7)] for row in range(2000)]
for i in range(len(shop_cnt)):
    shop_id = shop_cnt[i:i+1].values[0][0]
    date = shop_cnt[i:i+1].values[0][1]
    cnt = shop_cnt[i:i+1].values[0][2]
    print shop_id,date,cnt
    w = int(time.strftime('%w',time.strptime(date,'%Y-%m-%d')))
    if sum(num_week[shop_id-1]) < 28:
        ave_week[shop_id-1][w] += cnt
        num_week[shop_id-1][w] += 1
        print sum(num_week[shop_id-1])

这次提交之后,Loss值变成了0.96,排名提高到了200+。

总结

虽然算法很简单,但也算是我第一次参加大数据比赛的经历。第一次处理这么大规模的数据,虽然和生产环境相比,这点数据还是小儿科,但对我来说,是一笔宝贵的经验。7000w条数据,可能一条语句就会处理半天,所以使用更好的工具——比如pandas效率就很高——就变得尤为重要;处理时的策略也一定要想清楚,否则就是在浪费时间。

其实接触这个比赛才没几天,但已经给我打开了一扇关于数据处理的新的大门。相信继续研究下去会很有意思。

参考资料

pandas 数据分组运算

pandas聚合和分组运算之groupby

原创声明

转载请注明:呓语 » 【IJCAI-17 口碑商家客流量预测】使用Pandas计算商家平均客流量