反欺诈抱团实践
? ? ? ?之前寫過一篇《抱團(tuán)反欺詐問題探討》的交流文章,拋出了抱團(tuán)分析中回溯團(tuán)形成的問題,經(jīng)過這段時(shí)間的思考和琢磨,大致將這個(gè)想法落地實(shí)現(xiàn)了,所以重新梳理了一下寫出來(lái)。雖然研究得斷斷續(xù)續(xù),不過好在最后是完成了。
?
目錄
1.最大子團(tuán)分析
2.抱團(tuán)回溯分析
3.規(guī)則制定
4.總結(jié)
?
一、最大子團(tuán)分析
? ? ? ?本文用得是networkx庫(kù)實(shí)現(xiàn)抱團(tuán),并結(jié)合pandas進(jìn)行數(shù)據(jù)處理,衍生出抱團(tuán)過程中每一步的變量。我一開始是使用的python_igraph庫(kù),但是嘗試了一段時(shí)間后發(fā)現(xiàn)這個(gè)庫(kù)的依賴問題太多,大量精力耗費(fèi)在解決各種奇奇怪怪的依賴報(bào)錯(cuò)問題上。最后決定轉(zhuǎn)向networkx,由于是anaconda自帶的庫(kù),使用過程除了讀英文文檔耗了點(diǎn)時(shí)間外,沒有遇到特別難的問題。
? ? ? ?首先將全量申請(qǐng)訂單的申請(qǐng)時(shí)間、申請(qǐng)狀態(tài)、手機(jī)號(hào)、聯(lián)系人手機(jī)號(hào)、PD指標(biāo)按照申請(qǐng)時(shí)間從遠(yuǎn)到近排列。為了熟悉networkx的基本用法,本文先從最大團(tuán)的分析入手,然后再對(duì)最大團(tuán)的形成過程進(jìn)行抱團(tuán)回溯。
keys?=?df['apply_mobile'].tolist()
values?=?df['contactmobile'].tolist()
edgelist?=?list(zip(keys,?values))
#抱團(tuán)
H=nx.Graph(edgelist)
#增加節(jié)點(diǎn)屬性
for i in df.index:
? ? H.nodes[df.loc[i]['apply_mobile']]['user_id']=df.loc[i]['user_id']
? ? H.nodes[df.loc[i]['apply_mobile']]['app_create_time']=df.loc[i]['app_create_time']
? ? H.nodes[df.loc[i]['apply_mobile']]['fpd1']=df.loc[i]['fpd1']
? ? H.nodes[df.loc[i]['apply_mobile']]['fpd15']=df.loc[i]['fpd15']
? ? H.nodes[df.loc[i]['apply_mobile']]['fpd30']=df.loc[i]['fpd30']
#基于點(diǎn)連接劃分子團(tuán)
h=[H.subgraph(c).copy() for c in nx.connected_components(H)]
? ? ? ?這一步生成所有的基于點(diǎn)連接形成的子團(tuán),列表的每一個(gè)元素是一個(gè)graph對(duì)象,為了找出最大子團(tuán)的graph對(duì)象,需要做以下操作:
# 找出最大團(tuán)
h={}
for i in enumerate(nx.connected_components(H)):
? ? if len(i[1])==len(max(nx.connected_components(H),key=len)):
? ? ? ? h[i[0]]=H.subgraph(i[1]).copy()
? ? ? ?這一步用一個(gè)字典存儲(chǔ)了最大子團(tuán)對(duì)象,字典的鍵值為最大子團(tuán)產(chǎn)生的序號(hào)。這一步h有兩個(gè)最大子團(tuán),序號(hào)分別為777和2358。
畫出最大團(tuán):
? ? ? ?通過分析最大團(tuán)發(fā)現(xiàn):這個(gè)團(tuán)一共有9個(gè)人,4單申請(qǐng),2單決絕,拒絕原因?yàn)樵诰W(wǎng)時(shí)長(zhǎng)過短、外部分過低,關(guān)聯(lián)交易有欺詐嫌疑;通過2單,1單發(fā)生逾期。
?
二、抱團(tuán)回溯分析
? ? ? ?回溯分析的實(shí)現(xiàn)過程本質(zhì)就是循環(huán)抱團(tuán),并對(duì)每一步形成的團(tuán)進(jìn)行衍生變量的計(jì)算。在寫代碼的過程中我采取的思路是,先采用最大子團(tuán)最后一個(gè)申請(qǐng)的號(hào)碼為例,衍生出這個(gè)號(hào)碼申請(qǐng)時(shí)時(shí)看到團(tuán)的通過率、FPD1%、FPD15%、黑名單命中率、多頭拒絕率等指標(biāo),然后再去寫循環(huán),將這個(gè)號(hào)碼替換成循環(huán)過程中的每一個(gè)號(hào)碼即可。
# 循環(huán)抱團(tuán)衍生代碼
for i in df.index:
? ? keys = df['apply_mobile'][0:i+1].tolist()
? ? values = df['contactmobile'][0:i+1].tolist()
? ? edgelist = list(zip(keys, values))
? ? H=nx.Graph(edgelist)
? ? #如果形成的團(tuán)個(gè)數(shù)大于5個(gè),則開始衍生變量
? ? if len(nx.node_connected_component(H,df['apply_mobile'][i]))>=5:
? ? ? ? s=nx.node_connected_component(H,df['apply_mobile'][i])
? ? ? ? df.loc[df.apply_mobile==df['apply_mobile'][i],'團(tuán)人數(shù)']=len(s)
? ? ? ? df.loc[df.apply_mobile==df['apply_mobile'][i],'團(tuán)結(jié)構(gòu)']=str(nx.node_connected_component(H,df['apply_mobile'][i]))
? ? ? ? #需要剔除本單申請(qǐng)的號(hào)碼
? ? ? ? s.remove(df['apply_mobile'][i])
? ? ? ? print(i)
? ? ? ? #取出本單申請(qǐng)之前的團(tuán)內(nèi)所有號(hào)碼的訂單信息
? ? ? ? df_temp=df[0:i+1][df['apply_mobile'][0:i+1].isin(s)]
? ? ? ? #變量衍生
? ? ? ? df.loc[df.apply_mobile==df['apply_mobile'][i],'通過率']=df_temp.app_id.drop_duplicates().count()/len(df_temp.user_id.unique())
? ? ? ? df.loc[df.apply_mobile==df['apply_mobile'][i],'FPD1']=(df_temp[df_temp.fpd1==1].app_id.drop_duplicates().count())/df_temp.app_id.drop_duplicates().count()
? ? ? ? df.loc[df.apply_mobile==df['apply_mobile'][i],'FPD15']=(df_temp[df_temp.fpd15==1].app_id.drop_duplicates().count())/df_temp.app_id.drop_duplicates().count()
? ? ? ? df.loc[df.apply_mobile==df['apply_mobile'][i],'黑名單命中數(shù)']=df_temp[df_temp.reject==1].user_id.drop_duplicates().count()
? ? ? ? df.loc[df.apply_mobile==df['apply_mobile'][i],'逾期命中數(shù)']=df_temp[df_temp.reject==2].user_id.drop_duplicates().count()
? ? ? ? df.loc[df.apply_mobile==df['apply_mobile'][i],'多頭拒絕數(shù)']=df_temp[df_temp.reject==3].user_id.drop_duplicates().count()
? ? ? ? df.loc[df.apply_mobile==df['apply_mobile'][i],'外部逾期數(shù)']=df_temp[df_temp.reject==4].user_id.drop_duplicates().count()
? ? ? ? df.loc[df.apply_mobile==df['apply_mobile'][i],'團(tuán)內(nèi)在逾個(gè)數(shù)']=df_temp[(df_temp.delayed_status.notnull())&(df_temp.delayed_status!='M0')].user_id.drop_duplicates().count()
? ? ? 下面以兩個(gè)最大子團(tuán)(9人團(tuán))的形成過程為例,說(shuō)明團(tuán)的形成過程:
? ? ? ?以上為第一個(gè)最大子團(tuán)的形成過程,其中在形成最大子團(tuán)之前形成過一個(gè)5人團(tuán),這個(gè)團(tuán)如果不進(jìn)行回溯分析,是沒有辦法分析到的。
? ? ? ?上圖中有顏色的表示申請(qǐng)件,紅色表示申請(qǐng)被拒絕,黃色表示申請(qǐng)通過但發(fā)生逾期,綠色表示申請(qǐng)通過且未逾期。在團(tuán)形成的第2個(gè)人申請(qǐng)時(shí),形成了一個(gè)5人團(tuán),此時(shí)第三個(gè)人看到的團(tuán)的通過率為0%,多頭拒絕率為100%,第2個(gè)人申請(qǐng)通過且發(fā)生逾期;第3個(gè)人申請(qǐng)時(shí),他所填的聯(lián)系人未形成團(tuán);第4個(gè)人申請(qǐng)時(shí),他填寫的聯(lián)系人也是第3個(gè)人申請(qǐng)時(shí)填寫聯(lián)系人,因此5人團(tuán)與3人團(tuán)被連通,形成一個(gè)9人團(tuán)。此時(shí)第4個(gè)人申請(qǐng)時(shí)看到的團(tuán)的結(jié)構(gòu)為:3人申請(qǐng),1人通過,2人拒絕(都為多頭拒絕)。他的直接聯(lián)系人未發(fā)生逾期,但是他作為聯(lián)系人出現(xiàn)的申請(qǐng)人(一度關(guān)聯(lián))以及他的聯(lián)系人關(guān)聯(lián)的其他訂單(二度關(guān)聯(lián))發(fā)生逾期。這種情況下,第4人申請(qǐng)通過,未發(fā)生逾期。
? ? ? 再看另外一個(gè)最大團(tuán):
? ? ? ?這個(gè)9人團(tuán)生成的過程中,分別形成過5人團(tuán)、7人團(tuán),然后最終形成了9人團(tuán)。
? ? ? ?這個(gè)9人團(tuán)涉及的4筆訂單全部被拒絕,拒絕原因非黑名單類、信貸逾期類、多頭類規(guī)則,這里時(shí)由于變量衍生地不夠,應(yīng)該再加入一些其他拒絕原因的變量。另一方面也說(shuō)明風(fēng)控手段的有效性,在無(wú)聯(lián)系人抱團(tuán)規(guī)則的情況下依然有效地防范住了一定的欺詐。
?
三、規(guī)則制定
? ? ? ?通過上述地回溯過程,已經(jīng)得到所有5人以上的團(tuán)以及團(tuán)的各種衍生特征,以這些變量為x,是否通過/逾期為y,可以制定一些單變量或者組合變量規(guī)則。
? ? ? 上圖數(shù)據(jù)為根據(jù)抱團(tuán)結(jié)果虛構(gòu),從上圖可以看出,5人以上各團(tuán)的通過率、逾期率情況,一般來(lái)說(shuō)團(tuán)的人數(shù)越大通過率可能越低,但是由于通過率低了,壞人被其他規(guī)則拒絕了,進(jìn)來(lái)的人逾期指標(biāo)不一定和團(tuán)人數(shù)成正相關(guān)。
? ? ? ?通過分析發(fā)現(xiàn),團(tuán)內(nèi)黑名單命中數(shù)是比較有效的一條抱團(tuán)規(guī)則。團(tuán)內(nèi)黑名單命中人數(shù)越多時(shí),通過率越低,且通過件中的FPD15占比依然較高,因此通過抱團(tuán)分析要找的就是這種拒絕率很高且逾期率很高的規(guī)則,也就是單規(guī)則的lift值高。類似的規(guī)則還可以有:團(tuán)內(nèi)多頭拒絕占比、團(tuán)內(nèi)信貸逾期命中占比等等。
? ? ? ?通過組合規(guī)則的分析,也就解決了之前那篇文章中的問題:如果一個(gè)五人團(tuán),A是黑名單拒絕,B通過且未逾期,C通過且逾期(仍然在逾),D通過且逾期(已催回),此時(shí)E過來(lái)申請(qǐng)時(shí),他看到的團(tuán)的情況就是:和他有關(guān)系的4人中有通過率(75%),逾期率(66.6%)。這種情況下對(duì)E如何作決策的問題,通過這種抱團(tuán)回溯、衍生變量的分析就可以確定最終的閾值。反欺詐抱團(tuán)分析的核心還是在變量的衍生上,回溯的代碼完成的情況下,想要真正地在業(yè)務(wù)中落地,就需要在衍生變量這塊作一些文章了。
?
四、總結(jié)
? ? ? ?簡(jiǎn)單說(shuō)一下作這個(gè)分析的心得,一開始沒覺得自己可以把這件事情完成,看了手上excel和sql實(shí)現(xiàn)的文件也是很復(fù)雜難懂,最后索性搞清了思路后用python去實(shí)現(xiàn),確實(shí)簡(jiǎn)潔和迅速很多。在用python實(shí)現(xiàn)過程中,也遇到了不少問題,幾近讓我覺得自己完不成這個(gè)任務(wù),讀英文文檔時(shí)也覺得很難沉下心來(lái)去研讀,不過后來(lái)還是一點(diǎn)點(diǎn)、靜下心來(lái)堅(jiān)持完成了這個(gè)分析。心態(tài)很重要,堅(jiān)持也很重要,也許這個(gè)分析費(fèi)了很大的力氣依然沒能完成,或者沒有在業(yè)務(wù)上落地,但是重要的是努力去完成這件事情的過程,人生的很多事情,過程比結(jié)果重要。
【作者】:Labryant
【原創(chuàng)公眾號(hào)】:風(fēng)控獵人
【簡(jiǎn)介】:做一個(gè)有規(guī)劃的長(zhǎng)期主義者。
【轉(zhuǎn)載說(shuō)明】:轉(zhuǎn)載請(qǐng)說(shuō)明出處,謝謝合作!~
?
?
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
- 上一篇: 评分卡中的一些理论知识
- 下一篇: 信用卡葵花宝典笔记(一)