当前位置: 首页 > news >正文

风控中的文本相似方法之余弦定理

一、余弦相似

一、 余弦相似概述

余弦相似性通过测量两个向量的夹角的余弦值来度量它们之间的相似性。0度角的余弦值是1,而其他任何角度的余弦值都不大于1;并且其最小值是-1。

从而两个向量之间的角度的余弦值确定两个向量是否大致指向相同的方向。结果是与向量的长度无关的,仅仅与向量的指向方向相关。余弦相似度通常用于正空间,因此给出的值为-1到1之间。

例如在信息检索中,每个词项被赋予不同的维度,而一个维度由一个向量表示,其各个维度上的值对应于该词项在文档中出现的频率。余弦相似度因此可以给出两篇文档在其主题方面的相似度。另外,它通常用于文本挖掘中的文件比较,在数据挖掘领域中,会用到它来度量集群内部的凝聚力。

二、 余弦相似应用场景

原创文章检测:通过文本相似,可以检测公众号文章、论文等是否存在抄袭

垃圾邮件识别:如“诚聘淘宝兼职”、“诚聘打字员”、“文章代写”、“增值税发票”等这样的小广告满天飞,作为网站或者APP的风控,不可能简单的加几个关键字就能进行屏蔽的,一般常用的方法就是标注一部分典型的广告文本,与它相似度高的就进行屏蔽。

内容推荐系统:在腾讯新闻、微博、头条、知乎等,每一篇文章、帖子的下面都有一个推荐阅读,那就是根据一定算法计算出来的相似文章。

冗余新闻过滤:我们每天接触过量的信息,信息之间存在大量的重复,相似度可以帮我们删除这些重复内容,比如,大量相似新闻的过滤筛选。

可用于文本相似的方法非常多,比如基于字符的杰卡德相似、编辑距离相似、最长公共子串等,基于距离的相似也很多,比如汉明距离、欧几里得距离等。本文介绍的是余弦距离相似,比较简单,可以作为风控领域文本相似的入门。

废话不多说,先看一个案例,我们用三句话作为例子,我从自己的邮箱里面扒出来的垃圾邮件,具体步骤如下。

三、 计算文本余弦相似

第一步,分词。

A句子:有/发票/加/薇/45357

B句子:有/发票/加/微/45357

C句子:正规/ 增值税/ 发票

第二步,列出所有的词(所有词的长度作为向量长度)

有,发票,加,薇,微,45357,正规,增值税

第三步,计算词频

A句子:有 1,发票 1,加 1,薇 1,微 0,45357 1,正规 0,增值税 0

B句子:有 1,发票 1,加 1,薇 0,微 1,45357 1,正规 0,增值税 0

C句子:有 0,发票 1,加 0,薇 0,微 0,45357 0,正规 1,增值税 1

第四步,写出词频向量。

A句子:[1, 1, 1, 1, 0, 1, 0 ,0]

B句子:[1, 1, 1, 0, 1, 1, 0 ,0]

C句子:[0, 1, 0, 0, 0, 0, 1 ,1]

到这里,问题就变成了如何计算这两个向量的相似程度。我们可以把它们想象成空间中的两条线段,都是从原点(0, 0, ...)出发,指向不同的方向。两条线段之间形成一个夹角,如果夹角为0度,意味着方向相同、线段重合;如果夹角为90度,意味着形成直角,方向完全不相似;如果夹角为180度,意味着方向正好相反。因此,我们可以通过夹角的大小,来判断向量的相似程度。夹角越小,就代表越相似。

以二维空间为例,上图的a和b是两个向量,我们要计算它们的夹角θ。根据初中知识,余弦定理告诉我们,可以用下面的公式求得:

图片

假定a向量是[x1, y1],b向量是[x2, y2],那么可以将余弦定理改写成下面的形式:

图片

数学家已经证明,余弦的这种计算方法对n维向量也成立,假定A和B是两个n维向量,A是 [A1, A2, ..., An] ,B是 [B1, B2, ..., Bn] ,则A与B的夹角θ的余弦等于:

图片

使用这个公式,我们就可以得到,句子A与句子B的夹角的余弦。

图片

下面我们用Python代码计算看看

import numpy as npA = np.array([1, 1, 1, 1, 0, 1, 0 ,0])B = np.array([1, 1, 1, 0, 1, 1, 0 ,0])C = np.array([0, 1, 0, 0, 0, 0, 1 ,1])#定义相似计算函数def cos_simi(x,y):   num = x.dot(y.T)   denom = np.linalg.norm(x) * np.linalg.norm(y)   return num / denomcos_simi(A,B)0.7999999999999998cos_simi(A,C)0.2581988897471611cos_simi(B,C)0.2581988897471611

