web-dev-qa-db-fra.com

Former des bigrammes de mots dans une liste de phrases avec Python

J'ai une liste de phrases:

text = ['cant railway station','citadel hotel',' police stn']. 

Je dois former des paires bigrammes et les stocker dans une variable. Le problème est que lorsque je fais cela, je reçois une paire de phrases au lieu de mots. Voici ce que j'ai fait: 

text2 = [[Word for Word in line.split()] for line in text]
bigrams = nltk.bigrams(text2)
print(bigrams)

qui donne 

[(['cant', 'railway', 'station'], ['citadel', 'hotel']), (['citadel', 'hotel'], ['police', 'stn'])

La gare et l'hôtel de la citadelle ne peuvent pas former un seul bigram. Ce que je veux c'est 

[([cant],[railway]),([railway],[station]),([citadel,hotel]), and so on...

Le dernier mot de la première phrase ne doit pas fusionner avec le premier mot de la deuxième phrase .Que dois-je faire pour que cela fonctionne?

14
Hypothetical Ninja

Utilisation de liste compréhensions et Zip :

>>> text = ["this is a sentence", "so is this one"]
>>> bigrams = [b for l in text for b in Zip(l.split(" ")[:-1], l.split(" ")[1:])]
>>> print(bigrams)
[('this', 'is'), ('is', 'a'), ('a', 'sentence'), ('so', 'is'), ('is', 'this'), ('this',     
'one')]
32
butch

Plutôt que de transformer votre texte en listes de chaînes, commencez par chaque phrase séparément sous forme de chaîne. J'ai également supprimé la ponctuation et les mots vides. Supprimez simplement ces parties si elles ne vous concernent pas:

import nltk
from nltk.corpus import stopwords
from nltk.stem import PorterStemmer
from nltk.tokenize import WordPunctTokenizer
from nltk.collocations import BigramCollocationFinder
from nltk.metrics import BigramAssocMeasures

def get_bigrams(myString):
    tokenizer = WordPunctTokenizer()
    tokens = tokenizer.tokenize(myString)
    stemmer = PorterStemmer()
    bigram_Finder = BigramCollocationFinder.from_words(tokens)
    bigrams = bigram_Finder.nbest(BigramAssocMeasures.chi_sq, 500)

    for bigram_Tuple in bigrams:
        x = "%s %s" % bigram_Tuple
        tokens.append(x)

    result = [' '.join([stemmer.stem(w).lower() for w in x.split()]) for x in tokens if x.lower() not in stopwords.words('english') and len(x) > 8]
    return result

Pour l'utiliser, faites comme ça:

for line in sentence:
    features = get_bigrams(line)
    # train set here

Notez que cela va un peu plus loin et marque statistiquement les bigrammes (ce qui sera utile pour la formation du modèle).

6
Dan

Sans nltk:

ans = []
text = ['cant railway station','citadel hotel',' police stn']
for line in text:
    arr = line.split()
    for i in range(len(arr)-1):
        ans.append([[arr[i]], [arr[i+1]]])


print(ans) #prints: [[['cant'], ['railway']], [['railway'], ['station']], [['citadel'], ['hotel']], [['police'], ['stn']]]
4
alfasin
from nltk import Word_tokenize 
from nltk.util import ngrams


text = ['cant railway station', 'citadel hotel', 'police stn']
for line in text:
    token = nltk.Word_tokenize(line)
    bigram = list(ngrams(token, 2)) 

    # the '2' represents bigram...you can change it to get ngrams with different size
3
gurinder
>>> text = ['cant railway station','citadel hotel',' police stn']
>>> bigrams = [(ele, tex.split()[i+1]) for tex in text  for i,ele in enumerate(tex.split()) if i < len(tex.split())-1]
>>> bigrams
[('cant', 'railway'), ('railway', 'station'), ('citadel', 'hotel'), ('police', 'stn')]

Utilisation de la fonction énumérer et diviser.

1
Tanveer Alam

Juste réparer le code de Dan:

def get_bigrams(myString):
    tokenizer = WordPunctTokenizer()
    tokens = tokenizer.tokenize(myString)
    stemmer = PorterStemmer()
    bigram_Finder = BigramCollocationFinder.from_words(tokens)
    bigrams = bigram_Finder.nbest(BigramAssocMeasures.chi_sq, 500)

    for bigram_Tuple in bigrams:
        x = "%s %s" % bigram_Tuple
        tokens.append(x)

    result = [' '.join([stemmer.stem(w).lower() for w in x.split()]) for x in tokens if x.lower() not in stopwords.words('english') and len(x) > 8]
    return result
1
Jay Marm

Lire le jeu de données

df = pd.read_csv('dataset.csv', skiprows = 6, index_col = "No")

Recueillir tous les mois disponibles

df["Month"] = df["Date(ET)"].apply(lambda x : x.split('/')[0])

Créez des jetons de tous les tweets par mois

tokens = df.groupby("Month")["Contents"].sum().apply(lambda x : x.split(' '))

Créer des bigrammes par mois

bigrams = tokens.apply(lambda x : list(nk.ngrams(x, 2)))

Comptez les bigrammes par mois

count_bigrams = bigrams.apply(lambda x : list(x.count(item) for item in x))

Envelopper le résultat dans des cadres de données propres

month1 = pd.DataFrame(data = count_bigrams[0], index= bigrams[0], columns= ["Count"])
month2 = pd.DataFrame(data = count_bigrams[1], index= bigrams[1], columns= ["Count"])
0
avi

Il y a un nombre de façons pour le résoudre mais j'ai résolu de cette façon:

>>text = ['cant railway station','citadel hotel',' police stn']
>>text2 = [[Word for Word in line.split()] for line in text]
>>text2
[['cant', 'railway', 'station'], ['citadel', 'hotel'], ['police', 'stn']]
>>output = []
>>for i in range(len(text2)):
    output = output+list(bigrams(text2[i]))
>>#Here you can use list comphrension also
>>output
[('cant', 'railway'), ('railway', 'station'), ('citadel', 'hotel'), ('police', 'stn')]
0
saicharan