Différentes façons de calculer la similitude entre les données avec python

Il existe de nombreuses façons de calculer à quel point une donnée est similaire à une autre. http://wikiwiki.jp/cattail/?%CE%E0%BB%F7%C5%D9%A4%C8%B5%F7%CE%A5

Parmi eux, la distance euclidienne, le coefficient de corrélation du facteur de produit de Pearson et le coefficient de Jaccard sont implémentés en python. Programmation collective des connaissances Chapitre 2 Référence. https://www.oreilly.co.jp/books/9784873113647/

Distance euclidienne

Une distance générale similaire à celle des mathématiques du collège et du lycée. S'il est à 2 ou 3 dimensions, il peut être représenté par une figure et une image peut être créée, mais il n'est pas possible d'imaginer d'autres dimensions. Mais ce que je fais est fondamentalement le même que le troisième et inférieur.

(a_1, a_2, a_3, ... a_i), (b_1, b_2, b_3, ... b_i)

Lorsqu'il y a deux données telles que, la distance euclidienne d entre ab est

d = \sqrt{(a_1 - b_1)^2 + (a_2 -b_2)^2 + (a_3 -b_3)^2 + ...+(a_i-b_i)^2}

Si cela reste tel quel, la distance sera renvoyée, mais je veux une valeur facile à comprendre en tant que degré de similitude, par exemple plus les valeurs sont similaires de 0 à 1, plus elles sont proches de 1. Une telle valeur peut être obtenue en ajoutant 1 à ce d et en prenant le nombre inverse pour éviter une erreur de division à 0.

1/(1 + d)

Ce qui suit est l'implémentation de ceci en python.

recommendation.py


import math

def sim_distance(prefs, person1, person2):
    #Liste des choses que personne1 et personne2 évaluent
    si = {}

    for item in prefs[person1]:
        if item in prefs[person2]:
            si[item] = 1

    #La similitude est de 0 si ni personne1 ni personne2 ne sont
    if len(si) == 0 :
        return 0

    #Carré de différence pour chaque élément
    squares = [(prefs[person1][item] - prefs[person2][item]) ** 2 for item in si]
    sum_of_sqrt = math.sqrt(sum(squares))
    return 1/(1 + sum_of_sqrt)

Essayez de trouver la similitude en utilisant les données suivantes. critcs stocke plusieurs films et la note de 5 points de chaque personne pour ces films.

critics = {
    'Lisa Rose': {
        'Lady in the Water': 2.5,
        'Snakes on a Plane': 3.5,
        'Just My Luck': 3.0,
        'Superman Returns': 3.5,
        'The Night Listener': 3.0,
        'You, Me and Dupree': 2.5,
    },
    'Gene Seymour': {
        'Lady in the Water': 3.0,
        'Snakes on a Plane': 3.5,
        'Just My Luck': 1.5,
        'Superman Returns': 5.0,
        'The Night Listener': 3.0,
        'You, Me and Dupree': 3.5,
    },
    'Michael Phillips': {
        'Lady in the Water': 2.5,
        'Snakes on a Plane': 3.0,
        'Superman Returns': 3.5,
        'The Night Listener': 4.0,
    },
    'Claudia Puig': {
        'Snakes on a Plane': 3.5,
        'Just My Luck': 3.0,
        'The Night Listener': 4.5,
        'Superman Returns': 4.0,
        'You, Me and Dupree': 2.5,
    },
    'Mick LaSalle': {
        'Lady in the Water': 3.0,
        'Snakes on a Plane': 4.0,
        'Just My Luck': 2.0,
        'Superman Returns': 3.0,
        'The Night Listener': 3.0,
        'You, Me and Dupree': 2.0,
    },
    'Jack Matthews': {
        'Lady in the Water': 3.0,
        'Snakes on a Plane': 4.0,
        'The Night Listener': 3.0,
        'Superman Returns': 5.0,
        'You, Me and Dupree': 3.5,
    },
    'Toby': {
        'Snakes on a Plane': 4.5,
        'You, Me and Dupree': 1.0,
        'Superman Returns': 4.0,
    }
}

$ python
Python 3.5.1 (default, Nov  7 2016, 22:30:16)
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import recommendation
>>> recommendation.sim_distance(critics, 'Lisa Rose', 'Gene Seymour')
0.29429805508554946

Coefficient de corrélation du facteur produit de Pearson

Si les données ne sont pas normalisées, trouver simplement la distance euclidienne ne donnera que des résultats subtils. Par exemple, lors de l'évaluation d'un film, lorsque M. A et M. B ont des goûts similaires. Dans ce cas, je veux que MM. A et B aient un degré élevé de similitude. Supposons que les évaluations des films X, Y et Z par deux personnes soient les suivantes.

Film X Film Y Film Z
Monsieur A 3 1.5 3.5
Monsieur B 4 2 5

Bien que les goûts semblent similaires, M. A a une évaluation plutôt sèche et M. B a une évaluation douce. Lorsque cela est calculé par la sim_distance ci-dessus, la similitude est de 0,348. Si les points d'évaluation sont biaisés ou obstrués, quelle que soit la similitude des goûts, la distance euclidienne ne peut pas les couvrir.

Le coefficient de corrélation du facteur produit de Pearson est utilisé dans de tels cas. Quantifiez la corrélation, pas la simple distance entre les données.

\frac{ \sum_{i=1}^{n} (X_i - \bar{X})(Y_i - \bar{Y}) } { \sqrt{ \sum_{i=1}^{n} (X_i - \bar{X})^2} \sqrt{ \sum_{i=1}^{n} (Y_i - \bar{Y})^2} } 

La barre supérieure est la valeur moyenne. Je ne suis pas sûr de ce que je fais simplement en regardant la formule, mais la molécule est codisperse et le dénominateur est l'écart type de chaque donnée. Peut-il être considéré comme un calcul de similarité cosinus? (Je ne comprends pas bien ...)

Référence: http://mathtrain.jp/correlation http://aoki2.si.gunma-u.ac.jp/lecture/Soukan/pearson.html http://d.hatena.ne.jp/sleepy_yoshi/20110325/p1

Implémentez ceci en python

def sim_pearson(prefs, person1, person2):
    si = {}

    for item in prefs[person1]:
        if item in prefs[person2]:
            si[item] = 1

    n = len(si)

    if n == 0: return 0

    mean1 = sum([prefs[person1][item] for item in si]) / n
    mean2 = sum([prefs[person2][item] for item in si]) / n
    variance1 = math.sqrt(sum([((prefs[person1][item] - mean1) ** 2) for item in si]))
    variance2 = math.sqrt(sum([((prefs[person2][item] - mean2) ** 2) for item in si]))

    covariance = sum([(prefs[person1][item] - mean1)*(prefs[person2][item] - mean2) for item in si])

    if variance1 * variance2 == 0: return 0

    return covariance / (variance1 * variance2)

>>> data = {'Asan': {'X': 3.0,'Y': 1.5,'Z': 3.5,},'Bsan': {'X': 4.0,'Y': 2.0,'Z': 5.0,}}
>>> recommendation.sim_pearson(data, 'Asan', 'Bsan')
0.9958705948858225

Un nombre beaucoup plus élevé que la distance euclidienne est sorti. Ensuite, j'ai pensé que le coefficient de corrélation du facteur produit de Pearson était le plus fort, mais il ne pouvait pas être bien compris à moins qu'il ne s'agisse d'une relation linéaire sur le diagramme de dispersion, les données de comparaison devaient être distribuées normalement et les valeurs aberrantes étaient Il semble que s'il y en a, il sera traîné par lui, alors nous devons remplir les conditions dans une certaine mesure.

Une autre implémentation de python

Dans la programmation des connaissances collectives, la fonction de recherche du coefficient de corrélation du facteur produit du même Pearson a été implémentée comme suit.

def sim_pearson(prefs, p1, p2):
    '''
    Returns the Pearson correlation coefficient for p1 and p2.
    '''

    # Get the list of mutually rated items
    si = {}
    for item in prefs[p1]:
        if item in prefs[p2]:
            si[item] = 1
    # If they are no ratings in common, return 0
    if len(si) == 0:
        return 0
    # Sum calculations
    n = len(si)
    # Sums of all the preferences
    sum1 = sum([prefs[p1][it] for it in si])
    sum2 = sum([prefs[p2][it] for it in si])
    # Sums of the squares
    sum1Sq = sum([pow(prefs[p1][it], 2) for it in si])
    sum2Sq = sum([pow(prefs[p2][it], 2) for it in si])
    # Sum of the products
    pSum = sum([prefs[p1][it] * prefs[p2][it] for it in si])
    # Calculate r (Pearson score)
    num = pSum - sum1 * sum2 / n
    den = sqrt((sum1Sq - pow(sum1, 2) / n) * (sum2Sq - pow(sum2, 2) / n))
    if den == 0:
        return 0
    r = num / den
    return r

https://github.com/arthur-e/Programming-Collective-Intelligence/blob/master/chapter2/recommendations.py

Quand j'ai regardé ce code dans ce livre, je ne pouvais pas comprendre comment transformer la formule ci-dessus en ce type d'implémentation, j'ai donc implémenté la formule comme avant. Quand j'ai vérifié avec scipy.stats.pearsonr dans scipy, le code que j'ai implémenté et ce code a renvoyé la même valeur. Peu importe l'implémentation que vous utilisez, mais je ne sais pas comment transformer l'expression pour obtenir le code affiché dans la programmation d'intelligence collective ci-dessous ... Si vous le savez, faites-le moi savoir.

Coefficient de Jaccard

Calculez la similitude entre les ensembles.

 J( A, B ) = \frac { \mid A \cap B \mid } { \mid A \cup B \mid  }  = \frac { \mid A \cap B \mid } { |A| + |B| - \mid A \cap B \mid }

https://en.wikipedia.org/wiki/Jaccard_index#Tanimoto_similarity_and_distance

Il est utilisé lorsque vous souhaitez calculer la similitude entre les phrases. Extrayez les mots utilisés dans la phrase A et les mots utilisés dans la phrase B, et trouvez la valeur de l'ensemble de somme des mots et de la partie commune. Dans de tels cas, plus il y a de mots couramment utilisés, plus la similitude est élevée.

def sim_jaccard(prefs, a, b):
    si = {}
    for item in prefs[a]:
        if item in prefs[b]:
            si[item] = 1

    n = len(si)
    if n == 0:
        return 0

    len_a = len(prefs[a])
    len_b = len(prefs[b])

    return n / (len_a + len_b - n)

>>> data = {'machine-learning': ['DNN', 'python', 'chainer', 'scikit-learn'], 'python-waf': ['python', 'django', 'flask', 'pyenv']}
>>> recommendation.sim_pearson(data, 'machine-learning', 'python-waf')
0.14285714285714285

Recommended Posts

Différentes façons de calculer la similitude entre les données avec python
Différentes façons de lire la dernière ligne d'un fichier csv en Python
Dans la commande python, python pointe vers python3.8
Essayez de calculer Trace en Python
6 façons d'enchaîner des objets en Python
Calculer le mois précédent en Python
Différentes façons de créer un tableau de nombres de 1 à 10 en Python.
Divers commentaires à écrire dans le programme
[Harlem] Il y en a trop pour choisir! 13 façons de calculer la circonférence π en Python
[Python] Compréhension de liste Différentes façons de créer une liste
Comment utiliser la bibliothèque C en Python
3 façons d'analyser les chaînes de temps avec python [Note]
Pour remplacer dynamiquement la méthode suivante en python
À propos de la différence entre "==" et "is" en python
Dessinez des graphiques dans Julia ... Laissez les graphiques à Python
Conseils pour rédiger un aplatissement concis en python
Essayez de calculer RPN avec Python (pour les débutants)
Comment obtenir les fichiers dans le dossier [Python]
L'histoire de la lecture des données HSPICE en Python
Je veux afficher la progression en Python!
Utilisez PIL en Python pour extraire uniquement les données souhaitées d'Exif
Comment récupérer la nième plus grande valeur en Python
J'ai essayé de représenter graphiquement les packages installés en Python
Comment obtenir le nom de la variable lui-même en python
Diverses méthodes pour extraire les colonnes du tableau NumPy
Essayez de le résoudre de différentes manières (SAT, CSP)
Convertissez l'image au format .zip en PDF avec Python
Ne pas être conscient du contenu des données en python
Écrire des données dans KINTONE à l'aide du module de requêtes Python
Je veux écrire en Python! (3) Utiliser des simulacres
Utilisons les données ouvertes de "Mamebus" en Python
Comment utiliser le modèle appris dans Lobe en Python
Essayez de déchiffrer les données de connexion stockées dans Firefox
[Python] Comment afficher les valeurs de liste dans l'ordre
Pour faire l'équivalent de Ruby ObjectSpace._id2ref en Python
Je veux utiliser le jeu de données R avec python
Python Open CV a essayé d'afficher l'image sous forme de texte.
Différences de comportement entre les opérateurs append () et "+ =" lors de l'ajout de données à une liste en Python
Notez que la méthode de publication des modules sur PyPI a changé de différentes manières.
Essayez de gratter les données COVID-19 Tokyo avec Python
Calculer mW <-> dBm en Python
Pour vider stdout en Python
Sortie "Dessiner fougère par programmation" dans le processus de dessin en Python
J'ai essayé de créer diverses "données factices" avec Python faker
[Python] Il peut être utile de lister les trames de données
Comment déboguer une bibliothèque Python standard dans Visual Studio
Trouver des erreurs en Python
Afficher les données UTM-30LX en Python
Comment utiliser la méthode __call__ dans la classe Python
[Python] Différentes façons de générer des données avec Numpy (arange / linspace / logspace / zeros / ones / mgrid / ogrid)
Changer la destination de sortie standard en un fichier en Python
Calculez des millions de chiffres dans la racine carrée de 2 avec python
Connectez-vous au site Web en Python
[Comprendre au plus court] Principes de base de Python pour l'analyse des données
[Homologie] Comptez le nombre de trous dans les données avec Python
Créer un environnement Python et transférer des données vers le serveur
Comment calculer la somme ou la moyenne des données csv de séries chronologiques en un instant
Comment obtenir la dernière (dernière) valeur d'une liste en Python