Go+PHP实现敏感词检测
概述
广告,敏感词检测一直以来都是让人头疼的话题,仅仅通过添加敏感词列表是解决不了问题的。今天封禁了这个词,明天又会有新的违禁词冒出来,比起愚公无穷尽的子孙更甚。
敏感词匹配这种治标不治本的方法,在一定的语义下蛮有效的,但是这个场景对高并发,访问QPS高的服务来说,不是很合适。前段时间看到垃圾邮件检测用到的贝叶斯分类算法,这种“半学习”形式的方法的准确度依赖于先验概率的准确性,而公司长期以来整理到的违禁词列表就是一个很好的源,随着贝叶斯分类的数据越来越多,分类的准确性也会越来越高,后期仅仅需要对违禁词文件进行添加即可,方便又准确。
PHP做贝叶斯分类不能很好的利用内存,针对每一个请求都会创建一个进程,各个请求相互独立,所以每个请求都会重新来一遍贝叶斯分类数据集构建,这效率可想而知,因此不打算用PHP去实现。
go语言一直以来以快著称,就用它吧。那么问题又来了,怎么让go作为PHP的后端实现这个检测服务呢。进程间的数据通常来讲有这么几种方式:
- http
- rpc
- unix domain socket
- pipe
看完了 https://blog.csdn.net/lengyuezuixue/article/details/79314987 这篇文章后,决定采用unix domain socket的形式,毕竟NGINX和php-fpm之间的通信都是这么搞起来的,效率应该还不赖。
实现
golang 后端
package mainimport ("src/github.com/ajph/nbclassifier-go""log""os""bufio""io""net""syscall""fmt""src/github.com/yanyiwu/gojieba""strings"
)const SPAM_CHECK_SOCKET_FILE = "/tmp/spamcheck.sock"// 使用go 实现简单的贝叶斯分类
func getWords(filepath string)[]string {file, err := os.Open(filepath)if err != nil {log.Fatal(err)}defer file.Close()reader := bufio.NewReader(file)ret := []string{}for {line, err := reader.ReadString('\n')if err != nil || io.EOF == err {if line == "" {break}}line = strings.Trim(line, "\n")fmt.Println("处理单词:" + line)ret = append(ret, line)}return ret
}func learn(){m := nbclassifier.New()m.NewClass("normal")normalwords := getWords("normalwords.txt")//fmt.Println(normalwords)m.Learn("normal", normalwords...)//m.Learn("normal", "a", "need")m.NewClass("forbidden")forbiddenwords := getWords("forbiddenwords.txt")//fmt.Println(forbiddenwords)m.Learn("forbidden", forbiddenwords...)//m.Learn("forbidden", " design ", "banner", " picture", " logo ", "clip art", " ad ", "clipart", "hairstyles", " drawing", " rendering", " diagram ", " poster", "изображение")m.NewClass("terror")terrorwords := getWords("terrorwords.txt")//fmt.Println(terrorwords)m.Learn("terror", terrorwords...)//m.Learn("terror", "...", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "…", "image", "pinterest", ".c", "ltd.", "vector", "quote", "video", "search", "?", "click", "psd", "ai", "print", "file", "related", "download", "submit", "view", "buy", "how", "maker", "online", " on", "by")m.SaveToFile("materiel.json")}func reloadModel() *nbclassifier.Model{model, _ := nbclassifier.LoadFromFile("materiel.json")//fmt.Println(model.Classes[0].Items[0])//fmt.Println(model.Classes[1])//fmt.Println(model.Classes[2])return model
}func match(model *nbclassifier.Model, content string) string {// 分词jieba := gojieba.NewJieba()defer jieba.Free()words := jieba.Cut(content, true)cls, unsure,_ := model.Classify(words...)fmt.Println("检测到分类为:" + cls.Id)result := "normal"if unsure == false {result = cls.Idfmt.Println(cls, unsure)}return result
}func run() {socket, _ := net.Listen("unix", SPAM_CHECK_SOCKET_FILE)defer syscall.Unlink(SPAM_CHECK_SOCKET_FILE)learn()// 训练物料model := reloadModel()for {client, _ := socket.Accept()buf := make([]byte, 1024)datalength, _ := client.Read(buf)data := buf[:datalength]fmt.Println("client msg:" + string(data))checkret := match(model, string(data))fmt.Println("check result: " + checkret)response := []byte("")if len(checkret) > 0 {response = []byte(checkret)}_,_ = client.Write(response)}
}func main() {// 开启sock,检测服务run()//fmt.Println(reloadModel())
}
php 前端
<?php$msg = "你说谎, 你放屁,你这个傻子";
$SOCKET_FILE = "/tmp/spamcheck.sock";
$socket = socket_create(AF_UNIX, SOCK_STREAM, 0);
socket_connect($socket, $SOCKET_FILE);
socket_send($socket, $msg, strlen($msg), 0);
$response = socket_read($socket, 1024);
socket_close($socket);var_dump($response);
测试
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iYTGxWu9-1572595323364)(https://upload-images.jianshu.io/upload_images/8196049-1616cc949979ad27.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]
源码
https://github.com/guoruibiao/spamcheck
总结整理
目前看起来,sock的形式还有蛮多局限性的。目前只是单机,后续可以考虑继续进行优化。先这么着吧,后面应该还要继续跟进…
Go+PHP实现敏感词检测相关推荐
- 关于java中敏感词检测的一些总结
之前项目里客户提出一个需求,需要对系统中使用文本转化成语音发送的功能进行敏感词检测,禁止用户提交有敏感词的语音.通过查询各方面资料,整理了大概几种方案: 项目启动时对载入敏感词库作为缓存(一个大map ...
- 写一个高性能的敏感词检测组件
最近写了一个高性能的敏感词检测组件[ToolGood.Words]. 一.高性能,它的效率到底有多快? 如果将正则表达式的算法效率设为1,高性能可达到正则表达式的1.5万倍. 二.选一个巧妙的算法: ...
- php访问小程序内容检测接口,关于小程序接入敏感词检测接口的坑
接入 msgSecCheck 接口47001 错误码踩坑! 这是官方文档要求,写的有些笼统,根据开发者社区提供需要进行编码后在传参,以下为 php 代码示例/** * 敏感词检测 * @param $ ...
- 免费敏感词检测API
免费敏感词检测,免费文本内容审核, 不用什么注册key,下载到本地直接运行,直接http json查询. 下载地址 https://github.com/bosnzt/wordscheck ...
- 一种基于DFA算法的敏感词检测JAVA程序片段
本文章提供一种基于DFA算法的敏感词检测JAVA程序片段,如下: 1.构造多叉树数据结构 import org.jetbrains.annotations.NotNull;/*** 多叉树* @aut ...
- 测试.net开源敏感词检测库ToolGood.Words
微信公众号"DotNet"看到介绍.net开源敏感词检测库ToolGood.Words的文章<.NET Core一款高性能敏感词检测开源库>,根据参考文献2中的测试 ...
- java 敏感词检测
在网上看到好多的敏感词检测,发现都是在推荐某某算法,但是敏感词全是利用文本去存放.在项目中不能很好的进行维护和管理(个人看法). 本文的敏感词的检测方式还是DFA算法检测,不过敏感词存放地址放入了Re ...
- 【敏感词检测】用DFA构建字典树完成敏感词检测任务
任务概述 敏感词检测是各类平台对用户发布内容(UGC)进行审核的必做任务. 对于文本内容做敏感词检测,最简单直接的方法就是规则匹配.构建一个敏感词词表,然后与文本内容进行匹配,如发现有敏感词,则提交报 ...
- 一次敏感词检测开发记录
需求 用户上传execl,前端解析excel ,解析之后,将excel的json数据,传给后端,后端通过关键字检测算法,返回你之前传的数据,并且附件敏感字.然后前端渲染数据只table.并且用户以到e ...
最新文章
- 常用的6款Java开源报表制作工具
- Focal Loss改进版 GFocal Loss
- OVS sflow(二十六)
- 已解决:Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: TLS handshaketimeout
- 鸿蒙发布官网,鸿蒙发布在即,高情商似乎也非常重要
- SAP CRM和Cloud for Customer中的Event handler(事件处理器)
- 【云速建站】后台配置邮费
- 【英语学习】【Level 08】U04 What I love L4 Take your sweet time
- 敏捷开发一千零一问系列之五:怎样让队员主动要活?
- 为增强软件供应链安全,NIST 发布《开发者软件验证最低标准指南》
- html中怎么点按钮切换图片,如何只用css实现点击按钮切换图片
- DroidDraw Android 界面设计工具使用
- IDEA中配置OpenJDK8并查看native方法源码
- 双网口设备 网关设置注意事项
- java错误代码1061_求助java大神,看下这是哪里出错了
- html倒计时面自动跳转,小代码 html 自己网页倒计时跳转
- crond和crontab详解
- ALPS语言学校(西雅图)|ALPS Language School (Seattle)
- 为什么学习Linux系统?
- 警告!来历不明的疫情邮件或许是黑客陷阱
热门文章
- 多态综合案例——电脑的USB 接口
- 2019年大学生智能车大赛室外光电组+在ROS下搭建仿真模拟环境,编程控制小车完成定位导航仿真
- MIT 18.06 +线性代数的几何意义+3Blue1Brown 笔记
- ContentSizeFitter刷新不及时
- MATLAB中cumsum函数
- Luogu5405 CTS2019氪金手游(容斥原理+树形dp)
- 狼来了,海康威视被黑客入侵,视频监控设备被境外IP地址控制
- 【她的心你伤的起吗?】
- 三位一体自荐信计算机专业,三位一体自荐信写法和范文
- python无法正常启动0xc000007b_应用程序无法正常启动(0xc000007b)。