栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

【python数据分析】零售场景(附数据集链接)

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【python数据分析】零售场景(附数据集链接)

文章目录
  • 前言
  • 一、探索性数据分析
    • 1.是否存在空值或异常值,如何处理
    • 2.有变量需要转换数据类型吗
    • 3.你注意到数据中有什么异常吗?
    • 4.对于给定的数据,你是否可以设计一些有用的变量?
  • 二、请以回归的形式运行统计测试以回答这些问题,并提出数据驱动的行动建议。用非统计术语来解释你的结果。
    • 1.哪些因素与最后一次宣传活动的效果显著相关?
  • 三、请回答以下问题的并可视化。
    • 1.买黄金的人比较保守。因此,那些在过去2年花费高于平均水平黄金的人会有更多的商店购买,请问这句陈述是否正确。
    • 2.使用适当的统计测试来证明或反驳这种说法鱼含有对大脑有益的- 3脂肪酸。因此,“已婚博士候选人”与花在鱼上的钱有显著的关系吗?
    • 3.还有哪些因素与花在鱼上的钱有显著的关系?
  • 总结


部分词典

列名对照
Recency距离最后一次到店的时间
Kidhome家里有多少个儿童
NumStorePurchases到店购买数量
AcceptedCmp3参加活动3
Response参加最后一次活动

注:对于定性变量,1为是,0为否

前言

数据集github链接
总体目标:你是一名营销分析师,首席营销官告诉你,最近的营销活动没有预期的那么有效。您需要分析数据集来理解这个问题,并提出数据驱动的解决方案。)


一、探索性数据分析

导入库,读取文件

import pandas as pd
import seaborn as sns
import numpy as np
from matplotlib import pyplot as plt 
df = pd.read_csv('ml_project1_data.csv')
1.是否存在空值或异常值,如何处理
df.isna().sum()

输出:

ID                      0
Year_Birth              0
Education               0
Marital_Status          0
Income                 24
Kidhome                 0
Teenhome                0
Dt_Customer             0
Recency                 0
MntWines                0
MntFruits               0
MntMeatProducts         0
MntFishProducts         0
MntSweetProducts        0
MntGoldProds            0
NumDealsPurchases       0
NumWebPurchases         0
NumCatalogPurchases     0
NumStorePurchases       0
NumWebVisitsMonth       0
AcceptedCmp3            0
AcceptedCmp4            0
AcceptedCmp5            0
AcceptedCmp1            0
AcceptedCmp2            0
Complain                0
Z_CostContact           0
Z_Revenue               0
Response                0
dtype: int64

Income列有24个空值,先看看它的分布再决定如何处理空值

sns.boxplot(data=df,y='Income')

输出:

有几个异常大的值,为了不改变数据分布所以这里采用中位数填充空值

df['Income'] = df['Income'].fillna(df['Income'].median())
2.有变量需要转换数据类型吗

先看一下数据类型

df.info()

输出:


RangeIndex: 2240 entries, 0 to 2239
Data columns (total 29 columns):
 #   Column               Non-Null Count  Dtype  
---  ------               --------------  -----  
 0   ID                   2240 non-null   int64  
 1   Year_Birth           2240 non-null   int64  
 2   Education            2240 non-null   object 
 3   Marital_Status       2240 non-null   object 
 4   Income               2216 non-null   float64
 5   Kidhome              2240 non-null   int64  
 6   Teenhome             2240 non-null   int64  
 7   Dt_Customer          2240 non-null   object 
 8   Recency              2240 non-null   int64  
 9   MntWines             2240 non-null   int64  
 10  MntFruits            2240 non-null   int64  
 11  MntMeatProducts      2240 non-null   int64  
 12  MntFishProducts      2240 non-null   int64  
 13  MntSweetProducts     2240 non-null   int64  
 14  MntGoldProds         2240 non-null   int64  
 15  NumDealsPurchases    2240 non-null   int64  
 16  NumWebPurchases      2240 non-null   int64  
 17  NumCatalogPurchases  2240 non-null   int64  
 18  NumStorePurchases    2240 non-null   int64  
 19  NumWebVisitsMonth    2240 non-null   int64  
 20  AcceptedCmp3         2240 non-null   int64  
 21  AcceptedCmp4         2240 non-null   int64  
 22  AcceptedCmp5         2240 non-null   int64  
 23  AcceptedCmp1         2240 non-null   int64  
 24  AcceptedCmp2         2240 non-null   int64  
 25  Complain             2240 non-null   int64  
 26  Z_CostContact        2240 non-null   int64  
 27  Z_Revenue            2240 non-null   int64  
 28  Response             2240 non-null   int64  
