Está en la página 1de 12

Machine Learning: Cómo Desarrollar un Modelo desde Cero

1. Definir adecuadamente el problema

La primera y más crítica tarea que hay que realizar es encontrar cuáles son las entradas y las
salidas esperadas. Habría que responder a las siguientes cuestiones:

a) ¿Cuál es el principal objetivo?. ¿Qué vamos a intentar predecir?


b) ¿Cuáles son las características objetivo?
c) ¿Cuáles son los datos de entrada?, ¿están disponibles?
d) ¿A qué clase de problema nos enfrentamos?, ¿clasificación binaria?,
¿agrupamiento?
e) ¿Cuál es la mejora esperada?
f) ¿Cuál es el estado actual de la variable objetivo?
g) ¿Cómo se va a medir la variable objetivo?

No todos los problemas se pueden resolver, solo podemos hacer ciertas hipótesis hasta que
tengamos un modelo funcionando:

Nuestras salidas se pueden predecir proporcionando las entradas.

Los datos disponibles contienen la información suficiente para aprender la relación entre las
entradas y las salidas.

Es fundamental tener presente que el Machine Learning solo puede ser usado para memorizar
pautas que están presentes en los datos de entrenamiento, por lo tanto solo podemos
reconocer lo que hemos visto antes. Cuando usamos Machine Learning estamos asumiendo que
el futuro se comportará como el pasado, lo que no siempre es cierto.

2. Recopilar datos

Este es el primer paso en el desarrollo de un modelo de Machine Learning . Es un paso crítico


con una influencia absoluta en cómo será de adecuado el modelo. Cuanto más y mejores datos
obtengamos, mejor será el rendimiento de nuestro modelo. Hay varias técnicas para recopilar
los datos

Típicamente, nuestros datos serán de la siguiente forma:

Nota: La tabla corresponde al famoso conjunto de datos del mercado inmobiliario de Boston, un
clásico conjunto de datos usado frecuentemente para desarrollar modelos simples de Machine
Learning. Cada fila representa un diferente vecindario de Boston y cada columna indica alguna
característica del vecindario (índice de criminalidad, edad media de los habitantes,…etc). La

1
última columna representa el precio medio de las viviendas del vecindario. Este es el objetivo,
el dato que será predicho teniendo en cuenta el otro.

3.1._ Exploración de datos (véase sección 5)

Una vez recopilados se debe realizar un análisis exploratorio de los datos:

a) Nº de registros suficiente?
b) ¿Campos nulos? Eliminarlos si hay
c) ¿Los datos son discretos, continuos…?
d) ¿Salida es binaria, una cantidad…?
e) ¿Están balanceados? Importante en clasificación
f) Seleccionar las variables relevantes
g) ¿Las variables siguen alguna distribución?
h) ¿Correlación entre las variables?
i) Limpiar datos
j) ¿Hay outliers? ¿Los eliminamos? ¿Son errores?

3. Elegir una medida o indicador de éxito:

Esta medida debe estar directamente alineada con los objetivos de mayor nivel del negocio, y
también directamente relacionada con el tipo de problema al que nos enfrentamos:

a) Los problemas de regresión utilizan ciertas métricas de evaluación, como el


error cuadrático medio.
b) Los problemas de clasificación usan métricas de evaluación como precisión,
exactitud y recuerdo.

En los siguientes apartados exploraremos en profundidad dichas métricas, cuáles son las más
adecuadas para abordar el problema considerado, y aprenderemos cómo implantarlas.

4. Estableciendo un protocolo de evaluación

Una vez está claro el objetivo, se deberá decidir cómo medir el progreso en la persecución de
dicho objetivo. Los protocolos de evaluación más comunes son:

4.1 Set de Validación “hold out”

Este método consiste en mantener aparte una porción de los datos como conjunto de datos de
prueba.

En el proceso, se entrena el modelo con la fracción restante de datos, ajustando sus parámetros
con los datos de validación, y finalmente evaluando su rendimiento con el conjunto de datos de
prueba que hemos dejado aparte.

