文/明道軟件 胡晨川 個(gè)人公眾號(hào)“川術(shù)”
平均數(shù)計(jì)算的目的,是用來判斷一個(gè)序列的集中趨勢(shì)夕吻,進(jìn)而對(duì)數(shù)據(jù)總體有一個(gè)合理的認(rèn)知诲锹。要求一個(gè)序列的平均數(shù),主流算法其實(shí)有三種:算術(shù)平均數(shù)涉馅,中位數(shù)归园,眾數(shù)。
算術(shù)平均數(shù)即大家用得最多的稚矿,幾個(gè)數(shù)加總后除以個(gè)數(shù)庸诱;而中位數(shù)是序列中的數(shù)進(jìn)行大小排序后,排名在中間的數(shù)(若序列中數(shù)值個(gè)數(shù)是偶數(shù)晤揣,則取排名在中間的兩個(gè)數(shù)的算數(shù)平均數(shù))桥爽;而眾數(shù)是指序列中出現(xiàn)頻率最高的那個(gè)數(shù)。
三種算法在excel中對(duì)應(yīng)的函數(shù)是average(),median()和mode()昧识。
三種算法各有特點(diǎn)钠四,也各有使用條件。算數(shù)平均數(shù)的使用跪楞,有時(shí)侯會(huì)把你帶坑里缀去。我用最近遇到的一個(gè)案例,來說說為什么要使用中位數(shù)习霹。
用中位數(shù)來避免算數(shù)平均數(shù)陷阱
中位數(shù)數(shù)的計(jì)算方式朵耕,我用下面一段python的代碼表示,程序員們或許更好理解:
def Median(a):
a = sorted(a)
l = len(a)
l2 = l / 2
return a[l2] if l % 2 else (a[l2] + a[l2 - 1]) / 2.0
(文章末尾附錄中我列出了sql語句計(jì)算中位數(shù)的方式)
最近在做明道crm中的統(tǒng)計(jì)模塊淋叶,計(jì)算訂單承擔(dān)周期時(shí)阎曹,遇到了算數(shù)平均數(shù)陷阱:
比如,某個(gè)銷售在6月份簽了5單煞檩,每單的周期是order_period=[15,18,26,30,365]处嫌。其中有一個(gè)訂單是去年注冊(cè)的線索(小概率事件),因此周期的算數(shù)平均數(shù)90.8斟湃。之前成單周期水平都在一個(gè)月左右的人熏迹,在這個(gè)月突然變成了3個(gè)月,這個(gè)數(shù)值顯然是不公平的凝赛。這樣的巨幅變化注暗,也會(huì)給銷售決策造成干擾(對(duì)數(shù)據(jù)總體的認(rèn)知被扭曲了)坛缕。因?yàn)?65這個(gè)極大值,拉高了整個(gè)序列的算數(shù)平均數(shù)捆昏,使得數(shù)據(jù)失真赚楚。這正是算數(shù)平均數(shù)的弊端。
取用中位數(shù)骗卜,便排除了特?cái)?shù)值帶來的影響宠页。縱使有一單是去年的線索寇仓,這位顧問的成單周期是26举户,依然是正常水準(zhǔn)。
算數(shù)平均數(shù)與中位數(shù)的結(jié)合
而算數(shù)平均數(shù)也有它的優(yōu)勢(shì)遍烦,它是匯總所有數(shù)值信息后俭嘁,計(jì)算的集中趨勢(shì),只要不出現(xiàn)特殊值服猪,它的精確度是超過中位數(shù)的兄淫。所以,算數(shù)平均數(shù)和中位數(shù)如何結(jié)合呢蔓姚?
crm成單周期的統(tǒng)計(jì),又引發(fā)出另一個(gè)問題:從哪個(gè)層面來計(jì)算中位數(shù)慨丐?
我們的計(jì)算其實(shí)有四級(jí):
公司銷售部宏觀的成單周期??每個(gè)城市分公司的成單周期??各個(gè)銷售團(tuán)隊(duì)的成單周期??個(gè)人的成單周期坡脐。
如果每一級(jí)都計(jì)算中位數(shù),顯然是過于粗放的房揭。我采用的方式是在個(gè)人這一級(jí)取中位數(shù)备闲,之后的所有層級(jí)都取算數(shù)平均數(shù)。
但這還是有問題的:
個(gè)人成單量比較少的情況下捅暴,計(jì)算中位數(shù)也會(huì)不合理恬砂。比如,某個(gè)團(tuán)隊(duì)三個(gè)人蓬痒,每個(gè)人周期序列分別是[2泻骤,300,200]梧奢,[15狱掂,3],[5亲轨,14趋惨,26],中位數(shù)分別是200惦蚊,14器虾,14讯嫂,算團(tuán)隊(duì)算數(shù)平均數(shù)時(shí),依然沒有排除掉極值的影響兆沙。
所以椎眯,最合理的方式也許是:
人均訂單數(shù)超過5單的團(tuán)隊(duì),計(jì)算一級(jí)中位數(shù)泡挺;而人均訂單數(shù)小于5的團(tuán)隊(duì)煌抒,計(jì)算兩級(jí)中位數(shù)。
當(dāng)然装悲,這里組合的方式就需要讀者您根據(jù)自己業(yè)務(wù)情況來定了昏鹃。
眾數(shù)目前我還沒有用上,它一般會(huì)用在離散型序列且數(shù)值個(gè)數(shù)較多的時(shí)候诀诊。
附錄:
sql語句中似乎沒有直接計(jì)算中位數(shù)的方式洞渤,我這邊從網(wǎng)上找了一段,個(gè)人讀后感覺是靠譜的属瓣,也貼出來载迄,供大家理解。概括的說抡蛙,它是使用2個(gè)子查詢來計(jì)算护昧,1個(gè)子查詢用來排序,1個(gè)子查詢用于計(jì)算總數(shù)粗截,然后根據(jù)總數(shù)的 奇/偶惋耙,來決定哪些行需要進(jìn)行計(jì)算。
SELECT
data_with_rownumber.Name,
AVG(data_with_rownumber.val) AS median
FROM
(
SELECT
ROW_NUMBER() OVER(PARTITION BY Name ORDER BY val) AS seq,
Name,val
FROM
test_median
) data_with_rownumber
JOIN
(
SELECT
Name, COUNT(1) AS NumOfVal
FROM
test_median
GROUP BY
Name
) data_count
ON
(
data_count.Name = data_with_rownumber.Name
AND
(
(data_count.NumOfVal % 2 = 0 AND data_with_rownumber.seq
IN (data_count.NumOfVal / 2, (data_count.NumOfVal / 2) + 1))
OR
(data_count.NumOfVal % 2 = 1
AND
data_with_rownumber.seq = 1 + data_count.NumOfVal / 2)
)
)
GROUP BY
data_with_rownumber.Name