Nonintrusive Load Monitoring (NILM)

Begonnen von plin, 07 November 2020, 16:56:40

Vorheriges Thema - Nächstes Thema

ch.eick

Zitat von: plin am 26 Januar 2021, 13:10:05
Mein Wasserzählerableser beschäftigt mich im Moment mehr (habe jetzt die zweite kaputte SD-Karte).
Ich habe da auch noch einen Wasserzähler und einen Wärmemengenzähler, beides an entfernten Stellen. Was gäbe es da denn für Möglichkeiten?

Zitat
Und die KI-basierte Prognose der Solarerträge ...
Da bin ich ja auch anwesend, bist Du mit Ki schon weiter gekommen?
RPI4; Docker; CUNX; Eltako FSB61NP; SamsungTV H-Serie; Sonos; Vallox; Luxtronik; 3x FB7490; Stromzähler mit DvLIR; wunderground; Plenticore 10 mit BYD; EM410; SMAEM; Modbus TCP
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/ch.eick

plin

Zitat von: ch.eick am 26 Januar 2021, 16:23:55
Ich habe da auch noch einen Wasserzähler und einen Wärmemengenzähler, beides an entfernten Stellen. Was gäbe es da denn für Möglichkeiten?
Die Kurzfassung:
https://forum.fhem.de/index.php/topic,115506.0.html
https://github.com/jomjol/AI-on-the-edge-device
FHEM1 (Main) Raspi4 mit CUL, Homematic, SDUINO 433/OOK, zentrale Steuerung
FHEM2 (Keller) x86 mit CUL/hmland, IP-basierte Module
FHEM3 (Erdgeschoss) Raspi2 mit SDUINO 868/GFSK
FHEM4 (Hausanschlussraum), USV und OBIS-Modul
FHEM5 (Docker) mit FHEM2FHEM, InfluxDB

plin

Zitat von: ch.eick am 26 Januar 2021, 16:23:55
Da bin ich ja auch anwesend, bist Du mit Ki schon weiter gekommen?

Mein aktueller Stand mit multiple linear regression sieht so aus:

#!/usr/bin/env python
# coding: utf-8

# Version die eine Vorhersage auf Basis der Messwerte (ohne Zeitangabe) ermittelt, alle Daten in dwdfull, inkl. DB Update

import pandas as pd
import numpy as np
from sqlalchemy import create_engine
import pymysql
import sklearn as sk

# für alle relevanten Solar-Tabellen
db_connection_str = 'mysql+pymysql://fhem:fhem@192.168.3.10/Solar'
db_connection = create_engine(db_connection_str)

# alle Wetterdaten
dfdwd = pd.read_sql('SELECT * FROM dwdfull', con=db_connection)

dfall = dfdwd
# Rad1h = Globale Einstrahlung
# Neff  = Effektive Wolkendecke
# R101  = Niederschlagswahrscheinlichkeit> 0,1 mm während der letzten Stunde
# SunD1 = Sonnenscheindauer während der letzten Stunde
# VV    = Sichtweite
# N     = Gesamte Wolkendecke
# DD    = Windrichtung
# RRS1c = Schneeregen-Äquivalent während der letzten Stunde
columns = ['Rad1h','Neff','R101','Azimuth','Altitude','SunD1','VV','N','DD','RRS1c']

# jetzt gehen wir die Analyse an
from sklearn import linear_model
import statsmodels.api as sm

# Regression ermitteln
X = dfall[columns]
Y = dfall['yield']

# with sklearn
regr = linear_model.LinearRegression()
regr.fit(X, Y)

# Ergebnisse ausgeben
print('Intercept: \n', regr.intercept_)
print('Coefficients: \n', regr.coef_)


# with statsmodels
X = sm.add_constant(X) # adding a constant

model = sm.OLS(Y, X).fit()
predictions = model.predict(X)

print_model = model.summary()
print(print_model)

from datetime import date, timedelta
import datetime

today = datetime.datetime.now()
end_date = datetime.datetime.now()
delta = timedelta(days=1)
oneday = timedelta(days=1)
fiveedays = timedelta(days=5)
print(delta)
start_date = end_date - delta
end_date = today + fiveedays
print(start_date)
print(end_date)

# Daten in die Tabelle dwdfull schreiben

