Fabric: Crea tu propios DataSet

Author Image

Brian Estévez LinkedIn

Blog

La creación y gestión de conjuntos de datos son pasos fundamentales cuando queremos realizar test sobre herramientas de análisis de datos como Microsoft Fabric o cuando se quiere realizar un ejemplo de Informe con Power BI. Sin embargo, a menudo nos encontramos con la necesidad de contar con datos específicos que no están disponibles en conjuntos de datos existentes. En tales casos, la creación de un dataset propio se convierte en una tarea crucial.

En este artículo se intentará utilizar las diferentes posibilidades de lenguaje que nos permite los notebooks de Fabric. Para comenzar deberemos tener creado un WorkSpace con la capacidad de Microsoft Fabric asignada, y un Lakehouse creado (en mi caso se llama Silver)

A raíz de aquí, crearemos en el WorkSpace un Notebook para comenzar a desarrollar las diferentes tablas delta, y en conjunto, el pequeño Dataset de ejemplo.

En primer lugar, para crear la tabla productos haremos uso del comando mágico %%sql y crearemos la tabla productos.

 


%%sql

CREATE TABLE productos (
    ID INT,
    nameProduct VARCHAR(255),
    Type VARCHAR(50),
    Price DECIMAL(10, 2),
    Stock INT
); 

Se nos habrá creado una tabla Delta dentro de nuestro Lakehouse

 

Llegados hasta este punto tenemos varias opciones para generar los productos iniciales

Opción 1

Hacer uso de una IA Generativa como Copilot, ChatGPT o Gemini y pedirle que te de un listado de 10 productos Prompt: Por favor, genera una lista de valores que representen una serie de productos con sus respectivas características, como nombre, tipo, precio y stock. Puedes incluir una variedad de productos, como teléfonos móviles y fundas para teléfonos, con precios y stocks aleatorios. Créame una sentencia INSERT INTO SQL que incluya todos los valores

Lo copiamos y lo insertamos en el notebook haciendo uso del comando mágico %%sql

%%sql
INSERT INTO productos (ID, Nombre_del_Producto, Tipo, Precio, Stock)
VALUES
    (1, 'iPhone 13', 'Móvil', 799.00, 50),
    (2, 'Samsung Galaxy S21', 'Móvil', 899.00, 30),
    (3, 'Xiaomi Redmi Note 9', 'Móvil', 249.00, 40),
    (4, 'Funda de Cuero para iPhone 13', 'Funda', 29.99, 100),
    (5, 'Funda Transparente para Samsung Galaxy S21', 'Funda', 14.99, 75),
    (6, 'Funda Antigolpes para Xiaomi Redmi Note 9', 'Funda', 19.99, 50),
    (7, 'iPhone 13 Pro', 'Móvil', 999.00, 40),
    (8, 'iPhone 13 Pro Max', 'Móvil', 1099.00, 35),
    (9, 'iPhone 14', 'Móvil', 849.00, 20),
    (10, 'iPhone 14 Pro', 'Móvil', 1099.00, 25),
    (11, 'iPhone 14 Pro Max', 'Móvil', 1199.00, 30),
    (12, 'Funda de Cuero para iPhone 13 Pro', 'Funda', 34.99, 80),
    (13, 'Funda Transparente para iPhone 13 Pro Max', 'Funda', 19.99, 60),
    (14, 'Funda Antigolpes para iPhone 14', 'Funda', 24.99, 45),
    (15, 'Funda de Cuero para iPhone 14 Pro', 'Funda', 39.99, 70),
    (16, 'Funda Transparente para iPhone 14 Pro Max', 'Funda', 24.99, 55);

Para corroborar que todo está funcionando correctamente hacemos una consulta SQL con un SELECT a la tabla Delta correspondiente

%%sql

SELECT * FROM Silver.productos

Si prefieres hacer uso de PySpark puedes obtener el mismo resultado con el siguiente código.

Cargar la tabla de productos desde Delta Lake products_df = spark.read.format("delta").load("Tables/productos") display(products_df)

Ahora vamos a divertirnos un poco, si recuerdas, comenté que podíamos utilizar dos opciones. Vamos allá con la opción 2

Opción 2

Para la opción dos también haremos uso de la IA generativa, pero, a través de LM Studio. Para ello, lo primero que debemos hacer es descargarnos el Software LM Studio

 

