案例背景
某企业由于投放的广告渠道比较多,需要对其做广告效果分析以实现有针对性的广告效果测量和优化工作。跟以应用为目的的案例不同的是,由于本案例是一个分析型案例,该过程的输出其实是不固定的,因此需要跟业务运营方具体沟通需求。
以下是在开展研究之前的基本预设条件:
- 广告渠道的范畴是什么?具体包括哪些渠道?——所有站外标记的广告类渠道(以ad_开头)。
- 数据集时间选择哪个时间段?——最近90天的数据。
- 数据集选择哪些维度和指标?——渠道代号、日均UV、平均注册率、平均搜索量、访问深度、平均停留时间、订单转化率、投放总时间、素材类型、广告类型、合作方式、广告尺寸、广告卖点。
- 专题分析要解决什么问题?——将广告分类并找出其重点特征,为接下来的业务讨论和数据分析提供支持。
案例数据
以下是本数据集的13个字段的详细说明:
- 渠道代号:业务方统一命名规划的唯一渠道标志。
- 日均UV:每天的平均独立访客,从一个渠道中带来的一个访客即使一天中到达多次都统计为1次。
- 平均注册率:日均注册的用户数量/平均每天的访问量。
- 平均搜索量:平均每个访问的搜索次数。
- 访问深度:总页面浏览量/平均每天的访问量。
- 平均停留时间:总停留时间/平均每天的访问量。
- 订单转化率:总订单数量/平均每天的访问量。
- 投放总时间:每个广告媒介在站外投放的天数。
- 素材类型:广告素材类型,包括jpg、gif、swf、sp。
- 广告类型:广告投放类型,包括banner、tips、横幅、通栏、暂停以及不确定(不知道到底是何种形式)。
- 合作方式:广告合作方式,包括roi、cpc、cpm和cpd。
- 广告尺寸:每个广告投放的尺寸大小,包括14040、308388、450300、60090、480360、960126、900120、390270。
- 广告卖点:广告素材上主要的卖点诉求信息,包括打折、满减、满赠、秒杀、直降、满返。
案例实现
import numpy as np
import pandas as pd
from sklearn.feature_extraction import DictVectorizer
from sklearn.preprocessing import MinMaxScaler
from sklearn.cluster import KMeans
from sklearn import metrics # 导入sklearn效果评估模块
import matplotlib.pyplot as plt
%matplotlib inline
# 载入数据,空格为间隔
df = pd.read_csv('https://raw.githubusercontent.com/ffzs/dataset/master/ad_performance.txt', delimiter='\t')
# 数据概观
df.tail(3).T
# 数据类型
df.dtypes
'''
渠道代号 object
日均UV float64
平均注册率 float64
平均搜索量 float64
访问深度 float64
平均停留时间 float64
订单转化率 float64
投放总时间 float64
素材类型 object
广告类型 object
合作方式 object
广告尺寸 object
广告卖点 object
dtype: object
'''
# 缺失值情况
df.isna().sum()
'''
渠道代号 0
日均UV 0
平均注册率 0
平均搜索量 0
访问深度 0
平均停留时间 2
订单转化率 0
投放总时间 0
素材类型 0
广告类型 0
合作方式 0
广告尺寸 0
广告卖点 0
dtype: int64
'''
# 原始数据基本描述
df.describe().round(3)
如下的描述性统计结果中,反映了3个信息点:
- 日均UV的数据标准差很大,说明了不同渠道间的特征差异非常明显。
- 平均停留时间的有效数据(非空数据)只有887,比其他数据少2条,这也印证了上述缺失值统计结果。
- 平均注册率、平均搜索量、订单转化率的多个统计量(例如最小值、25%分位数等)都为0,看似数据不太正常。
# 计算特征相关性
df.corr()
通过相关性结果分析,12个特征中平均停留时间和访问深度的相关系数为0.72,这两个指标具有较高的相关性,但特征也不是非常明显;其他特征之间的相关性关系都不突出。
# 使用平均值替换缺失值
df = df.fillna(df['平均停留时间'].mean())
# 字符串分类转整数分类
conver_cols = ['素材类型', '广告类型', '合作方式', '广告尺寸', '广告卖点']
convert_matrix = df[conver_cols] # 获得要转换的数组
lines = df.shape[0] # 获得总记录数
dict_list = [] # 总空列表,用于存放字符串与对应索引组成的字典
unique_list =