精华内容
下载资源
问答
  • 深度序列到序列实体匹配,实现异构实体解析
  • 跨多个异构数据源的实体匹配
  • 基于mapReduce的大规模实体匹配的高效方法
  • 主要是有关地理信息系统地图面实体匹配技术的资料!
  • 提出一种基于BP神经网络的二步检查法实体匹配新算法,将基于学习的思想引入到异构数据库实体匹配领域中,避开了传统方法计算属性权重的问题。实验结果显示,该算法很有效,能明显提高实体匹配的查准率,有较强的环境...
  • 垂直搜索中基于Lucene的实体匹配设计,李俊波,王洪波,通常垂直搜索系统需要整合多个信息来源或者多家网站的信息,以提供覆盖全网的垂直搜索服务,本文提出了一种基于Lucene的实体匹配
  • 为发现针对新闻事件中实体展开的网络评论,提出一种基于条件随机场的网络评论与新闻事件中命名实体匹配方法,使用semi-Markov CRFs从评论语句中识别出片段粒度的命名实体;针对评论描述随意的特点,结合命名实体的...
  • 针对面实体匹配问题进行了研究。面实体的边界线在某点的拱高正是对边界线在该点的弯曲程度和凸凹性的反映, 该点的中心距离又可以对面实体形状的整体进行描述, 通过边界线上某点的中心距离和拱高组成复数, 并对其进行...
  • 论文笔记整理:高凤宁,南京大学硕士,研究方向为知识图谱、实体消解。链接:https://doi.org/10.1145/3308558.3313578动机目前实体匹配过程...
        

    论文笔记整理:高凤宁,南京大学硕士,研究方向为知识图谱、实体消解。


    640?wx_fmt=png

    链接:https://doi.org/10.1145/3308558.3313578


    动机

    目前实体匹配过程中实体之间的差异比较微妙,不同的情况下可能会有不同的决策结果,导致难以做出精确的匹配决策。另外现存的实体匹配方法在做出决策之前,往往需要大量的训练数据,而这在许多的应用场景中是难以做到的。


    亮点

    本文的亮点主要包括:

    (1)设计了一种层次化的深度模型,利用了字符级别和单词级别的信息,来预训练常见属性类型的相关模型。

    (2)使用了迁移学习的方法,能够利用预训练模型并进行微调,使其能够处理新的属性类型的实体匹配任务。

     

    系统结构

    640?wx_fmt=png

    从上图可以看出,整个的系统分为三个组成部分,分别是Attribute Type Detection ModelAttribute-level EMTable-level EM &Fine-tuning。其中Attribute-levelEM是整个系统的核心部分。

    概念及模型

    1.    HI-EM 模型

    640?wx_fmt=png

    首先该模型针对字符级别和单词级别可以进行划分。在字符级别的层次上,先将输入的字符进行 embedding,转化为向量表示。再通过 BiGRU,使得模型能够学习到字符间的上下文信息。下面通过输入间的注意力机制,进行对齐工作。然后进行聚合工作,将对齐后的表示形式与 BiGRU 得到的表示形式分别进行作差和乘积,然后进行拼接,得到新的表示形式。最后通过输入内部的注意力机制,更新当前字符的权重,最后通过将其他输入对当前字符的影响进行求和,得到单词级别的表示形式。下面单词级别层次上的工作与之类似,最后每一个输入都得到相应的表示形式,然后通过MLP 进行打分,从而进行匹配决策。

     

    2.    Type-detection 模型

    640?wx_fmt=png

    该模型与HI-EM模型结构相似,但是没有沿用HI-EM模型,是因为在这两个任务中,同一个输入的不同元组的重要程度恰好是完全相反的。基于这一点考虑,Type-detection模型在结构上进行了变动,并且对最后的MLP层的输出结果进行了softmax操作,得到分别表征某个输入属于某个属性这件事为TrueFalse的表示形式。

     

    3.    Transfer Learning

    在属性类型检测和属性级别的实体匹配中,在处理未知的实体类型时都用到了迁移学习的方法。例如,在属性级别的实体匹配中,对已知的49种属性类型,每种类型都要单独训练一个模型,而对于未知类型的属性,训练模型时采用之前的49种属性类型的训练集的并集,模型基本沿用HI-EM模型,大体结构不变,只改变了MLP层,并进行微调,最终结果是训练得到一个模型。

     

    4.    Table-level EM 模型

    对属性类型明确的以及未知类型的属性级别实体匹配模型的最终表示形式进行了拼接,最终通过新的MLP层,并进行微调,即可得到表格级别的实体匹配模型。


    实验

    1.     Type Detection Experiments

    (1)   Entity-value type-detection

     

    640?wx_fmt=png

    40种常见属性类型中,绝大多数属性类型上面都有较高的准确率和召回率;在9种添加的地址类型中,尽管测试数据之间的差异较小,模型仍然能够较好地分辨属性类型。

     

    (2)   Table-column type-detection

    640?wx_fmt=png

    与基于关键字的这种很强的baseline方法相比,本文提出的模型在绝大多数属性类型上面,仍然能够取得跟前者相近甚至较好的实验效果。

     

    (3)   Transfer-learning to new types

    640?wx_fmt=png

    利用迁移学习方法的模型与从零开始学习的模型相比,前者的学习速度更快,有着更高的准确率和召回率。

     

    2.     Attribute-Level Entity Matching

    (1)   Pre-trained attribute-level EM

    640?wx_fmt=png

    从上表中可以得到如下几点发现:

    • 与其他所有方法相比,HI-EM 的实验结果是最好的;

    • HI-EM(Unified) 模型比 DeepMatcher (Unified) 模型的实验结果要好;

    • 与属性类型明确的实验模型相比,unified 类型的模型实验结果较差。

    640?wx_fmt=png

    640?wx_fmt=png

    从上图可以发现,在准确率和召回率这对指标上面的实验结果,与MRR上的实验结果基本一致。

     

    (2)   Transfer-learning to new types

    640?wx_fmt=png

    从上表中可以得到如下几点发现:

    • 在相同的训练样本数量下,利用迁移学习训练的模型比从零开始训练的模型的实验效果要好;

    • 训练数据越少时,两个模型之间的差异越明显。

     

    640?wx_fmt=png

    640?wx_fmt=png

    从上图可以发现,在准确率和召回率这对指标上面的实验结果,与MRR上的实验结果基本一致。

     

    3.     Table-level Entity Matching

    640?wx_fmt=png

    从上表中可以得到如下几点发现:

    • 利用预训练模型的实验效果较好,即使只有少量的训练数据;

    • 在属性级别的实体匹配任务中,属性类型明确的模型是更为准确的;

    • 绝大多数情况中HI-EM模型的实验效果比 DeepMatcher Magellan 更好。


    总结

    本文提出了一种利用预训练模型的端到端的实体匹配系统,在迁移学习的帮助下,证明了表格级别的实体匹配模型可以仅用少量的训练数据进行训练。

     


    OpenKG

    开放知识图谱(简称 OpenKG)旨在促进中文知识图谱数据的开放与互联,促进知识图谱和语义技术的普及和广泛应用。

    640?wx_fmt=jpeg

    点击阅读原文,进入 OpenKG 博客。

    展开全文
  • 一个实施数据科学管道的项目-提取原始数据,数据清理,特征提取,实体匹配,数据匹配,数据合并和OLAP样式探索。 选择的两个实体是Yelp和Zomato。 来自相同地点的餐厅数据将从这两个站点中提取,并且相似的餐厅将...
  • <p>I have two entities ServeApp and App. They both have a relation to AppPage. I'm trying to get ServeApps that have AppPages which App does not have. <p>So ServeApps.appPages should not contain ...
  • 实体匹配用户内容搜索的状态进行预测可显著提高物联网搜索的效率,降低搜索过程的通信开销。该文提出等时距与周期内实体状态预测方法,估计实体在用户查询时刻的状态;设计了适用于内容搜索的有序验证方法,依据实体...
  • 首先,我们定义annotation,关联数据库每一张表中的字段,数据在读取时自动匹配对应的实体中的属性。这我们就不用在考虑加载数据是表中字段是否与实体中的属性匹配了。package org.apath.com.common;import java....

    整理一下自己的笔记,关于Annotation注解的一个小案例。

    Annotation注解:

    1.首先,我们定义annotation,关联数据库每一张表中的字段,数据在读取时自动匹配对应的实体中的属性。这我们就不用在考虑加载数据是表中字段是否与实体中的属性匹配了。

    package org.apath.com.common;

    import java.lang.annotation.ElementType;

    import java.lang.annotation.Retention;

    import java.lang.annotation.RetentionPolicy;

    import java.lang.annotation.Target;

    /***

    * 注解--数据库字段与实体类字段

    * @author Dawn

    * @author 2010-04-15

    */

    @Target({ElementType.METHOD,ElementType.FIELD}) //表示这个注解是放在方法上的

    @Retention(RetentionPolicy.RUNTIME) // 表示着个方法是在运行时反射出来

    public @interface ColumnAnnotation {

    //列名 注解的属性

    String columnName();

    }

    //end annotation

    2.下面是一个实体,在实体的每个getter方法上注入我的annotation,标志从这里开始。

    package org.apath.com.entity;

    import org.apath.com.common.ColumnAnnotation;

    /**

    * 存放用户基本信息类

    * @author Dawn

    * @author 2010-04-14

    */

    public class UserInfo {

    private int userId; //用户Id

    private String userName; //真实姓名

    private String passWord; //密码

    private int departId; //所在部门

    private int gender; //性别

    private int roleId; //用户角色

    private int userStateId; //用户状态

    private String face;//用户图像

    public String getFace() {

    return face;

    }

    @ColumnAnnotation(columnName="face")

    public void setFace(String face) {

    this.face = face;

    }

    public int getUserStateId() {

    return userStateId;

    }

    @ColumnAnnotation(columnName="userStateId")

    public void setUserStateId(int userStateId) {

    this.userStateId = userStateId;

    }

    public int getUserId() {

    return userId;

    }

    @ColumnAnnotation(columnName="userId")

    public void setUserId(int userId) {

    this.userId = userId;

    }

    public String getUserName() {

    return userName;

    }

    @ColumnAnnotation(columnName="userName")

    public void setUserName(String userName) {

    this.userName = userName;

    }

    public String getPassWord() {

    return passWord;

    }

    @ColumnAnnotation(columnName="passWord")

    public void setPassWord(String passWord) {

    this.passWord = passWord;

    }

    public int getDepartId() {

    return departId;

    }

    @ColumnAnnotation(columnName="departId")

    public void setDepartId(int departId) {

    this.departId = departId;

    }

    public int getGender() {

    return gender;

    }

    @ColumnAnnotation(columnName="gender")

    public void setGender(int gender) {

    this.gender = gender;

    }

    public int getRoleId() {

    return roleId;

    }

    @ColumnAnnotation(columnName="roleId")

    public void setRoleId(int roleId) {

    this.roleId = roleId;

    }

    }

    //end Entity

    3.获取数据库驱动

    package org.apath.com.common;

    import java.sql.*;

    /***

    * 连接驱动

    * @author Dawn

    * @author 2010-04-14

    */

    public class GetDriver {

    static Connection conncetion=null;

    static ResultSet rs=null;

    static PreparedStatement pstmt=null;

    //单线程模式

    static ThreadLocal thread = new ThreadLocal();

    public static ThreadLocal getThread() {

    return thread;

    }

    static

    {

    try {

    Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");

    } catch (ClassNotFoundException e) {

    e.printStackTrace();

    }

    }

    public static Connection getConncetion() throws Exception

    {

    conncetion=(Connection)thread.get();

    if(conncetion==null)

    {

    conncetion=DriverManager.getConnection("jdbc:sqlserver://localhost:1434;databaseName=HR_DB","sa","sa");

    }else

    {

    thread.set(conncetion);

    }

    return conncetion;

    }

    /***

    * 关闭数据库

    */

    public void getClose()

    {

    conncetion=(Connection)thread.get();

    try{

    if(rs!=null)

    rs.close();

    if(pstmt!=null)

    pstmt.close();

    if(conncetion!=null)

    conncetion.close();

    }catch(Exception ex){

    ex.printStackTrace();

    }

    //删除

    thread.remove();

    }

    }

    //end 获取数据库驱动

    4.反射获取表中的数据

    package org.apath.com.common;

    import java.lang.reflect.Method;

    import java.sql.ResultSet;

    import java.sql.ResultSetMetaData;

    import java.sql.SQLException;

    import java.util.ArrayList;

    import java.util.List;

    import org.apath.com.entity.MeetingInfo;

    import org.apath.com.entity.Schedule;

    /**

    * 执行查询对象操作

    *

    * @param Sql

    * ,Class

    * @throws Exception

    */

    public class DBConnection extends GetDriver {

    /**

    * 执行查询对象操作

    *

    * @param Sql

    * ,Class

    * @throws Exception

    */

    public Object executeQuery(String sql, Class clz) throws Exception

    {

    List list = null;

    try

    {

    rs =executeQuerys(sql);

    // 得到所有的列的名称

    String[] columStrings = getColumnsName(rs);

    // 得到类所有的方法

    Method[] methods = clz.getDeclaredMethods();

    Object object = null;

    list=new ArrayList();

    while (rs.next())

    {

    // 得到一个实例

    object = clz.newInstance();

    for (int i = 0; i < columStrings.length; i++)

    {

    // 得到每一列的名称

    String ColumnName = columStrings[i];

    // 遍历所有列的方法名称进行比较

    for (Method method : methods)

    {

    // 判断方法上面是否有注解

    if (method.isAnnotationPresent(ColumnAnnotation.class))

    {

    // 得到一个注解的对象

    ColumnAnnotation annotation = method

    .getAnnotation(ColumnAnnotation.class);

    // 根据我们数据库的列名与我们注解的名称来比较是否相等,相等的话,执行那个方法为它设置值

    if (ColumnName.equalsIgnoreCase(annotation.columnName()))

    {

    // 调用相应的方法

    method.invoke(object, rs.getObject(ColumnName));

    }

    }

    }

    }

    list.add(object);

    }

    }catch(Exception ex)

    {

    System.out.println("注解抛出异常!");

    ex.printStackTrace();

    }

    finally

    {

    this.getClose();

    }

    return list;

    }

    /**

    * 得到数据库所有的列名

    *

    * @param rs

    * @return

    * @throws SQLException

    */

    public String[] getColumnsName(ResultSet rs) throws SQLException {

    // 得到所有的列

    ResultSetMetaData methodDate = rs.getMetaData();

    // 得到列的总数

    int methodCount = methodDate.getColumnCount();

    String[] column = new String[methodCount];

    for (int i = 1; i <= column.length; i++) {

    // 得到列的名称

    column[i - 1] = methodDate.getColumnName(i);

    }

    return column;

    }

    /***

    * 查询操作

    *

    * @param sql

    * @return ResultSet

    */

    public ResultSet executeQuerys(String sql) {

    try

    {

    //获取连接

    getConncetion();

    pstmt = conncetion.prepareStatement(sql);

    rs = pstmt.executeQuery();

    }catch (Exception e) {

    e.printStackTrace();

    }

    return rs;

    }

    /***

    * 非查询操作

    *

    * @param sql

    * @return

    */

    public int executeUpdate(String sql) throws SQLException, Exception {

    int result=0;

    getConncetion();

    pstmt = conncetion.prepareStatement(sql);

    result= pstmt.executeUpdate();

    getClose();

    return result;

    }

    }

    //end annotation操作

    5.action中只要调用方法操作即可。

    展开全文
  • Rasa绝对匹配提取实体

    2020-05-18 11:26:57
    提供查找表,自定义组件对输入文本进行绝对匹配提取实体

    查看GitHub项目:rasa_nlu_xercis: Rasa的自定义中文组件




    问题描述

    Rasa文档关于训练数据中说到,查询表(lookup)提供了一种提供实体示例的简便方法

    然而要注意:要使查找表有效,训练数据中必须有一些匹配的示例,否则模型不会学习使用查找表匹配特性

    在查看官方视频教程配套代码后发现,人家训练数据压根没提供lookup,而是给出了一堆重复的相似数据

    ## intent:inform
    - [Sitka](location)
    - [Juneau](location)
    - [Virginia](location)
    - [Cusseta](location)
    - [Chicago](location)
    - [Tucson](location)
    
    ......
    
    ## intent:search_provider
    - i am in [Amarillo](location) and i need a [nursing home](facility_type)
    - i am in [New York](location) and i need a [hospital](facility_type)
    - i am in [Las Vegas](location) and i need a [home healt agency](facility_type)
    - i need a [nursing home](facility_type) in [Katy](location)
    - i need a [hospital](facility_type) in [Waco](location)
    - i need a [home health agency](facility_type) in [Clarksville](location)
    - show me [nursing home](facility_type) in [Knoxville](location)
    - show me [hospital](facility_type) in [Durham](location)
    - show me [home health agency](facility_type) in [Detroit](location)
    - hi i am in [Tampa](location) i need a [nursing  home](facility_type:b27b-2uc7)
    - hi i am in [San Diego](location) i need a [hospital](facility_type:xubh-q36u)
    - hi i am in [Nashville](location) i need a [home health agenc](facility_type:9wzi-peqs)
    - hello i am in [Tampa](location) i need a [nursing  home](facility_type:b27b-2uc7)
    - hello i am in [San Diego](location) i need a [hospital](facility_type:xubh-q36u)
    - hello i am in [Nashville](location) i need a [home health agenc](facility_type:9wzi-peqs)
    
    ......
    
    




    解决方案

    提供查找表,自定义组件对输入文本进行绝对匹配提取实体




    代码

    match_entity_extractor.py

    新版Rasa需要将from rasa.nlu.extractors import EntityExtractor改成from rasa.nlu.extractors.extractor import EntityExtractor

    # -*- coding: utf-8 -*-
    # @Author  : XerCis
    # @Time    : 2020/5/15 15:33
    # @Function: Extract entity
    
    import os
    from itertools import combinations
    from typing import Any, Text, Dict
    from rasa.nlu.extractors import EntityExtractor
    
    
    class MatchEntityExtractor(EntityExtractor):
        """绝对匹配提取实体"""
        provides = ["entities"]
    
        defaults = {
            "dictionary_path": None,
            "take_long": None,
            "take_short": None
        }
    
        def __init__(self, component_config=None):
            print("init")
            super(MatchEntityExtractor, self).__init__(component_config)
            self.dictionary_path = self.component_config.get("dictionary_path")
            self.take_long = self.component_config.get("take_long")
            self.take_short = self.component_config.get("take_short")
            if self.take_long and self.take_short:
                raise ValueError("take_long and take_short can not be both True")
            self.data = {}  # 用于绝对匹配的数据
            for file_path in os.listdir(self.dictionary_path):
                if file_path.endswith(".txt"):
                    file_path = os.path.join(self.dictionary_path, file_path)
                    file_name = os.path.basename(file_path)[:-4]
                    with open(file_path, mode="r", encoding="utf-8") as f:
                        self.data[file_name] = f.read().splitlines()
    
        def process(self, message, **kwargs):
            """绝对匹配提取实体词"""
            print("process")
            entities = []
            for entity, value in self.data.items():
                for i in value:
                    start = message.text.find(i)
                    if start != -1:
                        entities.append({
                            "start": start,
                            "end": start + len(i),
                            "value": i,
                            "entity": entity,
                            "confidence": 1
                        })
            if self.take_long or self.take_short:
                for i in list(combinations(entities, 2)):
                    v0, v1 = i[0]["value"], i[1]["value"]
                    if v0 in v1 or v1 in v0:
                        (long, short) = (i[0], i[1]) if len(v0) > len(v1) else (i[1], i[0])
                        if self.take_long == True and short in entities:
                            entities.remove(short)
                        if self.take_short == True and long in entities:
                            entities.remove(long)
            extracted = self.add_extractor_name(entities)
            message.set("entities", extracted, add_to_output=True)
    
        @classmethod
        def load(cls, meta: Dict[Text, Any], model_dir=None, model_metadata=None, cached_component=None, **kwargs):
            print("load")
            return cls(meta)
    

    config.yml添加

    - name: "match_entity_extractor.MatchEntityExtractor"
      dictionary_path: "data/lookup_tables/"
    

    ./data/lookup_tables/city.txt

    北京
    上海
    广州
    深圳
    海西
    海西蒙古族藏族自治州
    

    ./data/lookup_tables/scene.txt

    故宫
    长城
    圆明园
    外滩
    白云山
    欢乐谷
    

    input:

    我想去北京的圆明园玩
    

    output:

      "entities": [
        {
          "start": 3,
          "end": 5,
          "value": "北京",
          "entity": "city",
          "confidence": 1,
          "extractor": "MatchEntityExtractor"
        },
        {
          "start": 6,
          "end": 9,
          "value": "圆明园",
          "entity": "scene",
          "confidence": 1,
          "extractor": "MatchEntityExtractor"
        }
      ],
    





    配置

    - name: "extractors.match_entity_extractor.MatchEntityExtractor"
      dictionary_path: "data/lookup_tables/"
      take_short: True  # 重复实体取短
    #  take_long: True  # 重复实体取长
    

    输入

    海西全称为海西蒙古族藏族自治州
    

    输出

      "entities": [
        {
          "start": 0,
          "end": 2,
          "value": "海西",
          "entity": "city",
          "confidence": 1,
          "extractor": "MatchEntityExtractor"
        }
      ],
    




    参考文献

    1. Training Data Format
    2. RasaHQ/rasa-masterclass: Data and code files for specific Rasa Masterclass episodes
    3. Custom NLU Components
    4. Rasa自定义NLU组件
    5. GaoQ1/rasa_nlu_gq
    6. Python绝对匹配提取实体
    7. rasa_nlu_xercis: Rasa的自定义中文组件





    在这里插入图片描述

    展开全文
  • 实体解析的端到端多视角匹配
  • 在本文中,我们提出了一种通过形式化上下文匹配和类别匹配实体搜索方法。 此外,我们提出了一种结果重排序策略,可以轻松地对其进行调整,以实现两种上下文匹配策略的混合。 INEX 2009实体排名任务的实验表明,与...
  • 方法1. 生成器读取 方法2. 将文件读进内存 选项 重复实体取长或取短

    问题描述

    ./data/city.txt

    北京
    上海
    广州
    深圳
    海西
    海西蒙古族藏族自治州
    

    ./data/scene.txt

    故宫
    长城
    圆明园
    外滩
    白云山
    欢乐谷
    

    input:

    我想去北京的圆明园玩
    

    output:

    [{'start': 3, 'end': 5, 'value': '北京', 'entity': 'city'}, {'start': 6, 'end': 9, 'value': '圆明园', 'entity': 'scene'}]
    




    解决方案

    1. 文件名作为实体名
    2. 绝对匹配




    生成器读取

    # -*- coding: utf-8 -*-
    # @Author  : XerCis
    # @Time    : 2020/5/15 17:00
    # @Function: 绝对匹配提取实体词
    
    import os
    
    
    def read(file_path):
        """读取文本文档生成器"""
        with open(file_path, mode="r", encoding="utf-8") as f:
            for line in f:
                yield line.strip()  # 去除空格换行
    
    
    def extract(message, dictionary_path):
        """绝对匹配提取实体词"""
        entities = []
        for file_path in os.listdir(dictionary_path):
            if file_path.endswith(".txt"):
                file_path = os.path.join(dictionary_path, file_path)
                it = read(file_path)
                for i in it:
                    start = message.find(i)
                    if start != -1:
                        entities.append({
                            "start": start,
                            "end": start + len(i),
                            "value": i,
                            "entity": os.path.basename(file_path)[:-4],  # 以文件名作实体名
                            "confidence": 1
                        })
        return entities
    
    
    if __name__ == "__main__":
        print(extract("我想去北京的圆明园玩", dictionary_path="./data"))
    

    优点:逐行读取文件,内存消耗极小
    缺点:运行效率慢




    将文件读进内存

    # -*- coding: utf-8 -*-
    # @Author  : XerCis
    # @Time    : 2020/5/15 17:00
    # @Function: 绝对匹配提取实体词
    
    import os
    
    
    def read(dictionary_path):
        """读取文本文档数据进字典"""
        data = {}
        for file_path in os.listdir(dictionary_path):
            if file_path.endswith(".txt"):
                file_path = os.path.join(dictionary_path, file_path)
                file_name = os.path.basename(file_path)[:-4]  # 以文件名作实体名
                with open(file_path, mode="r", encoding="utf-8") as f:
                    data[file_name] = f.read().splitlines()
        return data
    
    
    def extract(data, message):
        """绝对匹配提取实体词"""
        entities = []
        for entity, value in data.items():
            for i in value:
                start = message.find(i)
                if start != -1:
                    entities.append({
                        "start": start,
                        "end": start + len(i),
                        "value": i,
                        "entity": entity,
                        "confidence": 1
                    })
        return entities
    
    
    if __name__ == "__main__":
        data = read("./data")
        print(extract(data, message="我想去北京的圆明园玩"))
    




    重复实体取长或取短

    # -*- coding: utf-8 -*-
    # @Author  : XerCis
    # @Time    : 2020/5/15 17:00
    # @Function: 绝对匹配提取实体词
    
    import os
    from itertools import combinations
    
    
    def read(dictionary_path):
        """读取文本文档数据进字典"""
        data = {}
        for file_path in os.listdir(dictionary_path):
            if file_path.endswith(".txt"):
                file_path = os.path.join(dictionary_path, file_path)
                file_name = os.path.basename(file_path)[:-4]  # 以文件名作实体名
                with open(file_path, mode="r", encoding="utf-8") as f:
                    data[file_name] = f.read().splitlines()
        return data
    
    
    def extract(data, message, take_long=False, take_short=False):
        """绝对匹配提取实体词"""
        if take_long and take_short:
            raise ValueError("take_long and take_short can not be both True")
        entities = []
        for entity, value in data.items():
            for i in value:
                start = message.find(i)
                if start != -1:
                    entities.append({
                        "start": start,
                        "end": start + len(i),
                        "value": i,
                        "entity": entity,
                        "confidence": 1
                    })
        for i in list(combinations(entities, 2)):
            v0, v1 = i[0]["value"], i[1]["value"]
            if v0 in v1 or v1 in v0:
                (long, short) = (i[0], i[1]) if len(v0) > len(v1) else (i[1], i[0])
                if take_long == True and short in entities:
                    entities.remove(short)
                if take_short == True and long in entities:
                    entities.remove(long)
        return entities
    
    
    if __name__ == "__main__":
        data = read("./data")
        print(extract(data, message="海西全称为海西蒙古族藏族自治州", take_long=True))
        print(extract(data, message="海西全称为海西蒙古族藏族自治州", take_short=True))
        # [{'start': 5, 'end': 15, 'value': '海西蒙古族藏族自治州', 'entity': 'city', 'confidence': 1}]
        # [{'start': 0, 'end': 2, 'value': '海西', 'entity': 'city', 'confidence': 1}]
    




    参考文献

    1. Python可迭代对象、迭代器和生成器的区别
    2. Python os.path() 模块 | 菜鸟教程
    3. Python 字符串
    展开全文
  • ERSOM:使用自动学习的实体表示的StructureOntology匹配方法
  • 准确匹配实体名称在信息系统集成中有广泛的应用,而在中文环境中,实体名称的变化和笔误使得中文实体名称难以准确匹配,所以需要开发出适应这些变化和笔误的匹配方法。中文实体名称的相似度从字、词、语义三个层次...
  • Mysql字段和java实体类属性类型匹配

    千次阅读 2019-06-19 15:59:13
    Mysql字段和java实体类属性类型匹配 参见下图:
  • JPA实体是否应该匹配它们正在映射的数据库的约束? 用于数据生成的数据库触发器又如何呢? 最佳答案 是的,您应该在JPA模型中对约束建模,因为最好在实体中明确声明那些约束. 一方面,仅出于文档目的(许多开发人员...
  • 基于该模型,本文设计了一种模糊匹配的方法用于计算命名实体子向量之间 的关联度,它们和多个向量相似度一起用支持向量机进行整合,形成报道模型间的相似度。本文选用TDT4中文 语料作为测试语料,将上述模型及模糊...
  • 摘要: 前面介绍了MapStrut简单用法,MapStrut的最重要的特点就是处理Java中实体与模型间不匹配属性的转换。实体模型有一个User对象:public class User { private Integer id; private String name; private ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,396
精华内容 958
关键字:

实体匹配