Una vez descargado e instalado, tendremos una interfaz como esta

Ahora empieza lo divertido, busca un modelo que encaje dentro de tus necesidades o que te gustaría probar e instálalo. Para instalarlo simplemente una vez encontrado el modelo de tu elección dale al botón de "Download"

Yo he probado con varios, aquí te dejo una pequeña muestra de los que he utilizado

Poner en marcha el modelo

Para comenzar a utilizar el modelo, sitúate en la barra lateral izquierda en donde dice AI Chat

Posteriormente en la barra superior selecciona el modelo a cargar "Select a model to load" y una vez cargado ya podrás probarlo.

 

🔧 El resto de configuraciones sobre uso de GPU, CPU, RAM no entran dentro de este artículo.

¿Y ahora qué?

Bueno, ahora tendremos que habilitar la opción de Local Server que nos facilita LM Studio y poder utilizarlo en el Notebook de Microsoft Fabric. Para ello, en la barra lateral izquierda clickamos en Local Server

Y teniendo cargado el modelo deseado, clickamos en Start Server

Abrimos un nuevo bloque de código e instalamos la siguiente librería, y ejecutamos la celda


    %pip install openai

👉 Si ves que tienes algún inconveniente a posteriori ejecutando el código haz uso de


    %pip install openai --upgrade

El siguiente paso, es crear un nuevo bloque de código y hacer uso de la API que el propio Local Server nos da como ejemplo (con algunos retoques)


    # Chat
from openai import OpenAI

# Local Server
client = OpenAI(base_url="http://localhost:1234/v1", api_key="lm-studio")

history = [
    {"role": "system", "content": "Eres un asistente inteligente. Siempre das respuestas razonadas, correctas y útiles. Hablas Español"},
    {"role": "user", "content": "Por favor, genera una lista de valores que representen una serie de productos con sus respectivas características, como id, nombre, tipo, precio y stock. Puedes incluir una variedad de productos, como teléfonos móviles y fundas para teléfonos, con precios y stocks aleatorios.Creame 10 rows distintas Debes crear un INSERT INTO de SQL como esto ID Nombre	Tipo	Precio	Stock	Descripción 1 Samsung Galaxy S23 Ultra	Teléfono móvil	€1.299	50	Smartphone de alta gama con pantalla AMOLED de 6.8 pulgadas, cámara de 108MP y procesador Snapdragon 8 Gen 2. Y creame un INSERT INTO productos (ID, Nombre_del_Producto, Tipo, Precio, Stock) VALUES (1, 'iPhone 13', 'Móvil', 799.00, 50) con los productos que has generado"},
]

while True:
    completion = client.chat.completions.create(
        model="local-model", # this field is currently unused
        messages=history,
        temperature=0.7,
        stream=True,
    )

    new_message = {"role": "assistant", "content": ""}
    
    for chunk in completion:
        if chunk.choices[0].delta.content:
            print(chunk.choices[0].delta.content, end="", flush=True)
            new_message["content"] += chunk.choices[0].delta.content

    history.append(new_message)


    print()
    break
    history.append({"role": "user", "content": input("> ")}) 

¿Te has fijado en la base_url?

Apunta a un servidor local, algo que a priori Microsoft Fabric arrojará un error si ejecutamos el código. Así, para poder llamar a la API que hemos levantado en local, usaremos (a modo de testeo y educativo) Ngrok.

 En mi caso, he levantado el servidor en el puerto 1234, por lo que, para utilizar ngrok abriré la terminal cmd y escribiré este comando

ngrok http 1234

Y te deberá dar como respuesta algo similar a

La dirección https que te de en Forwarding es la que debes copiar en la base_url. Si ejecutamos la celda en Microsoft Fabric el resultado es

 

A partir de aquí que la imaginación vuele respecto a las posibilidades en cuanto a peticiones hacia la IA con LM Studio, pero recuerda, siempre con fines de conocer mejor la herramienta.

👉 Recuerda apagar el servidor local, y ngrok.

Vamos a crear la tabla ventas que guarde relación con la tabla productos

Ahora, una vez realizada la primera parte y creada la tabla productos generaremos la tabla de ventas a raíz de los productos creados.

from pyspark.sql import SparkSession, functions as F, types as T
from pyspark.sql.functions import col, expr, rand, abs, floor, dayofmonth, to_date, datediff, monotonically_increasing_id
from random import randrange
from datetime import datetime, timedelta