[有/发票/加/薇/45357]  和 [有/发票/加/微/45357] 只有一个字的差异,相似度0.80

[有/发票/加/薇/45357]  和 [正规/ 增值税/ 发票] 只有一个词相同,相似度0.2581,结果符合我们的感知。到此,我们就学会了计算两个句子的相似度

四、完整版代码

# 输入A,B两段语句,判断相似度import jieba
from collections import Counterdef preprocess_data(text):"""数据预处理函数,分词并去除停用词"""# 使用结巴分词对文本进行分词words = jieba.cut(text)# 去除停用词,这里只列举了几个示例停用词,实际应用中需要根据具体需求添加更多停用词stopwords = ['的', '了', '和', '是', '就', '而', '及', '与', '或']filtered_words = [word for word in words if word not in stopwords]return filtered_wordsdef extract_features(words):"""特征提取函数,使用词袋模型"""features = Counter(words)return str(features)def cosine_similarity(features1, features2):"""余弦相似度计算函数"""numerator = sum(features1[word] * features2[word] for word in set(features1) & set(features2))denominator = ((sum(features1[word] ** 2 for word in features1) ** 0.5) * (sum(features2[word] ** 2 for word in features2) ** 0.5))if not denominator:return 0.0else:return round(numerator / float(denominator), 3)def check_duplicate(content, input_text, threshold=0.7):"""查重函数,判断当前文本是否与已有文本重复"""# 对当前文本进行预处理和特征提取words = preprocess_data(content)features = extract_features(words)# 在此模拟已有文本的特征existing_features = extract_features(preprocess_data(input_text))similarity = cosine_similarity(eval(features), eval(existing_features))# 根据设定的相似度阈值来判断是否重复if similarity >= threshold:return similarityelse:return similaritysimilarity = check_duplicate("我是你的人","我是你的情人")
print('similarity',similarity)

二、杰卡德相似

杰卡德相似是比较常见的文本相似计算方法,文本分词后的交集比上并集,公式如下:

图片

但在风控的实际业务中,有很多场景存在大规模的重复文本片段,比如:

S1 = '模具硅胶 翻模硅胶 指纹签到手指摸 指纹假膜 模具硅胶 液态硅胶 半透明硅胶 指模自制 指纹识别硅胶 打卡指纹透明膜 指纹膜 指纹 胶膜 手机指纹打卡假膜 指纹打卡机指纹胶膜 指纹识别贴打卡 diy硅胶模具材料 指纹打卡 指纹打卡道具 指纹打卡假膜人脸 指纹识别膜 硅胶 硅胶模具diy 模型制作材料 指模 液体硅胶 考勤指纹胶 指纹打卡假膜科密 指纹打卡假膜 硅橡胶 指纹胶膜制作 打卡 翻模硅胶材料 食品级硅胶 打卡考勤指纹 指模具考勤 翻模硅胶 diy 指纹打卡膜 指纹打卡假膜 打卡机指纹识别膜 指纹制作 diy液体材料 指纹制作工具 指模具 手指打卡 手办工具 签到指纹胶膜制作 模具硅胶翻模 翻模硅胶 指纹识别胶打卡 硅胶 硅胶打卡 打卡指纹胶膜 指纹识别膜套'

S2 = '指纹打卡假膜科密 指纹签到手指摸 指纹识别膜 硅胶 指模具 手指打卡 指纹打卡膜 指纹打卡假膜人脸 打卡考勤指纹 指模具考勤 指纹打卡机指纹胶膜 指纹制作工具 指纹打卡 指纹识别套 硅胶 硅橡胶 指模 diy硅胶模具材料 指纹制作 指纹识别硅胶 指模自制 打卡指纹胶膜 指纹打卡假膜 指纹打卡道具 手机指纹打卡假膜 指纹假膜 指纹膜 指纹打卡假膜 硅橡胶 打卡机指纹识别膜 指纹识别模具 硅胶 指纹识别膜套 硅胶模具diy 打卡指纹透明膜 上班 打卡指纹透明膜 指纹识别胶打卡 硅胶 指纹识别打卡膜假手指 硅胶 考勤指纹胶 硅胶打卡 指纹胶膜制作 打卡 签到指纹胶膜制作 指纹 胶膜 指纹识别贴打卡abcdedf'

使用杰卡德相似计算相似度:0.7647,在S2中加入'abcdedf'干扰字符串后,相似度 0.6964

使用新加权算法计算相似度:0.7305   在S2中加入'abcdedf'干扰字符串后,相似度 0.7252

