[PYTHON] Un échantillon pour essayer rapidement les machines de factorisation avec fastFM

――Ceci est un article d'introduction qui vous permet d'essayer rapidement l'algorithme des machines de factorisation, qui a attiré l'attention ces dernières années dans la technologie de recommandation, en utilisant une bibliothèque. ――Ce n'est pas une explication théorique mais un article pour bouger. ――En gros, suivez le tutoriel + le supplément.

Divers matériaux de référence

Cette fois, j'ai utilisé une bibliothèque appelée fastFM. De plus, l'explication et les performances de cette librairie sont publiées sur arXiv.

Pour ceux qui veulent connaître les grandes lignes et les tendances des machines de factorisation, il existe des articles de référence à l'intérieur et à l'extérieur de Qiita, je vais donc en publier quelques-uns. Les livres suivants sont également disponibles pour fastFM. En gros, il s'agit d'un algorithme qui «utilise la décomposition matricielle pour effectuer une régression, une classification et un classement qui sont solides par rapport aux données rares».

Histoire principale

introduction

Il y a des notes. Dans le cas de mon propre environnement, c'était comme suit.

Pour Python 3.6.10.

Pour Python 3.7.6

Donc, si vous êtes dans un nouvel environnement, vous pouvez l'installer à partir de la source, créer un environnement qui peut exécuter plusieurs pythons tels que pyenv et introduire la série 3.6, ou créer un environnement 3.6 avec Docker, etc. Je pense que ce sera.

Exemple de données

En ce qui concerne les échantillons de Factorization Machines (FM), je pense que les échantillons de type dictionnaire sont souvent utilisés pour les données d'échantillonnage.

[
{user:A, item:X, ...},
{user:B, item:Y, ...}, ...
]

Comme. Il semble que ces données soient souvent entrées pour des données rares, mais cette fois, je voudrais les gérer en supposant un csv simple.

Exemple de données factices


Catégorie,rating,is_A,is_B,is_C,is_X,is_Y,is_Z
A,5,0,0,1,0,1,0
A,1,1,0,0,0,0,1
B,2,0,1,0,0,0,0
B,5,0,0,0,0,1,0
C,1,1,0,0,0,0,1
C,4,0,0,0,0,1,0
...

Je vais mettre toutes les versions en bas. La valeur est une valeur factice faite de manière appropriée,

Est assumé.

Confirmation du flux de traitement avec analyse de régression

L'utilisation de la bibliothèque elle-même est simple et familière à ceux qui ont utilisé scicit-learn, etc. Tout d'abord, créons un flux de traitement avec une simple logique d'analyse de régression. Les détails sont brisés, mais la création générale du modèle semble être la suivante.

  1. Lire les données
  2. Prétraitement (convertir les données dans un format adapté au modèle)
  3. Divisé en "données de formation" (, "données de validation") et "données de test"
  4. Créez un modèle avec des données d'entraînement
  5. Appliquer le modèle aux données de test
  6. Définir et évaluer les indicateurs d’évaluation des performances

Cette fois, je vais créer un modèle de régression avec le thème de ** rating **. (Par souci de clarté, j'importe à chaque fois, mais vous pouvez tout importer en haut.)

Lecture des données

import numpy as np
import pandas as pd

#lire les données csv
raw = pd.read_csv('fm_sample.csv')

#Colonnes cibles séparées et autres informations
target_label = "rating"

data_y = raw[target_label]
data_X = raw.drop(target_label, axis=1)

Division pré-traitement des données

#Prétraitement
##Bibliothèque de traitement de données de catégorie pratique, scikit-Utilisez les fonctions pratiques d'apprentissage
import category_encoders as ce

##Un pour la colonne spécifiée-encodage à chaud
enc = ce.OneHotEncoder(cols=['Catégorie'])

X = enc.fit_transform(data_X)
y = data_y

#Répartition des données
from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=810)

Modélisation-évaluation

L'évaluation est MAE (erreur absolue moyenne), mais MSE etc. peut être calculé rapidement.

from sklearn import linear_model
from sklearn.metrics import mean_squared_error, mean_absolute_error

#La modélisation
reg = linear_model.LinearRegression()
reg.fit(X_train, y_train)

#Évaluation
##Applicabilité aux données de formation
mean_absolute_error(y_train, reg.predict(X_train))
##Erreur de données de test
mean_absolute_error(y_test, reg.predict(X_test))

Je pense que ce sera comme ça. Bien sûr, je ferais plus dans la partie évaluation, comme dessiner la ligne de régression calculée et voir comment l'erreur s'écarte, mais cette fois jusqu'à ce que je la déplace.

Retour par FM

Si le flux ci-dessus peut être effectué, le reste est terminé si la partie calcul est intégrée à la spécification fastFM utilisée cette fois. Un point à noter est que ** DataFrame ne peut pas être traité tel quel, donc csr_matrix est utilisé **.

