[PYTHON] [Pour les débutants] Quantifier la similitude des phrases avec TF-IDF

0. en bref

    1. ** TF-IDF ** est un bon moyen de quantifier facilement la similitude des phrases.
  1. La similitude est calculée en multipliant la fréquence (** TF ) des mots figurant dans la phrase par la rareté ( IDF **).
    1. Si la commodité est importante, ** janome ** est recommandé de ** Mecab ** pour l'analyse morphologique, et ** TF-IDF ** est recommandé de ** doc2vec ** pour le jugement de similarité. ⇒ ** Je pense que cela sera utile pour quantifier le degré de similitude avec la littérature antérieure en recherche de brevets et pour évaluer objectivement les réponses aux questions descriptives du test commun d'entrée à l'université. ** Cependant, il ne peut être jugé que si une personne le lit si la phrase a un sens ou non. Eh bien, bien sûr (rires)

1. 1. Sensibilisation aux problèmes

Quand je lis une phrase, je pense parfois que c'est une phrase similaire. ** TF-IDF ** est un moyen pratique d'exprimer objectivement le vague sentiment d'être similaire. Il existe un site qui explique TF-IDF d'une manière facile à comprendre, donc s'il vous plaît google. Si vous augmentez le site recommandé, ce sera comme suit. [Pour les débutants] J'ai brièvement résumé TFIDF

Le point est (1) si le mot qui apparaît fréquemment dans une certaine phrase (** TF: Term Frequency frequency ), (2) s'il s'agit d'un mot rare qui n'apparaît pas souvent dans les phrases ordinaires ( IDF: Inverse) Document Frequency Rarity **), partant de l'idée que la phrase est un sujet lié au mot. L'idée de base de TF-IDF est de comparer la somme de TF et IDF du mot et de juger de la similitude sous forme de phrase.

2. Préparation

Eh bien, cela ne démarre pas même si je dis désordre, alors calculons en utilisant ** scikit-learn (sklearn) **, qui est souvent utilisé pour faire des choses de type IA avec Python. Préparez-vous d'abord.

import numpy as np
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity

