找回密码
 立即注册
查看: 273|回复: 0

NILMTK——经典数据集REDD介绍和使用

[复制链接]
发表于 2022-6-28 14:05 | 显示全部楼层 |阅读模式
配置了NILMTK包的环境之后,想找数据测试一下,在NILMTK官网的API Docs里边发现dataset_converters模块中有内置的数据集处理函数,如图:


将数据转换成HDF文件,这些数据都是比较优秀的,其中,常用的数据集是REDD和UK_DALE。
1. REDD数据集
目前版本的下载地址为: http://redd.csail.mit.edu,需要向作者发送邮件,才能获取用户名和密码进行下载!
论文为:J. Zico Kolter and Matthew J. Johnson. REDD: A public data set for energy disaggregation research. In proceedings of the SustKDD workshop on Data Mining Applications in Sustainability, 2011. [pdf]
数据集的文件为:


文件主要包含低频功率数据和高频电压电流数据
low_freq:1Hz功率数据
high_freq:校准和分组之后的电压电流波形数据
high_freq_row:原生电压电流波形数据
(1)low_freq的文件目录


总共收集了6个家庭的数据,labels记录了每个channel的设备类型,channel是记录每个channel的UTC时间戳的功率数据。
labels:


channel(一秒一个点):


(2)high_freq的文件目录


总共收集了6个家庭的数据,current_1记录了第一电源的电流数据,current_1记录了第二电源的电流数据,voltage记录了电压数据。
需要注意的是:
a、十进制的UTC时间戳,与低频的UTC时间戳是一样的格式,但是这个允许有小数部分。
b、循环计数,虽然它在文件中表示为双精度,但实际上它是一个整数,表示该特定波形保留多少交流周期。
c、在等间隔的周期中,275个十进制数值,表示波形的数值
下载完数据集之后,可通过dataset_converters 的函数将数据改为HDF格式:
  1. from nilmtk.dataset_converters import convert_redd
  2. convert_redd(r'C:\Users\admin\Anaconda3\nilm_metadata\low_freq',r'C:\Users\admin\Anaconda3\nilm_metadata\low_freq\redd_low_new.h5')
复制代码
2. REDD数据集的使用
a、负荷分解算法
通过NILMTK官网的API知道负荷分解包的算法有组合优化(CombinatorialOptimisation)、因子隐马尔可夫(FHMM)、Hart 1985(Hart 1985 algorithm),常用的是CO和FHMM。


b、负荷分解实现
以下例子是通过CO和FHMM计算的,文件获取在:
CO:http://nilmtk.github.io/nilmtk/master/_modules/nilmtk/disaggregate/combinatorial_optimisation.html#CombinatorialOptimisation
FHMM:nilmtk.legacy.disaggregate文件下的fhmm_exact文件。
    获取数据:
  1. from __future__ import print_function, division
  2. import pandas as pd
  3. import numpy as np
  4. from nilmtk.dataset import DataSet
  5. #from nilmtk.metergroup import MeterGroup
  6. #from nilmtk.datastore import HDFDataStore
  7. #from nilmtk.timeframe import TimeFrame
  8. from nilmtk.disaggregate.combinatorial_optimisation import CombinatorialOptimisation
  9. from nilmtk.legacy.disaggregate.fhmm_exact import FHMM
  10. train = DataSet('C:/Users/admin/PycharmProjects/nilmtktest/low_freq/redd_low.h5')  # 读取数据集
  11. test = DataSet('C:/Users/admin/PycharmProjects/nilmtktest/low_freq/redd_low.h5') # 读取数据集
  12. building = 1  ## 选择家庭house
  13. train.set_window(end="30-4-2011")  ## 划分数据集,2011年4月20号之前的作为训练集
  14. test.set_window(start="30-4-2011") ## 四月40号之后的作为测试集
  15. ## elec包含了这个家庭中的所有的电器信息和总功率信息,building=1-6个家庭
  16. train_elec = train.buildings[1].elec  
  17. test_elec = test.buildings[1].elec
  18. top_5_train_elec = train_elec.submeters().select_top_k(k=5)  ## 选择用电量排在前5的来进行训练和测试
