7

我的数据库中有一个大表,其中包含来自文本顺序中各种文本的大量单词。我想找出某组单词一起出现的次数/频率。

示例:假设我在许多文本中有这 4 个单词:United | States | of | America. 我会得到结果:

美国: 50
美国: 45
美国: 40

(这只是一个4个单词的例子,但可以有少于和多于4个)。

有一些算法可以做到这一点或类似的吗?

编辑:欢迎使用一些显示如何操作的 R 或 SQL 代码。我需要一个实际的例子来说明我需要做什么。

表结构

我有两张桌子:Tokenwhich hassidtext. 文本是 is UNIQUE,并且该表中的每个入口代表一个不同的单词。

TextBlockHasToken是保持文本顺序的表格。每行代表文本中的一个单词。

textblockid具有令牌所属的文本块。sentence那就是token的句子,position就是token在句子里面的位置tokenid,就是token表的引用。

4

4 回答 4

14

它被称为 N-gram;在你的情况下是 4 克。它确实可以作为马尔可夫链的副产品获得,但您也可以使用滑动窗口(大小 4)在更新 4 维“直方图”时浏览(线性)文本。

更新 2011-11-22:马尔可夫链是一种在给定当前状态的情况下对切换到新状态的概率进行建模的方法。这是“状态机”的随机等价物。在自然语言的情况下,“状态”由“前 N 个词”形成,这意味着您将先验概率(在前 N 个词之前)视为 equal_to_one。计算机人员很可能会在 NLP 案例中使用树来实现马尔可夫链。“状态”只是从根到当前节点的路径,words_to_follow 的概率是当前节点后代的概率。但是每次我们选择一个新的子节点时,我们实际上向下移动了树,并“忘记”了根节点,out window只有N个字宽,

你可以很容易地看到,如果你像这样走一个马尔可夫链/树,在任何时候第一个词之前的概率是 1,第一个词之后的概率是 P(w1),第二个词之后 = P(w2) || w1 等因此,在处理语料库时,您会构建马尔可夫树(:= 更新节点中的频率),在骑行结束时,您可以通过 freq(word) / SUM 估计给定单词选择的概率(频率(兄弟姐妹))。对于树 5 深的单词,这是给定前 4 个单词的单词的概率。如果你想要 N-gram 概率,你想要从根到最后一个单词的路径中所有概率的乘积。

于 2011-11-09T18:23:00.583 回答
4

这是马尔可夫链的典型用例。从您的文本库中估计马尔可夫模型并在转换表中找到高概率。由于这些表示一个词跟随另一个词的概率,因此短语将显示为高转换概率。

通过计算短语起始词在文本中出现的次数,您还可以得出绝对数字。

于 2011-11-09T18:14:17.577 回答
2

Here is a small snippet that calculates all combinations/ngrams of a text for a given set of words. In order to work for larger datasets it uses the hash library, though it is probably still pretty slow...

require(hash)

get.ngrams <- function(text, target.words) {
  text <- tolower(text)
  split.text <- strsplit(text, "\\W+")[[1]]
  ngrams <- hash()
  current.ngram <- ""
  for(i in seq_along(split.text)) {
    word <- split.text[i]
    word_i <- i
    while(word %in% target.words) {
      if(current.ngram == "") {
        current.ngram <- word
      } else {
        current.ngram <- paste(current.ngram, word)
      }
      if(has.key(current.ngram, ngrams)) {
        ngrams[[current.ngram]] <- ngrams[[current.ngram]] + 1
      } else{
        ngrams[[current.ngram]] <- 1
      }
      word_i <- word_i + 1
      word <- split.text[word_i]
    }
    current.ngram <- ""
  }
  ngrams
}

So the following input ...

some.text <- "He states that he loves the United States of America,
 and I agree it is nice in the United States."
some.target.words <- c("united", "states", "of", "america")

usa.ngrams <- get.ngrams(some.text, some.target.words)

... would result in the following hash:

>usa.ngrams
<hash> containing 10 key-value pair(s).
  america : 1
  of : 1
  of america : 1
  states : 3
  states of : 1
  states of america : 1
  united : 2
  united states : 2
  united states of : 1
  united states of america : 1

Notice that this function is case insensitive and registers any permutation of the target words, e.g:

some.text <- "States of united America are states"
some.target.words <- c("united", "states", "of", "america")
usa.ngrams <- get.ngrams(some.text, some.target.words)

...results in:

>usa.ngrams
<hash> containing 10 key-value pair(s).
  america : 1
  of : 1
  of united : 1
  of united america : 1
  states : 2
  states of : 1
  states of united : 1
  states of united america : 1
  united : 1
  united america : 1
于 2011-11-21T11:09:26.520 回答
1

我不确定它是否对你有帮助,但这是我大约一年前写的一个小 Python 程序,它计算 N-grams(嗯,只有 mono-、bi- 和 trigrams)。(它还计算每个 N-gram 的熵)。我用它来计算大文本中的那些 N-gram。 关联

于 2011-11-16T19:52:05.813 回答