資料科學實戰行銷活動評估!(附Python 程式碼)
若您是行銷部門的人員,每天可能為了增加產品的曝光,運用不同的行銷手法,例如:透過媒體廣告、網路廣告、報章雜誌、各種不同的數位行銷通路宣傳…等;若您是單位主管,可能想知道不同行銷活動的開支,到底帶來了多少的營收~
本篇文章將用案例帶您在操作資料產出前,如何進行前面的資料處理,讓分析結果能更具管理意涵!
這時候,你如何用資料科學的方法評估這些行銷活動的效益呢?
我們先來看一下本案例的情境主題內容:
情境主題概要說明:
- 資料來源:以某零售商品平台的匿名銷售資料,
- 數據筆數: 2016~2019年的資料,筆數大約30萬筆資料,
- 如何評估: 我們將探討「不同的行銷活動」與「顧客回購次數多寡」與「利潤」的關係
- 如何呈現:將資料視覺化,讓大家一目了然圖形中所帶給我們的重要資訊。
當我們拿到大量的資料時,如何快速找到所需要的重要資料,快速作出有價值的分析並進一步視覺化呢?資料前處理的作業是相當重要的,好的資料處理,可以幫助我們使資料呈現更整潔、讓資料成更具有意義的內容,還能使資料視覺化過程更有效率。
這裡的概念與整理髒亂的房間有異曲同工之妙,必須將房間好好整理一番,才能快速地找到我們所需要的物品,同樣地,為了找到重要線索,我們必須要把資料先整理好!
資料前處理-取出重要關鍵欄位
第一階段要進行的是資料前處理的動作,資料前處理的三個主要過程分為將原始資料中取出所需要的項目並且整理,接下來將整理好的資料按照時間先後順序去分類,並建立一個會員消費紀錄資料庫,最後使用資料庫的內容彙整成繪圖所需的基本元素。
一、資料前處理-取出重要關鍵資料
本次資料處理主要會使用到的工具為pandas、numpy以及datetime,我們使用import將工具們套用進來後,接著使用pandas讀取sales_data.csv檔案(可點擊鏈結下載銷售資料),讀取後一樣可以在右上角的variable explorer中查看資料。
部分原始資料的具體模樣如圖1所示:

檢視完原始資料後,是不是不太清楚要採用哪幾個欄位來作行銷活動的效益評估分析呢?本篇文章要分析客戶透過甚麼「行銷活動」的吸引而「回購產品」的情形與「利潤」之間的關係。將會需要以下這些欄位項目,因此先將後續分析及繪圖可能會使用到的欄位取出,如下:
- 廣告代號all:每筆訂單不同時期的行銷活動
- 會員:每一位會員的專屬編號
- 訂單時間:會員送出訂單的時間
- 系列:由許多類似的產品所組成的系列(舉例:產品1–1、產品1–2、產 品1–3組成系列1)
- 單價:每一個產品的單價
- 成本:每一個產品的成本
我們可以看到取出的欄位有單價以及成本的欄位,從這兩個欄位可以切割出一個新的重要欄位-「利潤」,如程式碼1所示。 - 利潤:由同一個產品的單價減掉它的成本所得出的金額
利潤能和其他不同欄位配合解釋出不同的關係,之後的視覺化圖形的呈現也會是非常重要的元素,可以說是在這次顧客回購分析是不可或缺的角色!
程式碼1:
# 從資料中只取得所需的項目
all_data = all_data[['廣告代號all','會員','訂單時間','系列','單價','成本']]
# 計算出利潤項目(單價-成本)
all_data['利潤'] = all_data['單價'] - all_data['成本']
產出:
從原始資料取出的關鍵資料並且新增欄位「利潤」,如圖2所示。

取得所需要的欄位後,為了使內容看起來比較整潔,接著要將「廣告代號all」的名稱的「all」去除,以及它的欄位每一個項目中「廣告_」的部分刪除,最後再把所有廣告分類歸納成主要系列廣告(舉例:GINEP_D與GINEP_P都會被歸類在GINEP),如程式碼2所示。
程式碼2:
# 將【廣告代號all】 --> 【廣告代號】
all_data = all_data.rename(columns = {'廣告代號all' :'廣告代號',})
# 將廣告代號中的項目「廣告_」去除
all_data['廣告代號'] = all_data['廣告代號'].str.replace('廣告_','')
# 把子項廣告歸納回大廣告
all_data['廣告代號'] = all_data['廣告代號'].str.split('_').str.get(0)
產出:
廣告代號欄位以及名稱整理後的成果,如圖3所示。

