1. - Introducción al Machine Learning¶
1.1. - IA vs ML vs DL vs GenAI¶
Cuando se oye hablar de Inteligencia Artificial (IA) es común verlo mezclado con otros términos como Machine Learning (ML) o Deep Learning (DL) o IA Generativa, pero ¿todos significan los mismo?¿Qué relación hay entre ellos?
Inteligencia Artificial¶
Es el concepto más amplio, hacer referencia a cualquier sistema informático capaz de "razonar". Se considera que una máquina "razona" cuando su funcionamiento no está directamente implementado como software, sino que es consecuencia indirecta de aplicar una serie de reglas heurísticas o fórmulas matemáticas
Machine Learning¶
Dentro de la Inteligencia Artificial, el Machine Learning es el área de la IA que se encarga en conseguir que la "inteligencia", se consiga a través del aprendizaje en base a datos
Deep Learning¶
Dentro del Machine Learning, el Deep Learning es el área que se encarga de que las máquinas aprendan tarea caracter cognitivo sobre datos no numéricos como imágenes o audio (por ejemplo reconocimiento facial en una imágen, reconocimiento de una canción a través de un audio, resumen de un texto,...)
Generative AI¶
Dentro del Deep Learning, la IA Generativa se encarga de que las máquinas aprendan concretamente a "generar" esos datos de caracter cognitivo, como pueden ser audios, texto o imágenes (por ejemplo, generación de imágenes a través de una descripción)
1.2. - ¿Qué es el Machine Learning?¶
El Machine Learning es el área de las ciencias de la computación que estudia cómo las máquinas pueden "aprender" en base a datos a resolver tareas. Mientras que en el desarrollo de software tiene como objetivo combinar un dato de entrada junto con un código para dar un resultado, el Machine Learning tiene como objetivo combinara un dato de entrada junto con el resultado esperado para generar un conocimiento
Para poder generar ese conocimiento, un proyecto de Machine Learning requiere de 3 ingredientes para ser creado:
Datos¶
Para que las máquinas puedan aprender necesitan de datos sobre los que aprender. Según el tipo tarea que tenga la inteligencia artificial que queremos crear requerirá de unos datos u otros.
Por ejemplo, un modelo que sea capaz de aprender a escribir, necesitará de datos de texto escrito, como por ejemplo libros o páginas webs. Un modelo capaz de predecir el precido de un inmueble en base a sus características necesitará datos históricos de compra-venta de inmuebles en una ciudad (e incluso también otras variables socioeconómicas, como la inflación, el sueldo medio...)
NOTA: Se dice que los datos están "etiquetados" cuando contienen la información de los que se quiere predecir
Modelo¶
El modelo hace referencia al algoritmo y/o fórmulación matemática que representa el proceso de aprendizaje.
Por hacer un símil con el proceso de aprendizaje humano, cuando un estudiante está estudiando para un examen, los datos harían referencia al libro de la asignatura, mientras que el modelo haría referencia a las técnicas de estudio que un estudiante para aprenderlo. Estas técnicas no tiene por qué ser las mismas para todos los estudiantes (hay algunos que prefieren aprender por temas, otros empezar por la práctica, otros por la teoría...), del mismo modo, también existen diferentes modelos de Machine Learning
Código¶
El software hacer referencia a la implementación en código del proceso que se encarga de leer los datos como de la implementación del modelo. Aunque en teoría podríamos hacer Machine Learning con "papel y boli" en la práctica, para que sea útil en el mundo real, se implementa de manera programática con software.
1.3. - ¿Qué se puede hacer con IA?¶
Ejemplo 1: Diagnóstico de tumores en radiografías¶
Caso de uso A partir de radiografías, crear una inteligencia artificial que use la imagen como input y sea capaz de detectar si hay algún tipo de tumor. Para ello, el tipo de IA que se desarrolla y sus componentes son las siguientes
- Deep Learning: Este tipo de problema se resuelve con Deep Learning, ya que tenemos que utilizar IAs con la capacidad cognitiva de "ver" imágenes. Del mismo modo no se hace con GenAI ya que el objetivo no es generar imágenes sino detectar si hay tumores en la imagen.
- Radiografías etiquetadas: La IA aprende a detectar tumores en base a datos, por ello es necesario tener un histórico de imágenes de radiografías con y sin tumores, para que el modelo sea capaz de aprender a distinguir entre unas y otras.
Ejercicio¶
Tratar de adivinar el tipo de Inteligencia Artificial, así cómo de componentes que son necesarias para las siguientes aplicaciones
ChatGPT
- Tipo de IA
- Datos
Tesla: Vehículos autónomos
- Tipo
- Datos
Autocorrector del movil
- Tipo
- Datos
Predicción de ventas en una empresa
- Tipo
- Datos
2. - Regressión Lineal Básica¶
Para empezar a entender cómo podemos crear modelos de Machine Learning, vamos a empezar con el algoritmo más sencillo, la regresión lineal. Además, para poder entenderlo de forma visual, vamos a empezar viéndolo con Excel
¿Qué es la regresión lineal?
La regresión lineal es un tipo de modelo de Machine Learning que presupone que exite una relación lineal entre los datos de entrada y el resultado a predecir (se podría decir que casi funciona como una "regla de 3" pero con más variables)
Por ejemplo, si queremos hacer un modelo que prediga que nota va a sacar un alumno en un examen a partir del número de horas estudidas, podemos suponer que (en general) quien estudia más saca más nota y quien estudia menos saca menos nota. También podemos suponer (en parte) que quien estudia el doble saca el doble de nota. Es por ello por lo que en este caso podríamos usar una regresión lineal como modelo.
2.1 - Regresión con Excel¶
Datos - Nota de examen¶
Lo primero que necesitamos para que un modelo aprenda es tener datos de notas de otros años, por ello vamos a coger las notas de otros años para generar el dataset (conjunto de datos que usa un modelo) para generar el modelo.
| Alumno | Horas de estudio | Nota |
|---|---|---|
| 1 | 7 | 9,05 |
| 2 | 6 | 8,85 |
| 3 | 1 | 2,91 |
| 4 | 1,5 | 3 |
| 5 | 8 | 7,62 |
| 6 | 4 | 6,64 |
| 7 | 3 | 5,5 |
| 8 | 4 | 5,37 |
| 9 | 6 | 8,34 |
| 10 | 6 | 9,22 |
| 11 | 6 | 6,64 |
| 12 | 2 | 4,5 |
| 13 | 2 | 3,8 |
| 14 | 2 | 5,37 |
| 15 | 5 | 4,62 |
| 16 | 5 | 6,04 |
| 17 | 6 | 7,62 |
| 18 | 10 | 8,85 |
| 19 | 1 | 2,25 |
| 20 | 7 | 7,16 |
En este caso nos gustaría se capaces de predecir la variable Nota en base a la variable Horas de estudio. En términos de Machine Learning, este problema se define de la siguiente forma
- Tarjet (Variable Dependiente): Variable que queremos predecir a partir de un modelo de Machine Learning (en este caso la Regresión Lineal).
- Variables independientes: Variables que usamos para predecir el tarjet, en este caso la variable
Horas de Estudio. La variableAlumnono la tenemos en cuenta porque no aporta información, solo es un identificador.
Modelo con Excel¶
Creamos el dataset de notas
Generar gráfico de dispersión
Hacer ajuste del modelo
Coeficientes¶
Excel trae ya una implementación de la Regresión Lineal, por lo que no es necesario tener que programar nosotros las ecuaciones y el algoritmo para calcular la recta que mejor se ajusta a los datos. En general, la ecuación matemática de la regresión lineal es la siguiente:
\begin{equation} y = α \cdot x + β \end{equation}
Donde α y β son los coeficientes que el modelo tiene que aprender a partir de los datos. En nuestro caso, vemos que Excel después de aplicar la Regresión Lineal sobre los datos, los coefiecies que hemos obtenido (o lo que es lo mismo, el conocimiento del modelo) son los siguientes:
\begin{equation} y = 0.753 \cdot x + 2.69 \end{equation}
NOTA La regresión lineal es un modelo de ML donde se aprenden 2 parámetros. ChatGPT tiene 175B de parámetros
Interpretación de R²¶
Además de la ecuación de la recta, podemos ver otro número dentro de la gráfica de Excel, el coeficiente de determinación. Este coeficiente mide cómo de bien se ajusta nuestro modelo a los datos. Un coeficiente R²=1 significa que nuestro modelo se ajuta de manera perfecta a los datos, mientras que un coeficientes de R²=0 significa que no ha aprendido nada.
En este caso, el modelo que estamos usando es el de la regresión lineal. Como hemos dicho, este modelo supone que los datos tienen un comportamiento lineal, por lo tanto, el hecho de que obtuviesemos un valor de R²=0 significa que nuestros datos no tienen un comportamiento lineal
TIP: En Machine Learning, se considera que un algoritmo tiene un coeficiente de R² suficientemente cuando está entre 0.8 y 1.0. Se considera que tiene cierta correlación, aunque no sea completamente determinista cuando está entre 0.6 y 0.8
2.2 - Regresión Python¶
En la sección anterior hemos visto que la Regresión Lineal es un modelo de Machine Learning que trata de predecir el valor de una variable numérica a partir de suponer una relación lineal con otra variable. Sin embargo, en la mayoría de casos de la vida real no tratamos de predecir a partir de una única variable, sino que tenemos muchas (decenas). En estos casos la Regresión Lineal es más difícil de visualizar
En estos casos, para poder hacer una regresión lineal es necesario usar herramientas más potentes que excel, como por ejemplo Python
Predicción de la resistencia del cemento¶
Un problema clásico en la literatura de Machine Learning es el de la predicción de la resitencia del cemento. La resistencia del cemento es muy importante ya que es necesario asegurar que cumple un nivel de resistencia a la hora de ser usado. Sin embargo, según variables como la humedad, el paso del tiempo,... puede reducir sus resistencia. En un estudio de 1998 se desarrolló un modelo de Machine Learning capaz de predecir la resistencia del cemento en base a las siguientes variables:
| variable | naturaleza | descripción | tipo |
|---|---|---|---|
| Cemento | cuantitativo | kg en una mezcla de m³ | Variable de Entrada |
| Escoria de Alto Horno | cuantitativo | kg en una mezcla de m³ | Variable de Entrada |
| Ceniza Volante | cuantitativo | kg en una mezcla de m³ | Variable de Entrada |
| Agua | cuantitativo | kg en una mezcla de m³ | Variable de Entrada |
| Superplastificante | cuantitativo | kg en una mezcla de m³ | Variable de Entrada |
| Agregado Grueso | cuantitativo | kg en una mezcla de m³ | Variable de Entrada |
| Agregado Fino | cuantitativo | kg en una mezcla de m³ | Variable de Entrada |
| Edad | cuantitativo | Días (1~365) | Variable de Entrada |
| Resistencia a la compresión del cemento | cuantitativo | MPa | Variable de Salida |
Para ver más sobre el dataset se puede echar un ojo a este link
Leer los datos¶
Empezamos leyendo el dataset con Python usando una url de una página web donde está subido este dataset
import pandas as pd
url = 'https://raw.githubusercontent.com/stedy/Machine-Learning-with-R-datasets/refs/heads/master/concrete.csv'
data = pd.read_csv(url)
data
| cement | slag | ash | water | superplastic | coarseagg | fineagg | age | strength | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 540.0 | 0.0 | 0.0 | 162.0 | 2.5 | 1040.0 | 676.0 | 28 | 79.99 |
| 1 | 540.0 | 0.0 | 0.0 | 162.0 | 2.5 | 1055.0 | 676.0 | 28 | 61.89 |
| 2 | 332.5 | 142.5 | 0.0 | 228.0 | 0.0 | 932.0 | 594.0 | 270 | 40.27 |
| 3 | 332.5 | 142.5 | 0.0 | 228.0 | 0.0 | 932.0 | 594.0 | 365 | 41.05 |
| 4 | 198.6 | 132.4 | 0.0 | 192.0 | 0.0 | 978.4 | 825.5 | 360 | 44.30 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 1025 | 276.4 | 116.0 | 90.3 | 179.6 | 8.9 | 870.1 | 768.3 | 28 | 44.28 |
| 1026 | 322.2 | 0.0 | 115.6 | 196.0 | 10.4 | 817.9 | 813.4 | 28 | 31.18 |
| 1027 | 148.5 | 139.4 | 108.6 | 192.7 | 6.1 | 892.4 | 780.0 | 28 | 23.70 |
| 1028 | 159.1 | 186.7 | 0.0 | 175.6 | 11.3 | 989.6 | 788.9 | 28 | 32.77 |
| 1029 | 260.9 | 100.5 | 78.3 | 200.6 | 8.6 | 864.5 | 761.5 | 28 | 32.40 |
1030 rows × 9 columns
Separación de Train y Test¶
Cuando se desarrolla un modelo de Machine Learning es común separar el conjunto de datos en 2 conjuntos distintos, uno que se denominada dataset de entrenamiento que es el que se usa para generar el modelo y otro que se llama dataset de test que es el que se usa para medir cómo de bien funciona el modelo entrenado.
Esto es muy importante, ya que para poder saber que un modelo funciona correctamente es necesario medirlo y esto no se puede hacer sobre datos que "ha visto" (ya que puede que por haberlos visto antes no falle). Lo que queremos ver es que no falla sobre nuevos datos.
NOTA: Generalmente, el dataset de entrenamiento suele ser el 80%-90% del volumen total de datos, mientras que el dataset de test suele ser solamente el 20%-10%.
#data = data.sample(n=len(data), random_state=0)
data_train = data[0:int(0.9*len(data))]
data_test = data[int(0.9*len(data)):]
data_train
| cement | slag | ash | water | superplastic | coarseagg | fineagg | age | strength | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 540.0 | 0.0 | 0.0 | 162.0 | 2.5 | 1040.0 | 676.0 | 28 | 79.99 |
| 1 | 540.0 | 0.0 | 0.0 | 162.0 | 2.5 | 1055.0 | 676.0 | 28 | 61.89 |
| 2 | 332.5 | 142.5 | 0.0 | 228.0 | 0.0 | 932.0 | 594.0 | 270 | 40.27 |
| 3 | 332.5 | 142.5 | 0.0 | 228.0 | 0.0 | 932.0 | 594.0 | 365 | 41.05 |
| 4 | 198.6 | 132.4 | 0.0 | 192.0 | 0.0 | 978.4 | 825.5 | 360 | 44.30 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 922 | 255.0 | 99.0 | 77.0 | 189.0 | 6.0 | 919.0 | 749.0 | 28 | 33.80 |
| 923 | 162.0 | 207.0 | 172.0 | 216.0 | 10.0 | 822.0 | 638.0 | 28 | 39.84 |
| 924 | 136.0 | 196.0 | 98.0 | 199.0 | 6.0 | 847.0 | 783.0 | 28 | 26.97 |
| 925 | 164.0 | 163.0 | 128.0 | 197.0 | 8.0 | 961.0 | 641.0 | 28 | 27.23 |
| 926 | 162.0 | 214.0 | 164.0 | 202.0 | 10.0 | 820.0 | 680.0 | 28 | 30.65 |
927 rows × 9 columns
data_test
| cement | slag | ash | water | superplastic | coarseagg | fineagg | age | strength | |
|---|---|---|---|---|---|---|---|---|---|
| 927 | 157.0 | 214.0 | 152.0 | 200.0 | 9.0 | 819.0 | 704.0 | 28 | 33.05 |
| 928 | 149.0 | 153.0 | 194.0 | 192.0 | 8.0 | 935.0 | 623.0 | 28 | 24.58 |
| 929 | 135.0 | 105.0 | 193.0 | 196.0 | 6.0 | 965.0 | 643.0 | 28 | 21.91 |
| 930 | 159.0 | 209.0 | 161.0 | 201.0 | 7.0 | 848.0 | 669.0 | 28 | 30.88 |
| 931 | 144.0 | 15.0 | 195.0 | 176.0 | 6.0 | 1021.0 | 709.0 | 28 | 15.34 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 1025 | 276.4 | 116.0 | 90.3 | 179.6 | 8.9 | 870.1 | 768.3 | 28 | 44.28 |
| 1026 | 322.2 | 0.0 | 115.6 | 196.0 | 10.4 | 817.9 | 813.4 | 28 | 31.18 |
| 1027 | 148.5 | 139.4 | 108.6 | 192.7 | 6.1 | 892.4 | 780.0 | 28 | 23.70 |
| 1028 | 159.1 | 186.7 | 0.0 | 175.6 | 11.3 | 989.6 | 788.9 | 28 | 32.77 |
| 1029 | 260.9 | 100.5 | 78.3 | 200.6 | 8.6 | 864.5 | 761.5 | 28 | 32.40 |
103 rows × 9 columns
Separación de Features y Target¶
Una vez que tenemos separados los datasets de entrenamiento y test, separamos el conjunto de datos de la variable a predecir. En nuestro caso el objetivo de este problema es que a partir de la medida de variables como humedad, edad... sepamos predecir la resistencia del hormigón
La variable a predecir (variable dependientes) es la resistencia del hormigón, mientras que las variables de entrada (variables independientes) son el resto
X_train = data_train.drop("strength", axis=1)
y_train = data_train[["strength"]]
X_test = data_test.drop("strength", axis=1)
y_test = data_test[["strength"]]
X_train
| cement | slag | ash | water | superplastic | coarseagg | fineagg | age | |
|---|---|---|---|---|---|---|---|---|
| 0 | 540.0 | 0.0 | 0.0 | 162.0 | 2.5 | 1040.0 | 676.0 | 28 |
| 1 | 540.0 | 0.0 | 0.0 | 162.0 | 2.5 | 1055.0 | 676.0 | 28 |
| 2 | 332.5 | 142.5 | 0.0 | 228.0 | 0.0 | 932.0 | 594.0 | 270 |
| 3 | 332.5 | 142.5 | 0.0 | 228.0 | 0.0 | 932.0 | 594.0 | 365 |
| 4 | 198.6 | 132.4 | 0.0 | 192.0 | 0.0 | 978.4 | 825.5 | 360 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 922 | 255.0 | 99.0 | 77.0 | 189.0 | 6.0 | 919.0 | 749.0 | 28 |
| 923 | 162.0 | 207.0 | 172.0 | 216.0 | 10.0 | 822.0 | 638.0 | 28 |
| 924 | 136.0 | 196.0 | 98.0 | 199.0 | 6.0 | 847.0 | 783.0 | 28 |
| 925 | 164.0 | 163.0 | 128.0 | 197.0 | 8.0 | 961.0 | 641.0 | 28 |
| 926 | 162.0 | 214.0 | 164.0 | 202.0 | 10.0 | 820.0 | 680.0 | 28 |
927 rows × 8 columns
y_test
| strength | |
|---|---|
| 927 | 33.05 |
| 928 | 24.58 |
| 929 | 21.91 |
| 930 | 30.88 |
| 931 | 15.34 |
| ... | ... |
| 1025 | 44.28 |
| 1026 | 31.18 |
| 1027 | 23.70 |
| 1028 | 32.77 |
| 1029 | 32.40 |
103 rows × 1 columns
Modelo de Sklearn¶
Una ver que ya tenemos los datos, tenemos que crear el modelo. En Python existen muchas librerías que contienen modelos preconstruidos, una de ellas es Scikit-Learn. Scikit-Learn es la librerías más popular para la mayoría de modelos de Machine Learning (en el caso particular de Deep Learning se suelen usar otras).
Scikit-Learn nos permite usar modelos sin tener que programar las matemáticas que lo componen. Por ejemplo, para crear un modelo de regresión lineal solo tenemos que hacer lo siguiente
from sklearn.linear_model import LinearRegression
model = LinearRegression()
Una vez hemos creado (en informática esto se llama "instanciar") el modelo. Tenemos que pasarle los datos para que aprenda en base a ellos. El proceso durante el cual un algoritmo aprende a partir de los datos se denomina entrenamiento. Para entrenar el modelo de regresión lineal solamente tenemos que hacer lo siguiente
model.fit(X_train,y_train)
LinearRegression()In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
LinearRegression()
X_train.columns
Index(['cement', 'slag', 'ash', 'water', 'superplastic', 'coarseagg',
'fineagg', 'age'],
dtype='object')
model.coef_
array([[ 0.11324122, 0.09721257, 0.08663271, -0.17011027, 0.311439 ,
0.01555368, 0.01260836, 0.11543239]])
2.3. - Ejecución¶
Predicción¶
Ya tenemos el modelo entrenado (i.e. un modelo de ML que tiene todo el conocimiento de los datos que le hemos pasado para predecir la dureza del hormigón en base a sus otras propiedades). Para poder hacer predicciones tenemos simplemente tenemos que pasarle un dato a la función predict
X_test
| cement | slag | ash | water | superplastic | coarseagg | fineagg | age | |
|---|---|---|---|---|---|---|---|---|
| 927 | 157.0 | 214.0 | 152.0 | 200.0 | 9.0 | 819.0 | 704.0 | 28 |
| 928 | 149.0 | 153.0 | 194.0 | 192.0 | 8.0 | 935.0 | 623.0 | 28 |
| 929 | 135.0 | 105.0 | 193.0 | 196.0 | 6.0 | 965.0 | 643.0 | 28 |
| 930 | 159.0 | 209.0 | 161.0 | 201.0 | 7.0 | 848.0 | 669.0 | 28 |
| 931 | 144.0 | 15.0 | 195.0 | 176.0 | 6.0 | 1021.0 | 709.0 | 28 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 1025 | 276.4 | 116.0 | 90.3 | 179.6 | 8.9 | 870.1 | 768.3 | 28 |
| 1026 | 322.2 | 0.0 | 115.6 | 196.0 | 10.4 | 817.9 | 813.4 | 28 |
| 1027 | 148.5 | 139.4 | 108.6 | 192.7 | 6.1 | 892.4 | 780.0 | 28 |
| 1028 | 159.1 | 186.7 | 0.0 | 175.6 | 11.3 | 989.6 | 788.9 | 28 |
| 1029 | 260.9 | 100.5 | 78.3 | 200.6 | 8.6 | 864.5 | 761.5 | 28 |
103 rows × 8 columns
one_sample = X_test.head(1)
one_sample
| cement | slag | ash | water | superplastic | coarseagg | fineagg | age | |
|---|---|---|---|---|---|---|---|---|
| 927 | 157.0 | 214.0 | 152.0 | 200.0 | 9.0 | 819.0 | 704.0 | 28 |
predicted_output = model.predict(one_sample)
predicted_output
array([[36.23203658]])
y_test.head(1)
| strength | |
|---|---|
| 927 | 33.05 |
model.predict(X_test)[0:10]
array([[36.23203658],
[34.86710668],
[27.94435169],
[35.96892648],
[25.49301934],
[28.72115096],
[40.76506435],
[27.58893858],
[30.86572079],
[17.92332847]])
one_sample = X_test.head(1)
expected_output = y_test.head(1)
predicted_output = model.predict(one_sample)
print("Sample\n\n",one_sample)
print("\n")
print("Strength\t",expected_output.values[0][0])
print("Prediction\t", predicted_output[0][0])
Sample
cement slag ash water superplastic coarseagg fineagg age
927 157.0 214.0 152.0 200.0 9.0 819.0 704.0 28
Strength 33.05
Prediction 36.2320365763017
Evaluación¶
R2 Score
Finalmente evaluamos sobre el dataset de test cómo de bien funciona el modelo. Como hemos dicho antes, el coeficiente de determinación nos permite saber cómo de bien sabe estimar nuesto modelo la dureza del cemento en base a las variables que le hemos pasasdo.
from sklearn.metrics import r2_score
y_pred = model.predict(X_test)
r2_score(y_test,y_pred)
0.5565254570001374
Root Mean Squared Error
El coeficiende de correlación nos dice en un número entre 0 y 1 cuánto ha aprendido el modelo. Sin embargo, muchas veces nos interesa más saber "cuánto se equivoca", o lo que es lo mismo, si cuando el modelo estima una fuerza del cemento de 56.04, podamos saber si el error +-1 +-10 o +-100. Esto se puede calcular por medio de lo que se denomina error cuadrático medio o RMSE (de sus siglas en inglés: Root Mean Square Error)
from sklearn.metrics import root_mean_squared_error
y_pred = model.predict(X_test)
root_mean_squared_error(y_test,y_pred)
7.995842426210273
Ejercicio¶
Utilizar los datos que hemos visto de notas de alumnos para hacer una regresión lineal en Python
data = pd.DataFrame([
{"Alumno":1, "Horas de estudio":7, "Nota":10.0},
{"Alumno":2, "Horas de estudio":6, "Nota":8.5},
{"Alumno":3, "Horas de estudio":1, "Nota":2.1},
{"Alumno":4, "Horas de estudio":1.5,"Nota":3},
{"Alumno":5, "Horas de estudio":8, "Nota":7.2},
{"Alumno":6, "Horas de estudio":4, "Nota":6.4},
{"Alumno":7, "Horas de estudio":3, "Nota":5.0},
{"Alumno":8, "Horas de estudio":4, "Nota":5.7},
{"Alumno":9, "Horas de estudio":6, "Nota":8.4},
{"Alumno":10, "Horas de estudio":6, "Nota":9.2},
{"Alumno":11, "Horas de estudio":6, "Nota":6.4},
{"Alumno":12, "Horas de estudio":2, "Nota":4.},
{"Alumno":13, "Horas de estudio":2, "Nota":3.},
{"Alumno":14, "Horas de estudio":2, "Nota":5.7},
{"Alumno":15, "Horas de estudio":5, "Nota":4.2},
{"Alumno":16, "Horas de estudio":5, "Nota":6.4},
{"Alumno":17, "Horas de estudio":6, "Nota":7.2},
{"Alumno":18, "Horas de estudio":10, "Nota":8.5},
{"Alumno":19, "Horas de estudio":1, "Nota":2.5},
{"Alumno":20, "Horas de estudio":7, "Nota":7.6}
])
data.head()
| Alumno | Horas de estudio | Nota | |
|---|---|---|---|
| 0 | 1 | 7.0 | 10.0 |
| 1 | 2 | 6.0 | 8.5 |
| 2 | 3 | 1.0 | 2.1 |
| 3 | 4 | 1.5 | 3.0 |
| 4 | 5 | 8.0 | 7.2 |
3. - Regresión Lineal Avanzada¶
En la sección anterior hemos visto las componentes más básicas para hacer una regresión lineal con Python, sin embargo, en proyectos reales suele haber más pasos intermedios que suelen ser necesarios para conseguir un buen resultado. Est podemos hacerlo a partir de análisis estadístico y/o a partir de visualizaciones
data = data.set_index('Alumno')
data.describe()
| Horas de estudio | Nota | |
|---|---|---|
| count | 20.000000 | 20.000000 |
| mean | 4.625000 | 6.050000 |
| std | 2.528131 | 2.342401 |
| min | 1.000000 | 2.100000 |
| 25% | 2.000000 | 4.150000 |
| 50% | 5.000000 | 6.400000 |
| 75% | 6.000000 | 7.800000 |
| max | 10.000000 | 10.000000 |
data.Nota.hist(bins=8)
<Axes: >
3.1. - Limpieza de datos¶
Es común que cuando trabajamos con datos reales haya datos erroneos de diferentes tipos (NA, outliers,...). Antes de entrenar un modelo de Machine Learning es necesario "resolver" este tipo de te problemas con diferentes estrategias.
# Esto sería un outlier
data.loc[20, "Horas de estudio"] = 99999
# Esto sería un dato erroneo
data.loc[20, "Horas de estudio"] = -1
# Esto sería un dato vacío
data.loc[20, "Horas de estudio"] = pd.NA
data.tail()
| Horas de estudio | Nota | |
|---|---|---|
| Alumno | ||
| 16 | 5.0 | 6.4 |
| 17 | 6.0 | 7.2 |
| 18 | 10.0 | 8.5 |
| 19 | 1.0 | 2.5 |
| 20 | NaN | 7.6 |
Por ejemplo, para eliminar NAs podemos hacer lo siguiente
data = data.dropna()
data.tail()
| Horas de estudio | Nota | |
|---|---|---|
| Alumno | ||
| 15 | 5.0 | 4.2 |
| 16 | 5.0 | 6.4 |
| 17 | 6.0 | 7.2 |
| 18 | 10.0 | 8.5 |
| 19 | 1.0 | 2.5 |
3.2. - Preprocesamiento¶
Más allá de limpiar el dataset, suele ser importante hacer procesamiento previo para mejorar los resultados. Según qué datos manejes y qué algoritmo estés usando es conveniente hacer un tipo de preprocesamiento u otro (p.e. en el caso de la regresión lineal suele ser interesante el Standard Scaller).
Standard Scaler
Hay veces que el orden de magnitud y la varianza numérica de las variables influye en el aprendizaje. El Standard Scaler hace que todas las variables estén centradas en 0 con varianza 1
from sklearn import preprocessing
data = data[["Nota", "Horas de estudio"]]
scaler = preprocessing.StandardScaler().fit(data)
data_scaled = pd.DataFrame(scaler.transform(data), columns=data.columns, index=data.index)
data_scaled.head()
| Nota | Horas de estudio | |
|---|---|---|
| Alumno | ||
| 1 | 1.742395 | 1.013972 |
| 2 | 1.094115 | 0.608383 |
| 3 | -1.671880 | -1.419560 |
| 4 | -1.282912 | -1.216766 |
| 5 | 0.532272 | 1.419560 |
One Hot Encodder
Este tipo de preprocesamiento es útil cuando tenemos alguna variable de caracter categórico. Este tipo de preprocesamiento se encarga de convertir esta variable en formato numérico
import pandas as pd
data = pd.DataFrame([
{"Alumno":1, "Clase": "A", "Horas de estudio":7, "Nota":9.5},
{"Alumno":2, "Clase": "A", "Horas de estudio":6, "Nota":8.5},
{"Alumno":3, "Clase": "A", "Horas de estudio":1, "Nota":2.1},
{"Alumno":4, "Clase": "A", "Horas de estudio":1, "Nota":3},
{"Alumno":5, "Clase": "A", "Horas de estudio":8, "Nota":7.2},
{"Alumno":6, "Clase": "A", "Horas de estudio":4, "Nota":6.4},
{"Alumno":7, "Clase": "B", "Horas de estudio":3, "Nota":5.0},
{"Alumno":8, "Clase": "B", "Horas de estudio":4, "Nota":5.7},
{"Alumno":9, "Clase": "B", "Horas de estudio":6, "Nota":8.4},
{"Alumno":10, "Clase": "B", "Horas de estudio":6, "Nota":9.2},
{"Alumno":11, "Clase": "B", "Horas de estudio":6, "Nota":6.4},
{"Alumno":12, "Clase": "B", "Horas de estudio":2, "Nota":4.},
{"Alumno":13, "Clase": "B", "Horas de estudio":2, "Nota":3.},
{"Alumno":14, "Clase": "C", "Horas de estudio":2, "Nota":5.7},
{"Alumno":15, "Clase": "C", "Horas de estudio":5, "Nota":4.2},
{"Alumno":16, "Clase": "C", "Horas de estudio":5, "Nota":6.4},
{"Alumno":17, "Clase": "C", "Horas de estudio":6, "Nota":7.2},
{"Alumno":18, "Clase": "C", "Horas de estudio":10, "Nota":8.5},
{"Alumno":19, "Clase": "C", "Horas de estudio":1, "Nota":2.5},
{"Alumno":20, "Clase": "C", "Horas de estudio":7, "Nota":7.6}
]).set_index('Alumno')
data
| Clase | Horas de estudio | Nota | |
|---|---|---|---|
| Alumno | |||
| 1 | A | 7 | 9.5 |
| 2 | A | 6 | 8.5 |
| 3 | A | 1 | 2.1 |
| 4 | A | 1 | 3.0 |
| 5 | A | 8 | 7.2 |
| 6 | A | 4 | 6.4 |
| 7 | B | 3 | 5.0 |
| 8 | B | 4 | 5.7 |
| 9 | B | 6 | 8.4 |
| 10 | B | 6 | 9.2 |
| 11 | B | 6 | 6.4 |
| 12 | B | 2 | 4.0 |
| 13 | B | 2 | 3.0 |
| 14 | C | 2 | 5.7 |
| 15 | C | 5 | 4.2 |
| 16 | C | 5 | 6.4 |
| 17 | C | 6 | 7.2 |
| 18 | C | 10 | 8.5 |
| 19 | C | 1 | 2.5 |
| 20 | C | 7 | 7.6 |
from sklearn.preprocessing import OneHotEncoder
encoder = OneHotEncoder(sparse_output=False).set_output(transform="pandas")
encoder.fit(data[['Clase']])
data_encoded = pd.DataFrame(encoder.transform(data[['Clase']]))
data_encoded = data.merge(data_encoded, left_index=True, right_index=True)
data_encoded = data_encoded.drop('Clase', axis=1)
data_encoded
| Horas de estudio | Nota | Clase_A | Clase_B | Clase_C | |
|---|---|---|---|---|---|
| Alumno | |||||
| 1 | 7 | 9.5 | 1.0 | 0.0 | 0.0 |
| 2 | 6 | 8.5 | 1.0 | 0.0 | 0.0 |
| 3 | 1 | 2.1 | 1.0 | 0.0 | 0.0 |
| 4 | 1 | 3.0 | 1.0 | 0.0 | 0.0 |
| 5 | 8 | 7.2 | 1.0 | 0.0 | 0.0 |
| 6 | 4 | 6.4 | 1.0 | 0.0 | 0.0 |
| 7 | 3 | 5.0 | 0.0 | 1.0 | 0.0 |
| 8 | 4 | 5.7 | 0.0 | 1.0 | 0.0 |
| 9 | 6 | 8.4 | 0.0 | 1.0 | 0.0 |
| 10 | 6 | 9.2 | 0.0 | 1.0 | 0.0 |
| 11 | 6 | 6.4 | 0.0 | 1.0 | 0.0 |
| 12 | 2 | 4.0 | 0.0 | 1.0 | 0.0 |
| 13 | 2 | 3.0 | 0.0 | 1.0 | 0.0 |
| 14 | 2 | 5.7 | 0.0 | 0.0 | 1.0 |
| 15 | 5 | 4.2 | 0.0 | 0.0 | 1.0 |
| 16 | 5 | 6.4 | 0.0 | 0.0 | 1.0 |
| 17 | 6 | 7.2 | 0.0 | 0.0 | 1.0 |
| 18 | 10 | 8.5 | 0.0 | 0.0 | 1.0 |
| 19 | 1 | 2.5 | 0.0 | 0.0 | 1.0 |
| 20 | 7 | 7.6 | 0.0 | 0.0 | 1.0 |
X = data_encoded.drop('Nota', axis=1)
y = data_encoded[["Nota"]]
LinearRegression().fit(X,y)
LinearRegression()In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
LinearRegression()
Nota: Para más información sobre cómo preprocesar datos leer esta documentacion
3.3. - Hiperparametrización¶
En el caso de la regresión lineal es un modelo muy sencillo y tiene pocos grados de libertad, sin embargo, es común que otros modelos sean configurables. ElasticNet es una extensión del concepto de Regresión Lineal que permite configurar diferentes parámetros.
Cada model tiene sus propios parámetros para entrenar y durante el proceso de creación de un modelo se van "afinando" (tunning) hasta encontrar con la configuración que da mejores resultados.
from sklearn.linear_model import ElasticNet
model = ElasticNet(
alpha=1.0,
l1_ratio=0.5,
fit_intercept=True,
precompute=False,
max_iter=1000,
tol=0.0001,
warm_start=False,
)
3.4. - ¿Donde encontrar datasets?¶
Un problema común cuando se quiere hacer proyectos de Machine Learning es el de encontrar los datos para poder entrenar un modelo. En esta sección vamos a ver algunos repositorios donde se pueden encontrar datasets
Datos de investigación
Para investigación / aprendizaje existen páginas web que tienen información de dominio público. Algunos ejemplos son:
UCI - Machine learning: Repositorio de dataset usados generalmente para papers y/o proyectos de I+D
Kaggle: Plataforma de cursos y retos de machine learning donde también es fácil encontrar aquí datasets.
HuggingFace: Repositorio de modelso de lenguaje así como datasets de lenguaje tanto de la comunidad como opensource
Acceso a datos reales
- Newspaper: Librería en Python para poder acceder fácilmente a periódicos de todo el mundo
!pip3 install -q newspaper3k
!pip3 install -q lxml_html_clean
import newspaper
url = 'https://elpais.com/'
first_article = newspaper.build(url).articles[0]
first_article.download()
first_article.parse()
print(first_article.text)
Preparing metadata (setup.py) ... done
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 7.4/7.4 MB 41.4 MB/s eta 0:00:00
Preparing metadata (setup.py) ... done
Preparing metadata (setup.py) ... done
Preparing metadata (setup.py) ... done
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 211.1/211.1 kB 5.5 MB/s eta 0:00:00
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 81.5/81.5 kB 3.2 MB/s eta 0:00:00
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 105.9/105.9 kB 4.5 MB/s eta 0:00:00
Building wheel for tinysegmenter (setup.py) ... done
Building wheel for feedfinder2 (setup.py) ... done
Building wheel for jieba3k (setup.py) ... done
Building wheel for sgmllib3k (setup.py) ... done
CRITICAL:newspaper.network:[REQUEST FAILED] 404 Client Error: Not Found for url: https://elpais.com/feed/ CRITICAL:newspaper.network:[REQUEST FAILED] 404 Client Error: Not Found for url: https://elpais.com/feeds/
Las caras de la protesta en Minneapolis. En la fila de arriba, de izquierda derecha, Sarah Charging, Mike Camilleri, Abe Eversman tras una máscara de primate,, Josiah Myeog, Julie Prokes y Lesley Ernst. Abajo, también de izquierda a derecha, Nekima Levy Armstrong, Jim Winterer, una mujer vestida de rana, Cathy Anderson, Joey Keillor y Rogelio Aguilar. Con una mezcla de solidaridad y rebeldía, los vecinos de Minnesota llevan semanas perfeccionando la red con la que plantan cara a los agentes federales y han logrado torcer la mano del Gobierno de Estados Unidos Desde hace semanas, los teléfonos vibran sin cesar en Minneapolis. Son cientos de pequeños calambrazos al día; uno por cada mensaje que reciben los vecinos apuntados en los grupos de Signal que vigilan y hostigan a los 3.000 agentes de la policía secreta migratoria de Donald Trump desplegados en la ciudad. En esa red social encriptada, el papel de cada cual viene definido por un código de emoticonos: coches, platos, corazones vendados… Los hay que patrullan las calles en busca de los federales enmascarados, que circulan en coches sin marcar y van armados hasta los dientes. Están los que administran los primeros auxilios cuando la cosa se tuerce, los que fotografían matrículas y los que las cotejan con las bases de datos disponibles. Hay varias llamadas al día de puesta en común. Cuando alguien avisa de una redada en marcha, los vehículos de los “observadores” que están en la zona salen zumbando para tratar de impedirla o, al menos, para ser testigos o entorpecer la cacería al inmigrante. Una vez allí, soplan sus silbatos, graban a los agentes con el móvil y se encaran con ellos. A veces acaban arrestados. Cada barrio de las Twin Cities (que forman las ciudades gemelas de Minneapolis y St. Paul; 3,7 millones de habitantes en total) tiene su propio grupo. Y no es tan fácil ser admitido. El motivo se entiende después, con la primera advertencia al recién llegado: mejor no compartir ninguna información personal, porque “la extrema derecha se ha infiltrado” en ellos. Además, el FBI ya ha advertido de que analizará su contenido. 03:47 Por qué Trump eligió Minnesota para dar ejemplo con el ICE Memorial en honor a Alex Pretti en el lugar en el que unos agentes lo mataron en Minneapolis. Foto: Jack Brook (AP) Así están las cosas en la nueva normalidad de la Minneapolis ocupada, que resiste desde hace dos meses a la Operación Metro Surge, ordenada por el Gobierno federal para acelerar las deportaciones en Minnesota, un Estado demócrata. El hecho de que el porcentaje de indocumentados sea menor que en muchas otras partes del país no impidió que Trump advirtiera el 13 de enero a sus habitantes que les había llegado “EL DÍA DEL AJUSTE DE CUENTAS Y LA VENGANZA”. No estuvo claro entonces a qué se refería exactamente, pero esta semana no quedaron dudas de que la resistencia de ese “gran pueblo” está arruinando los planes de la Casa Blanca. “La mayor deportación de la historia” Minneapolis es la séptima parada, tras Los Ángeles, Washington, Chicago, Portland, Memphis y Nueva Orleans, de la autoritaria huida hacia delante de Trump, ansioso por firmar la “mayor deportación de la historia” de Estados Unidos y por tachar nombres de su lista de enemigos. En todas esas ciudades, los agentes federales y la Guardia Nacional se encontraron con baches, pero lo de Minnesota se parece más a un muro infranqueable, especialmente desde que los agentes del ICE (Servicio de Inmigración y Control de Aduanas) y la Patrulla Fronteriza mataron a balazos a dos estadounidenses indefensos: el enfermero de cuidados intensivos de un hospital de veteranos Alex Pretti y la poeta Renée Good. Lejos de amedrentar a los manifestantes, esas muertes, grabadas con los móviles de ciudadanos como Kayla Schultz —que asistió a la de Pretti y no le tembló el pulso— han atizado el activismo de miles de vecinos: desde los veteranos activistas hasta los que, como contó Joey Keillor a EL PAÍS, nunca habían protestado antes. Protesta frente a los agentes federales de Minneapolis, el pasado 24 de febrero. Associated Press/LaPresse (APN) “Se han topado con la gente más dura del país”, advierte Jaylani Hussein, líder de esa comunidad somalí que Trump ha empleado como pretexto para la ocupación al hacerla responsable en conjunto de un fraude masivo en las ayudas públicas. “Sobrevivimos a los peores inviernos, y lo hacemos sabiendo que podemos confiar en nuestros vecinos. Hemos creado el manual de resistencia para las ciudades que nos sigan en la lista”. Ese manual está basado en la solidaridad, y no se entiende sin el precedente de las protestas por el asesinato del afroamericano George Floyd a manos de un policía blanco, ni sin los vínculos e infraestructuras forjados entonces en las Twin Cities. Aunque esta vez sea distinta. “Lo de ahora carece de precedentes”, confirma Jim Winterer, periodista jubilado. Ha vivido toda su vida en Minnesota y fue de los pocos que levantó la mano cuando en una manifestación esta semana el orador preguntó si había alguien entre el público que hubiera participado en las protestas contra la guerra de Vietnam. La columnista Lydia Polgreen, que ha cubierto conflictos por todo el mundo, escribió en The New York Times que lo visto sobre el terreno en Minnesota, Estado que no votó republicano ni cuando arrasó Ronald Reagan en 1980, le recordaba al inicio de una guerra civil. Aquí prefieren el paralelismo con la revolución contra los ingleses que hace 250 años trajo la independencia de Estados Unidos. “Esta vez el rey se llama Trump”, aclaró Ken Brown, mientras se manifestaba con un cartel diseñado por él mismo que acusaba a los agentes del ICE de ser “los orcos” del presidente. 01:41 La secuencia del tiroteo del ICE a un hombre en Minneapolis, desde diferentes ángulos Detención por parte de los agentes del ICE de un hombre en Minneapolis el pasado 24 de enero. Foto: Associated Press/LaPresse (APN) Brown recordó, como decenas de otros entrevistados estos días, el momento en el que sintió la “necesidad de hacer algo”. En su caso fue pronto, cuando empezó a ver agentes enmascarados patrullando su ciudad. Pero pudo haber sido al asistir a los brutales arrestos de los que levantan acta los observadores de Signal o a las muertes en directo de Pretti y Good, dos estadounidenses blancos, como la inmensa mayoría de los que protestan. Puente sobre la autopista Ese “algo” puede ser, simplemente, aguantar durante horas el frío sujetando carteles que piden la expulsión o la abolición de ICE en los puentes sobre las autopistas, para que los conductores toquen sus bocinas al pasar. Los inquilinos de un edificio en el cruce de la calle 28 y la avenida Thomas salen desde hace semanas cada miércoles por la tarde a soplar con fuerza sus silbatos. Hay vecinos que donan o reparten comida a las familias necesitadas, o a las que no se atreven a salir a la calle por miedo a ser arrestadas y deportadas. Otros regalan dónuts, gafas y máscaras antigás, barras para los labios cortados por el frío y calentadores para las manos o los pies en una ciudad que esta semana ha alcanzado los 25 grados bajo cero. A veces, basta con consumir: Miguel Zagal, de la Taquería La Hacienda contó el miércoles pasado que el negocio de sus padres estuvo tres semanas cerrado por miedo, y que, cuando volvieron a abrir, el barrio se volcó tanto en echarles una mano que cada día se quedaban sin comida antes del cierre. En otras ocasiones, funciona no gastar: muchos en la ciudad se han sumado a un boicot a los grandes almacenes Target, una de las 15 empresas del Fortune 500 con sede en Minneapolis. ¿El motivo? La prisa con la que sus gestores se plegaron a las exigencias de la Casa Blanca y eliminaron los programas de diversidad, igualdad e inclusión adoptados por un cálculo empresarial tras la muerte de Floyd. La nativa americana Sarah Charging, miembro de las Tres Tribus Afiliadas de Dakota del Norte, empezó a protestar tras la muerte de Good, a la que un agente del ICE llamado Jonathan Ross, que aún no ha sido acusado de nada, disparó tres tiros a bocajarro. Desde entonces, Charging se planta “cuatro o cinco veces” por semana, “antes o después del trabajo” ante el edificio federal Obispo Whipple, la mole brutalista a la que llevan a los detenidos. Tanto a los inmigrantes indocumentados, a los que envían a otros Estados para entorpecer su defensa, como a los estadounidenses que detienen en las protestas o a los refugiados arrestados por error a los que luego no les pagan los billetes de vuelta desde lugares como Florida o Texas. Al lado de un cartel que da bienvenida al complejo, en el que alguien ha tachado la palabra “empleados” y ha escrito “cerdos”, un coche que dice “Haven” (refugio) hace guardia 24 horas al día para asistir a los que sueltan sin cargos, muchas veces, de madrugada. “Les confiscan los teléfonos móviles y les quitan los abrigos”, advierte Cathy Anderson, una de las voluntarias. Agentes federales arrestan a un manifestante a las puertas del edificio federal Whipple. Adam Gray (AP) En el Whipple no es raro que huela a gas lacrimógeno y hay gente a todas horas que, con o sin megáfono, gritan e insultan a los uniformados que custodian la entrada o a los 4X4 con cristales tintados que ingresan en el recinto, en torno al que han levantado una valla para contener a los manifestantes. A veces, los agentes cargan o lanzan botes de humo. A eso de las 10.00 del viernes, uno de ellos se fue para los que en ese momento estaban allí concentrados, y arrastró a un hombre por el suelo y lo detuvo sin aparente motivo. Disfraz de rana Estos días, en el Whipple había muchas banderas estadounidenses del revés, vieja señal marinera para advertir del peligro que aquí sirve de espejo de un país en crisis, y una mujer disfrazada de rana, que definió su estrategia de protesta como un acto de “frivolidad táctica”. Mike Camilleri, profesor de Denver (Colorado) y padre de tres hijos, contó que había conducido 13 horas para “tomar nota” y así poder contar a sus vecinos cómo se defendió “el pueblo libre de Minnesota”. Una jubilada llamada Lesley Ernst llevaba un silbato colgado del cuello y un cartel que decía “Jesús te ama”. “Supongo que soy uno de esos agitadores violentos de los que habla Trump”, dijo con ironía. El presidente de Estados Unidos suele añadir, sin pruebas, que todo esto está financiado por agentes “desestabilizadores” como el magnate progresista George Soros. Aunque la aportación de Julie Prokes parezca mucho más modesta. Funcionario estatal, esta semana se la cogió libre para montar una mesa en el parking del Whipple, que ofrece gratis a los manifestantes desde barritas energéticas hasta café caliente o los silbatos que, dijo, fabrica en una impresora en 3-D en su casa, “a razón de 50 por día”. “Todo lo pago de mi bolsillo”, aclaró. También ofrece su coche, encendido a todas horas y con la calefacción puesta, por si alguien necesita entrar en calor. Además de en ese improvisado puesto, los silbatos los dan gratis en muchos puntos de Minneapolis: desde Birchbark Books, la librería de la premio Pulitzer Louise Erdrich, a la pastelería que hay frente al lugar en el que hace un par de sábados unos agentes de la patrulla fronteriza acribillaron por la espalda a Pretti. Por allí, como por el sitio en el que Good perdió la vida, centenares de personas pasan cada día para llorar en silencio, presentar sus respetos, compartir sus pensamientos en voz alta, dejar una vela encendida o un papel con algo escrito. En todos esos escenarios predominan los hombres y mujeres blancos. No solo porque representan el 77% del censo de Minnesota, un Estado en proceso de diversificación demográfica. También porque miles de personas, especialmente entre las familias hispanas y asiáticas, llevan semanas sin salir de sus casas por miedo a ser arrestadas. No son solo los indocumentados; también los ciudadanos y aquellos que residen legalmente en una ciudad en la que se ha vuelto una imprudencia ir por la vida sin el pasaporte encima. Una mujer se encara con un silbato a Greg Bovino, el 7 de enero en Minneapolis. Evelyn Hockstein (REUTERS) Ese ambiente de pesadilla disuade a muchos latinos de sumarse a las protestas, o de participar en los grupos que vigilan los movimientos del ICE. Rogelio Aguilar —que asistió a la manifestación multitudinaria que tomó el viernes esas calles de Minneapolis del himno improvisado Bruce Springsteen poco después de que este actuara por sorpresa en una sala de la ciudad—, se cuenta entre los que sí se atreven. Llevaba una bandera y un poncho mexicanos, y contó que estos días se da largos paseos por la ciudad de esa desafiante guisa, porque, agregó, “los chicanos son siempre los que dan un paso al frente”. Aguilar, que se ha vuelto conocido en estas calles, dice que lo hace por la gente que no pueden protestar. Gente como Clara y Manuel, por ejemplo, que accedieron a hablar con EL PAÍS en el modesto apartamento del sur de Minneapolis en el que llevan recluidos dos meses. No tienen papeles; por eso Clara y Manuel son nombres ficticios. Apenas trabajan, así que viven de la solidaridad de los vecinos, que, cuentan, son “puros güeros”. “Descubrir que estaban ahí para nosotros ha sido la parte positiva de todo esto”, explica ella, que a veces pierde la esperanza de que algún día “vuelva lo de antes”, y puedan sacudirse “el miedo”. Su hijo mayor, que es estadounidense, va a la compra y lleva a los pequeños al colegio, donde estos escuchan historias sobre lo que está pasando que obligan a sus padres a tener conversaciones que nunca creyeron que llegarían a tan temprana edad. En la ciudad, sigue muy fresco el recuerdo de Liam Conejo Ramos, el niño de cinco años al que el ICE usó de anzuelo para tratar de arrestar a su madre. Cuando lo detuvieron, llevaba un gorro que le venía grande y una mochila de Spiderman que le han quitado en el centro de detención de Texas en el que aguardaba a ser deportado junto a su padre, antes de que este sábado un juez federal ordenara la liberación de ambos. La imagen se convirtió en un símbolo de la brutalidad del operativo de Trump. Pero no ha logrado que esta remita: otros dos niños de su colegio han sido arrestados esta semana. Una vecina de Clara y Manuel, hispana también, explicó que, aunque ella sí cuenta con papeles, le da miedo “hasta ir a la esquina a sacar la basura”, y que cuando le toca médico se mete en una app para pedir un “raiter”, un conductor voluntario. “Si el que está al volante es blanco”, dice, “entonces vas más segura”. El presidente de Estados Unidos relevó el lunes al frente del operativo a Greg Bovino, con su aspecto de paramilitar de saldo, para poner al llamado zar de la frontera Tom Homan, y ha hablado de “desescalada” para hacer frente a una crisis de imagen por la muerte de dos ciudadanos estadounidenses y las evidencias que desmienten que su policía migratoria solo va a por “lo peor de lo peor”. The New York Times informó de que el jefe en funciones del ICE, Todd Lyons, al que un juez amonestó dos días antes por entorpecer la justicia, envió el miércoles un documento a sus agentes. En él, les autoriza a hacer registros en viviendas sin orden judicial, pese a que la ley lo prohíbe. También se han intensificado las detenciones de ciudadanos estadounidenses. Un grupo de ellos, a los que ya se les conoce como los “16 de Minnesota”, adquirió notoriedad a su pesar cuando la fiscal general, Pam Bondi, publicó en X sus fotos y su información personal, sin importarle la presunción de inocencia o el hecho de que les estaba poniendo una diana digital en la espalda. Nekima Levy Armstrong, el pasado 19 de enero en St. Paul (Minnesota). Angelina Katsanis (AP) El viernes, dos periodistas fueron arrestados. El día anterior, Nekima Levy Armstrong rememoró a EL PAÍS su propio calvario. Armstrong fue detenida por participar en una protesta en una iglesia de St. Paul, a cuyo pastor se vincula con el ICE. La Casa Blanca difundió después una foto de ella, manipulada con inteligencia artificial. “Me sacaron llorando, histérica, cuando en ningún momento derramé una lágrima”, recordó Armstrong, abogada de profesión, cuyo caso dio la vuelta al mundo como otro ejemplo de la falta de escrúpulos de la Administración de Trump. “Además, exageraron mis rasgos y oscurecieron mi piel. Eso solo tiene un nombre: racismo”. La activista denuncia que le colocaron grilletes, “como si fuera una asesina”, que aún no le han devuelto el teléfono y que los agentes se tomaron fotos con ella y con las otras dos personas detenidas por esos mismos hechos como quien posa con un trofeo. “Pueden hacer todo eso, pero no van a callarnos. No lograrán intimidarnos. Seguiremos enfrentándonos a sus armas con nuestros silbatos”. La advertencia, que seguramente suscribirían muchos aquí, la soltó Armstrong a mitad de la conversación. Interrumpida por el zumbido constante del teléfono móvil, esta acabó con el mismo ruego al forastero que todas las demás en la nueva normalidad de Minneapolis: “Ve con cuidado y mantente a salvo”.
Ejercicio Predicción - California House Prizing¶
El California Housing Dataset es uno de los más conocidos en la literatura. Este dataset es un conjunto de datos de regresión que recoge información socioeconómica y geográfica de distritos de California a partir del censo de 1990, con el objetivo de predecir el precio medio de la vivienda. Contiene unas 20.000 observaciones y 8 variables numéricas como el ingreso medio, la edad de las viviendas, la población y la localización.
Para más información: https://scikit-learn.org/stable/datasets/real_world.html#california-housing-dataset
import pandas as pd
from sklearn.datasets import fetch_california_housing
data = fetch_california_housing(as_frame=True).frame
data
| MedInc | HouseAge | AveRooms | AveBedrms | Population | AveOccup | Latitude | Longitude | MedHouseVal | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 8.3252 | 41.0 | 6.984127 | 1.023810 | 322.0 | 2.555556 | 37.88 | -122.23 | 4.526 |
| 1 | 8.3014 | 21.0 | 6.238137 | 0.971880 | 2401.0 | 2.109842 | 37.86 | -122.22 | 3.585 |
| 2 | 7.2574 | 52.0 | 8.288136 | 1.073446 | 496.0 | 2.802260 | 37.85 | -122.24 | 3.521 |
| 3 | 5.6431 | 52.0 | 5.817352 | 1.073059 | 558.0 | 2.547945 | 37.85 | -122.25 | 3.413 |
| 4 | 3.8462 | 52.0 | 6.281853 | 1.081081 | 565.0 | 2.181467 | 37.85 | -122.25 | 3.422 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 20635 | 1.5603 | 25.0 | 5.045455 | 1.133333 | 845.0 | 2.560606 | 39.48 | -121.09 | 0.781 |
| 20636 | 2.5568 | 18.0 | 6.114035 | 1.315789 | 356.0 | 3.122807 | 39.49 | -121.21 | 0.771 |
| 20637 | 1.7000 | 17.0 | 5.205543 | 1.120092 | 1007.0 | 2.325635 | 39.43 | -121.22 | 0.923 |
| 20638 | 1.8672 | 18.0 | 5.329513 | 1.171920 | 741.0 | 2.123209 | 39.43 | -121.32 | 0.847 |
| 20639 | 2.3886 | 16.0 | 5.254717 | 1.162264 | 1387.0 | 2.616981 | 39.37 | -121.24 | 0.894 |
20640 rows × 9 columns