电商-广告投放效果分析(KMeans聚类、数据分析-pyhton数据分析

本文主要是介绍电商-广告投放效果分析(KMeans聚类、数据分析-pyhton数据分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

电商-广告投放效果分析(KMeans聚类、数据分析)

文章目录

  • 电商-广告投放效果分析(KMeans聚类、数据分析)
  • 项目介绍
    • 数据
      • 数据维度概况
      • 数据13个维度介绍
    • 导入库,加载数据
    • 数据审查
    • 相关性分析
    • 数据处理
    • 建立模型
    • 聚类结果特征分析与展示
    • 数据结论

项目介绍

数据

假如公司投放广告的渠道很多,每个渠道的客户性质也可能不同,比如在优酷视频投广告和今日头条投放广告,效果可能会有差异。现在需要对广告效果分析实现有针对性的广告效果测量和优化工作。

本案例,通过各类广告渠道90天内额日均UV,平均注册率、平均搜索率、访问深度、平均停留时长、订单转化率、投放时间、素材类型、广告类型、合作方式、广告尺寸和广告卖点等特征,将渠道分类,找出每类渠道的重点特征,为加下来的业务讨论和数据分析提供支持。

数据维度概况

除了渠道唯一标识,共12个维度,889行,有缺失值,有异常值。

数据13个维度介绍

1、渠道代号:渠道唯一标识
2、日均UV:每天的独立访问量
3、平均注册率=日均注册用户数/平均每日访问量
4、平均搜索量:每个访问的搜索量
5、访问深度:总页面浏览量/平均每天的访问量
6、平均停留时长=总停留时长/平均每天的访问量
7、订单转化率=总订单数量/平均每天的访客量
8、投放时间:每个广告在外投放的天数
9、素材类型:‘jpg’ ‘swf’ ‘gif’ ‘sp’
10、广告类型:banner、tips、不确定、横幅、暂停
11、合作方式:‘roi’ ‘cpc’ ‘cpm’ ‘cpd’
12、广告尺寸:‘14040’ '308388’ ‘450300’ '60090’ ‘480360’ '960126’ ‘900120’ '390270’
13、广告卖点:打折、满减、满赠、秒杀、直降、满返

导入库,加载数据

import pandas as pd 
import numpy as np 
import matplotlib as mpl 
import matplotlib.pyplot as plt 
from sklearn.preprocessing import MinMaxScaler,OneHotEncoder 
from sklearn.metrics import silhouette_score # 导入轮廓系数指标
from sklearn.cluster import KMeans # KMeans模块
%matplotlib inline
## 设置属性防止中文乱码
mpl.rcParams['font.sans-serif'] = [u'SimHei']
mpl.rcParams['axes.unicode_minus'] = False

以上是加载库的国际惯例,OneHotEncoder是独热编码,如果一个类别特征有n个类别,将该变量按照类别分裂成N维新变量,包含则标记为1,否则为0,用N维特征表示原来的特征。

raw_data = pd.read_csv(r'./ad_performance.csv')
raw_data.head()
  1. raw_data = pd.read_csv(r'./ad_performance.csv'):这行代码使用Pandas库的read_csv()函数读取名为 “ad_performance.csv” 的CSV文件中的数据,并将数据加载到名为 raw_data 的DataFrame对象中。r'./ad_performance.csv' 是CSV文件的路径。r 表示使用原始字符串,防止反斜杠被转义。

  2. raw_data.head():这行代码使用DataFrame对象的head()方法查看DataFrame的前几行数据,默认显示前5行。这有助于了解数据的结构和格式。

数据审查

# 查看基本状态
raw_data.head(2)  # 打印输出前2条数据
raw_data.info()# 打印数据类型分布
raw_data.describe().round(2).T # 打印原始数据基本描述性信息
# 缺失值审查
na_cols = raw_data.isnull().any(axis=0)  # 查看每一列是否具有缺失值
na_cols
raw_data.isnull().sum().sort_values(ascending=False)# 查看具有缺失值的行总记录数
  1. raw_data.head(2):这行代码打印输出了数据的前两条记录,以便快速查看数据的样式和结构。

  2. raw_data.info():这行代码打印输出了数据集中每一列的数据类型以及非空值的数量,这有助于了解数据的完整性和类型。

  3. raw_data.describe().round(2).T:这行代码打印了数据集的基本描述性信息,包括计数、均值、标准差、最小值、25%分位数、中位数、75%分位数和最大值。.round(2)方法用于将描述性统计结果保留两位小数,.T方法用于转置结果,以便查看。

  4. na_cols = raw_data.isnull().any(axis=0):这行代码查看了每一列是否具有缺失值。raw_data.isnull()会生成一个布尔值的DataFrame,表示每个单元格是否为缺失值,.any(axis=0)会沿着列方向(axis=0)判断是否有至少一个True,即是否存在缺失值。

  5. na_cols:这行代码会输出一个布尔型Series,其中索引是DataFrame的列名,值为True表示该列存在缺失值,值为False表示该列没有缺失值。

  6. raw_data.isnull().sum().sort_values(ascending=False):这行代码查看了具有缺失值的列,并统计了每列的缺失值数量,并按照缺失值数量降序排列。.isnull()用于判断每个单元格是否为缺失值,.sum()对每列的缺失值数量进行求和,.sort_values(ascending=False)将结果按照缺失值数量进行降序排序。

相关性分析

# 相关性分析
raw_data.corr(numeric_only=True).round(2).T # 打印原始数据相关性信息
# 相关性可视化展示
import seaborn as sns 
corr = raw_data.corr().round(2)
sns.heatmap(corr,cmap='Reds',annot = True)
  1. raw_data.corr(numeric_only=True).round(2).T:这行代码计算了原始数据中数值型列之间的相关性,并将结果打印输出。.corr(numeric_only=True)表示只考虑数值型列之间的相关性,.round(2)将相关性系数保留两位小数,.T方法用于转置结果,以便查看。

  2. import seaborn as sns:这行代码导入了Seaborn库,用于绘制数据可视化图形。

  3. corr = raw_data.corr().round(2):这行代码计算了原始数据的相关性矩阵,并将相关性系数保留两位小数。

  4. sns.heatmap(corr,cmap='Reds',annot = True):这行代码绘制了一个热力图来展示相关性矩阵。heatmap()函数用于绘制热力图,corr是相关性矩阵,cmap='Reds'指定了颜色映射为红色调,annot = True表示在图中显示相关性系数的数值。

在这里插入图片描述

数据处理

数据了解的差不多了,我们开始时处理数据,把常规数据通过清洗、转换、规约、聚合、抽样等方式变成机器学习可以识别或者提升准确度的数据。

# 1 删除平均平均停留时间列
raw_data2 = raw_data.drop(['平均停留时间'],axis=1)
  1. raw_data2 = raw_data.drop(['平均停留时间'],axis=1):这行代码使用了DataFrame的drop()方法,通过指定'平均停留时间'列和axis=1参数,从原始数据中删除了’平均停留时间’列。删除操作不会在原始数据上进行,而是返回一个新的DataFrame对象,即raw_data2,其中不包含被删除的列。

类别变量的独热编码:

# 类别变量取值
cols=["素材类型","广告类型","合作方式","广告尺寸","广告卖点"]
for x in cols:data=raw_data2[x].unique()print("变量【{0}】的取值有:\n{1}".format(x,data))print("-·"*20)
  1. cols=["素材类型","广告类型","合作方式","广告尺寸","广告卖点"]:定义了一个列表 cols,其中包含了需要统计取值的类别变量的列名。

  2. for x in cols::这是一个循环语句,用于遍历列表 cols 中的每个元素。

  3. data=raw_data2[x].unique():这行代码获取了 DataFrame 中列 x(循环变量)的唯一取值,即去除重复后的取值列表。

  4. print("变量【{0}】的取值有:\n{1}".format(x,data)):这行代码使用字符串格式化,打印输出了变量 x 的取值列表。其中 {0}{1} 分别被循环变量 x 和取值列表 data 所替代。

  5. print("-·"*20):这行代码打印了一条分隔线,用于区分不同类别变量的取值统计结果。

# 字符串分类独热编码处理
cols = ['素材类型','广告类型','合作方式','广告尺寸','广告卖点'] 
model_ohe = OneHotEncoder(sparse=False)  # 建立OneHotEncode对象
ohe_matrix = model_ohe.fit_transform(raw_data2[cols])  # 直接转换
print(ohe_matrix[:2])
  1. cols = ['素材类型','广告类型','合作方式','广告尺寸','广告卖点']:定义了一个列表 cols,其中包含了需要进行独热编码处理的字符串分类变量的列名。

  2. model_ohe = OneHotEncoder(sparse=False):这行代码创建了一个OneHotEncoder对象 model_ohe,用于进行独热编码处理。sparse=False参数表示不生成稀疏矩阵,而是直接生成密集矩阵。

  3. ohe_matrix = model_ohe.fit_transform(raw_data2[cols]):这行代码对原始数据集 raw_data2 中的 cols 列进行独热编码处理,得到编码后的矩阵。fit_transform()方法将字符串分类变量转换为独热编码表示。

  4. print(ohe_matrix[:2]):这行代码打印输出了独热编码后的矩阵的前两行。这样做是为了查看编码结果是否符合预期。

# 用pandas的方法
ohe_matrix1=pd.get_dummies(raw_data2[cols])
ohe_matrix1.head(5)
  1. ohe_matrix1=pd.get_dummies(raw_data2[cols]):这行代码调用了 Pandas 的 get_dummies() 方法,对原始数据集 raw_data2 中的 cols 列进行独热编码处理。get_dummies() 方法会将指定列中的每个分类值都转换为一个独热编码的列,并生成一个新的 DataFrame 对象 ohe_matrix1

  2. ohe_matrix1.head(5):这行代码打印输出了独热编码后的结果的前 5 行。这样做是为了查看编码结果是否符合预期。

# 数据标准化
sacle_matrix = raw_data2.iloc[:, 1:7]  # 获得要转换的矩阵
model_scaler = MinMaxScaler()  # 建立MinMaxScaler模型对象
data_scaled = model_scaler.fit_transform(sacle_matrix)  # MinMaxScaler标准化处理
print(data_scaled.round(2))
  1. sacle_matrix = raw_data2.iloc[:, 1:7]:这行代码从原始数据集 raw_data2 中提取了需要进行标准化处理的数据子集。iloc[:, 1:7]表示选取所有行,以及第 2 到第 7 列的数据(Python中索引是从0开始的)。

  2. model_scaler = MinMaxScaler():这行代码创建了一个MinMaxScaler对象 model_scaler,用于进行最小-最大缩放标准化处理。

  3. data_scaled = model_scaler.fit_transform(sacle_matrix):这行代码使用 fit_transform() 方法对提取的数据子集 sacle_matrix 进行标准化处理,得到标准化后的结果。MinMaxScaler会将每列的数据缩放到指定的范围(默认为[0, 1]),并返回一个标准化后的NumPy数组 data_scaled

  4. print(data_scaled.round(2)):这行代码打印输出了标准化后的数据,使用 round(2) 方法保留两位小数。这样做是为了查看标准化后的数据是否符合预期。

# # 合并所有维度
X = np.hstack((data_scaled, ohe_matrix))
  1. np.hstack((data_scaled, ohe_matrix)):这行代码使用了 NumPy 的 hstack() 函数,将两个矩阵水平堆叠在一起。data_scaled 是经过标准化处理后的特征矩阵,ohe_matrix 是经过独热编码处理后的特征矩阵。水平堆叠意味着将两个矩阵按列连接起来。

  2. X = np.hstack((data_scaled, ohe_matrix)):这行代码将水平堆叠后的矩阵赋值给变量 X,这样就得到了合并后的特征矩阵 X,其中包含了标准化处理后的数据和独热编码处理后的数据。

建立模型

# 通过平均轮廓系数检验得到最佳KMeans聚类模型
score_list = list()  # 用来存储每个K下模型的平局轮廓系数
silhouette_int = -1  # 初始化的平均轮廓系数阀值
for n_clusters in range(2, 8):  # 遍历从2到5几个有限组model_kmeans = KMeans(n_clusters=n_clusters)  # 建立聚类模型对象labels_tmp = model_kmeans.fit_predict(X)  # 训练聚类模型silhouette_tmp = silhouette_score(X, labels_tmp)  # 得到每个K下的平均轮廓系数if silhouette_tmp > silhouette_int:  # 如果平均轮廓系数更高best_k = n_clusters  # 保存K将最好的K存储下来silhouette_int = silhouette_tmp  # 保存平均轮廓得分best_kmeans = model_kmeans  # 保存模型实例对象cluster_labels_k = labels_tmp  # 保存聚类标签score_list.append([n_clusters, silhouette_tmp])  # 将每次K及其得分追加到列表
print('{:*^60}'.format('K值对应的轮廓系数:'))
print(np.array(score_list))  # 打印输出所有K下的详细得分
print('最优的K值是:{0} \n对应的轮廓系数是:{1}'.format(best_k, silhouette_int))

总体思想(评价指标)还是怎么聚才能使得簇内距离足够小,簇与簇之间平均距离足够大来评判。

  1. score_list = list():创建一个空列表,用于存储每个K值下模型的平均轮廓系数。

  2. silhouette_int = -1:初始化平均轮廓系数的阈值为-1。

  3. for n_clusters in range(2, 8)::循环遍历从2到7的整数,这些整数代表了KMeans聚类模型的聚类数。

  4. model_kmeans = KMeans(n_clusters=n_clusters):创建一个KMeans聚类模型对象,其中n_clusters参数表示要创建的聚类数。

  5. labels_tmp = model_kmeans.fit_predict(X):利用输入数据 X 对KMeans模型进行训练,并预测每个样本的聚类标签。

  6. silhouette_tmp = silhouette_score(X, labels_tmp):计算当前K值下的平均轮廓系数,用来衡量聚类效果的好坏。

  7. if silhouette_tmp > silhouette_int::如果当前K值下的平均轮廓系数大于之前的最高值。

  8. best_k = n_clusters:更新最佳的K值为当前K值。

  9. silhouette_int = silhouette_tmp:更新最高的平均轮廓系数为当前轮廓系数。

  10. best_kmeans = model_kmeans:保存当前最佳的KMeans聚类模型对象。

  11. cluster_labels_k = labels_tmp:保存当前最佳的聚类标签。

  12. score_list.append([n_clusters, silhouette_tmp]):将当前K值和对应的平均轮廓系数追加到列表score_list中。

  13. print('{:*^60}'.format('K值对应的轮廓系数:')):打印输出一个60个星号的分割线。

  14. print(np.array(score_list)):打印输出所有K值及其对应的平均轮廓系数。

  15. print('最优的K值是:{0} \n对应的轮廓系数是:{1}'.format(best_k, silhouette_int)):打印输出最佳的K值和对应的平均轮廓系数。

聚类结果特征分析与展示

通过上面模型,我们其实给每个观测(样本)打了个标签clusters,即他属于4类中的哪一类:

# 将原始数据与聚类标签整合
cluster_labels = pd.DataFrame(cluster_labels_k, columns=['clusters'])  # 获得训练集下的标签信息
merge_data = pd.concat((raw_data2, cluster_labels), axis=1)  # 将原始处理过的数据跟聚类标签整合
merge_data.head()
  1. cluster_labels = pd.DataFrame(cluster_labels_k, columns=['clusters']):这行代码创建了一个名为 cluster_labels 的DataFrame对象,其中包含了聚类模型预测得到的聚类标签信息。cluster_labels_k 是之前代码中得到的聚类标签数据,columns=['clusters'] 指定了DataFrame的列名为’clusters’。

  2. merge_data = pd.concat((raw_data2, cluster_labels), axis=1):这行代码使用了 Pandas 的 concat() 函数,将原始处理过的数据 raw_data2 与聚类标签数据 cluster_labels 沿着列方向(axis=1)进行合并。合并后的结果赋值给变量 merge_data

  3. merge_data.head():这行代码打印输出了合并后的DataFrame的前几行数据。这样做是为了查看整合后的数据是否符合预期。

然后看看,每个类别下的样本数量和占比情况:

# 计算每个聚类类别下的样本量和样本占比
clustering_count = pd.DataFrame(merge_data['渠道代号'].groupby(merge_data['clusters']).count()).T.rename({'渠道代号': 'counts'})  # 计算每个聚类类别的样本量
clustering_ratio = (clustering_count / len(merge_data)).round(2).rename({'counts': 'percentage'})  # 计算每个聚类类别的样本量占比
print(clustering_count)
print("#"*30)
print(clustering_ratio)
  1. clustering_count = pd.DataFrame(merge_data['渠道代号'].groupby(merge_data['clusters']).count()).T.rename({'渠道代号': 'counts'}):这行代码首先使用 Pandas 的 groupby() 函数按照聚类标签 clusters渠道代号 这一列进行分组,然后对每个组计算该列的计数。结果是一个包含每个聚类类别下的样本量的 Series 对象。接着使用 pd.DataFrame() 将其转换为 DataFrame,并进行转置(.T)操作,以使行和列对调。最后使用 rename() 函数将列名 渠道代号 更改为 counts,以反映其含义。

  2. clustering_ratio = (clustering_count / len(merge_data)).round(2).rename({'counts': 'percentage'}):这行代码计算每个聚类类别的样本量占比。首先将每个聚类类别的样本量除以总样本量,然后使用 round(2) 方法将结果保留两位小数。接着使用 rename() 函数将列名 counts 更改为 percentage,以反映其含义。

  3. print(clustering_count):打印输出每个聚类类别下的样本量。

  4. print("#"*30):打印输出一个包含30个 ‘#’ 字符的分隔线。

  5. print(clustering_ratio):打印输出每个聚类类别的样本量占比。

每个类别内部最显著的特征:

# 计算各个聚类类别内部最显著特征值
cluster_features = []  # 空列表,用于存储最终合并后的所有特征信息
for line in range(best_k):  # 读取每个类索引label_data = merge_data[merge_data['clusters'] == line]  # 获得特定类的数据part1_data = label_data.iloc[:, 1:7]  # 获得数值型数据特征part1_desc = part1_data.describe().round(3)  # 得到数值型特征的描述性统计信息merge_data1 = part1_desc.iloc[2, :]  # 得到数值型特征的均值part2_data = label_data.iloc[:, 7:-1]  # 获得字符串型数据特征part2_desc = part2_data.describe(include='all')  # 获得字符串型数据特征的描述性统计信息merge_data2 = part2_desc.iloc[2, :]  # 获得字符串型数据特征的最频繁值merge_line = pd.concat((merge_data1, merge_data2), axis=0)  # 将数值型和字符串型典型特征沿行合并cluster_features.append(merge_line)  # 将每个类别下的数据特征追加到列表#  输出完整的类别特征信息
cluster_pd = pd.DataFrame(cluster_features).T  # 将列表转化为矩阵
print('{:*^60}'.format('每个类别主要的特征:'))
all_cluster_set = pd.concat((clustering_count, clustering_ratio, cluster_pd),axis=0)  # 将每个聚类类别的所有信息合并
all_cluster_set
  1. cluster_features = []:创建一个空列表,用于存储每个聚类类别内部最显著的特征值。

  2. for line in range(best_k)::循环遍历每个聚类类别的索引。

  3. label_data = merge_data[merge_data['clusters'] == line]:获取特定聚类类别的数据,即通过筛选出'clusters'列值等于当前索引值的行。

  4. part1_data = label_data.iloc[:, 1:7]part2_data = label_data.iloc[:, 7:-1]:分别提取数值型特征和字符串型特征的数据子集。

  5. part1_desc = part1_data.describe().round(3)part2_desc = part2_data.describe(include='all'):分别计算数值型特征和字符串型特征的描述性统计信息。

  6. merge_data1 = part1_desc.iloc[2, :]merge_data2 = part2_desc.iloc[2, :]:分别获取数值型特征和字符串型特征的均值(数值型特征)或最频繁值(字符串型特征)。

  7. merge_line = pd.concat((merge_data1, merge_data2), axis=0):将数值型特征和字符串型特征沿行方向合并为一个Series对象。

  8. cluster_features.append(merge_line):将每个类别下的数据特征追加到列表cluster_features中。

  9. cluster_pd = pd.DataFrame(cluster_features).T:将列表cluster_features转换为DataFrame对象,转置以便特征信息按列排列。

  10. all_cluster_set = pd.concat((clustering_count, clustering_ratio, cluster_pd),axis=0):将聚类类别的样本量、样本占比和主要特征值信息沿着行方向合并为一个DataFrame对象all_cluster_set

  11. print('{:*^60}'.format('每个类别主要的特征:')):打印输出一个包含60个星号的标题行,用于分隔不同部分的输出。

  12. print(all_cluster_set):打印输出合并后的聚类类别的所有信息,包括样本量、样本占比和主要特征值信息。

图形化输出:

#各类别数据预处理
num_sets = cluster_pd.iloc[:6, :].T.astype(np.float64)  # 获取要展示的数据
num_sets_max_min = model_scaler.fit_transform(num_sets)  # 获得标准化后的数据
print(num_sets)
print('-'*20)
print(num_sets_max_min)
  1. num_sets = cluster_pd.iloc[:6, :].T.astype(np.float64):这行代码从合并后的聚类类别特征数据 cluster_pd 中提取了前6行(即数值型特征)的转置,并将其转换为np.float64类型的数据。这样做是为了将数据按列排列,方便后续处理。

  2. num_sets_max_min = model_scaler.fit_transform(num_sets):这行代码利用之前创建的 MinMaxScaler 对象 model_scaler 对数值型特征数据进行标准化处理。使用 fit_transform() 方法对数据进行标准化,将数据缩放到[0, 1]的范围内。

  3. print(num_sets):打印输出原始的数值型特征数据,用于查看。

  4. print('-'*20):打印输出一行分隔线。

  5. print(num_sets_max_min):打印输出标准化后的数值型特征数据,用于查看。

# 画图
fig = plt.figure(figsize=(7,7))  # 建立画布
ax = fig.add_subplot(111, polar=True)  # 增加子网格,注意polar参数
labels = np.array(merge_data1.index)  # 设置要展示的数据标签
cor_list = ['g', 'r', 'y', 'b']  # 定义不同类别的颜色
angles = np.linspace(0, 2 * np.pi, len(labels), endpoint=False)  # 计算各个区间的角度
angles = np.concatenate((angles, [angles[0]]))  # 建立相同首尾字段以便于闭合
# 画雷达图
for i in range(len(num_sets)):  # 循环每个类别data_tmp = num_sets_max_min[i, :]  # 获得对应类数据data = np.concatenate((data_tmp, [data_tmp[0]]))  # 建立相同首尾字段以便于闭合ax.plot(angles, data, 'o-', c=cor_list[i], label="第%d类渠道"%(i))  # 画线ax.fill(angles, data,alpha=0.8)# 设置图像显示格式
print(angles)
print(labels)ax.set_thetagrids(angles[0:-1] * 180 / np.pi, labels, fontproperties="SimHei")  # 设置极坐标轴
ax.set_title("各聚类类别显著特征对比", fontproperties="SimHei")  # 设置标题放置
ax.set_rlim(-0.2, 1.2)  # 设置坐标轴尺度范围
plt.legend(loc="upper right" ,bbox_to_anchor=(1.2,1.0))  # 设置图例位置
  1. fig = plt.figure(figsize=(7,7)):创建一个大小为7x7的画布。

  2. ax = fig.add_subplot(111, polar=True):在画布上添加一个极坐标子网格,参数polar=True表示使用极坐标。

  3. labels = np.array(merge_data1.index):将聚类类别的特征名称作为要展示的数据标签。

  4. cor_list = ['g', 'r', 'y', 'b']:定义不同类别的颜色。

  5. angles = np.linspace(0, 2 * np.pi, len(labels), endpoint=False):计算各个特征区间的角度。

  6. angles = np.concatenate((angles, [angles[0]])):建立相同首尾字段以便于闭合。

  7. for i in range(len(num_sets))::遍历每个聚类类别。

  8. data_tmp = num_sets_max_min[i, :]:获取当前聚类类别对应的标准化后的特征数据。

  9. data = np.concatenate((data_tmp, [data_tmp[0]])):建立相同首尾字段以便于闭合。

  10. ax.plot(angles, data, 'o-', c=cor_list[i], label="第%d类渠道"%(i)):绘制雷达图,表示各个特征在当前聚类类别下的数值,使用不同颜色区分不同类别。

  11. ax.fill(angles, data,alpha=0.8):填充雷达图的闭合区域,以加强可视化效果。

  12. ax.set_thetagrids(angles[0:-1] * 180 / np.pi, labels, fontproperties="SimHei"):设置极坐标轴的刻度标签和标签文字。

  13. ax.set_title("各聚类类别显著特征对比", fontproperties="SimHei"):设置雷达图的标题。

  14. ax.set_rlim(-0.2, 1.2):设置雷达图的坐标轴尺度范围。

  15. plt.legend(loc="upper right" ,bbox_to_anchor=(1.2,1.0)):设置图例的位置,将图例放在图的右上角。

在这里插入图片描述

数据结论

从案例结果来看,所有的渠道被分为4各类别,每个类别的样本量分别为:154、313、349 、73,对应占比分别为:17%、35%、39%、8%。

通过雷达图可以清楚的知道:

类别1(索引为2类的渠道) 这类广告媒体除了访问深度和投放时间较高,其他属性较低,因此这类广告媒体效果质量较差,并且占到39%,因此这类是主题渠道之一。 业务部门要考虑他的实际投放价值。

类别2(索引为1类的渠道) 这类广告媒体除了访问深度略差,在平均搜索量、日均UV、订单转化率等广告效果指标上表现良好,是一类综合效果较好的渠道。 但是日均UV是短板,较低。无法给企业带来大量的流量以及新用户,这类广告的特质适合用户转化,尤其是有关订单的转化提升。

类别3(索引为0类的渠道) 这类广告媒体的显著特征是日均UV和注册率较高,其“引流”和“拉新”效果好,可以在广告媒体中定位为引流角色。 符合“广而告之”的诉求,适合“拉新”使用。

类别4(索引为3类的渠道) 这类渠道各方面特征都不明显,各个流量质量和流量数量的指标均处于“中等”层次。不突出但是均衡,考虑在各场景下可以考虑在这个渠道投放广告。

这篇关于电商-广告投放效果分析(KMeans聚类、数据分析-pyhton数据分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/872136

相关文章

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

防近视护眼台灯什么牌子好?五款防近视效果好的护眼台灯推荐

在家里,灯具是属于离不开的家具,每个大大小小的地方都需要的照亮,所以一盏好灯是必不可少的,每个发挥着作用。而护眼台灯就起了一个保护眼睛,预防近视的作用。可以保护我们在学习,阅读的时候提供一个合适的光线环境,保护我们的眼睛。防近视护眼台灯什么牌子好?那我们怎么选择一个优秀的护眼台灯也是很重要,才能起到最大的护眼效果。下面五款防近视效果好的护眼台灯推荐: 一:六个推荐防近视效果好的护眼台灯的

SWAP作物生长模型安装教程、数据制备、敏感性分析、气候变化影响、R模型敏感性分析与贝叶斯优化、Fortran源代码分析、气候数据降尺度与变化影响分析

查看原文>>>全流程SWAP农业模型数据制备、敏感性分析及气候变化影响实践技术应用 SWAP模型是由荷兰瓦赫宁根大学开发的先进农作物模型,它综合考虑了土壤-水分-大气以及植被间的相互作用;是一种描述作物生长过程的一种机理性作物生长模型。它不但运用Richard方程,使其能够精确的模拟土壤中水分的运动,而且耦合了WOFOST作物模型使作物的生长描述更为科学。 本文让更多的科研人员和农业工作者

MOLE 2.5 分析分子通道和孔隙

软件介绍 生物大分子通道和孔隙在生物学中发挥着重要作用,例如在分子识别和酶底物特异性方面。 我们介绍了一种名为 MOLE 2.5 的高级软件工具,该工具旨在分析分子通道和孔隙。 与其他可用软件工具的基准测试表明,MOLE 2.5 相比更快、更强大、功能更丰富。作为一项新功能,MOLE 2.5 可以估算已识别通道的物理化学性质。 软件下载 https://pan.quark.cn/s/57

线性代数|机器学习-P36在图中找聚类

文章目录 1. 常见图结构2. 谱聚类 感觉后面几节课的内容跨越太大,需要补充太多的知识点,教授讲得内容跨越较大,一般一节课的内容是书本上的一章节内容,所以看视频比较吃力,需要先预习课本内容后才能够很好的理解教授讲解的知识点。 1. 常见图结构 假设我们有如下图结构: Adjacency Matrix:行和列表示的是节点的位置,A[i,j]表示的第 i 个节点和第 j 个

衡石分析平台使用手册-单机安装及启动

单机安装及启动​ 本文讲述如何在单机环境下进行 HENGSHI SENSE 安装的操作过程。 在安装前请确认网络环境,如果是隔离环境,无法连接互联网时,请先按照 离线环境安装依赖的指导进行依赖包的安装,然后按照本文的指导继续操作。如果网络环境可以连接互联网,请直接按照本文的指导进行安装。 准备工作​ 请参考安装环境文档准备安装环境。 配置用户与安装目录。 在操作前请检查您是否有 sud

线性因子模型 - 独立分量分析(ICA)篇

序言 线性因子模型是数据分析与机器学习中的一类重要模型,它们通过引入潜变量( latent variables \text{latent variables} latent variables)来更好地表征数据。其中,独立分量分析( ICA \text{ICA} ICA)作为线性因子模型的一种,以其独特的视角和广泛的应用领域而备受关注。 ICA \text{ICA} ICA旨在将观察到的复杂信号

【软考】希尔排序算法分析

目录 1. c代码2. 运行截图3. 运行解析 1. c代码 #include <stdio.h>#include <stdlib.h> void shellSort(int data[], int n){// 划分的数组,例如8个数则为[4, 2, 1]int *delta;int k;// i控制delta的轮次int i;// 临时变量,换值int temp;in

三相直流无刷电机(BLDC)控制算法实现:BLDC有感启动算法思路分析

一枚从事路径规划算法、运动控制算法、BLDC/FOC电机控制算法、工控、物联网工程师,爱吃土豆。如有需要技术交流或者需要方案帮助、需求:以下为联系方式—V 方案1:通过霍尔传感器IO中断触发换相 1.1 整体执行思路 霍尔传感器U、V、W三相通过IO+EXIT中断的方式进行霍尔传感器数据的读取。将IO口配置为上升沿+下降沿中断触发的方式。当霍尔传感器信号发生发生信号的变化就会触发中断在中断

kubelet组件的启动流程源码分析

概述 摘要: 本文将总结kubelet的作用以及原理,在有一定基础认识的前提下,通过阅读kubelet源码,对kubelet组件的启动流程进行分析。 正文 kubelet的作用 这里对kubelet的作用做一个简单总结。 节点管理 节点的注册 节点状态更新 容器管理(pod生命周期管理) 监听apiserver的容器事件 容器的创建、删除(CRI) 容器的网络的创建与删除