# Define start and end dates
start_date = '2022-01-01'
end_date = '2023-12-31'

# Load products table from Delta Lake
products_df = spark.read.format("delta").load("Tables/productos")

# Recopilar los datos de productos en un diccionario
products_dict = {row["ID"]: row["Precio"] for row in products_df.select("ID", "Precio").collect()}

data = []

# Generar datos
for _ in range(10):
    # Generar un ID de producto aleatorio
    random_product_id = randrange(1, 12)

    # Verificar si el ID de producto aleatorio existe en el diccionario de productos
    if random_product_id in products_dict:
        random_quantity = randrange(1, 5)
        precio = products_dict[random_product_id]
        total = precio * random_quantity
        
        # Generar una fecha de transacción aleatoria dentro del rango proporcionado
        transaction_date = (datetime.strptime(start_date, '%Y-%m-%d') + timedelta(days=randrange((datetime.strptime(end_date, '%Y-%m-%d') - datetime.strptime(start_date, '%Y-%m-%d')).days))).strftime('%Y-%m-%d')
        
        data.append((random_product_id, random_quantity, precio, total, transaction_date))

# Crear DataFrame a partir de la lista de datos
schema = T.StructType([
    T.StructField("random_product_id", T.IntegerType(), True),
    T.StructField("random_quantity", T.IntegerType(), True),
    T.StructField("Precio", T.DecimalType(10, 2), True),
    T.StructField("Total", T.DecimalType(10, 2), True),
    T.StructField("Transaction_Date", T.StringType(), True),
])

df = spark.createDataFrame(data, schema=schema)

# Mostrar el DataFrame resultante
df.show()

 

Este código lo podemos resumir de la siguiente manera

  1. Importa las clases y funciones necesarias de PySpark para trabajar con DataFrames y realizar operaciones en ellos.
  2. Definimos el rango de fecha
  3. Leemos los datos de productos desde la tabla Delta Lake ubicada en nuestro Lakehouse y carga estos datos en un DataFrame llamado products_df.
  4. Recopilamos los datos del DataFrame products_df en un diccionario llamado products_dict, donde las claves son los ID de los productos y los valores son los precios de los productos.
  5. Se generan datos aleatorios simulando transacciones de productos. Por cada iteración en un rango de 10 repeticiones. Puedes añadirle más repeticiones para ver el comportamiento de Microsoft Fabric, y que el dataset que generes tenga más volumen.
  6. Se crea un DataFrame llamado df a partir de la lista de datos (data) y el esquema definido anteriormente (schema).
  7. Por último se muestra el dataframe para estar seguros de que lo que se está ejecutando es correcto.

 

A continuación generamos un bloque de código y creamos la tabla de ventas con el comando mágico %%sql

%%sql

CREATE TABLE IF NOT EXISTS ventas (
productId INT,
quantity INT,
price DECIMAL(10,2),
discount DECIMAL(10,2),
totalAmount DECIMAL(10,2),
date DATE,
storeId INT
) USING DELTA;


Deberemos crear un nuevo Dataframe tf_df que contendrá las mismas filas que el DataFrame original df, pero con columnas seleccionadas y renombradas según lo especificado en la creación de la tabla Delta.

from pyspark.sql.functions import col


tf_df = df.select(
    col("random_product_id").alias("productId"),
    col("random_quantity").alias("quantity"),
    col("Precio").alias("price"),
    col("Total").alias("totalAmount"),
    col("Transaction_Date").alias("date")
)

# Convierte la columna "date" del DataFrame tf_df al tipo de datos DateType utilizando la función to_date()

tf_df = tf_df.withColumn("date", to_date("date"))

👉A veces, esto puede ser útil para cambiar el nombre de las columnas o seleccionar solo un subconjunto de columnas para su uso posterior en análisis o procesamiento de datos.

Por último, especificaremos que el DataFrame tf_df se guardará en formato Delta Lake. Recuerda: Delta Lake es un formato de almacenamiento de datos de código abierto que proporciona transacciones ACID (Atomicity, Consistency, Isolation, Durability) y funcionalidades de versionado.

tf_df.write.format("delta").mode("append").save("Tables/ventas")

Para corroborar que todo es correcto

%%sql

SELECT * from Silver.ventas