資料介紹

本案例的業務場景:

假如你們公司投放廣告的渠道很多,每個渠道的客戶性質也可能不同,比如在優酷影片投廣告和今日頭條投放廣告,效果可能會有差異。現在需要對廣告效果分析實現有針對性的廣告效果測量和最佳化工作。

資料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

f

=

open

‘E://Python練手//一些資料//ad_performance。csv’

encoding

=

‘utf-8’

ad_data

=

pd

read_csv

f

iloc

[:,

1

:]

ad_data

head

()

廣告效果分析——基於K-Means演算法分層

資料審查

檢視基本狀態

ad_data

head

()

廣告效果分析——基於K-Means演算法分層

ad_data

info

()

#列印資料型別

RangeIndex: 889 entries, 0 to 888

Data columns (total 13 columns):

渠道代號 889 non-null object

日均UV 889 non-null float64

平均註冊率 889 non-null float64

平均搜尋量 889 non-null float64

訪問深度 889 non-null float64

平均停留時間 887 non-null float64

訂單轉化率 889 non-null float64

投放總時間 889 non-null int64

素材型別 889 non-null object

廣告型別 889 non-null object

合作方式 889 non-null object

廣告尺寸 889 non-null object

廣告賣點 889 non-null object

dtypes: float64(6), int64(1), object(6)

memory usage: 90。4+ KB

ad_data

describe

()

round

2

T

#列印原資料基本描述資訊

廣告效果分析——基於K-Means演算法分層

上面程式碼,分別展示前五條資料、所有特徵的資料型別、以及數值型特徵的五值分佈

——————————————————————————————————————

檢視缺失值情況:

# 缺失值審查

ad_data

isnull

()

any

()

#檢視每一列缺失情況

渠道代號 False

日均UV False

平均註冊率 False

平均搜尋量 False

訪問深度 False

平均停留時間 True

訂單轉化率 False

投放總時間 False

素材型別 False

廣告型別 False

合作方式 False

廣告尺寸 False

廣告賣點 False

dtype: bool

ad_data

isnull

()

sum

()

sort_values

()

# 檢視具有缺失值的行總記錄數

渠道代號 0

日均UV 0

平均註冊率 0

平均搜尋量 0

訪問深度 0

訂單轉化率 0

投放總時間 0

素材型別 0

廣告型別 0

合作方式 0

廣告尺寸 0

廣告賣點 0

平均停留時間 2

dtype: int64

——————————————————————————————————————

變數之間的相關性分析:

# 相關性分析

ad_data

corr

()

round

2

# 列印原始資料相關性資訊

廣告效果分析——基於K-Means演算法分層

# 相關性視覺化展示

import

seaborn

as

sns

corr

=

ad_data

corr

()

round

2

sns

heatmap

corr

cmap

=

‘Reds’

annot

=

True

<

matplotlib

axes

_subplots

AxesSubplot

at

0x2935f4014e0

>

廣告效果分析——基於K-Means演算法分層

可以看到,“訪問深度”和“平均停留時間”相關性比較高,相關性高說明兩個變數在建立模型的時候,作用是一樣或者效果是一樣的,可以考慮組合或者刪除其一。

資料處理

刪除平均平均停留時間列

ad_data_new

=

ad_data

drop

([

‘平均停留時間’

],

axis

=

1

ad_data_new

head

()

廣告效果分析——基於K-Means演算法分層

類別變數的獨熱編碼:

cols

=

ad_data_new

columns

values

tolist

()[

-

5

:]

for

x

in

cols

data

=

ad_data_new

x

unique

()

print

“變數【{0}】的取值有:

\n

{1}”

format

x

data

))

print

“-·”

*

20

變數【素材型別】的取值有:

[‘jpg’ ‘swf’ ‘gif’ ‘sp’]

-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·

變數【廣告型別】的取值有:

[‘banner’ ‘tips’ ‘不確定’ ‘橫幅’ ‘暫停’]

-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·

變數【合作方式】的取值有:

[‘roi’ ‘cpc’ ‘cpm’ ‘cpd’]

-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·

變數【廣告尺寸】的取值有:

[‘140*40’ ‘308*388’ ‘450*300’ ‘600*90’ ‘480*360’ ‘960*126’ ‘900*120’

‘390*270’]

-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·

變數【廣告賣點】的取值有:

[‘打折’ ‘滿減’ ‘滿贈’ ‘秒殺’ ‘直降’ ‘滿返’]

-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·-·

字串分類獨熱編碼處理

from

sklearn。preprocessing

import

LabelEncoder

OneHotEncoder

labelencoder

=

LabelEncoder

()

ad_data_cols

=

ad_data_new

cols

for

i

in

cols

ad_data_cols

i

=

labelencoder

fit_transform

ad_data_new

i

])

print

“labelencoder:”

print

ad_data_cols

head

())

labelencoder:

素材型別 廣告型別 合作方式 廣告尺寸 廣告賣點

0 1 0 3 0 0

1 1 0 0 0 1

2 1 0 0 0 1

3 1 0 0 0 1

4 1 0 0 0 1

onehotencoder

=

OneHotEncoder

()

enc_matrix

=

onehotencoder

fit_transform

ad_data_cols

toarray

()

print

enc_matrix

[:

2

])

[[0。 1。 0。 0。 1。 0。 0。 0。 0。 0。 0。 0。 1。 1。 0。 0。 0。 0。 0。 0。 0。 1。 0。 0。

0。 0。 0。]

[0。 1。 0。 0。 1。 0。 0。 0。 0。 1。 0。 0。 0。 1。 0。 0。 0。 0。 0。 0。 0。 0。 1。 0。

0。 0。 0。]]

資料標準化

sacle_matrix

=

ad_data_new

iloc

