Modelo de pronóstico de autorregresión para el consumo de electricidad de los hogares


Dado el auge de los medidores de electricidad inteligentes y la amplia adopción de tecnología de generación de electricidad como los paneles solares, hay una gran cantidad de datos disponibles sobre el uso de electricidad.

Estos datos representan una serie temporal multivariante de variables relacionadas con la energía que, a su vez, podrían usarse para modelar e incluso pronosticar el consumo futuro de electricidad.

Los modelos de autocorrelación son muy simples y pueden proporcionar una forma rápida y efectiva de hacer pronósticos hábiles de uno o varios pasos para el consumo de electricidad.

Descripción del problema

El conjunto de datos de ‘ Consumo de energía del hogar ‘ es un conjunto de datos de series de tiempo multivariable que describe el consumo de electricidad de un solo hogar durante cuatro años.

Los datos se recopilaron entre diciembre de 2006 y noviembre de 2010 y cada minuto se recopilaron observaciones del consumo de energía dentro del hogar.

Es una serie multivariada compuesta por siete variables (además de la fecha y la hora); ellos son:

  • global_active_power : la potencia activa total consumida por el hogar (kilovatios).
  • global_reactive_power : La potencia reactiva total consumida por el hogar (kilovatios).
  • voltaje : Voltaje promedio (voltios).
  • global_intensity : Intensidad de corriente promedio (amperios).
  • sub_metering_1 : Energía activa para cocina (vatios-hora de energía activa).
  • sub_metering_2 : Energía activa para lavandería (vatios-hora de energía activa).
  • sub_metering_3 : Energía activa para sistemas de control climático (vatios-hora de energía activa).

Las energías activa y reactiva se refieren a los dos componentes de la potencia. La potencia activa se refiere a la parte de la potencia que realiza trabajo útil, como la alimentación de dispositivos eléctricos, la generación de calor, la iluminación, etc. Se mide en watts (W) y es la potencia que se contabiliza en la facturación eléctrica.

Por otro lado, la potencia reactiva se refiere a la parte de la potencia que no realiza trabajo útil, sino que está asociada al almacenamiento y liberación de energía en los componentes inductivos y capacitivos de un sistema eléctrico. Se mide en voltiamperios reactivos (VAR) y no contribuye directamente al trabajo útil, pero es necesario para mantener la tensión y el flujo de energía en el sistema.

El factor de potencia, representado por el coseno de fi (θ), es una medida de la eficiencia con la que la energía eléctrica se utiliza en un sistema. Es el coseno del ángulo de desfase entre la corriente y la tensión en un circuito de corriente alterna. Un factor de potencia cercano a 1 indica un uso eficiente de la energía, donde la potencia activa es alta en comparación con la potencia reactiva. Un factor de potencia bajo indica que hay una cantidad significativa de potencia reactiva en relación con la potencia activa

Se puede crear una cuarta variable de submedición restando la suma de tres variables de submedición definidas de la energía activa total de la siguiente manera:

sub_metering_remainder = (global_active_power * 1000 / 60) - (sub_metering_1 + sub_metering_2 + sub_metering_3)

Cargar y preparar conjunto de datos

El conjunto de datos se puede descargar desde el repositorio de UCI Machine Learning como un solo archivo .zip de 20 megabytes: consumo_electricidad_hogar.zip

Descargue el conjunto de datos y descomprímalo en su directorio de trabajo actual. Ahora tendrá el archivo “ home_power_consumption.txt ” que tiene un tamaño de aproximadamente 127 megabytes y contiene todas las observaciones.

Podemos usar la función read_csv() para cargar los datos y combinar las dos primeras columnas en una única columna de fecha y hora que podemos usar como índice.

dataset = read_csv('household_power_consumption.txt', sep=';', header=0, low_memory=False, infer_datetime_format=True, parse_dates={'datetime':[0,1]}, index_col=['datetime'])

A continuación, podemos marcar todos los valores faltantes indicados con un ‘ ‘ carácter con un valor NaN , que es un flotante.

Esto nos permitirá trabajar con los datos como una matriz de valores de punto flotante en lugar de tipos mixtos (menos eficientes).


# mark all missing values
dataset.replace('?', nan, inplace=True)
# make dataset numeric
dataset = dataset.astype('float32')

También necesitamos completar los valores faltantes ahora que han sido marcados.

Un enfoque muy simple sería copiar la observación a la misma hora del día anterior. Podemos implementar esto en una función llamada fill_missing() que tomará la matriz NumPy de los datos y copiará los valores de hace exactamente 24 horas.

def fill_missing(values):
 one_day = 60 * 24
 for row in range(values.shape[0]):
 for col in range(values.shape[1]):
 if isnan(values[row, col]):
 values[row, col] = values[row - one_day, col]

Podemos aplicar esta función directamente a los datos dentro del DataFrame.

# fill missing
fill_missing(dataset.values)

Ahora podemos crear una nueva columna que contenga el resto de la submedición, utilizando el cálculo de la sección anterior.

values = dataset.values
dataset['sub_metering_4'] = (values[:,0] * 1000 / 60) - (values[:,4] + values[:,5] + values[:,6])