2
La razón de dividir los datos en tres partes es evitar las pérdidas de información. El principal
inconveniente de este método es que, si hay poco volumen de datos disponible, los conjuntos
de datos de validación y prueba contendrán tan pocos casos que el modelo no será efectivo.

4.2 Validación “K-Fold”

K-Fold consiste en dividir los datos en K particiones del mismo tamaño. Para cada partición i, el
modelo es entrenado con las restantes K-1 particiones, y evaluado en la propia partición i.

La puntuación final es la media de las K puntuaciones obtenidas. Esta técnica es especialmente


útil cuando el rendimiento del modelo es significativamente diferente del rendimiento del
fragmento “entrenamiento-prueba”.

4.3 Validación Iterada “K-Fold” con Arrastre

Esta técnica es especialmente relevante cuando tenemos pocos datos disponibles y se precisa
evaluar el modelo de forma tan precisa como sea posible (es la aproximación estándar en las
competiciones Kaggle).

Consiste en aplicar la validación K-Fold varias veces, y “arrastrar” los datos cada vez antes de
dividirlos en K particiones. La puntuación final es la media de los puntos obtenidos en cada
iteración de la validación K-Fold.

Este método puede ser muy costoso desde el punto de vista computacional, ya que el número
de modelos de entrenamiento y validación será I x K, siendo el I el número de iteraciones y K el
número de particiones.

Nota: Es esencial tener presente lo siguiente al escoger un protocolo de evaluación:

a) En problemas de clasificación, los datos de entrenamiento y pruebas deben ser


representativos de los datos, de forma que deberemos “arrastrar” los datos antes de
fragmentarlos, para asegurarnos de que todo el espectro del conjunto de datos está
cubierto.
b) Cuando se pretende predecir el futuro con información del pasado (predicción
meteorológica, predicción del precio de acciones,…..) los datos no se deben arrastrar,

3
ya que la secuencia de los datos es una característica esencial y el arrastre podría
ocasionar una pérdida temporal.
c) Siempre deberemos buscar y eliminar posibles duplicados en nuestros datos. De otra
manera, podrían aparecer datos redundantes en los conjuntos de datos de
entrenamiento y prueba que causarían aprendizaje inexacto en nuestro modelo.

5. Preparando los datos

Antes de comenzar a entrenar modelos, deberíamos transformar nuestros datos de una manera
que puedan alimentar un modelo de Machine Learning. Las técnicas más comunes son:

5.1 Qué hacer con los datos perdidos

Es muy común en los problemas del mudo real perder algunos valores de los datos de muestra.
Puede ser debido a errores en la recopilación de datos, espacios en blanco en encuestas,
medidas no aplicables,etc.

Los campos vacíos se representan típicamente con los indicadores “NaN” or “Null”. El problema
es que la mayoría de los algoritmos no pueden manejar esos valores faltantes, por lo que los
tenemos que tener en cuenta antes de alimentar nuestro modelos con datos. Una vez que están
identificados hay varias formas de tratar con ellos:

Eliminar las muestras o características con campos vacíos (corremos el riesgo de borrar
información relevante o demasiadas muestras)

Estimar los campos vacíos con algún estimador preinstalado, como “Imputer Class” de la
herramienta “Scikit Learn”. Primero ajustaremos nuestros datos, y después los transformaremos
para estimarlos. Una aproximación común es establecer los valores faltantes como el valor
medio del resto de las muestras.

5.2 Manejando datos categóricos

Cuando manejamos datos categóricos, trabajamos con características ordinales y numerales.


Las características ordinales son características categóricas que pueden ser ordenadas (talla de
ropa: L<M<S), mientras que las características nominales no implican ningún orden (color de la
ropa: amarillo, verde, rojo). Los métodos para trabajar con características ordinales y nominales
son:

a) Conversión de características ordinales: para asegurarnos de que el algoritmo interpreta


correctamente las características ordinales, es preciso convertir los valores a números
enteros. Con frecuencia se realiza dicha conversión manualmente. Por ejemplo, en el
caso de las tallas de ropa se puede realizar la siguiente correspondencia: L:2, M:1, S:0.

