来自麻省理工的信息抽取

简介: MITIEMITIE 即 MIT 的 NLP 团队发布的一个信息抽取库和工具。它是一款免费且先进的信息抽取工具,目前包含了命名实体抽取、二元关系检测功能,另外也提供了训练自定义抽取器和关系检测器的工具。

MITIE

MITIE 即 MIT 的 NLP 团队发布的一个信息抽取库和工具。它是一款免费且先进的信息抽取工具,目前包含了命名实体抽取、二元关系检测功能,另外也提供了训练自定义抽取器和关系检测器的工具。

MITIE 是核心代码是使用 C++ 写的,建立在高性能的机器学习库 dlib 上。MIT 团队给我们提供了一些已训练好了的模型,这其中包含了英语、西班牙语和德语,这些模型都使用了大量的语料进行训练。我们发现并没有我们要的中文的模型,所以这个还得我们自己训练。

尽管 MITIE 是 C++ 写的,但它也提供了其他语言的调用 API 。在我自己的项目中常常会跟 Java 、 Python 混合用,所以只要编译成动态库再分别用 Java 和 Python 调用就行了,很方便。

为什么出现MITIE

看看 MIT 实验室的人怎么说就知道了。

I work at a lab and there are a lot of cool things about my job. In fact, I could go on all day about it, but in this post I want to talk about one thing in particular, which is that we recently got funded by the program to make an open source natural language processing library focused on information extraction.

Why make such a thing when there are already open source libraries out there for this (e.g. OpenNLP, NLTK, Stanford IE, etc.)? Well, if you look around you quickly find out that everything which exists is either expensive, not state-of-the-art, or GPL licensed. If you wanted to use this kind of NLP tool in a non-GPL project then you are either out of luck, have to pay a lot of money, or settle for something of low quality. Well, not anymore! We just released the first version of our MIT Information Extraction library which is built using state-of-the-art statistical machine learning tools.

怎么使用

提取实体为例,为方便可直接使用 MITIE 提供给我们的模型,否则你就需要自己训练了。从 https://github.com/mit-nlp/MITIE/releases/download/v0.4/MITIE-models-v0.2.tar.bz2 下载。

然后创建一个 test.txt 文件,待测试内容为

I met with john becker at HBU.
The other day at work I saw Brian Smith from CMU.

最后编写代码如下,

#include <mitie/named_entity_extractor.h>
#include <mitie/conll_tokenizer.h>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cstdlib>

using namespace std;
using namespace mitie;

std::vector<string> tokenize_file (
    const string& filename
)
{
    ifstream fin(filename.c_str());
    if (!fin)
    {
        cout << "Unable to load input text file" << endl;
        exit(EXIT_FAILURE);
    }
    conll_tokenizer tok(fin);
    std::vector<string> tokens;
    string token;
    while(tok(token))
        tokens.push_back(token);

    return tokens;
}


int main(int argc, char** argv)
{
    try
    {
        if (argc != 3)
        {
            printf("You must give a MITIE ner model file as the first command line argument\n");
            printf("followed by a text file to process.\n");
            return EXIT_FAILURE;
        }
        string classname;
        named_entity_extractor ner;
        dlib::deserialize(argv[1]) >> classname >> ner;

        const std::vector<string> tagstr = ner.get_tag_name_strings();
        cout << "The tagger supports "<< tagstr.size() <<" tags:" << endl;
        for (unsigned int i = 0; i < tagstr.size(); ++i)
            cout << "   " << tagstr[i] << endl;

        std::vector<string> tokens = tokenize_file(argv[2]);

        std::vector<pair<unsigned long, unsigned long> > chunks;
        std::vector<unsigned long> chunk_tags;
        std::vector<double> chunk_scores;

        ner.predict(tokens, chunks, chunk_tags, chunk_scores);

        cout << "\nNumber of named entities detected: " << chunks.size() << endl;
        for (unsigned int i = 0; i < chunks.size(); ++i)
        {
            cout << "   Tag " << chunk_tags[i] << ": ";
            cout << "Score: " << fixed << setprecision(3) << chunk_scores[i] << ": ";
            cout << tagstr[chunk_tags[i]] << ": ";
            for (unsigned long j = chunks[i].first; j < chunks[i].second; ++j)
                cout << tokens[j] << " ";
            cout << endl;
        }

        return EXIT_SUCCESS;
    }
    catch (std::exception& e)
    {
        cout << e.what() << endl;
        return EXIT_FAILURE;
    }
}

执行结果为,

The tagger supports 4 tags:
   PERSON
   LOCATION
   ORGANIZATION
   MISC

Number of named entities detected: 4
   Tag 0: Score: 1.532: PERSON: john becker
   Tag 2: Score: 0.340: ORGANIZATION: HBU
   Tag 0: Score: 1.652: PERSON: Brian Smith
   Tag 2: Score: 0.471: ORGANIZATION: CMU

中文模型训练

主要是要训练所有词向量特征,后面的实名实体模型和关系模型都是建立在它的基础上,MITIE 给我们提供了工具完成上述操作,我们可以用 cmake 生成vs项目,但一般我们没有必要改动到代码,直接使用 cmake 构建一下就可直接使用。主要操作有

D:\MITIE\tools\wordrep>mkdir build
D:\MITIE\tools\wordrep>cd build
D:\MITIE\tools\wordrep\build>cmake ..
D:\MITIE\tools\wordrep\build>cmake --build . --config Release

再一个是需要收集大量的词汇,可以通过维基百科和百度百科收集,类似处理可以参加前面的文章 《如何使用中文维基百科语料》。

接着就可以开始训练了,参数e表示生成所有我们需要的模型,data为语料库的目录。