Modélisation-évaluation

from fastFM import als
from scipy.sparse import csr_matrix

#La modélisation
fm = als.FMRegression(n_iter=1000, init_stdev=0.1, rank=8, l2_reg_w=0.5, l2_reg_V=0.5, random_state=810)
fm.fit(csr_matrix(X_train), y_train)

#Évaluation
##Applicabilité aux données de formation
mean_absolute_error(y_train, fm.predict(csr_matrix(X_train)))
##Erreur de données de test
mean_absolute_error(y_test, fm.predict(csr_matrix(X_test)))

Matrice clairsemée, csr_matrix

Voici la csr_matrix. Il traite des données rares. L'image est simple et si DataFrame ou matrice normale gère les données bidimensionnelles comme suit:

matrix


array([
  [0, 0, 1],
  [0, 0, 0],
  [0, 3, 0]
])

Seule la partie contenant les données est gérée

Traitement des données rares


Taille: 3 x 3
Là où il y a des données:
([0,2]1 au point)
([2,1]3 au point)

C'est une image comme. Il existe plusieurs types de manipulation, tels que csr_matrix, coo_matrix, csc_matrix, lil_matrix, et il semble que la manipulation et la vitesse de traitement soient différentes, donc si vous êtes intéressé, veuillez rechercher avec "scipy sparse matrix" etc. note.nkmk.me et ainsi de suite.

De quoi se souvenir cette fois

--Exemple de conversion depuis DataFrame: csr_matrix (df) --converting csr_matrix en une matrice Todense Exemple: csr_matrix (X_train) .todense ()

Je me demande si.

Classification par FM

La classification binaire est également possible, je vais donc l'essayer. Cette fois, je vais faire la tâche de ** deviner 2 classes avec une note de 4 ou plus ou moins **. Après la partie de division des données de prétraitement, le modèle est créé et évalué après avoir créé les données de réponse pour savoir si la note est de 4 ou plus. Notez également que la classification fastFM crée des valeurs avec «-1 ou 1» au lieu de «0 ou 1».

from fastFM import sgd
from sklearn.metrics import roc_auc_score

#Prétraitement continué
##1 si 4 ou plus autrement-Définir sur 1
y_ = np.array([1 if r > 3 else -1 for r in y])

##Création de données d'entraînement / de données de test
X_train, X_test, y_train, y_test = train_test_split(X, y_, random_state=810)

#La modélisation
fm = sgd.FMClassification(n_iter=5000, init_stdev=0.1, l2_reg_w=0,
                          l2_reg_V=0, rank=2, step_size=0.1)
fm.fit(csr_matrix(X_train), y_train)

##Il semble que vous puissiez obtenir deux types de valeurs prédites.
y_pred = fm.predict(csr_matrix(X_test))
y_pred_proba = fm.predict_proba(csr_matrix(X_test))

#Évaluation
##Exemple d'évaluation de la valeur de l'AUC
roc_auc_score(y_test, y_pred_proba)

Dessiner une courbe ROC

J'écrirai la courbe ROC en me référant à la page de note.nkmk.me. ..

fpr, tpr, thresholds = metrics.roc_curve(y_test, y_pred_proba, drop_intermediate=False)

auc = metrics.auc(fpr, tpr)

#Tracer la courbe ROC
plt.plot(fpr, tpr, label='ROC curve (area = %.2f)'%auc)
plt.legend()
plt.title('ROC curve')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.grid(True)
plt.show()

image.png

J'ai pu le faire.

autre

Ci-dessous, collez les exemples de données. C'est fait correctement, donc ce ne sont pas des données intéressantes. Veuillez vérifier le fonctionnement.

fm_sample.csv


Catégorie,rating,is_A,is_B,is_C,is_X,is_Y,is_Z
A,5,0,0,1,0,1,0
A,1,1,0,0,0,0,1
A,3,0,0,1,0,1,0
A,2,1,0,0,0,0,1
A,4,0,0,0,0,0,1
A,5,1,0,0,1,1,0
A,1,0,1,0,0,0,1
A,2,0,0,0,0,0,1
B,2,0,1,0,0,0,0
B,5,0,0,0,0,1,0
B,3,1,1,0,0,1,0
B,2,0,0,1,0,0,0
B,1,0,0,0,0,0,1
B,3,0,0,1,0,0,1
B,4,0,1,0,0,0,0
B,1,0,0,0,0,0,1
B,2,0,1,0,0,0,1
C,1,1,0,0,0,0,1
C,4,0,0,0,0,1,0
C,2,1,0,1,0,1,0
C,4,0,0,0,0,0,0
C,5,0,0,1,1,1,0
C,2,0,1,0,0,0,1
C,5,1,0,0,0,1,0
C,3,0,0,1,1,1,0
C,2,0,0,0,0,0,1
C,3,0,0,0,0,1,0
A,2,0,0,0,0,0,1
A,4,1,0,0,0,1,0
A,3,0,0,0,0,0,0
A,1,0,0,0,0,0,1
A,3,1,0,0,0,0,0
A,4,0,0,1,0,1,0
A,5,1,1,0,0,1,0
A,3,1,0,0,1,0,0
B,4,0,0,0,0,1,0
B,1,0,0,0,0,0,1
B,5,0,0,0,0,1,0
B,3,0,0,0,0,0,0
B,1,0,0,0,1,0,1
B,3,0,0,1,0,0,0
B,2,0,1,0,0,0,1
B,5,1,0,0,0,1,0
B,4,0,0,0,1,1,1
C,1,0,0,0,0,0,0
C,2,0,0,0,0,0,1
C,3,0,0,1,0,0,0
C,4,0,1,0,0,1,0
C,1,0,0,1,0,0,1
C,1,0,0,0,0,0,0
C,3,0,0,1,0,0,0
C,3,0,0,1,0,1,0
C,5,0,0,0,1,1,0
C,3,0,0,1,0,1,0

