句子中的单词共现

Posted

技术标签:

【中文标题】句子中的单词共现【英文标题】:Word cooccurence in sentences 【发布时间】:2016-06-26 05:52:37 【问题描述】:

我在一个文件中有大量句子(10,000 个)。该文件每个文件包含一个句子。在整个集合中,我想找出哪些单词在一个句子中一起出现以及它们的频率。

例句:

"Proposal 201 has been accepted by the Chief today.", 
"Proposal 214 and 221 are accepted, as per recent Chief decision",     
"This proposal has been accepted by the Chief.",
"Both proposal 3 MazerNo and patch 4 have been accepted by the Chief.",     
"Proposal 214, ValueMania, has been accepted by the Chief.";

我想对以下输出进行编码。我应该能够提供三个起始词作为程序的参数:“Chief, accepted, Proposal”

Chief accepted Proposal            5
Chief accepted Proposal has        3
Chief accepted Proposal has been   3

... 
...
for all combinations.

我知道组合可能很大。

我在网上搜索过,但没有找到。我已经编写了一些代码,但无法理解它。也许知道该域的人可能知道。

ReadFileLinesIntoArray rf = new ReadFileLinesIntoArray();

            try 
                String[] tmp = rf.readFromFile("c:/scripts/SelectedSentences.txt");
                for (String t : tmp)
                      String[] keys = t.split(" ");
                      String[] uniqueKeys;
                      int count = 0;
                      System.out.println(t);
                      uniqueKeys = getUniqueKeys(keys);
                        for(String key: uniqueKeys)
                        
                            if(null == key)
                            
                                break;
                                       
                            for(String s : keys)
                            
                                if(key.equals(s))
                                
                                    count++;
                                               
                            
                            System.out.println("Count of ["+key+"] is : "+count);
                            count=0;
                        
                
             catch (IOException e) 
                // TODO Auto-generated catch block
                e.printStackTrace();
            

private static String[] getUniqueKeys(String[] keys) 
        String[] uniqueKeys = new String[keys.length];

        uniqueKeys[0] = keys[0];
        int uniqueKeyIndex = 1;
        boolean keyAlreadyExists = false;

        for (int i = 1; i < keys.length; i++) 
            for (int j = 0; j <= uniqueKeyIndex; j++) 
                if (keys[i].equals(uniqueKeys[j])) 
                    keyAlreadyExists = true;
                
            

            if (!keyAlreadyExists) 
                uniqueKeys[uniqueKeyIndex] = keys[i];
                uniqueKeyIndex++;
            
            keyAlreadyExists = false;
        
        return uniqueKeys;
    

有人可以帮忙编码吗?

【问题讨论】:

是的,你会有非常大的排列集。您可以使用 Map(如 TreeMap)将地图中的键存储为唯一字符串,并将地图的值存储为计数。或者,您可以创建自己的小型数据结构来存储名称/值信息。 3 的输出对于 Chief、accepted、Proposal 意味着什么?这是否意味着有 3 个句子在句子中出现这 3 个单词?大小写重要吗? 抱歉“首席接受提案”应为 5,“已接受首席提案”应为 3...将编辑 @JonathanGrey:为什么“首席接受提案”的值为 5? 可能是您应该考虑的一个问题,您打算如何处理这些排列?取决于此,您是否真的需要生成所有这些?给定一组维度,您能否构建一个带有显式接收器/顶部节点的图并对其进行操作,边表示出现次数 【参考方案1】:

您可以应用标准信息检索数据结构,尤其是倒排索引。这是你的做法。

考虑您的原始句子。用一些整数标识符对它们进行编号,如下所示:

    “201 号提案今天已被酋长接受。”, “根据最近的首席决定,接受提案 214 和 221”, “此提议已被酋长接受。”, “提案 3 MazerNo 和补丁 4 均已被酋长接受。”, “提议 214,ValueMania,已被酋长接受。”

对于您在句子中遇到的每一对单词,将其添加到倒排索引中,该倒排索引会将这对单词映射到一组句子标识符(一组唯一项)。对于一个长度为 N 的句子,有 N-choose-2 对。

适当的 Java 数据结构将是 Map&lt;String, Map&lt;String, Set&lt;Integer&gt;&gt;。按字母顺序排列这些对,这样“has”和“Proposal”对将仅作为 ("has", "Proposal") 而不是 ("Proposal", "has") 出现。

此地图将包含以下内容:

"has", "Proposal" --> Set(1, 5)
"accepted", "Proposal" --> Set(1, 2, 5)
"accepted", "has" --> Set(1, 3, 5)
etc.

例如,单词对“has”和“Proposal”有一组 (1, 5),表示它们出现在句子 1 和 5 中。

现在假设您要查找“accepted”、“has”和“Proposal”列表中单词的共现次数。从此列表中生成所有对并与它们各自的列表相交(使用 Java 的 Set.retainAll())。这里的结果将最终设置为 (1, 5)。它的大小是2,意思是有两个句子包含“accepted”、“has”和“Proposal”。

要生成所有对,只需根据需要遍历您的地图。要生成大小为 N 的所有单词元组,您需要迭代并根据需要使用递归。

【讨论】:

以上是关于句子中的单词共现的主要内容,如果未能解决你的问题,请参考以下文章

如何存储句子中的单词

Lc5413_重新排列句子中的单词

Lc5413_重新排列句子中的单词

如何让 Python 循环遍历句子,但它给了我句子中的单词而不是句子中的每个字母? [复制]

javascript 在句子中反转单词并维持句子中的顺序

使用python将句子中的每个单词替换为单词索引