wordrep -e data
if (parser.option("e"))
        {
            count_words(parser);
            word_vects(parser);
            basic_morph(parser);
            cca_morph(parser);
            return 0;
        }

Java&Python调用

主要的一步都是要生成共享链接库,同样使用 cmake 可以很方便生成,到 mitielib 目录,

D:\MITIE\mitielib>mkdir build
D:\MITIE\mitielib>cd build
D:\MITIE\mitielib\build>cmake ..
D:\MITIE\mitielib\build>cmake --build . --config Release --target install

生成需要的链接库。

-- Install configuration: "Release"
-- Installing: D:/MITIE/mitielib/msvcp140.dll
-- Installing: D:/MITIE/mitielib/vcruntime140.dll
-- Installing: D:/MITIE/mitielib/concrt140.dll
-- Installing: D:/MITIE/mitielib/mitie.lib
-- Installing: D:/MITIE/mitielib/mitie.dll

然后 python 就能轻易完成调用。而对于 Java 也而需要类似的操作,但它的构建过程还需要有 SWIG 。生成如下的链接库和 jar 包,然后 Java就能轻易完成调用。

-- Install configuration: "Release"
-- Installing: D:/MITIE/mitielib/java/../javamitie.dll
-- Installing: D:/MITIE/mitielib/java/../javamitie.jar
-- Up-to-date: D:/MITIE/mitielib/java/../msvcp140.dll
-- Up-to-date: D:/MITIE/mitielib/java/../vcruntime140.dll
-- Up-to-date: D:/MITIE/mitielib/java/../concrt140.dll

github

一个文本分析项目使用MITIE,https://github.com/sea-boat/TextAnalyzer.git

以下是广告

========广告时间========

鄙人的新书《Tomcat内核设计剖析》已经在京东销售了,有需要的朋友可以到 https://item.jd.com/12185360.html 进行预定。感谢各位朋友。

为什么写《Tomcat内核设计剖析》

=========================

欢迎关注:

这里写图片描述
这里写图片描述

目录
相关文章
|
弹性计算 运维 监控
GPU实例使用--vGPU驱动自动安装和升级
为了适配最新的渲染软件,以及驱动稳定性的提升,vGPU实例的驱动需要定期进行升级,因为使用vgpu的客户多数为渲染和云游戏等业务场景,对vGPU驱动的快速升级和批量自动化要求比较高。
GPU实例使用--vGPU驱动自动安装和升级
|
运维 监控 Java
内存溢出+CPU占用过高:问题排查+解决方案+复盘(超详细分析教程)
全网最全的内存溢出CPU占用过高排查文章,包含:问题出现现象+临时解决方案+复现问题+定位问题发生原因+优化代码+优化后进行压测,上线+复盘
3303 5
|
SQL Java Linux
聊聊 kerberos 的 kinit 命令和 ccache 机制
聊聊 kerberos 的 kinit 命令和 ccache 机制
|
JavaScript 关系型数据库 MySQL
创建nodejs项目并接入mysql,完成用户相关的增删改查的详细操作
创建nodejs项目并接入mysql,完成用户相关的增删改查的详细操作
244 0
万年历[取当日信息]免费API接口教程
此API提供万年历当天的详细信息,包括农历、星期、宜忌、生肖、星座、节日、五行、星宿等。支持POST和GET请求,需提供用户ID和KEY。返回数据包含阳历、农历、干支、节日列表等多项内容。示例URL:https://cn.apihz.cn/api/time/getday.php?id=88888888&key=88888888。
3677 10
|
Java 开发工具 Android开发
搭建大型源码阅读环境——使用 OpenGrok
RTFSC 是程序员成长的必修课,营造舒适的环境至关重要。本文介绍了阅读大型源码(如 AOSP)的工具选择,重点推荐了免费开源的 OpenGrok。OpenGrok 提供快速搜索、版本历史查看、语法高亮等功能,适用于特大型项目。文章还详细讲解了 OpenGrok 的安装和配置步骤,帮助读者高效阅读源码。
2486 6
|
前端开发 JavaScript 开发工具
独家揭秘:前端大牛们都在用的高效开发工具,你get了吗?
前端开发领域日新月异,Visual Studio Code、Webpack、React/Vue和Git等工具凭借高效、便捷的特点,深受前端大牛们青睐。本文将揭秘这些工具的使用技巧,帮助你提升开发效率,轻松应对各种前端挑战。
154 3
|
架构师 开发者
【悬念揭秘】DDD:那片隐藏在软件深处的业务乐土——.NET项目如何借力领域驱动设计,让复杂业务逻辑迎刃而解?
【8月更文挑战第28天】领域驱动设计(DDD)在.NET项目中的应用聚焦于将业务领域知识与软件开发紧密结合,通过构建清晰的领域模型管理复杂业务逻辑。DDD的核心概念包括限界上下文、聚合、实体等,确保模型与实现的统一。在.NET中,通过CQRS和事件源等模式提高系统响应性和可扩展性,实现业务事件驱动的解耦与协作。DDD不仅是一种设计方法,更是要求开发者深入理解业务的文化,助力.NET项目应对复杂挑战,实现业务与技术的融合。
239 6
|
网络协议 小程序 物联网
Gateway-Worker启动失败或者启动无法正常使用的几种方法
Workerman是一款开源高性能异步PHP socket即时通讯框架。支持高并发,超高稳定性,被广泛的用于手机app、移动通讯,微信小程序,手游服务端、网络游戏、PHP聊天室、硬件通讯、智能家居、车联网、物联网等领域的开发。 支持TCP长连接,支持Websocket、HTTP等协议,支持自定义协议
384 3
|
存储 NoSQL Ubuntu
在Ubuntu 16.04上安装和配置Redis的方法
在Ubuntu 16.04上安装和配置Redis的方法
333 0