본문 바로가기

[중급] 가볍게 이것저것

[Turbofan] 설비 잔존수명 예측 / 예방보전 / 관리한계선 설정방법

 

 

 

In [ ]:
 
 

각 센서 값들을 기반으로 RUL(잔존수명) 을 도출합니다.

In [183]:
import pandas as pd
import numpy as np
from glob import glob
unit_1 = pd.read_csv('FD001_RUL.csv')

%matplotlib inline
sns.set(rc={'figure.figsize':(15,6)})
 

RUL 은 향후 사용 가능한 잔여 횟수를 의미합니다.

10회 미만 사용 가능할 경우 CRITICAL
10 ~ 20 이면 CAUTION // 20 ~ 30 이면 NEED_CARE // 30 이상이면 HEALTHY 로 라벨링 하였습니다.

라벨링 한 컬럼 이름은 LEVEL 입니다.

In [184]:
unit_1.loc[unit_1['RUL'] <= 10, 'LEVEL'] = 'CRITICAL'
unit_1.loc[unit_1['RUL'] > 10, 'LEVEL'] = 'CAUTION'
unit_1.loc[unit_1['RUL'] > 20, 'LEVEL'] = 'NEED_CARE'
unit_1.loc[unit_1['RUL'] > 30, 'LEVEL'] = 'HEALTHY'
 

기존 데이터 셋은 약 20000 row 가 있습니다.

이를 1만건을 기준으로 잘라 train / test 로 사용하고자 합니다.
In [185]:
import numpy as np
slicing_constant = 10000

cols = list(unit_1.columns)
features = cols[3:-2]
label = 'LEVEL'

train = unit_1[:slicing_constant]
test = unit_1[slicing_constant:]
 

MinMaxScaler 로 모든 컬럼의 값들을 0 ~ 1 사이로 만들어 줍니다.

변수마다 단위가 다르기 때문에 일괄 적용하였습니다.

std 값이 0.01 이하인 컬럼 또한 일괄 제거하였습니다.
In [186]:
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()

tt_list = [train, test]

for n, d_set in enumerate(tt_list):
    target = pd.DataFrame(scaler.fit_transform(tt_list[n][features]), columns=features)
    desc = target.describe()
    null_cols = []
    for cols in desc.columns:
        if desc[cols][2] < 0.01:
            null_cols.append(cols)
    clean = target.drop(columns=null_cols)
    clean[clean==np.inf]=np.nan
    clean = clean.dropna()
    tt_list[n] = clean

X_train, X_test = tt_list[0], tt_list[1]
y_train, y_test = train[label], test[label]
 

PCA 로 주성분 2개를 뽑아 라벨링한 LEVEL 컬럼의 값으로 보고자 합니다.

주성분 1(x축) 기준 0.7 정도에 관리한계선을 설정한다면 CRITICAL 상태 분류가 가능합니다.
In [187]:
from sklearn.decomposition import PCA
import pandas as pp
pca = PCA(n_components=2)
principalComponents = pca.fit_transform(X_train)
principalDf = pp.DataFrame(principalComponents
             , columns = ['principal component 1', 'principal component 2'])
finalDf = pp.concat([principalDf, y_train], axis=1)

import matplotlib.pyplot as plt
import seaborn as sns

ax = sns.scatterplot(x = 'principal component 1', 
                     y = 'principal component 2', 
                     hue = 'LEVEL',
                     data = finalDf, 
                     palette ='Spectral')
 
 

PLS 로 x 와 RUL 컬럼을 가장 잘 설명하는 주성분 2개를 뽑았습니다.

y 값이 없는 PCA 와는 다르게 PLS 는 y값을 고려한 알고리즘입니다.

회귀 과정이 있기 때문에 LEVEL 컬럼이 아닌 'RUL' 을 기준으로 합니다.

주성분 1(x축) 기준 6 정도에 관리한계선을 설정한다면 CRITICAL 상태 분류가 가능합니다.
In [206]:
from sklearn.cross_decomposition import PLSRegression
principalComponents, _ = PLSRegression(n_components=2).fit_transform(train[X_train.columns], train['RUL'])
principalDf = pp.DataFrame(principalComponents
             , columns = ['PLS component 1', 'PLS component 2'])
finalDf = pp.concat([principalDf, train['RUL']], axis=1)

import matplotlib.pyplot as plt
import seaborn as sns

cutter = []
for i in range(3):
    cutter.append(10 ** i)
    i = i + 1

finalDf['rul_range'] = pd.cut(finalDf['RUL'], cutter)
ax = sns.scatterplot(x = 'PLS component 1', 
                     y = 'PLS component 2', 
                     hue = 'rul_range',
                     data = finalDf, 
                     palette ='Spectral')
 
 