Ahora podemos guardar la versión limpia del conjunto de datos en un nuevo archivo; en este caso, simplemente cambiaremos la extensión del archivo a .csv y guardaremos el conjunto de datos como ‘ home_power_consumption.csv ‘.

# save updated dataset
dataset.to_csv(‘household_power_consumption.csv’)

Uniendo todo esto, el ejemplo completo de cargar, limpiar y guardar el conjunto de datos se enumera a continuación.


# load and clean-up data
from numpy import nan
from numpy import isnan
from pandas import read_csv
from pandas import to_numeric
 
# fill missing values with a value at the same time one day ago
def fill_missing(values):
 one_day = 60 * 24
 for row in range(values.shape[0]):
 for col in range(values.shape[1]):
 if isnan(values[row, col]):
 values[row, col] = values[row - one_day, col]
 
# load all data
dataset = read_csv('household_power_consumption.txt', sep=';', header=0, low_memory=False, infer_datetime_format=True, parse_dates={'datetime':[0,1]}, index_col=['datetime'])
# mark all missing values
dataset.replace('?', nan, inplace=True)
# make dataset numeric
dataset = dataset.astype('float32')
# fill missing
fill_missing(dataset.values)
# add a column for for the remainder of sub metering
values = dataset.values
dataset['sub_metering_4'] = (values[:,0] * 1000 / 60) - (values[:,4] + values[:,5] + values[:,6])
# save updated dataset
dataset.to_csv('household_power_consumption.csv')

Al ejecutar el ejemplo, se crea el nuevo archivo » home_power_consumption.csv » que podemos usar como punto de partida para nuestro proyecto de modelado.

Evaluación del modelo

Encuadre del problema

Hay muchas maneras de aprovechar y explorar el conjunto de datos de consumo de energía del hogar.En este enfoque, usaremos los datos para explorar una pregunta muy específica; eso es: Dado el consumo de energía reciente, ¿cuál es el consumo de energía esperado para la próxima semana? Esto requiere que un modelo predictivo pronostique la potencia activa total para cada día durante los próximos siete días.

Técnicamente, este encuadre del problema se conoce como un problema de pronóstico de serie de tiempo de múltiples pasos, dados los múltiples pasos de pronóstico. Un modelo que hace uso de múltiples variables de entrada puede denominarse modelo de pronóstico de serie de tiempo multivariante de múltiples pasos.

Un modelo de este tipo podría ser útil dentro del hogar en la planificación de gastos. También podría ser útil desde el punto de vista de la oferta para planificar la demanda de electricidad de un hogar específico.

Este marco del conjunto de datos también sugiere que sería útil reducir la muestra de las observaciones por minuto del consumo de energía a los totales diarios. Esto no es obligatorio, pero tiene sentido, dado que estamos interesados ​​en la potencia total por día.

Podemos lograr esto fácilmente usando la función resample() en pandas DataFrame. Llamar a esta función con el argumento ‘ D ‘ permite que los datos cargados indexados por fecha y hora se agrupen por día ( ver todos los alias de compensación ). Luego podemos calcular la suma de todas las observaciones para cada día y crear un nuevo conjunto de datos de consumo de energía diario para cada una de las ocho variables.

El ejemplo completo se muestra a continuación.

from pandas import read_csv
# load the new file
dataset = read_csv('household_power_consumption.csv', header=0, infer_datetime_format=True, parse_dates=['datetime'], index_col=['datetime'])
# resample data to daily
daily_groups = dataset.resample('D')
daily_data = daily_groups.sum()
# summarize
print(daily_data.shape)
print(daily_data.head())
# save
daily_data.to_csv('household_power_consumption_days.csv')

Al ejecutar el ejemplo, se crea un nuevo conjunto de datos de consumo de energía total diario y se guarda el resultado en un archivo separado llamado » home_power_conquisition_days.csv «.

Podemos usar esto como el conjunto de datos para ajustar y evaluar modelos predictivos para el marco elegido del problema.

Métrica de evaluación

Un pronóstico estará compuesto por siete valores, uno para cada día de la semana siguiente. Es común con los problemas de pronóstico de varios pasos evaluar cada paso de tiempo pronosticado por separado. Esto es útil por varias razones:

  • Para comentar sobre la aptitud en un plazo de entrega específico (p. ej., +1 día frente a +3 días).
  • Para contrastar modelos en función de sus habilidades en diferentes plazos de entrega (por ejemplo, modelos buenos en +1 día frente a modelos buenos en días +5).

Las unidades de la potencia total son los kilovatios y sería útil tener una métrica de error que también estuviera en las mismas unidades. Tanto el error cuadrático medio (RMSE) como el error absoluto medio (MAE) se ajustan a esta factura, aunque RMSE se usa más comúnmente y se adoptará en este tutorial. A diferencia de MAE, RMSE castiga más los errores de pronóstico.

La métrica de rendimiento para este problema será el RMSE para cada tiempo de entrega desde el día 1 hasta el día 7.

Como atajo, puede ser útil resumir el rendimiento de un modelo utilizando una puntuación única para ayudar en la selección del modelo.

