Python:需求预估

作者: slade_sal | 来源:发表于2017-07-12 09:42 被阅读54次

之前写了一篇以基于elastic的需求预估的文章,只不过用的是R语言开发的,最近在学python,就仿照逻辑写了一篇python的,主要修改点如下:

  • 用决策树替换了elastic算法
  • 用分层抽样替换了组合抽样

需要看详细理论及思考过程参考链接:商品需求预估

python code如下:

# -*- coding:utf-8 -*-
import pandas as pd
import numpy as np
import random as rd
from sklearn import tree

# 读取数据
data_orgin = pd.read_table("C:/Users/17031877/Desktop/supermarket_second_hair_washing_train.txt")
data_deal_1 = data_orgin.drop(['aimed_date', 'member_id', 'age', 'gender', 'diff_rgst'], axis=1)

这边是常规的数据读取,删除了不必要的列


#因变量单列
label = data_deal_1['label']

# 用户分量级
value00 = ['max_date_diff', 'aimed_max_date_diff']
data00 = data_deal_1[value00]

value01 = ['max_pay', 'per_pay', 'six_month_max_pay', 'six_month_per_pay', 'three_month_max_pay', 'three_month_per_pay',
           'one_month_max_pay', 'one_month_per_pay', 'fifteen_day_max_pay', 'fifteen_day_per_pay', 'aimed_max_pay',
           'aimed_per_pay', 'aimed_six_month_max_pay', 'aimed_six_month_per_pay', 'aimed_three_month_max_pay',
           'aimed_three_month_per_pay', 'aimed_one_month_max_pay', 'aimed_one_month_per_pay',
           'aimed_fifteen_day_max_pay', 'aimed_fifteen_day_per_pay', 'qty_drtn_seven', 'qty_drtn_fourteen']
data01 = data_deal_1[value01]

value02 = ['cnt_time', 'six_month_cnt_time', 'three_month_cnt_time', 'one_month_cnt_time', 'fifteen_day_cnt_time',
           'aimed_cnt_time', 'aimed_six_month_cnt_time', 'aimed_three_month_cnt_time', 'aimed_one_month_cnt_time',
           'aimed_fifteen_day_cnt_time', 'pv_times_seven', 'pv_times_fourteen', 'search_times_seven',
           'search_times_fourteen', 'clc_times_seven', 'clc_times_fourteen', 'cart2_times_seven',
           'cart2_times_fourteen', 'cart1_times_seven', 'cart1_times_fourteen', 'unpay_times_seven',
           'unpay_times_fourteen']
data02 = data_deal_1[value02]

value03 = ['pv_visit_last_period', 'search_last_period', 'clc_last_period', 'cart2_last_period', 'cart1_last_period',
           'unpay_last_period']
data03 = data_deal_1[value03]

因为不同量级的数据之后做异常点处理的时候截断位置不同,所有需要分割数据处理


def test_function_one(x, l):
    k = x.dropna(how='any')
    y = k.quantile(l)
    z = k.max()
    x[x > y] = y
    x = x.fillna(value=z)
    return x
for i in range(len(data00.columns)):
    data00.iloc[:, i] = test_function_one(data00.iloc[:, i], 0.98)

def test_function_two(x, l):
    k = x.dropna(how='any')
    y = k.quantile(l)
    z = 0
    x[x > y] = y
    x = x.fillna(value=z)
    return x
for i in range(len(data01.columns)):
    data01.iloc[:, i] = test_function_two(data01.iloc[:, i], 0.95)
for i in range(len(data02.columns)):
    data02.iloc[:, i] = test_function_two(data02.iloc[:, i], 0.99)

def test_function_three(x):
    z = 14
    x[x > z] = z
    x = x.fillna(value=z)
    return x
for i in range(len(data03.columns)):
    data03.iloc[:, i] = test_function_three(data03.iloc[:, i])
# 数据合并
data_train = pd.concat([label, data00, data01, data02, data03], axis=1)

根据数据量的不同做数据分割,跑上面写完的code函数就可以


#数量级对比
zero_case = data_train[data_train['label'] == 0]['label'].count()
print '负样本数:%d' % zero_case
one_case = data_train[data_train['label'] == 1]['label'].count()
print '正样本数: %d' % (one_case)

负样本数:292936
正样本数: 3973
Backend TkAgg is interactive backend. Turning interactive mode on.

实际看下来,正负样本的差异的确还是很大,这个其实做多了就有经验,常规的来看,潜在的浏览、搜索到最后的成单,普遍自然转化不到1%,也正是这么低的转化,才需要一些算法来做信息抓去。


def case_sample(x, y, z):
    diff_case = pd.DataFrame(x[y]).drop_duplicates([y])
    result = []
    result = pd.DataFrame(result)
    for i in range(len(diff_case)):
        k = np.array(diff_case)[i]
        data_set = x[x[y] == k[0]]
        nrow_nb = data_set.iloc[:, 0].count()
        data_set.index = range(nrow_nb)
        index_id = rd.sample(range(nrow_nb), int(nrow_nb * z))
        result = pd.concat([result, data_set.iloc[index_id, :]], axis=0)
    return result


