Transformacion December 20, 2020 1 Transformación de datos [38]: import pandas as pd import numpy as np import matplotlib.pyplot as plt from sklearn.preprocessing import MinMaxScaler [15]: # Carga de datos data_frame = pd.read_csv("Churn_Modelling.csv") data_frame.head() [15]: 0 1 2 3 4 RowNumber 1 2 3 4 5 CustomerId 15634602 15647311 15619304 15701354 15737888 0 1 2 3 4 Tenure 2 1 8 1 2 0 1 2 3 4 EstimatedSalary 101348.88 112542.58 113931.57 93826.63 79084.10 Balance 0.00 83807.86 159660.80 0.00 125510.82 Surname Hargrave Hill Onio Boni Mitchell NumOfProducts 1 1 3 2 1 CreditScore Geography 619 France 608 Spain 502 France 699 France 850 Spain HasCrCard 1 0 1 0 1 Gender Female Female Female Female Female IsActiveMember 1 1 0 0 1 Age 42 41 42 39 43 \ \ Exited 1 0 1 0 0 [16]: # Valores nulos for feature in data_frame.columns: print('Total de valores nulos de', feature, '=', data_frame[feature].isna(). ,→sum()) 1 Total Total Total Total Total Total Total Total Total Total Total Total Total Total de de de de de de de de de de de de de de valores valores valores valores valores valores valores valores valores valores valores valores valores valores nulos nulos nulos nulos nulos nulos nulos nulos nulos nulos nulos nulos nulos nulos de de de de de de de de de de de de de de RowNumber = 0 CustomerId = 0 Surname = 0 CreditScore = 0 Geography = 0 Gender = 0 Age = 0 Tenure = 0 Balance = 0 NumOfProducts = 0 HasCrCard = 0 IsActiveMember = 0 EstimatedSalary = 0 Exited = 0 [44]: # Selecciona solo las características que se van a considerar en los␣ ,→posteriores análisis X = data_frame.iloc[:, 3:-1].values # La ùltima columna (sale o no sale) se separa del resto para analizar la␣ ,→relación que tiene ella con el resto y = data_frame.iloc[:, -1].values [25]: pd.DataFrame(X).head(10) [25]: 0 1 2 3 4 5 6 7 8 9 0 619 608 502 699 850 645 822 376 501 684 1 France Spain France France Spain Spain France Germany France France 2 Female Female Female Female Female Male Male Female Male Male 3 42 41 42 39 43 44 50 29 44 27 4 2 1 8 1 2 8 7 4 4 2 5 0 83807.9 159661 0 125511 113756 0 115047 142051 134604 6 1 1 3 2 1 2 2 4 2 1 [28]: pd.DataFrame(y).head(5) [28]: 0 1 2 3 4 0 1 0 1 0 0 2 7 1 0 1 0 1 1 1 1 0 1 8 1 1 0 0 1 0 1 0 1 1 9 101349 112543 113932 93826.6 79084.1 149757 10062.8 119347 74940.5 71725.7 1.1 Transformación de variables categóricas Una variable categórica es aquella que toma valores desde un conjunto limitado de elementos. Se revisarán 3 enfoques para tratar este tipo de variables. Antes de revisarlos es conveniente preguntar ¿por qué deben ser tratadas?, la respuesta: los algoritmos que se revisarán más adelante requieren, muchos de ellos, que las variables sean numéricas. Los enfoques son: 1. Borrar las variables categóricas. Se aplica cuando la columna no aporta mayor valor al análisis. 2. Etiqueta codificada (Label Encoding(. Asigna a cada valor de la lista un número entero diferente. Se debe tener cuidado porque el orden de los números no necesariamente representa el orden de las categorías. 3. One-hot-encoding. Crea nuevas columnas indicando la presencia (o ausencia) de cada posible valor en el set de datos original. Antes de comenzar a trabajar con nuestro set de datos, se revisará primero la forma en que trabaja el Label y el one-hot encoding [36]: from numpy import array from numpy import argmax from sklearn.preprocessing import LabelEncoder from sklearn.preprocessing import OneHotEncoder # define example data = ['frio', 'frio', 'templado', 'frio', 'calor', 'calor', 'templado',␣ ,→'frio', 'templado', 'calor'] values = array(data) print('Valores:',values) # integer encode label_encoder = LabelEncoder() integer_encoded = label_encoder.fit_transform(values) print('Label encoder integer:',integer_encoded) # binary encode onehot_encoder = OneHotEncoder(sparse=False) integer_encoded = integer_encoded.reshape(len(integer_encoded), 1) onehot_encoded = onehot_encoder.fit_transform(integer_encoded) print('one-hot encoder:\n', onehot_encoded) # invert first example inverted = label_encoder.inverse_transform([argmax(onehot_encoded[0, :])]) print(inverted) Valores: ['frio' 'frio' 'templado' 'frio' 'calor' 'calor' 'templado' 'frio' 'templado' 'calor'] Label encoder integer: [1 1 2 1 0 0 2 1 2 0] one-hot encoder: [[0. 1. 0.] [0. 1. 0.] [0. 0. 1.] 3 [0. 1. 0.] [1. 0. 0.] [1. 0. 0.] [0. 0. 1.] [0. 1. 0.] [0. 0. 1.] [1. 0. 0.]] ['frio'] Analizando el resultado anterior La matriz que aparece junto one-hot-encoder es de 3x3; esto es porque se tienen tres valores distintos. Si se revisa la primera fila: [0 1 0] significa que el primer valor corresponde a frío; es decir, la primera columna representa el valor calor (codificado en 0), la segunda es frio (codificada en 1) y la tercera columna es templado (codificada en 2). 1.1.1 Se comienza con la columna que contiene el género [45]: from sklearn.preprocessing import LabelEncoder le = LabelEncoder() X[:, 2] = le.fit_transform(X[:, 2]) pd.DataFrame(X) [45]: 0 1 2 3 4 … … 9995 9996 9997 9998 9999 0 619 608 502 699 850 771 516 709 772 792 1 France Spain France France Spain … .. .. France France France Germany France 2 3 0 42 0 41 0 42 0 39 0 43 .. 1 39 1 35 0 36 1 42 0 28 4 2 1 8 1 2 … 5 10 7 3 4 5 0 83807.9 159661 0 125511 .. .. .. 0 57369.6 0 75075.3 130143 6 1 1 3 2 1 7 1 0 1 0 1 2 1 1 2 1 1 1 0 1 1 8 1 1 0 0 1 9 101349 112543 113932 93826.6 79084.1 0 1 1 0 0 96270.6 101700 42085.6 92888.5 38190.8 … [10000 rows x 10 columns] Para el caso de la columna de Geografía (columna 1 en el dataframe anterior) se usará el tercer enfoque [46]: # Primero se revisan los valores únicos pd.DataFrame(X)[1].unique() [46]: array(['France', 'Spain', 'Germany'], dtype=object) 4 Se observan 3 valores distintos, por lo que se espera que se agreguen 3 columnas y que cada una de ellas contenga 0 (ausencia) o 1 (presencia) del valor original [47]: from sklearn.compose import ColumnTransformer from sklearn.preprocessing import OneHotEncoder ct = ColumnTransformer(transformers=[('encoder', OneHotEncoder(), [1])],␣ ,→remainder='passthrough') X = np.array(ct.fit_transform(X)) pd.DataFrame(X) [47]: 0 1 2 3 4 … .. 9995 9996 9997 9998 9999 0 1 0 1 1 0 .. 1 1 1 0 1 1 0 0 0 0 0 .. 0 0 0 1 0 2 0 1 0 0 1 … 0 0 0 0 0 3 4 619 0 608 0 502 0 699 0 850 0 .. .. 771 1 516 1 709 0 772 1 792 0 5 42 41 42 39 43 .. 39 35 36 42 28 6 2 1 8 1 2 5 10 7 3 4 7 8 0 1 83807.9 1 159661 3 0 2 125511 1 … .. .. .. 0 2 57369.6 1 0 1 75075.3 2 130143 1 9 10 1 1 0 1 1 0 0 0 1 1 … 1 0 1 1 0 1 1 0 1 0 11 101349 112543 113932 93826.6 79084.1 96270.6 101700 42085.6 92888.5 38190.8 [10000 rows x 12 columns] 1.1.2 Comprobando la salida Se visualizan 3 columnas al inicio de la matriz; si se considera la primera fila es (1,0,0) y sabiendo que el orden sería (France, Germany y Spain) indica que la primera observación sería de France. El mismo análisis se hace para la segunda fila (0,0,1) que corresponde a Spain 1.2 Escalar las características Existen varias alternativas: 1. StandardScaler 2. MinMaxScaler [49]: from sklearn.preprocessing import StandardScaler sc = StandardScaler() scaled_data = sc.fit_transform(X) pd.DataFrame(scaled_data).head() [49]: 0 0 1 2 3 4 0.997204 -0.578736 -0.573809 -0.326221 -1.095988 5 5 6 0.293517 -1.041760 \ 1 -1.002804 -0.578736 1.742740 -0.440036 -1.095988 2 0.997204 -0.578736 -0.573809 -1.536794 -1.095988 3 0.997204 -0.578736 -0.573809 0.501521 -1.095988 4 -1.002804 -0.578736 1.742740 2.063884 -1.095988 0.198164 -1.387538 0.293517 1.032908 0.007457 -1.387538 0.388871 -1.041760 7 8 9 10 11 0 -1.225848 -0.911583 0.646092 0.970243 0.021886 1 0.117350 -0.911583 -1.547768 0.970243 0.216534 2 1.333053 2.527057 0.646092 -1.030670 0.240687 3 -1.225848 0.807737 -1.547768 -1.030670 -0.108918 4 0.785728 -0.911583 0.646092 0.970243 -0.365276 [51]: scaler = MinMaxScaler() scaled_data_1 = sc.fit_transform(X) pd.DataFrame(scaled_data_1).head() [51]: 0 1 2 3 4 0 0.997204 -0.578736 -0.573809 -0.326221 -1.095988 1 -1.002804 -0.578736 1.742740 -0.440036 -1.095988 2 0.997204 -0.578736 -0.573809 -1.536794 -1.095988 3 0.997204 -0.578736 -0.573809 0.501521 -1.095988 4 -1.002804 -0.578736 1.742740 2.063884 -1.095988 0 1 2 3 4 5 0.293517 0.198164 0.293517 0.007457 0.388871 6 -1.041760 -1.387538 1.032908 -1.387538 -1.041760 \ 7 8 9 10 11 -1.225848 -0.911583 0.646092 0.970243 0.021886 0.117350 -0.911583 -1.547768 0.970243 0.216534 1.333053 2.527057 0.646092 -1.030670 0.240687 -1.225848 0.807737 -1.547768 -1.030670 -0.108918 0.785728 -0.911583 0.646092 0.970243 -0.365276 [53]: pd.DataFrame(scaled_data_1).describe() [53]: 0 1 2 3 4 count 1.000000e+04 1.000000e+04 1.000000e+04 1.000000e+04 1.000000e+04 mean 1.143974e-16 -1.989520e-17 5.684342e-17 -4.824585e-16 8.455459e-17 std 1.000050e+00 1.000050e+00 1.000050e+00 1.000050e+00 1.000050e+00 min -1.002804e+00 -5.787359e-01 -5.738092e-01 -3.109504e+00 -1.095988e+00 25% -1.002804e+00 -5.787359e-01 -5.738092e-01 -6.883586e-01 -1.095988e+00 50% 9.972039e-01 -5.787359e-01 -5.738092e-01 1.522218e-02 9.124191e-01 75% 9.972039e-01 1.727904e+00 -5.738092e-01 6.981094e-01 9.124191e-01 max 9.972039e-01 1.727904e+00 1.742740e+00 2.063884e+00 9.124191e-01 \ 5 6 7 8 9 count 1.000000e+04 1.000000e+04 1.000000e+04 1.000000e+04 1.000000e+04 mean 2.414069e-16 -1.325162e-16 6.218670e-15 7.105427e-19 -2.273737e-17 std 1.000050e+00 1.000050e+00 1.000050e+00 1.000050e+00 1.000050e+00 min -1.994969e+00 -1.733315e+00 -1.225848e+00 -9.115835e-01 -1.547768e+00 \ 6 25% 50% 75% max -6.600185e-01 -6.959818e-01 -1.225848e+00 -9.115835e-01 -1.547768e+00 -1.832505e-01 -4.425957e-03 3.319639e-01 -9.115835e-01 6.460917e-01 4.842246e-01 6.871299e-01 8.199205e-01 8.077366e-01 6.460917e-01 5.061197e+00 1.724464e+00 2.795323e+00 4.246377e+00 6.460917e-01 10 11 count 1.000000e+04 1.000000e+04 mean 6.394885e-18 3.519141e-15 std 1.000050e+00 1.000050e+00 min -1.030670e+00 -1.740268e+00 25% -1.030670e+00 -8.535935e-01 50% 9.702426e-01 1.802807e-03 75% 9.702426e-01 8.572431e-01 max 9.702426e-01 1.737200e+00 [55]: df_x = pd.DataFrame(scaled_data) df_x.head() [55]: 0 1 2 3 4 0 0.997204 -1.002804 0.997204 0.997204 -1.002804 1 2 3 4 -0.578736 -0.573809 -0.326221 -1.095988 -0.578736 1.742740 -0.440036 -1.095988 -0.578736 -0.573809 -1.536794 -1.095988 -0.578736 -0.573809 0.501521 -1.095988 -0.578736 1.742740 2.063884 -1.095988 0 1 2 3 4 7 8 9 10 11 -1.225848 -0.911583 0.646092 0.970243 0.021886 0.117350 -0.911583 -1.547768 0.970243 0.216534 1.333053 2.527057 0.646092 -1.030670 0.240687 -1.225848 0.807737 -1.547768 -1.030670 -0.108918 0.785728 -0.911583 0.646092 0.970243 -0.365276 [ ]: 7 5 0.293517 0.198164 0.293517 0.007457 0.388871 6 -1.041760 -1.387538 1.032908 -1.387538 -1.041760 \