Una puntuación posible que podría usarse sería el RMSE en todos los días de pronóstico.

La función Evaluation_forecasts() a continuación implementará este comportamiento y devolverá el rendimiento de un modelo basado en múltiples pronósticos de siete días.

def evaluate_forecasts(actual, predicted):
 scores = list()
 # calculate an RMSE score for each day
 for i in range(actual.shape[1]):
 # calculate mse
 mse = mean_squared_error(actual[:, i], predicted[:, i])
 # calculate rmse
 rmse = sqrt(mse)
 # store
 scores.append(rmse)
 # calculate overall RMSE
 s = 0
 for row in range(actual.shape[0]):
 for col in range(actual.shape[1]):
 s += (actual[row, col] - predicted[row, col])**2
 score = sqrt(s / (actual.shape[0] * actual.shape[1]))
 return score, scores

Ejecutar la función primero devolverá el RMSE general independientemente del día, luego una matriz de puntajes de RMSE para cada día.

Conjuntos de entrenamiento y prueba

Usaremos los primeros tres años de datos para entrenar modelos predictivos y el último año para evaluar modelos.

Los datos de un conjunto de datos determinado se dividirán en semanas estándar. Son semanas que comienzan en domingo y terminan en sábado.

Esta es una forma realista y útil de usar el encuadre elegido del modelo, donde se puede predecir el consumo de energía para la próxima semana. También es útil con el modelado, donde los modelos se pueden usar para predecir un día específico (por ejemplo, el miércoles) o la secuencia completa.

Dividiremos los datos en semanas estándar, trabajando hacia atrás desde el conjunto de datos de prueba.

El último año de los datos es 2010 y el primer domingo de 2010 fue el 3 de enero. Los datos terminan a mediados de noviembre de 2010 y el último sábado más cercano en los datos es el 20 de noviembre. Esto da 46 semanas de datos de prueba.

La primera y la última fila de datos diarios para el conjunto de datos de prueba se proporcionan a continuación para su confirmación

2010-01-03,2083.4539999999984,191.61000000000055,350992.12000000034,8703.600000000033,3842.0,4920.0,10074.0,15888.233355799992
...
2010-11-20,2197.006000000004,153.76800000000028,346475.9999999998,9320.20000000002,4367.0,2947.0,11433.0,17869.76663959999

Los datos diarios comienzan a finales de 2006.

El primer domingo en el conjunto de datos es el 17 de diciembre, que es la segunda fila de datos. La organización de los datos en semanas estándar proporciona 159 semanas estándar completas para entrenar un modelo predictivo. La función split_dataset() a continuación divide los datos diarios en conjuntos de entrenamiento y prueba y organiza cada uno en semanas estándar.

Se utilizan compensaciones de fila específicas para dividir los datos utilizando el conocimiento del conjunto de datos. Luego, los conjuntos de datos divididos se organizan en datos semanales mediante la función NumPy split()

# split a univariate dataset into train/test sets
def split_dataset(data):
 # split into standard weeks
 train, test = data[1:-328], data[-328:-6]
 # restructure into windows of weekly data
 train = array(split(train, len(train)/7))
 test = array(split(test, len(test)/7))
 return train, test

Podemos probar esta función cargando el conjunto de datos diario e imprimiendo la primera y la última fila de datos tanto del tren como de los conjuntos de prueba para confirmar que cumplen con las expectativas anteriores

El ejemplo de código completo se muestra a continuación.


# split into standard weeks
from numpy import split
from numpy import array
from pandas import read_csv
 
# split a univariate dataset into train/test sets
def split_dataset(data):
 # split into standard weeks
 train, test = data[1:-328], data[-328:-6]
 # restructure into windows of weekly data
 train = array(split(train, len(train)/7))
 test = array(split(test, len(test)/7))
 return train, test
 
# load the new file
dataset = read_csv('household_power_consumption_days.csv', header=0, infer_datetime_format=True, parse_dates=['datetime'], index_col=['datetime'])
train, test = split_dataset(dataset.values)
# validate train data
print(train.shape)
print(train[0, 0, 0], train[-1, -1, 0])
# validate test
print(test.shape)
print(test[0, 0, 0], test[-1, -1, 0])


Ejecutar el ejemplo muestra que, de hecho, el conjunto de datos del tren tiene 159 semanas de datos, mientras que el conjunto de datos de prueba tiene 46 semanas.

Podemos ver que la potencia activa total para el tren y el conjunto de datos de prueba para la primera y la última fila coinciden con los datos de las fechas específicas que definimos como los límites de las semanas estándar para cada conjunto


(159, 7, 8)
3390.46 1309.2679999999998
(46, 7, 8)
2083.4539999999984 2197.006000000004

Validación Walk-Forward

Los modelos se evaluarán utilizando un esquema llamado validación de avance .

Aquí es donde se requiere que un modelo haga una predicción de una semana, luego los datos reales de esa semana se ponen a disposición del modelo para que pueda usarse como base para hacer una predicción en la semana siguiente. Esto es tanto realista en cuanto a cómo se puede usar el modelo en la práctica como beneficioso para los modelos, permitiéndoles hacer uso de los mejores datos disponibles.

