Nothing Special   »   [go: up one dir, main page]

01 Introduccion - Python - paraML - Ipynb - Colaboratory

Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 17

20/6/23, 15:03 Introduccion_Python_paraML.

ipynb - Colaboratory

Fundamentos de Python para el aprendizaje automático


Este cuaderno cubrira los siguientes temas:

Introduccion
Visualizacion de datos
Algebra lineal
Feature engineering
Machine Learning

Introducción a Temas Clave en Machine Learning


Machine Learning es una disciplina que se encuentra en el corazón de numerosas aplicaciones modernas, desde sistemas de recomendación
hasta coches autónomos. Python es uno de los lenguajes más utilizados en este campo, debido a su sencillez y la abundancia de bibliotecas
especializadas.

A lo largo de nuestro estudio, exploraremos los siguientes temas clave:

Visualización de Datos
La visualización de datos es esencial para entender nuestros datasets. Nos permite detectar patrones, identificar anomalías y validar modelos.
Con bibliotecas como Matplotlib y Seaborn, podemos crear gráficos y visualizaciones detalladas y personalizables.

Álgebra Lineal
El Álgebra Lineal es la base de muchas técnicas y algoritmos de Machine Learning. Conceptos como vectores, matrices y operaciones entre
ellos son fundamentales para entender y aplicar estos algoritmos. La biblioteca Numpy nos proporciona las herramientas para trabajar con
estos conceptos en Python.

Feature Engineering
Feature Engineering es el proceso de transformar los datos brutos en características que mejor representen el problema a los algoritmos de
Machine Learning, mejorando así su rendimiento. Pandas es una biblioteca muy útil para esta tarea, permitiéndonos manipular datos
fácilmente.

Machine Learning
El Machine Learning nos permite aprender de los datos y hacer predicciones o decisiones sin ser explícitamente programados para hacerlo. Es
una parte fundamental de muchas aplicaciones modernas. Sklearn es una de las bibliotecas más populares para Machine Learning en Python,
proporcionando una gran variedad de algoritmos y herramientas.

A lo largo de este curso, utilizaremos los siguientes módulos de Python:

Numpy: para manipulación de matrices y operaciones de álgebra lineal.


Pandas: para manipulación de datos y feature engineering.
Matplotlib y Seaborn: para la visualización de datos.
Scipy: para tareas científicas y técnicas.
Sklearn: para aplicar técnicas y algoritmos de Machine Learning.

Aunque cada uno de estos temas puede ser una disciplina en sí misma, juntos forman las habilidades fundamentales que necesita un
practicante de Machine Learning. Al dominar estos temas, estarás bien preparado para adentrarte en el emocionante campo del Machine
Learning.

Visualización de datos
Importancia de la Visualización de Datos en Machine Learning
La visualización de datos es un componente fundamental en el campo del Machine Learning. Permite entender mejor los datos con los que
estamos trabajando, detectar patrones, identificar anomalías y validar nuestras hipótesis. La visualización es una herramienta poderosa para la
exploración y análisis de datos, así como para la presentación de los resultados de nuestras predicciones y modelos de Machine Learning.

¿Por qué utilizar Matplotlib, Pandas, Seaborn y Numpy?


Python es uno de los lenguajes de programación más utilizados en el campo del Machine Learning, en gran parte debido a su ecosistema de
bibliotecas y módulos robustos y versátiles. Entre ellos, Matplotlib, Pandas, Seaborn y Numpy destacan por su utilidad en el manejo, análisis y
visualización de datos.

https://colab.research.google.com/drive/1NN0ujvf1zIJNqtey4Ve6DyMwslbfb8Ak?usp=sharing#scrollTo=97902dbd&printMode=true 1/17
20/6/23, 15:03 Introduccion_Python_paraML.ipynb - Colaboratory

Numpy: Es la biblioteca fundamental para la computación científica con Python. Proporciona un objeto de matriz multidimensional y
herramientas para trabajar con estas matrices.

Pandas: Es una biblioteca que proporciona estructuras de datos y funciones de alto nivel para facilitar la manipulación y análisis de
datos. Pandas se integra bien con otras bibliotecas de Python como Numpy y Matplotlib.

Matplotlib: Es la biblioteca de trazado más utilizada en Python. Permite crear una gran variedad de gráficos y visualizaciones con control
completo sobre los estilos y propiedades de los gráficos.

Seaborn: Basado en Matplotlib, Seaborn proporciona una interfaz de alto nivel para crear gráficos estadísticos atractivos. Seaborn trabaja
bien con los DataFrames de Pandas, lo que facilita la visualización de datos.

Estas bibliotecas juntas forman una poderosa caja de herramientas para cualquier científico de datos o profesional de Machine Learning.

!pip install pandas

Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/


