J'essaie d'utiliser le wrapper python autour de Word2vec. J'ai un mot d'intégration ou un groupe de mots qui peuvent être vus ci-dessous et à partir d'eux j'essaie de déterminer quels sont les deux mots qui se ressemblent le plus.

Comment puis-je faire ceci?

['architecte', 'infirmière', 'chirurgien', 'grand-mère', 'papa']

4
Kann 15 mars 2019 à 20:49

2 réponses

Meilleure réponse

La réponse de @ rylan-feldspar est généralement la bonne approche et fonctionnera, mais vous pourriez le faire un peu plus compactement en utilisant des bibliothèques / idiomes Python standard, en particulier itertools, une compréhension de liste et des fonctions de tri.

Par exemple, utilisez d'abord combinations() à partir de itertools pour générer toutes les paires de vos mots candidats:

from itertools import combinations
candidate_words = ['architect', 'nurse', 'surgeon', 'grandmother', 'dad']
all_pairs = combinations(candidate_words, 2)

Décorez ensuite les paires avec leur similitude par paire:

scored_pairs = [(w2v_model.wv.similarity(p[0], p[1]), p)
                for p in all_pairs]

Enfin, triez pour placer la paire la plus similaire en premier et signalez ce score et cette paire:

sorted_pairs = sorted(scored_pairs, reverse=True)
print(sorted_pairs[0])  # first item is most-similar pair

Si vous vouliez être compact mais un peu moins lisible, ce pourrait être un (long) "1-liner":

print(sorted([(w2v_model.wv.similarity(p[0], p[1]), p) 
              for p in combinations(candidate_words, 2)
             ], reverse=True)[0])

Mise à jour:

En intégrant la suggestion de @ ryan-feldspar à propos de max(), et en optant pour la minimalité, cela devrait également fonctionner pour signaler la meilleure paire (mais pas son score):

print(max(combinations(candidate_words, 2),
          key=lambda p:w2v_model.wv.similarity(p[0], p[1])))
2
gojomo 16 mars 2019 à 01:51

Étant donné que vous utilisez word2vec de gensim, selon votre commentaire:

Chargez ou entraînez le modèle pour vos plongées puis, sur votre modèle, vous pouvez appeler:

min_distance = float('inf')
min_pair = None
word2vec_model_wv = model.wv  # Unsure if this can be done in the loop, but just to be safe efficiency-wise
for candidate_word1 in words:
    for candidate_word2 in words:
        if candidate_word1 == candidate_word2:
            continue  # ignore when the two words are the same

        distance = word2vec_model_wv.distance(candidate_word1, candidate_word2)
        if distance < min_distance:
            min_pair = (candidate_word1, candidate_word2)
            min_distance = distance

https://radimrehurek.com/gensim/models/keyedvectors.html#gensim.models.keyedvectors.WordEmbeddingsKeyedVectors.distance

Cela pourrait aussi être une similitude (je ne suis pas tout à fait sûr s'il y a une différence). https://radimrehurek.com/gensim/models/ keyedvectors.html#gensim.models.keyedvectors.WordEmbeddingsKeyedVectors.similarity

Si la similitude devient plus grande avec des mots plus proches, comme je m'y attendais, alors vous voudrez maximiser pas minimiser et simplement remplacer les appels de fonction de distance par des appels de similitude. Fondamentalement, ce n'est que la simple fonction min / max sur les paires.

2
Sylex 15 mars 2019 à 18:24