Podemos demostrar esto a continuación con la separación de los datos de entrada y los datos de salida/predichos.

Input, Predict
[Week1] Week2
[Week1 + Week2] Week3
[Week1 + Week2 + Week3] Week4

El enfoque de validación de avance para evaluar modelos predictivos en este conjunto de datos se implementa a continuación y se llama evaluar_modelo() .

El nombre de una función se proporciona para el modelo como el argumento » model_func «. Esta función es responsable de definir el modelo, ajustar el modelo a los datos de entrenamiento y hacer un pronóstico de una semana.

Los pronósticos hechos por el modelo luego se evalúan contra el conjunto de datos de prueba utilizando la función de evaluación_previsiones() previamente definida .

# evaluate a single model
def evaluate_model(model_func, train, test):
 # history is a list of weekly data
 history = [x for x in train]
 # walk-forward validation over each week
 predictions = list()
 for i in range(len(test)):
 # predict the week
 yhat_sequence = model_func(history)
 # store the predictions
 predictions.append(yhat_sequence)
 # get real observation and add to history for predicting the next week
 history.append(test[i, :])
 predictions = array(predictions)
 # evaluate predictions days for each week
 score, scores = evaluate_forecasts(test[:, :, 0], predictions)
 return score, scores

Una vez que tenemos la evaluación de un modelo, podemos resumir el rendimiento.

La función a continuación denominada resume_scores() mostrará el rendimiento de un modelo en una sola línea para facilitar la comparación con otros modelos.


# summarize scores
def summarize_scores(name, score, scores):
 s_scores = ', '.join(['%.1f' % s for s in scores])
 print('%s: [%.3f] %s' % (name, score, s_scores))

Ahora tenemos todos los elementos para comenzar a evaluar modelos predictivos en el conjunto de datos.

Análisis de autocorrelación

La correlación estadística resume la fuerza de la relación entre dos variables.

Podemos suponer que la distribución de cada variable se ajusta a una distribución gaussiana (curva de campana). Si este es el caso, podemos usar el coeficiente de correlación de Pearson para resumir la correlación entre las variables.

El coeficiente de correlación de Pearson es un número entre -1 y 1 que describe una correlación negativa o positiva respectivamente. Un valor de cero indica que no hay correlación.

Podemos calcular la correlación de las observaciones de series de tiempo con observaciones con pasos de tiempo anteriores, llamados retrasos. Debido a que la correlación de las observaciones de la serie temporal se calcula con valores de la misma serie en momentos anteriores, esto se denomina correlación serial o autocorrelación.

Una gráfica de la autocorrelación de una serie de tiempo por retraso se denomina función de autocorrelación , o el acrónimo ACF. Esta gráfica a veces se denomina correlograma o gráfica de autocorrelación.

Una función de autocorrelación parcial o PACF es un resumen de la relación entre una observación en una serie de tiempo con observaciones en pasos de tiempo anteriores con las relaciones de las observaciones intermedias eliminadas.

La autocorrelación para una observación y una observación en un paso de tiempo anterior se compone tanto de la correlación directa como de las correlaciones indirectas. Estas correlaciones indirectas son una función lineal de la correlación de la observación, con observaciones en pasos de tiempo intermedios.

Son estas correlaciones indirectas las que la función de autocorrelación parcial busca eliminar. Sin entrar en matemáticas, esta es la intuición de la autocorrelación parcial.

Podemos calcular gráficos de autocorrelación y autocorrelación parcial utilizando las funciones de modelos estadísticos plot_acf() y plot_pacf() respectivamente.

Para calcular y trazar la autocorrelación, debemos convertir los datos en una serie de tiempo univariante. Específicamente, la energía total diaria observada consumida.

La función to_series() a continuación tomará los datos multivariados divididos en ventanas semanales y devolverá una sola serie temporal univariada.

def to_series(data):
 # extract just the total power from each week
 series = [week[:, 0] for week in data]
 # flatten into a single series
 series = array(series).flatten()
 return series

Podemos llamar a esta función para el conjunto de datos de entrenamiento preparado.

Primero, se debe cargar el conjunto de datos de consumo de energía diario.

# load the new file
dataset = read_csv('household_power_consumption_days.csv', header=0, infer_datetime_format=True, parse_dates=['datetime'], index_col=['datetime'])


Luego, el conjunto de datos debe dividirse en conjuntos de entrenamiento y prueba con la estructura de ventana de semana estándar.

# split into train and test
train, test = split_dataset(dataset.values)

A continuación, se puede extraer una serie de tiempo univariante del consumo de energía diario del conjunto de datos de entrenamiento.

# convert training data into a series
series = to_series(train)


Entonces podemos crear una sola figura que contenga un gráfico ACF y PACF. Se puede especificar el número de pasos de tiempo de retraso. Arreglaremos esto para que sea un año de observaciones diarias, o 365 días.

# plots
pyplot.figure()
lags = 365
# acf
axis = pyplot.subplot(2, 1, 1)
plot_acf(series, ax=axis, lags=lags)
# pacf
axis = pyplot.subplot(2, 1, 2)
plot_pacf(series, ax=axis, lags=lags)
# show plot
pyplot.show()