Requirement already satisfied: pandas in /usr/local/lib/python3.10/dist-packages (1.5.3)
Requirement already satisfied: python-dateutil>=2.8.1 in /usr/local/lib/python3.10/dist-packages (from pandas) (2.8.2)
Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.10/dist-packages (from pandas) (2022.7.1)
Requirement already satisfied: numpy>=1.21.0 in /usr/local/lib/python3.10/dist-packages (from pandas) (1.22.4)
Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.10/dist-packages (from python-dateutil>=2.8.1->pandas) (1.16.0)

# importamos los modulos que vamos a necesitar


import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
import numpy as np

plt.rcParams['figure.figsize'] = [10, 8] # Opcional: seteamos el tamaño de las imagenes


# para visualizar los gráficos dentro de la notebook
%matplotlib inline

Aleatoriedad
Cuando lidiamos con data, siempre es importante tener a manos maneras de generar numeros aleatorios, ya sea para elegir muestras y no
generar sesgos, o por otra razón. En python, tenemos modulos específicos para hacer eso, pero también dentro de numpy tenemos el
submodulo random.

# Simular el lanzamiento de un dado


die_faces = [1,2,3,4,5,6]

# Creemos un generador aleatorio. El valor `seed`


# es un número utilizado para inicializar un generador de
# números pseudoaleatorios. Nos permitirá obtener resultados
# reproducibles si queremos ejecutar el experimento de nuevo.
rng = np.random.RandomState(seed=23)

# Elegimos al azar uno de los lados del dado ...


choice = rng.choice(die_faces, size=1)
choice

array([4])

seaborn y pyplot
Podemos pasar todo el dia viendo las distintas cosas que se pueden hacer con seaborn y pyplot, pero usemos el poder de google, y por que no,
de chatGPT (u otros LLMs). Como guia genera, aqui estan algunas de las funcionalidades básicas de seaborn: seaborn

# Distribucion de probabilidad teorica para un dado


sns.histplot([1,2,3,4,5,6], bins=list(range(1,8)), stat='probability').set_title(f'Probability Distribution')
plt.show()

https://colab.research.google.com/drive/1NN0ujvf1zIJNqtey4Ve6DyMwslbfb8Ak?usp=sharing#scrollTo=97902dbd&printMode=true 2/17
20/6/23, 15:03 Introduccion_Python_paraML.ipynb - Colaboratory

# Generamos una distribucion de 100 muestras


rng = np.random.RandomState(seed=23)
num_samples = 100
x = rng.choice([1,2,3,4,5,6], num_samples)
print(f"Generamos un objeto de tipo {type(x)}")
print("Cuyos valores son los siguientes:")
print(x)

Generamos un objeto de tipo <class 'numpy.ndarray'>


Cuyos valores son los siguientes:
[4 1 2 1 6 5 4 3 2 4 4 6 5 2 3 4 6 6 1 5 6 1 2 3 2 4 2 4 5 2 2 5 4 4 5 3 2
3 3 5 6 4 1 1 6 5 1 6 1 3 5 1 4 1 3 3 6 4 2 5 4 3 3 4 6 6 5 4 1 6 1 5 5 4
2 2 5 3 6 2 6 1 2 3 1 6 4 3 6 3 5 6 1 3 6 4 2 1 4 3]

# Ahora les damos esos datos empiricos a sns.histoplot. Estamos reemplazando la lista "teorica": [1,2,3,4,5,6]
# con la lista generada
sns.histplot(x, bins=list(range(1,8)), stat='probability').set_title(f'Distribution from {num_samples} samples')
plt.show()

https://colab.research.google.com/drive/1NN0ujvf1zIJNqtey4Ve6DyMwslbfb8Ak?usp=sharing#scrollTo=97902dbd&printMode=true 3/17
20/6/23, 15:03 Introduccion_Python_paraML.ipynb - Colaboratory

Pueden probar generando varias veces, y jueguen con el numero de parametros. Mientras menos tenemos, mas azarozo sera.

# 100000 muestras
rng = np.random.RandomState(seed=1)
num_samples = 100000
x = rng.choice([1,2,3,4,5,6], num_samples)
sns.histplot(x, bins=list(range(1,8)), stat='probability').set_title(f'Distribution from {num_samples} samples')
plt.show()

Aqui el histograma se parece mas al contenido "teorico"

Un ejemplo con datos reales


Pandas
El objeto escencial que van a usar en pandas es el "dataframe". Esto lo vamos a utilizar para visualizar y explorar datos. Pueden pensar en un
dataframe como una tabla, compuesta por columnas, que son "series", que es el segundo objeto mas utilizado en pandas. En el caso que van a
ver, "Home", "Price", "SqFt", "Bedrooms", "Bathrooms", "Offers", "Brick, y "Neighborhood" son las series. Cada serie tiene un "tipo" Python (es
decir, pueden ser numeros, o caracteres, u otra cosa, pero no una mezcla)

###