b) Codificación de etiquetas de clases nominales: La aproximación más común es realizar


una codificación “one-hot”, que consiste en crear una nueva característica ficticia para
cada valor único en la columna de características nominales. Ejemplo: si tenemos tres
clases en la columna color : rojo, amarillo, verde, y realizamos la codificación “one-hot”,

4
obtendremos tres nuevas columnas, una para cada clase única. Después, si tenemos una
camiseta amarilla, será representado como amarillo = 1, verde = 0, rojo = 0. De esta
forma nos aseguramos de un buen rendimiento del algoritmo, ya que es mucho más
eficiente cuando trabaja con matrices “ligeras” (matrices poco densas, con muchos
valores “0”).

5.3 Escalación de Características

Este es un paso esencial en la fase de pre-procesamiento, ya que la mayoría de los algoritmos


de Machine Learning tienen mucho mejor rendimiento cuando tratan con características que
están en la misma escala. Las técnicas más comunes son:

a) Normalización: se refiere a reescalar las características en un rango [0,1], que es un caso


especial de la escalación “min-max”. Para normalizar nuestros datos, simplemente
necesitaremos aplicar el método de escalación “min-max” a cada columna de
características.

b) Estandarización: consiste en centrar las columnas de características con respecto a


media 0 con desviación estándar 1 de forma que las columnas de características tengan
los mismos parámetros que una distribución normal estándar (media cero y varianza
unidad). De esta forma, es mucho más fácil para los algoritmos de aprendizaje
“aprender” los pesos de los parámetros. Adicionalmente, mantiene información útil
sobre valores atípicos y hace los algoritmos menos sensibles a ellos.

5.4 Seleccionando Características Relevantes

Como veremos más tarde, una de las principales razones del “overfitting” o sobre-ajuste, que es
un tipo de funcionamiento inadecuado de los modelos de Machine Learning, es la existencia de
redundancia en los datos. Esto hace que el modelo sea demasiado complejo con respecto a los
datos de entrenamiento facilitados, y por tanto incapaz de hacer generalizaciones correctas en
datos no procesados aún.

Una de las soluciones más comunes para evitar el overfitting es reducir la dimensionalidad de
los datos. Esto se realiza frecuentemente reduciendo el número de características de nuestro
conjunto de datos por medio de Principal Component Analysis (PCA), que es una clase de
algoritmo no supervisado de Machine Learning.

PCA identifica pautas en nuestro dato basado en las correlaciones entre características. Esta
correlación implica que hay redundancia en nuestros datos, en otras palabras , que hay parte de
los datos que se pueden explicar por relaciones con otras partes de los mismos.

5
Estos datos correlacionados no son necesarios para el aprendizaje correcto del modelo, y por
tanto pueden ser eliminados. Se pueden eliminar borrando directamente ciertas columnas
(características) o combinando un número de ellos y obteniendo nuevos datos que contengan
la mayoría de la información. Estudiaremos con más profundidad esta técnica en futuros
artículos.

5.5 División de Datos en “Subsets”

En general, fragmentaremos nuestros datos en tres partes: conjuntos de entrenamiento,


validación y pruebas. Entrenamos nuestro modelo con datos de entrenamiento, lo evaluamos
con datos de validación, y finalmente, una vez está listo para usarse, lo probamos una última
vez con datos de prueba.

Ahora, es razonable preguntar la siguiente cuestión: ¿Por qué no tener solo dos conjuntos de
datos, entrenamiento y pruebas?. De esta manera, el proceso será mucho más simple,
simplemente entrena el modelo con datos de entrenamiento y pruébalo con datos de prueba.

La respuesta es que, desarrollar un modelo implica ajustar su configuración, en otras palabras,


escoger ciertos valores para sus hiperparámetros (que son diferentes de los parámetros del
modelo — “pesos de la red”). Este ajuste se realiza con la información recibida de los datos de
validación, y es en esencia una forma de aprendizaje.