El ejemplo completo se muestra a continuación.

Esperaríamos que la energía consumida mañana y la próxima semana dependa de la energía consumida en los días anteriores. Como tal, esperaríamos ver una fuerte señal de autocorrelación en los gráficos ACF y PACF.

# acf and pacf plots of total power
from numpy import split
from numpy import array
from pandas import read_csv
from matplotlib import pyplot
from statsmodels.graphics.tsaplots import plot_acf
from statsmodels.graphics.tsaplots import plot_pacf
 
# split a univariate dataset into train/test sets
def split_dataset(data):
 # split into standard weeks
 train, test = data[1:-328], data[-328:-6]
 # restructure into windows of weekly data
 train = array(split(train, len(train)/7))
 test = array(split(test, len(test)/7))
 return train, test
 
# convert windows of weekly multivariate data into a series of total power
def to_series(data):
 # extract just the total power from each week
 series = [week[:, 0] for week in data]
 # flatten into a single series
 series = array(series).flatten()
 return series
 
# load the new file
dataset = read_csv('household_power_consumption_days.csv', header=0, infer_datetime_format=True, parse_dates=['datetime'], index_col=['datetime'])
# split into train and test
train, test = split_dataset(dataset.values)
# convert training data into a series
series = to_series(train)
# plots
pyplot.figure()
lags = 365
# acf
axis = pyplot.subplot(2, 1, 1)
plot_acf(series, ax=axis, lags=lags)
# pacf
axis = pyplot.subplot(2, 1, 2)
plot_pacf(series, ax=axis, lags=lags)
# show plot
pyplot.show()

Ejecutar el ejemplo crea una sola figura con gráficos ACF y PACF.

Las tramas son muy densas y difíciles de leer. Sin embargo, es posible que podamos ver un patrón de autorregresión familiar.

También podríamos ver algunas observaciones de retraso significativas dentro de un año. La investigación adicional puede sugerir un componente de autocorrelación estacional, lo que no sería un hallazgo sorprendente.

Podemos ampliar la gráfica y cambiar el número de observaciones de retraso de 365 a 50.

lags = 50

Volver a ejecutar el ejemplo de código con los resultados de este cambio es una versión ampliada de los gráficos con mucho menos desorden.

Podemos ver claramente un patrón de autorregresión familiar en las dos gráficas. Este patrón se compone de dos elementos:

  • ACF : una gran cantidad de observaciones de retraso significativas que se degradan lentamente a medida que aumenta el retraso.
  • PACF : algunas observaciones de retraso significativas que caen abruptamente a medida que aumenta el retraso.

La gráfica ACF indica que hay un fuerte componente de autocorrelación, mientras que la gráfica PACF indica que este componente es distinto para las primeras aproximadamente siete observaciones de retraso.

Esto sugiere que un buen modelo inicial sería un AR(7); que es un modelo de autorregresión con siete observaciones de retraso utilizadas como entrada.

Podemos desarrollar un modelo de autorregresión para series univariadas de consumo diario de energía.

La biblioteca de Statsmodels proporciona múltiples formas de desarrollar un modelo AR, como usar las clases AR, ARMA, ARIMA y SARIMAX.

Usaremos la implementación ARIMA ya que permite una fácil expansión en diferenciación y promedio móvil.

En primer lugar, los datos históricos compuestos por semanas de observaciones anteriores deben convertirse en una serie de tiempo univariada de consumo de energía diario. Podemos usar la función to_series() desarrollada en la sección anterior.

#convert history into a univariate series

series = to_series(history)


A continuación, se puede definir un modelo ARIMA pasando argumentos al constructor de la clase ARIMA.

Especificaremos un modelo AR(7), que en notación ARIMA es ARIMA(7,0,0).

#define the model

model = ARIMA(series, order=(7,0,0))


A continuación, el modelo se puede ajustar a los datos de entrenamiento.

#fit the model

model_fit = model.fit()


Ahora que el modelo se ha ajustado, podemos hacer una predicción.

Se puede hacer una predicción llamando a la función predict() y pasándole un intervalo de fechas o índices relativos a los datos de entrenamiento. Usaremos índices comenzando con el primer paso de tiempo más allá de los datos de entrenamiento y extendiéndolo seis días más, dando un total de un período de pronóstico de siete días más allá del conjunto de datos de entrenamiento.

#make forecast

yhat = model_fit.predict(len(series), len(series)+6)


Podemos envolver todo esto en una función a continuación llamada arima_forecast() que toma el historial

y devuelve un pronóstico de una semana.

arima forecast

def arima_forecast(history):
# convert history into a univariate series
series = to_series(history)
# define the model
model = ARIMA(series, order=(7,0,0))
# fit the model
model_fit = model.fit()
# make forecast
yhat = model_fit.predict(len(series), len(series)+6)
return yhat


Esta función se puede utilizar directamente en el arnés de prueba descrito anteriormente.

El ejemplo completo se muestra a continuación.