# Bajamos los datos de una pagina web, utiliando `read_csv` de pandas


hp = pd.read_csv('https://raw.githubusercontent.com/anyoneai/notebooks/main/datasets/house-prices.csv')
# Le echamos un vistazo con el metodo `head`
hp.head(20)

https://colab.research.google.com/drive/1NN0ujvf1zIJNqtey4Ve6DyMwslbfb8Ak?usp=sharing#scrollTo=97902dbd&printMode=true 4/17
20/6/23, 15:03 Introduccion_Python_paraML.ipynb - Colaboratory

Home Price SqFt Bedrooms Bathrooms Offers Brick Neighborhood

0 1 114300 1790 2 2 2 No East

1 2 114200 2030 4 2 3 No East

2 3 114800 1740 3 2 1 No East

3 4 94700 1980 3 2 3 No East

4 5 119800 2130 3 3 3 No East

5 6 114600 1780 3 2 2 No North

6 7 151600 1830 3 3 3 Yes West

7 8 150700 2160 4 2 2 No West

8 9 119200 2110 4 2 3 No East

9 10 104000 1730 3 3 3 No East

10 11 132500 2030 3 2 3 Yes East

11 12 123000 1870 2 2 2 Yes East

12 13 102600 1910 3 2 4 No North

13 14 126300 2150 3 3 5 Yes North

14 15 176800 2590 4 3 4 No West


hp['Neighborhood'].mode()
15 16 145800 1780 4 2 1 No West
0 East
Name:
16 Neighborhood, dtype: object
17 147100 2190 3 3 4 Yes East

17 18 83600 1990 3 3 4 No North


# que tamano tiene esto?
18 19 111400
print(f"Tenemos 1700 {len(hp)}2 casas") 2
datos sobre 1 Yes East
# Cual19
es el20precio promedio?
167200 1920 utilizamos
3 el metodo
3 mean 2de pandas.
Yes West
# Recuerden que siempre podemos buscar estos metodos en Goole
print(f"El precio promedio es {hp['Price'].mean()}")
# Cual es la moda?
mode = hp['Neighborhood'].mode()[0] # el metodo moda nos da una serie. Asi que accedemos a su primer elemento
print(f"La moda es {mode}")

Tenemos datos sobre 128 casas


El precio promedio es 130427.34375
La moda es East

hp['Neighborhood'].mode()[0]

'East'

# juguemos con los datos y seaborn


fig = sns.countplot(data=hp, x='Neighborhood', palette='Paired')
plt.show()
# Pueden encontrar mas colores en https://matplotlib.org/stable/tutorials/colors/colormaps.html

https://colab.research.google.com/drive/1NN0ujvf1zIJNqtey4Ve6DyMwslbfb8Ak?usp=sharing#scrollTo=97902dbd&printMode=true 5/17
20/6/23, 15:03 Introduccion_Python_paraML.ipynb - Colaboratory

hp.head()

Home Price SqFt Bedrooms Bathrooms Offers Brick Neighborhood

0 1 114300 1790 2 2 2 No East

1 2 114200 2030 4 2 3 No East

2 3 114800 1740 3 2 1 No East

3 4 94700 1980 3 2 3 No East

4 5 119800 2130 3 3 3 No East

# Hagamos un histogrma del precio

sns.displot(data=hp, x="SqFt", kind="hist").set(title='Precios de casas')


plt.show()

# Podemos hacer un boxplot, que nos da una idea del rango, de los cuartiles, la mediana, etc.
sns.boxplot(data=hp, y='Price')
plt.show()

https://colab.research.google.com/drive/1NN0ujvf1zIJNqtey4Ve6DyMwslbfb8Ak?usp=sharing#scrollTo=97902dbd&printMode=true 6/17
20/6/23, 15:03 Introduccion_Python_paraML.ipynb - Colaboratory

No quiero perder mas el tiempo, ni tentarme con mas ejemplos pero les urjo que jueguen con algunos de las siguientes funciones, que pueden
buscarlas en seaborn. Tambien tenemos ejemplos en algunos de los notebooks que subimos en otro lugar del curso:

scatterplot: representa los datos con puntos


violinplot: parecido a histograma, tambien al boxplot. Experimenten
displot: jueguen con el parametro fill=True, y kind="kde"
displot: de vuelta, jueguen con parametro hue= "pinta" el grafico segun algun otra columna. Es una forma de incorporar mas informacion
en una sola imagen

# Bueno, me tente, les muestro el hue


sns.displot(data=hp, x="Price", hue="Brick", kind='kde', fill=True)
plt.show()

Feature engineering

Introducción al Feature Engineering


La clave para hacer buenos modelos de machine learning son datos. Necesitamos que los datos sean, escencialmente, abundantes.

A diferencia de metodos estadisticos que pueden funcionar con relativamente pocos datos el ML es muy hambrientos de datos.

