lección 7
Viernes: las fichas de segmento y la demo
Asignar su segmento a cada cliente, sacar la tabla cups→segmento, montar las figuras con las dos siluetas enfrentadas y cerrar con el one-pager.
⏱ 55 min
## Viernes, 10:00. De los grupos a la decisión
Toda la semana ha sido para llegar aquí: no a un modelo, sino a una decisión que alguien pueda tomar. Fátima no quiere ver tu Pipeline ni tu silueta; quiere saber cuántos grupos hay, cómo es cada uno en una frase, y si puede fiarse de ellos para repartir las tarifas. Y Rosalía quiere algo todavía más concreto: la lista de qué cliente va en qué grupo, para meterla en su herramienta de campañas y lanzar la de la tarifa nocturna. Hoy conviertes el trabajo de modelado en esas dos entregas, y de paso cierras el repositorio que has ido montando sin darte cuenta.
El primer paso es el más directo: usar el modelo bueno —el escalado, dentro del Pipeline— para asignarle a cada cliente su segmento, y sacar la tabla cups→segmento. Esa tabla es la entrega que de verdad usa Rosalía: una columna con el identificador del cliente y otra con su grupo. Y el número que más le interesa es cuántos clientes caen en el grupo NOCTURNO —los que consumen sobre todo de noche—, porque es exactamente la gente a la que quiere ofrecer la tarifa nocturna. Son unos 150, alrededor del 25% de la cartera de la muestra. Y ojo con la lectura: no son "los que más gastan" (gastan como todos, un total normal), son "los que gastan de noche". Esa distinción es justo lo que el modelo del miércoles no sabía ver, y es la que hace útil la lista.
## Antes de recomendar tarifa: las franjas no son los periodos de la factura
Tus franjas de noche (0-8), día (8-18) y tarde (18-24) sirven para describir la forma de la curva. Pero la factura no se cobra por esas franjas. En España, casi todos los hogares tienen el peaje 2.0TD, que parte la semana en tres periodos: punta (de 10 a 14 y de 18 a 22, de lunes a viernes; el más caro), llano (de 8 a 10, de 14 a 18 y de 22 a 24, de lunes a viernes) y valle (de 0 a 8 los laborables, y todo el sábado, el domingo y los festivos nacionales; el más barato). Una tarifa con discriminación horaria como la nocturna de LuzClara cobra distinto cada periodo. Así que, antes de decir qué tarifa le va a cada grupo, hay que mirar cuánto consume cada grupo en cada periodo. Tu franja de "tarde" es el mejor ejemplo de por qué: de 18 a 22 es punta, la hora cara.
1# Reparto del consumo de cada segmento por periodo 2.0TD (de lecturas.csv).2# cups_segmento es la tabla cups -> segmento del primer ejercicio de hoy.3import numpy as np4import pandas as pd56L = pd.read_csv('datos/lecturas.csv')7L['cups'] = L['cups'].astype(str).str.strip().str.upper().str.replace('-', '').str.replace(' ', '')8L = L[L['consumo'] >= 0].copy()9es_wh = (L['unidad'] == 'Wh') | (L['unidad'].isnull() & (L['consumo'] > 10))10L['kwh'] = L['consumo'].where(~es_wh, L['consumo'] / 1000)11ts = pd.to_datetime(L['fecha_hora'], format='mixed', dayfirst=True)12h, finde = ts.dt.hour, ts.dt.dayofweek >= 5 # la semana tipo no tiene festivos13L['periodo'] = np.select(14 [finde | (h < 8), ((h >= 10) & (h < 14)) | ((h >= 18) & (h < 22))],15 ['valle', 'punta'], 'llano')16t = L.merge(cups_segmento, on='cups').groupby(['segmento', 'periodo'])['kwh'].sum().unstack()17print((100 * t.div(t.sum(axis=1), axis=0)).round(1))
El cálculo, a partir de las lecturas limpias y la tabla cups→segmento. Los periodos son los de la 2.0TD; la semana tipo (del 5 al 11 de febrero de 2024) no tiene ningún festivo nacional.
1% del consumo de cada segmento en cada periodo 2.0TD23segmento punta llano valle4noche 5,7 7,0 87,35tarde 37,1 23,1 39,86día 33,5 32,2 34,37plano 23,8 23,7 52,589horas de la semana en cada periodo:10 23,8 23,8 52,4 (40 h, 40 h y 88 h de 168)
Cómo se reparte el consumo de cada segmento entre punta, llano y valle. La última fila es el reparto de las horas: un cliente que consumiera lo mismo a todas horas caería ahí.
Ahora sí se puede leer la tabla como una recomendación. El grupo NOCHE pone el 87 % de su consumo en valle: la discriminación horaria le encaja de lleno. Ojo: de esos 150 clientes, 83 ya tienen la nocturna, así que la campaña es para los otros 67. El grupo de TARDE es el que más consume en punta (37 %): una tarifa por periodos le cobraría más justo en sus horas fuertes, así que lo suyo es un precio fijo. El de DÍA también pone un tercio en punta (de 10 a 14 es punta): precio fijo. Y el PLANO reparte su consumo casi igual que las horas de la semana, así que una tarifa por periodos ni le gana ni le pierde mucho: decide el precio, y la plana gana por sencillez.
Esto son recomendaciones para probar, no ahorros garantizados. Que a un grupo le "encaje" una tarifa depende de los precios de cada periodo, que no están en estos datos. Se confirma de dos maneras: calculando la factura de cada cliente con cada tarifa y sus precios reales, y midiendo la campaña con una prueba A/B (ofrecer la tarifa a la mitad del grupo, elegida al azar, y comparar con la otra mitad cuántos cambian y cuántos se quedan).
## La figura estrella: la silueta engañosa al lado de la honesta
De todas las figuras que llevas a la demo, hay una que resume el caso entero, y es la que te va a salvar cuando alguien pregunte "¿y por qué no usasteis el modelo de silueta más alta?". Es un gráfico de dos barras: a la izquierda, la silueta del modelo sin escalar (0,550); a la derecha, la del modelo escalado (0,441). La barra de la izquierda es más alta, y precisamente por eso es la trampa. Tienes que contarla al revés de como se lee: la barra más alta es el modelo peor, porque medía la separación por volumen; la más baja es el bueno, porque separa por patrón. Es contraintuitivo, y por eso es importante dibujarlo: así Fátima lo ve de un vistazo y entiende que elegisteis el modelo con el número peor a propósito.
Consejo de senior: en matplotlib dentro del navegador, pon matplotlib.use("Agg") al principio: fija un backend que dibuja a imagen sin pedir ventana, y la plataforma captura la figura sola. Y para esta figura, los colores SÍ van a fuego, no con variables de tema: la barra de la silueta engañosa en ámbar (atención) y la honesta en verde (la buena) codifican un significado, son dato del gráfico, no decoración. Esa es la excepción de los diagramas con datos dentro.
Con las fichas, las figuras y la tabla cups→segmento, el repositorio queda completo: src/05_perfiles.py cierra el código, las figuras van a output/, y solo falta el README, que lo escribes tú. El README de un proyecto de datos no es un trámite: es lo primero que lee quien abre tu repo en GitHub, y lo que convierte una carpeta de scripts en una pieza de portfolio que cuenta una historia. Lleva qué hace el proyecto, cómo se ejecuta (las dependencias y el orden de los scripts) y —lo que de verdad importa— el hallazgo honesto de la semana. Ese hallazgo es el one-pager que le dejas a Fátima, y es el último ejercicio.
## comentarios
Reporta erratas, ayuda a otros o comparte tu opinión. Sé constructivo.
Inicia sesión para comentar y responder.
cargando comentarios...
Regístrate para guardar tu progreso.