while start_date <= end_date:
    print (start_date.strftime("%Y-%m-%d"))
    New_year = str(start_date.year)
    New_month = str(start_date.month)
    New_day = str(start_date.day)
    print ('Forecast für ',start_date)
    query = 'year == "'+New_year+'" and month == "'+New_month+'" and day == "'+New_day+'"'
    dfq = dfall.query(query)[columns]
    for New_hour in range(23):
        parms = dfq.iloc[New_hour].values
        list = parms.reshape(1, -1)
        print ('Predicted yield: ', New_hour, ": ", regr.predict(list))
        mdt = start_date.strftime("%Y-%m-%d")
        forecast = regr.predict(list)[0]
        sql = "UPDATE dwdfull SET Forecast ="+str(forecast)+" WHERE mydatetime like '"+mdt+"%%' AND hour ="+str(New_hour)+";"
        db_connection.execute(str(sql))
    start_date += oneday


Die Tabelle dwdfull ist der umfangreichere Datensatz des DWD, angereichert durch Azimuth/Altitude und den gemittelten stündlichen Ertrag (yield):

+-------------+------------+------+-----+---------------------+-------+
| Field       | Type       | Null | Key | Default             | Extra |
+-------------+------------+------+-----+---------------------+-------+
| mydatetime  | datetime   | NO   | PRI | 0000-00-00 00:00:00 |       |
| mytimestamp | int(11)    | NO   | PRI | NULL                |       |
| year        | int(11)    | NO   |     | NULL                |       |
| PPPP        | float(8,2) | NO   |     | 0.00                |       |
| E_PPP       | float(8,2) | NO   |     | 0.00                |       |
| TX          | float(8,2) | NO   |     | 0.00                |       |
| TTT         | float(8,2) | NO   |     | 0.00                |       |
| E_TTT       | float(8,2) | NO   |     | 0.00                |       |
| Td          | float(8,2) | NO   |     | 0.00                |       |
| E_Td        | float(8,2) | NO   |     | 0.00                |       |
| TN          | float(8,2) | NO   |     | 0.00                |       |
| TG          | float(8,2) | NO   |     | 0.00                |       |
| TM          | float(8,2) | NO   |     | 0.00                |       |
| T5cm        | float(8,2) | NO   |     | 0.00                |       |
| DD          | float(8,2) | NO   |     | 0.00                |       |
| E_DD        | float(8,2) | NO   |     | 0.00                |       |
| FF          | float(8,2) | NO   |     | 0.00                |       |
| E_FF        | float(8,2) | NO   |     | 0.00                |       |
| FX1         | float(8,2) | NO   |     | 0.00                |       |
| FX3         | float(8,2) | NO   |     | 0.00                |       |
| FX625       | float(8,2) | NO   |     | 0.00                |       |
| FX640       | float(8,2) | NO   |     | 0.00                |       |
| FX655       | float(8,2) | NO   |     | 0.00                |       |
| FXh         | float(8,2) | NO   |     | 0.00                |       |
| FXh25       | float(8,2) | NO   |     | 0.00                |       |
| FXh40       | float(8,2) | NO   |     | 0.00                |       |
| FXh55       | float(8,2) | NO   |     | 0.00                |       |
| N           | float(8,2) | NO   |     | 0.00                |       |
| Neff        | float(8,2) | NO   |     | 0.00                |       |
| Nlm         | float(8,2) | NO   |     | 0.00                |       |
| Nh          | float(8,2) | NO   |     | 0.00                |       |
| Nm          | float(8,2) | NO   |     | 0.00                |       |
| Nl          | float(8,2) | NO   |     | 0.00                |       |
| N05         | float(8,2) | NO   |     | 0.00                |       |
| VV          | float(8,2) | NO   |     | 0.00                |       |
| VV10        | float(8,2) | NO   |     | 0.00                |       |
| wwM         | float(8,2) | NO   |     | 0.00                |       |
| wwM6        | float(8,2) | NO   |     | 0.00                |       |
| wwMh        | float(8,2) | NO   |     | 0.00                |       |
| wwMd        | float(8,2) | NO   |     | 0.00                |       |
| ww          | float(8,2) | NO   |     | 0.00                |       |
| ww3         | float(8,2) | NO   |     | 0.00                |       |
| W1W2        | float(8,2) | NO   |     | 0.00                |       |
| wwP         | float(8,2) | NO   |     | 0.00                |       |
| wwP6        | float(8,2) | NO   |     | 0.00                |       |
| wwPh        | float(8,2) | NO   |     | 0.00                |       |
| wwPd        | float(8,2) | NO   |     | 0.00                |       |
| wwZ         | float(8,2) | NO   |     | 0.00                |       |
| wwZ6        | float(8,2) | NO   |     | 0.00                |       |
| wwZh        | float(8,2) | NO   |     | 0.00                |       |
| wwD         | float(8,2) | NO   |     | 0.00                |       |
| wwD6        | float(8,2) | NO   |     | 0.00                |       |
| wwDh        | float(8,2) | NO   |     | 0.00                |       |
| wwC         | float(8,2) | NO   |     | 0.00                |       |
| wwC6        | float(8,2) | NO   |     | 0.00                |       |
| wwCh        | float(8,2) | NO   |     | 0.00                |       |
| wwT         | float(8,2) | NO   |     | 0.00                |       |
| wwT6        | float(8,2) | NO   |     | 0.00                |       |
| wwTh        | float(8,2) | NO   |     | 0.00                |       |
| wwTd        | float(8,2) | NO   |     | 0.00                |       |
| wwS         | float(8,2) | NO   |     | 0.00                |       |
| wwS6        | float(8,2) | NO   |     | 0.00                |       |
| wwSh        | float(8,2) | NO   |     | 0.00                |       |
| wwL         | float(8,2) | NO   |     | 0.00                |       |
| wwL6        | float(8,2) | NO   |     | 0.00                |       |
| wwLh        | float(8,2) | NO   |     | 0.00                |       |
| wwF         | float(8,2) | NO   |     | 0.00                |       |
| wwF6        | float(8,2) | NO   |     | 0.00                |       |
| wwFh        | float(8,2) | NO   |     | 0.00                |       |
| DRR1        | float(8,2) | NO   |     | 0.00                |       |
| RR6c        | float(8,2) | NO   |     | 0.00                |       |
| RRhc        | float(8,2) | NO   |     | 0.00                |       |
| RRdc        | float(8,2) | NO   |     | 0.00                |       |
| RR1c        | float(8,2) | NO   |     | 0.00                |       |
| RRS1c       | float(8,2) | NO   |     | 0.00                |       |
| RRL1c       | float(8,2) | NO   |     | 0.00                |       |
| RR3c        | float(8,2) | NO   |     | 0.00                |       |
| RRS3c       | float(8,2) | NO   |     | 0.00                |       |
| R101        | float(8,2) | NO   |     | 0.00                |       |
| R102        | float(8,2) | NO   |     | 0.00                |       |
| R103        | float(8,2) | NO   |     | 0.00                |       |
| R105        | float(8,2) | NO   |     | 0.00                |       |
| R107        | float(8,2) | NO   |     | 0.00                |       |
| R110        | float(8,2) | NO   |     | 0.00                |       |
| R120        | float(8,2) | NO   |     | 0.00                |       |
| R130        | float(8,2) | NO   |     | 0.00                |       |
| R150        | float(8,2) | NO   |     | 0.00                |       |
| RR1o1       | float(8,2) | NO   |     | 0.00                |       |
| RR1w1       | float(8,2) | NO   |     | 0.00                |       |
| RR1u1       | float(8,2) | NO   |     | 0.00                |       |
| R600        | float(8,2) | NO   |     | 0.00                |       |
| R602        | float(8,2) | NO   |     | 0.00                |       |
| R610        | float(8,2) | NO   |     | 0.00                |       |
| R650        | float(8,2) | NO   |     | 0.00                |       |
| Rh00        | float(8,2) | NO   |     | 0.00                |       |
| Rh02        | float(8,2) | NO   |     | 0.00                |       |
| Rh10        | float(8,2) | NO   |     | 0.00                |       |
| Rh50        | float(8,2) | NO   |     | 0.00                |       |
| Rd00        | float(8,2) | NO   |     | 0.00                |       |
| Rd02        | float(8,2) | NO   |     | 0.00                |       |
| Rd10        | float(8,2) | NO   |     | 0.00                |       |
| Rd50        | float(8,2) | NO   |     | 0.00                |       |
| SunD        | float(8,2) | NO   |     | 0.00                |       |
| RSunD       | float(8,2) | NO   |     | 0.00                |       |
| PSd00       | float(8,2) | NO   |     | 0.00                |       |
| PSd30       | float(8,2) | NO   |     | 0.00                |       |
| PSd60       | float(8,2) | NO   |     | 0.00                |       |
| RRad1       | float(8,2) | NO   |     | 0.00                |       |
| Rad1h       | float(8,2) | NO   |     | 0.00                |       |
| SunD1       | float(8,2) | NO   |     | 0.00                |       |
| SunD3       | float(8,2) | NO   |     | 0.00                |       |
| PEvap       | float(8,2) | NO   |     | 0.00                |       |
| WPc11       | float(8,2) | NO   |     | 0.00                |       |
| WPc31       | float(8,2) | NO   |     | 0.00                |       |
| WPc61       | float(8,2) | NO   |     | 0.00                |       |
| WPch1       | float(8,2) | NO   |     | 0.00                |       |
| WPcd1       | float(8,2) | NO   |     | 0.00                |       |
| Azimuth     | float(8,2) | NO   |     | 0.00                |       |
| Altitude    | float(8,2) | NO   |     | 0.00                |       |
| yield       | float(8,2) | NO   |     | 0.00                |       |
| Forecast    | float(8,2) | NO   |     | 0.00                |       |
| month       | int(11)    | NO   |     | NULL                |       |
| day         | int(11)    | NO   |     | NULL                |       |
| hour        | int(11)    | NO   |     | NULL                |       |
| forecast1   | float(8,2) | NO   |     | 0.00                |       |
| forecast2   | float(8,2) | NO   |     | 0.00                |       |
| forecast3   | float(8,2) | NO   |     | 0.00                |       |
| forecast4   | float(8,2) | NO   |     | 0.00                |       |
| forecast5   | float(8,2) | NO   |     | 0.00                |       |
+-------------+------------+------+-----+---------------------+-------+


