[PYTHON] Ich habe Pandas 'kategoriale Beziehung überprüft - es ist praktisch, wenn man sich daran gewöhnt (glaube ich).

"Pandas", die Datenanalyse unterstützen, aber neulich (02.10.2016) ver. 0.19.0 (stabil) wurde veröffentlicht. Unter einigen neuen Funktionen gibt es eine Option für "read_csv ()", um die "kategorialen" Daten zu scannen (zu analysieren). Wenn ich von "kategorialen" Daten spreche, fällt mir der Faktortyp der R-Sprache ein, aber ich habe die kategorialen Funktionen von Pandas nie verwendet. Ich war neugierig, also nutzte ich die Gelegenheit von Version 0.19.0 und recherchierte.

(Die Betriebsumgebung ist Pandas 0.19.0 (zum Vergleich werden etwa 0.18.1 verwendet), Numpy 1.11.1 und Python ist 3.5.2.)

Vergleich des Unterstützungsstatus von Pandas'Categorical mit der R-Sprache

In der Sprache R wird ein Variablentyp namens Faktortyp (Faktortyp) unterstützt. Dies ist ein Typ, der in allgemeinen Programmiersprachen nicht zu finden ist, daher ist es schwierig, sich daran zu gewöhnen, aber er ist für die Verarbeitung von Daten vom Typ Kategorie vorbereitet. Es scheint jedoch, dass selbst R-Programmierer es mögen und nicht mögen, und es scheint, dass es einige Leute gibt, die "stingAsFactor = FALSE" angeben, um die Konvertierung von Daten in einen Faktortyp bei der Eingabe aus der CSV-Datei in "data.frame" zu unterdrücken. .. (Hinweis. In read.csv (), {data.table} fread () lautet der Standardwert "stringAsFactor = TURE" (sofern sich der Benutzerstandard nicht ändert).

Natürlich gibt es in Python keinen Faktortyp in den Sprachspezifikationen, aber es scheint, dass der kategoriale Typ (dtype) in Pandas seit Version 0.15.0 unterstützt wird (möglicherweise handelt es sich um eine Funktionsanforderung eines Programmierers, der an den R-Faktortyp gewöhnt ist). (Ich wusste es nicht...)

Dieses Mal wurde in Version 0.19.0 die Funktion erweitert, sodass die Kategorie mit read_csv () analysiert werden kann und Operationen unter Berücksichtigung der Kategorie wie Datenverkettung ausgeführt werden können.

** Zitiert aus der Dokumentation ** pandas_cat_1.PNG

(Der Kategorietyp von Pandas ist eine Implementierung, die sich des Faktortyps der R-Sprache bewusst ist, aber es scheint einen Unterschied zwischen den beiden in den Details zu geben. Ich habe keine Auflösung dafür. Wenn Sie also interessiert sind, Pandas Bitte beziehen Sie sich auf das Dokument (Version 0.19.0).)

Funktionsprüfung anhand des Datensatzes "Pilz"

Lassen Sie uns nun den folgenden Vorgang überprüfen. "Mushroom" wurde vorbereitet und als Datensatz aus dem UCI-Repository für maschinelles Lernen verwendet. Der Inhalt von "Pilz" besteht darin, anhand der Merkmale wie der Form des Pilzes zu klassifizieren, ob ein Pilz ein giftiger Pilz ist oder nicht, und der Inhalt (Kopfteil) ist wie folgt.

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

Die Daten bestehen ausschließlich aus alphabetischen Zeichen und sind perfekt für diesen Artikel. Die erste Spalte ist eine Beschriftung, die ** "e" ** .. "essbar" "essbar", ** "p" ** .. "giftig" "giftig" angibt.

Wenn Sie dies als normale Datei eingeben, sieht es wie folgt aus.

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

Zu diesem Zeitpunkt werden die Daten (p, x, s, n, t ...) als Zeichenfolgentyp behandelt. Auf der anderen Seite können Sie in Pandas 0.19.0 Folgendes eingeben. (Hinzugefügt dtype = 'category')

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

Da der Typ nicht anhand des Header-Teils der Daten gefunden werden kann, überprüfen Sie den dtype.

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

Die einzelnen Daten von mr1 sind vom Typ "str", aber der Datentyp von pd.Series () ist der abstrakte Objekttyp "object". Andererseits kann bestätigt werden, dass mr2, das mit der Option "dtype =" category "eingegeben wurde, ordnungsgemäß in" category "konvertiert wurde.

Übrigens können auch in der vorherigen Version (Pandas 0.18.1) die gleichen Daten wie mr2 erhalten werden, indem nach der Eingabe der Datei eine Typkonvertierung mit "als Typ" durchgeführt wird.

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

Für Kategorietypdaten werden einige Funktionen (Methoden) über den Accessor cat (Abkürzung für Kategorie) unterstützt. Zum Beispiel können die Arten von Kategorien wie folgt erhalten werden.

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')

Bei der obigen Operation werden die Reihenfolge und die Reihenfolge der erhaltenen Kategorietypen (Listen) nicht besonders bestimmt. Eine ähnliche Operation ist unique () für das pd.Series-Objekt.

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

Die hier erhaltene Ergebnismenge ist dieselbe wie die obigen xx.cat.categories, aber die Reihenfolge dieses Ergebnisses ist die Reihenfolge des Auftretens beim Scannen des Datensatzes (pd.Series-Objekt). Ding. (Ich glaube nicht, dass es viele Fälle gibt, in denen die Reihenfolge des Auftretens eine besondere Bedeutung hat.)

Ich möchte die Reihenfolge der Kategorien mit anderen Daten bestätigen. (Siehe unten)

Übrigens, wenn maschinelles Lernen im Nachprozess der Datenanalyse durchgeführt wird, muss der Datensatz in einen numerischen Typ (int-Typ, float-Typ) konvertiert werden. Der Kategorietyp von Pandas kann wie folgt durch die Funktion Codes (Methode) in den Typ int konvertiert werden.

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

Der Rückgabewert für Ausreißer, die nicht in der Kategorie enthalten sind, beträgt "-1" (siehe unten).

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                             

Umfrage zur Kategorie "Bestellt"

Der Pandas-Kategorietyp verfügt über eine "geordnete" Option. Hier werden wir mit einem Beispiel von Elementsymbolen bestätigen. Bereiten Sie zuerst die Daten vor (pd.Series).

#Funktionen zum Erstellen von Datenproben
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())

