import pandas as pd
import matplotlib.pyplot as plt
inputfile = "C:\\Users\\Lenovo\\Desktop\\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('不同水流状态记录数 学号:3122')
plt.show()
plt.close()
# 查看水流量分布
water = data['水流量']
# 绘制水流量分布箱型图
fig = plt.figure(figsize = (5 ,8))
plt.boxplot(water,
patch_artist=True,
labels = ['水流量'], # 设置x轴标题
boxprops = {'facecolor':'lightblue'}) # 设置填充颜色
plt.title('水流量分布箱线图 学号:3122')
# 显示y坐标轴的底线
plt.grid(axis='y')
plt.show()
![]()
import pandas as pd
import numpy as np
data = pd.read_excel("C:\\Users\\Lenovo\\Desktop\\original_data.xls")
print('初始状态的数据形状为:', data.shape)
# 删除热水器编号、有无水流、节能模式属性
data.drop(labels=["热水器编号","有无水流","节能模式"],axis=1,inplace=True)
print('删除冗余属性后的数据形状为:', data.shape)
data.to_csv("C:\\Users\\Lenovo\\Desktop\\water_heart.csv",index=False)
# 读取数据
data = pd.read_csv("C:\\Users\\Lenovo\\Desktop\\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("C:\\Users\\Lenovo\\Desktop\\sj.csv",index = False)
# 确定单次用水事件时长阈值
n = 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)
data = pd.read_csv("C:\\Users\\Lenovo\\Desktop\\water_heart.csv") # 读取热水器使用数据记录
sj = pd.read_csv("C:\\Users\\Lenovo\\Desktop\\sj.csv")
![]()
import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.neural_network import MLPClassifier
import joblib
# 读取数据
Xtrain = pd.read_excel("C:\\Users\\Lenovo\\Desktop\\sj_final.xlsx")
ytrain = pd.read_excel("C:\\Users\\Lenovo\\Desktop\\water_heater_log.xlsx")
test = pd.read_excel("C:\\Users\\Lenovo\\Desktop\\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,"C:\\Users\\Lenovo\\Desktop\\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("C:\\Users\\Lenovo\\Desktop\\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曲线 学号:3122') # 标题
plt.xlabel('FPR') # x轴标签
plt.ylabel('TPR') # y轴标签
#plt.savefig('D:\PhotoWork\大数据\数据\第七次\用户用水事件识别ROC曲线.png') # 保存图片
plt.show() # 显示图形
![]()