Streamlit

Streamlit

Tutorial Streamlit: Integrar Scikit Learn en Streamlit

Implementa un modelo de regresión y clasificación con Scikit-Learn en Streamlit. Aprende a crear aplicaciones para predicciones interactivas eficientes con Streamlit para Machine Learning.

Aprende Streamlit y certifícate

Implementación de modelos de regresión de Scikit-Learn en Streamlit

La integración de modelos de regresión de Scikit-Learn en Streamlit permite crear aplicaciones interactivas para predecir valores numéricos. A continuación, se ejemplifica cómo implementar un modelo de regresión lineal utilizando el conjunto de datos California Housing proporcionado por Scikit-Learn.

Primero, se importan las bibliotecas necesarias y se cargan los datos:

import streamlit as st
import numpy as np
from sklearn.datasets import fetch_california_housing
from sklearn.linear_model import LinearRegression

# Cargar el conjunto de datos
datos = fetch_california_housing()
X = datos.data
y = datos.target

Se entrena el modelo de regresión lineal con los datos cargados:

# Entrenar el modelo
modelo = LinearRegression()
modelo.fit(X, y)

En la aplicación de Streamlit, se crean controles de entrada para que el usuario ingrese los valores de las características:

st.title("Predicción del precio de viviendas en California")

# Entradas del usuario
col1, col2 = st.columns(2)

with col1:
    MedInc = st.number_input('Ingreso medio', min_value=0.0, step=0.1, value=3.5)
    HouseAge = st.number_input('Edad de la vivienda', min_value=0, step=1, value=25)
    AveRooms = st.number_input('Número medio de habitaciones', min_value=0.0, step=0.1, value=5.0)
    AveBedrms = st.number_input('Número medio de dormitorios', min_value=0.0, step=0.1, value=1.0)

with col2:
    Population = st.number_input('Población', min_value=0, step=1, value=1000)
    AveOccup = st.number_input('Número medio de ocupantes', min_value=0.0, step=0.1, value=3.0)
    Latitude = st.number_input('Latitud', min_value=32.0, max_value=42.0, step=0.01, value=34.05)
    Longitude = st.number_input('Longitud', min_value=-124.0, max_value=-114.0, step=0.01, value=-118.25)

Se organiza la entrada del usuario y se realiza la predicción al pulsar un botón:

# Preparar los datos de entrada
entrada = np.array([[MedInc, HouseAge, AveRooms, AveBedrms, Population, AveOccup, Latitude, Longitude]])

if st.button('Predecir precio'):
    # Realizar la predicción
    prediccion = modelo.predict(entrada)
    st.write(f'El precio estimado de la vivienda es: **{prediccion[0]:.2f} cientos de miles de dólares**')

Este enfoque permite al usuario interactuar con el modelo, modificando los parámetros y observando cómo afectan al precio estimado de la vivienda. Además, se puede mejorar la aplicación incorporando visualizaciones que muestren la dispersión de los datos y las predicciones del modelo.

Para optimizar el rendimiento, es recomendable utilizar la caché de Streamlit al cargar y entrenar el modelo:

@st.cache_data
def cargar_datos():
    datos = fetch_california_housing()
    return datos.data, datos.target

@st.cache_data
def entrenar_modelo(X, y):
    modelo = LinearRegression()
    modelo.fit(X, y)
    return modelo

# Cargar y entrenar el modelo
X, y = cargar_datos()
modelo = entrenar_modelo(X, y)

Con estas funciones cacheadas, se evita recalcular el modelo en cada ejecución, mejorando la eficiencia de la aplicación.

También es posible mostrar métricas de rendimiento del modelo, como el coeficiente de determinación R², para informar al usuario sobre la precisión de las predicciones:

from sklearn.metrics import r2_score

# Calcular R² en el conjunto de entrenamiento
r2 = r2_score(y, modelo.predict(X))
st.write(f'El coeficiente de determinación R² del modelo es: **{r2:.2f}**')

Integrar modelos de regresión en Streamlit ofrece una forma dinámica de presentar resultados y permite a los usuarios explorar diferentes escenarios modificando las variables de entrada.

