2014-07-04 88 views
4

(很抱歉,如果标题是顺便一完整的红鲱鱼)反向索引

背景:

我开发地图所有的鸣叫的在世界上真正的使用Twitter Streaming API和ASP.NET SignalR。我使用Tweetinvi C#Twitter库异步地使用SignalR将推文推送到浏览器。一切都按预期工作 - 请参阅http://dev.wherelionsroam.co.uk了解它。

开发的下一步包括使用斯坦福自然语言解析库(http://nlp.stanford.edu/software/corenlp.shtml),特别是命名实体识别器(也称为CRFClassifier)解析每条推文的文本数据,以便从每条推文中提取有意义的元数据即提到的人物,地点和组织)。期望的结果是,我将能够确定许多人正在讨论的人物,地点和组织(类似于“趋势”概念),并将其广播给使用SignalR的所有客户。我知道Twitter API有GET trends方法,但这不会有什么乐趣吗?!

这里是我的应用程序的主要类型:

主要类型:

TweetModel.cs(包含所有的关于鸣叫广播将其从流API的信息):

public class TweetModel 
{ 
    public string User { get; set; } 
    public string Text { get; set; } 
    public DateTime CreatedAt { get; set; } 
    public string ImageUrl { get; set; } 
    public double Longitude { get; set; } 
    public double Latitude { get; set; } 
    public string ProfileUrl { get; set; } 

    // This field is set later during Tokenization/Named Entity Recognition 
    public List<NamedEntity> entities = new List<NamedEntity>(); 
} 

摘要NamedEntity类:

public abstract class NamedEntity 
{ 
    /// <summary> 
    /// Abstract modelling class for NER tagging - overridden by specific named entities. Used here so that all classes inherit from a single base class - polymorphic list 
    /// </summary> 
    protected string _name; 
    public abstract string Name { get; set; } 
} 

Person类,它覆盖抽象NamedEntity类的类的一个示例:

public class Person : NamedEntity 
{ 
    public override string Name 
    { 
     get 
     { 
      return _name; 
     } 
     set 
     { 
      _name = value; 
     } 
    } 
    public string entityType = "Person"; 
} 

的TweetParser类:

public class TweetParser 
    { 
     // Static List to hold all of tweets (and their entities) - tweets older than 20 minutes are cleared out 
     public static List<TweetModel> tweets = new List<TweetModel>(); 
     public TweetParser(TweetModel tweet) 
     { 
      ProcessTweet(tweet); 
      // Removed all of NER logic from this class 
     } 
} 

的命名实体识别器的说明:

的NER识别库工作的方式是将句子中的单词用“PERSON”作为“Luis Suarez”或“PLACE”作为“纽约”的标签进行分类。此信息存储在子类中NamedEntity类的,这取决于由NER库已被归因于这个词是什么类型的标签(选择PERSONLOCATIONORGANISATION

问题:

我的问题是,考虑到可能有多个版本的“路易斯苏亚雷斯”(即路易斯苏亚雷斯,路易斯苏亚雷斯),这两个版本都将在他们自己的不同NamedEntity实例中定义(在List<NamedEntity>实例中,然后在TweetModel实例中),将术语“Luis Suarez”的匹配实例分组的最佳方式是什么呃来自所有推文,同时仍然保留亲子关系TweetModel>List<NamedEntity>。我被告知这实际上是一个倒排索引,但我不确定这个人有多了解!

可视化结构:

enter image description here

我真的很抱歉,如果这个问题还不清楚;我不能用比这更简洁的表达来表达它!至于完整的src到目前为止,请参阅https://github.com/adaam2/FinalUniProject

+0

所以你想要一个结构,其中Tweets包含名称,同时一个名称包含Tweets?这听起来像是一个倒排索引。然后,你对字符串的模糊比较是第二个要求,第一个要求会让第一个要求复杂化。 –

+0

@NathanCooper实际上是的。就模糊字符串匹配而言,我使用了一个模糊匹配库,它返回Levenshtein距离(返回double类型的值),以确定字符串需要与另一个字符串相同的编辑次数。我认为编辑次数的任意最大值为1或2次编辑 – adaam

+0

您想要的是多对多关系,其中TweetModel具有许多NamedEntities,而NamedEntity存在于Many TweetModels中。 –

回答

1

1-将List<TweetModel>财产添加到您的NamedEntity

public abstract List<TweetModel> Tweets { get; set; } 

2-保证你的符号化功能始终返回相同标记的相同NamedEntity对象。

3-当您将NamedEntity添加到实体列表时,还会将TweetModel添加到NamedEntity的列表中。

Person p = this is the result of the Tokenization; 
entities.Add(p); 
p.Tweets.Add(this); 

基本上唯一的困难的部分是有一个生成所述命名实体返回相同的对象时,发现在不同的鸣叫文本“苏亚雷斯”和“苏亚雷斯”的功能。

+0

我明白了!对,当我下班回家看看它是否有效时,我将不得不试试这个! – adaam

+0

这很好用!快速的问题..肯定TweetModel>命名实体> TweetModel等关系会递减无限还是我误解? – adaam

+0

@adaam是的,它将是无限的,但你只能迭代一个,但手动用户可以无限期地从一个到另一个。 –

1

如果你能比较人,那么你应该能够找到一个唯一的名称来表示他们。

举例而言,所有路易斯·苏亚雷斯,苏亚雷斯,苏亚雷斯,苏亚雷斯L.全部翻译成“苏亚雷斯” 这对通过MyHashFunctionForPerson

然后使用哈希表:

Dictionary<string,List<Person>> map = new Dictionary<string,List<Person>>(); 

List<Person> FindMatches(Person p) 
{ 
    string h = MyHashFunctionForPerson(p); 
    if (!map.ContainsKey(h)) 
    map[h] = new List<person(); 
    map[h].add(p); 
    return map[h]; 
} 

MyHashFunction可能是NamedEntity的抽象函数。 你也可以检查方向覆盖等于,GethashCode等

通常你有一个地图,每个人有一个索引。 在这种情况下,您可以进行反向查找,每个索引映射到Person列表。因此,“倒置”的索引名称。