Recommended Posts

Un échantillon pour essayer rapidement les machines de factorisation avec fastFM
Essayez rapidement de visualiser votre ensemble de données avec des pandas
Essayez de dessiner une courbe de vie avec python
Essayez de créer un code de "décryptage" en Python
Essayez de créer un groupe de dièdre avec Python
AWS Step Functions pour apprendre avec un exemple
Faisons un outil de veille de commande avec python
Essayez de créer un Checkbutton dynamiquement avec Tkinter en Python
Essayez de défier le sol par récursif
Essayez de programmer avec un shell!
Essayez de sélectionner une langue
Essayez de créer un réseau de neurones / d'apprentissage en profondeur avec scratch
J'ai écrit rapidement un programme pour étudier la DI avec Python ①
Essayez d'ouvrir une sous-fenêtre avec PyQt5 et Python
Essayez de dessiner une courbe de Bézier
Essayez d'exploiter Facebook avec Python
Essayez de créer un environnement python avec Visual Studio Code et WSL
Essayez d'extraire une chaîne de caractères d'une image avec Python3
Les utilisateurs de Rails essaient de créer un moteur de blog simple avec Django
Essayez de profiler avec ONNX Runtime
Essayez de créer un type de service Web avec un langage de balisage 3D
Essayez de produire de l'audio avec M5 STACK
Essayez d'ajouter un mur à votre fichier IFC avec IfcOpenShell python
Essayez de créer un article de Qiita avec l'API REST [Préparation environnementale]
Un référentiel essentiel à utiliser lorsque vous souhaitez l'essayer avec ansible
Essayez de créer un logiciel de capture aussi précis que possible avec python (2)
Essayez de résoudre le problème du voyageur de commerce avec un algorithme génétique (théorie)
Essayez de résoudre un problème défini de mathématiques au lycée avec Python
Essayez de vous connecter à qiita avec Python
Faisons un noyau jupyter
Essayez de dessiner une distribution normale avec matplotlib
Un échantillon complet du flux optique d'OpenCV
Essayez de prédire les fleurs de cerisier avec XG Boost
Essayez de convertir en données ordonnées avec les pandas
Essayez le scraping HTML avec la bibliothèque Python
Comment utiliser la commande CUT (avec exemple)
Premier YDK à essayer avec Cisco IOS-XE
Exemple de programme pour afficher des vidéos avec PyQt
Essayez de dessiner une carte avec python + cartopy 0.18.0
Essayez de générer une image avec aliénation
Essayez TensorFlow RNN avec un modèle de base
Exemple de conversion en ondelettes d'images en Python
Essayez de résoudre le problème du voyageur de commerce avec un algorithme génétique (code Python)
Essayez d'embellir avec Talking Head Anime à partir d'une seule image [préparation python]
Essayez de résoudre le problème du voyageur de commerce avec un algorithme génétique (résultat de l'exécution)
Une solution de contournement simple pour que les robots essaient de publier des tweets avec le même contenu
Essayez de créer un site de gestion Todo en utilisant WebSocket avec Django (Swamp Dragon)
WEB grattage avec python et essayez de créer un nuage de mots à partir des critiques
J'ai essayé de créer un modèle avec l'exemple d'Amazon SageMaker Autopilot
Essayez de créer votre propre AWS-SDK avec bash
Comment créer des exemples de données CSV avec hypothèse
Essayez de résoudre le problème du fizzbuzz avec Keras
Comment lire un fichier CSV avec Python 2/3
Envoyer un message à LINE avec Python (LINE Notify)
Comment envoyer un message à LINE avec curl
Calculons en fait le problème statistique avec Python
Essayez d'agréger les données de musique doujin avec des pandas
Comment dessiner un graphique à 2 axes avec pyplot
Comment développer une application de panier avec Django
Essayez de résoudre le diagramme homme-machine avec Python