可见第二种算法,针对这种无序的词组计算相似度,抗干扰能力要比传统的方法强很多,能够更稳点的计算类似的多来源文本的相似性。

具体的计算逻辑如下(只计算了top20):

图片

除了上面的案例,还有下面的各种场景,都存在大量重复的文本集合,我们需要有一种专门的方法来进行计算。

两个商家店铺所有商品名称集合,一般一个店铺商品都有差不多

百度推广者的竞价词集合,基本会穷举所有相关的搜索词

... ...

淘宝商家的推广词集合

我写了个函数实现,也不知道叫啥,就是一种加权的杰卡德相似。

S1 = '模具硅胶 翻模硅胶 指纹签到手指摸 指纹假膜 模具硅胶 液态硅胶 半透明硅胶 指模自制 指纹识别硅胶 打卡指纹透明膜 指纹膜 指纹 胶膜 手机指纹打卡假膜 指纹打卡机指纹胶膜 指纹识别贴打卡 diy硅胶模具材料 指纹打卡 指纹打卡道具 指纹打卡假膜人脸 指纹识别膜 硅胶 硅胶模具diy 模型制作材料 指模 液体硅胶 考勤指纹胶 指纹打卡假膜科密 指纹打卡假膜 硅橡胶 指纹胶膜制作 打卡 翻模硅胶材料 食品级硅胶 打卡考勤指纹 指模具考勤 翻模硅胶 diy 指纹打卡膜 指纹打卡假膜 打卡机指纹识别膜 指纹制作 diy液体材料 指纹制作工具 指模具 手指打卡 手办工具 签到指纹胶膜制作 模具硅胶翻模 翻模硅胶 指纹识别胶打卡 硅胶 硅胶打卡 打卡指纹胶膜 指纹识别膜套'S2 = '指纹打卡假膜科密 指纹签到手指摸 指纹识别膜 硅胶 指模具 手指打卡 指纹打卡膜 指纹打卡假膜人脸 打卡考勤指纹 指模具考勤 指纹打卡机指纹胶膜 指纹制作工具 指纹打卡 指纹识别套 硅胶 硅橡胶 指模 diy硅胶模具材料 指纹制作 指纹识别硅胶 指模自制 打卡指纹胶膜 指纹打卡假膜 指纹打卡道具 手机指纹打卡假膜 指纹假膜 指纹膜 指纹打卡假膜 硅橡胶 打卡机指纹识别膜 指纹识别模具 硅胶 指纹识别膜套 硅胶模具diy 打卡指纹透明膜 上班 打卡指纹透明膜 指纹识别胶打卡 硅胶 指纹识别打卡膜假手指 硅胶 考勤指纹胶 硅胶打卡 指纹胶膜制作 打卡 签到指纹胶膜制作 指纹 胶膜 指纹识别贴打卡 abcdedf'
from collections import Counter
class Similarty():    def __init__(self,S1,S2,topn):self.S1 = S1self.S2 = S2self.topn = topn''' 标准杰卡德'''    def normal_jaccard(self):return len(set(self.S1)&set(self.S2))/len(set(self.S1) | set(self.S2))''' 加权杰卡德'''      def weight_jaccard(self):       if self.S1 is not None and self.S2 is not None:sim_0 = self.S1.replace(' ','')sim_1 = self.S2.replace(' ','')collect0 = Counter(dict(Counter(sim_0).most_common(self.topn)))collect1 = Counter(dict(Counter(sim_1).most_common(self.topn)))       jiao = collect0 & collect1bing = collect0 | collect1       sim = float(sum(jiao.values()))/float(sum(bing.values()))        return(sim)              else:return 0.0sim =   Similarty(S1,S2,50)#初始化         
sim.normal_jaccard()
0.6964285714285714
sim.weight_jaccard()
0.7252396166134185

我这里为了简单,仅仅分字进行的相似计算,大家也可以自然语言分词计算,也可以N-gram后计算,稳定性会进一步加强。

好了,本期内容分享到此了,希望对你有启发。

有什么需求,可以联系我。

下面是一些计算的案例

图片

图片

图片

原文链接:在此鸣谢小伍哥!!!https://mp.weixin.qq.com/s?__biz=MzA4OTAwMjY2Nw==&mid=2650188043&idx=2&sn=2fd5d3e143050092ebbee5969a153852&chksm=88238ecfbf5407d9a0a31ba2d892f87214e7225becf25ec4c209a66e4283aa2c08b990bfb73c&scene=21#wechat_redirect

相关文章:

风控中的文本相似方法之余弦定理