Da meine Datenerfassung erst seit Mitte November läuft habe ich tendentiell wenig Ertrag - entsprechend schlecht fällt der Forecast aus (siehe blaue Linie im Screenshot). Jetzt könnte man meinen "ist 'ne nette Spielerei", wenn da nicht die von sklearn ermittelten Koeffizienten wären:

                            OLS Regression Results
==============================================================================
Dep. Variable:                  yield   R-squared:                       0.484
Model:                            OLS   Adj. R-squared:                  0.481
Method:                 Least Squares   F-statistic:                     169.2
Date:                Tue, 26 Jan 2021   Prob (F-statistic):          1.31e-250
Time:                        18:11:49   Log-Likelihood:                -12010.
No. Observations:                1813   AIC:                         2.404e+04
Df Residuals:                    1802   BIC:                         2.410e+04
Df Model:                          10
Covariance Type:            nonrobust
==============================================================================
                 coef    std err          t      P>|t|      [0.025      0.975]
------------------------------------------------------------------------------
const       -174.2252     36.881     -4.724      0.000    -246.558    -101.892
Rad1h          0.9166      0.061     15.101      0.000       0.798       1.036
Neff           2.9379      1.055      2.785      0.005       0.869       5.007
R101          -1.6842      0.254     -6.623      0.000      -2.183      -1.185
Azimuth        0.0936      0.047      1.976      0.048       0.001       0.186
Altitude       0.8525      0.215      3.959      0.000       0.430       1.275
SunD1          0.0763      0.025      3.103      0.002       0.028       0.125
VV             0.0043      0.001      6.235      0.000       0.003       0.006
N             -0.5462      0.956     -0.572      0.568      -2.420       1.328
DD             0.0060      0.060      0.100      0.921      -0.112       0.124
RRS1c        132.6038     91.895      1.443      0.149     -47.628     312.836
==============================================================================
Omnibus:                     1250.407   Durbin-Watson:                   0.640
Prob(Omnibus):                  0.000   Jarque-Bera (JB):            40771.136
Skew:                           2.784   Prob(JB):                         0.00
Kurtosis:                      25.554   Cond. No.                     3.15e+05
==============================================================================

Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
[2] The condition number is large, 3.15e+05. This might indicate that there are
strong multicollinearity or other numerical problems.


