`
orange.lpai
  • 浏览: 89465 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Lingpipe中的spell模块-拼写纠错

阅读更多
基本模型
基本技术工作如下:搜索引擎提供可使用的稳定被用来索引和被训练成为一种语言模型。这种语言模型存储的是短语和短语统计的特征信息。当提交一个查询时,
类src/QuerySpellCheck.java 在模型中寻找与之匹配的字符编辑操作,诸如字符截取,插入,替换,转换和删除等等,这样使查询更好的适用于语言模型。如果
你提交一个查询"Gretski",模型中的数据来源为rec.sport.hockey,这个模型将会把'Gretzky' 推荐出来。

领域相关性
基于字典的拼写校正方案的最大优势是校正结果依赖于搜索索引数据。因此查询词"trt"在法律领域别校正为"tort",在厨餐领域被校正为"tart",在生物信息学
领域被校正为"TRt"。但是在Goole中,没有被纠正的推荐词,因为web域名"trt.com"分别是Thessaly Radio Television 和 Turkiye Radyo Televizyon的缩略形式。

上下文相关校正
Yahoo和Google采用的是上下文相关的校正。例如,查询"frod"(来自于德语的老英文单词,意思是智慧的、有经验的)被建议校正为"ford"(一家汽车公司);然而
查询词"frod baggins"被纠正为"frodo baggins"(一个20世纪编造的虚词)。以上是雅虎的校正结果。Google并不校正"frod baggins",页面返回有大约785条结果
满足它,而有820000条结果满足"frodo baggins"。而且Google也不校正"frdo and frdo baggins"。Amazon表现相似,但Bing纠正frd baggins为ford baggins比
frodo baggins要多。
Lingpipe的模型精确的支持这种上下文相关校正

运行的例子
下载并安装Lingpipe.然后修改路径如下:
> cd LING_PIPE/demos/tutorial/querySpellCheck



使用ant命令
ant querySpelcheck



运行程序在windows上
java
-cp "../../../lingpipe-4.0.0.jar;
     ../../lib/lucene-core-2.3.0.jar;
     querySpellCheck.jar"
QuerySpellCheck



下面的会话,用户输入的是斜体
PHASE I: TRAINING
     CONFIGURATION:
     Model File: SpellCheck.model
     N-gram Length: 5
     File=..\..\data\rec.sport.hockey\train/52550
     File=..\..\data\rec.sport.hockey\train/52551
...
     File=..\..\data\rec.sport.hockey\train/55022
Writing model to file=SpellCheck.model
Writing lucene index to =lucene
Reading model from file=SpellCheck.model

PHASE II: CORRECTION
     Constructing Spell Checker from File

Enter query <RETURN>.
     Use just <RETURN>b to exit.

>Wayn Gretsky
Found 0 document(s) that matched query 'Wayn Gretsky':
Found 43 document(s) matching best alt='Wayne Gretzky':

>Wayne Gretzky
Found 43 document(s) that matched query 'Wayne Gretzky':
 No spelling correction found.

>Stanley Cub Plaoofs
Found 90 document(s) that matched query 'Stanley Cub Plaoofs':
Found 208 document(s) matching best alt='Stanley Cup Playoffs':

>StanleyCup
Found 0 document(s) that matched query 'StanleyCup':
Found 143 document(s) matching best alt='Stanley Cup':

>Stan ley Cup
Found 132 document(s) that matched query 'Stan ley Cup':
Found 143 document(s) matching best alt='Stanley Cup':

>
     Detected empty line.
     Ending test.



通过拼写校正后我们发现查询索引文档,返回的文档数量增长的比较显著。尽管纠正的结果不是所有的都正确,但对一些模糊查询往往能得到比较好的结果。
lingpipe的拼写纠错模型与许多其他普通的拼写纠错模型的不同之处在于,它能对查询词进行分词,如查询"Stanleycup"时一个几个单词兼并的词,能被纠正为
"Stan ley Cup".

训练数据采用5-grams;编辑距离字符操作数限制在8到10;训练数据中校正需要250到1000倍左右的次的编辑

开始集成到搜索引擎中
类QuerySpellCheck.java 集成的拼写模块以及lucene搜索引擎
基本数据流:
1.搭建语言模型,拼写纠错模块和Lucene类
2.集成语言模型和Lucene索引
3.命令行上输入查询

搭建Spell Checker
需要几个相关类组合。首先我们需要TrainSpellChecker对象训练搜索引擎索引中的数据。这一部如下代码
FixedWeightEditDistance fixedEdit =
    new FixedWeightEditDistance(MATCH_WEIGHT,
                                DELETE_WEIGHT,
                                INSERT_WEIGHT,
                                SUBSTITUTE_WEIGHT,
                                TRANSPOSE_WEIGHT);

NGramProcessLM lm = new NGramProcessLM(NGRAM_LENGTH);
TokenizerFactory tokenizerFactory
    = new IndoEuropeanTokenizerFactory();
TrainSpellChecker sc
    = new TrainSpellChecker(lm,fixedEdit,
                            tokenizerFactory);



工作流自顶向下,通过创建FixedWeightEditDistance对象,它能设置像删除,插入等操作的权重。合理的值已经设置在demo中了,它只能在某种特定数据集中
的纠错效果较好。
下一步就是要创建NGramProcessLM ,搭建字符级别的语言模型在我们的demo中。这时我们需要知道数据集中所有的字符数量。越小的数据量。再者,你能评估
查询和查询纠正的质量
另外我们需要TokenizerFactory对象帮助查询的编辑,这个tokenizer和Lucene中的tokenizer是完全匹配的 ,即是org.apache.lucene.analysis.Analyzer接口
的实现,看下文
上面的对象在类TrainSpellChecker 中聚集到一起,做分词相关的训练

搭建Lucene搜素引擎
Lucene中的类IndexWriter确定了数据写索引的路径,数据分词器,以及新索引是否创建的布尔标志位等等。
static final File LUCENE_INDEX_DIR = new File("lucene");
    static final StandardAnalyzer ANALYZER = new StandardAnalyzer(Version.LUCENE_30);
    static final String TEXT_FIELD = "text";
...
        FSDirectory fsDir 
            = new SimpleFSDirectory(LUCENE_INDEX_DIR,
                                    new NativeFSLockFactory());
        IndexWriter luceneIndexWriter 
            = new IndexWriter(fsDir,
                              ANALYZER,
                              IndexWriter.MaxFieldLength.LIMITED);


...
例子中使用的是Lucene的StandardAnalyzer,它提供了一些标准的Filtersh和大小写转换

文档索引和训练拼写纠错模块
增加 的数据时非常简单,所有的数据需要分别进行语言模型的训练和索引过程
String[] filesToIndex = DATA.list();
for (int i = 0; i < filesToIndex.length; ++i) {
    System.out.println("     File="
                       + DATA + "/"
                       +filesToIndex[i]);
    File file = new File(DATA,filesToIndex[i]);
    String charSequence
        = Files.readFromFile(file);
    sc.handle(charSequence);
    Document luceneDoc = new Document();
    Field textField
        = new Field(TEXT_FIELD,charSequence,
                    Field.Store.YES,Field.Index.TOKENIZED);
    luceneDoc.add(textField);
    luceneIndexWriter.addDocument(luceneDoc);
}

System.out.println("Writing model to file="
                   + MODEL_FILE);
writeModel(sc,MODEL_FILE);

System.out.println("Writing lucene index to ="
                   + LUCENE_INDEX_DIR);
luceneIndexWriter.close();




一旦我们将文件转换为字符串,训练语言模型为代码sc.handle(charSequence)。训练后的数据加入到Lucene需要一些复杂过程,因为这些结构化的数据以一种
复杂的方式来支持所有的搜索引擎特征的。于是我们创建新的文本对象,添加数据导域名中(查询时需要的field名),然后添加文档到索引中。

下面我们简要阐述下spell checker序列化过程以及Lucne索引写到磁盘上,Lucene关闭和写索引以代码行luceneIndexWriter.close()为准

private static void writeModel(TrainSpellChecker sc,
                               File modelFile)
    throws IOException {

    FileOutputStream fileOut
        = new FileOutputStream(modelFile);
    BufferedOutputStream bufOut
        = new BufferedOutputStream(fileOut);
    ObjectOutputStream objOut
        = new ObjectOutputStream(bufOut);

    // write the spell checker to the file
    sc.compileTo(objOut);

    Streams.closeOutputStream(objOut);
    Streams.closeOutputStream(bufOut);
    Streams.closeOutputStream(fileOut);
}



从磁盘上读数据
一旦模型和索引写到磁盘上,我们能读它们,然后纠正查询。这种读模型方法显示了如何兼并相关的Java I/O 序列化连载类。我们通过请求产生纠错结果的
CompiledSpellChecker从而改变类。主要原因是编译的语言模型要比未编译版本快得多


// read compiled model from model file
System.out.println("Reading model from file="
                   + MODEL_FILE);
CompiledSpellChecker compiledSC
    = readModel(MODEL_FILE);
IndexSearcher luceneIndex
    = new IndexSearcher(fsDir);

System.out.print(TEST_INTRO);
testModelLoop(compiledSC,luceneIndex);


下载Lucene相似度改变了IndexSearcher的核心类,我们开始纠正查询了。上面最后一一行代码就是命令行的插查询纠错循环。

查询纠错循环

一个搜索引擎的基本部署需要比我们demo更多的功能,比如检索文档的排序。但是下面我们要尽量得到更好的拼写纠错模块,比想象中的部署要全面,
这个方法是一个无限循环命令行代码。流程是得到查询,流程是输入一个查询,运行Lucene并得到结果。
static void testModelLoop(SpellChecker sc,
                          IndexSearcher luceneIndex)
        throws IOException, ParseException {

    InputStreamReader isReader
        = new InputStreamReader(System.in);
    BufferedReader bufReader
        = new BufferedReader(isReader);

    QueryParser queryParser 
        = new QueryParser(Version.LUCENE_30,
                          TEXT_FIELD,
                          ANALYZER);

    while (true) {
        // collect query or end if null
        System.out.print(">");
        System.out.flush();
        String queryString = bufReader.readLine();
        if (queryString == null || queryString.length() == 0)
            break;

        Query query = queryParser.parse(queryString);
        TopDocs results = searcher.search(query,MAX_HITS);
        System.out.println("Found "
            + results.totalHits
            + " document(s) that matched query '"
            + query + "':");

        // compute alternative spelling
        String bestAlternative = sc.didYouMean(queryString);

        Query alternativeQuery
            = queryParser.parse(bestAlternative);
        TopDocs results2
            = luceneIndex.search(alternativeQuery,MAX_HITS);

        System.out.println("Found " + results2.totalHits
            + " document(s) matched best alternate '"
            + bestAlternative + "':");
    }
}



查阅更多相关代码,处理搞乱I/O和输入空查询时而破坏循环。首先我们使用Lucnene中的QueryParser产生查询。这样携带参数并保护查询串,然后Lucene索引的域被检索
(TEXT_FIELD),然后Analyzer对查询进行分词处理(UCENE_TOKENIZER),同样的采用相同的分词器对索引数据进行处理。

下一步我们收集匹配查询的文档Hits hits = luceneIndex.search(origQuery)。我们需要从Lucene中获取文档数量,以及Hits类提供的方法即及时每个文档与查询的相似度得分。

最后我们得到拼写纠错结果代码 String bestAlternative = sc.didYouMean(query);它采用了语言模型,我们通过有关查询的文本中的简单编辑距离发现更好的匹配。
如果纠错结果中没有更高得分的查询,那边系统就返回原始查询串

协调和部署
部署好的查询纠错模块需要比这个Demo系统更加完善,比如系统需要能兼容各种版本。协调模型有点复杂,另外模型训练数据量大小也是个问题。通常理想情况下,你需要
查询纠错系统评测集,结果好坏来自于实际不同使用者,你可以选择合适参数来协调系统。
分享到:
评论

相关推荐

    起点小说解锁.js

    起点小说解锁.js

    299-煤炭大数据智能分析解决方案.pptx

    299-煤炭大数据智能分析解决方案.pptx

    299-教育行业信息化与数据平台建设分享.pptx

    299-教育行业信息化与数据平台建设分享.pptx

    基于Springboot+Vue酒店客房入住管理系统-毕业源码案例设计.zip

    网络技术和计算机技术发展至今,已经拥有了深厚的理论基础,并在现实中进行了充分运用,尤其是基于计算机运行的软件更是受到各界的关注。加上现在人们已经步入信息时代,所以对于信息的宣传和管理就很关键。系统化是必要的,设计网上系统不仅会节约人力和管理成本,还会安全保存庞大的数据量,对于信息的维护和检索也不需要花费很多时间,非常的便利。 网上系统是在MySQL中建立数据表保存信息,运用SpringBoot框架和Java语言编写。并按照软件设计开发流程进行设计实现。系统具备友好性且功能完善。 网上系统在让售信息规范化的同时,也能及时通过数据输入的有效性规则检测出错误数据,让数据的录入达到准确性的目的,进而提升数据的可靠性,让系统数据的错误率降至最低。 关键词:vue;MySQL;SpringBoot框架 【引流】 Java、Python、Node.js、Spring Boot、Django、Express、MySQL、PostgreSQL、MongoDB、React、Angular、Vue、Bootstrap、Material-UI、Redis、Docker、Kubernetes

    时间复杂度的一些相关资源

    时间复杂度是计算机科学中用来评估算法效率的一个重要指标。它表示了算法执行时间随输入数据规模增长而变化的趋势。当我们比较不同算法的时间复杂度时,实际上是在比较它们在不同输入规模下的执行效率。 时间复杂度通常用大O符号来表示,它描述了算法执行时间上限的增长率。例如,O(n)表示算法执行时间与输入数据规模n呈线性关系,而O(n^2)则表示算法执行时间与n的平方成正比。当n增大时,O(n^2)算法的执行时间会比O(n)算法增长得更快。 在比较时间复杂度时,我们主要关注复杂度的增长趋势,而不是具体的执行时间。这是因为不同计算机硬件、操作系统和编译器等因素都会影响算法的实际执行时间,而时间复杂度则提供了一个与具体实现无关的评估标准。 一般来说,时间复杂度越低,算法的执行效率就越高。因此,在设计和选择算法时,我们通常希望找到时间复杂度尽可能低的方案。例如,在排序算法中,冒泡排序的时间复杂度为O(n^2),而快速排序的时间复杂度在平均情况下为O(nlogn),因此在处理大规模数据时,快速排序通常比冒泡排序更高效。 总之,时间复杂度是评估算法效率的重要工具,它帮助我们了解算法在不同输入规模下的性

    安全承诺书-施工(单位版).docx

    5G通信行业、网络优化、通信工程建设资料

    基于Springboot+Vue人口老龄化社区服务与管理平台-毕业源码案例设计.zip

    网络技术和计算机技术发展至今,已经拥有了深厚的理论基础,并在现实中进行了充分运用,尤其是基于计算机运行的软件更是受到各界的关注。加上现在人们已经步入信息时代,所以对于信息的宣传和管理就很关键。系统化是必要的,设计网上系统不仅会节约人力和管理成本,还会安全保存庞大的数据量,对于信息的维护和检索也不需要花费很多时间,非常的便利。 网上系统是在MySQL中建立数据表保存信息,运用SpringBoot框架和Java语言编写。并按照软件设计开发流程进行设计实现。系统具备友好性且功能完善。 网上系统在让售信息规范化的同时,也能及时通过数据输入的有效性规则检测出错误数据,让数据的录入达到准确性的目的,进而提升数据的可靠性,让系统数据的错误率降至最低。 关键词:vue;MySQL;SpringBoot框架 【引流】 Java、Python、Node.js、Spring Boot、Django、Express、MySQL、PostgreSQL、MongoDB、React、Angular、Vue、Bootstrap、Material-UI、Redis、Docker、Kubernetes

    node-v12.22.6-sunos-x64.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    通信工程施工作业现场高危险源控制图集.docx

    5G通信行业、网络优化、通信工程建设资料

    毕设绝技《基于小程序的交友系统的设计与实现》

    《基于小程序的交友系统的设计与实现》是一个融合了小程序技术和社交功能的毕业设计项目。该项目旨在通过开发一款小程序,为用户提供一个便捷、有趣的交友平台,满足用户寻找新朋友、拓展社交圈的需求。 一、项目背景与目标 随着移动互联网的普及,小程序以其轻便、易用的特性受到了广大用户的喜爱。本项目旨在利用小程序技术开发一款交友系统,通过简洁明了的界面设计和丰富多样的社交功能,吸引用户参与并提升用户体验。通过实现这一系统,旨在帮助用户拓展社交圈,增进人际关系,并推动社交领域的创新与发展。 二、系统设计与功能实现 用户注册与登录:系统提供用户注册与登录功能,确保用户信息的真实性和安全性。用户可以通过手机号或第三方社交账号进行注册和登录。 个人资料展示:用户可以在个人资料页面展示自己的基本信息、兴趣爱好、照片等,以便其他用户了解并产生互动。 附近的人:系统通过定位功能展示附近的其他用户,用户可以浏览附近的人的信息,并主动发起聊天或交友请求。 聊天功能:系统提供一对一的聊天功能,用户可以与感兴趣的人进行实时交流,增进彼此的了解。 活动组织:用户可以发起或参与各类线下活动,如聚会、运动、旅行

    安全生产教育培训制度.doc

    5G通信行业、网络优化、通信工程建设资料

    shampoo-sales.csv

    shampoo-sales.csv

    59-《煤矿测量规程(1989版)》150.pdf

    59-《煤矿测量规程(1989版)》150.pdf

    node-v12.18.1-sunos-x64.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    node-v12.22.3-sunos-x64.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    项目代维费报价书.doc

    5G通信行业、网络优化、通信工程建设资料。

    AXIS T864 系列多通道 PoE+ 同轴电缆刀片套件 AXIS T8648 PoE+ 同轴电缆刀片紧凑型套件安装指南

    AXIS T864 系列多通道 AXIS T8646 PoE+ 同轴电缆刀片套件 AXIS T8648 PoE+ 同轴电缆刀片紧凑型套件安装指南

    MATLAB学习个人笔记总结.7z

    MATLAB学习个人笔记总结.7z

    课设&大作业-毕业设计基于SSM的毕业设计论文题目审核及选题管理系统.zip

    【资源说明】【毕业设计】 1、该资源内项目代码都是经过测试运行成功,功能正常的情况下才上传的,请放心下载使用。 2、适用人群:主要针对计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、数学、电子信息等)的同学或企业员工下载使用,具有较高的学习借鉴价值。 3、不仅适合小白学习实战练习,也可作为大作业、课程设计、毕设项目、初期项目立项演示等,欢迎下载,互相学习,共同进步!

    驻地网施工组织设计方案.doc

    5G通信、网络优化与通信建设

Global site tag (gtag.js) - Google Analytics