# arima forecast
from math import sqrt
from numpy import split
from numpy import array
from pandas import read_csv
from sklearn.metrics import mean_squared_error
from matplotlib import pyplot
from statsmodels.tsa.arima.model import ARIMA
 
# split a univariate dataset into train/test sets
def split_dataset(data):
 # split into standard weeks
 train, test = data[1:-328], data[-328:-6]
 # restructure into windows of weekly data
 train = array(split(train, len(train)/7))
 test = array(split(test, len(test)/7))
 return train, test
 
# evaluate one or more weekly forecasts against expected values
def evaluate_forecasts(actual, predicted):
 scores = list()
 # calculate an RMSE score for each day
 for i in range(actual.shape[1]):
 # calculate mse
 mse = mean_squared_error(actual[:, i], predicted[:, i])
 # calculate rmse
 rmse = sqrt(mse)
 # store
 scores.append(rmse)
 # calculate overall RMSE
 s = 0
 for row in range(actual.shape[0]):
 for col in range(actual.shape[1]):
 s += (actual[row, col] - predicted[row, col])**2
 score = sqrt(s / (actual.shape[0] * actual.shape[1]))
 return score, scores
 
# summarize scores
def summarize_scores(name, score, scores):
 s_scores = ', '.join(['%.1f' % s for s in scores])
 print('%s: [%.3f] %s' % (name, score, s_scores))
 
# evaluate a single model
def evaluate_model(model_func, train, test):
 # history is a list of weekly data
 history = [x for x in train]
 # walk-forward validation over each week
 predictions = list()
 for i in range(len(test)):
 # predict the week
 yhat_sequence = model_func(history)
 # store the predictions
 predictions.append(yhat_sequence)
 # get real observation and add to history for predicting the next week
 history.append(test[i, :])
 predictions = array(predictions)
 # evaluate predictions days for each week
 score, scores = evaluate_forecasts(test[:, :, 0], predictions)
 return score, scores
 
# convert windows of weekly multivariate data into a series of total power
def to_series(data):
 # extract just the total power from each week
 series = [week[:, 0] for week in data]
 # flatten into a single series
 series = array(series).flatten()
 return series
 
# arima forecast
def arima_forecast(history):
 # convert history into a univariate series
 series = to_series(history)
 # define the model
 model = ARIMA(series, order=(7,0,0))
 # fit the model
 model_fit = model.fit()
 # make forecast
 yhat = model_fit.predict(len(series), len(series)+6)
 return yhat
 
# load the new file
dataset = read_csv('household_power_consumption_days.csv', header=0, infer_datetime_format=True, parse_dates=['datetime'], index_col=['datetime'])
# split into train and test
train, test = split_dataset(dataset.values)
# define the names and functions for the models we wish to evaluate
models = dict()
models['arima'] = arima_forecast
# evaluate each model
days = ['sun', 'mon', 'tue', 'wed', 'thr', 'fri', 'sat']
for name, func in models.items():
 # evaluate and get scores
 score, scores = evaluate_model(func, train, test)
 # summarize scores
 summarize_scores(name, score, scores)
 # plot scores
 pyplot.plot(days, scores, marker='o', label=name)
# show plot
pyplot.legend()
pyplot.show()


Ejecutar el ejemplo primero imprime el rendimiento del modelo AR(7) en el conjunto de datos de prueba.

Nota : Sus resultados pueden variar dada la naturaleza estocástica del algoritmo o procedimiento de evaluación, o diferencias en la precisión numérica. Considere ejecutar el ejemplo varias veces y compare el resultado promedio.

Podemos ver que el modelo alcanza el RMSE general de alrededor de 381 kilovatios.

Este modelo tiene habilidad en comparación con los modelos de pronóstico ingenuos, como un modelo que pronostica la semana siguiente utilizando observaciones del mismo período hace un año que logró un RMSE general de aproximadamente 465 kilovatios.

arima: [381.636] 393.8, 398.9, 357.0, 377.2, 393.9, 306.1, 432.2

También se crea un diagrama de líneas del pronóstico, que muestra el RMSE en kilovatios para cada uno de los siete tiempos de anticipación del pronóstico.

Podemos ver un patrón interesante.

Podríamos esperar que los plazos de entrega más tempranos sean más fáciles de pronosticar que los plazos de entrega posteriores, ya que el error en cada uno de los plazos de entrega sucesivos se compone.

En cambio, vemos que el viernes (tiempo de entrega +6) es el más fácil de pronosticar y el sábado (tiempo de entrega +7) es el más difícil de pronosticar. También podemos ver que los plazos de entrega restantes tienen un error similar en el rango medio a alto de 300 kilovatios.

Extensiones

En esta sección se enumeran algunas ideas para ampliar este articulo que tal vez desee explorar.

  • Sintoniza ARIMA . Los parámetros del modelo ARIMA no fueron ajustados. Explore o busque un conjunto de parámetros ARIMA (q, d, p) para ver si el rendimiento se puede mejorar aún más.
  • Explora AR estacional . Explore si el rendimiento del modelo AR se puede mejorar al incluir elementos de autorregresión estacional. Esto puede requerir el uso de un modelo SARIMA.
  • Explore la preparación de datos . El modelo se ajustó directamente a los datos sin procesar. Explore si la estandarización o la normalización o incluso las transformaciones de potencia pueden mejorar aún más la habilidad del modelo AR.

