[PYTHON] J'ai vérifié la relation catégorique de Pandas - c'est pratique si vous vous y habituez (je pense)

"Pandas" qui prend en charge l'analyse des données, mais l'autre jour (2016/10/2) ver. 0.19.0 (stable) a été publié. Parmi certaines nouvelles fonctionnalités, il existe une option pour read_csv () pour analyser (analyser) les données catégoriques. En parlant de données «catégoriques», le type de facteur du langage R me vient à l'esprit, mais je n'ai jamais utilisé les fonctions catégoriques des pandas. J'étais curieux, alors j'ai profité de la version 0.19.0 et j'ai fait quelques recherches.

(L'environnement d'exploitation est pandas 0.19.0 (quelque 0.18.1 est utilisé pour la comparaison), numpy 1.11.1 et python est 3.5.2.)

Comparaison du statut de support de Pandas avec le langage R

Dans le langage R, un type de variable appelé type de facteur (type de facteur) est pris en charge. C'est un type qui ne se trouve pas dans les langages de programmation à usage général, il est donc difficile de s'y habituer, mais il est préparé pour gérer des données de type catégorie. Cependant, il semble que même les programmeurs R l'aiment et ne l'aiment pas, et lors de la saisie du fichier csv vers data.frame, il semble qu'il y ait pas mal de gens qui spécifient stingAsFactor = FALSE pour supprimer la conversion des données en type de facteur. .. (Remarque. Dans read.csv (), {data.table} fread (), la valeur par défaut est stringAsFactor = TURE (sauf si la valeur par défaut de l'utilisateur change).

Bien sûr, il n'y a pas de type de facteur dans les spécifications du langage en Python, mais il semble que le type catégorique (dtype) soit pris en charge dans les pandas depuis la version 0.15.0 (peut-être qu'il s'agit d'une demande de fonction d'un programmeur habitué au type de facteur R). (Je ne savais pas...)

Cette fois, dans la version 0.19.0, la fonction a été développée pour que Category puisse être analysée avec read_csv () et que les opérations puissent être effectuées en tenant compte de Category comme la concaténation de données.

** Cité de la documentation ** pandas_cat_1.PNG