Pero, una vez obtenidos los datos, es suficiente? Por lo general, no. Los datos en el mundo real suelen tener diversas fuentes, estar "sucios", no
ser adecuados.

Es comun, por ejemplo, que tengamos datos en distintos formatos (string, en vez de int, datos incompletos, etc).

Consideremos los datos con los que venimos trabajando, por ejemplo. Que hubiera sucedido si alguien hubiera puesto un cero de mas en el
precio? Tendriamos un precio exorbitante que puede cambiar radicalmente nuestros resultados. Y si en vez de un cero de mas hubiera
introducido un signo menos? o una coma. Todas estas cosas y mas tenemos que tener en cuenta al hacer feature engineering.

El Feature Engineering puede incluir técnicas como la normalización, la discretización, la creación de características interactivas, la
codificación de variables categóricas, la imputación de valores perdidos y muchas otras. La elección de las técnicas a utilizar depende en gran
medida de la naturaleza de los datos y del problema a resolver.

https://colab.research.google.com/drive/1NN0ujvf1zIJNqtey4Ve6DyMwslbfb8Ak?usp=sharing#scrollTo=97902dbd&printMode=true 7/17
20/6/23, 15:03 Introduccion_Python_paraML.ipynb - Colaboratory

En el curso siguiente veran mas en profundidad tecnicas para visualizar y preprocesar datos, pero introduzcamos algunos conceptos basicos, y
modulos de python.

¿Por qué elegir scikit-learn (sklearn) para el preprocesamiento de datos?


Scikit-learn (o sklearn) es una de las bibliotecas más populares y completas para el Machine Learning en Python. Ofrece una amplia gama de
algoritmos de aprendizaje supervisado y no supervisado, así como herramientas para el preprocesamiento de datos, la selección de modelos y
la evaluación.

Sklearn facilita el proceso de preprocesamiento de datos y el Feature Engineering gracias a su consistencia en la interfaz y a su eficiencia. Los
métodos de sklearn están diseñados para integrarse de manera eficiente con otras bibliotecas de Python como NumPy y Pandas, lo que facilita
la manipulación de datos.

Entre los submódulos de sklearn que pueden ser útiles para el preprocesamiento de datos y el Feature Engineering, se incluyen:

sklearn.preprocessing: Este módulo incluye métodos para la estandarización, normalización, codificación de variables categóricas, etc.
sklearn.impute: Este módulo proporciona métodos para la imputación de valores perdidos.
sklearn.feature_extraction: Este módulo puede ser útil para convertir datos textuales o categóricos en representaciones numéricas que
pueden ser usadas por los algoritmos de Machine Learning.
sklearn.decomposition: Este módulo incluye métodos para la reducción de dimensionalidad, como PCA.

En resumen, el Feature Engineering es esencial para obtener el máximo rendimiento de nuestros modelos de Machine Learning, y sklearn es
una herramienta excelente que nos ayuda a realizar esta tarea de manera eficiente y efectiva.

# La base de datos con la que habiamos estado trabajando ya tenia datos preprocesados.
# Intentemos con una algo mas imperfecta
movies = pd.read_csv('https://raw.githubusercontent.com/anyoneai/notebooks/main/datasets/imdb_dataset.csv')
print(f"La longitud de esta base de datos es de {len(movies)}")
movies.head()

La longitud de esta base de datos es de 979


star_rating title content_rating genre duration actors_list