复制代码
选取了第一个家庭,用电量在前5的电器数据进行测试。
    计算:
  1. def predict(clf, test_elec, sample_period, timezone):   ## 定义预测的方法
  2.     pred = {}
  3.     gt= {}
  4.     #获取总的负荷数据
  5.     for i, chunk in enumerate(test_elec.mains().load(sample_period=sample_period)):
  6.         chunk_drop_na = chunk.dropna()   ### 丢到缺省值
  7.         pred[i] = clf.disaggregate_chunk(chunk_drop_na)  #### 分解,disaggregate_chunk #通过调用这个方法实现分解,这部分代码在下面可以见到
  8.         gt[i]={}  ## 这是groudtruth,即真实的单个电器的消耗功率
  9.         for meter in test_elec.submeters().meters:
  10.             # Only use the meters that we trained on (this saves time!)   
  11.             gt[i][meter] = next(meter.load(sample_period=sample_period))  
  12.         gt[i] = pd.DataFrame({k:v.squeeze() for k,v in gt[i].items()}, index=next(iter(gt[i].values())).index).dropna()   #### 上面这一块主要是为了得到pandas格式的gt数据
  13.     # If everything can fit in memory
  14.     gt_overall = pd.concat(gt)   
  15.     gt_overall.index = gt_overall.index.droplevel()
  16.     pred_overall = pd.concat(pred)
  17.     pred_overall.index = pred_overall.index.droplevel()
  18.     # Having the same order of columns
  19.     gt_overall = gt_overall[pred_overall.columns]
  20.     #Intersection of index
  21.     gt_index_utc = gt_overall.index.tz_convert("UTC")
  22.     pred_index_utc = pred_overall.index.tz_convert("UTC")
  23.     common_index_utc = gt_index_utc.intersection(pred_index_utc)
  24.     common_index_local = common_index_utc.tz_convert(timezone)
  25.     gt_overall = gt_overall.ix[common_index_local]
  26.     pred_overall = pred_overall.ix[common_index_local]
  27.     appliance_labels = [m.label() for m in gt_overall.columns.values]
  28.     gt_overall.columns = appliance_labels
  29.     pred_overall.columns = appliance_labels
  30.     return gt_overall, pred_overall
  31. classifiers = { 'CO':CombinatorialOptimisation(),'FHMM':FHMM()}   ### 设置了两种算法,一种是CO,一种是FHMM
  32. predictions = {}
  33. sample_period = 120  ## 采样周期是两分钟
  34. for clf_name, clf in classifiers.items():
  35.     print("*"*20)
  36.     print(clf_name)
  37.     print("*" *20)
  38.     clf.train(top_5_train_elec, sample_period=sample_period)  ### 训练部分
  39.     gt, predictions[clf_name] = predict(clf, test_elec, 120, train.metadata['timezone'])
复制代码
先用clf.train训练这5种电器的特征规律,然后在用总的功率数据进行各种电器特征分解。gt记录了每个电器的功率数据,采样周期是两分钟一个点,后边根据预测的电器种类选取了用电量排名比较高的5种电器。


predictions变量记录了两个算法的计算结果:


    评估:
  1. def compute_rmse(gt, pred):   ### 评估指标 rmse
  2.     from sklearn.metrics import mean_squared_error
  3.     rms_error = {}
  4.     for appliance in gt.columns:
  5.         rms_error[appliance] = np.sqrt(mean_squared_error(gt[appliance], pred[appliance])) ## 评价指标的定义很简单,就是均方根误差
  6.     return pd.Series(rms_error)
  7. rmse = {}
  8. for clf_name in classifiers.keys():
  9.     rmse[clf_name] = compute_rmse(gt, predictions[clf_name])
  10. rmse = pd.DataFrame(rmse)
复制代码
计算结果为:


参考博客:https://blog.csdn.net/baidu_36161077/article/details/81144037

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-26 03:39 , Processed in 0.088048 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表