Regresión con Pipeline

En este ejemplo montamos un Pipeline de regresión con Scikit Learn, lo exportamos con joblib y lo usamos en Streamlit para predecir las propinas tip de un restaurante, el ejemplo es extrapolable a cualquier otro dataset.

Primero creamos en un notebook o un archivo python independiente el código para crear el pipeline. Ejemplo de estructura de aplicación:

Contenido del pipeline:

import pandas as pd
import seaborn as sns
from sklearn.pipeline import make_pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import MinMaxScaler, OneHotEncoder
from sklearn.ensemble import RandomForestRegressor
from sklearn.compose import ColumnTransformer, make_column_selector, make_column_transformer
import joblib

df = sns.load_dataset('tips')

X = df.drop('tip', axis=1)
y = df['tip']

column_transformer = make_column_transformer(
    (
        make_pipeline(
            SimpleImputer(strategy='median'),
            MinMaxScaler()
        ),
        make_column_selector(dtype_include='number') # detecta automaticamente columnas numéricas
    ),
    (
        make_pipeline(
            SimpleImputer(strategy='most_frequent'),
            OneHotEncoder(sparse_output=False)
        ),
        make_column_selector(dtype_include=['object', 'category']) # detecta automaticamente columnas categóricas
    )
)
pipeline = make_pipeline(column_transformer, RandomForestRegressor(random_state=42))
pipeline.fit(X, y)
print('R2 en train', pipeline.score(X, y))
joblib.dump(pipeline, 'pipeline.joblib')

Contenido para app.py usando el pipeline:

import streamlit as st
import joblib
import seaborn as sns
import pandas as pd 

# @st.cache_resource
# def load_keras_model():
#     return tf.keras.models.load_model('model.keras')
@st.cache_resource
def load_scikit_model():
    return joblib.load('pipeline.joblib')

model = load_scikit_model()

# 1. Mostrar datos (opcional)
st.title('Regresión tip')
st.write('Ejemplo de los datos')
df = sns.load_dataset('tips')
tip_mean = df['tip'].mean() # propina media de todo el dataset

st.table(df.head())

# 2. Formulario para predicción
st.header('Introduce datos para la predicción')

with st.form("tips_form"):
    total_bill = st.number_input(
                    'Introduce total cuenta (total_bill)', 
                    min_value=0.0, max_value=100.0, 
                    value=df['total_bill'].mean(), 
                    step=0.1
    )
    size = st.number_input(
        'Introduce número comensales (size)',
        min_value=1, 
        value=df['size'].mode()[0], # opcional poner el valor más habitual
        max_value=10,
        step=1
    )
    sex = st.selectbox('Introduce género (sex)', ['Male', 'Female'])
    smoker = st.selectbox('Introduce si es fumador (smoker)', ['Yes', 'No'])
    day = st.selectbox('Introduce día semana (day)', ['Thur', 'Fri', 'Sat', 'Sun'])
    time = st.selectbox('Introduce horario (time)', ['Lunch', 'Dinner'])

    boton_enviar = st.form_submit_button("Generar predicción")

    if boton_enviar:
        X_new = pd.DataFrame({
            'total_bill': [total_bill],
            'sex': [sex],
            'smoker': [smoker],
            'day': [day],
            'time': [time],
            'size': [size]                        
        })
        prediccion = model.predict(X_new)[0] # esta prediccion se podría guardar en base de datos junto a los datos introducidos
        # st.write(prediccion)
        delta_value = prediccion - tip_mean
        col1, col2 = st.columns(2)
        col1.metric('Propina estimada (predicción)', value=f'{prediccion:.2f} $', delta=f'{delta_value:.2f} $')
        col2.metric('Propina media', value=f'{tip_mean:.2f} $')

Resultado al ejecutar la aplicación:

Implementación de modelos de clasificación de Scikit-Learn en Streamlit