El último objetivo es que el modelo pueda generalizar bien con datos no procesados aún, en
otras palabras, predecir con exactitud resultados con datos nuevos, basados en sus parámetros
internos ajustados mientras el modelo fue entrenado y validado.

a) Proceso de aprendizaje

Podemos echar un vistazo más cercano a cómo se realiza el proceso de aprendizaje estudiando
uno de los algoritmos más simples: la regresión lineal.

En la regresión lineal tenemos un número de variables predictoras (explicativas) y una respuesta


variable continua (resultado), e intentamos encontrar la relación entre ambas variables que nos
permita predecir un resultado continuo.

Un ejemplo de regresión lineal: dados X e Y, calculamos una recta que minimice la distancia
entre los puntos de muestra y la recta ajustada, utilizando algunos métodos para estimar los
coeficientes (como mínimos cuadrados o gradiente decreciente). Después, utilizaremos la
ecuación de la recta obtenida para predecir el resultado utilizando datos nuevos.

La fórmula que muestra la posición de los puntos es: y = B0 + B1x +u.


6
Donde:

x es la entrada, B1 es la pendiente de la recta.

B0 el corte de la recta con el eje y.

u es distancia vertical del punto considerado a la recta (llamado residual).

y es el valor obtenido para un x dado.

Los valores disponibles para el entrenamiento son B0 y B1, que son los valores que afectan a la
posición del recta, ya que las otras variables son la entrada (x) y el resultado (y) (el residual no
se considera). Estos valores (B0 y B1) son los “pesos” de la función de predicción.

Estos pesos, y otros llamados sesgos, son los parámetros que se agruparán en matrices (W para
los pesos y B para los sesgos).

El proceso de entrenamiento implica inicializar algunos valores aleatorios para cada una de las
matrices de entrenamiento, y se trata de predecir la salida correspondiente a los valores de
entrada usando los valores aleatorios iniciales. Al principio el error será grande, pero a través de
la comparación de la predicción del modelo con los resultados correctos, el modelo es capaz de
ajustar los pesos y los sesgos hasta conseguir un buen modelo de predicción.

El proceso se repite iteración tras iteración, y en cada una de ellas la recta aleatoria inicial se va
acercando a la ideal y más exacta.

b) “Overfitting” y “Underfitting”

Uno de los problemas más importantes cuando trabajamos con el entrenamiento de modelos,
es el conflicto entre optimización y generalización.

a) Optimización es el proceso de ajuste de un modelo para conseguir el mejor rendimiento


posible de los datos de entrenamiento (proceso de apredizaje).
b) Generalización es cómo de bien se comporta el modelos ante datos no procesados aún.
El objetivo es conseguir la mejor capacidad de generalización.

Al principio del entrenamiento, estos dos aspectos están relacionados, cuanto menos desajuste
en datos de entrenamiento, menos desajuste en datos de prueba. Esto ocurre mientras el

7
modelo está infra-ajustado ó“underfitted”: todavía hay aprendizaje por realizar ya que aún no
ha sido modelado según todos los parámetros relevantes.

Pero, después de un número de iteraciones de los datos de entrenamiento, la generalización


detiene su progreso y las métricas de validación primero se paralizan y después comienzan a
degradarse. El modelo comienza a estar sobre-ajustado ó “overfitted”: ha aprendido tan bien
los datos de entrenamiento, que ha aprendido pautas que son demasiado específicas de los
datos de entrenamiento e irrelevantes para los nuevos datos.

Hay dos formas de evitar el “overfitting”, obtener más datos y la regularización.

a) Obtener más datos es normalmente la mejor solución, un modelo entrenado con más
datos generalizará mejor de forma natural.
b) La regularización se realiza cuando lo anterior no es posible. Es el proceso de modular
la cantidad de información que el modelo puede almacenar o añadir restricciones con
la información que se permite mantener. Si el modelo solo memorizar un pequeño
número de pautas, la optimización hará que el enfoque se haga en las más relevantes,
mejorando la posibilidad de generalizar bien.