(Le type de catégorie de Pandas est une implémentation consciente du type de facteur du langage R, mais il semble y avoir une différence entre les deux dans les détails. Je n'ai pas la résolution pour cela, donc si vous êtes intéressé, pandas Veuillez vous référer au document (ver 0.19.0).)

Contrôle de fonctionnement à l'aide du jeu de données "Mushroom"

Maintenant, vérifions l'opération ci-dessous. «Mushroom» a été préparé et utilisé comme un ensemble de données à partir du référentiel d'apprentissage automatique de l'UCI. Le contenu de "Champignon" consiste à classer si un champignon est un champignon vénéneux ou non en fonction des caractéristiques telles que la forme du champignon, mais le contenu (partie en-tête) est le suivant.

p,x,s,n,t,p,f,c,n,k,e,e,s,s,w,w,p,w,o,p,k,s,u
e,x,s,y,t,a,f,c,b,k,e,c,s,s,w,w,p,w,o,p,n,n,g
e,b,s,w,t,l,f,c,b,n,e,c,s,s,w,w,p,w,o,p,n,n,m
p,x,y,w,t,p,f,c,n,n,e,e,s,s,w,w,p,w,o,p,k,s,u
e,x,s,g,f,n,f,w,b,k,t,e,s,s,w,w,p,w,o,e,n,a,g
e,x,y,y,t,a,f,c,b,n,e,c,s,s,w,w,p,w,o,p,k,n,g
e,b,s,w,t,a,f,c,b,g,e,c,s,s,w,w,p,w,o,p,k,n,m
e,b,y,w,t,l,f,c,b,n,e,c,s,s,w,w,p,w,o,p,n,s,m
p,x,y,w,t,p,f,c,n,p,e,e,s,s,w,w,p,w,o,p,k,v,g
e,b,s,y,t,a,f,c,b,g,e,c,s,s,w,w,p,w,o,p,k,s,m

Les données sont tous des caractères alphabétiques et sont parfaites pour cet article. La première colonne est une étiquette indiquant ** "e" ** .. "comestible" "comestible", ** "p" ** .. "toxique" "toxique".

Si vous entrez ce fichier comme un fichier normal, ce sera comme suit.

fn = '../Data/Mushroom/agaricus-lepiota.data'
# names for all columns
cols = ['label', 'cap-shape', 'cap-surface', 'cap-color', 'bruises', 'odor',
    'gill-attachment', 'gill-spacing', 'gill-size', 'gill-color', 'stalk-shape',
    'stalk-root', 'stalk-surface-above-ring', 'stalk-surface-below-ring',
    'stalk-color-above-ring', 'atalk-color-below-ring', 'veil-type', 
    'veil-color', 'ring-number', 'ring-type', 'spore-print-color', 
    'population', 'habitat']
# names for subset
col_subset = ['label', 'cap-shape', 'cap-surface', 'cap-color', 'bruises']

mr1 = pd.read_csv(fn, header=None, names=cols, usecols=col_subset)

In [1]: mr1.head()
Out[1]:
  label cap-shape cap-surface cap-color bruises
0     p         x           s         n       t
1     e         x           s         y       t
2     e         b           s         w       t
3     p         x           y         w       t
4     e         x           s         g       f

À ce stade, les données (p, x, s, n, t ...) sont traitées comme un type de chaîne de caractères. D'autre part, dans pandas 0.19.0, vous pouvez entrer comme suit. (Ajout de dtype = 'category')

mr2 = pd.read_csv(fn, header=None, names=cols, usecols=col_subset, dtype='category')

Puisque le type ne peut pas être trouvé en regardant la partie d'en-tête des données, vérifiez le type.

In [4]: mr1.dtypes
Out[4]:
label          object
cap-shape      object
cap-surface    object
cap-color      object
bruises        object
dtype: object

In [5]: mr2.dtypes
Out[5]:
label          category
cap-shape      category
cap-surface    category
cap-color      category
bruises        category
dtype: object

Les données individuelles de mr1 sont de type str, mais le type de données de pd.Series () est ʻobjectde type objet abstrait. D'autre part, il peut être confirmé que mr2 entré avec l'optiondtype = 'category' est correctement converti en category`.

En passant, même dans la version précédente (pandas 0.18.1), les mêmes données que mr2 peuvent être obtenues en effectuant une conversion de type avec ʻas type` après avoir entré le fichier.

mr11 = mr1.apply(lambda x: x.astype('category'))

In [9]: mr11.dtypes
Out[9]:
label          category
cap-shape      category
cap-surface    category
cap-color      category
bruises        category
dtype: object

Pour les données de type Catégorie, certaines fonctions (méthodes) sont prises en charge via l'accesseur cat (abréviation de catégorie). Par exemple, les types de catégories peuvent être obtenus comme suit.

In : mr2['cap-shape'].cat.categories
Out: Index(['b', 'c', 'f', 'k', 's', 'x'], dtype='object')

In : mr2['cap-color'].cat.categories
Out: Index(['b', 'c', 'e', 'g', 'n', 'p', 'r', 'u', 'w', 'y'], dtype='object')

Dans l'opération ci-dessus, l'ordre et l'ordre des types de catégories (listes) obtenus ne sont pas particulièrement déterminés. Une opération similaire est unique () pour l'objet pd.Series.

In : mr2['cap-shape'].unique()
Out:
[x, b, s, f, k, c]
Categories (6, object): [x, b, s, f, k, c]

L'ensemble de résultats obtenu ici est le même que les catégories xx.cat.categories ci-dessus, mais l'ordre de ce résultat est l'ordre d'apparition dans le processus d'analyse de l'ensemble de données (objet pd.Series). chose. (Je ne pense pas qu'il existe de nombreux cas où l'ordre d'apparition a une signification particulière.)

Je souhaite confirmer l'ordre des catégories avec d'autres données. (Voir ci-dessous)

À propos, lorsque l'apprentissage automatique est effectué dans le post-processus d'analyse des données, l'ensemble de données doit être converti en un type numérique (type int, type float). Le type de catégorie des pandas peut être converti en type int par la fonction (méthode) codes comme suit.

In : mr2_numeric = mr2['cap-shape'].cat.codes

In : mr2_numeric[:10]
Out:
0    5
1    5
2    0
3    5
4    5
5    5
6    0
7    0
8    5
9    0
dtype: int8

La valeur de retour pour les valeurs aberrantes non incluses dans la catégorie est «-1» comme indiqué ci-dessous.

In : mr2.loc[3, 'cap-shape'] = np.nan

In : mr2.loc[6, 'cap-shape'] = np.nan

In : mr2['cap-shape'].cat.codes[:10]
Out:                                
0    5                                  
1    5                                  
2    0                                  
3   -1                                  
4    5                                  
5    5                                  
6   -1                                  
7    0                                  
8    5                                  
9    0                                  
dtype: int8                             

Enquête sur la catégorie "Ordonnée"

Le type de catégorie pandas a une option «ordonné». Ici, nous allons confirmer avec un exemple de symboles d'élément. Tout d'abord, préparez les données (pd.Series).

#Fonctions de création d'échantillons de données
def mk_rand_elements():
    elem_dict = {1: 'H', 2: 'He', 3: 'Li', 4: 'Be', 5: 'B', 6: 'C', 7: 'N'}
    sz = 10
    r = np.random.randint(1, 7, size=sz)
    rand_el = [elem_dict[i] for i in r]

    return rand_el

elem_series = pd.Series(mk_rand_elements())

Ensuite, préparez l'ordre correct que vous souhaitez définir avec les variables. (Bien que ce soit un symbole d'élément, je m'en souviens jusqu'à l'azote ...)

elem_ord = ['H', 'He', 'Li', 'Be', 'B', 'C', 'N']

Comme décrit ci-dessus, les variables catégorielles sont créées à partir des séries de données et des données dans le bon ordre.

# convert to categorical and encoding 
elem_cat = elem_series.astype('category', categories=elem_ord, ordered=True)

# check
In : elem_cat
Out:
0     B
1     H
2    Li
3    Be
4    He
5    Li
6     B
7    Li
8    He
9     C
dtype: category
Categories (7, object): [H < He < Li < Be < B < C < N]

Ce à quoi nous voulons prêter attention est la ligne du bas Catégories (7, objet): [H <He <Li <Be <B <C <N]. La partie indiquée par le symbole d'inégalité indique que la variable 'elem_cat' est le dtype de la catégorie ordonnée.

Lorsqu'il est codé dans un type numérique, les valeurs numériques sont données dans l'ordre des catégories.

# Encoding to numeric data
encoded = elem_cat.cat.codes

#En python, le tableau est index=Puisqu'il commence à 0, le tout est décalé
encoded = encoded + 1

#Afficher avant et après Encoder ensemble
result = pd.DataFrame(columns=['elem', 'num'])
result['elem'] = elem_series
result['num'] = encoded

In : result
Out:
  elem  num
0    B    5
1    H    1
2   Li    3
3   Be    4
4   He    2
5   Li    3
6    B    5
7   Li    3
8   He    2
9    C    6

Comme indiqué ci-dessus, on peut voir que la chaîne de données des symboles d'élément est correctement codée en nombres atomiques. En définissant correctement l'ordre de l'extérieur et en définissant l'option «ordonnée» sur «Vrai» de cette manière, l'ordre des catégories peut être conservé. Il n'y a rien dont vous voulez être conscient dans l'ordre des données telles que les caractéristiques de forme des champignons dans le jeu de données "Mushroom", mais par exemple, si les notes de l'élève sont marquées avec ["A", "B", "C", "D"]. De plus, les notations [«AAA», «AA», «A», «BBB», «BB», «B»] souvent utilisées par les sociétés d'investissement ont des informations dans l'ordre lui-même. Dans de tels cas, vous pouvez utiliser la «catégorie ordonnée».

Résumé

Dans l'ensemble du processus d'apprentissage automatique, un ensemble de données constitué de chaînes de caractères, etc. est lu à partir d'un fichier, soumis à un traitement prédéterminé et entré dans un modèle (modèle de classification, modèle de régression). Étant donné que le modèle peut gérer des données numériques, il n'est pas nécessaire de le traiter comme un "type de catégorie" s'il est directement converti d'une chaîne de caractères en une valeur numérique.

Pour la conversion de chaînes de caractères en valeurs numériques, il semble que vous puissiez préparer votre propre fonction et l'appliquer, ou vous pouvez utiliser les fonctions de scicit-learn (pré-traitement). Cependant, comme les fonctions liées aux pandas «catégoriques» étudiées cette fois-ci peuvent également être traitées à l'intérieur des pandas, on s'attend à ce qu'elles soient utilisées à divers endroits, par exemple en voulant l'utiliser avec un cahier Jupyter ou en voulant tracer une figure et la regarder. En d'autres termes, il est considéré comme une fonction pratique que vous connaissez et «ne perdez pas».

(Comme il s'agit d'une fonction qui est entrée en fonction de la mise à niveau de la version dans la demande de fonctionnalité, il semble qu'il y ait une certaine demande.)

(Ajout) date.11 / 21/2016

Il semble y avoir une fonction qui prend en charge la conversion de type catégorique de Pandas appelée pd.factorize ().

>>> myseq = ['a', 'b', 'c', 'a', 'b']
>>> encoded = pd.factorize(myseq)
>>> encoded
(array([0, 1, 2, 0, 1]), array(['a', 'b', 'c'], dtype=object))

La valeur de retour est un tuple composé des données de type numérique converties (indexeur) et des données d'origine uniques. http://pandas.pydata.org/pandas-docs/stable/generated/pandas.factorize.html (Document Pandas)

Références / site web

Recommended Posts

J'ai vérifié la relation catégorique de Pandas - c'est pratique si vous vous y habituez (je pense)
Si vous souhaitez simplement obtenir le fichier de vidage du serveur, il était pratique de créer un serveur http
Que faire si Combinaisons devient «couverture inconnue»
Je veux que Sphinx soit pratique et utilisé par tout le monde