zero_case = data_train[data_train['label'] == 0]
one_case = data_train[data_train['label'] == 1]
# 开始分层抽样
new_zero_case = case_sample(zero_case, 'unpay_last_period', 0.1)
# 新数量级对比
new_zero_case_count = new_zero_case[new_zero_case['label'] == 0]['label'].count()
# 数据集合并
new_data_train = pd.concat([new_zero_case, one_case], axis=0)

case_sample是一个简单的分层抽样的小函数,x是数据集,y是分层变量,z是抽样占比;新的样本new_data_train中正负样本比例在1:10左右,这边的样本比是我自己设置的,不一定是最合理的;且此处也不一定要求一定用分层抽样,只是我用来练练手的;推荐还是遵从奥卡姆原理,在未知的情况下,尽可能简单的解决问题,比如组合抽样就是很不错的方法。


#函数设置
clf = tree.DecisionTreeRegressor(criterion='mse', max_features='log2', random_state=1)

#函数拟合
y = new_data_train['label']
x = new_data_train.drop('label', 1)
clf.fit(x, y)

#数据预测
y_predict = clf.predict(x)

# 结果对比
y.index = range(len(y))
combined_date = pd.concat([y, pd.DataFrame(y_predict)], axis=1)
combined_date.columns = ['actual', 'predict']

这边稍微讲解一下,我认为的sklearnDecisionTreeRegressor中比较终于的参数设置,criterion这边为模型优化的标准,常规的有msemae,建议在数据量差异不大的时候多考虑msemax_features是每次训练用的特征个数,综合特征量级考虑,一般有log2sqrt,尽可能是抽取比例在70%;max_depth刚开始可以默认,第一类模型出来后,可在结果附近迭代,寻找out of bag最小的error下的值;另外,我没有发现有weight设置,可能是我不熟悉,但是如果sklearn这边不提供weight的化,我们在做数据预处理的时候一定要平衡数据,不然当数据集过偏的时候最后的结果会以“牺牲”少类的判断正确率去完善整体正确率。



# case 1
x = []
y = []
for i in range(1, 10):
    test_data = combined_date
    i = i / float(10)
    for j in range(combined_date['actual'].count()):
        if test_data.iloc[j, 1] > i:
            test_data.iloc[j, 1] = 1
        else:
            continue
    z = test_data[test_data['actual'] == test_data['predict']]['actual'].count() / float(test_data['actual'].count())
    x.append(i)
    y.append(z)

这边写了检查函数,检查了分别0.1~1,以0.1为间隔的情况下的分割点,每个分割点下预测正确的数量/所有统计的样本数,也就是下面的accuracy.


# case 2
test_data = combined_date
aimed_data = test_data[test_data['predict']>0]
k1=aimed_data[aimed_data['actual']==1]['predict'].count()
k2=float(aimed_data['predict'].count())

print '所有预测可能下单用户中真实下单用户数:%d' %(k1)
print '所有预测可能下单用户数:%d' %(k2)

因为这边需要对用户营销,所以更关系topN的转化率,需要看一下实际正样本被覆盖了多数,以上即为code,这边的效果值为98.7%,还是比较高的,但是应该是过拟合了,所有一般不建议单纯使用决策树模型


所有的python code到这里就结束了,后续我做项目的同时会同时更新R及python两种code的思考,和大家讨论分享学习,谢谢。

参考文献:

相关文章

  • Python:需求预估

    之前写了一篇以基于elastic的需求预估的文章,只不过用的是R语言开发的,最近在学python,就仿照逻辑写了一...

  • 应用:商品需求预估

    摘要:想要更好的改变用户体验,非常重要的点在于在用户交易过程前,提前预测到用户的需求,做到“口未开,物先呈” 1....

  • 互联网都在讲敏捷开发,这些敏捷开发流程你都知道吗?

    需求理解 理解需求背景 确认需求明确,无逻辑遗漏 确认所有需求方案都有实现方案 合理预估时间 需求不明确或者不清晰...

  • 需求测试

    https://www.sohu.com/a/289021847_505788补充:需求安全性:从安全角度预估需求...

  • 68--番茄工作法--2018-10-17

    预估活动需要番茄钟数,使用 正方形 做标记(比如预估需求3个番茄钟能完成此项目,就画3个正方形),一个番茄钟做完,...

  • Appium

    iOS自动化测试完全实现预估周期 Appium iOS入门环境搭建Hello world(Python重点学习)n...

  • B端产品交互设计流程梳理

    一.评估需求。 1. 拿到PRD文档后,评估PRD文档的清晰程度,如果比较粗糙,在需求启动时需要多预估一些时间。 ...

  • windows下scrapy 的安装

    安装python 根据你的需求下载python安装包,安装python(本文基于python27)https://...

  • 代写Python、Python代写、代做Python、Pytho

    代写Python、Python代写、代做Python、Python程序代做, 承接个人需求,博客项目,devops...

  • 作业【45天课程】2.面试甄选兵法

    一.招募与面试的流程有几步?是什么? 1.提前计划人员需求 预估人员需求量,餐厅人员情况调查,当地人力市场情况分析...

网友评论

    本文标题:Python:需求预估

    本文链接:https://www.haomeiwen.com/subject/tdivhxtx.html