?本項目主要實現邏輯如下:

1.將測試數據分表格存入mysql資料庫。

2.設計知識圖譜關係圖,按照設計思路將node與對應的relationship存入neo4j資料庫。

3.設計一套有效的特徵,提取特徵用於機器學習模型進行訓練,用以風控判斷。

4.將提取特徵的cypher語句存入mysql,使用SpringBoot搭建微服務,用以讀取api獲取每個進件的特徵矩陣。

5.使用邏輯回歸、GBDT,神經網路等模型在訓練數據上搭建風控模型,通過AUC指標判斷模型的準確率。

6.使用測試數據,通過最優模型獲取預測結果。

下面講解具體實現過程:

1.測試數據準備

我們準備了如下幾個測試數據集

person:標註用戶姓名、性別、手機號、用戶黑名單

phone:手機號、手機號黑名單

phone2phone:通話記錄撥打方、接聽方、通話的起止時間

apply_train與apply_test:進件貸款金額、實現、申請人工作、地點、父母手機號、同事手機號、公司電話、申請人id、進件狀態(其中apply_test內status值為空)

將以上所有數據導入mysql

2.設計知識圖譜

由測試數據可直接得到以下關係: 1.people節點與apply節點之間有fill關係 2.apply節點與phone節點之間有parent_phone、colleague_phone、company_phone等關係 3.people與phone之間有has_phone的關係 然後通過上述關係可推得以下關係: 4.parent_phone的持有人與進件的申請人為parent_of關係,同理可推得colleague_of關係 5.通過通話記錄可推得兩個people節點之間的known關係

通過以上關係圖譜,使用APOC將數據以對應的關係存入neo4j中,得到類似於以下結構的數據

3.設計特徵提取規則

因為最終傳入機器學習模型的訓練應該是一個二維數組,所以我們需要從neo4j中提取每個進件的特徵。實際項目中,可能需要設計幾十個或上百個規則才可以達到需要的準確率,在這裡以7個特徵為例做講解。

我們需要將以上規則存入mysql,用以後續調用

4.搭建SpringBoot微服務

代碼結構如下:業務代碼放在RuleController類中

@RestController
@Api(value = "/" , description = "規則引擎服務")
@RequestMapping("v1")
public class RuleController {

@Autowired
private SqlSessionTemplate template;

@Autowired
private Driver driver;

@ApiOperation(value = "獲取規則引擎中規則執行的結果",httpMethod = "POST")
@RequestMapping(value = "/getRuleResult", method = RequestMethod.POST)
public int getRuleResult(@RequestParam String ruleID, @RequestParam Integer applyId){
/**
* 從mysql中拿到規則
*/
String ruleCypher = template.selectOne("getRule",ruleID);

/**
* 獲取到neo4j的session 對象,用來執行cypher語句
*/
Session session = driver.session();
Map ruleMap = new HashMap();
ruleMap.put("applyId",applyId);

//用來存儲Cypher最終執行的結果
int resultCount = 0;

// 執行cypher語句
StatementResult result = session.run(ruleCypher,ruleMap);

Map resultMap = new HashMap();
while (result.hasNext()){
Record record = result.next();
resultMap = record.asMap();
Long resultLong = (Long) resultMap.get("count(a)");
resultCount = Math.toIntExact(resultLong);
}
return resultCount;
}
}

我們在傳入對應的rule_id和進件id時,可以通過微服務拿到我們需要的特徵值,然後將所有特徵組合為二維向量,形成機器學習模型所需的測試數據集。 此時所有OVERDUE狀態的進價,我們將label標記為1,其他狀態的進件標記為0,導入data.txt文件

import re
import requests

f2 = open(data.txt, a+, encoding=utf8)
with open(train.txt, r, encoding=utf8) as f:
for i in f.readlines():
l = []
num = re.findall((d{6}), i)[0]
l.append(int(num))
for rule in range(1, 8):
r = requests.post(
http://localhost:9527/v1/getRuleResult?ruleID= + str(rule) + &applyId= + str(num)).text
l.append(int(r))
status = re.findall(IN_PROGREESS|REPAID|OVERDUE|RETURNING, i)[0]

if status == OVERDUE:
label = 1
else:
label = 0
l.append(label)
f2.write(str(l)+,)

當然,猶豫樣本不均衡的原因,直接使用測試數據會導致模型AUC值較低,所以需要對測試數據集進行一定處理,樣本不均衡問題的解決方案不在此做過多闡述。

5.機器學習模型訓練

使用邏輯回歸、GBDT、神經網路等常用二分類問題模型,對測試數據進行訓練,再次僅以神經網路模型進行代碼演示。 導入數據集

import pandas as pd
dataArray = eval(open(data.txt, r, encoding=utf8).read())
df = pd.DataFrame(dataArray)
X = df.iloc[:, 1:8].values
y = df.iloc[:,8].values

建立神經網路模型進行訓練:通過K-FORD交叉驗證對模型進行調參

from sklearn.neural_network import MLPClassifier
from sklearn.model_selection import KFold
from sklearn.metrics import roc_auc_score
import numpy as np

param_hidden_layer_sizes = np.linspace(10, 200, 20) # 針對參數 「hidden_layer_sizes」, 嘗試幾個不同的值
param_alphas = np.logspace(-4,1,6) # 對於參數 "alpha", 嘗試幾個不同的值

best_hidden_layer_size = param_hidden_layer_sizes[0]
best_alpha = param_alphas[0]

for size in param_hidden_layer_sizes:
for val in param_alphas:
sc = []
for train_index, test_index in kf.split(X):
mlp = MLPClassifier(alpha=int(val),hidden_layer_sizes=int(size)).fit(X[train_index],y[train_index])
y_predict = mlp.predict(X[test_index])
sc.append(roc_auc_score(y[test_index],y_predict))
auc_list = np.array(sc)
auc_avg = auc_list.mean()
print(auc_avg)
if auc_avg > best_auc_avg:
best_auc_avg = auc_avg
best_hidden_layer_size = size
best_alpha = val
auc_std = auc_list.std()

print ("auc均值最高時,參數hidden_layer_size值為: %f" % (best_hidden_layer_size))
print ("auc均值最高時,參數alpha值為: %f" % (best_alpha))
print ("此時auc平均值為: %f" % (best_auc_avg))
print ("此時auc標準差為: %f" % (auc_std))
mlp = MLPClassifier(alpha=best_alpha,hidden_layer_sizes=best_hidden_layer_size).fit(X,y)
y_pred = clf.predict(X)
print("模型準確率為: %f" % (clf.score(X,y)))

當獲得最優參數的模型後,對模型進行保存

from sklearn.externals import joblib
joblib.dump(mlp, mlp.pkl)

6.對測試數據進行標記

載入模型,調取test.txt文件的測試數據,通過SpringBoot獲取特徵數組,將數組傳入神經網路獲取label值,然後存入applt_test_pred文件中,到此整個風控模型項目的搭建就結束了。

import re
import requests
lr = joblib.load(mlp.pkl)
f2 = open(applt_test_pred.txt, a+, encoding=utf8)
with open(test.txt, r, encoding=utf8) as f:
for i in f.readlines():
l = []
num = re.findall((d{6}), i)[0]
for rule in range(1, 8):
r = requests.post(
http://localhost:9527/v1/getRuleResult?ruleID= + str(rule) + &applyId= + str(num)).text
l.append(int(r))
label = lr.predict(l)[0]
if label == 1:
f2.write(OVERDUE+
)
else:
f2.write(NORMAL+
)
f2.flush(

推薦閱讀:

相关文章