The [u'Tim Robbins',


0 9.3 Shawshank R Crime NaN u'Morgan Freeman',
Redemption u'Bob Gunt...

[u'Marlon Brando',
1 NaN The Godfather R Crime 175.0 u'Al Pacino', u'James
Caan']

[u'Al Pacino',
The Godfather:
2 91 R NaN 200 0 u'Robert De Niro'

Valores faltantes
Inicialmente, ya vemos un valor Nan, en la linea 3, en la columna duration. Esto indica que no hay un valor alli. Hay diferentes formas de tratar
los valores Nan.

# isna, de pandas, nos da una lista de verdaderos y falsos para cada lugar. Falso significa:
# "aqui hay un valor" verdadero indica "aqui hay un Nan", o "aqui no hay ningun valor"
movies.isna()

star_rating title content_rating genre duration actors_list

0 False False False False True False

1 True False False False False False

2 False False False True False False

3 False False False False True False

4 False False False False False False

... ... ... ... ... ... ...

974 False False False False False False

975 False False False False False False

976 False False False False False False

977 False False False False False False

978 False False False False False False

979 rows × 6 columns

# Esto es demasiado para leer, con el metodo sum, vemos cuantos nan hay en cada columna.
movies.isna().sum()

https://colab.research.google.com/drive/1NN0ujvf1zIJNqtey4Ve6DyMwslbfb8Ak?usp=sharing#scrollTo=97902dbd&printMode=true 8/17
20/6/23, 15:03 Introduccion_Python_paraML.ipynb - Colaboratory

star_rating 1
title 0
content_rating 1
genre 1
duration 19
actors_list 0
dtype: int64

# Podemos utilizar un metodo comun, aunque poco sofisticado de tratar a los valores nan:
# reemplazarlos con el valor de la media para esa columna
numericas = movies.select_dtypes(include=['int','float']).columns
print(numericas)
# obtenemos las medias de las numericas

Index(['star_rating', 'duration'], dtype='object')

movies[numericas]

star_rating duration

0 9.3 NaN

1 NaN 175.0

2 9.1 200.0

3 9.0 NaN

4 8.9 154.0

... ... ...

974 7.4 116.0

975 7.4 118.0

976 7.4 138.0

977 7.4 114.0

978 7.4 126.0

979 rows × 2 columns

medias = movies[numericas].mean()
medias

star_rating 7.888446
duration 120.844792
dtype: float64

# usamos el metodo fillna para rellenar los datos faltantes


movies[numericas] = movies[numericas].fillna(medias)
movies.isna().sum()

star_rating 0
title 0
content_rating 1
genre 1
duration 0
actors_list 0
dtype: int64

Normalizacion de datos
En el contexto del aprendizaje automático, la transformación de datos implica modificar la información para que sea más adecuada y útil para
los modelos de machine learning. Por ejemplo:

tengan escala similar


convertir variables categoricas a numericas
extraer caracteristicas relevantes de los datos
extraer outliers

Estas transformaciones nos permiten entrenar modelos más efectivos y tomar decisiones inteligentes basadas en los datos.

Llevar datos a una escala similar


Algunos algoritmos de machine learning son sensibles a la escala de las variables. Cuando las características varían en escalas, los algoritmos
pueden dar mayor importancia a las características con una escala más grande.

MinMaxScaler

https://colab.research.google.com/drive/1NN0ujvf1zIJNqtey4Ve6DyMwslbfb8Ak?usp=sharing#scrollTo=97902dbd&printMode=true 9/17
20/6/23, 15:03 Introduccion_Python_paraML.ipynb - Colaboratory

Una técnica popular de normalización es MinMax Scaler. Esta técnica lleva todas las características a una escala entre 0 y 1 , donde el valor
minimo es igual a 0 y el valor maximo es igual a 1. Esta es la formula:

X_std = (X - X.min(axis=0)) / (X.max(axis=0) - X.min(axis=0))


X_scaled = X_std * (max - min) + min

# veamos rapidamente la disparidad entre features


from sklearn.preprocessing import MinMaxScaler, StandardScaler
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

with plt.style.context('dark_background'):
sns.boxplot(data= movies, palette='viridis')
plt.title("Variables sin estandarizar")
plt.xlabel("Categorias")
plt.ylabel("Valores")
plt.show()

Oh no! 😟

# En sklearn casi siempre vamos a actuar instanciando objetos primero.


# Todos los objetos vienen con un metodo fit, un metodo transform y un metodo fit_transform que combina ambos
# En este caso, fit calcula los valores minimos y maximos del rango, y transform transforma los datos
# en valores que van de 0 a 1

mm_scaler = MinMaxScaler(feature_range=(0, 1), clip=False)


# utilizamos el metodo reshape porque el transformador espera un array de 2 dimensiones. Pueden leer mas sobre el metodo
# reshape en los notebooks compartidos o en [https://www.w3schools.com/python/numpy/numpy_array_reshape.asp]

min_max_star = mm_scaler.fit_transform(movies['star_rating'].values.reshape(-1, 1))


min_max_duration = mm_scaler.fit_transform(movies['duration'].values.reshape(-1,1))
movies['star_rating'] = min_max_star
movies['duration'] = min_max_duration

with plt.style.context('dark_background'):
sns.boxplot(data= movies, palette='magma')
plt.title("Variables estandarizadas")

https://colab.research.google.com/drive/1NN0ujvf1zIJNqtey4Ve6DyMwslbfb8Ak?usp=sharing#scrollTo=97902dbd&printMode=true 10/17
20/6/23, 15:03 Introduccion_Python_paraML.ipynb - Colaboratory
plt.xlabel("Categorias")
plt.ylabel("Valores")
plt.show()

Mejor!!!!! 😄

ML (Finalmente)

Aprendizaje Automático con Scikit-Learn: Prediciendo Precios de Casas


Ahora volvemos al conjunto de datos de precios de casas (que tiene los datos ya preprocesados) y usaremos estos datos para predecir el
precio de una casa basándonos en su superficie.

Conjunto de Datos
El conjunto de datos que utilizaremos se puede encontrar en la siguiente URL:

'https://raw.githubusercontent.com/anyoneai/notebooks/main/datasets/house-prices.csv'

Este conjunto de datos contiene información sobre varias casas, incluyendo su metraje cuadrado y precio. Usaremos estos datos para entrenar
nuestros modelos de aprendizaje automático.

Modelos de Aprendizaje Automático


Crearemos dos modelos para esta tarea:

1. Modelo de Regresión Lineal: Este es un modelo simple pero poderoso que asume una relación lineal entre las variables de entrada
(metraje cuadrado) y la única variable de salida (precio).

2. Regresor Ingenuo: Este modelo siempre predecirá el precio mediano de nuestro conjunto de datos de entrenamiento. Es un modelo
simple que usaremos como base para comparar con nuestro modelo de Regresión Lineal.

Clases en Python

https://colab.research.google.com/drive/1NN0ujvf1zIJNqtey4Ve6DyMwslbfb8Ak?usp=sharing#scrollTo=97902dbd&printMode=true 11/17
20/6/23, 15:03 Introduccion_Python_paraML.ipynb - Colaboratory

Como parte de este tutorial, crearemos una clase en Python. Si eres nuevo en las clases en Python, ¡no te preocupes! Revisaremos un poco de
teoría y te guiaremos a través del proceso. Esencialmente, una clase es un plano para crear objetos en Python. Nos permite encapsular datos y
funciones relacionadas en una sola entidad.

Visualización de Datos
Para ayudarnos a entender nuestros datos y el rendimiento de nuestros modelos, utilizaremos Seaborn, una poderosa biblioteca de
visualización de datos en Python. Crearemos gráficos que nos ayudarán a visualizar la distribución de los precios de las casas, la relación entre
el metraje cuadrado y el precio, y el rendimiento de nuestros modelos de aprendizaje automático.

¡Empecemos!

from sklearn.linear_model import LinearRegression


from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import make_pipeline
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

# %matplotlib notebook
%matplotlib inline

plt.rcParams['figure.figsize'] = [8, 6]

hp

Home Price SqFt Bedrooms Bathrooms Offers Brick Neighborhood

0 1 114300 1790 2 2 2 No East

1 2 114200 2030 4 2 3 No East

2 3 114800 1740 3 2 1 No East

3 4 94700 1980 3 2 3 No East

4 5 119800 2130 3 3 3 No East

... ... ... ... ... ... ... ... ...

123 124 119700 1900 3 3 3 Yes East

124 125 147900 2160 4 3 3 Yes East

125 126 113500 2070 2 2 2 No North

126 127 149900 2020 3 3 1 No West

127 128 124600 2250 3 3 4 No North

128 rows × 8 columns

# La funcion scatterplot suele ser muy util para la visualizacion de datos


sns.scatterplot(x='SqFt', y='Price', data=hp).set_title('Price vs Square Feet')
plt.show()

https://colab.research.google.com/drive/1NN0ujvf1zIJNqtey4Ve6DyMwslbfb8Ak?usp=sharing#scrollTo=97902dbd&printMode=true 12/17
20/6/23, 15:03 Introduccion_Python_paraML.ipynb - Colaboratory

Introducción a las Clases en Python


En Python, una clase es una estructura de código que permite la creación de objetos. Estos objetos pueden tener propiedades (también
conocidas como atributos) y comportamientos (conocidos como métodos).

¿Qué es una Clase?

Una clase es como un plano para crear un objeto. Por ejemplo, podríamos tener una clase Casa que define las propiedades que todas las
casas tienen en común, como el número de habitaciones, el color, el tamaño, etc. También podría definir comportamientos comunes, como
abrir y cerrar puertas o ventanas.

¿Qué es un Objeto?
Un objeto es una instancia de una clase. Siguiendo con el ejemplo anterior, si Casa es una clase, entonces cada casa que construyamos a
partir de esa clase es un objeto. Cada objeto Casa tendría sus propias propiedades únicas, como el número de habitaciones, el color, el
tamaño, etc.

¿Cómo se define una Clase en Python?


En Python, una clase se define usando la palabra clave class , seguida del nombre de la clase y dos puntos. Dentro de la clase, podemos definir
los atributos y métodos de la clase.

Aquí tienes un ejemplo de cómo se podría definir una clase Casa :

class Casa:
def __init__(self, habitaciones, color, dimensiones):
# Con init, inicio automaticamente ciertas 'atributos' de la clase
# self hace referencia a la instancia de la clase
self.habitaciones = habitaciones
self.color = color
self.dimensiones = dimensiones
self.puerta = "cerrada" #Noten que los 3 atributos anteriores se los pase como parametros, pero self.puerta
# lo pongo por default como "cerrada"
def status_puerta(self):
print(f"La puerta esta {self.puerta}")

# puedo definir metodos en la clase, como cerrar y abrir una puerta, segun su estado actual
def cerrar_abrir_puerta(self):
if self.puerta == "abierta":
self.puerta = "cerrada"
else:
self.puerta = "abierta"
self.status_puerta() # Un metodo dentro de una clase puede llamar a otros dentro de la clase

mi_casa = Casa(4, 'rojo', 'chiquita')


print(f"Mi casa es una casa {mi_casa.dimensiones} de color {mi_casa.color}, con {mi_casa.habitaciones} habitaciones")

Mi casa es una casa chiquita de color rojo, con 4 habitaciones

mi_casa.puerta

'cerrada'

# Para entrar, me fijo si la puerta esta abierta o cerrada


mi_casa.status_puerta()

# Si esta cerrada, la abro ...


mi_casa.cerrar_abrir_puerta()

# ... entro a casa


print("Cariño! Ya llegué! ...")

# ... y vuelvo a cerrarla ...


mi_casa.cerrar_abrir_puerta()

La puerta esta cerrada


La puerta esta abierta
Cariño! Ya llegué! ...
La puerta esta cerrada

https://colab.research.google.com/drive/1NN0ujvf1zIJNqtey4Ve6DyMwslbfb8Ak?usp=sharing#scrollTo=97902dbd&printMode=true 13/17
20/6/23, 15:03 Introduccion_Python_paraML.ipynb - Colaboratory

Finalmente, tengan en cuenta que podemos construir varias instancias de una misma clase, cada una de las cuales sera un objeto distinto

tu_casa = Casa(15, 'magenta', 'gigante')


print(type(mi_casa))
print(type(tu_casa))

<class '__main__.Casa'>
<class '__main__.Casa'>

mi_casa == tu_casa

False

su_casa = Casa(mi_casa.habitaciones,mi_casa.color, mi_casa.dimensiones)


mi_casa == su_casa

False

Bueno, volvamos a los nuestro. Vamos a crear nuestra primera clase en Python que posta hace algo con nuestros datos. Nuestra clase es un
predictor del valor de una casa, pero no uno muy bueno.

Si no tengo muchas ganas de laburar, puedo organizar todos los precios de las casas de menor a mayor y elegir el del medio, cualquier sean
los datos que me den.

De esta forma, si los datos estan normalmente distribuidos, no le voy a errar por mucho ...

Este valor, el medio, se llama mediana, pero eso quizas ya lo sabian. No confundir con media.

Podria simplemente llamar el metodo de pandas, df.median(), pero tengo ganas de probar las clases de Python.

A esta clase le puedo agregar varios metodos:

init: simplemente inicializa la clase con algunos atributos. Recuerdan los pesos?
funcion de fit: En este caso, solo me va a dar la mediana de los datos
funcion predict: Ahora puedo introducir un dato, y me va a dar la prediccion del precio.
funcion cost: Ahora queremos evaluar como nos fue con las predicciones. El costo es una forma de expresar el error de un monton de
predicciones con un solo valor. Hay diferentes calculos que se pueden hacer, pero resumiendo, a menor costo, mejor fueron nuestras
predicciones, y mejor funciona el modelo. Si quieren, pueden cambiar la forma de predecir el error, tomando por ejemplo el error
promedio.

class NaiveRegressor():
"""
Este modelo calcula la mediana y lo usa como el valor predicho
"""

def __init__(self):
self.w0 = 0
self.w1 = 0

def cost(self, X, y):


# Este metodo predice un costo
diff = (self.predict(X) - y)**2
diff_sum = sum(diff) / 2
return diff_sum

def fit(self, X, y):


self.w0 = np.median(y)

def predict(self, x):


return x * self.w1 + self.w0

# Creamos el modelo regresor


nv_regressor = NaiveRegressor()
# Calculamos el costo sin entrenar el modelo
costo_se = nv_regressor.cost(X=hp["SqFt"], y=hp["Price"])
print(f'el costo sin entrenar es {int(costo_se)}')

el costo sin entrenar es 1134565295000

# Predice 0 porque todavia no entrenamos el modelo


# Los pesos estan en 0 todavia
nv_regressor.predict(100)

https://colab.research.google.com/drive/1NN0ujvf1zIJNqtey4Ve6DyMwslbfb8Ak?usp=sharing#scrollTo=97902dbd&printMode=true 14/17
20/6/23, 15:03 Introduccion_Python_paraML.ipynb - Colaboratory
# Entrenamos el modelo
nv_regressor.fit(X=hp["SqFt"], y=hp["Price"])

costo_e = nv_regressor.cost(X=hp["SqFt"], y=hp["Price"])

print(f'El costo, entrenando es {int(costo_e)}')


print(f"Mejoramos nuestro costo en {int(costo_se - costo_e)}")

El costo, entrenando es 47125590000


Mejoramos nuestro costo en 1087439705000

# Entonces, predigo que una casa de 2500 pies cuadrados tendra:


nv_regressor.predict(2500)

125950.0

# Pero tambien predigo que una casa de 25000 pies cuadrados tendra:
nv_regressor.predict(25_000)

125950.0

# Y predigo que una casa de 2500000 pies cuadrados tendra:


nv_regressor.predict(2_500_000)

125950.0

🤔 hmmmmm.....teniendo en cuenta que el palacio de Buckingham tiene 400_000 pies cuadrados es sospechoso ...

sns.scatterplot(x='SqFt', y='Price', data=hp).set_title('Price vs Superficie')

x1 = hp["SqFt"].min()
x2 = hp["SqFt"].max()
y1 = nv_regressor.predict(x1)
y2 = nv_regressor.predict(x2)

plt.xlabel('Pies cuadrados')
plt.ylabel('Precio en dolares')
sns.lineplot(x=[x1, x2], y=[y1, y2], color='r') # mostramos nuestra prediccion en rojo
# sns.lineplot(x=[x1,x2],y=[hp['Price'].mean()]*2, color='b')
plt.show()

sns.scatterplot(x='SqFt', y='Price', data=hp).set_title('Price vs Superficie')

x1 = hp["SqFt"].min()
x2 = hp["SqFt"].max()
y1 = nv_regressor.predict(x1)
y2 = nv_regressor.predict(x2)

https://colab.research.google.com/drive/1NN0ujvf1zIJNqtey4Ve6DyMwslbfb8Ak?usp=sharing#scrollTo=97902dbd&printMode=true 15/17
20/6/23, 15:03 Introduccion_Python_paraML.ipynb - Colaboratory

plt.xlabel('Pies cuadrados')
plt.ylabel('Precio en dolares')
sns.lineplot(x=[x1, x2], y=[y1, y2], color='r') # mostramos nuestra prediccion en rojo

# Echemos un istazo a esos errores


for _, row in hp.iterrows():
plt.plot([row['SqFt'], row['SqFt']], [row['Price'], nv_regressor.predict(np.array(row['SqFt']))], 'b')

plt.show()

Regresion lineal (ya terminamos)

Ahora, sin entrar en detalles, vemos que puede hacer un modelo simple, pero real, de sklearn

lr1 = LinearRegression()
X = hp.SqFt.values.reshape(-1, 1)
y = hp.Price.values

# Entrenamos nuestro modelo con fit:


lr1.fit(X, y)

▾ LinearRegression
LinearRegression()

Veamos como se compara con nuestro modelo un poco peresozo. La libreria sklearn.metrics tiene distintos funciones para evaluar a
nuestros modelos. La funcion de costo que usamos previamente se llama "error cuadrado medio", o mean_squared_error, y es ampliamente
utilizada en modelos de regresion lineal.

import warnings
warnings.filterwarnings('ignore', category=np.VisibleDeprecationWarning)

# Primero, obtengamos una intuicion de lo que hace el modelo y como se compara con lo que hicimos anteriormente:
sns.scatterplot(x='SqFt', y='Price', data=hp).set_title('Precio vs Superficie')

x1 = hp["SqFt"].min()
x2 = hp["SqFt"].max()
y1 = lr1.predict(np.array([[x1]]))[0] # Ojo, aca predict de skearn espera siempre un array de 2 dimensiones
y2 = lr1.predict(np.array([[x2]]))[0] # Ojo, nos devuelve tambien un array (o vector)

plt.xlabel('Pies cuadrados')
plt.ylabel('Precio en dolares')
sns.lineplot(x=[x1, x2], y=[y1, y2], color='r') # mostramos nuestra prediccion en rojo

https://colab.research.google.com/drive/1NN0ujvf1zIJNqtey4Ve6DyMwslbfb8Ak?usp=sharing#scrollTo=97902dbd&printMode=true 16/17
20/6/23, 15:03 Introduccion_Python_paraML.ipynb - Colaboratory

# Echemos un istazo a esos errores


for _, row in hp.iterrows():
plt.plot([row['SqFt'], row['SqFt']], [row['Price'], lr1.predict(np.atleast_2d(row['SqFt']))], 'b')

plt.show()

from sklearn.metrics import mean_squared_error

# Hacemos nuestras predicciones con transform


y_pred = lr1.predict(X)

costo_sklearn = mean_squared_error(y, y_pred)


print(f"Nuestro modelo nos da un error de {int(costo_sklearn)}")
print(f"El error de sklearn es {int(costo_e - costo_sklearn)} menor que nuestro modelo peresozo")

Nuestro modelo nos da un error de 497256650


El error de sklearn es 46628333349 menor que nuestro modelo peresozo

Mejoramos nuestro error al predecir una linea que se ajusta mas a los datos. En las proximas clases, entraremos en detalle con el modelo de
regresion lineal

https://colab.research.google.com/drive/1NN0ujvf1zIJNqtey4Ve6DyMwslbfb8Ak?usp=sharing#scrollTo=97902dbd&printMode=true 17/17

También podría gustarte