Kaggle---Instacart Market Basket Analysis(根据数据预测复购)

今天完成本周的kaaggle 项目,通过该项目,可以学习到pandas 在数据分析中的基本应用,非常有用

具体代码如下

# coding: utf-8

# ##背景介绍
# 
# 目的就是找出该款软件app的用户可能会再次购买她买过的哪些产品

# In[1]:


import numpy as np 
import pandas as pd 
import matplotlib.pyplot as plt 
import seaborn as sns
color=sns.color_palette()


# In[2]:


#读入数据
aisles_df=pd.read_csv('aisles.csv')
departments_df=pd.read_csv('departments.csv')
order_products_prior_df=pd.read_csv('order_products__prior.csv')
order_products_train_df=pd.read_csv('order_products__train.csv')
orders_df=pd.read_csv('orders.csv')
products_df=pd.read_csv('products.csv')
sample_submission_df=pd.read_csv('sample_submission.csv')


# In[24]:


## orders_df 的含义是什么,因为开头背景就介绍,每一个人的数据可能出现多次,4-100个订单   order_num
type(orders_df['eval_set'].value_counts())#series
eval_set_info=orders_df['eval_set'].value_counts()
##下面进行可视化
plt.figure(figsize=(10,5))
plt.bar(eval_set_info.index,eval_set_info.values,color='grey',alpha=0.8)
"""
主要的参数有
color bar的颜色
edgecolor 边线bash线的颜色
height bar 的 高度 
width  bar 的 宽度 

"""
plt.xlabel('the kinds of eval_set')
plt.ylabel('the valuesof eval_set')
plt.show()


# In[37]:


###看一下来自这三个不同类型文件中 userr_id 的个数
def unique_counts(x):
#     return len((x))  发现每一个永辉会有多条记录
    return len(np.unique(x))

user_eval_counts=orders_df.groupby('eval_set')["user_id"].apply(lambda x: unique_counts(x))
# user_eval_counts=orders_df.groupby('eval_set')["user_id"].agg(unique_counts)
"""
圆括号是要进行聚类的列名 
中括号是要进行计算的列名
后续传入参数可以用apply 所有的行参与运算,这里每一个x 都是以 eval_set 为 一组 
也可以用agg 这个可以指定列
"""
user_eval_counts

##从这一步的碳素可以知道, perior 中user 最多,train 中最少
#test+train=prior


# In[56]:


###现在我们来验证一下关于 每一个消费者订单数量-----order_num的最大值,注意 一个用户会出现多次
order_num_info=orders_df.groupby("user_id")["order_number"].agg(np.max).reset_index()
"""
不加reset_index 就会发现是以 user_id 为索引的series
加了后,index以0,1,2,...为索引的dataframe 
"""
order_num_info_data=order_num_info.order_number.value_counts()#这样做就是看了一下大多数人出现订单最大值是多少
plt.figure(figsize=(20,5))
# plt.plot(order_num_info_data.index,order_num_info_data.values,alpha=0.5)
# plt.bar(order_num_info_data.index,order_num_info_data.values,color='r')
sns.barplot(order_num_info_data.index,order_num_info_data.values,color=color[2])##条形图或者 热力图比较方便
plt.show()

#发现每个人一次订单最多的不小于4个


# In[67]:


"""
order_dow 
是星期,1,2,3,等
"""

##接下来研究一下星期数
def week_num(x):
    return len(np.unique(x))
order_dow_info=orders_df.groupby("order_dow")["user_id"].agg(week_num).reset_index()
order_dow_info.columns=['index','user_num']##发现周日下单人数最多
sns.barplot(order_dow_info.index,order_dow_info.user_num,color=color[3])
plt.show()


# In[69]:


##同样可以看一下每天下单的时间,中午成为高峰期
def hour_num(x):
    return len(np.unique(x))
order_dow_info=orders_df.groupby("order_hour_of_day")["user_id"].agg(week_num).reset_index()
order_dow_info.columns=['index','user_num']##发现周日下单人数最多
sns.barplot(order_dow_info.index,order_dow_info.user_num,color=color[4])
plt.show()


# In[76]:


"""
当然我们也可以 
结合相应的星期和小时 
来看一下哪天哪段时间 
订单量最多
"""
order_num_day_hour=orders_df.groupby(["order_dow","order_hour_of_day"])["order_number"].count().reset_index()#不管order_num 等于多少都算一次
order_num_day_hour
order_num_day_hour_pivot=order_num_day_hour.pivot("order_dow","order_hour_of_day","order_number")
"""
类似于数据透视表
第一个参数类似于excel 里面的行
第二个参数类似于excel 里面的列
第三个是值
"""
order_num_day_hour_pivot#瞧,跟excel 里面的数据透视表一样
"""
数据透视表一个
最重要的应用就是做出一个热力图
"""
plt.figure(figsize=(12,6))
sns.heatmap(order_num_day_hour_pivot)
plt.title("Frequency of Day of week Vs Hour of day")
plt.show()


# In[90]:


##接下来 可以看一下 两次下单之间的时间间隔,给出两种不同的方法
plt.figure(figsize=(12,6))
order_interview=orders_df["days_since_prior_order"].value_counts().reset_index()
order_interview.columns=["inter_days","counts"]
sns.barplot(order_interview.inter_days,order_interview.counts,color=color[4])
plt.show()

#方法2
plt.figure(figsize=(12,8))
sns.countplot(x="days_since_prior_order", data=orders_df, color=color[3])
"""
countplot 不像barplot 
b不能同时传入x和y,
而是限定x,或者y,再 
用data 参数传入 dataframe 数据类型

"""
plt.ylabel('Count', fontsize=12)
plt.xlabel('Days since prior order', fontsize=12)
plt.xticks(rotation='vertical')
plt.title("Frequency distribution by days since prior order", fontsize=15)
plt.show()