Wenn wir uns schon immer gefragt haben "Mit welchem Anteil fließt die Bewölkung Neff in die Ertragsformel ein?" - am Ende der Trainingsphase können wir die Antwort geben. Ich kann dann auch sagen welche Fakltoren gar keine Rolle spielen. Da ich den den kompletten DWD-Forceast in der DB-Tabelle habe bin ich auch in der Lage nachtraglich Faktoren reinzunehmen.

Da gilt es jetzt nur noch abzuwarten.

Andererseits habe ich natürlich den Berg im Nacken, der um diese Jahreszeit am frühen Nachmittag zuschlägt. Dafür ist ein lineares Modell wenig geeignet. Also Spiele ich jetzt auch mit ein nichtlinearen Modell rum (deshalb auch vorsorglich die Felder Forecast 1...5 in der DB-Tabelle) .

@wzut: War das ein kleiner Appettitanreger für Dich? Kauf Dir dann zur PV-Anlage noch einen Zoe, ich habe schon das passende Modul dafür :-).

VG Peter
FHEM1 (Main) Raspi4 mit CUL, Homematic, SDUINO 433/OOK, zentrale Steuerung
FHEM2 (Keller) x86 mit CUL/hmland, IP-basierte Module
FHEM3 (Erdgeschoss) Raspi2 mit SDUINO 868/GFSK
FHEM4 (Hausanschlussraum), USV und OBIS-Modul
FHEM5 (Docker) mit FHEM2FHEM, InfluxDB