1. 概述

自然语言处理(NLP)是人工智能(AI)的一个分支,它让计算机能够像人类一样理解书面或口头语言。在当前AI革命时代,NLP有着广泛的应用场景。

本教程将探索Java中不同的NLP库,并演示如何使用Apache OpenNLP和Stanford CoreNLP实现一些NLP任务。

2. 什么是NLP?

NLP赋予计算机以类似人类的方式处理文本和单词的能力。它结合了计算语言学、统计学、深度学习和机器学习技术。

人类每天通过各种媒介在线互动,分享文本、语音、图像等不同类型的数据。这些数据对于理解人类行为和习惯至关重要,因此被用来训练计算机模拟人类智能。

NLP利用数据训练机器模拟人类语言行为,其处理流程包含以下关键步骤:

  1. 将文本分割成更小的单元(如句子或单词)
  2. 对文本进行分词(为每个单词分配唯一标识符)
  3. 移除停用词(如"the"、"a"、"and"等无实际意义的常见词)
  4. 进行词干提取或词形还原(将单词还原为词根或词典形式)
  5. 为每个单词标注词性
  6. 为每个单词标注命名实体(如人名、地名、组织机构名等)

3. NLP的应用场景

NLP是众多现代实际应用中机器智能的核心驱动力:

机器翻译:如Google Translate等系统,其核心技术基于NLP算法
垃圾邮件检测:主流邮箱服务商通过NLP文本分类技术识别垃圾邮件
AI聊天机器人:如Siri、Google Assistant、Alexa等,使用语音识别和自然语言处理理解语音模式并作出响应

这些应用的核心逻辑都依赖NLP技术,因为它使计算机能够处理自然语言输入输出(如文本和语音),并理解其中的含义和意图。

4. OpenNLP

Apache OpenNLP是一个利用机器学习处理自然语言文本的工具包。它支持分词、分割、词性标注等常见NLP任务。

OpenNLP的主要目标是提供NLP任务支持,并为多种语言提供大量预训练模型,同时提供命令行界面(CLI)方便实验和训练。

Apache OpenNLP官网提供多种预训练模型下载。下面我们使用预训练模型实现一个简单的语言检测器。首先在pom.xml中添加依赖:

<dependency>
    <groupId>org.apache.opennlp</groupId>
    <artifactId>opennlp-tools</artifactId>
    <version>2.1.1</version>
</dependency>

然后使用langdetect-183.bin预训练模型实现语言检测:

@Test
void givenTextInEnglish_whenDetectLanguage_thenReturnsEnglishLanguageCode() {
        
    String text = "the dream my father told me";
    LanguageDetectorModel model;
    
    try (InputStream modelIn = new FileInputStream("langdetect-183.bin")) {
        model = new LanguageDetectorModel(modelIn);
    } catch (IOException e) {
        return;
    }
    
    LanguageDetectorME detector = new LanguageDetectorME(model);
    Language language = detector.predictLanguage(text);
    assertEquals("eng", language.getLang());
}

这个示例中,我们将OpenNLP的语言检测模型放在项目根目录,然后加载模型并创建LanguageDetectorME实例进行语言检测,最后验证返回的语言代码是否符合预期。

5. Stanford NLP

Stanford NLP团队开发了多种算法,帮助机器处理、生成和理解人类文本和语言。

CoreNLP是Stanford NLP团队用Java编写的一套程序,可执行分词、词性标注、词形还原等多种NLP任务,支持命令行、Java代码或服务器调用三种使用方式。

下面演示使用Stanford CoreNLP进行分词。首先在pom.xml中添加依赖:

<dependency>
    <groupId>edu.stanford.nlp</groupId>
    <artifactId>stanford-corenlp</artifactId>
    <version>4.5.3</version>
</dependency>

然后实现分词功能:

@Test
void givenSampleText_whenTokenize_thenExpectedTokensReturned() {
    Properties props = new Properties();
    props.setProperty("annotators", "tokenize");
    StanfordCoreNLP pipeline = new StanfordCoreNLP(props);
        
    String text = "The german shepard display an act of kindness";
    Annotation document = new Annotation(text);
    pipeline.annotate(document);
        
    List<CoreMap> sentences = document.get(CoreAnnotations.SentencesAnnotation.class);
    StringBuilder tokens = new StringBuilder();
    
    for (CoreMap sentence : sentences) {
        for (CoreLabel token : sentence.get(CoreAnnotations.TokensAnnotation.class)) {
            String word = token.get(CoreAnnotations.TextAnnotation.class);
            tokens.append(word).append(" ");
        }
    }
    assertEquals("The german shepard display an act of kindness", tokens.toString().trim());
}

这个示例中,我们配置了StanfordCoreNLP对象使用分词注解器,创建Annotation实例后,通过处理流程从示例句子中提取出单词序列。

6. CogComp NLP

CogComp NLP是由认知计算小组开发的自然语言处理库集合,提供分词、词形还原、词性标注等NLP任务的工具和模块。

CogComp NLP可作为命令行工具或Java API使用。其中cogcomp-nlp-pipeline模块可对给定文本执行基础NLP任务,但仅支持英文纯文本。另一个similarity模块则用于计算文本或对象间的相似度并返回评分。

7. GATE

文本工程通用架构(GATE)是一个能解决文本分析和语言处理问题的工具包。它是开发人类语言处理软件组件的优秀基础设施,也是强大的NLP工具包。

该工具包拥有庞大的开发者社区,常用于信息抽取、情感分析、社交媒体挖掘和生物医学文本处理等领域。

GATE通过提供语言处理软件架构和实现该架构的类库来帮助开发者和研究人员

8. Apache UIMA

非结构化信息管理应用程序(UIMA)是能处理和分析大量非结构化数据(包括文本、音频和视频)的软件系统。它帮助创建能从内容中检测情感、实体等信息的组件,这些组件可用Java或C++编写。

Apache UIMA是一个框架,使我们能使用UIMA组件构建应用程序并处理海量非结构化数据,从中提取相关信息用于各种目的。

9. MALLET

语言学习工具包(MALLET)是一个Java包,为文档分类、主题建模、序列标注等NLP任务提供各种工具和算法。其中包含的朴素贝叶斯算法在NLP的文本分类和情感分析中被广泛使用。

MALLET是开源Java包,提供多种文本分析工具。其主题建模功能可发现大量未标记文本文档中的主要主题。

此外,MALLET还能将文本文档转换为可用于机器学习的数值向量,支持命令行工具和直接Java API两种使用方式。

10. 总结

本文介绍了NLP的核心概念及其应用场景,展示了不同的Java NLP库和工具包,并通过示例演示了使用CoreNLP和OpenNLP进行分词和句子检测的方法。

完整示例代码可在GitHub获取。


原始标题:Overview of NLP Libraries in Java