您好,登錄后才能下訂單哦!
首先舉個例子:
正樣本(90) 負樣本(10)
模型1預測 正(90) 正(10)
模型2預測 正(70)負(20) 正(5)負(5)
結論:
模型1準確率90%;
模型2 準確率75%
考慮對正負樣本對預測能力,顯然模型2要比模型1好,但對于這種正負樣本分布不平衡對數據,準確率不能衡量分類器對好壞了,所以需要指標auc解決傾斜樣本的評價問題。
二分類混淆矩陣
預測\實際 1 0
1 TP FP
0 FN TN
TPR=TP/P=TP/TP+FN 直觀1中猜對多少
FPR=FP/N=FP/FP+TN 直觀0中猜錯多少
Auc對橫縱坐標分別為FPR和TPR,相對于y=x這條直線靠近左上角對分類器性能更好,所以模型2更優。
TPR FPR
模型1 90/90=1 10/10=1
模型2 70/90=0.78 5/10=0.5
模型1和2的auc點位分別如下圖所示,顯然模型1更優:
二 研究現狀
AUC直觀概念,任意取一對正負樣本,正樣本score大于負樣本對概率。
計算方法:正樣本和負樣本pair對,auc=預估正樣本score大于負樣本score的pair對數/總的pair對數。
E.g. 分別計算模型1和2對auc?
四個樣本label為y1=+1, y2=+1, y3=-1, y4=-1
模型1的預測為 y1=0.9, y2=0.5, y3=0.2, y4=0.6
模型2的預測為 y1=0.1, y2=0.9, y3=0.8, y4=0.2
解:
模型1: 正樣本score大于負樣本的pair包括(y1, y3), (y1, y4), (y2, y3),auc為3/4=0.75
模型2: 正樣本score大于負樣本的pair包括(y2, y3),(y2, y4),auc為2/4=0.5
計算參考paper:《 An introduction to ROC analysis 》(Tom Fawcett)
方法:
1按照score對樣本排序;
2依次對每個樣本,label分對TP增1,否則FP增1。計算每個小梯形的面積。
3累加所有樣本,計算auc
代碼:
= sorted(range(len(probs)),key=lambda i: probs[i], reverse== = = = = = = = probs[i_sorted[]] + i last_prob !=+= (TP+TP_pre) * (FP-FP_pre) / === labels[i_sorted[i]] == = TP + = FP + += (TP+TP_pre) * (FP-FP_pre) / = auc_temp / (TP *=== line = line.strip().split(= (line[= (line[ len(sys.argv) != = read_file(sys.argv[= % __name__==
三 點擊率模型auc計算方法
如上圖,以兩個分桶為例,每個分桶計算的AUC為圖中的陰影部分。全局AUC部分需要補充P3部分的面積,等于前i-1個桶的sum(click)乘以每i個桶的noclick。
整體的AUC就是曲線下的面積除以曲線的起點、終點錨定矩型的面積。
步驟
1按照pctr聚合 sum_show和sum_clk;
2樣本按照pctr排序;
3依次對每個樣本,計算noclk和clk圍成對小梯形對面積。
代碼:
import sys #init auc dict params_auc_dict = {"last_ctr":1.1, "slot_show_sum":0, "slot_click_sum":0, \ "auc_temp":0.0, "click_sum":0.0, "old_click_sum":0.0, "no_click":0.0, \ "no_click_sum":0.0} #init q distribute q_bucket = 1000params_Q_dict = {"count_list":[0]*(q_bucket+1)}for line in sys.stdin: lineL = line.strip().split('\t') if len(lineL) < 3: continue pctr = float(lineL[0]) #print lineL[0] #pctr = float(lineL[0])/1e6 show = int(float(lineL[1])) click = int(float(lineL[2])) slot_info = '-' ### calculate auc params_auc_dict["slot_show_sum"] += show params_auc_dict["slot_click_sum"] += click if params_auc_dict["last_ctr"] != pctr: params_auc_dict["auc_temp"] += (params_auc_dict["click_sum"] + \ params_auc_dict["old_click_sum"]) * params_auc_dict["no_click"] / 2.0 params_auc_dict["old_click_sum"] = params_auc_dict["click_sum"] params_auc_dict["no_click"] = 0.0 params_auc_dict["last_ctr"] = pctr params_auc_dict["no_click"] += show - click params_auc_dict["no_click_sum"] += show - click params_auc_dict["click_sum"] += click ### calculate Q distribution index = int(pctr / (1.0/q_bucket)) #interval [0, 0.001) left close, right open count_list = params_Q_dict["count_list"] count_list[index] += show # last instance for auc params_auc_dict["auc_temp"] += (params_auc_dict["click_sum"] + \ params_auc_dict["old_click_sum"]) * params_auc_dict["no_click"] / 2.0if params_auc_dict["auc_temp"] > 0: auc = params_auc_dict["auc_temp"] / (params_auc_dict["click_sum"] * params_auc_dict["no_click_sum"])else: auc = 0print "AUC:%s\tshow_sum:%s\tclk_sum:%s" %( auc, params_auc_dict["slot_show_sum"], params_auc_dict["slot_click_sum"]) #print Q distribution resultfor item in params_Q_dict: count_list = params_Q_dict["count_list"] print "Max bucket num: %s" %(sum(count_list)) for i in range(q_bucket+1): if i < (q_bucket - 1): print str((i+1)*(1.0/q_bucket)) + '\t' + str(count_list[i]) else: print '1.0\t' + str(count_list[i]+count_list[i+1]) break
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。