风控建模
inputvector
自定义jquery插件完成用户输入表单控件的输入行为的追踪,形成用户输入向量,将用户输入向量封装成cookie对接给后台用户登录服务
//首先这个输入向量的长度如果不够的话就没有评估的必要直接返回false
var n=historyVector.length
if(n<2){
return ("FORM_INPUT",false)
}
首先计算平均向量
//计算平均向量 得到一个double数组 这个数组的每个元素 都是一个输入的向量加起来除以个数
//比如全部的用户名输入向量加起来除以历史个数 就是用户名的平均向量
var avgVector=new Array[Double](currentInputVector.length)
for(i <- 0 until currentInputVector.length ){
avgVector(i) = historyVector.map(v=>v(i)).reduce(_+_)/historyVector.length
}
//n个历史向量间 彼此距离
var distances=new ListBuffer[Double]
for(i<- historyVector ;j <- historyVector;if(i!=j)){ //任意两个点坐标的距离
//必须保证 i!=j 计算 i和j的距离
var total:Double=0
for( item<- 0 until avgVector.length){
//Math.pow(x,y)表示x的y次方
total+= Math.pow((i(item)-j(item)),2)
}
//添加距离 开根号
distances += Math.sqrt(total)
//将向量从historyVector中移除
historyVector -= i
}
//对distances结果进行排序
distances=distances.sortBy(distance=>distance)
//计算当前输入向量和平均向量的距离
var curentDistance:Double=0
for( item<- 0 until avgVector.length){
curentDistance+= Math.pow((avgVector(item)-currentInputVector(item)),2)
}
curentDistance=Math.sqrt(curentDistance)
//获取比对阈值 这里的distance是上面的listbuffer[Double]集合 取其中大约1/3处作为阈值
var threshold: Double = distances((n * (n - 1))/6)
//最后一步如果 当前输入向量和平均向量的距离大于阈值 值输出为true 否则为false
return ("FORM_INPUT",curentDistance>threshold)
词袋模型
//第一步首先要是没有历史密码这一步就不用评估了
if(historyPasswords.size<1){
return ("PASSWORD_INPUT",false)
}
//这一步是建立词袋模型 将历史密码摊平 去重 排序 adcb3212变成 abcd123
val wordBag = historyPasswords.flatMap(password=> password.toCharArray).distinct.toList.sortBy(c=>c)
//这一步就是将abc12变成1110110 将历史的密码都和词袋模型做对比 然后得出的向量组 组成一个listBuffer
var historyPwddwordVectors=new ListBuffer[Array[Int]]
for(pwd<-historyPasswords){
val vector = convertString2Vectors(wordBag,pwd)
historyPwddwordVectors += vector
}
//当前输入的密码也转为一个当前向量
val currentVector = convertString2Vectors(wordBag,currentPawssword)
//用当前的向量去和历史向量组成的listBuffer[Array[Int]]一一去做余弦相似度 然后求最大的相似度
var simlarity:Double=0.0
for(v <- historyPwddwordVectors){
var s:Double=calculateSimlarity(currentVector,v)
println("s:"+s)
if(s>simlarity){ //获取自大相似度
simlarity=s
}
}
//最后如果这个相似度小于我们定下的阈值0.95就是true 超过了就是false
if(simlarity < 0.95){
return ("PASSWORD_INPUT",true)
}
return ("PASSWORD_INPUT",false)
余弦相似度
地理位置风险评估(瞬间位移距离)
后台使用geo-ip转换工具将ip地址转换为经纬度信息,然后在求出在地球上的距离 最后除以俩次登录的时间 求出瞬间位移距离 如果大于高铁时速代表有风险
userAgent
用@RequestHeader这个注解提取User-Agent设备信息通过前期制定的Flume+logback 将用户登录信息存储在分布式日志系统中
def doEvaluate(lastAgent: String, lastAgents: ListBuffer[String]): (String, Boolean) = {
return ("AGENT_INPUT",lastAgents.indexOf(lastAgent) == -1)
}