`
qindongliang1922
  • 浏览: 2188462 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
7265517b-f87e-3137-b62c-5c6e30e26109
证道Lucene4
浏览量:117659
097be4a0-491e-39c0-89ff-3456fadf8262
证道Hadoop
浏览量:126068
41c37529-f6d8-32e4-8563-3b42b2712a50
证道shell编程
浏览量:60013
43832365-bc15-3f5d-b3cd-c9161722a70c
ELK修真
浏览量:71398
社区版块
存档分类
最新评论

Lucene暴走之巧用内存倒排索引高效识别垃圾数据

阅读更多


识别垃圾数据,在一些大数据项目中的ETL清洗时,非常常见,比如通过关键词
(1)过滤垃圾邮件
(2)识别yellow网站
(3)筛选海量简历招聘信息
(4)智能机器人问答测试
........
各个公司的业务规则都不一样,那么识别的算法和算法也不一样,这里提供一种思路,来高效快速的根据关键词规则识别垃圾数据。

下面看下需求:

业务定义一些主关键词若干少则几百个,多则几千个上万个,例如:

公司
机车厂
化纤厂
建设局
实业集团
中心店
桑拿中心
托管中心

然后又定义一些辅助关键词若干:
原告
被告
委托代理人
当事人
申请人
上诉人


ok,关键词有了,下面看下业务规则 , 规定如下:

任意辅助关键词组合主关键词都命中的情况下,并且词组间距不大于20者,即为合法数据。

嗯,没听懂?,那么来看个例子,一段文本如下:

上诉人北京金建出租汽车有限公司因机动车x通事故责任纠纷一案


使用IK细粒度分词后可能是这样的:

上诉人|上诉|人|北京|金|建出|出租汽车|出租|汽车|有限公司|有限|有|限|公司|因|机动车|机动|车|x通事故|x通|通事|事故责任|事故|责任|纠纷|一案|


根据规则,辅助词库与主词库都命中,而且中间的词组间距不超过20的,为合法数据,
本例子中:
辅助关键词:上诉人
    主关键词:  公司
都出现,中间词组是12个,所以符合业务规则,即为合法数据,

假设,改变原来的文本的公司为集团,再次测试:

上诉人北京金建出租汽车有限集团因机动车x通事故责任纠纷一案

使用IK细粒度分词后可能是这样的:
上诉人|上诉|人|北京|金|建出|出租汽车|出租|汽车|有限集团|有限|有|限|集团|因|机动车|机动|车|x通事故|x通|通事|事故责任|事故|责任|纠纷|一案|


这次因为辅助关键词库命中了,但是主关键词库没有命中,所以会被当成垃圾数据。

上面是帮助理解业务的一个例子,下面再分析下,性能问题,假设主关键词有500个,辅助关键词有10个,那么任意
两两组合的可能就是500*10=5000个规则条件,也就是意味着需要最坏情况下,需要匹配5000次才能识别一篇垃圾数据,当然如果你参与识别垃圾的文本不是一个字段,而是二个字段,一个是标题,一个是内容,那么最后真正的匹配次数是5000*2=10000词匹配,如果再加上距离条件,那么查询的复杂度将会大幅度增加,这个时候,如果我们使用正则匹配
效率可想而知,使用正则每次全文扫描定位,耗时非常之慢,这时候我们假设有一种快捷的hash算法,来提升性能,毫无疑问,类似的倒排索引将会是解决这种问题的神器。

因为只需要构建一次临时索引,不落地磁盘,不与IO打交道,仅仅在内存和cpu之间参与计算匹配,而且规则方式非常灵活,可以有更多的规则制定进来,特别是关键词匹配这块,lucene索引非常完美的解决了这个问题。当然如此这种计算,非常耗CPU,对内存的占用不是非常高,因为一条数据,处理完之后,他占用的资源,会被释放。

在线情况下:平均几十毫秒左右就能识别一条数据,已经接近实时了

离线情况下:在集成到hadoop或者Spark这种分布式的集群里面,也是非常给力的,因为通常情况下spark和hadoop比较耗IO和磁盘而加入这种运算将会大大提升集群的资源使用效率。

本项目只是给出了一个根据关键词识别的例子,这个项目拿到你们本地也许并不能立刻使用,但是相似的业务,但是它提供了一种思路,大部分情况下,改动少许代码,即可适应大部分类似的业务。
核心代码如下:


package com.anytrust.algo;

import com.anytrust.model.MonitorType;
import com.anytrust.tools.DictTools;
import org.apache.lucene.index.memory.MemoryIndex;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.BooleanQuery;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.wltea.analyzer.lucene.IKAnalyzer;

/**
 * Created by qindongliang on 2016/1/7.
 * 根据规则识别是否为垃圾数据
 */
public class CheckOneAlgo {

    //IK中文分词器
      IKAnalyzer analyzer=new IKAnalyzer(false);
    //内存索引处理
      MemoryIndex index = new MemoryIndex();

    static {
        //设置Lucene的boolean query条件数最大支持个数
        BooleanQuery.setMaxClauseCount(10000);
    }



    static Logger logger= LoggerFactory.getLogger(CheckOneAlgo.class);


    /**构建查询query
     * @param type  根据类型构建
     * */
    private   String buildQuery(MonitorType type){

        StringBuffer sb =new StringBuffer("(");
        for(String kw: DictTools.main_kws){//遍历主词库
            switch (type) {
                case LITIGATION://代表文书  0105
                    for (String hkw : DictTools.assist_kws) { //遍历辅助词库
                        sb.append("tc:\"").append(hkw + kw).append("\"~20  ");
                    }
                    break;
                case ANNOUNCEMENT://公告 0104
                    sb.append("tc:\"").append(kw).append("\"  ");
                    break;
                default:
                    logger.error("未知类型:{}",type);
                    break;

            }
        }
        sb.append(" ) ");
        return  sb.toString();
    }



    /***
     *  对一段文本执行垃圾数据识别功能
     *  返回true说明是有效数据
     *  返回false说明是垃圾数据
      * @param text 监测的文本
     * @return
     */
  public   boolean checkDoc(String text,MonitorType type){
        String query=buildQuery(type);
        QueryParser parser = new QueryParser("", analyzer);
        index.addField("tc", text, analyzer);
      try {
          float score = index.search(parser.parse(query));
          if(score > 0.0f){
            return true;//正确数据
          }else{
            return false;//垃圾数据
          }

      }catch (Exception e){
          logger.error("识别垃圾数据异常!",e);
      }finally {
          index.reset();//重置index引擎,服复用类对象
      }
      return false;
  }







}


有些关键词在Iteye博客会屏蔽,建议直接到github看:
Github地址:https://github.com/qindongliang/lucene-garbage-check


有什么问题 可以扫码关注微信公众号:我是攻城师(woshigcs),在后台留言咨询。
本公众号的内容是有关搜索和大数据技术和互联网等方面内容的分享,也是一个温馨的技术互动交流的小家园





分享到:
评论

相关推荐

    倒排索引java实现

    倒排索引是一种高效的数据结构,常用于全文搜索引擎中,以快速定位文档中包含特定关键词的位置。在Java中实现倒排索引,可以利用标准库或者其他第三方库,如Apache Lucene,但这里我们主要讨论基于自定义代码的实现...

    Hadoop倒排索引程序

    本程序“Hadoop倒排索引程序”巧妙地结合了Hadoop的并行处理能力,实现了在大规模数据集上的高效倒排索引构建,尤其在处理莎士比亚文集这样的大量文本数据时,表现出了卓越的性能。 首先,我们来理解一下什么是倒排...

    lucene检索文档、检索大数据量数据

    倒排索引是Lucene实现高效搜索的基础。在倒排索引中,每个唯一的词项(token)都会指向包含该词项的文档列表,而不是像正排索引那样,每个文档指向其包含的所有词项。当用户输入查询时,Lucene会分解查询语句成词项...

    深入 Lucene 索引机制

    这些Term对象会存储在一个倒排索引(Inverted Index)中,这是Lucene的核心数据结构。 3. 倒排索引构建:倒排索引将词项与包含该词项的文档列表关联起来。对于每个Term,Lucene会创建一个Posting List,记录每个...

    基于lucene技术的增量索引

    Lucene首先需要理解的是它的核心概念,包括文档(Document)、字段(Field)、术语(Term)和倒排索引(Inverted Index)。每个文档由多个字段组成,字段内包含文本内容。Lucene通过分析这些文本,将其拆分为术语,...

    Lucene之删除索引

    Lucene的索引删除过程并不像传统的文件系统删除那么简单,它涉及到对倒排索引结构的修改。 1. **删除文档**:在Lucene中,删除操作并不是真正地从磁盘上移除文档,而是通过添加一个删除标记到索引中。当你调用`...

    Lucene 倒排原理.docx

    本篇将通过Lucene这一知名的开源全文检索库,来深入探讨搜索引擎是如何利用倒排索引原理实现高效查询的。 #### 二、倒排索引的基本概念 倒排索引是一种数据结构,它将文档中的词汇与包含这些词汇的文档列表相对应。...

    JAVA倒排索引及JSP网页显示

    在信息技术领域,搜索引擎是数据检索的重要工具,而倒排索引是其核心技术之一。本项目专注于使用JAVA实现基于Lucene的倒排索引,并通过JSP(JavaServer Pages)技术进行网页展示,为用户提供了便捷的信息查询体验。 ...

    lucene索引结构原理

    首先,我们要知道Lucene的索引并非数据库中的那种可以立即定位数据的索引,而是用于快速查找文档中包含特定单词的索引。这个过程分为以下几个关键步骤: 1. **分词(Tokenization)**:Lucene使用Analyzer进行文本...

    Lucene索引和查询

    这些词项构成了倒排索引(Inverted Index),这是一种数据结构,它允许我们快速找到包含特定词项的所有文档。具体步骤包括: - 分词(Tokenization):通过分词器(Tokenizer)将文本切分成词项。 - 词项处理(Term...

    lucene 索引 查看 工具

    1. **Lucene 索引**:Lucene 的索引是一种倒排索引,它将文档中的词项(tokens)映射到包含这些词项的文档列表。这种数据结构使得搜索过程高效,能够在大量文档中快速找到包含特定关键词的文档。 2. **Luke 工具**...

    lucene 索引小示例

    倒排索引是一种数据结构,它将每个关键词与包含该关键词的文档位置相关联,使得我们可以迅速找到包含特定词汇的文档。 接下来,我们来看一个小示例的实现步骤: 1. **初始化**: 首先,需要引入Lucene的依赖库。在...

    lucene并行索引

    Lucene的核心是基于倒排索引(Inverted Index)的数据结构,这种结构非常适合于文档检索。倒排索引的基本思想是为每个文档中的每个词建立索引,并记录该词出现在哪些文档中及其位置信息。 - **倒排索引**:对于每个...

    lucene索引查看工具及源码

    - **倒排索引结构**:分析 Luke 如何遍历和展示倒排索引,包括 postings 数据和 term frequencies。 总的来说,Luke 不仅是一个实用的 Lucene 索引查看工具,还是学习 Lucene 内部原理的宝贵资料。通过研究 Luke 的...

    lucene索引优化多线程多目录创建索引

    倒排索引是一种数据结构,它允许快速查找包含特定词项的所有文档。这种高效的数据结构是Lucene快速搜索的基础。 当我们面临大量数据需要索引时,单线程处理可能会成为性能瓶颈。因此,引入多线程可以显著提升索引...

    lucene 对 xml建立索引

    ### Lucene对XML文档建立索引的技术解析与实践 #### 一、引言 随着互联网技术的迅猛发展,非结构化数据(如...在未来的发展中,随着数据量的不断增加和技术的进步,Lucene对XML文档的索引建立将会更加高效和智能化。

    luke8用于查看lucene保存的索引库数据和文档数据

    这一过程包括分词、建立倒排索引、存储字段值等步骤。Lucene支持多种高级特性,如模糊搜索、短语搜索、评分机制等,使得搜索体验更加智能化。 **2. luke8的用途** luke8是Lucene的官方可视化工具,主要功能有: -...

Global site tag (gtag.js) - Google Analytics