Bereiten Sie als Nächstes die richtige Reihenfolge vor, die Sie mit Variablen festlegen möchten. (Obwohl es ein Elementsymbol ist, kann ich mich bis zu Stickstoff daran erinnern ...)

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

Wie oben beschrieben, werden kategoriale Variablen aus den Datenreihen und den Daten in der richtigen Reihenfolge erstellt.

# 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]

Was wir beachten wollen, ist das Endergebnis "Kategorien (7, Objekt): [H <He <Li <Be <B <C <N]". Der durch das Ungleichheitssymbol angegebene Teil gibt an, dass die Variable 'elem_cat' der dtype der geordneten Kategorie ist.

Wenn dies in einen numerischen Typ codiert ist, werden die numerischen Werte in der Reihenfolge der Kategorien angegeben.

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

#In Python ist das Array Index=Da es bei 0 beginnt, wird das Ganze versetzt
encoded = encoded + 1

#Vor und nach dem Codieren zusammen anzeigen
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

Wie oben gezeigt, ist ersichtlich, dass die Datenzeichenfolge von Elementsymbolen ordnungsgemäß in Ordnungszahlen codiert ist. Indem Sie die Reihenfolge von außen richtig einstellen und die Option "bestellt" auf diese Weise auf "Wahr" setzen, kann die Reihenfolge der Kategorien beibehalten werden. Es gibt nichts, was Sie in der Reihenfolge der Daten beachten möchten, wie z. B. die Formmerkmale von Pilzen im Datensatz "Pilz", aber zum Beispiel, wenn die Noten des Schülers mit ['A', 'B', 'C', 'D'] gekennzeichnet sind. Darüber hinaus enthalten die von Investmentgesellschaften häufig verwendeten Ratings ['AAA', 'AA', 'A', 'BBB', 'BB', 'B'] Informationen in der Bestellung selbst. In solchen Fällen möchten Sie möglicherweise die 'geordnete Kategorie' verwenden.

Zusammenfassung

Während des gesamten Prozesses des maschinellen Lernens wird ein Datensatz, der aus Zeichenketten usw. besteht, aus einer Datei gelesen, einer vorbestimmten Verarbeitung unterzogen und in ein Modell (Klassifizierungsmodell, Regressionsmodell) eingegeben. Da das Modell numerische Daten verarbeiten kann, muss es nicht als "Kategorietyp" verarbeitet werden, wenn es direkt von einer Zeichenfolge in einen numerischen Wert konvertiert wird.

Für die Konvertierung von Zeichenfolgen in numerische Werte können Sie anscheinend Ihre eigene Funktion vorbereiten und anwenden oder die Funktionen von scicit-learn (Vorverarbeitung) verwenden. Da die Funktionen, die sich auf Pandas "Categorical" beziehen, die diesmal untersucht wurden, auch innerhalb von Pandas verarbeitet werden können, wird erwartet, dass sie an verschiedenen Orten verwendet werden, z. B. um sie in einem Jupyter-Notizbuch zu verwenden, eine Figur zu zeichnen und sie anzusehen. Mit anderen Worten, es wird als eine bequeme Funktion angesehen, die Sie kennen und "nicht verlieren".

(Da es sich um eine Funktion handelt, die gemäß dem Versions-Upgrade in der Funktionsanforderung eingegeben wird, scheint eine bestimmte Anforderung zu bestehen.)

(Ergänzung) Datum.11 / 21/2016

Es scheint "pd.factorize ()" als eine Funktion zu geben, die die kategoriale Typkonvertierung von Pandas unterstützt.

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

Der Rückgabewert ist ein Tupel, das aus den konvertierten numerischen Datendaten (Indexer) und den eindeutigen Originaldaten besteht. http://pandas.pydata.org/pandas-docs/stable/generated/pandas.factorize.html (Pandas Dokument)

Referenzen / Website

Recommended Posts

Ich habe Pandas 'kategoriale Beziehung überprüft - es ist praktisch, wenn man sich daran gewöhnt (glaube ich).
Wenn Sie nur die Dump-Datei des Servers abrufen möchten, war es praktisch, einen http-Server zu erstellen
Was tun, wenn Overalls "Abdeckung unbekannt" werden?
Ich möchte, dass Sphinx bequem ist und von allen benutzt wird