Python数据分析之共享单车及建模探索(CLV建模、可视化)
Python数据分析之共享单车及建模探索(CLV建模、可视化)
开发环境
4.3【开发平台及环境】
Windons 10 教育版
Python 3.7
IntelliJ IDEA 2018.2.1 / PyCharm
Googe Chrome
数据清洗 分析模块pandas,numpy
可视化模块matplotlib
⼀:数据格式
中⽂字段:
订单ID,⽤户ID,单车类型,开始时间,开始定位,结束定位
。
注释:后续会通过geohash模块计算经纬度转换成具体距离
数据⼤⼩:
180M
前⾔
数据涵盖了48万 + 的单车,涵盖了近35W的骑,通过导⼊Geohash脚本中的decode函数,获取经纬度,⽤haversine公式计算球⾯两点间的距离。并计算和预估每个⽤户的消费和统计单车骑⾏公⾥数超过多少提⽰报修
代码
控制台输出显⽰所有⾏
from DPM_File.showed import show
import datetime
# show()
import pandas as pd
import geohash
import seaborn as sns
from math import radians, cos, sin, asin, sqrt
import matplotlib.pyplot as plt
file='F:/数据集/国内摩拜共享单车数据集/train.csv'
df = pd.read_csv('%s'%file, sep=',', parse_dates=['starttime'])
# 数据涵盖了48万 + 的单车,涵盖了近35W的骑
bikeid_size, userid_size = df['bikeid'].unique().size, df.userid.unique().size
print(bikeid_size,'辆单车 ', userid_size,'⽤户')
# 抽取1%的数据
df = df.sample(frac=0.002)
print('抽取20%的数据:',len(df))
# 通过导⼊Geohash脚本中的decode函数,获取经纬度
df["start_lat_lng"]= df["geohashed_start_loc"].apply(lambda s: geohash.decode(s))
df["end_lat_lng"]= df["geohashed_end_loc"].apply(lambda s: geohash.decode(s))
# # 获取出发地点所在区块周围的8个相邻区块编码
# df['start_neighbors'] = df['geohashed_start_loc'].apply(lambda s: ighbors(s))
# # 提取区块对应的6位Geohash编码
# df["geohashed_start_loc_6"] = df["geohashed_start_loc"].apply(lambda s: s[0:6])
# df["geohashed_end_loc_6"] = df["geohashed_end_loc"].apply(lambda s: s[0:6])
# # 获取出发地点所在区块周围的8个相邻区块的6位Geohash编码
# df["start_neighbors_6"] = df["geohashed_start_loc_6"].apply(lambda s: ighbors(s))
# print(df.head(5))
print("Geohash编码处理完毕!")
# 判断⽬的地是否在当前区块或相邻区块内
print('⼀阶完成')
# ⽤haversine公式计算球⾯两点间的距离
def haversine(lon1, lat1, lon2, lat2):
# 这⾥error,需要专float类型才能进⾏运算
lon1, lat1, lon2, lat2 =map(radians,[float(lon1),float(lat1),float(lon2),float(lat2)])
dlon = lon2 - lon1
dlat = lat2 - lat1
# print(type(lon1.head(1)))
# print(type(lon2.head(1)))
# print(type(lat1.head(1)))
python新手代码userid
# print(type(lat2.head(1)))
a = sin(dlat /2)**2+ cos(lat1)* cos(lat2)* sin(dlon /2)**2
c =2* asin(sqrt(a))
r =6371# 地球平均半径,单位为公⾥
return c * r *1000
df["start_end_distance"]= df.apply(lambda s: haversine(s['start_lat_lng'][1],s['start_lat_lng'][0], s['end_lat_lng'][1],s['end_lat_lng'][0]), axis=1) print('⼆阶完成')
#获取⼩时
df['hour']= df['starttime'].apply(lambda s : s.hour)
# print(df.head(5))
hour_group = df[['userid','hour']].groupby('hour',as_index=False).count()
print(hour_group.sort_values('userid',ascending=False))
hour_num_df = hour_group.agg({'userid':'count'}).reset_index()
sns.barplot(x=hour_group['hour'],y = hour_group['userid'],data = hour_num_df)
# plt.bar(hour_group['hour'],hour_group['userid'])
sns.displot(df['start_end_distance'])
plt.show()
#单车报修统计
'统计单车骑⾏公⾥数超过多少提⽰报修'
number_bike = df[['bikeid','start_end_distance']].groupby('bikeid',as_index=False).sum()
number_bike = number_bike[number_bike['start_end_distance']>]
number_bike = number_bike.sort_values('start_end_distance',ascending=False)
print(number_bike.head(5))
结果 1
" start_end_distance " 开始到结束的距离(单位:公⾥)
注释:180M数据,随机抽取了 20%
结果 2
每个时间段订单⾛势(赶时间省略100字)
注释:180M数据,随机抽取了 20%
结果 3
预估单车骑⾏公⾥数超过多少提⽰报修
number_bike = number_bike[number_bike['start_end_distance']> N ]
print(number_bike.head(5))
bikeid start_end_distance = N 有⾃⾏车⾏业经验的⾃⾏决定
439670 10754.385365
441905 9453.600628
251484 8895.594132
355054 8895.594132
385307 7830.297728
CLV探索
计算⽤户骑⾏距离所消费的⾦额money
‘3km=1元=5分钟’
‘6km=2元=10分钟’
‘12km=3元=15分钟’
‘经过上述统计得到2017-05-24 19:00:16为结束时间,数据量320W条’‘统计frequency频次为0的占⽐(2017-05-10 到 2017-05-24之间)’‘使⽤BG / NBD 模型分析频次和/新近度bgf’
‘预测前5⼤客户未来T=15天可能发⽣的购买频次’
‘未来T⽇可能产⽣多少ORI ?’
注释:这个个⼈定义的,实际骑⾏距离所⽤的时间因⼈⽽异
from lifetimes.utils import*
from lifetimes import*
from commerce.CLV.摩拜bike import df
import pandas as pd
import datetime
'1.分析⽤户未来5天可能消费的频次和消费⾦额(CLV建模)'
# 需要的字段
data = df[['userid','starttime','start_end_distance']]
# 筛选出骑⾏距离⼤于0的
data = data[data['start_end_distance']>0]
# 计算⽤户骑⾏距离所消费的⾦额money
# '3km=1元=5分钟'
# '6km=2元=10分钟'
# '6km=2元=10分钟'
# '12km=3元=15分钟'
def fun(x):
if0<= x <3000:
return1
elif3000<= x <5000:
return2
elif5000<= x <7000:
return3
elif7000<= x <9000:
return4
elif9000<= x <11000:
return5
elif x >=11000:
return50
data['money']= data['start_end_distance'].apply(lambda x: fun(x))
# 特殊时间格式处理
data['starttime']= pd.to_datetime(data['starttime'], unit='s').dt.strftime('%Y-%m-%d %H:%M:%S') print(data.head(5))
print(list(data['starttime']))
# 将时间排序,查看开始⽇期到结束⽇期 0.003=2017-05-10 00:02:45 2017-05-24 18:58:01
# a = list(data['starttime'])
# def get_list(date):
# return datetime.datetime.strptime(date, "%Y-%m-%d %H:%M:%S").timestamp()
# list = sorted(a, key=lambda date: get_list(date))
# print(list[1])
'经过上述统计得到2017-05-24 19:00:16为结束时间,数据量320W条'
# CLV建模
CLV_data = summary_data_from_transaction_data(data,'userid','starttime',
monetary_value_col='money',
observation_period_end='2017-05-24')
print('CLV建模后:',len(CLV_data),' ⾏\n', CLV_data.head(5))
# 统计frequency频次为0的占⽐(2017-05-10 到 2017-05-24之间)
frequencys =(sum(CLV_data.frequency ==0)/len(data))*100
print('频次为0的占⽐:',round(frequencys,2),' %',len(CLV_data),' ⾏')
# 使⽤BG / NBD 模型分析频次和/新近度bgf
bgf = BetaGeoFitter(penalizer_coef=0)
bgf.fit(CLV_data['frequency'], CLV_data['recency'], CLV_data['T'])
print('lifetimes数据: ','\n', bgf)
print('lifetimes数据summary: ','\n', bgf.summary)
# 预测前5⼤客户未来T=15天可能发⽣的购买频次
T =15
data = CLV_data[CLV_data['frequency']>0]
data['predicted_purchases']= ditional_expected_number_of_purchases_up_to_time(
T, data['frequency'], data['recency'], data['T'])
# 未来T⽇可能产⽣多少ORI?
data['ORI']= ary_value * data.predicted_purchases
ROI = data.sort_values(by='predicted_purchases', ascending=False)
# print('未来T⽇客户购买频次和ORI:', len(data), ' ⾏\n', data.head(5))
print('预测15天内该前5⼤客户购买频次:','\n', ROI.head(5))
# 有时候出错,要检测 penalizer_coef (惩戒系数)
赶时间不写了(数据⽐较⼤,不上传了,要数据看主页加V)
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论