我的问题在概念上类似于解决字谜,除了我不能只使用字典查找.我试图找到合理的词而不是真实的词.
我已经基于一堆文本中的字母创建了一个N-gram模型(现在,N = 2).现在,给定一个随机的字母序列,我想根据转移概率将它们置于最可能的序列中.我认为在开始时我需要维特比算法,但随着我看起来更深入,维特比算法根据观察到的输出优化了一系列隐藏的随机变量.我正在尝试优化输出序列.
有没有一个众所周知的算法,我可以阅读?或者我是否与Viterbi走在正确的轨道上,我只是没有看到如何应用它?
更新
我已经添加了一笔赏金来要求更深入地了解这个问题.(分析解释为什么不能采用有效的方法,除模拟退火之外的其他启发式/近似等)
algorithm machine-learning mathematical-optimization markov n-gram
我编写了以下用于计算字符双字母的代码,输出就在下面.我的问题是,如何获得排除最后一个字符(即t)的输出?有没有更快更有效的计算字符n-gram的方法?
b='student'
>>> y=[]
>>> for x in range(len(b)):
n=b[x:x+2]
y.append(n)
>>> y
['st', 'tu', 'ud', 'de', 'en', 'nt', 't']
Run Code Online (Sandbox Code Playgroud)
这是我想得到的结果:['st','tu','ud','de','nt]
提前感谢您的建议.
k skipgram是ngram,它是所有ngrams和每个(ki)skipgram的超集,直到(ki)== 0(包括0跳过克).那么如何在python中有效地计算这些跳过头文件呢?
以下是我尝试的代码,但它没有按预期执行:
<pre>
input_list = ['all', 'this', 'happened', 'more', 'or', 'less']
def find_skipgrams(input_list, N,K):
bigram_list = []
nlist=[]
K=1
for k in range(K+1):
for i in range(len(input_list)-1):
if i+k+1<len(input_list):
nlist=[]
for j in range(N+1):
if i+k+j+1<len(input_list):
nlist.append(input_list[i+k+j+1])
bigram_list.append(nlist)
return bigram_list
</pre>
Run Code Online (Sandbox Code Playgroud)
上面的代码无法正确呈现,但print find_skipgrams(['all', 'this', 'happened', 'more', 'or', 'less'],2,1)提供以下输出
[['this','发生','更多'],['发生','更多','或',['更多','或','更少'],['或','更少'',['less'],['发生','更多','或'],['更多','或','更少',['或','更少'],['更少'], ['减']]
此处列出的代码也没有给出正确的输出:https: //github.com/heaven00/skipgram/blob/master/skipgram.py
print skipgram_ndarray("你叫什么名字")给出:['什么,是','是,你的','你的名字','名字','什么,你的','是,名字']
名字是一个unigram!
我想用n-gram(最好用PHP)实现一些应用程序.
哪种类型的n-gram更适合大多数用途?单词级别或字符级别n-gram?你怎么能在PHP中实现一个n-gram-tokenizer?
首先,我想知道N-gram到底是什么.它是否正确?这就是我理解n-gram的方式:
句子:"我住在纽约."
单词级别的双字母(n为2):"#I","我活着","住在纽约","NY#"
字符级别双字母(n为2):"#I","I#","#l","li","iv","ve","e#","#i","in"," n#","#N","NY","Y#"
如果你有这个n-gram-parts数组,你可以删除重复的数组并为每个给出频率的部分添加一个计数器:
单词级别双字母:[1,1,1,1,1]
字符级别的双字母:[2,1,1,...]
它是否正确?
此外,我想了解更多关于你可以用n-gram做什么:
您如何看待我的应用方法,特别是最后一个?
我希望你能帮助我.提前致谢!
我正在使用NLTK在语料库中搜索n-gram,但在某些情况下需要很长时间.我注意到计算n-gram在其他包中并不常见(显然Haystack有一些功能).这是否意味着如果我放弃NLTK,我的语料库中有更快的方法可以找到n-gram?如果是这样,我可以用什么来加快速度?
我正在寻找一个库或使用现有库的方法(difflib,fuzzywuzzy,python-levenshtein)中查找的字符串(的最接近的匹配query)文本(corpus)
我开发了一个基于的方法difflib,我将其corpus分成大小n(长度query)的ngrams .
import difflib
from nltk.util import ngrams
def get_best_match(query, corpus):
ngs = ngrams( list(corpus), len(query) )
ngrams_text = [''.join(x) for x in ngs]
return difflib.get_close_matches(query, ngrams_text, n=1, cutoff=0)
Run Code Online (Sandbox Code Playgroud)
当查询和匹配字符串之间的差异只是字符替换时,它可以按我的意愿工作.
query = "ipsum dolor"
corpus = "lorem 1psum d0l0r sit amet"
match = get_best_match(query, corpus)
# match = "1psum d0l0r"
Run Code Online (Sandbox Code Playgroud)
但是当差异是字符删除时,它不是.
query = "ipsum dolor"
corpus = "lorem 1psum dlr sit …Run Code Online (Sandbox Code Playgroud) 我有这个例子,我想知道如何得到这个结果.我有文字,我对它进行了标记,然后我收集了二元组和三元组以及四元组
import nltk
from nltk import word_tokenize
from nltk.util import ngrams
text = "Hi How are you? i am fine and you"
token=nltk.word_tokenize(text)
bigrams=ngrams(token,2)
Run Code Online (Sandbox Code Playgroud)
二元语法: [('Hi', 'How'), ('How', 'are'), ('are', 'you'), ('you', '?'), ('?', 'i'), ('i', 'am'), ('am', 'fine'), ('fine', 'and'), ('and', 'you')]
trigrams=ngrams(token,3)
Run Code Online (Sandbox Code Playgroud)
八卦: [('Hi', 'How', 'are'), ('How', 'are', 'you'), ('are', 'you', '?'), ('you', '?', 'i'), ('?', 'i', 'am'), ('i', 'am', 'fine'), ('am', 'fine', 'and'), ('fine', 'and', 'you')]
bigram [(a,b) (b,c) (c,d)]
trigram [(a,b,c) (b,c,d) (c,d,f)]
i want the …Run Code Online (Sandbox Code Playgroud) 我有3,000,000行的巨大文件,每行有20-40个单词.我必须从语料库中提取1到5个ngrams.我的输入文件是标记化的纯文本,例如:
This is a foo bar sentence .
There is a comma , in this sentence .
Such is an example text .
Run Code Online (Sandbox Code Playgroud)
目前,我正在执行以下操作,但这似乎不是提取1-5grams的有效方法:
#!/usr/bin/env python -*- coding: utf-8 -*-
import io, os
from collections import Counter
import sys; reload(sys); sys.setdefaultencoding('utf-8')
with io.open('train-1.tok.en', 'r', encoding='utf8') as srcfin, \
io.open('train-1.tok.jp', 'r', encoding='utf8') as trgfin:
# Extract words from file.
src_words = ['<s>'] + srcfin.read().replace('\n', ' </s> <s> ').split()
del src_words[-1] # Removes the final '<s>'
trg_words = ['<s>'] + trgfin.read().replace('\n', ' …Run Code Online (Sandbox Code Playgroud) 什么算法用于查找ngrams?
假设我的输入数据是一个单词数组和我想要找到的ngram的大小,我应该使用什么算法?
我要求代码,优先选择R.数据存储在数据库中,因此也可以是plgpsql函数.Java是我更熟悉的语言,因此我可以将其"翻译"为另一种语言.
我不是懒惰,我只是要求代码,因为我不想重新发明轮子试图做一个已经完成的算法.
编辑:重要的是知道每个n-gram出现多少次.
编辑2:N-GRAMS有一个R包吗?
编辑:新包text2vec非常好,并且很好地解决了这个问题(和许多其他问题).
关于github 插图的CRAN text2vec上的text2vec,用于说明ngram标记化
我在R中有一个非常大的文本数据集,我已将其作为字符向量导入:
#Takes about 15 seconds
system.time({
set.seed(1)
samplefun <- function(n, x, collapse){
paste(sample(x, n, replace=TRUE), collapse=collapse)
}
words <- sapply(rpois(10000, 3) + 1, samplefun, letters, '')
sents1 <- sapply(rpois(1000000, 5) + 1, samplefun, words, ' ')
})
Run Code Online (Sandbox Code Playgroud)
我可以将此字符数据转换为词袋表示,如下所示:
library(stringi)
library(Matrix)
tokens <- stri_split_fixed(sents1, ' ')
token_vector <- unlist(tokens)
bagofwords <- unique(token_vector)
n.ids <- sapply(tokens, length)
i <- rep(seq_along(n.ids), n.ids)
j <- match(token_vector, bagofwords)
M <- sparseMatrix(i=i, j=j, x=1L)
colnames(M) <- bagofwords
Run Code Online (Sandbox Code Playgroud)
所以R可以在大约3秒钟内将1,000,000,000个短句矢量化为一个单词表示形式(不错!):
> M[1:3, …Run Code Online (Sandbox Code Playgroud)