概述

广告,敏感词检测一直以来都是让人头疼的话题,仅仅通过添加敏感词列表是解决不了问题的。今天封禁了这个词,明天又会有新的违禁词冒出来,比起愚公无穷尽的子孙更甚。

敏感词匹配这种治标不治本的方法,在一定的语义下蛮有效的,但是这个场景对高并发,访问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实现敏感词检测相关推荐

  1. 关于java中敏感词检测的一些总结

    之前项目里客户提出一个需求,需要对系统中使用文本转化成语音发送的功能进行敏感词检测,禁止用户提交有敏感词的语音.通过查询各方面资料,整理了大概几种方案: 项目启动时对载入敏感词库作为缓存(一个大map ...

  2. 写一个高性能的敏感词检测组件

    最近写了一个高性能的敏感词检测组件[ToolGood.Words]. 一.高性能,它的效率到底有多快? 如果将正则表达式的算法效率设为1,高性能可达到正则表达式的1.5万倍. 二.选一个巧妙的算法: ...

  3. php访问小程序内容检测接口,关于小程序接入敏感词检测接口的坑

    接入 msgSecCheck 接口47001 错误码踩坑! 这是官方文档要求,写的有些笼统,根据开发者社区提供需要进行编码后在传参,以下为 php 代码示例/** * 敏感词检测 * @param $ ...

  4. 免费敏感词检测API

    免费敏感词检测,免费文本内容审核, 不用什么注册key,下载到本地直接运行,直接http json查询. 下载地址 ​​https://github.com/bosnzt/wordscheck​​ ​ ...

  5. 一种基于DFA算法的敏感词检测JAVA程序片段

    本文章提供一种基于DFA算法的敏感词检测JAVA程序片段,如下: 1.构造多叉树数据结构 import org.jetbrains.annotations.NotNull;/*** 多叉树* @aut ...

  6. 测试.net开源敏感词检测库ToolGood.Words

      微信公众号"DotNet"看到介绍.net开源敏感词检测库ToolGood.Words的文章<.NET Core一款高性能敏感词检测开源库>,根据参考文献2中的测试 ...

  7. java 敏感词检测

    在网上看到好多的敏感词检测,发现都是在推荐某某算法,但是敏感词全是利用文本去存放.在项目中不能很好的进行维护和管理(个人看法). 本文的敏感词的检测方式还是DFA算法检测,不过敏感词存放地址放入了Re ...

  8. 【敏感词检测】用DFA构建字典树完成敏感词检测任务

    任务概述 敏感词检测是各类平台对用户发布内容(UGC)进行审核的必做任务. 对于文本内容做敏感词检测,最简单直接的方法就是规则匹配.构建一个敏感词词表,然后与文本内容进行匹配,如发现有敏感词,则提交报 ...

  9. 一次敏感词检测开发记录

    需求 用户上传execl,前端解析excel ,解析之后,将excel的json数据,传给后端,后端通过关键字检测算法,返回你之前传的数据,并且附件敏感字.然后前端渲染数据只table.并且用户以到e ...

最新文章

  1. 常用的6款Java开源报表制作工具
  2. Focal Loss改进版 GFocal Loss
  3. OVS sflow(二十六)
  4. 已解决:Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: TLS handshaketimeout
  5. 鸿蒙发布官网,鸿蒙发布在即,高情商似乎也非常重要
  6. SAP CRM和Cloud for Customer中的Event handler(事件处理器)
  7. 【云速建站】后台配置邮费
  8. 【英语学习】【Level 08】U04 What I love L4 Take your sweet time
  9. 敏捷开发一千零一问系列之五:怎样让队员主动要活?
  10. 为增强软件供应链安全,NIST 发布《开发者软件验证最低标准指南》
  11. html中怎么点按钮切换图片,如何只用css实现点击按钮切换图片
  12. DroidDraw Android 界面设计工具使用
  13. IDEA中配置OpenJDK8并查看native方法源码
  14. 双网口设备 网关设置注意事项
  15. java错误代码1061_求助java大神,看下这是哪里出错了
  16. html倒计时面自动跳转,小代码   html 自己网页倒计时跳转
  17. crond和crontab详解
  18. ALPS语言学校(西雅图)|ALPS Language School (Seattle)
  19. 为什么学习Linux系统?
  20. 警告!来历不明的疫情邮件或许是黑客陷阱

热门文章

  1. 多态综合案例——电脑的USB 接口
  2. 2019年大学生智能车大赛室外光电组+在ROS下搭建仿真模拟环境,编程控制小车完成定位导航仿真
  3. MIT 18.06 +线性代数的几何意义+3Blue1Brown 笔记
  4. ContentSizeFitter刷新不及时
  5. MATLAB中cumsum函数
  6. Luogu5405 CTS2019氪金手游(容斥原理+树形dp)
  7. 狼来了,海康威视被黑客入侵,视频监控设备被境外IP地址控制
  8. 【她的心你伤的起吗?】
  9. 三位一体自荐信计算机专业,三位一体自荐信写法和范文
  10. python无法正常启动0xc000007b_应用程序无法正常启动(0xc000007b)。