概述
余弦相似度,又称为余弦相似性,是通过计算两个向量的夹角余弦值来评估他们的相似度。余弦相似度将向量根据坐标值,绘制到向量空间中,如最常见的二维空间。
详见 百度百科
:https://baike.baidu.com/item/%E4%BD%99%E5%BC%A6%E7%9B%B8%E4%BC%BC%E5%BA%A6/17509249?fr=aladdin
数学模型
计算公式
一般来讲最终数据越接近于
1,表示分子与分母部分的夹角越小
用途:
使用
余弦相似度
的场景一般用在判断两条数据的相似程度
上,常见使用在,风控系统中对密码验证的场景等。当相似度即最终值越接近于1
时,表示密码的相似度越高。
使用
本文将根据 密码相似度验证
简单介绍此算法的使用。
- 所谓验证密码相似度,可以转化为求
当前请求密码
中的所有字符
与历史密码
的相似度
的判定。
但是,现实往往是存在着差异性的,比如
用户的历史密码的长度都不一致
等,因此,在此场景下,我们需要引入词袋。
词袋
:词袋模型(英语:Bag-of-words model)是个在自然语言处理和信息检索(IR)下被简化的表达模型。
百度百科:https://baike.baidu.com/item/%E8%AF%8D%E8%A2%8B%E6%A8%A1%E5%9E%8B/22776998?fr=aladdin
- 使用词袋,我们对所有在密码(
包括历史密码与当前请求密码
)出现过的字符
进行提取,通过每个密码中的字符的出现次数进行建模
提取出每个密码的特征向量
。 - 最后通过比较,当前请求密码的特征向量与历史每个密码的特征向量的余弦值大小,判断相似度。
代码实现
/**① 主干--作评估
ordernessPassword ---- 请求密码
historyOrdernessPasswords ----- 历史密码集合
*/
public boolean doEval(String ordernessPassword, Set<String> historyOrdernessPasswords){
//如果历史密码没有,则证明第一次登陆,不校验
if(historyOrdernessPasswords.size()==0 || historyOrdernessPasswords==null){
return false;
}
//获取包含所有历史密码的词袋
Set<Character> wordBag = new HashSet<Character>();
//获取历史密码流
List<char[]> collect = historyOrdernessPasswords.stream().map(histroyt -> histroyt.toCharArray()).collect(Collectors.toList());
for (char[] chars : collect) {
for (int i = 0; i < chars.length; i++) {
//词袋获取所有历史的单词
wordBag.add(chars[i]);
}
}
//将当前输入的密码加入词袋
char[]