Estou procurando uma maneira de dividir um texto em n gramas. Normalmente eu faria algo como:
import nltk
from nltk import bigrams
string = "I really like python, it's pretty awesome."
string_bigrams = bigrams(string)
print string_bigrams
Estou ciente de que o nltk oferece apenas bigrams e trigramas, mas existe uma maneira de dividir meu texto em quatro gramas, cinco gramas ou mesmo cem gramas?
Obrigado!
ingrams
cujo segundo parâmetro é o grau dos ngrams que você deseja. É ESTA a versão do nltk você está usando? Mesmo se não, aqui está a fonte EDIT: Existengrams
eingrams
existeingrams
um gerador.Respostas:
Ótimas respostas nativas baseadas em python fornecidas por outros usuários. Mas aqui está a
nltk
abordagem (por precaução, o OP é penalizado por reinventar o que já existe nanltk
biblioteca).Existe um módulo ngram que as pessoas raramente usam
nltk
. Não é porque é difícil ler ngrams, mas treinar uma base de modelo em ngrams em que n> 3 resultará em muita escassez de dados.fonte
sixgrams
?Estou surpreso que isso ainda não tenha aparecido:
fonte
Usando apenas ferramentas nltk
Saída de exemplo
Para manter os ngrams no formato array, basta remover
' '.join
fonte
aqui está outra maneira simples de fazer n-gramas
fonte
As pessoas já responderam muito bem ao cenário em que você precisa de bigrams ou trigramas, mas se você precisar de everygram para a frase, nesse caso, poderá usar
nltk.util.everygrams
No caso de você ter um limite, como no caso de trigramas, onde o comprimento máximo deve ser 3, você pode usar o parâmetro max_len para especificá-lo.
Você pode modificar o parâmetro max_len para obter qualquer grama, isto é, quatro gramas, cinco gramas, seis ou mesmo cem gramas.
As soluções mencionadas anteriormente podem ser modificadas para implementar a solução mencionada acima, mas essa solução é muito simples.
Para ler mais, clique aqui
E quando você só precisa de um grama específico, como bigram ou trigram, etc, pode usar os nltk.util.ngrams, como mencionado na resposta do MAHassan.
fonte
Você pode facilmente criar sua própria função para fazer isso usando
itertools
:fonte
izip(*(islice(seq, index, None) for index, seq in enumerate(tee(s, N))))
eu não entendo direito?Uma abordagem mais elegante para criar bigrams com o python embutido
zip()
. Simplesmente converta a string original em uma lista porsplit()
, depois passe a lista uma vez normalmente e uma vez deslocada por um elemento.fonte
Eu nunca lidei com o nltk, mas fiz N-gramas como parte de algum projeto de classe pequena. Se você deseja encontrar a frequência de todos os N-gramas que ocorrem na string, aqui está uma maneira de fazer isso.
D
daria a você o histograma de suas N-palavras.fonte
collections.Counter(tuple(strparts[i:i+N]) for i in xrange(len(strparts)-N))
vai trabalhar mais rápido do que o try-exceptoPara four_grams, ele já está no NLTK , aqui está um pedaço de código que pode ajudá-lo nesse sentido:
Espero que ajude.
fonte
Você pode usar sklearn.feature_extraction.text.CountVectorizer :
saídas:
Você pode definir
ngram_size
como qualquer número inteiro positivo. Ou seja, você pode dividir um texto em quatro gramas, cinco gramas ou até cem gramas.fonte
Se a eficiência é um problema e você precisa criar vários n-gramas diferentes (até cem, como você diz), mas você deseja usar python puro, eu faria:
Uso:
~ Mesma velocidade que o NLTK:
Repost da minha resposta anterior .
fonte
Nltk é ótimo, mas às vezes é uma sobrecarga para alguns projetos:
Exemplo de uso:
fonte
Você pode obter todos os 4-6 gramas usando o código sem outro pacote abaixo:
a saída está abaixo:
você pode encontrar mais detalhes neste blog
fonte
Após cerca de sete anos, eis uma resposta mais elegante usando
collections.deque
:Resultado:
fonte
Se você deseja uma solução pura de iterador para cadeias grandes com uso constante de memória:
Teste:
Resultado:
fonte