dtypes: float64(1), int64(25), object(3)
memory usage: 507.6+ KB

有三个object类型的列,下面看看它们分别是什么类型的数据

df[['Education','Marital_Status','Dt_Customer']].head()

输出:

EducationMarital_StatusDt_Customer
0GraduationSingle2012-09-04
1GraduationSingle2014-03-08
2GraduationTogether2013-08-21
3GraduationTogether2014-02-10
4PhDMarried2014-01-19

为方便处理,前两列需要map为数字,时间类就转为datetime类
不过再map之前需要先看下前两列的分布

f, axes = plt.subplots(1, 2, figsize=(16, 4),sharey=True)
for ax,col in zip(axes,['Education','Marital_Status']):
    sns.countplot(x=df[col],ax=ax)

输出:

Marital_Status有三个明显异常值,先看看这些数据正不正常

df[df['Marital_Status'].isin(['Alone','Absurd','YOLO'])]

输出:

IDYear_BirthEducationMarital_StatusIncomeKidhomeTeenhomeDt_CustomerRecencyMntWines...NumWebVisitsMonthAcceptedCmp3AcceptedCmp4AcceptedCmp5AcceptedCmp1AcceptedCmp2ComplainZ_CostContactZ_RevenueResponse
1314331958MasterAlone61331.0112013-03-1042534...80000003110
13876601973PhDAlone35860.0112014-05-193715...51000003111
153921988GraduationAlone34176.0102014-05-12125...60000003110
209377341993GraduationAbsurd79244.0002012-12-1958471...10011003111
213443691957MasterAbsurd65487.0002014-01-1048240...20000003110
21774921973PhDYOLO48432.0012012-10-183322...80000003110
2202111331973PhDYOLO48432.0012012-10-183322...80000003111

7 rows × 29 columns

婚姻状态值为Alone或YOLO的数据显示这些顾客家中都有儿女,因而可以将其归为Divorced类,而值为Absurd的顾客家中无儿女,这里简单的将其归为Single类
可以看到婚姻状况为YOLO两行数据除了ID列外其余列的数据相同,因此认定为重复项,因为数据集还可能有其它重复项,所以在这里先简单处理一下

print('除去',len(df)-len(df.drop_duplicates(subset=df.columns[1:])),'重复项')
df=df.drop_duplicates(subset=df.columns[1:])

输出:

除去 182 重复项

现在回头map前两列数据以及把时间列转为datetime类型

df['Marital_Status']=df['Marital_Status'].map({'Single':'1','Together':'4','Married':'5',
                                               'Divorced':'2','Widow':'3','Alone':'2',
                                               'Absurd':'1','YOLO':'2'}).astype(int)
df['Education']=df['Education'].map({'Graduation':'2', 'PhD':'5', 'Master':'4', 
                                     'Basic':'1', '2n Cycle':'3'}).astype(int)
df['Dt_Customer']=pd.to_datetime(df['Dt_Customer'])

注:数值大小根据来源为生活经验

3.你注意到数据中有什么异常吗?

现在看看其余列的数据分布是否有异常

df.drop(['ID','Education','Marital_Status','Dt_Customer'],1).plot(subplots=True, kind='box',
                                                                  layout=(5,5), figsize=(16,16), patch_artist=True)

输出:

根据箱图明显有异常值的是Year_Birth列,这里可以用均值代替异常值

df.loc[df['Year_Birth']<1910,'Year_Birth'] = df['Year_Birth'].mean()
4.对于给定的数据,你是否可以设计一些有用的变量?

日常商品购买量,全部商品购买量,年龄,顾客首次注册信息距今天数(根据时间长短可以判断是否为老顾客),以往营销活动参加次数

df['MntRegularTotal']=df[['MntWines', 'MntFruits','MntMeatProducts', 
                          'MntFishProducts','MntSweetProducts']].sum(1)
df['MntTotal']=df[['MntWines', 'MntFruits','MntMeatProducts', 'MntFishProducts', 
                   'MntSweetProducts','MntGoldProds']].sum(1)