La regularización se realiza principalmente con las siguientes técnicas:

Reduciendo el tamaño del modelo: disminuyendo el número parámetros que el modelo


tiene que aprender, y con ello, su capacidad de aprendizaje. El objetivo es conseguir un
punto de equilibrio entre una capacidad de aprendizaje excesiva o no suficiente.
Desafortunadamente, no hay fórmulas mágicas para determinar ese equilibrio, debe ser
probado y evaluado estableciendo diferentes números de parámetros y observando su
rendimiento.

Añadiendo regularización de peso: en general, cuanto más simple es el modelo, es


mejor. Mientras pueda aprender bien, un modelo más simple es menos proclive a sufrir
“overfitting”. Una forma común de conseguir esto es restringir la complejidad de la red
forzando sus pesos para solamente tomar pequeños valores, regularizando la
distribución de valores de peso. Esto se realiza añadiendo a la función de pérdida de la
red un coste asociado a tener grandes pesos. El coste viene de dos maneras:

Regularización L1: El coste es proporcional al cuadrado del valor de los


coeficientes de peso (norma L1 de los pesos).

Regularización L2: El coste es proporcional al cuadrado del valor de los


coeficientes de peso (norma L2 de los pesos)

8
Para decidir cuál de ellos aplicar a nuestro modelo se recomienda tener presente la
siguiente información y tener en cuenta la naturaleza de nuestro problema

6. Desarrollando un Modelo de Base

El objetivo en este paso del proceso es desarrollar un modelo de comparación que sirva de
referencia, sobre el que mediremos el rendimiento de un algoritmo mejor y más ajustado.

La comparación requiere que los experimentos sean comparables, medibles y reproducibles. Es


importante hacer énfasis en la parte reproducible del párrafo anterior.

Hoy día las librerías de ciencia de datos realizan fragmentaciones aleatorias de datos, esta
aleatoriedad debe ser consistente a lo largo de todas las ejecuciones. La mayoría de generadores
de aleatoriedad permiten “poner la semilla” (seed) para este propósito. En Python usaremos el
método “random.seed” del “random package”.

Normalmente es útil comparar la mejora del modelo sobre un modelo de referencia simplificado
como KNN o Naive Bayes para datos categóricos, o el EWMA de un valor en datos de series
temporales. Estas referencias proporcionan conocimiento sobre el posible valor predictivo de
un conjunto de datos.

Los modelos a menudo requieren mucho menos tiempo y poder de computación para el
entrenamiento y predicción, haciendo de ellos un análisis cruzado útil para la viabilidad de una
respuesta. Ni KNN ni los modelos nativos de Naive Bayes son adecuados para capturar
interacciones complejas. Sin embargo, proporcionarán una estimación razonable del mínimo
nivel de capacidades predictivas de un modelo de comparación.

Adicionalmente, este ejercicio proporciona la oportunidad para probar la fuente de información


de la comparación. Es importante que estas fuentes de información proporcionen resultados
estables para un modelo con características de rendimiento entendidas. Un KNN o un Naive
Bayes en el conjunto de datos en bruto, o mínimamente manipulados con centrado o escalado
de columnas, proporcionarán a menudo un débil, pero adecuado aprendiz, con características
útiles para los propósitos de comparación. Las características de modelos más complejos
pueden ser menos entendidos exigentes para las pruebas.

7. Desarrollando un Modelo Mejor y Ajustando sus Parámetros

7.1 Encontrando un buen modelo

Uno de los métodos más comunes para encontrar un buen modelo es la validación cruzada . En
la validación cruzada, estableceremos:

a) Un número de subdivisiones en los que fragmentaremos nuestros datos.


b) Un método de puntuación (que variará dependiendo de la naturaleza del problema —
regresión, clasificación,…..)
c) Algunos algoritmos apropiados que queremos comprobar

9
Pasaremos nuestro conjunto de datos a nuestra función de puntuación de validación cruzada y
obtener el modelo que da la mejor puntuación. Éste será el que optimizaremos, ajustando sus
parámetros en consecuencia.