La integración de modelos de clasificación de Scikit-Learn en Streamlit permite desarrollar aplicaciones interactivas para predecir categorías o etiquetas. A continuación, se muestra cómo implementar un modelo de clasificación utilizando el conjunto de datos Iris proporcionado por Scikit-Learn.

Primero, se importan las bibliotecas necesarias y se cargan los datos:

import streamlit as st
import pandas as pd
from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestClassifier

# Cargar el conjunto de datos Iris
datos = load_iris()
X = datos.data
y = datos.target
especies = datos.target_names

Se entrena el modelo de Bosque Aleatorio con los datos cargados:

# Entrenar el modelo
modelo = RandomForestClassifier()
modelo.fit(X, y)

En la aplicación de Streamlit, se crean controles para que el usuario introduzca las características de una flor y se realice la predicción:

st.title("Clasificación de Flores Iris")
st.write("Ingrese las características de la flor para predecir su especie.")

# Entradas del usuario
longitud_sepalo = st.slider('Longitud del sépalo (cm)', float(X[:, 0].min()), float(X[:, 0].max()), float(X[:, 0].mean()))
ancho_sepalo = st.slider('Ancho del sépalo (cm)', float(X[:, 1].min()), float(X[:, 1].max()), float(X[:, 1].mean()))
longitud_petalo = st.slider('Longitud del pétalo (cm)', float(X[:, 2].min()), float(X[:, 2].max()), float(X[:, 2].mean()))
ancho_petalo = st.slider('Ancho del pétalo (cm)', float(X[:, 3].min()), float(X[:, 3].max()), float(X[:, 3].mean()))

Se organiza la entrada del usuario y se utiliza el modelo para predecir la especie:

# Preparar los datos de entrada
entrada_usuario = [[longitud_sepalo, ancho_sepalo, longitud_petalo, ancho_petalo]]

# Realizar la predicción
prediccion = modelo.predict(entrada_usuario)
probabilidades = modelo.predict_proba(entrada_usuario)

Se muestra la especie predicha y las probabilidades asociadas a cada clase:

st.subheader('Resultado de la predicción')
st.write(f"La especie predicha es: **{especies[prediccion[0]]}**")

st.subheader('Probabilidades por especie')
probabilidades_df = pd.DataFrame(probabilidades, columns=especies)
st.write(probabilidades_df)

Para enriquecer la aplicación, se pueden añadir visualizaciones que ayuden a entender mejor los datos y las predicciones. Por ejemplo, un gráfico de dispersión de las características:

import matplotlib.pyplot as plt

st.subheader('Visualización de las características')

fig, ax = plt.subplots()
scatter = ax.scatter(X[:, 0], X[:, 1], c=y, cmap='viridis')
ax.set_xlabel('Longitud del sépalo (cm)')
ax.set_ylabel('Ancho del sépalo (cm)')
legend = ax.legend(*scatter.legend_elements(), title="Especies")
ax.add_artist(legend)
st.pyplot(fig)

La integración de modelos de clasificación en Streamlit permite a los usuarios interactuar con los modelos de aprendizaje y explorar cómo diferentes entradas afectan a las predicciones. Esto facilita la comprensión y el análisis de los resultados en tiempo real.

Implementación de modelos de aprendizaje no supervisado de Scikit-Learn en Streamlit

La integración de modelos de aprendizaje no supervisado de Scikit-Learn en Streamlit ofrece la posibilidad de crear aplicaciones interactivas para explorar y analizar datos sin etiquetas predefinidas. A continuación, se muestra cómo implementar un modelo de clustering K-Means utilizando datos generados con Scikit-Learn y visualizar los resultados en una aplicación de Streamlit.

Primero, se importan las bibliotecas necesarias y se generan datos sintéticos para realizar el agrupamiento:

import streamlit as st
from sklearn.datasets import make_blobs
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt

# Generar datos sintéticos
X, y = make_blobs(n_samples=300, centers=4, cluster_std=0.60, random_state=0)

Se crea una aplicación de Streamlit donde el usuario puede seleccionar el número de clusters para el modelo K-Means:

st.title("Clustering con K-Means")