NMF 기준으로 주성분 2개를 뽑았습니다.

기존 PCA 와 PLS 와는 다르게 성분 2 개를 동시에 이용해야 관리한계선 설정이 가능합니다.
In [189]:
from sklearn.decomposition import NMF
NMFComponents = NMF(n_components=2).fit_transform(train[X_train.columns])
NMFDf = pp.DataFrame(NMFComponents
             , columns = ['NMF component 1', 'NMF component 2'])
finalDf = pp.concat([NMFDf, y_train], axis=1)

import matplotlib.pyplot as plt
import seaborn as sns

ax = sns.scatterplot(x = 'NMF component 1', 
                     y = 'NMF component 2', 
                     hue = 'LEVEL',
                     data = finalDf, 
                     palette ='Spectral')
 
 

PCA 에서 커널 트릭을 사용하여 주성분 2개를 뽑았습니다.

poly-nomial 커널을 사용하고 3차항까지 고려하였습니다.

기존 PCA 와 PLS 와는 다르게 성분 2 개를 동시에 이용해야 관리한계선 설정이 가능합니다.
In [190]:
from sklearn.decomposition import KernelPCA
KPCAComponents = KernelPCA(n_components=2, kernel='poly', degree=3).fit_transform(train[X_train.columns])
KPCADf = pp.DataFrame(KPCAComponents
             , columns = ['KPCA component 1', 'KPCA component 2'])
finalDf = pp.concat([KPCADf, y_train], axis=1)

import matplotlib.pyplot as plt
import seaborn as sns

ax = sns.scatterplot(x = 'KPCA component 1', 
                     y = 'KPCA component 2', 
                     hue = 'LEVEL',
                     data = finalDf, 
                     palette ='Spectral')
 
 

y 값인 RUL 을 기준으로 변수간 상관관계를 보았습니다.

RUL 기준으로
P30, phi, W31, W32 가 강한 양의 상관관계를 보였고
Nc, NRc, P15 는 뚜렷한 상관관계가 없었습니다.
Ps30, T50, BPR, T24, htBleed, T30, NRf, Nf 는 강한 음의 상관관계를 보였습니다.
In [191]:
corr_heatmap = train[list(X_train.columns) + ['RUL']].corr().sort_values(by='RUL')
sns.heatmap(corr_heatmap)
Out[191]:
<matplotlib.axes._subplots.AxesSubplot at 0x2830619ccc0>
 
 

PCA 와 PLS 에서 첫 번째 주성분으로 관리한계선 설정이 가능합니다.

따라서, PCA 와 PLS 의 첫 번째 주성분은 RUL 을 잘 설명하고 있습니다.

첫 번째 주성분에서 각 변수의 기여도를(계수를) 뽑아내어 표준화하였습니다.

In [208]:
from sklearn.cross_decomposition import PLSRegression

corr = corr_heatmap['RUL'][:-1]
corr = pd.DataFrame(corr)
corr.columns=['corr_coeff']
corr.reset_index()

pca_coeff = pd.DataFrame(pca.components_[0])
pca_coeff.index=X_train.columns
pca_coeff.columns=['PCA_coeff']
pca_coeff.reset_index()

pls2 = PLSRegression(n_components=2)
pls2.fit(train[X_train.columns], train['RUL'])
pls_coeff = pd.DataFrame(pls2.coef_)
pls_coeff.index=X_train.columns
pls_coeff.columns=['pls_coeff']
pls_coeff.reset_index()

coeff_merged = pd.concat([corr, pca_coeff, pls_coeff], axis=1, sort=False)

for col in coeff_merged.columns:
    coeff_merged[col] = coeff_merged[col] / np.std(coeff_merged[col])
    coeff_merged[col] = coeff_merged[col] - np.min(coeff_merged[col])
    coeff_merged[col] = (((coeff_merged[col] / np.max(coeff_merged[col])) * 2) - 1)
 

이 표준화 한 변수들을 상관계수와 비교하였습니다.

PCA 와 PLS 에서 추출한 변수가 각 모델에 기여하는 정도를 RUL과 각 변수간 산광계수와 비교합니다.
PCA 는 부호가 반대일 뿐이지 상관계수를 잘 반영하고 있습니다.
In [209]:
sns.lineplot(data=coeff_merged)
Out[209]:
<matplotlib.axes._subplots.AxesSubplot at 0x2831a33c390>
 
 

y 값인 RUL 과 연관이 높은 변수를 추출할#54624; 수 있었습니다.

설비 정비시 이 변수를 잘 관리해야 하는 것으로 보입니다.

관리한계선을 설정할 수 있기 때문에 PM 등 예방보전시 용이합니다.

In [ ]: