Mettre en œuvre des recommandations en Python

Depuis le second semestre de cette année, la fréquence des mises à jour de placage a diminué, mais il s'agit de la première mise à jour depuis longtemps.

L'article dans Dernière fois a plus de 3 mois, et l'article avec beaucoup de stock est affiché comme il y a plus d'un an, la notation de Qiita ( J'oublie (≒ Markdown), c'est misérable ...

Cette fois, je vais écrire le co-filtrage (recommandation) en Python.

Cela dit, il y a un article écrit en Ruby en janvier de cette année, alors veuillez vous y référer également.

données brutes

Utilise les mêmes données que dans l'article précédent (http://qiita.com/ynakayama/items/ceb3f6408231ea3d230c).

Nous avons demandé à une personne ayant déjeuné à la cafétéria d'entreprise d'une entreprise A de donner une note parfaite de 5,0 pour les impressions des 10 derniers jours.

Les scores pour chaque menu étaient les suivants. Le menu que je n'ai jamais mangé est-.

Nom curry ramen Riz sauté Sushi bol de boeuf Udon
M. Yamada 2.5 3.5 3.0 3.5 2.5 3.0
Tanaka 3.0 3.5 1.5 5.0 3.0 3.5
Monsieur Sato 2.5 3.0 -- 3.5 -- 4.0
M. Nakamura -- 3.5 3.0 4.0 2.5 4.5
M. Kawamura 3.0 4.0 2.0 3.0 2.0 3.0
Suzuki 3.0 4.0 -- 5.0 3.5 3.0
M. Shimobayashi -- 4.5 -- 4.0 1.0 --

Tout le monde a des préférences gustatives différentes et il semble que le même menu ait des scores plus ou moins élevés selon les personnes.

Création de données originales

Tout d'abord, préparez les données sous une forme qui peut être gérée par Python et appelez-la recommandation_data.py.

dataset = {
    'Yamada': {'curry': 2.5,
           'ramen': 3.5,
           'Riz sauté': 3.0,
           'Sushi': 3.5,
           'bol de boeuf': 2.5,
           'Udon': 3.0},
    'Tanaka': {'curry': 3.0,
           'ramen': 3.5,
           'Riz sauté': 1.5,
           'Sushi': 5.0,
           'Udon': 3.0,
           'bol de boeuf': 3.5},
    'Sato': {'curry': 2.5,
           'ramen': 3.0,
           'Sushi': 3.5,
           'Udon': 4.0},
    'Nakamura': {'ramen': 3.5,
           'Riz sauté': 3.0,
           'Udon': 4.5,
           'Sushi': 4.0,
           'bol de boeuf': 2.5},
    'Kawamura': {'curry': 3.0,
           'ramen': 4.0,
           'Riz sauté': 2.0,
           'Sushi': 3.0,
           'Udon': 3.0,
           'bol de boeuf': 2.0},
    'Suzuki': {'curry': 3.0,
           'ramen': 4.0,
           'Udon': 3.0,
           'Sushi': 5.0,
           'bol de boeuf': 3.5},
    'Shimobayashi': {'ramen': 4.5,
           'bol de boeuf': 1.0,
           'Sushi': 4.0}}

Le traitement des données

Lisons les données de recommandation_data.py ci-dessus et affichons-les en Python.

from recommendation_data import dataset
from math import sqrt

print(("Évaluation du curry de M. Yamada: {}".format(
    dataset['Yamada']['curry'])))
print(("Évaluation de l'udon de M. Yamada: {}\n".format(
    dataset['Yamada']['Udon'])))
print(("Évaluation du curry de M. Sato: {}".format(
    dataset['Sato']['curry'])))
print(("Évaluation de l'udon de M. Sato: {}\n".format(
    dataset['Sato']['Udon'])))

print("La cote de Suzuki: {}\n".format((dataset['Suzuki'])))

#=>Évaluation du curry de M. Yamada: 2.5
#=>Évaluation de l'udon de M. Yamada: 3.0

#=>Évaluation du curry de M. Sato: 2.5
#=>Évaluation de l'udon de M. Sato: 4.0

#=>La cote de Suzuki: {'Sushi': 5.0, 'Udon': 3.0, 'curry': 3.0, 'bol de boeuf': 3.5, 'ramen': 4.0}

Mise en place du co-filtrage

Il existe différentes mesures de similitude. Voici le code pour trouver la distance euclidienne.

def similarity_score(person1, person2):
    #La valeur de retour est la distance euclidienne entre personne1 et personne2

    both_viewed = {}  #Obtenez des éléments communs aux deux

    for item in dataset[person1]:
        if item in dataset[person2]:
            both_viewed[item] = 1

    #Renvoie 0 si vous n'avez pas d'élément commun
    if len(both_viewed) == 0:
        return 0

    #Calcul de la distance euclidienne
    sum_of_eclidean_distance = []

    for item in dataset[person1]:
        if item in dataset[person2]:
            sum_of_eclidean_distance.append(
                pow(dataset[person1][item] - dataset[person2][item], 2))
    total_of_eclidean_distance = sum(sum_of_eclidean_distance)

    return 1 / (1 + sqrt(total_of_eclidean_distance))

print("Similitude entre M. Yamada et M. Suzuki(Distance euclidienne)",
      similarity_score('Yamada', 'Suzuki'))

#=>Similitude entre M. Yamada et M. Suzuki(Distance euclidienne) 0.3405424265831667

Voici le code pour trouver le coefficient de corrélation de Pearson. On dit souvent que de meilleurs résultats que les distances euclidiennes sont obtenus dans des situations où les données ne sont pas normalisées.

def pearson_correlation(person1, person2):

    #Obtenez les deux articles
    both_rated = {}
    for item in dataset[person1]:
        if item in dataset[person2]:
            both_rated[item] = 1

    number_of_ratings = len(both_rated)

    #Vérifie les éléments communs, renvoie 0 sinon
    if number_of_ratings == 0:
        return 0

    #Ajouter toutes les préférences pour chaque utilisateur
    person1_preferences_sum = sum(
        [dataset[person1][item] for item in both_rated])
    person2_preferences_sum = sum(
        [dataset[person2][item] for item in both_rated])

    #Calculez le carré de la valeur préférée de chaque utilisateur
    person1_square_preferences_sum = sum(
        [pow(dataset[person1][item], 2) for item in both_rated])
    person2_square_preferences_sum = sum(
        [pow(dataset[person2][item], 2) for item in both_rated])

    #Calculer et additionner les notes entre les utilisateurs pour chaque élément
    product_sum_of_both_users = sum(
        [dataset[person1][item] * dataset[person2][item] for item in both_rated])

    #Calcul du score Pearson
    numerator_value = product_sum_of_both_users - \
        (person1_preferences_sum * person2_preferences_sum / number_of_ratings)
    denominator_value = sqrt((person1_square_preferences_sum - pow(person1_preferences_sum, 2) / number_of_ratings) * (
        person2_square_preferences_sum - pow(person2_preferences_sum, 2) / number_of_ratings))
    if denominator_value == 0:
        return 0
    else:
        r = numerator_value / denominator_value
        return r

print("Similitude entre M. Yamada et M. Tanaka(Coefficient de corrélation de Pearson)",
      (pearson_correlation('Yamada', 'Tanaka')))

#=>Similitude entre M. Yamada et M. Tanaka(Coefficient de corrélation de Pearson) 0.39605901719066977

Calculer la similitude

Nous recherchons les 3 meilleures personnes qui ont des préférences alimentaires similaires à celles de M. Yamada.

def most_similar_users(person, number_of_users):
    #Renvoie des utilisateurs similaires et leur similitude
    scores = [(pearson_correlation(person, other_person), other_person)
              for other_person in dataset if other_person != person]

    #Trier de manière à ce que la personne présentant la similitude la plus élevée vienne en premier
    scores.sort()
    scores.reverse()
    return scores[0:number_of_users]

print("Les 3 meilleures personnes comme M. Yamada",
      most_similar_users('Yamada', 3))

#=>Les 3 meilleures personnes comme M. Yamada[(0.9912407071619299, 'Shimobayashi'), (0.7470178808339965, 'Suzuki'), (0.5940885257860044, 'Kawamura')]

Trouvez un menu recommandé

Enfin, je voudrais recommander un menu recommandé à M. Shimobayashi.

