这是RUL系列的终篇,在这一节中,将预测测试集合的RUL值。
In [1]:
from rul_code import *
score = model.predict(X_test)
score[0:10]
Out[1]:
可见所有的值基本上都在0-1这个区间内,但也有个别例外。
In [2]:
print(score.min(), score.max())
我们要将这些数值转换为可以表明设备剩余生命周期RUL的数值。首先,我们将构造一列,用来记录测试集中传感器的最大生命周期。
In [3]:
test = pd.merge(test, test.groupby('unit', as_index=False)['cycles'].max(), how='left', on='unit')
test.rename(columns={"cycles_x": "cycles", "cycles_y": "maxcycles"}, inplace=True)
test['score'] = score
test.head()
Out[3]:
需要注意的是测试集中只包含未筛选过的数据,也就是原始数据,但是我们在建模和预测时使用的是清洗过的数据;另外一个注意点是,为了预测RUL,我们需要预测测试集中所有的传感器的生命周期总数。使用如下公式:$$max(predictedcycles_i)=\frac{cycles_i}{(1−predictedfTTF_i)}$$
In [5]:
def totcycles(data):
return(data['cycles'] / (1-data['score']))
test['maxpredcycles'] = totcycles(test)
用预测的最大生命周期数减去测试集中的生命周期数据,即得到剩余生命周期数。$$RUL_i=max(predictedcycles_i)−max(cycles)$$
In [6]:
def RULfunction(data):
return(data['maxpredcycles'] - data['maxcycles'])
test['RUL'] = RULfunction(test)
test['RUL'].head()
Out[6]:
接下来就是基于预测的最大生命周期数预测每一个传感器的剩余生命周期。
In [9]:
t = test.columns == 'RUL'
ind = [i for i, x in enumerate(t) if x]
predictedRUL = []
for i in range(test.unit.min(), test.unit.max()+1):
npredictedRUL=test[test.unit==i].iloc[test[test.unit==i].cycles.max()-1,ind]
predictedRUL.append(npredictedRUL)
predictedRUL[0:10]
Out[9]:
In [8]:
len(predictedRUL)
Out[8]:
接下来我们将预测值和真实值做一个图形化的比较:
In [28]:
xtrueRUL = list(RUL.loc[:,0])
otrueRUL = []
for i in range(0,len(xtrueRUL)):
otrueRUL = np.concatenate((otrueRUL, list(reversed(np.arange(xtrueRUL[i])))))
otrueRUL
Out[28]:
In [39]:
xpredictedRUL = list(round(x) for x in predictedRUL)
opredictedRUL = []
for i in range(0,len(xpredictedRUL)):
opredictedRUL = np.concatenate((opredictedRUL, list(reversed(np.arange(xpredictedRUL[i]['RUL'])))))
opredictedRUL
Out[39]:
In [40]:
mx = 1000
fig = plt.figure(figsize = (12, 8))
fig.add_subplot(1,2,1)
plt.plot(opredictedRUL[0:mx], color='blue')
plt.legend(['Predicted RUL'], bbox_to_anchor=(0., 1.02, 1., .102), loc=3, mode="expand", borderaxespad=0)
plt.ylim(0, opredictedRUL[0:mx].max()+10)
plt.ylabel('RUL (cycles)')
fig.add_subplot(1,2,2)
plt.plot(otrueRUL[0:mx], color='purple')
plt.legend(['True RUL'], bbox_to_anchor=(0., 1.02, 1., .102), loc=3, mode="expand", borderaxespad=0)
plt.ylabel('RUL (cycles)')
plt.ylim(0,otrueRUL[0:mx].max()+10)
plt.show()
如果把预测值和真实值放在同一个折线图里面,虽然这样不太合适,因为不含有时间维度,但是仍然可以直观地感受二者的差异:预测值通常比实际值要大。
In [42]:
plt.figure(figsize = (16, 8))
plt.plot(RUL)
plt.plot(predictedRUL)
plt.xlabel('# Unit', fontsize=16)
plt.xticks(fontsize=16)
plt.ylabel('RUL', fontsize=16)
plt.yticks(fontsize=16)
plt.legend(['True RUL','Predicted RUL'], bbox_to_anchor=(0., 1.02, 1., .102), loc=3, mode="expand", borderaxespad=0)
plt.show()
在大多数数学科学领域内,适当的高估是可以接受的。