df['Age']=2020-df['Year_Birth']
df['CustDuration_days'] = (pd.to_datetime('2020/1/1')-df['Dt_Customer']).apply(lambda x:x.days)
df['AccCamTotal'] = df[['AcceptedCmp3','AcceptedCmp4', 'AcceptedCmp5',
                        'AcceptedCmp1', 'AcceptedCmp2']].sum(1)

假设现在的时间是2020年1月1日

二、请以回归的形式运行统计测试以回答这些问题,并提出数据驱动的行动建议。用非统计术语来解释你的结果。 1.哪些因素与最后一次宣传活动的效果显著相关?

训练模型

from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
df_nor = df.drop(['ID','Year_Birth','Dt_Customer','Z_CostContact','Z_Revenue'],1).astype(float).
                apply(lambda x: (x-x.min())/(x.max()-x.min()),0)
train, val = train_test_split(
    df_nor, test_size=0.33, random_state=42)
clf_l2_LR = LogisticRegression( penalty="l2")
clf_l2_LR.fit(train.drop(['Response'],1),train['Response'])
print('逻辑回归模型验证集准确率为: ',accuracy_score(val['Response'],clf_l2_LR.predict(val.drop(['Response'],1))))

输出:



逻辑回归模型验证集准确率为: 0.875

fea_imp= {j:i for i , j in  zip(clf_l2_LR.coef_[0],train.drop(['Response'],1).columns)}
fea_imp = pd.DataFrame(fea_imp,index=[0]).T
fea_imp = fea_imp.sort_values(by=0,ascending=False)
plt.figure(figsize=(8,6))
sns.barplot(data = fea_imp,x=0,y=fea_imp.index)

输出:

顾客活跃度较高,并经常上网了解店铺优惠的忠实单身顾客会倾向于参加这次活动。
根据统计图的结果,参加这次活动的顾客倾向于上网浏览店铺(NumWebVisitMonth)的官网,而较少到实体店(NumStorePurchases)购买商品,并且网购次数(NumWebPurchases)可能也不算多,可以认为这些顾客总在网络寻找店铺可能出现的一些优惠或打折活动,所以他们参加这次活动的概率比较高。而且由于多为单身(Marital_Status)顾客,自由时间较多,参加活动的可能性更大。顾客活跃度较低(Recency)的顾客有可能为流失的客户,有可能不会有兴趣参加这次活动。

三、请回答以下问题的并可视化。 1.买黄金的人比较保守。因此,那些在过去2年花费高于平均水平黄金的人会有更多的商店购买,请问这句陈述是否正确。
df['goldAbove'] = 'Below' 
df.loc[df['MntGoldProds'] > df['MntGoldProds'].mean(),'goldAbove']='Above'
sns.violinplot(y=df['NumStorePurchases'],x=df['goldAbove'])

输出:

可以根据统计图看出, 购买黄金商品数量比平均值高的顾客,到店购买的次数分布上宽下窄,购买黄金商品数量比平均值低的顾客,到店购买的次数分布上窄下宽,陈述正确。

2.使用适当的统计测试来证明或反驳这种说法鱼含有对大脑有益的- 3脂肪酸。因此,“已婚博士候选人”与花在鱼上的钱有显著的关系吗?
df['Married PhD candidates'] = 'No' 
df.loc[(df['Education'] == 5)&(df['Marital_Status'] == 5),'Married PhD candidates']='Yes'
sns.violinplot(y=df['MntFishProducts'],x=df['Married PhD candidates'])

输出:

由图,两类顾客购买鱼类商品数量上的分布没有明显差异。

3.还有哪些因素与花在鱼上的钱有显著的关系?
corr = df_nor.corr()
corr['MntFishProducts'].sort_values(ascending=False)
plt.subplots(figsize=(10,10))
sns.heatmap(pd.DataFrame(corr['MntFishProducts']).sort_values(by='MntFishProducts',ascending=False),  cmap='BrBG',  center=0,
            square=True, linewidths=.5, cbar_kws={"shrink": 0.5})

由图,商品购买量高,目录购买次数高,到店购买次数高的顾客倾向于购买鱼类商品,并且与收入也有一定正相关关系。

总结

活动应以活跃度较高,并经常上网了解店铺优惠的忠实单身顾客为目标群体。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/931589.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号