web-dev-qa-db-fra.com

Vectorisation d'un cadre de données Pandas pour Scikit-Learn

Supposons que j'ai un cadre de données dans les pandas du type suivant:

> my_dataframe

col1   col2
A      foo
B      bar
C      something
A      foo
A      bar
B      foo

où les lignes représentent des instances et les colonnes des entités en entrée (ne montrant pas l’étiquette cible, mais cela s’applique à une tâche de classification), c’est-à-dire que j’essaie de construireXsur my_dataframe.

Comment puis-je vectoriser cela efficacement en utilisant par exemple DictVectorizer ?

Dois-je d'abord convertir chaque entrée de mon DataFrame en dictionnaire? (c'est comme ça que ça se passe dans l'exemple du lien ci-dessus). Y a-t-il un moyen plus efficace de le faire?

16

Premièrement, je ne vois pas où dans votre exemple de tableau sont des entités et où des observations.

Deuxièmement, DictVectorizer ne contient aucune donnée et concerne uniquement l'utilitaire de transformation et le stockage de métadonnées. Après la transformation, il stocke les noms des fonctionnalités et le mappage. Il retourne un tableau numpy, utilisé pour d'autres calculs. La taille du tableau Numpy (matrice d'éléments) est égale à features count x number of observations, avec des valeurs égales à la valeur d'entité pour une observation. Donc, si vous connaissez vos observations et fonctionnalités, vous pouvez créer ce tableau comme vous le souhaitez.

Au cas où vous espériez le faire à votre place, vous n'avez pas à reconstruire manuellement dict, comme vous pouvez le faire avec to_dict appliqué au cadre de données transposé:

>>> df
  col1 col2
0    A  foo
1    B  bar
2    C  foo
3    A  bar
4    A  foo
5    B  bar
>>> df.T.to_dict().values()
[{'col2': 'foo', 'col1': 'A'}, {'col2': 'bar', 'col1': 'B'}, {'col2': 'foo', 'col1': 'C'}, {'col2': 'bar', 'col1': 'A'}, {'col2': 'foo', 'col1': 'A'}, {'col2': 'bar', 'col1': 'B'}]

Depuis scikit-learn 0.13.0 (3 janv. 2014), un nouveau paramètre 'records' pour la méthode to_dict() est disponible. Vous pouvez donc maintenant utiliser cette méthode sans manipulations supplémentaires:

>>> df = pandas.DataFrame({'col1': ['A', 'B', 'C', 'A', 'A', 'B'], 'col2': ['foo', 'bar', 'foo', 'bar', 'foo', 'bar']})
>>> df
  col1 col2
0    A  foo
1    B  bar
2    C  foo
3    A  bar
4    A  foo
5    B  bar
>>> df.to_dict('records')
[{'col2': 'foo', 'col1': 'A'}, {'col2': 'bar', 'col1': 'B'}, {'col2': 'foo', 'col1': 'C'}, {'col2': 'bar', 'col1': 'A'}, {'col2': 'foo', 'col1': 'A'}, {'col2': 'bar', 'col1': 'B'}]
21
alko

Regardez sklearn-pandas qui fournit exactement ce que vous cherchez. Le repo Github correspondant est ici .

11
Matt

Vous pouvez certainement utiliser DictVectorizer. Étant donné que DictVectorizer attend un objet itérable de dict- like, vous pouvez procéder comme suit:

from sklearn.base import TransformerMixin
from sklearn.pipeline import make_pipeline
from sklearn.feature_extraction import DictVectorizer


class RowIterator(TransformerMixin):
    """ Prepare dataframe for DictVectorizer """
    def fit(self, X, y=None):
        return self

    def transform(self, X):
        return (row for _, row in X.iterrows())


vectorizer = make_pipeline(RowIterator(), DictVectorizer())

# now you can use vectorizer as you might expect, e.g.
vectorizer.fit_transform(df)
5
Kris

Vous voulez construire une matrice de conception à partir d’un pandas DataFrame contenant des catégories (ou simplement des chaînes) et la façon la plus simple de le faire consiste à utiliser patsy , une bibliothèque qui réplique et développe les fonctionnalités des formules R. 

En utilisant votre exemple, la conversion serait:

import pandas as pd
import patsy

my_df = pd.DataFrame({'col1':['A', 'B', 'C', 'A', 'A', 'B'], 
                      'col2':['foo', 'bar', 'something', 'foo', 'bar', 'foo']})

patsy.dmatrix('col1 + col2', data=my_df) # With added intercept
patsy.dmatrix('0 + col1 + col2', data=my_df) # Without added intercept

Les matrices de conception résultantes ne sont que des tableaux NumPy avec des informations supplémentaires et peuvent être directement utilisées dans scikit-learn.

Exemple de résultat avec interception ajoutée:

DesignMatrix with shape (6, 5)
  Intercept  col1[T.B]  col1[T.C]  col2[T.foo]  col2[T.something]
          1          0          0            1                  0
          1          1          0            0                  0
          1          0          1            0                  1
          1          0          0            1                  0
          1          0          0            0                  0
          1          1          0            1                  0
  Terms:
    'Intercept' (column 0)
    'col1' (columns 1:3)
    'col2' (columns 3:5)

Notez que patsy a essayé d'éviter la multicolinéarité en incorporant les effets de A et bar dans l'interception. Ainsi, par exemple, le prédicteur col1[T.B] devrait être interprété comme l'effet supplémentaire de B par rapport aux observations classées dans A.

3
foglerit