# Selección del número de clusters
num_clusters = st.slider('Seleccione el número de clusters', min_value=1, max_value=10, value=4)

Se entrena el modelo K-Means con el número de clusters seleccionado y se obtienen las etiquetas para cada punto de datos:

# Entrenar el modelo K-Means
modelo = KMeans(n_clusters=num_clusters)
modelo.fit(X)
labels = modelo.predict(X)

Se visualizan los resultados del clustering utilizando un gráfico de dispersión:

# Visualizar los clusters
fig, ax = plt.subplots()
scatter = ax.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis', alpha=0.6)
ax.scatter(modelo.cluster_centers_[:, 0], modelo.cluster_centers_[:, 1], c='red', marker='X', s=200, label='Centroides')
ax.set_xlabel('Característica 1')
ax.set_ylabel('Característica 2')
ax.legend()
st.pyplot(fig)

Con esta aplicación, el usuario puede interactuar modificando el número de clusters y observando cómo cambia el agrupamiento de los datos. Además, es posible mostrar las coordenadas de los centroides calculados por el modelo:

# Mostrar centroides
st.subheader('Centroides de los clusters')
st.write(modelo.cluster_centers_)

Para mejorar la eficiencia, se recomienda utilizar la caché de Streamlit al generar los datos y entrenar el modelo:

@st.cache_data
def generar_datos():
    X, y = make_blobs(n_samples=300, centers=4, cluster_std=0.60, random_state=0)
    return X

@st.cache_data
def entrenar_modelo(X, num_clusters):
    modelo = KMeans(n_clusters=num_clusters)
    modelo.fit(X)
    return modelo

# Generar datos y entrenar el modelo
X = generar_datos()
modelo = entrenar_modelo(X, num_clusters)
labels = modelo.predict(X)

También se puede permitir al usuario ajustar otros parámetros del modelo K-Means, como el criterio de inicialización y el número máximo de iteraciones:

# Selección de parámetros adicionales
init_method = st.selectbox('Método de inicialización', ('k-means++', 'random'))
max_iter = st.number_input('Número máximo de iteraciones', min_value=100, max_value=1000, value=300, step=100)

# Entrenar el modelo con los parámetros seleccionados
modelo = KMeans(n_clusters=num_clusters, init=init_method, max_iter=max_iter)
modelo.fit(X)
labels = modelo.predict(X)

Para evaluar la calidad del agrupamiento, se puede calcular el coeficiente de silueta y mostrarlo en la aplicación:

from sklearn.metrics import silhouette_score

# Calcular el coeficiente de silueta
score = silhouette_score(X, labels)
st.write(f'El coeficiente de silueta es: **{score:.2f}**')

Implementar modelos de aprendizaje no supervisado en Streamlit permite a los usuarios explorar interactivamente los datos y comprender mejor las estructuras internas sin la necesidad de etiquetas. Es una forma de presentar resultados de análisis exploratorio y facilitar la toma de decisiones basada en datos.

CONSTRUYE TU CARRERA EN IA Y PROGRAMACIÓN SOFTWARE

Accede a +1000 lecciones y cursos con certificado. Mejora tu portfolio con certificados de superación para tu CV.

30 % DE DESCUENTO

Plan mensual

19.00 /mes

13.30 € /mes

Precio normal mensual: 19 €
63 % DE DESCUENTO

Plan anual

10.00 /mes

7.00 € /mes

Ahorras 144 € al año
Precio normal anual: 120 €
Aprende Streamlit online

Todas las lecciones de Streamlit

Accede a todas las lecciones de Streamlit y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Accede GRATIS a Streamlit y certifícate

En esta lección

Objetivos de aprendizaje de esta lección

  • Implementar un modelo de regresión lineal utilizando Scikit-Learn.
  • Crear una interfaz interactiva en Streamlit para entradas del usuario.
  • Realizar predicciones y mostrar resultados dinámicos en la aplicación.
  • Optimizar el rendimiento de la aplicación con funcionalidades de caché.
  • Incorporar visualizaciones y métricas de evaluación para el modelo.