1、项目背景
以英国的在线电子零售公司的跨国交易数据集作为分析样本,通过对该公司的运营指标统计分析以及构建RMF模型、K-Means机器学习算法从大量的电子零售交易数据中分析并找出价值用户,针对价值用户提供以消费者为中心的智能商业模式。
2、数据详情
2.1 数据来源
数据集来自一个在英国注册的在线电子零售公司,其中包含2010年12月1日到2011年12月9日期间发生的网络交易数据。
2.2 数据量
数据集总共有541909条数据,8个字段
2.3 数据理解
字段名
含义
InvoiceNo
发票编号。为每笔订单唯一分配的6位整数。若以字母’C’开头,则表示该订单 被取消。
StockCode
产品代码。为每个产品唯一分配的编码。
Description
产品描述。
Quantity
数量。每笔订单中各产品分别的数量。
InvoiceDate
发票日期和时间。每笔订单发生的日期和时间。
UnitPrice
单价。单位产品价格,单位为英镑。
CustomerID
客户编号。为每个客户唯一分配的5位整数。
Country
国家。客户所在国家/地区的名称
3、数据清洗
3.1 准备工作
import pandas as pd
import numpy as np
import datetime as dt
import matplotlib. pyplot as plt
% matplotlib inline
plt. style. use( 'seaborn' )
plt. rcParams[ 'font.sans-serif' ] = [ 'SimHei' ]
plt. rcParams[ 'axes.unicode_minus' ] = False
import seaborn as sns
from sklearn. preprocessing import StandardScaler
from sklearn. cluster import KMeans
import warnings
warnings. filterwarnings( "ignore" )
salesOR = pd. read_csv( 'Online Retail.csv' )
salesOR. head( )
InvoiceNo
StockCode
Description
Quantity
InvoiceDate
UnitPrice
CustomerID
Country
0
536365
85123A
WHITE HANGING HEART T-LIGHT HOLDER
6
2010/12/1 8:26
2.55
17850.0
United Kingdom
1
536365
71053
WHITE METAL LANTERN
6
2010/12/1 8:26
3.39
17850.0
United Kingdom
2
536365
84406B
CREAM CUPID HEARTS COAT HANGER
8
2010/12/1 8:26
2.75
17850.0
United Kingdom
3
536365
84029G
KNITTED UNION FLAG HOT WATER BOTTLE
6
2010/12/1 8:26
3.39
17850.0
United Kingdom
4
536365
84029E
RED WOOLLY HOTTIE WHITE HEART.
6
2010/12/1 8:26
3.39
17850.0
United Kingdom
查看数据信息
salesOR. shape
(541909, 8)
salesOR. info( )
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 541909 entries, 0 to 541908
Data columns (total 8 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 InvoiceNo 541909 non-null object
1 StockCode 541909 non-null object
2 Description 540455 non-null object
3 Quantity 541909 non-null int64
4 InvoiceDate 541909 non-null object
5 UnitPrice 541909 non-null float64
6 CustomerID 406829 non-null float64
7 Country 541909 non-null object
dtypes: float64(2), int64(1), object(5)
memory usage: 33.1+ MB
3.2 删除重复值
salesOR_NoDup= salesOR. drop_duplicates( subset= [ 'InvoiceNo' , 'StockCode' , 'Description' , 'Quantity' , 'InvoiceDate' , 'UnitPrice' , 'CustomerID' , 'Country' ] )
dup= salesOR. shape[ 0 ] - salesOR_NoDup. shape[ 0 ]
print ( 'duplicates =' , dup)
duplicates = 5268
共删除了5268条重复数据
3.3 缺失值处理
查看数据缺失情况
tab_info= pd. DataFrame( salesOR. dtypes) . T. rename( index= {
0 : '特征类型' } )
tab_info= tab_info. append( pd. DataFrame( salesOR. isnull( ) . sum ( ) ) . T. rename( index= {
0 : '缺失值数量' } ) )
tab_info= tab_info. append( pd. DataFrame( salesOR. isnull( ) . sum ( ) / salesOR. shape[ 0 ] ) . T.
rename( index= {
0 : '缺失值占比' } ) )
display( tab_info)
InvoiceNo
StockCode
Description
Quantity
InvoiceDate
UnitPrice
CustomerID
Country
特征类型
object
object
object
int64
object
float64
float64
object
缺失值数量
0
0
1454
0
0
0
135080
0
缺失值占比
0.0
0.0
0.002683
0.0
0.0
0.0
0.249267
0.0
从上表可以看出,有近25%的条目未分配给特定客户。在现有的数据下,不可能为用户估算出数值,因此这些条目对目前的工作没有用处。所以应当从数据框中删除它们。
salesOR_NoDupNA= salesOR_NoDup. dropna( subset= [ 'InvoiceNo' , 'CustomerID' ] , how= 'any' )
missing= salesOR_NoDup. shape[ 0 ] - salesOR_NoDupNA. shape[ 0 ]
print ( 'missings =' , missing)
missings = 135037
共删除InvoiceNo 和 CustomerID字段缺失的数据135037条
3.4 数据一致化处理
将字符串类型数据转化为数值类型
salesOR_NoDupNA[ 'Quantity' ] = salesOR_NoDupNA[ 'Quantity' ] . astype( 'float' )
salesOR_NoDupNA[ 'UnitPrice' ] = salesOR_NoDupNA[ 'UnitPrice' ] . astype( 'float' )
salesOR_NoDupNA[ 'CustomerID' ] = salesOR_NoDupNA[ 'CustomerID' ] . astype( 'object' )
print ( 'Data type after changing:\n' , salesOR_NoDupNA. dtypes)
Data type after changing:
InvoiceNo object
StockCode object
Description object
Quantity float64
InvoiceDate object
UnitPrice float64
CustomerID object
Country object
dtype: object
将字符串类型数据转化为日期类型
salesOR_NoDupNA[ 'InvoiceDate' ] = pd. to_datetime( salesOR_NoDupNA[ 'InvoiceDate' ] , errors= 'coerce' )
salesOR_NoDupNA[ 'Year' ] = salesOR_NoDupNA[ 'InvoiceDate' ] . dt. year
salesOR_NoDupNA[ 'Month' ] = salesOR_NoDupNA[ 'InvoiceDate' ] . dt. month
salesOR_NoDupNA[ 'Date' ] = salesOR_NoDupNA[ 'InvoiceDate' ] . dt. date
salesOR_NoDupNA[ 'weekday' ] = salesOR_NoDupNA[ 'InvoiceDate' ] . dt. weekday
salesOR_NoDupNA. head( )
InvoiceNo
StockCode
Description
Quantity
InvoiceDate
UnitPrice
CustomerID
Country
Year
Month
Date
weekday
0
536365
85123A
WHITE HANGING HEART T-LIGHT HOLDER
6.0
2010-12-01 08:26:00
2.55
17850.0
United Kingdom
2010
12
2010-12-01
2
1
536365
71053
WHITE METAL LANTERN
6.0
2010-12-01 08:26:00
3.39
17850.0
United Kingdom
2010
12
2010-12-01
2
2
536365
84406B
CREAM CUPID HEARTS COAT HANGER
8.0
2010-12-01 08:26:00
2.75
17850.0
United Kingdom
2010
12
2010-12-01
2
3
536365
84029G
KNITTED UNION FLAG HOT WATER BOTTLE
6.0
2010-12-01 08:26:00
3.39
17850.0
United Kingdom
2010
12
2010-12-01
2
4
536365
84029E
RED WOOLLY HOTTIE WHITE HEART.
6.0
2010-12-01 08:26:00
3.39
17850.0
United Kingdom
2010
12
2010-12-01
2
数据转换过程中不符合日期格式的会转换为空值,需要再进行一次删除缺失值处理。
salesOR_NoDupNA= salesOR_NoDupNA. dropna( subset= [ 'InvoiceNo' , 'CustomerID' , 'InvoiceDate' ] , how= 'any' )
3.5 异常值处理
salesOR_NoDupNA[ [ 'Quantity' , 'UnitPrice' ] ] . describe( )
Quantity
UnitPrice
count
401604.000000
401604.000000
mean
12.183273
3.474064
std
250.283037
69.764035
min
-80995.000000
0.000000
25%
2.000000
1.250000
50%
5.000000
1.950000
75%
12.000000
3.750000
max
80995.000000
38970.000000
描述指标中购买产品的数量最小值为-8095,单品单价为0,这两个不符合实际情况确认为异常值。
querySer= salesOR_NoDupNA. loc[ : , 'Quantity' ] > 0
salesOR_NoDupNA= salesOR_NoDupNA. loc[ querySer, : ]
querySer1= salesOR_NoDupNA. loc[ : , 'UnitPrice' ] > 0
salesOR_NoDupNA= salesOR_NoDupNA. loc[ querySer1, : ]
print ( 'after delete outlier:' , salesOR_NoDupNA. shape)
after delete outlier: (392692, 12)
经过两次条件判断之后数据集大小为(392692,10),为了检查处理后的结果,再次检查描述指标:
salesOR_NoDupNA[ [ 'Quantity' , 'UnitPrice' ] ] . describe( )
Quantity
UnitPrice
count
392692.000000
392692.000000
mean
13.119702
3.125914
std
180.492832
22.241836
min
1.000000
0.001000
25%
2.000000
1.250000
50%
6.000000
1.950000
75%
12.000000
3.750000
max
80995.000000
8142.750000
原数据集的时期是2010-12-1到2011-12-09,2011年12月数据不满一个月,为了方便分析和讨论本次分析选择数据时间为:2010-12-01到2011-11-30,12个月。
querySer2= salesOR_NoDupNA. loc[ : , 'InvoiceDate' ] < '2011-12-01'
salesOR_NoDupNA= salesOR_NoDupNA. loc[ querySer2, : ]
print ( '删除2011-11-30之后的数据:' , salesOR_NoDupNA. shape)
删除2011-11-30之后的数据: (375666, 12)
4、运营指标统计分析
4.1 月追踪:月销售量、月销售额、月均销售额
4.11 月销售量
transUni= salesOR_NoDupNA. drop_duplicates( subset= [ 'InvoiceNo' ] )
monthly_trans= transUni. groupby