# In[91]:


order_products_prior_df.head(10)


# In[111]:


#可以提发现,一个订单包含多个商品,add_to_cart_order 最大值为订单中商品的数量
recordered s是表征 某个商品复购的次数
def products_prior(x):
    return len(np.unique(x))


order_reorder_info=order_products_prior_df.groupby("reordered")["product_id"].agg(products_prior).reset_index()
order_reorder_info##发现只有0,1,0表示复购过,1表示没有

##接下来看一下复购产品占总产品的概率 
reorder_rate=order_reorder_info.loc[1,"product_id"]/order_reorder_info.product_id.sum()
reorder_rate



同样检查一下训练结合

def products_train(x):
    return len(np.unique(x))


order_reorder_info=order_products_train_df.groupby("reordered")["product_id"].agg(products_train).reset_index()
order_reorder_info##发现只有0,1,0表示复购过,1表示没有

##接下来看一下复购产品占总产品的概率 
reorder_rate=order_reorder_info.loc[1,"product_id"]/order_reorder_info.product_id.sum()
reorder_rate


# In[8]:


##接下来看一下有购买和没有购买的订单数量占比
order_products_prior_df
ground_df=order_products_prior_df.groupby("order_id")["reordered"].agg(sum).reset_index()
ground_df[ground_df["reordered"]>0].shape[0]/ground_df.shape[0]##有复购订单的占比
ground_df[ground_df["reordered"]==0].shape[0]/ground_df.shape[0]##m没有复购的占比
##发现复购的占比接近9成


# In[ ]:


order_products_train_df
#下面看一下训练集中,每个订单中产品的数量分布
order_products_num=order_products_train_df.groupby("order_id")["add_to_cart_order"].agg(max).reset_index()
order_products_num
order_products_num.add_to_cart_order.value_counts().reset_index()#统计某一列中某一个数出现的次数
order_products_num.columns=["max_products_num","ord_cnt"]
order_products_num
plt.figure(figsize=(12,8))
sns.barplot(order_products_num["max_products_num"],order_products_num["ord_cnt"],alpha=0.5)
plt.show()


# In[7]:


products_df#该表存储的是产品的相关细节,比如名字,制作方法的备注(department_id),辅料(aisle_id)
products_df.head(10)
aisles_df.head(10)
departments_df.head(10)


# In[3]:


#下面将上述的信息进行关联 注意merge的使用方法

order_products_prior_df = pd.merge(order_products_prior_df, products_df, on='product_id', how='left')
order_products_prior_df = pd.merge(order_products_prior_df, aisles_df, on='aisle_id', how='left')
order_products_prior_df = pd.merge(order_products_prior_df, departments_df, on='department_id', how='left')
order_products_prior_df.head()


# In[10]:


#接下来看一下哪些产品比较受欢迎,根据出现的频次
products_num_info=order_products_prior_df.product_name.value_counts().reset_index()
products_num_info.colimns=["products","refer_num"]
products_num_info.head(10)
#发现提及最多的是 香蕉


# In[11]:


#看一下 aisele 的辅料的构造
cnt_srs = order_products_prior_df['aisle'].value_counts().head(20)
plt.figure(figsize=(12,8))
sns.barplot(cnt_srs.index, cnt_srs.values, alpha=0.8, color=color[5])
plt.ylabel('Number of Occurrences', fontsize=12)
plt.xlabel('Aisle', fontsize=12)
plt.xticks(rotation='vertical')
plt.show()


# In[12]:


#看一下departments 的区别
plt.figure(figsize=(10,10))
temp_series = order_products_prior_df['department'].value_counts()
labels = (np.array(temp_series.index))
sizes = (np.array((temp_series / temp_series.sum())*100))
plt.pie(sizes, labels=labels, autopct='%1.1f%%', startangle=200)#两个参数,一个表示发呢大小,一个表示每一个的标签
plt.title("Departments distribution", fontsize=15)
plt.show()


# In[16]:


#看一下,每一个department 出现复购的次数
grouped_df = order_products_prior_df.groupby(["department"])["reordered"].aggregate("mean").reset_index()
grouped_df#含有某个成分的订单被复购的概率
plt.figure(figsize=(12,6))
sns.pointplot(grouped_df["department"],grouped_df["reordered"],alpha=0.5,color=color[2])


# In[ ]:


#看一下购买的件数和复购之间的联系
order_products_prior_df["add_to_cart_order_mod"]=order_products_prior_df["add_to_cart_order"].copy()
order_products_prior_df["add_to_cart_order_mod"].max()#145
order_products_prior_df["add_to_cart_order_mod"].loc[order_products_prior_df["add_to_cart_order_mod"]>70] = 70
order_products_prior_df["add_to_cart_order_mod"].max()
grouped_df=order_products_prior_df.groupby("add_to_cart_order_mod")["reordered"].agg("mean").reset_index()
grouped_df
plt.figure(figsize=(12,6))
sns.barplot(order_products_prior_df["add_to_cart_order_mod"],order_products_prior_df["reordered"],alpha=0.5,color=color[2])
plt.show()


# In[ ]:


grouped_df = order_products_train_df.groupby(["order_dow", "order_hour_of_day"])["reordered"].aggregate("mean").reset_index()
grouped_df = grouped_df.pivot('order_dow', 'order_hour_of_day', 'reordered')

plt.figure(figsize=(12,6))
sns.heatmap(grouped_df)
plt.title("Reorder ratio of Day of week Vs Hour of day")
plt.show()

相应的kaggle 链接:[https://www.kaggle.com/sudalairajkumar/simple-exploration-notebook-instacart]

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容