def user_reommendations(person):

    #Rechercher des recommandations dans les classements en fonction des moyennes pondérées des autres utilisateurs
    totals = {}
    simSums = {}
    for other in dataset:
        #Ne me compare pas
        if other == person:
            continue
        sim = pearson_correlation(person, other)

        #Ignorer les scores inférieurs à zéro
        if sim <= 0:
            continue
        for item in dataset[other]:

            #Score des articles que vous n'avez pas encore
            if item not in dataset[person] or dataset[person][item] == 0:

                # Similrity *But
                totals.setdefault(item, 0)
                totals[item] += dataset[other][item] * sim
                #Somme de similitude
                simSums.setdefault(item, 0)
                simSums[item] += sim

        #Créer une liste normalisée

    rankings = [(total / simSums[item], item)
                for item, total in list(totals.items())]
    rankings.sort()
    rankings.reverse()
    #Retourner les articles recommandés
    recommendataions_list = [
        recommend_item for score, recommend_item in rankings]
    return recommendataions_list

print("Menu recommandé pour M. Shimobayashi",
      user_reommendations('Shimobayashi'))
#=>Menu recommandé pour M. Shimobayashi['Udon', 'curry', 'Riz sauté']

à la fin

Le code source de cet article est ici.

Le filtrage coopératif peut être globalement divisé en méthodes basées sur les éléments et basées sur l'utilisateur. Pour un commentaire comprenant un code spécifique, lisez le chapitre 2 de "Aggregate Knowledge Programming". Cet article suit ceci.

Si vous voulez connaître systématiquement l'algorithme du système de recommandation, l'article suivant du Journal of the Society of Artificial Intelligence écrit par Toshihiro Kamishima est personnel. Il est facile à comprendre et recommandé.

Toshihiro Kamishima:Algorithme du système de recommandation(1),Journal de la Société d'Intelligence Artificielle, vol.22, no.6, pp.826-837, 2007.
Toshihiro Kamishima:Algorithme du système de recommandation(2),Journal de la Société d'Intelligence Artificielle, vol.23, no.1, pp.89-103, 2008.
Toshihiro Kamishima:Algorithme du système de recommandation(3),Journal de la Société d'Intelligence Artificielle, vol.23, no.2, pp.248-263, 2008.

Si vous n'avez pas d'environnement pour lire les articles, vous devriez vous référer au Commentaire du système de recommandation sur le site de l'auteur car il a presque le même contenu. ..

En écrivant cet article, je me réfère au document ci-dessus, Group Knowledge Programming et aux articles suivants. collaborative filtering recommendation engine implementation in python http://dataaspirant.com/2015/05/25/collaborative-filtering-recommendation-engine-implementation-in-python/

Recommended Posts

Mettre en œuvre des recommandations en Python
Implémenter XENO avec python
Implémenter sum en Python
Implémenter Traceroute dans Python 3
Implémenter Naive Bayes dans Python 3.3
Implémenter d'anciens chiffrements en python
Implémenter Redis Mutex en Python
Implémenter l'extension en Python
Mettre en œuvre un RPC rapide en Python
Implémenter l'algorithme de Dijkstra en python
Implémenter le bot de discussion Slack en Python
Mettre en œuvre l'apprentissage de l'empilement en Python [Kaggle]
Implémenter la fonction power.prop.test de R en python
Implémenter le modèle Singleton en Python
Implémentez rapidement l'API REST en Python
Quadtree en Python --2
Python en optimisation
CURL en Python
Métaprogrammation avec Python
Python 3.3 avec Anaconda
Géocodage en python
SendKeys en Python
Méta-analyse en Python
Unittest en Python
Époque en Python
Discord en Python
Allemand en Python
DCI en Python
tri rapide en python
nCr en python
N-Gram en Python
Programmation avec Python
Plink en Python
Constante en Python
FizzBuzz en Python
Sqlite en Python
Étape AIC en Python
LINE-Bot [0] en Python
CSV en Python
Assemblage inversé avec Python
Réflexion en Python
Constante en Python
nCr en Python.
format en python
Scons en Python 3
Puyopuyo en python
python dans virtualenv
PPAP en Python
Quad-tree en Python
Réflexion en Python
Chimie avec Python
Hashable en Python
DirectLiNGAM en Python
LiNGAM en Python
Aplatir en Python
Aplatir en python
J'ai essayé d'implémenter PLSA en Python