Je souhaite trouver la fréquence (en pourcentage) d'un ensemble de mots, comme dans n_grams apparaît dans une phrase.

example_txt= ["order intake is strong for Q4"]

def find_ngrams(text):
    text = re.findall('[A-z]+', text)
    content = [w for w in text if w.lower() in n_grams] # you can calculate %stopwords using "in"
    return round(float(len(content)) / float(len(text)), 5)

#the goal is for the above procedure to work on a pandas datafame, but for now lets use 'text' as an example.
#full_MD['n_grams'] = [find_ngrams(x) for x in list(full_MD.loc[:,'text_no_stopwords'])]

Ci-dessous, vous voyez deux exemples. Le premier fonctionne, le dernier non.

n_grams= ['order']
res = [find_ngrams(x) for x in list(example_txt)]
print(res)
Output:
[0.16667]

n_grams= ['order intake']
res = [find_ngrams(x) for x in list(example_txt)]
print(res)
Output:
[0.0]

Comment puis-je faire en sorte que la fonction find_ngrams () traite les bigrammes, pour que le dernier exemple ci-dessus fonctionne?

Edit: D'autres idées?

0
doomdaam 8 avril 2020 à 13:04

3 réponses

Meilleure réponse

Vous pouvez utiliser SpaCy Matcher:

import spacy
from spacy.matcher import Matcher

nlp = spacy.load("en_core_web_sm")
matcher = Matcher(nlp.vocab)
# Add match ID "orderintake" with no callback and one pattern
pattern = [{"LOWER": "order"}, {"LOWER": "intake"}]
matcher.add("orderintake", None, pattern)

doc = nlp("order intake is strong for Q4")
matches = matcher(doc)
print(len(matches)) #Number of times the bi-gram appears in text
1
arpitrathi 10 avril 2020 à 14:50

Vous avez peut-être déjà exploité cette option, mais pourquoi ne pas utiliser le simple .count combiné avec len:

(example_txt[0].count(n_grams[0]) * len(n_grams[0])) / len(example_txt[0]) 

Ou si vous n'êtes pas intéressé par les espaces dans le cadre de votre calcul, vous pouvez utiliser les éléments suivants:

(example_txt[0].count(n_grams[0])* len(n_grams[0])) / len(example_txt[0].replace(' ',''))

Bien sûr, vous pouvez les utiliser dans une liste de compréhension, c'était juste à des fins de démonstration


0
emiljoj 8 avril 2020 à 10:22

La ligne

re.findall('[A-z]+', text)

Retour

['order', 'intake', 'is', 'strong', 'for', 'Q'].

Pour cette raison, la chaîne «prise de commande» ne sera pas mise en correspondance dans votre ici:

content = [w for w in text if w.lower() in n_grams]

Si vous voulez qu'il corresponde, vous devrez créer un seul string de chaque Bigram.

Au lieu de cela, vous devriez probablement utiliser this pour trouver des Bigrams.

Pour les N-grammes, consultez cette réponse.

0
Matheus Torquato 8 avril 2020 à 10:26