整理好「廣告代號」欄位名稱以及內容,是不是比較好看了一些呢,之後我們要開始取出所要分析的資料。然而這次實戰後續中主要分析的重心是「2018年系列1(舉例:產品1–1、產品1–2、產品1–3組成系列1)」的銷售資料。
二、取出分析資料(系列 1-全資料集)
首先,從整理好的資料中使用groupby按照系列分群,再將系列1的資料存取出來,然後把後續視覺化圖形呈現不會再用到的欄位(單價、成本)刪除,使資料讀起來更清楚,如程式碼3。
程式碼3:
# 產品分群
product_data = all_data.groupby('系列')
# 存取系列1
product_1 = pd.DataFrame(product_data.get_group('系列1'))
# 將之後不需要用到的欄位刪除
del product_1['單價']
del product_1['成本']
產出:
已取出關鍵資料中「系列1」的部分,並將後續不會用到的欄位刪除,如圖4所示。

接下來要把訂單時間改成可以計算時間的形式(datetime),在後續將資料用時間分類的時候能夠更加順利。
為了方便型態轉換,我們先把訂單時間中的 ’T’ 字母去除,去除完後使用datetime的功能,將原本為string的形式轉換成datetime形式,最後使用dtypes確認product_1中「訂單時間」的欄位項目是否轉換成功,如程式碼4所示。
程式碼4:
# 把訂單時間中的"T"去掉
product_1['訂單時間'] = product_1['訂單時間'].str.replace('T',' ')
# 將訂單時間改成datetime形式
product_1['訂單時間'] = pd.to_datetime(product_1['訂單時間'])
# 檢查「訂單時間」是成功更改為datetime
product_1.dtypes
產出:
已將「訂單時間」欄位的資料都已轉換成datetime型態,如圖5所示。

檢查完畢之後,要取得系列1曾經使用了哪些行銷活動,我們要從系列1的資料中得到所有的廣告代號類別,那為甚麼要這樣子做呢?還記得嗎?我們本系列要帶大家探討的是「行銷活動」與「顧客回購」分析,在本次實戰分析系列中行銷活動(廣告)是整個分析過程的主軸之一,因此要將廣告類別取出才能延續下去在後面的分析流程,如程式碼5所示。
程式碼5:
# 找到系列1中的所有廣告名稱
ad_pd1 =product_1['廣告代號'].unique().tolist()
產出:
2016~2019年曾使用在系列1上的行銷活動(包含自然流量),如圖6所示。

現在我們已經將大部分所需要的欄位及元素都處理到一個段落,接下來要跟大家分享如何使用「關鍵資料」建立一個「會員消費紀錄資料庫」。
現在我們要按照目前取出並且整理好的關鍵資料(product_1)的訂單時間,將其整理分為1到12月。
加了分月份的概念,可以讓我們分析每個行銷活動在不同月份的效益,比較每個廣告在「不同月份」顧客的回購狀態。而顧客回購狀態與利潤的關係又能帶給我們什麼新的洞察?讓我們延續進行資料前處理的動作,我們會將成果在後面一一跟大家分享!
現在請跟著我建立會員消費紀錄資料庫吧~
三、取出分析資料-2(系列 1-2018年度)
在這段資料前處理的部分,同樣會使用到datetime的功能,將string的型態轉成datetime形式,用來判斷時間的先後順序,把資料按照月份分類完成,如程式碼6所示。
程式碼6:
# 先設立一個可以放2018年每個月資料的list
original_2018 = []
for i in range(1,13):
# 當月份等於12月的時候,執行下方程式
if i == 12 :
# 設立選取資料起始時間 (2018年 12月 1日)
begin = datetime(2018, i, 1)
# 設立選取資料結束時間 (2019年 1月 1日)
end = datetime(2019, 1, 1)
# 選取資料 ( 結束時間之前 )
pd1_2018 = product_1[product_1['訂單時間'] <= end]
# 選取資料 ( 開始時間之後 )
pd1_2018 = pd1_2018[pd1_2018['訂單時間']>=begin]
# 將12月的資料加到存放每個月資料的list中
original_2018.append(pd1_2018)
# 當月份不等於12月的時候,執行下方程式
else :
# 設立選取資料起始時間 (2018年 某月 1日)
begin = datetime(2018, i, 1)
# 設立選取資料結束時間 (2018年 某月+1個月 1日)
end = datetime(2018, i+1, 1)
# 選取資料 ( 結束時間之前 )
pd1_2018 = product_1[product_1['訂單時間'] <= end]
# 選取資料 ( 開始時間之後 )
pd1_2018 = pd1_2018[pd1_2018['訂單時間'] >= begin]
# 將該月份的資料加到存放每個月資料的list中
original_2018.append(pd1_2018)
產出:
已將2018年系列1的訂單資料按照月份分類(original_2018),如圖7所示。