Datos en fichero housing.csv

# Test Options and Evaluation Metrics


num_folds = 10
scoring = "neg_mean_squared_error"

# Spot Check Algorithms


models = []
models.append(('LR', LinearRegression()))
models.append(('LASSO', Lasso()))
models.append(('EN', ElasticNet()))
models.append(('KNN', KNeighborsRegressor()))
models.append(('CART', DecisionTreeRegressor()))
models.append(('SVR', SVR()))

results = []
names = []

for name, model in models:


kfold = KFold(n_splits=num_folds, random_state=seed)
cv_results = cross_val_score(model, X_train, y_train, cv=kfold, scoring=scoring)
results.append(cv_results)
names.append(name)
msg = "%s: %f (%f)" % (name, cv_results.mean(), cv_results.std())
print(msg)

# Compare Algorithms
fig = pyplot.figure()
fig.suptitle('Algorithm Comparison')
ax = fig.add_subplot(111)
pyplot.boxplot(results)
ax.set_xticklabels(names)

10
pyplot.show()

7.2 Ajustando los hiperparámetros del modelo

Un algoritmo de Machine Learning tiene dos tipos de parámetros, el primer tipo son los
parámetros que se aprenden a través de la fase de aprendizaje, y el segundo tipo son los
hiperparámetros que transferimos al modelos de machine Learning.

Una vez identificado el modelo que usaremos, el siguiente paso es ajustar sus hiperparámetros
para obtener el mayor poder predictivo posible. La forma más común de encontrar la mejor
combinación de hiperparámetros se llama “Grid Search Cross Validation”.

El proceso sería el siguiente:

a) Establecer la matriz de parámetros que evaluaremos. Haremos esto creando un


diccionario de todos los parámetros y su conjunto correspondientes de valores que
deseamos para para las pruebas de mejor rendimiento.
b) Establecer el número de subdivisiones de datos, el estado aleatorio y un método de
puntuación.
c) Construir un objeto “K-Fold”con el número de subdivisiones seleccionado.
d) Construir un objeto de búsqueda de cuadrícula con el modelo seleccionado y ajustarlo.

# Build a scaler

scaler = StandardScaler().fit(X_train)
rescaledX = scaler.transform(X_train)

# Build parameter grid

c_values = [0.1, 0.3, 0.5, 0.7, 0.9, 1.0, 1.3, 1.5, 1.7, 2.0]
kernel_values = ['linear', 'poly', 'rbf', 'sigmoid']
param_grid = dict(C=c_values, kernel=kernel_values)

# Build the model

model = SVC()

11
kfold = KFold(n_splits=num_folds, random_state=seed)
grid = GridSearchCV(estimator=model, param_grid=param_grid, scoring=scoring, cv=kfold)
grid_result = grid.fit(rescaledX, y_train)

# Show the results

print("Best: %f using %s" % (grid_result.best_score_, grid_result.best_params_))


means = grid_result.cv_results_['mean_test_score']
stds = grid_result.cv_results_['std_test_score']
params = grid_result.cv_results_['params']
for mean, stdev, param in zip(means, stds, params):
print("%f (%f) with: %r" % (mean, stdev, param))

Este método devuelve un conjunto de hiperparámetros que se ajusta de la mejor forma al


problema que consideramos. Una vez que están determinados, nuestro modelo está listo para
ser usado. De esta forma, haremos las predicciones apropiadas en el conjunto de datos de
validación y grabaremos el modelo para uso posterior.

8. Conclusión

Hemos cubierto muchos conceptos importantes a lo largo de este artículo. Aunque se han
revisado estos concepto a alto nivel, es necesario desarrollar una intuición adecuada sobre cómo
y cuándo aplicar los métodos explicados.

Exploraremos estos métodos en mayor profundidad según sean abordados en los artículos
siguientes, así como las implementaciones Python.

En el siguiente artículo comenzaremos con el primer y más común tipo de problemas de


Machine Learning: Regresión

12

También podría gustarte