無母數檢定應用 —資料量太少或資料非常態分佈嗎?! Python實戰:商務資料結構整理(附Python 程式碼)

徐子皓 Nash Xu
Marketingdatascience
8 min readNov 25, 2020

一般常用的 T-test,F-test,或 ANOVA都是針對常態母體, 或是大樣本所推導出的方法。但若是群體分佈未知或不為常態分佈時,上述的這些檢定方法就不適用,無母數檢定就派上用場了。它是一個不需要假設群體呈常態分佈之統計檢定方法。

本篇文章的情境以某電商平台的後台銷售數據,在資料非常態分佈的情況下,我們要選定一特定系列商品,並分析特定系列商品在不同廣告下的成效為何?

以下我們將透過無母數檢定的方法,來進行此非常態分析特定系列商品在不同的廣告下的成效為何。

本篇文章先和大家分享在此情境下的資料結果整理心法及分析規劃,現在開始跟我往下進行無母數檢定的資料前處理。

一、讀入原始資料

首先將資料「new_salesdata.csv」(點我下載)下載讀入,並透過程式碼1將原始資料讀入電腦中,如下所示:

程式碼1:

# 導入分析資料
import pandas as pd
data = pd.read_csv('new_salesdata.csv', encoding = 'utf-8-sig')

產出:(如圖1所示)

圖 1 原始資料示意圖

該店商的原始資料十分詳盡,從產品編號、款式、購買時間、甚至是會員資料皆鉅細靡遺,共有353224筆交易資料。但並非所有資料都適合作為分析資料,因此只將本篇文章所需的欄位取出,分別如下:

1. 單價、成本:將用以相減計算「利潤」,以利判斷該筆消費帶來的淨營收。

2. 系列:相同款式的商品會集合成一個「系列」,本單元將使用其中一項系列作無母數檢定的個案分析。

3. 廣告代號all:用來做以判斷該交易資料的消費者是透過哪一種網路行銷管道而吸引過來的,本篇文章將用廣告作為變數,判斷不同廣告之間所帶來的淨營收是否有顯著的差距。

因此,下一步要讓分析資料中只留下需用以作為統計分析資料的欄位,並只取出「系列4」作為文篇文章的個案分析,如程式碼2所示:

程式碼2:

# 只留下需要的欄位
data = data[['單價', '成本', '系列', '廣告代號all']]
# 取系列4作分析
data = data[data['系列']=='系列4']

產出:(如圖2所示)

圖 2 篩選後資料

二、重新整理廣告代碼

在整理出可用的資料欄位後,緊接著要為分析資料中的廣告代號進行重新整理。由於電商的促銷方式五花八門,會推出各式各樣的廣告以刺激購買需求,因此會發生同一款底下還有許多不同代號的情況,如程式碼3的產出所示,光B2K廣告就衍生出了9種不同的系列。

程式碼3:

example = []
for i in data['廣告代號all']:
if '_B2K_' in i:
if i not in example:
example.append(i)
print(example)

產出:

['廣告_B2K_pid', '廣告_B2K_mqrukisleeve', '廣告_B2K_mqrukisleeve2', '廣告_B2K_MK', '廣告_B2K_ciccicqrtu', '廣告_B2K_mqrukitrqveltite', '廣告_B2K_ciccicqrtu2', '廣告_B2K_jqejqe', '廣告_B2K_cic2016']

若直接以這些項目作統計檢定,重複且攏長的代號不只讓分析結果錯縱複雜,少部分的廣告樣本數量甚至只有個位數,也使的檢定出來的結果變得更加失準。

為了避免這些情況的產生,在此會將相同系列的廣告(如B2K系列)後的細部代碼忽略掉,統一視為相同的廣告系列,如程式碼4所示。我們透過「split」這個功能將每一個廣告代號以「_」切分開,並只取出最中間的廣告系列名稱,儲存至清單「rep」中。

程式碼4:

rep = []
for i in range(0,data.shape[0]):
a = data['廣告代號all'][i].split('_')[1]
rep.append(a)
# rep中前十筆資料
rep[0:10]

產出:

['YND', 'YND', 'YND', 'YND', 'YND', 'YND', 'YND', '自然流量', '自然流量', '自然流量']

隨後,將剛剛製作完的清單「rep」回存至資料表「data」中,覆蓋欄位「廣告代號all」內的原始資料,如程式碼5所示:

程式碼5:

data['廣告代號all']=rep

產出:(如圖3所示)

圖 3 更改廣告代號後資料集

三、取出樣本數前三大廣告

雖然已將廣告的細項代碼整併,但該資料集中仍包含了許多種類的廣告,如程式碼6所示,系列4中包含了36種的廣告類別。

程式碼6:

len(data['廣告代號all'].unique())

產出:

36

為了方便大家理解,本篇文章將只取廣告樣本數前三大的廣告作為統計檢定分析的樣本標的。

透過程式碼7,可以清楚地掌握不同的廣告在資料集「data」中共出現了幾次,以利我們挑選廣告。

程式碼7:

from collections import Counter
count_list = Counter(data['廣告代號all'])

產出如圖4所示,廣告「B2K」共出現了452次,廣告「B2KDG」共出現了21次等。

圖 4 廣告頻率示意圖

再來,將廣告頻率清單「count_list」轉成dataframe的形式,讓後續的編輯跟修改可以更簡便,如程式碼8所示。

程式碼8:

count_list=pd.DataFrame.from_dict(count_list,orient='index').reset_index()count_list=count_list.rename(columns = {'index' : '廣告名稱', 0: '樣本數'})

產出:(如圖5所示)

圖 5 轉換為DataFrame格式的廣告頻率表

緊接著,透過python的一個功能「heapq」,找出樣本數第三大的數值「good_number」,如程式碼9所示,第三名為1285個廣告次數:

程式碼9:

import heapq
good_number = heapq.nlargest(3,list(count_list['樣本數']))[2]
good_number

產出:

1285

抓出第三名的數字後,再篩選出樣本數不小於第三名的廣告,便是數量前三大的廣告了,如程式碼10所示。

程式碼10:

good_list = count_list[count_list['樣本數'] >= good_number]

產出:(如圖6所示)

圖 6 樣本數前三大的廣告表

這三個廣告便是本單元要用來作以無母數統計檢定的廣告樣本,透過程式碼11,分別將將使用這三樣廣告的樣本各式取出後,再合併成新的資料表,如下所示。

程式碼11:

data = pd.concat([data[data['廣告代號all']==good_list.iloc[0,0]],
data[data['廣告代號all']==good_list.iloc[1,0]],
data[data['廣告代號all']==good_list.iloc[2,0]]],
ignore_index=True)

產出:(如圖7所示)

圖 7 符合廣告需求條件的資料表
Photo by: Shopify Partners

四、計算利潤

最後將每項交易的收入減掉成本,計算出當筆交易之利潤後,將無用之欄位刪除,如程式碼12所示,便完成資料前處理的動作了。

程式碼12:

data['利潤'] = data['單價'] - data['成本']
data = data.drop(['單價', '成本', '系列'], axis=1)

產出:(如圖8所示)

圖 8 完成資料前處理的可用分析資料

下一單元我們將利用這份處理後資料來進行無母數檢定,並進一步產出成果報表,敬請期待!

完整程式碼:https://reurl.cc/N60oan

作者:徐子皓(臺灣行銷研究特邀作者)、鍾皓軒(臺灣行銷研究有限公司創辦人)

--

--