[:,

1

7

# 獲得要轉換的矩陣

model_scaler

=

MinMaxScaler

()

# 建立MinMaxScaler模型物件

data_scaled

=

model_scaler

fit_transform

sacle_matrix

# MinMaxScaler標準化處理

print

data_scaled

round

2

))

[[0。 0。18 0。02 0。01 0。12 0。66]

[0。01 0。1 0。03 0。01 0。01 0。62]

[0。 0。06 0。05 0。01 0。01 0。1 ]

。。。

[0。01 0。01 0。 0。 0。 0。72]

[0。05 0。 0。 0。 0。 0。31]

[0。 0。 0。 0。53 0。 0。62]]

資料處理完,我們將獨熱編碼的資料和標準化轉化後的資料合併:

# 合併所有維度

X

=

np

hstack

((

data_scaled

enc_matrix

))

建立模型

# 透過平均輪廓係數檢驗得到最佳KMEANS劇烈模型

score_list

=

list

()

# 用來儲存每個K下模型的平局輪廓係數

silhouette_int

=

-

1

# 初始化的平均輪廓係數閥值

for

n_clusters

in

range

2

7

):

# 遍歷從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

))

*************************K值對應的輪廓係數:*************************

[[2。 0。38655493]

[3。 0。45757883]

[4。 0。50209812]

[5。 0。4800359 ]

[6。 0。47761127]]

最優的K值是:4

對應的輪廓係數是:0。5020981194788054

總體思想(評價指標)還是怎麼聚才能使得簇內距離足夠小,簇與簇之間平均距離足夠大來評判。

聚類結果特徵分析與展示

透過上面模型,我們其實給每個觀測(樣本)打了個標籤clusters,即他屬於4類中的哪一類:

# 將原始資料與聚類標籤整合

cluster_labels

=

pd

DataFrame

cluster_labels_k

columns

=

‘clusters’

])

# 獲得訓練集下的標籤資訊

merge_data

=

pd

concat

((

ad_data_new

cluster_labels

),

axis

=

1

# 將原始處理過的資料跟聚類標籤整合

merge_data

head

()

廣告效果分析——基於K-Means演算法分層

每個類別下的樣本數量和佔比情況

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

clustering_ratio

clusters 0 1 2 3

counts 313 349 154 73

clusters 0 1 2 3

percentage 0。35 0。39 0。17 0。08

每個類別內部最顯著的特徵:

# 計算各個聚類類別內部最顯著特徵值

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

# 將列表轉化為矩陣

all_cluster_set

=

pd

concat

((

clustering_count

clustering_ratio

cluster_pd

),

axis

=

0

# 將每個聚類類別的所有資訊合併

all_cluster_set

廣告效果分析——基於K-Means演算法分層

圖形化輸出

# 獲取要展示的資料

num_sets

=

cluster_pd

T

iloc

[:,

6

astype

np

float64

# 獲得標準化後的資料

num_sets_max_min

=

model_scaler

fit_transform

num_sets

print

num_sets

print

‘-’

*

60

print

num_sets_max_min

日均UV 平均註冊率 平均搜尋量 訪問深度 訂單轉化率 投放總時間

0 1390。013 0。003 0。152 1。168 0。017 8。199

1 933。015 0。003 0。064 5。916 0。006 8。770

2 2717。419 0。005 0。051 0。947 0。007 8。529

3 1904。371 0。003 0。106 0。943 0。009 8。217

——————————————————————————————

[[2。56106801e-01 0。00000000e+00 1。00000000e+00 4。52443193e-02

1。00000000e+00 0。00000000e+00]

[0。00000000e+00 0。00000000e+00 1。28712871e-01 1。00000000e+00

0。00000000e+00 1。00000000e+00]

[1。00000000e+00 1。00000000e+00 0。00000000e+00 8。04343455e-04

9。09090909e-02 5。77933450e-01]

[5。44358789e-01 0。00000000e+00 5。44554455e-01 0。00000000e+00

2。72727273e-01 3。15236427e-02]]

# 畫圖

fig

=

plt

figure

figsize

=

6

6

))

# 建立畫布

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

+

1

))

# 畫線

ax

fill

angles

data

alpha

=

2。5

# 設定影象顯示格式

ax

set_thetagrids

angles

*

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

))

# 設定圖例位置

<

matplotlib

legend

Legend

at

0x2935f4dcb00

>

廣告效果分析——基於K-Means演算法分層

資料結論

從案例結果來看,所有的渠道被分為4各類別,每個類別的樣本量分別為:154、349 、313、73,對應占比分別為:17%、39%、35%、8%。

透過雷達圖可以清楚的知道:

類別1(索引為2類的渠道)

這類廣告媒體除了訪問深度和投放時間較高,其他屬性較低,因此這類廣告媒體效果質量較差,並且佔到39%,因此這類是主體渠道之一。

業務部門要考慮他的實際投放價值。

類別2(索引為0類的渠道)

這類廣告媒體除了訪問深度略差,在平均搜尋量、日均UV、訂單轉化率等廣告效果指標上表現良好,是一類綜合效果較好的渠道。

但是日均UV是短板,較低。無法給企業帶來大量的流量以及新使用者,這類廣告的特質適合使用者轉化,尤其是有關訂單的轉化提升。

類別3(索引為1類的渠道)

這類廣告媒體的顯著特徵是日均UV和註冊率較高,其“引流”和“拉新”效果好,可以在廣告媒體中定位為引流角色。

符合“廣而告之”的訴求,適合“拉新”使用。

類別4(索引為3類的渠道)

這類渠道各方面特徵都不明顯,各個流量質量和流量數量的指標均處於“中等”層次。不突出但是均衡,考慮在各場景下可以考慮在這個渠道投放廣告。