scikit-learn https://interactivechaos.ovh/es es sklearn.model_selection.train_test_split https://interactivechaos.ovh/es/python/function/sklearnmodelselectiontraintestsplit <span class="field field--name-title field--type-string field--label-hidden">sklearn.model_selection.train_test_split</span> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/es/user/1" typeof="schema:Person" property="schema:name" datatype="">admin</span></span> <span class="field field--name-created field--type-created field--label-hidden">Dom, 28/04/2019 - 11:10</span> <div class="field field--name-field-fun-python-nombre-completo field--type-string field--label-above"> <div class="field__label">Nombre completo</div> <div class="field__item">sklearn.model_selection.train_test_split</div> </div> <div class="field field--name-field-libreria field--type-entity-reference field--label-above"> <div class="field__label">Librería</div> <div class="field__item">scikit-learn</div> </div> <div class="clearfix text-formatted field field--name-field-funcion-python-sintaxis field--type-text-long field--label-above"> <div class="field__label">Sintaxis</div> <div class="field__item"><p>sklearn.model_selection.train_test_split(*arrays, **options)</p></div> </div> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-above"> <div class="field__label">Descripción</div> <div class="field__item"><p>La función <a href="https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html" target="_blank">sklearn.model_selection.train_test_split</a> nos permite dividir un dataset en dos bloques, típicamente bloques destinados al entrenamiento y validación del modelo (llamemos a estos bloques "bloque de entrenamiento " y "bloque de pruebas" para mantener la coherencia con el nombre de la función).</p> </div> </div> <div class="clearfix text-formatted field field--name-field-ejemplos field--type-text-long field--label-above"> <div class="field__label">Ejemplos</div> <div class="field__items"> <div class="field__item"><p>Para probarlo comencemos cargando un dataset:</p> <div class="codigo"> <p>titanic = sns.load_dataset("titanic")<br /> titanic.head(1)</p> </div> <img alt="Dataset Titanic" data-entity-type="file" data-entity-uuid="99570b9f-ec2f-4f22-80d1-2c24b10e65c0" src="/sites/default/files/inline-images/tutorial_ml_018.png" class="align-center" width="785" height="58" loading="lazy" /><p>Veamos el tamaño de este dataset:</p> <div class="codigo">titanic.shape</div> <div class="respuesta">(891, 15)</div> <p>891 filas y 15 características (de las que una de ellas es la variable objetivo).</p> <p>Si pasamos como argumento a train_test_split el dataset completo, nos devolverá dos subconjuntos del mismo, escogiendo un cierto número de filas para el subconjunto de entrenamiento y el resto para el subconjunto de pruebas:</p> <div class="codigo"> <p>from sklearn.model_selection import train_test_split</p> </div> <div class="codigo"> <p>train, test = train_test_split(titanic, random_state = 0)</p> </div> <div class="codigo"> <p>print(train.shape)<br /> print(test.shape)</p> </div> <img alt="Tamaño de los bloques de entrenamiento y pruebas resultantes" data-entity-type="file" data-entity-uuid="049a078e-0369-4838-b022-c9d8391c0399" src="/sites/default/files/inline-images/tutorial_ml_019.png" class="align-center" width="85" height="43" loading="lazy" /><p>Salvo que se le indique otra cosa, la función train_test_split añade al bloque de entrenamiento el 75% de los registros, y al bloque de pruebas el 25% restante. Podemos controlar estas cifras con los parámetros <strong>train_size</strong> y <strong>test_size</strong>. Estos parámetros pueden ser números enteros, indicando exactamente el número de registros a incluir, o un número real, en cuyo caso indican el porcentaje del total de registros a incluir.</p> <p>Una vez generados los bloques de entrenamiento y pruebas, podemos extraer la variable objetivo para crear, de esta forma, las estructuras que típicamente exigen los algoritmos para su entrenamiento.</p> <p>El parámetro <strong>random_state</strong> simplemente fija una semilla para el generador de números aleatorios, lo que permite reproducir la función.</p> <p>El parámetro <strong>shuffle</strong> (que toma el valor True por defecto) especifica si los registros deberán ser desordenados previamente o no.</p> <p>Si pasamos a la función, no un dataset, sino dos estructuras de la misma longitud (típicamente el bloque de características y la variable objetivo), train_test_split va a generar bloques de entrenamiento y pruebas para ambas estructuras, haciendo innecesaria la división posterior entre bloque de características y variable objetivo:</p> <div class="codigo"> <p>y = titanic.pop("survived")<br /> X = titanic</p> </div> <div class="codigo"> <p>X_train, y_train, X_test, y_test = train_test_split(X, y)</p> </div> <div class="codigo"> <p>X_train.shape</p> </div> <div class="respuesta">(668, 14)</div> <div class="codigo"> <p>X_train.head(2)</p> </div> <img alt="train_test_split" data-entity-type="file" data-entity-uuid="52521bad-339f-4b0f-9087-b3016b0b7843" src="/sites/default/files/inline-images/tutorial_ml_020.png" class="align-center" width="756" height="85" loading="lazy" /></div> <div class="field__item"><p>La función train_test_split divide el dataset de forma aleatoria, lo que puede provocar que la distribución de alguna característica no sea la esperada. Veamos un ejemplo con el mismo dataset:</p> <div class="codigo"> <p>titanic = sns.load_dataset("titanic")</p> </div> <div class="codigo"> <p>train, test = train_test_split(titanic)</p> </div> <p>La característica "<em>who</em>" del dataset Titanic indica si el pasajero en cuestión era un hombre adulto, una mujer adulta o un niño. Comencemos viendo cuál es el porcentaje de estos valores en el dataset original:</p> <div class="codigo"> <p>titanic.groupby("who")["survived"].count()/len(titanic)</p> </div> <img alt="Distribución de los valores de la característica &quot;who&quot; en el dataset completo" data-entity-type="file" data-entity-uuid="0152466b-c41c-48d6-9e19-7c5d7cb307c7" src="/sites/default/files/inline-images/tutorial_ml_023.png" class="align-center" width="343" height="94" loading="lazy" /><p>Y veamos ahora cuál es el porcentaje de estos registros en los bloques train y test generados:</p> <div class="codigo"> <p>train.groupby("who")["survived"].count()/len(train)</p> </div> <img alt="Distribución de los valores de la característica &quot;who&quot; en el bloque de entrenamiento" data-entity-type="file" data-entity-uuid="aacc30d9-c9a5-4f37-b667-38662731ad06" src="/sites/default/files/inline-images/tutorial_ml_021.png" class="align-center" width="303" height="90" loading="lazy" /><div class="codigo"> <p>test.groupby("who")["survived"].count()/len(test)</p> </div> <img alt="Distribución de los valores de la característica &quot;who&quot; en el bloque de pruebas" data-entity-type="file" data-entity-uuid="c7f1e75b-8dad-4be5-b7bf-5e0b2e707acc" src="/sites/default/files/inline-images/tutorial_ml_022.png" class="align-center" width="308" height="93" loading="lazy" /><p>Aun cuando esta característica está razonablemente bien distribuida, vemos que hay diferencias con respecto a la distribución original en el dataset de hasta un 3% (por ejemplo en el porcentaje de hombres adultos del bloque de pruebas).</p> <p>Pues bien, el parámetro <strong>stratify</strong> nos permite generar los bloques de entrenamiento y pruebas preservando en ambos el porcentaje de las muestras del dataset original. Para ello hay que indicar en este parámetro cuál es el array de valores -que se asociarán a los datos- que determinan las etiquetas cuyas distribuciones se desea preservar. El ejemplo más sencillo es cuando pasamos a este parámetro una característica del dataset:</p> <div class="codigo"> <p>train, test = train_test_split(titanic, stratify = titanic["who"])</p> </div> <p>Si ahora volvemos a analizar el porcentaje de muestras con los valores que toma esta característica en los bloques de datos generados:</p> <div class="codigo"> <p>train.groupby("who")["survived"].count()/len(train)</p> </div> <img alt="Distribución de los valores de la característica &quot;who&quot; en el bloque de entrenamiento" data-entity-type="file" data-entity-uuid="53de1f94-3b53-4660-ac45-7d3f5c75bf07" src="/sites/default/files/inline-images/tutorial_ml_024.png" class="align-center" width="346" height="94" loading="lazy" /><div class="codigo"> <p>test.groupby("who")["survived"].count()/len(test)</p> </div> <img alt="Distribución de los valores de la característica &quot;who&quot; en el bloque de pruebas" data-entity-type="file" data-entity-uuid="ffea4130-7cd7-4c43-ba49-b0c52df0c266" src="/sites/default/files/inline-images/tutorial_ml_025.png" class="align-center" width="328" height="92" loading="lazy" /><p>...comprobamos que son cifras muy próximas a las originales, tal y como queríamos.</p> <p>Esta opción está especialmente indicada en datasets muy desequilibrados, en los que una división del mismo puede incluso dejar todos los registros con cierto valor en una característica en un único bloque.</p> </div> </div> </div> Sun, 28 Apr 2019 09:10:21 +0000 admin 1131 at https://interactivechaos.ovh SimpleImputer https://interactivechaos.ovh/es/python/function/simpleimputer <span class="field field--name-title field--type-string field--label-hidden">SimpleImputer</span> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/es/user/1" typeof="schema:Person" property="schema:name" datatype="">admin</span></span> <span class="field field--name-created field--type-created field--label-hidden">Dom, 28/04/2019 - 10:57</span> <div class="field field--name-field-fun-python-nombre-completo field--type-string field--label-above"> <div class="field__label">Nombre completo</div> <div class="field__item">sklearn.impute.SimpleImputer</div> </div> <div class="field field--name-field-libreria field--type-entity-reference field--label-above"> <div class="field__label">Librería</div> <div class="field__item">scikit-learn</div> </div> <div class="clearfix text-formatted field field--name-field-funcion-python-sintaxis field--type-text-long field--label-above"> <div class="field__label">Sintaxis</div> <div class="field__item"><p>class sklearn.impute.SimpleImputer(missing_values=nan, strategy=’mean’, fill_value=None, verbose=0, copy=True)</p></div> </div> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-above"> <div class="field__label">Descripción</div> <div class="field__item"><p>La función <a href="https://scikit-learn.org/stable/modules/generated/sklearn.impute.SimpleImputer.html" target="_blank">sklearn.impute.SimpleImputer</a> permite sustituir valores nulos por otros valores según varias estrategias disponibles. La estrategia a ejecutar se indica mediante el parámetro <strong>strategy</strong>.</p> <p>Una vez instanciado el imputador, puede entrenarse con el método <strong>fit</strong> (que genera un array conteniendo los valores por los que sustituir los valores nulos de cada característica) y puede ejecutarse la sustitución con el método <strong>transform</strong>. El atributo <strong>statistics_</strong> nos da acceso al array de valores a imputar (uno por cada característica). Debe tenerse en cuenta que el resultado del imputador es un array NumPy, no un dataframe.</p> </div> </div> <div class="clearfix text-formatted field field--name-field-parametros field--type-text-long field--label-above"> <div class="field__label">Parámetros</div> <div class="field__item"><ul><li><strong>missing_values</strong>: Objeto que representa un valor nulo. Puede ser un número, una cadena de texto, np.ana (valor por defecto) o None.</li> <li><strong>strategy</strong>: Estrategia a ejecutar. Puede tomar los siguientes valores <ul><li><strong>mean</strong>: (opción por defecto) reemplazando los valores nulos con la media de los valores de su misma columna</li> <li><strong>median</strong>: reemplazando los valores nulos con la mediana de los valores de su misma columna</li> <li><strong>most_frequent</strong>: reemplazando los valores nulos con el valor más frecuente de su misma columna</li> <li><strong>constant</strong>: reemplazando los valores nulos con un valor constante, pudiendo ser tanto un número como una cadena de texto</li> </ul></li> </ul><p>En este último caso, el parámetro <strong>fill_value</strong> indica el valor en cuestión.</p></div> </div> <div class="clearfix text-formatted field field--name-field-ejemplos field--type-text-long field--label-above"> <div class="field__label">Ejemplos</div> <div class="field__items"> <div class="field__item"><p>Partimos del siguiente dataframe:</p> <div class="codigo"> <p>df = pd.DataFrame({<br />     "x": [1, np.nan, 4, 2],<br />     "y": [np.nan, 2, 5, 2],<br />     "z": [0, 2, np.nan, 4]<br /> })<br /> df</p> </div> <img alt="Dataframe de pruebas" data-entity-type="file" data-entity-uuid="9ccafd53-ab61-41e4-be38-ed0359e3c1b8" src="/sites/default/files/inline-images/tutorial_ml_028.png" class="align-center" width="150" height="127" loading="lazy" /><p>Importamos e instanciamos ahora el imputador:</p> <div class="codigo"> <p>from sklearn.impute import SimpleImputer<br /> si = SimpleImputer()</p> </div> <p>Lo entrenamos (ya hemos visto que, por defecto, la estrategia es el sustituir los valores nulos por el valor medio de las características):</p> <div class="codigo"> <p>si.fit(df)</p> </div> <img alt="SimpleImputer" data-entity-type="file" data-entity-uuid="269a34e9-a187-412b-b59d-d904a3c85300" src="/sites/default/files/inline-images/tutorial_ml_029.png" class="align-center" width="623" height="42" loading="lazy" /><p>Los valores a imputar ya han sido calculados:</p> <div class="codigo"> <p>si.statistics_</p> </div> <div class="respuesta">array([2.33333333, 3. , 2. ])</div> <p>Por último, podríamos generar el array final usando el método <em>transform</em>:</p> <div class="codigo"> <p>si.transform(df)</p> </div> <img alt="Valores transformados" data-entity-type="file" data-entity-uuid="20bb76ab-6cae-4b06-99f5-c6023cd8838e" src="/sites/default/files/inline-images/tutorial_ml_030.png" class="align-center" width="363" height="83" loading="lazy" /><p>También podríamos haber modificado los datos originales directamente usando el método <strong>fit_transform</strong>:</p> <div class="codigo"> <p>si.fit_transform(df)</p> </div> <img alt="El método fit_transform" data-entity-type="file" data-entity-uuid="ca033f98-1fb0-4905-b8e0-5849a7a770e4" src="/sites/default/files/inline-images/tutorial_ml_031.png" class="align-center" width="362" height="81" loading="lazy" /><p>Podríamos sustituir los valores nulos tan solo de una de las características aplicando el imputador solo a la columna correspondiente, considerando que los métodos de entrenamiento de esta función esperan un array de entrada de dos dimensiones:</p> <div class="codigo"> <p>df["x"] = si.fit_transform(df["x"].values.reshape(-1, 1))<br /> df</p> </div> <img alt="Imputando los valores nulos solo de una columna" data-entity-type="file" data-entity-uuid="150ac992-7384-47f7-9539-6ae2bea8e04f" src="/sites/default/files/inline-images/tutorial_ml_032.png" class="align-center" width="180" height="132" loading="lazy" /><p>(en un caso sencillo como éste también podríamos recurrir a la función <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.fillna.html" target="_blank">fillna</a> de pandas).</p> </div> </div> </div> Sun, 28 Apr 2019 08:57:59 +0000 admin 1130 at https://interactivechaos.ovh LabelEncoder https://interactivechaos.ovh/es/python/function/labelencoder <span class="field field--name-title field--type-string field--label-hidden">LabelEncoder</span> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/es/user/1" typeof="schema:Person" property="schema:name" datatype="">admin</span></span> <span class="field field--name-created field--type-created field--label-hidden">Dom, 14/04/2019 - 14:34</span> <div class="field field--name-field-fun-python-nombre-completo field--type-string field--label-above"> <div class="field__label">Nombre completo</div> <div class="field__item">sklearn.preprocessing.LabelEncoder</div> </div> <div class="field field--name-field-libreria field--type-entity-reference field--label-above"> <div class="field__label">Librería</div> <div class="field__item">scikit-learn</div> </div> <div class="clearfix text-formatted field field--name-field-funcion-python-sintaxis field--type-text-long field--label-above"> <div class="field__label">Sintaxis</div> <div class="field__item"><p>sklearn.preprocessing.LabelEncoder()</p></div> </div> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-above"> <div class="field__label">Descripción</div> <div class="field__item"><p>La función <a href="https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.LabelEncoder.html" target="_blank">sklearn.preprocessing.LabelEncoder</a> codifica etiquetas de una característica categórica en valores numéricos entre 0 y el número de clases menos 1. Una vez instanciado, el método <strong>fit</strong> lo entrena (creando el mapeado entre las etiquetas y los números) y el método <strong>transform</strong> transforma las etiquetas que se incluyan como argumento en los números correspondientes. El método <strong>fit_transform</strong> realiza ambas acciones simultáneamente.</p> <p>El único atributo de esta función, <strong>classes_</strong>, almacena el array que mapea etiquetas y números (que coinciden con el índice de cada etiqueta en el array).</p></div> </div> <div class="clearfix text-formatted field field--name-field-ejemplos field--type-text-long field--label-above"> <div class="field__label">Ejemplos</div> <div class="field__items"> <div class="field__item"><p>Apliquemos esta función al dataset Titanic:</p> <div class="codigo"> <p>titanic = sns.load_dataset("titanic")<br /> titanic.head(1)</p> </div> <img alt="Dataset Titanic" data-entity-type="file" data-entity-uuid="99570b9f-ec2f-4f22-80d1-2c24b10e65c0" src="/sites/default/files/inline-images/tutorial_ml_018.png" class="align-center" width="785" height="58" loading="lazy" /><p>En este dataset se incluyen varias características categóricas: <em>sex</em>, <em>embarked</em>, <em>class</em>... Vamos a aplicar el codificador a la característica "embark_town", por ejemplo. Comencemos confirmando los valores diferentes en este campo:</p> <div class="codigo"> <p>titanic.embark_town.unique()</p> </div> <div class="respuesta">array(['Southampton', 'Cherbourg', 'Queenstown', nan], dtype=object)</div> <p>Vemos que en el campo hay valores nulos que deberían ser tratados previamente. Como en este escenario el objetivo es probar el codificador LabelEncoder, vamos a optar por agrupar los valores nulos en una categoría independiente, dejando de lado opciones más sofisticadas como predicción vía Machine Learning:</p> <div class="codigo"> <p>titanic.embark_town.fillna("nan", inplace = True)</p> </div> <div class="codigo"> <p>titanic.embark_town.unique()</p> </div> <div class="respuesta">array(['Southampton', 'Cherbourg', 'Queenstown', 'nan'], dtype=object)</div> <p>Hemos convertido los valores nulos en etiquetas de texto con el valor "nan". Ahora ya podemos aplicar el codificador:</p> <div class="codigo"> <p>embark_town_codified = le.fit_transform(titanic.embark_town)</p> </div> <p>Veamos el mapa creado y comparemos los valores originales y las valores generados:</p> <div class="codigo"> <p>le.classes_</p> </div> <div class="respuesta">array(['Cherbourg', 'Queenstown', 'Southampton', 'nan'], dtype=object)</div> <p>Este array nos indica que el valor "Cherbourg" va a ser mapeado al número 0, "Queenstown" al 1, etc.</p> <div class="codigo"> <p>pd.DataFrame({<br />     "original": titanic.embark_town[:6],<br />     "codificada": embark_town_codified[:6]<br /> })</p> </div> <img alt="Valores originales y codificados" data-entity-type="file" data-entity-uuid="8713f486-3358-4635-bcd8-3ca575a68542" src="/sites/default/files/inline-images/tutorial_ml_026.png" class="align-center" width="190" height="186" loading="lazy" /><p>Ahora podríamos agregar los valores al dataframe o sustituir la columna original por el array que hemos creado. También podríamos hacerlo directamente:</p> <div class="codigo"> <p>titanic.embark_town = le.fit_transform(titanic.embark_town)</p> </div> <div class="codigo"> <p>titanic.head()</p> </div> <img alt="Dataset transformado" data-entity-type="file" data-entity-uuid="43733d8e-ee13-4901-a163-093bfa3343f6" src="/sites/default/files/inline-images/tutorial_ml_027.png" class="align-center" width="827" height="160" loading="lazy" /><p>Para terminar, el método <strong>inverse_transform</strong> permite transformar las etiquetas generadas en los valores originales.</p></div> </div> </div> Sun, 14 Apr 2019 12:34:45 +0000 admin 1072 at https://interactivechaos.ovh MaxAbsScaler https://interactivechaos.ovh/es/python/function/maxabsscaler <span class="field field--name-title field--type-string field--label-hidden">MaxAbsScaler</span> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/es/user/1" typeof="schema:Person" property="schema:name" datatype="">admin</span></span> <span class="field field--name-created field--type-created field--label-hidden">Lun, 08/04/2019 - 22:10</span> <div class="field field--name-field-fun-python-nombre-completo field--type-string field--label-above"> <div class="field__label">Nombre completo</div> <div class="field__item">sklearn.preprocessing.MaxAbsScaler</div> </div> <div class="field field--name-field-libreria field--type-entity-reference field--label-above"> <div class="field__label">Librería</div> <div class="field__item">scikit-learn</div> </div> <div class="clearfix text-formatted field field--name-field-funcion-python-sintaxis field--type-text-long field--label-above"> <div class="field__label">Sintaxis</div> <div class="field__item"><p>sklearn.preprocessing.MaxAbsScaler(copy=True)</p></div> </div> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-above"> <div class="field__label">Descripción</div> <div class="field__item"><p>La función <a href="https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.MaxAbsScaler.html" target="_blank">sklearn.preprocessing.MaxAbsScaler</a> escala y traslada cada característica del array de entrada de forma que el valor absoluto máximo de cada una sea 1.0 (es decir, todas las características pasan a tener valores en el rango [-1, 1]).</p> <p>El array de entrada debe ser de números reales (enteros o de tipo <em>float</em>). No se aceptan números complejos.</p> <ul></ul></div> </div> <div class="clearfix text-formatted field field--name-field-parametros field--type-text-long field--label-above"> <div class="field__label">Parámetros</div> <div class="field__item"><ul><li><strong>copy</strong>: (True por defecto) booleano. Si toma el valor <em>False</em> y el array de entrada es un array NumPy, la transformación se realiza inplace.</li> </ul><p> </p> <p><strong>Atributos:</strong></p> <ul><li><strong>scale_</strong>: (array) escalado relativo de cada característica</li> <li><strong>max_abs_</strong>: (array) máximo valor de cada característica</li> <li><strong>n_samples_seen_</strong>: (entero), número de muestras (filas) procesadas.</li> </ul></div> </div> <div class="clearfix text-formatted field field--name-field-python-funcion-resultado field--type-text-long field--label-above"> <div class="field__label">Resultado</div> <div class="field__item"><p>El resultado de los métodos <em>fit_transform </em>y <em>transform</em> es siempre un array NumPy de tipo <em>float</em>.</p></div> </div> <div class="clearfix text-formatted field field--name-field-ejemplos field--type-text-long field--label-above"> <div class="field__label">Ejemplos</div> <div class="field__items"> <div class="field__item"><p>Comenzamos importando las librerías involucradas y creando el dataframe que queremos escalar:</p> <div class="codigo"> <p>import pandas as pd<br /> import numpy as np<br /> from sklearn.preprocessing import MaxAbsScaler</p> </div> <div class="codigo"> <p>df = pd.DataFrame({<br />     "w": [5, 2, -100],<br />     "x": [2, 10, -2],<br />     "y": [100, 0, -10],<br />     "z": [0.5, 0.1, -0.1],<br /> })<br /> df</p> </div> <img alt="DataFrame a escalar" data-entity-type="file" data-entity-uuid="d6f36704-0483-4ae0-b4ec-d6fa27390b91" src="/sites/default/files/inline-images/python_function_0001.PNG" class="align-center" width="172" height="115" loading="lazy" /><p>Instanciamos el escalador, lo entrenamos con el dataframe y lo transformamos:</p> <div class="codigo"> <p>scaler = MaxAbsScaler()<br /> scaler.fit_transform(df)</p> </div> <img alt="MaxAbsScaler" data-entity-type="file" data-entity-uuid="b24ff764-713f-4319-b91f-ba7d2e623650" src="/sites/default/files/inline-images/python_function_0002.PNG" class="align-center" width="302" height="64" loading="lazy" /><p>Observamos que los valores máximos y mínimos en todas las características son 1 y -1. El procedimiento seguido por el escalador ha sido comprobar el valor máximo absoluto de cada característica y dividir todas los valores (de cada característica) por su máximo absoluto. Podemos comprobar los valores máximos encontrados visualizando el valor del atributo <em>max_abs_</em>:</p> <div class="codigo"> <p>scaler.max_abs_</p> </div> <div class="respuesta">array([100. , 10. , 100. , 0.5])</div> <p>La escala aplicada (cifra por la que dividir los valores de cada característica) viene dada por el atributo <em>scale_</em> (la escala debe coincidir con el valor máximo encontrado):</p> <div class="codigo"> <p>scaler.scale_</p> </div> <div class="respuesta">array([100. , 10. , 100. , 0.5])</div> <p>Por último, el atributo n_samples_seen_ devuelve el número de muestras (filas de datos) procesadas:</p> <div class="codigo"> <p>scaler.n_samples_seen_</p> </div> <div class="respuesta"> <p>3</p> </div> </div> <div class="field__item"><p>¿Y cómo se gestionan los valores nulos? Hagamos la prueba:</p> <div class="codigo"> <p>df = pd.DataFrame({<br />     "w": [5, np.nan, -100],<br />     "x": [2, 10, -2],<br />     "y": [np.nan, 0, -10],<br />     "z": [0.5, 0.1, -0.1],<br /> })<br /> df</p> </div> <img alt="DataFrame a escalar" data-entity-type="file" data-entity-uuid="6257a637-4cf3-4de4-8859-1e7e18578c57" src="/sites/default/files/inline-images/python_function_0003.PNG" class="align-center" width="185" height="105" loading="lazy" /><div class="codigo"> <p>scaler.fit_transform(df)</p> </div> <img alt="MaxAbsScaler" data-entity-type="file" data-entity-uuid="b571ec56-7feb-4120-9459-907778a19b27" src="/sites/default/files/inline-images/python_function_0004.PNG" class="align-center" width="300" height="66" loading="lazy" /><p>Veamos los valores máximos encontrados:</p> <div class="codigo"> <p>scaler.max_abs_</p> </div> <div class="codigo">array([100. , 10. , 10. , 0.5])</div> <p>Comprobamos que los valores nulos se ignoran durante el entrenamiento y se mantienen durante la transformación.</p> </div> <div class="field__item"><p>¿Y si todos los valores de una característica son nulos?</p> <div class="codigo"> <p>df = pd.DataFrame({<br />     "w": [5, np.nan, -100],<br />     "x": [2, 10, -2],<br />     "y": [np.nan, np.nan, np.nan],<br />     "z": [0.5, 0.1, -0.1],<br /> })<br /> df</p> </div> <img alt="DataFrame a escalar" data-entity-type="file" data-entity-uuid="982c12ac-a35b-4fdc-9225-4352e3934145" src="/sites/default/files/inline-images/python_function_0005.PNG" class="align-center" width="178" height="111" loading="lazy" /><div class="codigo"> <p>scaler.fit_transform(df)</p> </div> <div class="error">C:\Users\xxx\Anaconda3\lib\site-packages\sklearn\preprocessing\data.py:923: RuntimeWarning: All-NaN slice encountered max_abs = np.nanmax(np.abs(X), axis=0)</div> <img alt="MaxAbsScaler" data-entity-type="file" data-entity-uuid="37cb3d0c-086f-4f88-bdfd-cfa12dcb1e7d" src="/sites/default/files/inline-images/python_function_0006.PNG" class="align-center" width="300" height="60" loading="lazy" /><p>Vemos que, a pesar del error que devuelve, el resultado es correcto.</p> </div> </div> </div> Mon, 08 Apr 2019 20:10:04 +0000 admin 1043 at https://interactivechaos.ovh Visualización de un árbol de decisión https://interactivechaos.ovh/es/python/scenario/visualizacion-de-un-arbol-de-decision <span class="field field--name-title field--type-string field--label-hidden">Visualización de un árbol de decisión</span> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/es/user/1" typeof="schema:Person" property="schema:name" datatype="">admin</span></span> <span class="field field--name-created field--type-created field--label-hidden">Mié, 03/04/2019 - 15:53</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>La librería sklearn incluye la función <a href="https://scikit-learn.org/stable/modules/generated/sklearn.tree.export_graphviz.html" target="_blank">sklearn.tree.export_graphviz</a> que permite la visualización de un árbol de decisión. Probémosla con el dataset de <em>tips </em>proveído por la librería seaborn:</p> <div class="codigo"> <p>import seaborn as sns</p> </div> <div class="codigo"> <p>tips = sns.load_dataset("tips")<br /> tips.sample(5)</p> </div> <img alt="Dataset tips" data-entity-type="file" data-entity-uuid="e370ab70-b4e8-4545-9147-0c81c5267e3f" src="/sites/default/files/inline-images/tutorial_sns_datasets_04.JPG" class="align-center" width="394" height="172" loading="lazy" /><p>Como la implementación del árbol de decisión para escenarios de regresión de sklearn no permite trabajar con características categóricas, comenzamos codificándolas:</p> <div class="codigo"> <p>from sklearn.preprocessing import LabelEncoder</p> </div> <div class="codigo"> <p>le = LabelEncoder()<br /> tips.sex = le.fit_transform(tips.sex)<br /> tips.smoker = le.fit_transform(tips.smoker)<br /> tips.day = le.fit_transform(tips.day)<br /> tips.time = le.fit_transform(tips.time)</p> </div> <p>Ahora podemos crear las estructuras X e y:</p> <div class="codigo"> <p>y = tips.pop("tip")<br /> X = tips</p> </div> <p>...e importar el algoritmo, instanciarlo y entrenarlo (con los parámetros por defecto salvo la profundidad máxima, que fijamos en 3 para no crear un árbol demasiado grande):</p> <div class="codigo"> <p>from sklearn.tree import DecisionTreeRegressor<br /> model = DecisionTreeRegressor(max_depth = 3)<br /> model.fit(X, y)</p> </div> <img alt="DecisionTreeRegressor entrenado" data-entity-type="file" data-entity-uuid="759b74e0-6ddf-4d5d-8981-b77bf5f51804" src="/sites/default/files/inline-images/python_escenario_0013.png" class="align-center" width="547" height="94" loading="lazy" /><p>Ahora importamos la función export_graphviz y un par de clases adicionales de sklearn, IPython y pydotplus:</p> <div class="codigo"> <p>from sklearn.externals.six import StringIO  <br /> from IPython.display import Image  <br /> from sklearn.tree import export_graphviz<br /> import pydotplus</p> </div> <div class="codigo"> <p>dot_data = StringIO()<br /> export_graphviz(model, out_file = dot_data,  <br />                 filled = True, rounded = True,<br />                 special_characters = True)<br /> graph = pydotplus.graph_from_dot_data(dot_data.getvalue())  <br /> Image(graph.create_png())</p> </div> <img alt="Árbol de decisión generado" data-entity-type="file" data-entity-uuid="a4c6fe1a-0174-4295-865b-3eeec55714df" src="/sites/default/files/inline-images/python_escenario_0014.png" class="align-center" width="1245" height="481" loading="lazy" /><p>Aunque entrar en el detalle de las funciones involucradas haría este escenario excesivamente complejo, aquí van algunos comentarios:</p> <p>Los parámetros usados en <em>export_graphviz</em> son los siguientes:</p> <ul><li>El primer parámetro es el modelo entrenado, ya sea de regresión o de clasificación.</li> <li><strong>out_file</strong> indica el fichero o el manejador al que volcar el resultado, en este caso es un objeto de la clase <em>StringIO</em>.</li> <li>El parámetro <strong>filled</strong> colorea los nodos generados para indicar en cuáles existe un valor más frecuente que otros (en clasificación) o en cuáles hay valores extremos (en regresión).</li> <li><strong>rounded </strong>muestra los rectángulos representando los nodos con las esquinas redondeadas</li> <li><strong>special_characters</strong>, por último, incluye en el gráfico generado caracteres especiales (el ignorarlos tendría sentido solo para asegurar la compatibilidad con el formato PostScript)</li> </ul><p>La función <strong>pydotplus.graph_from_dot_data</strong> carga un gráfico en formato DOT y, por último, la función <em>Image(graph.create_png())</em> crea y muestra la imagen generada en formato png.</p> </div> <div class="field field--name-field-escenario-python-categoria field--type-entity-reference field--label-above"> <div class="field__label">Categoría</div> <div class="field__items"> <div class="field__item"><a href="/es/taxonomy/scikit-learn" hreflang="es">scikit-learn</a></div> </div> </div> Wed, 03 Apr 2019 13:53:04 +0000 admin 1026 at https://interactivechaos.ovh Codificación One Hot Encoding de un conjunto de características categóricas con sklearn https://interactivechaos.ovh/es/python/scenario/codificacion-one-hot-encoding-de-un-conjunto-de-caracteristicas-categoricas-con <span class="field field--name-title field--type-string field--label-hidden">Codificación One Hot Encoding de un conjunto de características categóricas con sklearn</span> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/es/user/1" typeof="schema:Person" property="schema:name" datatype="">admin</span></span> <span class="field field--name-created field--type-created field--label-hidden">Lun, 03/12/2018 - 20:28</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>El método para aplicar una codificación de tipo One-Hot-Encoding a un conjunto de características categóricas pasa por:</p> <ol><li>Codificación de las características con valores entre 0 y el número de clases -1, por ejemplo mediante la función <strong>LabelEncoder</strong> de sklearn.</li> <li>Aplicación de la codificación One-Hot-Encoding, por ejemplo mediante la función <strong>OneHotEncoder</strong> de sklearn.</li> </ol><p>Para aplicar ambas codificaciones, además de importar las funciones correspondientes, solo hay que considerar que la función OneHotEncoder necesita como entrada una estructura de tipo array, por lo que habrá que redimensionar la salida de LabelEncoder. Así, si tenemos la siguiente lista de valores (también podría ser una serie Pandas):</p> <div class="codigo"> <p>y = ["a", "b", "a", "c"]</p> </div> <p>Podemos realizar la conversión con el siguiente código:</p> <div class="codigo"> <p>from sklearn.preprocessing import OneHotEncoder<br /> from sklearn.preprocessing import LabelEncoder</p> </div> <div class="codigo"> <p>ohe = OneHotEncoder(sparse = False)<br /> le = LabelEncoder()<br /> ohe.fit_transform(le.fit_transform(y).reshape(-1, 1))</p> </div> <p>Si deseásemos que el resultado fuese una matriz dispersa, bastaría con crear la instancia de la clase OneHotEncoder sin el argumento <em>sparse</em> (o dándole el valor <em>True</em>)</p> <p>Otra alternativa consiste en la creación de una clase, CatOneHotEncoder que aplique ambas condificaciones:</p> <div class="codigo"> <p>from sklearn.preprocessing import OneHotEncoder<br /> from sklearn.preprocessing import LabelEncoder</p> </div> <div class="codigo"> <p>class CatOneHotEncoder():</p> <p> </p> <p>    def __init__(self):<br />         self.ohe = OneHotEncoder()<br />         self.le = LabelEncoder()</p> <p> </p> <p>    def fit_transform(self, x):<br />         return self.ohe.fit_transform(self.le.fit_transform(x).reshape(-1, 1))</p> <p> </p> <p>    def transform(self, x):<br />         return self.ohe.transform(self.la.transform( x.reshape(-1, 1)))</p> </div> <p>Opción que nos permite añadir métodos adicionales, como <em>transform</em> que nos permitirá transformar un segundo listado de características tras haber entrenado la clase.</p> </div> <div class="field field--name-field-escenario-python-categoria field--type-entity-reference field--label-above"> <div class="field__label">Categoría</div> <div class="field__items"> <div class="field__item"><a href="/es/taxonomy/scikit-learn" hreflang="es">scikit-learn</a></div> </div> </div> Mon, 03 Dec 2018 19:28:59 +0000 admin 20 at https://interactivechaos.ovh KFold https://interactivechaos.ovh/es/python/function/kfold <span class="field field--name-title field--type-string field--label-hidden">KFold</span> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/es/user/1" typeof="schema:Person" property="schema:name" datatype="">admin</span></span> <span class="field field--name-created field--type-created field--label-hidden">Lun, 03/12/2018 - 20:27</span> <div class="field field--name-field-fun-python-nombre-completo field--type-string field--label-above"> <div class="field__label">Nombre completo</div> <div class="field__item">sklearn.model_selection.KFold</div> </div> <div class="field field--name-field-libreria field--type-entity-reference field--label-above"> <div class="field__label">Librería</div> <div class="field__item">scikit-learn</div> </div> <div class="clearfix text-formatted field field--name-field-funcion-python-sintaxis field--type-text-long field--label-above"> <div class="field__label">Sintaxis</div> <div class="field__item"><p>class sklearn.model_selection.KFold(n_splits=’warn’, shuffle=False, random_state=None)</p></div> </div> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-above"> <div class="field__label">Descripción</div> <div class="field__item"><p>La función <a href="https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.KFold.html" target="_blank">sklearn.model_selection.KFold</a> divide un conjunto de datos en k bloques. A continuación, considera uno de ellos como conjunto de validación y el resto como conjunto de entrenamiento, devolviendo las k combinaciones posibles (la primera combinación es la que considera el primer bloque como conjunto de validación y el resto como conjunto de entrenamiento, la segunda es la que considera el segundo bloque como conjunto de validación y el resto como conjunto de entrenamiento, etc.).</p> </div> </div> <div class="clearfix text-formatted field field--name-field-parametros field--type-text-long field--label-above"> <div class="field__label">Parámetros</div> <div class="field__item"><ul><li><strong>n_splits</strong>: entero, valor por defecto = 3. Número de bloques en el que dividir el conjunto de datos.</li> <li><strong>shuffle</strong>: boolean, opcional. Si toma el valor <em>True</em>, los datos se van a mezclar antes de generar los k bloques.</li> <li><strong>random_state</strong>: entero o None, opcional, valor por defecto = None. Semilla a utilizar en el generador de números aleatorios cuando <strong>shuffle</strong> toma el valor <em>True</em> para la mezcla de los datos.</li> </ul></div> </div> <div class="clearfix text-formatted field field--name-field-ejemplos field--type-text-long field--label-above"> <div class="field__label">Ejemplos</div> <div class="field__items"> <div class="field__item"><p>Supongamos que deseamos dividir un conjunto de 12 números (del 0 al 11, generados mediante la función <em>range</em>) en tres bloques, considerando uno de ellos como conjunto de validación y los otros dos como conjunto de entrenamiento, y generar los índices correspondientes para cada una de las combinaciones posibles:</p> <div class="codigo"> <p>from sklearn.model_selection import KFold<br /> cv = KFold(n_splits = 3)<br /> for train_indices, test_indices in cv.split(range(12)):<br />     print(train_indices, test_indices)</p> </div> <p>El resultado devuelto es:</p> <p><img alt="KFold" src="/sites/default/files/capturas_de_pantalla/python_funcion_kfold_01.png" /></p> <p>Si hacemos uso del argumento <strong>shuffle</strong> fijándolo al valor True:</p> <div class="codigo"> <p>from sklearn.model_selection import KFold<br /> cv = KFold(n_splits = 3, shuffle = True)<br /> for train_indices, test_indices in cv.split(range(12)):<br />     print(train_indices, test_indices)</p> </div> <p>el resultado es:</p> <p> <img alt="KFold" src="/sites/default/files/capturas_de_pantalla/python_funcion_kfold_02.png" /></p> </div> <div class="field__item"><p>Si tenemos el siguiente dataframe:</p> <div class="codigo"> <p>df = pd.DataFrame({<br /> "a": [1, 2, 1, 3, 2, 1],<br /> "b": [2, 4, 3, 6, 7, 1]<br /> })</p> </div> <p>..y queremos dividirlo en conjuntos de entrenamiento y validación a partir de 3 bloques de registros, el código a utilizar sería el siguiente:</p> <div class="codigo"> <p>from sklearn.model_selection import KFold<br /> cv = KFold(n_splits = 3)<br /> for train_indices, test_indices in cv.split(df):<br /> print(train_indices, test_indices)</p> </div> <p><img alt="KFold" src="/sites/default/files/capturas_de_pantalla/python_funcion_kfold_03.png" /></p> </div> </div> </div> Mon, 03 Dec 2018 19:27:10 +0000 admin 19 at https://interactivechaos.ovh