Este repositorio contiene dos implementaciones alternativas para pronosticar la predicción de potencia fotovoltaica basada en datos meteorológicos. Fue desarrollado para mi tesis de licenciatura que compara esos dos enfoques. Dos fuentes de datos sirven como datos de muestra de clima y potencia de salida.
Recomiendo Pipenv para configurar el proyecto. Con Pipenv instalado Ejecutar pipenv install desde la raíz del proyecto e instalará todas las dependencias necesarias. Luego use pipenv shell para ingresar al shell donde todas las dependencias estarán disponibles o simplemente pipenv run <command> para ejecutar un comando específico.
Si no usa Pipenv, las dependencias se especifican en PipFile y las versiones que uso se pueden encontrar en PipFile.lock.
Para usar el servicio PVWATTS descrito más adelante, debe obtener una clave API. Luego, debe configurarlo como variable de entorno (o ponerlo en el código directamente). Si usa Pipenv, esto se puede hacer en un archivo .env .
Se pueden encontrar ejemplos sobre cómo usar el proyecto en los archivos de ejemplo en el directorio raíz. Puede ejecutar directamente esos archivos después de completar los pasos necesarios para obtener datos descritos en la siguiente sección.
pipenv run python example_arima_pvwatts.py
pipenv run python example_arima_uq.py
pipenv run python example_svr_pvwatts.py
pipenv run python example_svr_uq.py
Para trazar con matplotlib, Pandas emite una advertencia futura, por lo que puse la siguiente línea después de las importaciones:
from pandas . plotting import register_matplotlib_converters ; register_matplotlib_converters ()Hay dos platos de datos para los que hay un importador disponible que analiza los datos en el formato correcto. Por supuesto, también es posible usar otras fuentes. En primer lugar, hay un envoltorio de Pvwatts y, en segundo lugar, para los datos obtenidos de UQ Solar.
Los datos preparados de PvWatts se parecen a esto:
| tiempo | copa | WSPD | fuerza |
|---|---|---|---|
| 2019-06-20 06:00:00 | 16.0 | 0.0 | 957.201 |
| 2019-06-20 07:00:00 | 18.0 | 1.5 | 1648.060 |
| 2019-06-20 08:00:00 | 21.0 | 3.1 | 2260.658 |
| 2019-06-20 09:00:00 | 23.0 | 4.1 | 2647.271 |
| 2019-06-20 10:00:00 | 24.0 | 2.6 | 2838.976 |
Se puede obtener a través de la API pública de Pvwatts. Para obtener una clave API, debe registrarse en la red de desarrolladores NREL. La clave API debe colocarse en la variable de entorno PVWATTS_API_KEY . Alternativamente, puede insertarlo en PVWATTS directamente. Cuando se haga, puedes usar
from importers import pvwatts
data = pvwatts . load () Esto llama a la API y analiza el resultado como un marco de datos PANDAS que puede pasar a los módulos de pronóstico. También puede pasar los siguientes parámetros opcionales para load :
Para obtener información sobre estos parámetros, consulte la descripción de la API PVWATTS V6. Todos los parámetros tienen valores predeterminados, por lo que también es posible llamar al método sin parámetros. Los datos de retorno se indexan utilizando DateTimeIndex. Dado que PVWATTS no especifica las fechas, pero siempre devuelve datos durante todo un año, el año 2019 se establecerá para cada marcado de datos devuelto de este módulo.
Si tiene una respuesta de PVWATTS JSON guardada en un archivo JSON, también es posible analizar ese archivo directamente utilizando el siguiente método de conveniencia:
pvwatts . load_from_json ( 'filepath.json' )Los datos preparados de UQ Solar Live Feed se parecen a esto:
| tiempo | avión | humedad | velocidad del viento | winddirección | fuerza |
|---|---|---|---|---|---|
| 2015-06-20 07:00:00 | 9.27 | 75.24 | 1.72 | 191.47 | 25302.00 |
| 2015-06-20 08:00:00 | 11.28 | 68.72 | 2.14 | 201.45 | 78240.83 |
| 2015-06-20 09:00:00 | 13.38 | 59.02 | 2.59 | 214.77 | 128523.08 |
| 2015-06-20 10:00:00 | 14.49 | 54.19 | 2.92 | 201.67 | 162968.83 |
| 2015-06-20 11:00:00 | 15.65 | 51.89 | 2.34 | 203.23 | 172535.83 |
Se puede descargar en el sitio web de Live Feed. Elija un PV Site y una PV Array desde la barra lateral a la derecha. Luego haga clic en Download Data y luego Download Daily Logs . A partir de ahí, puede especificar un rango de fechas (recomiendo un año), y luego descargar un archivo Power & Energy , así como un archivo Weather . Asegúrese de descargar ambos con los mismos rangos de fecha especificados.
Ahora puedes usar
from importers import uq
data = uq . load ( 'power_file.csv' , 'weather_file.csv' ) y sustituya ambos parámetros con las rutas de archivo para cada archivo respectivo. El método load combina ambos archivos nuevamente en un marco de datos PANDAS, listo para pasar a un módulo de pronóstico.
Ahora que hay un marco de datos con características y datos de potencia, puede hacer pronósticos. Ambos importadores devuelven un marco de datos que tiene diferentes características, pero ambos tienen una columna power que representa la salida de potencia.
Dado que los datos de ambos importadores tienen un DateTimeIndex, se puede dividir en datos de entrenamiento y prueba como este:
training_data = data [ '20190601' : '20190607' ] # first week of june 2019
testing_data = data [ '20190608' : '20190614' ] # second week of june 2019 Aquí las fechas se convierten de cuerdas implícitamente. Por ejemplo, '20190601' representa 2019/06/01 o 01 de junio de 2019.
Este algoritmo utiliza la implementación de Scikit-Learn de SVR que se basa en libsvm. Para usarlo, la siguiente clase está disponible:
from predictors . svr_model import SVRModelHacer una predicción sin escalar los datos:
model = SVRModel ( scaling = False )
model . fit ( training_data , kernel = 'rbf' , C = 1e3 , gamma = 0.1 , epsilon = 0.1 )
model . predict ( testing_data ) # returns the prediction data frame containing the testing features and the power prediction
model . prediction . power # use this to access the power prediction Filtrar la columna power de la trama testing_data no es necesaria, la clase SVRModel lo hace automáticamente. Opcionalmente, es posible pasar filter=['airtemp', 'humidity'] o similar al fit para restringir las características utilizadas para el pronóstico. No es necesario filtrar los datos manualmente de esta manera.
Las variables SVR kernel , C , gamma y epsilon son todas opcionales, todas tienen valores predeterminados.
Para dejar que el modelo escala los datos antes de aplicar la regresión, puede establecer el parámetro de escala en True (este es el valor predeterminado):
model = svr_model ( base_data = data , scaling = True ) De esa manera, debe especificar base_data , que puede ser un conjunto de datos para otro año. Esto no se utilizará para la regresión, únicamente para ajustar un objeto scaler factible. Para obtener más información sobre eso, consulte la implementación de StandartScaler de Scikit-Learn.
Este algoritmo hace uso en el paquete Pmdarima (anteriormente Pyramid-Arima). Se puede usar importando la clase necesaria:
from predictors . arima_model import ARIMAModelAhora para hacer una predicción sin usar variables exógenas haga lo siguiente:
model = ARIMAModel () # scaling is set to true automatically
model . fit ( training_data , order = ( 2 , 1 , 4 ), seasonal_order ( 3 , 1 , 2 , 24 ), use_exogenous = False )
model . predict ( hours = 48 ) # returns the prediction
model . prediction . power # use this to access the power predictionn Proporcionar características de prueba no es necesario porque el modelo estaba ajustado sin variables exógenas. En este caso, el DataFrame devuelto solo tendrá una columna power . El order especifica los parámetros (p,d,q) del modelo. The seasonal_order especifica los parámetros (P,D,Q,s) . El parámetro de escala se puede configurar al crear el modelo, de forma predeterminada se establece en True , pero puede no ser establecido con:
model = ARIMAModel ( scaling = false )Si desea agregar variables exógenas, establezca este parámetro:
model . fit ( training_data , order = ( 2 , 1 , 4 ), seasonal_order ( 3 , 1 , 2 , 24 ), use_exogenous = True ) # use_exogenous is True by default
model . predict ( testing_data = testing_data ) De esta manera, debe especificar testing_data al predecir. La columna power se eliminará automáticamente al hacer la predicción real. La predicción DataFrame ahora tendrá las columnas Testing_Data donde la columna power contiene los valores predichos.
Si desea dejar que el algoritmo encuentre automáticamente los parámetros p, q, P and Q apropiados use la siguiente llamada:
model . fit_auto ( training_data , p = ( 0 , 5 ), q = ( 0 , 5 ), P = ( 0 , 5 ), Q = ( 0 , 5 ), d = 1 , D = 1 ) Las tuplas definen rangos en los que el algoritmo buscará parámetros óptimos. El d y D se pueden dejar fuera para determinar automáticamente esos parámetros también. Al igual que con el método fit , use_exogenous se establecerá en True de forma predeterminada, pero también se puede especificar para ser False .
Como es posible con el SVRModel , también puede pasar una matriz de filtro para que fit y fit_auto para restringir qué características deben incluirse en el proceso de pronóstico.