一、余弦相似 一、 余弦相似概述 余弦相似性通过测量两个向量的夹角的余弦值来度量它们之间的相似性。0度角的余弦值是1,而其他任何角度的余弦值都不大于1;并且其最小值是-1。 从而两个向量之间的角度的余弦值确定两个向量是否大致指向相同的方向。结…...

Spring Boot定时任务编程指南:如何创建和配置周期性任务

🍁 作者:知识浅谈,CSDN签约讲师,CSDN博客专家,华为云云享专家,阿里云专家博主 📌 擅长领域:全栈工程师、爬虫、ACM算法 🔥 微信:zsqtcyw 联系我领取学习资料 …...

Java 获取客户端 IP 地址【工具类】

Java 获取客户端 IP 地址 import javax.servlet.http.HttpServletRequest; import java.net.InetAddress;/*** 网络工具类*/ public class NetUtils {/*** 获取客户端 IP 地址** param request 请求* return {link String}*/public static String getIpAddress(HttpServletReq…...

区块链中nonce是什么,什么作用

目录 区块链中nonce是什么,什么作用 区块链中nonce是什么,什么作用 Nonce在以太坊中是一个用于确保交易顺序性和唯一性的重要参数。以下是对Nonce的详细解释: 定义 Nonce是一个scalar值,它等于从该地址发送的交易数量,或在具有关联代码的账户的情况下,由该账户创建的合…...

探索Python的多媒体解决方案:ffmpy库

文章目录 探索Python的多媒体解决方案:ffmpy库一、背景:数字化时代的多媒体处理二、ffmpy:Python与ffmpeg的桥梁三、安装ffmpy:轻松几步四、ffmpy的五项基本功能1. 转换视频格式2. 调整视频质量3. 音频转换4. 视频截图5. 视频合并…...

dmhs同步因目的端表自增列报错解决方法

dmhs同步因目的端表自增列报错解决方法 1 dmhs copy 装载数据时报错 HY000 CODE:-27232 配置源端捕获器cpt 1 dmhs copy 装载数据时报错 HY000 CODE:-2723 ERR:Only if specified in the column list and SET IDENTITY INSERT is ON, then identity column could be assigned …...

封装分发安装教程

【安装环境】 Linux伪静态 PHP7.1mysql5.6 SSL 证书 (使用宝塔) 1、在宝塔上面新建站点,把压缩包上传到根目录,解压出来,然后导入 sql 数据库文件,再 然后修改数据库配置 source\system\db_config.php 2、…...

redis从入门到进阶——数据类型、 操作、数值操作、发布订阅、消息队列、布隆过滤器、事务

文章目录 基础数据类型操作数值操作 进阶发布订阅消息队列布隆过滤器事务 基础 数据类型 string,set, hash, list, zset 操作 string符串类型: 保存一个字符串:set key value [EX seconds|PX milliseconds...] [NX|XX]EX:设置…...

剖析 Kafka 消息丢失的原因

文章目录 前言一、生产者导致的消息丢失的场景场景1:消息太大解决方案 :1、减少生产者发送消息体体积2、调整参数max.request.size 场景2:异步发送机制解决方案 :1、使用带回调函数的发送方法 场景3:网络问题和配置不当…...

阿里又出AI神器,颠覆传统图像编辑,免费开源!

文章首发于公众号:X小鹿AI副业 大家好,我是程序员X小鹿,前互联网大厂程序员,自由职业2年,也一名 AIGC 爱好者,持续分享更多前沿的「AI 工具」和「AI副业玩法」,欢迎一起交流~ 最近阿里开源了 Mi…...

git 大文本上传和下载git-lfs

1. ubuntu 1)下载脚本来自动化配置系统上的包存储库,导入签名密钥等过程。这些脚本必须在root下运行。 # apt/deb repos: curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash # curl -s https://packag…...

Ps:脚本与动作

有三种脚本语言可用于编写 Photoshop 脚本:AppleScript(macOS)、JavaScript 和 VBScript(Windows)。 Photoshop 脚本文件默认文件夹 Win:C:\Program Files\Adobe\Adobe Photoshop 2024\Presets\Scripts Mac…...

MySQL数据库回顾(1)

数据库相关概念 关系型数据库 概念: 建立在关系模型基础上,由多张相互连接的二维表组成的数据库。 特点: 1.使用表存储数据,格式统一,便于维护 2.使用SQL语言操作,标准统一,使用方便 SOL SQL通用语法 …...

文字炫酷祝福 含魔法代码

效果下图&#xff1a;&#xff08;可自定义显示内容&#xff09; 代码如下&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initi…...

docker容器中连接宿主机mysql数据库

最近要在docker中使用mysql数据库&#xff0c;首先考虑在ubuntu的镜像中安装mysql&#xff0c;这样的脚本和数据库都在容器中&#xff0c;直接访问localhost&#xff1a;3306&#xff0c;脚本很简单&#xff0c;如下&#xff1a; import pymysql# 建立数据库连接 db pymysql.…...

Leetcode 41. 缺失的第一个正数

41. 缺失的第一个正数 - 力扣&#xff08;LeetCode&#xff09; class Solution {/**2024.6.18首先把小于等于0和大于n的全部标记成n1&#xff0c;这些数据不会是答案&#xff1b;把出现的数字标记为负数&#xff0c;比如数字3&#xff0c;那就是nums[2]-nums[2];下次从头遍历…...

MyBatis 自定义映射 ResultMap:字段与属性的映射详解

在 MyBatis 框架中&#xff0c;ResultMap是一个非常强大的功能&#xff0c;它允许我们自定义SQL查询结果与Java对象之间的映射关系。特别是在数据库字段名和Java对象属性名不一致时&#xff0c;ResultMap能够帮助我们精确地映射数据。 ResultMap 的基本使用 若字段名和实体类…...

找单身狗2

找单身狗2 之前遇到类似的题目的思路&#xff1a; 首先写出这些数的二进制形式&#xff1a; 核心原理 接下来的问题是怎么把5和6分开来&#xff1f; 这里是最后一位进行比较&#xff0c;按位异或是相同为0&#xff0c;相异为1&#xff0c;最后一位从上图看出是1&#xff0c;说…...

element-ui将组件默认语言改为中文

在main.js中加入以下代码即可 // 引入 Element Plus 及其样式 import ElementPlus from element-plus import element-plus/dist/index.css// 引入中文语言包 import zhCn from element-plus/es/locale/lang/zh-cn// 使用 Element Plus 并设置语言为中文 app.use(ElementPlus,…...

SuperMap iClient3D 11i(2023) SP1 for Cesium 调整

SuperMap iClient3D 11i(2023) SP1 for Cesium 最新版本 下载地址 SuperMap技术资源中心|为您提供全面的在线技术服务 每一次版本升级,都要对代码进行修改调整,都是为了解决功能需求。当然,也为产品做了小白鼠测试,发现bug,优化功能。 由于前端开发使用的是dojo框架,类…...

51c自动驾驶~合集58

我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留&#xff0c;CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制&#xff08;CCA-Attention&#xff09;&#xff0c;…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动&#xff08;如演唱会、马拉松赛事、高考中考等&#xff09;期间&#xff0c;城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例&#xff0c;暖城商圈曾因观众集中离场导致周边…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1)&#xff1a;从基础到实战的深度解析-CSDN博客&#xff0c;但实际面试中&#xff0c;企业更关注候选人对复杂场景的应对能力&#xff08;如多设备并发扫描、低功耗与高发现率的平衡&#xff09;和前沿技术的…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命

在华东塑料包装行业面临限塑令深度调整的背景下&#xff0c;江苏艾立泰以一场跨国资源接力的创新实践&#xff0c;重新定义了绿色供应链的边界。 跨国回收网络&#xff1a;废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点&#xff0c;将海外废弃包装箱通过标准…...

算法:模拟

1.替换所有的问号 1576. 替换所有的问号 - 力扣&#xff08;LeetCode&#xff09; ​遍历字符串​&#xff1a;通过外层循环逐一检查每个字符。​遇到 ? 时处理​&#xff1a; 内层循环遍历小写字母&#xff08;a 到 z&#xff09;。对每个字母检查是否满足&#xff1a; ​与…...

【Linux】Linux 系统默认的目录及作用说明

博主介绍&#xff1a;✌全网粉丝23W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...

并发编程 - go版

1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程&#xff0c;系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...

【网络安全】开源系统getshell漏洞挖掘

审计过程&#xff1a; 在入口文件admin/index.php中&#xff1a; 用户可以通过m,c,a等参数控制加载的文件和方法&#xff0c;在app/system/entrance.php中存在重点代码&#xff1a; 当M_TYPE system并且M_MODULE include时&#xff0c;会设置常量PATH_OWN_FILE为PATH_APP.M_T…...

全面解析数据库:从基础概念到前沿应用​

在数字化时代&#xff0c;数据已成为企业和社会发展的核心资产&#xff0c;而数据库作为存储、管理和处理数据的关键工具&#xff0c;在各个领域发挥着举足轻重的作用。从电商平台的商品信息管理&#xff0c;到社交网络的用户数据存储&#xff0c;再到金融行业的交易记录处理&a…...