Skip to content

Commit 0469b07

Browse files
committed
work-04-04-2019
1 parent 50525ba commit 0469b07

File tree

1 file changed

+134
-5
lines changed

1 file changed

+134
-5
lines changed

manipulando_dados_categoricos.py

Lines changed: 134 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import pandas as pd
2-
2+
import numpy as np
33

44
"""
55
Até agora, temos trabalhado apenas com valores numéricos. No entanto, não é incomum
@@ -19,23 +19,152 @@
1919
para uma tarefa de aprendizado supervisionada) são armazenados na última coluna. Os
2020
algoritmos de aprendizado para classificação que discutimos neste livro não usam
2121
informações ordinais em rótulos de classes.
22+
"""
23+
24+
df = pd.DataFrame([['green', 'M', 10.1, 'class1'],['red', 'L', 13.5, 'class2'],['blue', 'XL', 15.3, 'class1']])
25+
df.columns = ['color', 'size', 'price', 'classlabel']
26+
27+
print(df)
28+
29+
"""
30+
Mapeando atributos ordinais
31+
"""
2232

33+
"""
2334
Para certificar-se de que o algoritmo de aprendizado interpreta os recursos ordinais
2435
corretamente, precisamos converter os valores das cadeias categóricas em inteiros.
2536
Infelizmente, não há nenhuma função conveniente que possa derivar automaticamente a ordem
2637
correta das etiquetas do nosso recurso de tamanho. Assim, temos que definir o mapeamento
2738
manualmente. No exemplo simples a seguir, vamos supor que sabemos a diferença entre
2839
os recursos, por exemplo, XL = L + 1 = M + 2.
40+
"""
2941

42+
size_mapping = {'XL': 3, 'L': 2, 'M': 1}
43+
df['size'] = df['size'].map(size_mapping)
44+
45+
print(df)
46+
47+
"""
48+
Se quisermos transformar os valores inteiros de volta para a representação de string
49+
original em um estágio posterior, podemos simplesmente definir um dicionário de
50+
mapeamento inverso inv_size_mapping = {v: k for k, v in size_mapping.items()}
51+
que pode ser usado por meio de o método de mapa dos pandas na coluna de recurso
52+
transformado semelhante ao dicionário size_mapping que usamos anteriormente.
3053
"""
3154

32-
df = pd.DataFrame([['green', 'M', 10.1, 'class1'],['red', 'L', 13.5, 'class2'],['blue', 'XL', 15.3, 'class1']])
33-
df.columns = ['color', 'size', 'price', 'classlabel']
55+
56+
"""
57+
Codificando rótulos de classes
58+
"""
59+
60+
"""
61+
Muitas bibliotecas de aprendizado de máquina exigem que os rótulos de classe sejam
62+
codificados como valores inteiros. Embora a maioria dos estimadores para classificação
63+
em scikit-learn converta rótulos de classe para inteiros internamente, considera-se
64+
boa prática fornecer rótulos de classe como matrizes inteiras para evitar falhas
65+
técnicas. Para codificar os rótulos de classe, podemos usar uma abordagem semelhante
66+
ao mapeamento dos recursos ordinais discutidos anteriormente. Precisamos lembrar que
67+
os rótulos de classe não são ordinais e não importa qual número inteiro atribuímos a
68+
um determinado rótulo de sequência. Assim, podemos simplesmente enumerar os rótulos
69+
de classe começando em 0
70+
"""
71+
72+
73+
class_mapping = {label:idx for idx,label in enumerate(np.unique(df['classlabel']))}
74+
print(class_mapping)
75+
df['classlabel'] = df['classlabel'].map(class_mapping)
3476

3577
print(df)
3678

37-
size_mapping = {'XL': 3, 'L': 2, 'M': 1}
38-
df['size'] = df['size'].map(size_mapping)
79+
80+
"""
81+
Podemos inverter os pares de valor-chave no dicionário de mapeamento da seguinte
82+
forma para mapear os rótulos de classe convertidos de volta para a representação
83+
de sequência original:
84+
"""
85+
86+
inv_class_mapping = {v: k for k, v in class_mapping.items()}
87+
df['classlabel'] = df['classlabel'].map(inv_class_mapping)
3988