Dans le calcul de TF-IDF, ** CountVectorizer ** et ** TfidfTransformer ** peuvent être utilisés en combinaison à la place du ** TfidfVectorizer ** décrit ci-dessus (je l'essayerai plus tard). Lors de la combinaison, la fréquence des mots est vectorisée avec CountVectorizer, puis TF-IDF est calculée avec TfidfTransformer. Cependant, si vous voulez calculer TF-IDF, il est plus facile de calculer avec TfidfVectorizer à la fois, j'ai donc utilisé TfidfVectorizer cette fois. Les résultats étaient légèrement différents entre le cas utilisant TfidfVectorizer et le cas utilisant CountVectorizer et TfidfTransformer (les détails seront décrits plus loin). Je pense que c'est à cause des paramètres, mais malheureusement, la raison est inconnue. Si vous le savez, veuillez commenter. Le degré de similitude est obtenu en calculant le ** cosinus cos ** du vecteur dans chaque cas.

Ensuite, lorsqu'il s'agit de japonais, une analyse morphologique est nécessaire. En anglais, les mots sont séparés, donc il peut être analysé tel quel, mais en japonais, les mots sont joints de manière transparente dans la phrase, il est donc nécessaire de séparer chaque mot. La célèbre analyse morphologique est ** Mecab ** en python, mais ** janome ** est facile à manipuler, donc j'utiliserai ** janome ** cette fois.

from janome.tokenizer import Tokenizer

3. 3. Cible d'analyse

C'est une phrase à comparer, mais essayons d'utiliser des informations faciles à comprendre. Essayons de nous concentrer sur votre football préféré avec votre propre jugement et vos propres préjugés. La première phrase est la nouvelle que le frontale de tête a battu le deuxième Celeso.

text1.txt


Kawasaki F, 2e place C Battez 3 tirs et courez seul! 8 victoires consécutives qui élargissent la différence de points à "14"
La 20e manche de la Ligue Meiji Yasuda Seimei J1 a eu lieu le 3, et Celeso Osaka a accueilli Kawasaki Frontale chez lui, le Yanmar Stadium Nagai.
Kawasaki F (53 points) et C Osaka (42 points) se poursuivent après 20 matchs jusqu'à présent. Home C Osaka a remporté les trois premiers matchs de la section précédente, tandis que Kawasaki F a affronté cette confrontation au sommet avec un élan écrasant en remportant sept matchs consécutifs.

Ensuite, utilisons une autre actualité avec le même contenu. Faisons des hypothèses et testons la similitude entre les deux premiers reportages.

text2.txt


La différence de points est de 14 ... 8 victoires consécutives sur Kawasaki F et C Osaka!!
La J1 League a tenu la 20e manche le 3, et Celeso Osaka, qui a terminé deuxième au Yanmar Stadium Nagai(42 points)Kawasaki Frontale est en tête avec 11 points d'écart(53 points)Est un match. Kawasaki F a pris la tête avec un but contre son camp à la 37e minute de la première mi-temps, mais C Osaka a rattrapé le score du FW Hiroaki Okuno à la 17e minute de la seconde période. Cependant, à la 38e minute FW Leandro Damian et à la 39e minute MF Mitsuka Kaoru a secoué le filet en succession rapide, et Kawasaki F a obtenu 3-J'en ai gagné un.

La troisième est la même actualité de football, mais avec un contenu différent.

text3.txt


G Osaka, Yasuhito Endo, transféré à Iwata! "Les relations humaines avec le réalisateur Miyamoto" derrière "décision"
Gamba Osaka a rapporté par certains journaux sportifs et le transfert de la légende de l'équipe nationale japonaise Yasuhito Endo au J2 Iwata pour une durée limitée. Dès que cette nouvelle est sortie, non seulement les supporters de G Osaka mais aussi de nombreux fans de football ont été surpris sur Internet. En parlant d'Endo, il est actif en tant que pilier de G Osaka depuis 2001, date de son transfert de Kyoto. En tant que n ° 7 du G Osaka, en tant que tour de commandement, il a contribué à tous les titres remportés par l'équipe en tant que joueur principal.

Aussi, le genre est le même dans le sport, mais comparons-le avec l'actualité du baseball.

text4.txt


Maintenant hors FA Masahiro Tanaka est "un lanceur qui vaut la peine"
Le Yankees Masahiro Tanaka, qui deviendra agent libre (FA) après la fin de cette saison, a été exprimé très tôt par l'équipe et les médias locaux lui demandant de rester. Le bras droit, qui avait montré un chef-d'œuvre en séries éliminatoires jusqu'à la saison dernière, a débuté au deuxième tour de la série wild card avec les Indiens le 30 septembre (1ère fois au Japon). Dans les mauvaises conditions de pluie, il a eu du mal avec 6 buts en 4e manche, mais l'équipe dans son ensemble a décidé de se qualifier pour la série du district.

Enfin, les nouvelles sont des nouvelles, mais un genre complètement différent.

text5.txt


[New Corona] Président américain hospitalisé, «Cluster» de la Maison Blanche et OMS
Le président américain Trump est arrivé au centre médical Walter Reed près de Washington le 2 de la Maison Blanche à bord d'un hélicoptère présidentiel pour recevoir un traitement pour une nouvelle infection à coronavirus (COVID19). Cela suggère une inquiétude généralisée quant à la gravité de la maladie.

Les phrases ci-dessus seront reprises et analysées. Le degré de similitude avec la phrase 1 devrait être la phrase 2> la phrase 3> la phrase 4> la phrase 5. Eh bien, est-ce que ce sera vrai?

4. Essayer

Tout d'abord, lisez le texte. N'oubliez pas d'effectuer une analyse morphologique.

filenames=['text1.txt','text2.txt','text3.txt','text4.txt','text5.txt']
wakati_list = []
for filename in filenames: #Lire un fichier texte et l'affecter au texte
    with open(filename,mode='r',encoding = 'utf-8-sig') as f:
        text = f.read()    
    wakati = ''
    t = Tokenizer() 
    for token in t.tokenize(text):  #Analyse morphologique
        hinshi = (token.part_of_speech).split(',')[0]  #Informations sur les paroles des parties
        hinshi_2 = (token.part_of_speech).split(',')[1]
        if hinshi in ['nom']:  # 品詞がnomの場合のみ以下実行
            if not hinshi_2 in ['Vide','*']:  
            #Le deuxième élément des informations sur les paroles de la partie est-il vide?*Dans le cas de, ne pas exécuter ci-dessous
                word = str(token).split()[0]  #Obtenez le mot
                if not ',*,' in word:  #Au mot*Si n'est pas inclus, exécutez ce qui suit
                    wakati = wakati + word +' ' 
                    #Ajouter des mots et des espaces à l'objet wakati
    wakati_list.append(wakati) #Ajouter le résultat de la division à la liste
wakati_list_np = np.array(wakati_list) #Convertir la liste en ndarray

Enfin, le calcul de la similitude. Utilisons TfidfVectorizer.

vectorizer = TfidfVectorizer(token_pattern=u'\\b\\w+\\b')
transformer = TfidfTransformer()#Génération de transformateur. TF-Utiliser IDF
tf = vectorizer.fit_transform(wakati_list_np) #Vectorisation
tfidf = transformer.fit_transform(tf) # TF-IDF
tfidf_array = tfidf.toarray()
cs = cosine_similarity(tfidf_array,tfidf_array)  #calcul de similarité cos
print(cs)

Les résultats sont les suivants. L'ampleur relative de la similitude est, bien entendu, comme prévu.

[[1.         0.48812198 0.04399067 0.02065671 0.00164636]
 [0.48812198 1.         0.02875532 0.01380959 0.00149348]
 [0.04399067 0.02875532 1.         0.02595705 0.        ]
 [0.02065671 0.01380959 0.02595705 1.         0.00350631]
 [0.00164636 0.00149348 0.         0.00350631 1.        ]]

À propos, le cas de la combinaison de Count Vectorizer et de Tfidf Transformer écrit au début est le suivant. Vous devez l'importer avant de pouvoir l'utiliser.

from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer

#Générez un vectoriseur. jeton_pattern=u'\\b\\w+\\b'Paramètres qui incluent des mots d'une seule lettre dans
vectorizer = CountVectorizer(token_pattern=u'\\b\\w+\\b')
#Génération de transformateur. TF-Utiliser IDF
transformer = TfidfTransformer()
tf = vectorizer.fit_transform(wakati_list_np) #Vectorisation
tfidf = transformer.fit_transform(tf) # TF-IDF
tfidf_array = tfidf.toarray()
cs = cosine_similarity(tfidf_array,tfidf_array)  #calcul de similarité cos
print(cs)

Les résultats sont les suivants. Celui-ci a une valeur de similitude légèrement supérieure.

[[1.         0.59097619 0.07991729 0.03932476 0.00441963]
 [0.59097619 1.         0.05323053 0.03037231 0.00418569]
 [0.07991729 0.05323053 1.         0.03980858 0.        ]
 [0.03932476 0.03037231 0.03980858 1.         0.01072682]
 [0.00441963 0.00418569 0.         0.01072682 1.        ]]

5. finalement

Si vous voulez calculer la similitude en Python, ** doc2vec ** est également bon. Cependant, il est difficile de charger le modèle entraîné ici. En ce sens, je pense que ** TF-IDF ** devrait être capable de calculer facilement la similitude des phrases.

Pour le code, je me suis référé au site suivant. Nous aimerions profiter de cette occasion pour vous remercier.

Essayez différentes choses avec Python

Recommended Posts

[Pour les débutants] Quantifier la similitude des phrases avec TF-IDF
[Pour les débutants] Quantifier la similitude des phrases avec TF-IDF
Calculez la similitude entre les phrases avec Doc2Vec, une évolution de Word2Vec
La troisième nuit de la boucle avec pour
La deuxième nuit de la boucle avec pour
Ajouter des attributs d'objets de classe avec une instruction for
Vue d'ensemble de Docker (pour les débutants)
[Pour les débutants] Résumé de l'entrée standard en Python (avec explication)
[Python] Les principales faiblesses et inconvénients de Google Colaboratory [Pour les débutants]
L'histoire de la création d'un pilote standard pour db avec python.
Bases de Seaborn pour les débutants ① Graphique agrégé du nombre de données (Countplot)
Visualisez la fréquence des occurrences de mots dans les phrases avec Word Cloud. [Python]
Vérifiez la protection de la mémoire de Linux Kerne avec le code pour ARM
Mesurer la similitude du contenu avec Pyspark
4ème nuit de boucle avec pour
J'ai essayé d'exécuter le didacticiel TensorFlow avec des commentaires (_TensorFlow_2_0_Introduction pour les débutants)
Apprenez les bases de Python ① Débutants élémentaires
Explication d'approche pour que les débutants soient dans le top 1,5% (0,83732) dans Kaggle Titanic_3
Explication d'approche pour que les débutants soient dans le top 1,5% (0,83732) dans Kaggle Titanic_1
J'ai mesuré la vitesse de la notation d'inclusion de liste, pendant et pendant avec python2.7.
Explication d'approche pour que les débutants soient dans le top 1,5% (0,83732) dans Kaggle Titanic_2
INSÉRER dans MySQL avec Python [Pour les débutants]
Demandez Pi avec la commande bc
[Python] Compte-rendu de la réunion d'étude pour les débutants (7/15)
Alignez la taille de la barre de couleurs avec matplotlib
Défis de la compétition Titanic pour les débutants de Kaggle
Rechercher des fichiers avec l'extension spécifiée
Vérifier l'existence du fichier avec python
Pandas du débutant, par le débutant, pour le débutant [Python]
[Python] Lire des images avec OpenCV (pour les débutants)
Création WebApi avec Python (création CRUD) Pour les débutants
Compter le nombre de caractères avec écho
[Pour les débutants] Essayez le web scraping avec Python
Pour les débutants de SageMaker - Liens matériels -
Liste de contrôle pour éviter de transformer les éléments de array of numpy avec for
Alignez le nombre d'échantillons entre les classes de données pour l'apprentissage automatique avec Python
Un mémorandum de méthode souvent utilisé lors de l'analyse de données avec des pandas (pour les débutants)
[Introduction à Python] Comment obtenir l'index des données avec l'instruction for
Après avoir frappé l'API Qiita avec Python pour obtenir une liste d'articles pour les débutants, nous visiterons les articles divins
Les bases de Pandas pour les débutants ③ Créez un histogramme avec matplotlib
Le moyen le plus rapide pour les débutants de maîtriser Python
L'histoire de l'apprentissage profond avec TPU
Remarque: préparez l'environnement de CmdStanPy avec docker
L'histoire selon laquelle le coût d'apprentissage de Python est faible
Préparer l'environnement d'exécution de Python3 avec Docker
Raisonnement causal et recherche causale par Python (pour les débutants)
Mathématiques Todai 2016 résolues avec Python
[Note] Exportez le html du site avec python.
Présentation du modèle DCGAN pour Cifar 10 avec keras
Augmentez la taille de la police du graphique avec matplotlib
Visualisons l'état de l'infection par le virus corona avec Plotly [pour les débutants]
Calculez le nombre total de combinaisons avec python
Utilisez Logger avec Python pour le moment
Attention à la valeur de retour de __len__
Vérifiez la date du devoir de drapeau avec Python
J'ai joué avec Floydhub pour le moment
~ Conseils pour les débutants de Python donnés avec amour par Pythonista ① ~
Éliminez les inconvénients du widget QDock avec PySide
Renommer la balise avec un espace de noms en lxml
Compréhension facile de Python pour les tableaux et (pour les super débutants)