Fuente: https://machinelearningmastery.com/how-to-develop-an-autoregression-forecast-model-for-household-electricity-consumption/

Tardaran en llegar los medidores de glucosa sin pinchazos


Si desgraciadamente es usted diabético, no espere por el momento a que su reloj inteligente reemplace sus agujas. Lamentablemente entre las señales pequeñas, los obstáculos normativos, el color de la piel y la duración de la batería, hay mucho terreno por recorrer antes de que un reloj inteligente pueda medir los niveles de azúcar en la sangre.



Recientemente, Bloomberg publicó una historia que encendió la esfera de la tecnología de la salud. Citando información privilegiada, afirmó que Apple había alcanzado un hito importante en el control no invasivo de la glucosa en sangre que podría revolucionar el tratamiento de la diabetes tal como lo conocemos. Pero aunque esta tecnología esta de moda, no la veremos llegar al Apple Watch, ni a ningún dispositivo portátil de consumo, durante varios años.

Al igual que otros tipos de tecnología de salud emergente, el monitoreo no invasivo de glucosa en sangre tiene obstáculos tanto técnicos como normativos que superar. Pero incluso si Big Tech y los investigadores encontraran una solución viable mañana, los expertos dicen que la tecnología resultante probablemente no reemplazará las pruebas de punción digital. Resulta que, en primer lugar, puede que ni siquiera sea el uso más realista o útil de la tecnología.

Tecnologia sin pinchazos

La monitorización no invasiva de glucosa en sangre es tal como suena. Mide los niveles de azúcar en la sangre sin necesidad de extraer sangre, romper la piel o causar otros tipos de dolor o trauma. Hay varias razones por las que vale la pena seguir con esta tecnología, pero la principal es el tratamiento de la diabetes.

Cuando se tiene diabetes, su cuerpo no puede regular de manera efectiva el azúcar en la sangre porque no produce suficiente insulina (tipo 1) o se vuelve resistente a la insulina con el tiempo (tipo 2). Para controlar su condición, los pacientes con diabetes Tipo 1 y Tipo 2 deben controlar sus niveles de azúcar en la sangre a través de medidas típicamente invasivas, como una prueba de punción en el dedo o un monitor continuo de glucosa (en español MCG o en ingles CGM). Las pruebas de pinchazo en el dedo consisten en pinchar el dedo con una aguja y colocar una gota de sangre en una tira reactiva. Un CGM incorpora un sensor debajo de la piel, lo que permite a los pacientes controlar sus niveles de azúcar en la sangre en tiempo real, las 24 horas del día.

La monitorización no invasiva de los niveles de glucosa en sangre ha sido buscada durante muchos años, ya que sería más cómodo para los pacientes y permitiría un monitoreo remoto.

Actualmente, existen dos métodos principales para lograr esto: medir la glucosa en fluidos corporales como la orina o las lágrimas, y utilizar la espectroscopia para medir cómo la luz se refleja en el cuerpo. Esta última técnica es similar a la utilizada en relojes inteligentes y otros dispositivos para medir la frecuencia cardíaca y otros parámetros. Sin embargo, aplicarla a la glucosa en sangre es mucho más complicado. Aunque la investigación ha estado en curso durante décadas, aún no se ha encontrado una solución confiable para el monitoreo no invasivo de la glucosa en sangre.

Los relojes inteligentes tienen dificultades para medir de manera precisa los niveles de glucosa en sangre debido a varias limitaciones:

  • La señal de glucosa es muy pequeña y se ve afectada por sustancias similares en el cuerpo, como el agua.
  • Factores externos como la luz, el movimiento y el contacto deficiente de la piel con el sensor también pueden afectar las mediciones.
  • Además, la luz infrarroja emitida por los sensores puede confundirse con el calor del entorno. El uso de múltiples longitudes de onda de luz puede ayudar a aislar la señal de glucosa, pero esto presenta desafíos adicionales, como la necesidad de algoritmos más complejos y el agotamiento de la batería.
  • Los sensores ópticos también pueden tener problemas de precisión en personas con piel más oscura y tatuajes.
  • Problemas regulatorios: La FDA (Food and Drug Administration) regula y supervisa alimentos, medicamentos, productos médicos, cosméticos, productos veterinarios y productos biológicos en EE.UU. Su objetivo es proteger la salud pública estableciendo estándares de seguridad y calidad. También aprueba y regula ensayos clínicos, medicamentos y dispositivos médicos. Obtener la autorización de la FDA para dispositivos médicos de este tipo puede ser un proceso largo y costoso debido a las pruebas clínicas requeridas.

Por tanto, aunque la tecnología está evolucionando y mejorando, es poco probable que los relojes inteligentes reemplacen los métodos establecidos, como las pruebas de pinchazo en el dedo o los monitores continuos de glucosa, en el corto plazo.