4089
print(df)
4190

91+
"""
92+
Alternativamente, há uma classe LabelEncoder conveniente implementada diretamente
93+
no scikit-learn para obter o mesmo:
94+
"""
95+
96+
from sklearn.preprocessing import LabelEncoder
97+
class_le = LabelEncoder()
98+
y = class_le.fit_transform(df['classlabel'].values)
99+
print(y)
100+
101+
102+
"""
103+
Note que o método fit_transform é apenas um atalho para chamar fit e transform
104+
separadamente, e podemos usar o método inverse_transform para transformar os
105+
rótulos de classes inteiras de volta em sua representação de string original:
106+
"""
107+
y = class_le.inverse_transform(y)
108+
print(y)
109+
110+
111+
"""
112+
Executando one-hot enconding em atributos nominais
113+
"""
114+
115+
"""
116+
Como os estimadores do scikit-learn tratam os rótulos de classe sem qualquer
117+
ordem, usamos a conveniente classe LabelEncoder para codificar os rótulos de
118+
string em inteiros. Pode parecer que poderíamos usar uma abordagem semelhante
119+
para transformar a coluna de cor nominal do nosso conjunto de dados, da seguinte forma:
120+
"""
121+
122+
X = df[['color', 'size', 'price']].values
123+
color_le = LabelEncoder()
124+
X[:, 0] = color_le.fit_transform(X[:, 0])
125+
126+
print(X)
127+
128+
"""
129+
Se pararmos nesse ponto e alimentarmos o array para nosso classificador, faremos
130+
um dos erros mais comuns ao lidar com dados categóricos. Você pode identificar o
131+
problema? Embora os valores das cores não estejam em nenhuma ordem específica,
132+
um algoritmo de aprendizado agora assumirá que verde é maior que azul e vermelho
133+
é maior que verde. Embora essa suposição esteja incorreta, o algoritmo ainda
134+
pode produzir resultados úteis. No entanto, esses resultados não seriam ótimos.
135+
136+
Uma solução comum para esse problema é usar uma técnica chamada codificação
137+
simples (one-hot encoding). A ideia por trás dessa abordagem é criar
138+
um novo atributo fictício (dummy feature) para cada valor exclusivo na coluna
139+
de recurso nominal. Aqui, converteríamos o atributo
140+
de cores em três novos recursos: azul, verde e vermelho. Valores binários podem então
141+
ser usados para indicar a cor particular de uma amostra; por exemplo, uma amostra
142+
azul pode ser codificada como azul = 1, verde = 0, vermelho = 0. Para realizar
143+
essa transformação, podemos usar o OneHotEncoder implementado no módulo
144+
scikit-learn.preprocessing:
145+
146+
Quando inicializamos o OneHotEncoder, definimos a posição da coluna da variável
147+
que queremos transformar por meio do parâmetro categorical_features (observe que
148+
a cor é a primeira coluna na matriz de recursos X). Por padrão, o OneHotEncoder
149+
retorna uma matriz esparsa quando usamos o método transform e convertemos a
150+
representação de matriz esparsa em uma matriz NumPy regular (densa) para fins
151+
de visualização por meio do método toarray. As matrizes esparsas são simplesmente
152+
uma maneira mais eficiente de armazenar grandes conjuntos de dados e uma que é
153+
suportada por muitas funções scikit-learn, o que é especialmente útil se contiver
154+
muitos zeros. Para omitir a etapa toarray, poderíamos inicializar o codificador
155+
como OneHotEncoder (..., sparse = False) para retornar uma matriz NumPy regular.
156+
"""
157+
158+
from sklearn.preprocessing import OneHotEncoder
159+
ohe = OneHotEncoder(categorical_features=[0])
160+
ohe.fit_transform(X).toarray()
161+
162+
163+
"""
164+
Uma maneira ainda mais conveniente de criar esses recursos fictícios por meio
165+
de uma codificação simples é usar o método get_dummies implementado em pandas.
166+
Aplicado em um DataFrame, o método get_dummies só converterá colunas de string
167+
e deixará todas as outras colunas inalteradas:
168+
"""
169+
pd.get_dummies(df[['price', 'color', 'size']])
170+

0 commit comments

Comments
 (0)