探索分析热水器的水流量状况
#%% import pandas as pd import matplotlib.pyplot as plt #%% inputfile = '../data/original_data.xls' data = pd.read_excel(inputfile) #%% lv_non = pd.value_counts(data['有无水流'])['无'] lv_move = pd.value_counts(data['有无水流'])['有'] #%% fig = plt.figure(figsize=(6,5)) plt.rcParams['font.sans-serif']='SimHei' plt.rcParams['axes.unicode_minus']=False plt.bar(x=range(2),height=[lv_non,lv_move],width=0.4,alpha=0.8,color='skyblue') plt.xticks([index for index in range(2)],['无','有']) plt.xlabel('水流状态') plt.ylabel('记录数') plt.title('不同水流状态记录数_3113') plt.show()
#%% water = data['水流量'] fig = plt.figure(figsize=(5,8)) plt.boxplot(water, patch_artist=True, labels=['水流量'], boxprops={'facecolor':'lightblue'}) plt.title('水流量分布箱型图_3113') plt.grid(axis='y') plt.show()
删除冗余属性
import pandas as pd import numpy as np data = pd.read_excel('../data/original_data.xls') print('初始状态的数据形状为:',data.shape)
#删除热水器编号、有无水流、节能模式属性 data.drop(labels=['热水器编号','有无水流','节能模式'],axis=1,inplace=True) print('删除冗余属性后的数据形状为:',data.shape) data.to_csv('../data/water_heart.csv')
划分用水事件
#%% import pandas as pd import numpy as np #%% #读取数据 data = pd.read_csv('../data/water_heart.csv') #划分用水事件 threshold = pd.Timedelta('4 min') #阈值为4分钟 data['发生时间'] = pd.to_datetime(data['发生时间'],format='%Y%m%d%H%M%S') data = data[data['水流量']>0] # 只要流量大于0的记录 sjKs = data['发生时间'].diff() > threshold#相邻时间向前差分,比较是否大于阈值 sjKs.iloc[0] = True #令最后一个时间作为最后一个用水事件的结束时间 sjJs = sjKs.iloc[1:] #向后差分的结果 sjJs = pd.concat([sjJs,pd.Series(True)]) #令最后一个时间作为最后一个用水事件的结束时间 #创建数据框,并定义用水事件序列 sj = pd.DataFrame(np.arange(1,sum(sjKs)+1),columns=['事件序号']) sj['事件起始编号'] = data.index[sjKs == 1]+1 #定义用水事件的起始编号 sj['事件终止编号'] = data.index[sjJs == 1]+1 #定义用水事件的终止编号 print('当阈值为4分钟的时候事件数目为:',sj.shape[0]) sj.to_csv('../data/sj.csv',index=False)
#%% import pandas as pd import numpy as np #%% #读取数据 data = pd.read_csv('../data/water_heart.csv') #划分用水事件 threshold = pd.Timedelta('4 min') #阈值为4分钟 data['发生时间'] = pd.to_datetime(data['发生时间'],format='%Y%m%d%H%M%S') data = data[data['水流量']>0] # 只要流量大于0的记录 sjKs = data['发生时间'].diff() > threshold#相邻时间向前差分,比较是否大于阈值 sjKs.iloc[0] = True #令最后一个时间作为最后一个用水事件的结束时间 sjJs = sjKs.iloc[1:] #向后差分的结果 sjJs = pd.concat([sjJs,pd.Series(True)]) #令最后一个时间作为最后一个用水事件的结束时间 #创建数据框,并定义用水事件序列 sj = pd.DataFrame(np.arange(1,sum(sjKs)+1),columns=['事件序号']) sj['事件起始编号'] = data.index[sjKs == 1]+1 #定义用水事件的起始编号 sj['事件终止编号'] = data.index[sjJs == 1]+1 #定义用水事件的终止编号 print('当阈值为4分钟的时候事件数目为:',sj.shape[0]) sj.to_csv('../data/sj.csv',index=False) #%% #确定单次用水事件时长阈值 n = 4 # 使用以后4个点的平均斜率 threshold = pd.Timedelta(minutes=5) # 专家阈值 data['发生时间'] = pd.to_datetime(data['发生时间'],format='%Y%m%d%H%M%S') data = data[data['水流量']>0] # 只要流量大于0的记录 #自定义函数:输入划分时间的时间阈值,得到划分的事件数 def event_num(ts): d = data['发生时间'].diff() > ts # 相邻时间作差分,比较是否大于阈值 return d.sum() + 1 # 这样直接返回事件数 dt = [pd.Timedelta(minutes=i)for i in np.arange(1,9,0.25)] h = pd.DataFrame(dt,columns=['阈值']) #转换数据框,定义阈值列 h['事件数'] =h['阈值'].apply(event_num)#计算每个阈值对应的事件数 h['斜率'] = h['事件数'].diff()/0.25 #计算相邻两个点对应的斜率 h['斜率指标'] = h['斜率'].abs().rolling(4).mean() #往前取n个斜率绝对值平均作为斜率指标 ts = h['阈值'][h['斜率指标'].idxmin()-n] #用idxmin返回最小值的Index,由于rolling_mean()计算的是前n个斜率的平均 #所以结果要进行平移(-n) if ts > threshold: ts = pd.Timedelta(minutes=4) print('计算出的单词用水时长的阈值为:',ts)
确定单次用水时长阈值
#%% import pandas as pd import numpy as np #%% #读取数据 data = pd.read_csv('../data/water_heart.csv') #划分用水事件 threshold = pd.Timedelta('4 min') #阈值为4分钟 data['发生时间'] = pd.to_datetime(data['发生时间'],format='%Y%m%d%H%M%S') data = data[data['水流量']>0] # 只要流量大于0的记录 sjKs = data['发生时间'].diff() > threshold#相邻时间向前差分,比较是否大于阈值 sjKs.iloc[0] = True #令最后一个时间作为最后一个用水事件的结束时间 sjJs = sjKs.iloc[1:] #向后差分的结果 sjJs = pd.concat([sjJs,pd.Series(True)]) #令最后一个时间作为最后一个用水事件的结束时间 #创建数据框,并定义用水事件序列 sj = pd.DataFrame(np.arange(1,sum(sjKs)+1),columns=['事件序号']) sj['事件起始编号'] = data.index[sjKs == 1]+1 #定义用水事件的起始编号 sj['事件终止编号'] = data.index[sjJs == 1]+1 #定义用水事件的终止编号 print('当阈值为4分钟的时候事件数目为:',sj.shape[0]) sj.to_csv('../data/sj.csv',index=False) #%% #确定单次用水事件时长阈值 n = 4 # 使用以后4个点的平均斜率 threshold = pd.Timedelta(minutes=5) # 专家阈值 data['发生时间'] = pd.to_datetime(data['发生时间'],format='%Y%m%d%H%M%S') data = data[data['水流量']>0] # 只要流量大于0的记录 #自定义函数:输入划分时间的时间阈值,得到划分的事件数 def event_num(ts): d = data['发生时间'].diff() > ts # 相邻时间作差分,比较是否大于阈值 return d.sum() + 1 # 这样直接返回事件数 dt = [pd.Timedelta(minutes=i)for i in np.arange(1,9,0.25)] h = pd.DataFrame(dt,columns=['阈值']) #转换数据框,定义阈值列 h['事件数'] =h['阈值'].apply(event_num)#计算每个阈值对应的事件数 h['斜率'] = h['事件数'].diff()/0.25 #计算相邻两个点对应的斜率 h['斜率指标'] = h['斜率'].abs().rolling(4).mean() #往前取n个斜率绝对值平均作为斜率指标 ts = h['阈值'][h['斜率指标'].idxmin()-n] #用idxmin返回最小值的Index,由于rolling_mean()计算的是前n个斜率的平均 #所以结果要进行平移(-n) if ts > threshold: ts = pd.Timedelta(minutes=4) print('计算出的单词用水时长的阈值为:',ts)
预测模型
#%% import pandas as pd from sklearn.preprocessing import StandardScaler from sklearn.neural_network import MLPClassifier import joblib # 读取数据 Xtrain = pd.read_excel('../data/sj_final.xlsx') ytrain = pd.read_excel('../data/water_heater_log.xlsx') test = pd.read_excel('../data/test_data.xlsx') # 训练集测试集区分。 x_train, x_test, y_train, y_test = Xtrain.iloc[:,5:],test.iloc[:,4:-1],\ ytrain.iloc[:,-1],test.iloc[:,-1] # 标准化 stdScaler = StandardScaler().fit(x_train) x_stdtrain = stdScaler.transform(x_train) x_stdtest = stdScaler.transform(x_test) # 建立模型 bpnn = MLPClassifier(hidden_layer_sizes = (17,10), max_iter = 200, solver = 'lbfgs',random_state=50) bpnn.fit(x_stdtrain, y_train) # 保存模型 joblib.dump(bpnn,'../data/water_heater_nnet.m') print('构建的模型为:\n',bpnn)
#%% # 模型评价 from sklearn.metrics import classification_report from sklearn.metrics import roc_curve import joblib import matplotlib.pyplot as plt bpnn = joblib.load('../data/water_heater_nnet.m') # 加载模型 y_pred = bpnn.predict(x_stdtest) # 返回预测结果 print('神经网络预测结果评价报告:\n',classification_report(y_test,y_pred)) # 绘制roc曲线图 plt.rcParams['font.sans-serif'] = 'SimHei' # 显示中文 plt.rcParams['axes.unicode_minus'] = False # 显示负号 fpr, tpr, thresholds = roc_curve(y_pred,y_test) # 求出TPR和FPR plt.figure(figsize=(6,4)) # 创建画布 plt.plot(fpr,tpr) # 绘制曲线 plt.title('用户用水事件识别ROC曲线_3113') # 标题 plt.xlabel('FPR') # x轴标签 plt.ylabel('TPR') # y轴标签 plt.savefig('../data/用户用水事件识别ROC曲线.png') # 保存图片 plt.show() # 显示图形
标签:plt,阈值,家用,sj,热水器,事件,pd,识别,data From: https://www.cnblogs.com/zhilin00/p/17239147.html