當前位置:
首頁 >
【项目实战】:基于python的p2p运营商数据信息的特征挖掘
發布時間:2025/3/21
73
豆豆
生活随笔
收集整理的這篇文章主要介紹了
【项目实战】:基于python的p2p运营商数据信息的特征挖掘
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
######【風控建模】
基于python的p2p運營商數據信息的特征挖掘
**@author: sunyaowu** **@datetime: 2018年8月**說明:利用平臺數據和第三方數據建立基于用戶通信信息的反欺詐規則,判別通信信息及通話記錄對客戶潛在逾期發生的預警。
一 獲取數據
1)數據庫: petty_loan
①用戶信息
- cl_user_base_info
②運營商數據
- 賬戶信息
cl_operator_basic - 消費賬單
cl_operator_bills - 通話記錄
cl_operator_voices_1
cl_operator_voices_2
③通訊錄
- cl_user_contacts_1
- cl_user_contacts_2
④緊急聯系人
- cl_user_emer_contacts
⑤借貸客戶逾期數據
- cl_borrow_repay
2)數據信息
- 用戶手機號
- 用戶手機號開戶時間
- 用戶手機號在平臺注冊時間
- 用戶手機號歸屬地址、撥號地址
- 用戶手機號消費賬單
- 用戶手機號通話記錄
- 通話日期、時間
- 通話號碼
- 通話時間
- 主叫地址
- 用戶通訊錄詳單
- 用戶緊急聯系人電話號、身份關系
3)信息價值
| 手機號 | 手機號開戶時間 | ①手機號真實性 ②判斷手機號使用時長 ③用戶粘性 |
| 通話記錄 | ①通話地址(范圍) ②通話群體 ③通話時長 | ①手機號價值 ②手機號粘性 ③用戶活躍度 |
| 通訊錄 | ①通訊錄大小 ②判斷通訊錄名單聯系頻率 | ①客戶社交范圍 ②通訊錄價值 |
| 緊急聯系人 | ①是否在通訊錄中 ②是否有近期通話記錄 | ①聯系人真實性 ②潛在欺詐風險 |
| 逾期賬戶 | ①是否逾期 | ①逾期客戶通信信息情況反饋 |
二 數據預處理 + 特征分析 + 模型搭建
1)項目思路
①直接從數據庫中通過python/sql語句獲取測試數據,也可以保存excel、csv、pkl文件。
②數據預處理和數據分析。
③建立Logistic、隨機森林算法模型,尋找變量之間的關系。
2)分步邏輯
①從數據庫抓取數據,為方便代碼復用,建立三個函數,分別是:
- 專門用來連接mysql數據庫的DataBaseSql函數
- 專門用來存儲sql語句的sql_query函數
- 專門用來調用sql語句和mysql數據庫連接以生成Dataframe數據的get_data函數
②對數據進行預處理。包括數據缺失值、異常值處理等,主要分為三步:
- 合并數據。數據分別存儲在不同的excel文件中,以備不同情況下的處理,合并數據以獲得此次分析所需要的數據。
- 缺失值處理,對需要處理的數據字段進行缺失值填充和丟失處理。
- 生成用來作進一步分析處理的數據。
③數據分析+可視化報告:
- 爬取數據統計。主要就樣本總體情況做指標,打印報告。
- 緊急聯系人通話記錄統計。判斷緊急聯系人的通訊錄權限、運營商信息權限開通情況,做統計圖。
- 放款客戶逾期情況統計。
3)語法重點
①python編程整體思路:
- python: 函數式編程、數據流程、代碼復用、實例化、debug處理
②數據庫:
- mysql:多表查詢join、多表合并union、時間戳gettime、篩選條件where、
- python:調用數據庫connet、游標cursor、數據匹配fetchall、事務提交commit
③數據處理:
- 常用方法:讀取文件read_excel、計數value_counts、重置索引reset_index、關聯匹配merge、去除重復值drop_duplicates、最大值max、去除空值dropna、替換replace、字符串str、矩陣形狀shape、整形int
- 特殊思路:建立一個for循環,判斷字段里是否有某個字符串、建立循環,批量填充
③可視化+執行報告:
- 常用方法:
- xlsxwriter.Workbook、workbook.add_worksheet、time.sleep(0)、worksheet.insert_image、set_column、zip、plt、echart
4)執行代碼
①導入python模塊,定義類名:
""" pro:AntiFraudRule.py @author: sunyaowu """import numpy as np import pandas as pd import time import os import pymysql import sys import matplotlib.pyplot as plt import seaborn as sns import pyecharts import xlwt import xlsxwriter _path = r'C:\Users\A3\Desktop\2:項目\項目\項目22: Python數據庫模塊搭建,支持增刪查改調用' os.chdir(_path + '\data') sys.path.append(_path) import DataBaseSql②數據庫query數據
- 編寫數據庫查詢函數,可存為DataBaseSql.py文件,支持調用
- 編寫sql語句
- 從數據庫中query數據,保存為excel文件
②數據處理
def data_pro(self,name): data0 = pd.read_excel('%s.xlsx'%name[0])data1 = pd.read_excel('%s.xlsx'%name[1])_data1 = data1['user_id'].value_counts().reset_index()_data1.columns = 'user_id','phone_counts'data_mix = pd.merge(data0,_data1,on = 'user_id',how = 'left')data2 = pd.read_excel('%s.xlsx'%name[2])_data2 = data2['user_id'].value_counts().reset_index()_data2.columns = 'user_id','voice_counts' #data22.rename(columns = {'index':'user_id','user_id':'voice_counts'},inplace = True)data_mix = pd.merge(data_mix,_data2,on = 'user_id',how = 'left')_data2 = data2['voice_to_number'].value_counts().reset_index()_data2.columns = 'voice_to_number','tel_counts'__data2 = pd.merge(data2.dropna(),_data2,on = 'voice_to_number',how = 'left').drop_duplicates(subset=['voice_to_number']).astype({'tel_counts':'int'})__data2 = __data2 [__data2['tel_counts'] > 5] _data2 = __data2['user_id'].value_counts().reset_index()_data2.columns = 'user_id','tel_5_counts' _data2 = pd.merge(_data2,__data2[['user_id','tel_counts']].groupby('user_id').max().reset_index(),on = 'user_id',how = 'left')_data2.rename(columns = {'tel_counts':'max_tel_count'},inplace = True)data_mix = pd.merge(data_mix,_data2,on = 'user_id',how = 'left') data4 = pd.read_excel('%s.xlsx'%name[4])data24_mix = pd.merge(data2,data4,on = 'user_id',how = 'left').drop_duplicates(subset=['voice_to_number']).dropna().reset_index()#data24_mix['voice_to_number'] = data24_mix['voice_to_number'].str.replace(')','').str.replace('(','').str.replace('*','').str.replace('+','')#for i in range(data24_mix.shape[0]):# data24_mix['voice_to_number'][i] = int(''.join(list(filter(lambda ch: ch in '0123456789',data24_mix['voice_to_number'][i]))))# print(i)#data24_mix = data24_mix.dropna()data24_mix['emer_in_voice'] = 0for i in range(data24_mix.shape[0]):a = str(data24_mix['voice_to_number'][i])b = str(data24_mix['phone'][i])print (i)if a == b:data24_mix['emer_in_voice'][i] = 1data24_mix = data24_mix[data24_mix['emer_in_voice'] == 1]data_mix = pd.merge(data_mix,data24_mix[['user_id','emer_in_voice']],on = 'user_id',how = 'left') data3 = pd.read_excel('%s.xlsx'%name[3])data_mix = pd.merge(data_mix,data3,on = 'user_id',how = 'left')for i in ['phone_counts','voice_counts','tel_5_counts','max_tel_count','emer_in_voice']: data_mix[i].fillna(0,inplace = True)data_mix.to_excel(_path +'\data\%s.xlsx'%name[5]) emer_in_voice = data_mix[data_mix['emer_in_voice'] == 1]emer_in_voice.to_excel(_path +'\data\%s.xlsx'%name[6])emer_in_repay = data_mix[data_mix['penalty_day'] >= 0]'''emer_in_repay['penalty'] = 0for i in range(emer_in_repay.shape[0]):a = emer_in_repay['penalty_day'][i]pirnt(a)if a > 0 :emer_in_repay['penalty'][i] = 1'''emer_in_repay.to_excel(_path +'\data\%s.xlsx'%name[7])return data_mix,emer_in_voice,emer_in_repay③數據分析 + 可視化報告
'''所有抓取數據的特征描述、分析及可視化報告'''def data_query_description(self,num,name):data = pd.read_excel(_path +'\data\%s.xlsx'%name[5])worksheet1 = workbook.add_worksheet('query_data_report')worksheet1.set_column('A:B',50)a = ['通訊錄信息','運營商信息','通話記錄','通話記錄']b = ['phone_counts','voice_counts','tel_5_counts','emer_in_voice']c = ['開通通訊錄權限','開通運營商信息權限','有通話記錄','與緊急聯系人存在通話記錄']data_count = []m = 0for i,j,n in zip(a,b,c):_p = len(data)_q = len(data[data[j]>0])data_count.append(_q)d,e = '爬取%i數據共%s條,其中有效數據共%i條' %(num,i,_q),'說明用戶%s的比例為:%.2f%%' %(n,_q/_p*100)print(d,e) worksheet1.write(m,0,d)#寫入excel報告worksheet1.write(m,1,e)#寫入excel報告time.sleep(0) m += 1print('-----next-----')time.sleep(0) d = '開通運營商權限的%i個用戶中,有過通話記錄的為%i,占比%.2f%%' %(data_count[1],data_count[2],data_count[2]/data_count[1]*100) print(d) e = '有過通話記錄的%i個用戶中,與緊急聯系人通話的為%i,占比%.2f%%' %(data_count[2],data_count[3],data_count[3]/data_count[2]*100) print('-----next-----')print(e) print('Bingo!')worksheet1.write(m + 1,0,d)#寫入excel報告worksheet1.write(m + 2,0,e)#寫入excel報告self.data_query_show(num,data,name,worksheet1) workbook.close() #關閉excel文件return datadef data_query_show(self,num,data,name,worksheet):box = ['phone_counts','voice_counts','tel_5_counts','max_tel_count']for item in box :#data[item].bar()#plt.show() #直接利用Dataframe畫圖 self.hist_show(data[data[item] > 0],item,100) #為變量屬性畫直方圖 v = 8for p,q,l in zip(box,[8,8,18,18],['A','B','A','B']) :worksheet.insert_image('%s%i'%(l,q),_path + r'\report+image\%s.png'%p,{'x_scale': 0.5, 'y_scale': 0.5})#寫入excel報告#for item in ['relation','emer_in_voice']: # data[item].bar()# plt.show()#self.hist_show(data[data[item] > 0],item,100) #為變量屬性畫箱型圖 #self.data_report(): #self.echart_show(data['relation'])'''存在緊急聯系人數據的特征描述、分析及可視化報告'''def data_emer_description(self,num,name):data = pd.read_excel(_path +'\data\%s.xlsx'%name[5])worksheet2 = workbook.add_worksheet('emer_data_report')a = ['通訊錄信息','運營商信息','通話記錄','通話記錄']b = ['phone_counts','voice_counts','tel_5_counts','emer_in_voice']c = ['開通通訊錄權限','開通運營商信息權限','有通話記錄','與緊急聯系人存在通話記錄']data_count = []for i,j,n in zip(a,b,c):_p = len(data)_q = len(data[data[j]>0])data_count.append(_q)print('爬取客戶數據共%i條,其中有效%s數據共%i條' %(num,i,_q))print('說明用戶%s的比例為:%.2f%%' %(n,_q/_p*100)) print('-----next-----')time.sleep(0) #type(data_count[0])print('開通運營商權限的%i個用戶中,有過通話記錄的為%i,占比%.2f%%' %(data_count[1],data_count[2],data_count[2]/data_count[1]*100) ) print('-----next-----')time.sleep(0) print('有過通話記錄的%i個用戶中,與緊急聯系人通話的為%i,占比%.2f%%' %(data_count[2],data_count[3],data_count[3]/data_count[2]*100) ) print('Bingo!')#寫入text報告self.data_query_show(num,data,name)#函數中將過程產生圖片也保存在text報告中return data def data_emer_show(self,name): data = pd.read_excel(_path +'\data\%s.xlsx'%name[6])for item in ['phone_counts','voice_counts','tel_5_counts']:self.hist_show(data1[(data1[item] > 0) & (data1[item] < 1*data1[item].max())],item,20) return data'''借貸用戶還款數據的特征描述、分析及可視化報告'''def data_repay_description(self,num,name):data = pd.read_excel(_path +'\data\%s.xlsx'%name[5])worksheet3 = workbook.add_worksheet('repay_data_report')a = ['通訊錄信息','運營商信息','通話記錄','通話記錄']b = ['phone_counts','voice_counts','tel_5_counts','emer_in_voice']c = ['開通通訊錄權限','開通運營商信息權限','有通話記錄','與緊急聯系人存在通話記錄']data_count = []for i,j,n in zip(a,b,c):_p = len(data)_q = len(data[data[j]>0])data_count.append(_q)print('爬取%s數據共%i條,其中有效數據共%i條' %(i,num,_q))print('說明用戶%s的比例為:%.2f%%' %(n,_q/_p*100)) print('-----next-----')time.sleep(0) #type(data_count[0])print('開通運營商權限的%i個用戶中,有過通話記錄的為%i,占比%.2f%%' %(data_count[1],data_count[2],data_count[2]/data_count[1]*100) ) print('-----next-----')time.sleep(0) print('有過通話記錄的%i個用戶中,與緊急聯系人通話的為%i,占比%.2f%%' %(data_count[2],data_count[3],data_count[3]/data_count[2]*100) ) print('Bingo!')#寫入text報告self.data_query_show(num,data,name)#函數中將過程產生圖片也保存在text報告中return data def data_repay_show(self,name):data = pd.read_excel(_path +'\data\%s.xlsx'%name[7])for item in ['phone_counts','voice_counts','tel_5_counts']:self.hist_show(data1[data1[item] > 0],item,20) for item in ['relation','phone_counts','voice_counts']:self.boxplot_show(data3,item,'penalty_day') return data # ============================================================================= # #可視化及數據報告功能 # ============================================================================='''頻率分布直方圖''' def hist_show(self,data,field,bin):'''data[field].hist(bins = bin,histtype = 'bar',align = 'mid',orientation = 'vertical',alpha = 0.5,normed = True )data[field].plot(kind = 'kde',style = 'k--')'''plt.hist(data[field], bins=40, normed=0, facecolor="blue", edgecolor="black", alpha=0.7)plt.title(field)plt.savefig(_path + r'\report+image\%s.png' % field, dpi=100)plt.show()'''柱狀圖''' '''箱型圖''' '''雙變量箱型圖''' def boxplot_show(self,data,field1,field2):data = pd.concat([data[field1], data[field2]], axis=1)fig = sns.boxplot(x=field1, y=field2, data=data)plt.title(field1)plt.show() #plt.savefig('%s.png' % field, dpi=200)'''本地文件eharts''' def echart_show(self,data):from pyecharts import Bar from pyecharts import Bar, Linefrom pyecharts.engine import create_default_environmentbar = Bar("緊急聯系人分布", "副標題")bar.add('聯系人',data)# bar.print_echarts_options() # 該行只為了打印配置項,方便調試時使用bar.render() # 生成本地 HTML 文件'''寫入excel文件并生成報告''' def data_report():pass④特征挖掘
- 待續!
⑤主函數
if __name__ == "__main__":AFR = AntiFraudRule() number = 10000 #int(input('請輸入您要查詢的ID數量!\n')) name = ['emer_relation_data','phonebook_data','tel_records_data','repay_data','emer_real_data','data_mix','emer_in_voice','emer_in_repay']_begin_time = time.time() ''' 1、數據獲取'''print("---------- 1.get_data ----------")#AFR.get_data(name)''' 2、數據處理'''print("---------- 2.data_pro ----------")#data_mix,emer_in_voice,emer_in_repay = AFR.data_pro(name) ''' 3、數據分析'''print("---------- 3.data_show ----------")workbook = xlsxwriter.Workbook('report.xlsx')data_query = AFR.data_query_description(number,name)#data_emer = AFR.data_emer_description(number,name)#data_repay = AFR.data_repay_description(number,name)''' 4、特征挖掘'''#print("---------- 4.data_rule ----------")#print('finished!')''' 5、可視化報告'''#print("---------- 5.result_model ----------")#print('finished!')_end_time = time.time()print('You have finished!\nfanilly use time: {x:.2f}s'.format(x = _end_time - _begin_time))三 總結
- 初衷:此項目用于新手項目練手,重在完整的展現一個數據挖掘項目的數據整理流程。包括數據獲取、處理、挖掘、可視化等模塊。用時五個工作日,新手期可以接受。
- 問題:由于維度比較單一,可視化分析和可供挖掘的特征比較少,故只簡單的實現了基礎功能,并未深挖,后續有時間再補充。整個項目,看起來比較簡單,實則已經運用了python的一些基礎卻高效的功能。例如:pandas、matplotlib、sql、url、xlwt、echart、os、path等。
- 反思:代碼只是執行思維的工具,有一個接觸、理解、運用、熟練的過程。重點是coder思維邏輯是否清晰,能否按照工程流workflow、項目流、數據流的方式層次、結構化、邏輯化的去執行工作。
- Finally!
- 高效學習有兩個很重要的習慣:
①快速進入專注的狀態。
②長期保持專注的狀態。
- 高效學習有兩個很重要的習慣:
總結
以上是生活随笔為你收集整理的【项目实战】:基于python的p2p运营商数据信息的特征挖掘的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Python】xlwt基础:excel
- 下一篇: 【项目实战】基于python的 p2p