Sin embargo, se espera que los relojes inteligentes puedan ser útiles para el seguimiento del estado físico, el bienestar y como herramientas de detección de prediabetes. La tecnología podría alertar a las personas sobre posibles signos de prediabetes y proporcionar una imagen más completa de su salud. Aunque llevará tiempo desarrollar sensores no invasivos precisos y obtener la aprobación regulatoria, se espera que la investigación y la tecnología avancen en esta dirección en el futuro.

CGM

Por el momento, hasta que no evolucione la tecnología para medir la glucosa en sangre nos tendremos que conformar con los monitores continuo de glucosa en sangre (CGM, por sus siglas en inglés) , dispositivos que actualmente ya se utilizan para medir los niveles de glucosa en sangre de forma continua a lo largo del día y la noche. A diferencia de los medidores de glucosa tradicionales, que proporcionan una lectura puntual en un momento específico, un CGM nos da información en tiempo real sobre tus niveles de glucosa y cómo están cambiando con el tiempo.

El CGM consta de tres componentes principales:

  1. Sensor: Es un pequeño dispositivo que se coloca debajo de la piel, generalmente en el abdomen o el brazo. El sensor contiene una pequeña aguja o filamento que mide los niveles de glucosa en el líquido intersticial (el líquido que rodea las células) en lugar de medir directamente los niveles de glucosa en sangre.
  2. Transmisor: El transmisor se conecta al sensor y envía los datos de glucosa recopilados a un receptor o a un dispositivo compatible, como un teléfono inteligente, un reloj inteligente o una bomba de insulina. El transmisor generalmente utiliza tecnología inalámbrica, como Bluetooth, para transmitir los datos.
  3. Receptor o dispositivo compatible: El receptor recibe los datos de glucosa del transmisor y muestra las lecturas en tiempo real, así como también proporciona alarmas y alertas cuando los niveles de glucosa están fuera del rango objetivo establecido.

El CGM mide continuamente los niveles de glucosa en el líquido intersticial y los convierte en lecturas de glucosa. Estas lecturas se muestran normalmente en una app en un smartphone, aunque también es posible verlas directamente en algunos modelos de relojes inteligentes ( Apple watch, Samsung o Garmin son de los mas conocidos ) para visualizarlas en forma de gráfica, que permiten ver cómo los niveles de glucosa están cambiando a lo largo del tiempo. También existe la posibilidad en algunos modelos de recibir las lecturas en monitores específicos en lugar de usar el móvil pero quizás esto no sea realmente interesante porque casi todos los sistemas de CGM también tienen funciones de alerta que avisan cuando los niveles de glucosa están demasiado altos o demasiado bajos, lo que puede ayudarte a tomar medidas adecuadas, como ajustar su plan de alimentación o administrar insulina.


Los monitores continuos de glucosa (CGM, por sus siglas en inglés) a pesar de que estan en continua evolución pueden tener algunos inconvenientes destacando especialmente el alto costo y la incomodidad de portarlo de forma permanente en nuestro cuerpo.

A continuación presentamos algunas barreras para su adopción:

  1. Precisión: Aunque los CGM han mejorado significativamente en términos de precisión en los últimos años, todavía pueden presentar ciertas discrepancias en comparación con las mediciones de glucosa en sangre tradicionales. Esto puede resultar en lecturas inexactas, lo que a su vez puede afectar la toma de decisiones en el manejo de la diabetes.
  2. Calibración y mantenimiento: Los CGM requieren calibración periódica para garantizar una lectura precisa de los niveles de glucosa. Esto implica la realización de pruebas de glucosa en sangre y la introducción de los valores en el dispositivo. Además, los sensores deben reemplazarse cada pocos días, lo que puede resultar en una carga adicional de trabajo y costos asociados.
  3. Interferencias y errores: Los CGM pueden ser susceptibles a interferencias externas, como la presencia de sustancias químicas o medicamentos que pueden afectar la precisión de las mediciones. Además, pueden ocurrir errores técnicos o fallas en el dispositivo que puedan afectar su funcionamiento adecuado.
  4. ALTO Costo: Los CGM pueden ser costosos, especialmente si no están cubiertos por el seguro médico. Este costo ademas se ve limitada por su durabilidad ( deben cambiarde coda 15 dias o asi). Esto puede limitar el acceso a esta tecnología para algunas personas con diabetes que podrían beneficiarse de su uso.
  5. Dificultades en la colocación y uso: Algunas personas pueden encontrar complicaciones al insertar los sensores o usar los dispositivos CGM de manera adecuada. Esto puede requerir práctica y orientación para garantizar un uso efectivo y preciso.

Es importante tener en cuenta que, a pesar de estos inconvenientes, los CGM también ofrecen muchas ventajas en términos de monitoreo continuo y mejor control de la diabetes. Cada persona debe evaluar los pros y los contras en función de sus necesidades y preferencias individuales. Asimismo destacar que, aunque los CGM son herramientas útiles para el monitoreo continuo de glucosa, aún es necesario confirmar las lecturas con un medidor de glucosa tradicional antes de tomar decisiones relacionadas con el tratamiento. Además, es recomendable consultar con un médico o especialista en diabetes para obtener una guía adecuada sobre cómo interpretar y utilizar la información proporcionada por el CGM.