可以從月份資料清單中點擊不同月份,會顯示出該月份的資料,以6月份的資料做範例,如圖8所示:

四、建立會員消費紀錄資料庫
分類好每個月的訂單資料後,再從每個月的每筆資料分析每一個會員分別在「哪個月」購買系列1的產品,並且判斷出他是「第幾次購買」、是因為「甚麼廣告」吸引會員前往購買,最後將上述資訊使用二維(雙層)字典的方式建立成一個資料庫,如程式碼7所示。
程式碼7:
# 建立每個會員的消費紀錄
customer_record = {}
for mon in range(len(original_2018)):
# 將每個訂單的利潤計算出來存成list
profit_gp = original_2018[mon].groupby('訂單時間')["利
潤"].sum().tolist()
# 把訂單時間重複的drop掉
original_2018[mon] = original_2018[mon].drop_duplicates(subset=['訂單時間'])
# 把利潤補回原本df
original_2018[mon]['利潤'] = profit_gp
# 將index 重新排序
original_2018[mon] = original_2018[mon].reset_index(drop = True)
a = original_2018[mon]
for i in range(len(a['會員'])):
# 如果會員「不在」字典的keys中,執行下方程式
if str(a['會員'][i]) not in customer_record.keys():
# 新增會員到keys中,並且放上對應的消費紀錄
customer_record[ str(a['會員'][i]) ] = {'1':str(mon+1)+'月_'+a['廣告代號'][i]}
# 如果會員已經在字典的keys中,執行下方程式
else:
# 直接在原有的會員keys下,放上對應的消費紀錄
customer_record[ str(a['會員'][i]) ][str(len(customer_record[ str(a['會員'][i]) ])+1)] = str(mon+1)+'月_'+a['廣告代號'][i]
產出:
建立完成的2018年系列1會員消費紀錄資料庫,如圖9所示。

建立完會員消費紀錄庫之後,還不太理解其中的意涵嗎?以下舉一個例子為大家說明:
圖9中的Key代表的是會員編號,Value表示的是會員的過往消費紀錄,然而我們可以看到會員編號「10024521」的過往消費紀錄,是以一個dictionary的型態呈現{ ‘ 1 ‘ :’ 1月_B2KP ‘ },那麼這層dictionary的Key跟Value分別又是甚麼意思呢?
「’ 1 ‘(key):’ 1月_B2KP ‘(value)」
冒號前面的 ‘ 1 ‘ (key)代表此次消費紀錄是第一次購買,
冒號後面 ‘ 1月_B2KP ‘(value)的部分表達的意思是此會員在1月的時候因為被行銷活動B2KP吸引而前往消費。
到這裡,您已經建立好會員消費紀錄資料庫了,資料前處理的部份還差最後一步!
再加油一下~
接下來要跟大家分享如何將「會員消費紀錄資料庫」彙整出後續「資料視覺化」所會使用到的基本元素,雖然稱作是「基本元素」,不過此處的基本元素是從資料庫中萃取出來的精華呢!
五、彙整資料清單
首先,我們需從消費紀錄資料庫中去比對時間後,然後建立2018年1~12月的會員消費資料,並且把每個月份的資料彙整成一個清單,如程式碼8所示。
程式碼8:
# 分類好每個月的資料(哪個會員在第幾個月因為甚麼廣告而購買、第幾次購買)
final_2018 = []
# 從1月開始蒐集
for mon in range(len(original_2018)):
# 建立存取【會員】、【廣告代號】、【第幾次購買】之串列
original_2018_id = []
original_2018_ad = []
original_2018_count =[]
# 每個會員編號都跑一次 i:不同會員編號 舉例:會員10071970
for i in customer_record.keys():
# 舉例:會員10071970 在2018年購買系列1的所有消費紀錄
for j in customer_record[i].values() :
# 消費紀錄中若開頭為蒐集的該月份則執行下方程式
if j.startswith(str(mon+1)+'月'):
# 存取該會員編號 舉例:10071970
original_2018_id.append(i)
print('會員編號:',i)
# 存取其廣告代號 舉例:1月_GINEP
original_2018_ad.append(j)
print('廣告代號:',j)
# 存取會員在這筆消費紀錄中是第幾次購買舉例:'1'
original_2018_count.append(list (customer_record[i].keys()) [list (customer_record[i].values()).index (j)])
print('第幾次購買:',list (customer_record[i].keys()) [list (customer_record[i].values()).index (j)])
# 建立DataFrame
original_2018_df = pd.DataFrame({'會員':original_2018_id,
'廣告代號':original_2018_ad,
'第幾次購買':original_2018_count})
# 存放到分類12個月的串列之中
final_2018.append(original_2018_df)
產出:
將會員消費紀錄資料庫的內容按照每個月份彙整內容,如圖10所示。

如果想查看該月份的資料,一樣可以從月份資料清單中點擊不同月份,下圖同樣以6月份的資料做範例,可以比對一下圖8的內容,我們留下了「會員」、「廣告代號」兩個欄位,同時也新增了「第幾次購買」欄位。

"到目前為止是不是覺得還少了些甚麼呢?"
沒錯!就是少了最重要的元素「利潤」!因此下一個步驟就是要將每筆訂單資料的利潤補上去,使繪圖的資料更加完整。
六、調整資料清單
要怎麼把利潤對應到相符合的訂單資料呢?為了更好釐清以下的步驟,我們用一個例子舉例:
下列有兩份不同的月份資料清單,原本就有利潤欄位的命名為「original_2018」,其中6月的DataFrame則稱作「original_2018–6」,另一個即將要新增利潤欄位的清單名為「final_2018」,其中6月的DataFrame稱作「final_2018–6」。
首先,將original _2018–6中的「廣告代號」項目中的名稱都加上「月份_」在最前面,並且把會員欄位的項目從integer型態轉到string型態。
清單中總共有12個月,我們將使用for迴圈把每個月份都經由上方的方式處理一次,如程式碼9所示。程式碼的產出也是會以清單的方式呈現。
程式碼9:
# 目的:為了跟final_2018去做merge
# 補上月份
for i in range(len(original_2018)):
original_2018[i]['廣告代號'] = str(i+1) + '月_' + original_2018[i]['廣告代號']
# 目的:使original_2018 和 final_2018 的會員欄位內容「type」相同
# 將original_2018中的會員轉成string
for i in range(len(original_2018)):
original_2018[i]['會員'] = original_2018[i]['會員'].astype(str)
print(str(i+1)+'月check!' )
產出:
已在廣告代號欄位補上月份以及轉換完會員欄位型態過後的「original_2018」,如圖12所示。

可再點擊清單中的項目查看資料內容,詳細檢查是否執行成功,如圖13所示。

Thinking smarte檢查完畢後,接下來就把 original_2018的利潤欄位使用merge的方式加到 final_2018上,如程式碼 10所示。
程式碼 10:
# 目的:final_2018 1~12月的資料補上相對應的利潤
for i in range(len(final_2018)) :
# 將original_2018數據中的利潤 依照【會員&廣告代號】去merge到 final_2018上
final_2018[i] = final_2018[i].merge(original_2018[i], how='inner', left_on=['會員', '廣告代號'], right_on=['會員', '廣告代號'])
# 刪除重複merge到的錯誤
final_2018[i] = final_2018[i].drop_duplicates(subset=['訂單時間'])
final_2018[i] = final_2018[i].reset_index(drop = True)
del final_2018[i]['訂單時間']
del final_2018[i]['系列']
產出:
成功與「original_2018」merge後的「final_2018」內容,如圖14所示。

將圖14和圖10比較後,可以看見每個月的資料都新增了利潤欄位。
恭喜各位完成了本案例的資料前處理的階段啦~
想要知道如何將資料視覺化嗎?
想要知道分析資料視覺化的成果後能帶給公司什麼樣的關鍵消息嗎?
想要知道更多的後續內容嗎?
我們將在之後的文章一一和大家分享分析結果以及如何找出視覺化結果的「管理意涵」。
Thinking smarter makes you work smarter
如果你喜歡我的文章的話,請給我一點拍手~
如果你覺得喜歡又實用的話,請給我更多的拍手!
程式碼:
資料科學實戰行銷活動評估!-1
作者:張友志 (臺灣行銷研究特邀作者)、鍾皓軒(臺灣行銷研究有限公司創辦人)
更多實戰案例及情境好文推薦
如何 0–1 來預測新酒品的市場趨勢?(深度學習 - Part 1 : EDA 與 Python 畫圖工具)
如何 0–1 來預測新酒品的市場趨勢? (深度學習 - Part 1 : EDA 與 Python 畫圖工具) 「品酒」已經不再是有錢人的權
掌握投資關鍵消息! 從當日熱門新聞預測股票走勢(基本資料處理篇)(附Python程式碼)
掌握投資關鍵消息! 從當日熱門新聞預測股票走勢 (基本資料處理篇)(附Python程式碼) 情境 在股票市場中,即時的消息對於投資者而言至關
如何用資料科學方法找出高CP值產品 (附Python程式碼)
如何使用機器學習提高房仲業潛在成交率?進階資料處理面與基礎建模(附Python程式碼) 先回顧上一篇文章吧~如何使用機器學習提高房仲業潛在成