내일배움캠프(QA,QC_5기)

[내일배움캠프] QA/QC_5기 ( 66일차 )

lshxkwh 2026. 6. 16. 19:57

NASA C-MAPSS 항공 엔진 수명 예측 프로젝트

처음부터 딥러닝까지들어가며

오늘은 NASA에서 공개한 항공 엔진 데이터셋(C-MAPSS FD001)으로
엔진이 언제 고장날지 예측하는 AI 모델을 처음부터 만들어봤다.

머신러닝부터 시작해서 딥러닝까지 단계별로 진행했고,
최종적으로 RMSE 9.40 / 조기경보 정확도 96% 를 달성했다.


1. 문제 정의

왜 이 문제가 중요한가?

항공사는 엔진 고장 시점을 미리 알 수 없어서 두 가지 문제가 생긴다.

  • 과도한 예방 정비 → 멀쩡한 엔진을 너무 자주 정비 → 비용 낭비
  • 예상치 못한 고장 → 결항, 안전사고 → 훨씬 큰 손실

그래서 센서 데이터로 남은 수명(RUL, Remaining Useful Life) 을 예측해서
적절한 시점에 정비하는 것이 목표다.

성공 기준

지표 목표

RMSE ≤ 30 사이클
조기경보 정확도 ≥ 85% (RUL ≤ 30 구간)

조기경보란? 고장이 30사이클 이내로 임박한 엔진을 얼마나 잘 탐지하는지


2. 데이터 소개 (NASA C-MAPSS FD001)

  • 엔진 수: Train 100대 / Test 100대
  • 센서: 21개 (온도, 압력, 팬 속도 등)
  • 구조: 엔진이 고장날 때까지 매 사이클 센서값 기록 (run-to-failure)
  • 컬럼: unit(엔진번호), cycle(사이클), os1~3(운전조건), s1~s21(센서)
# 데이터 로드
COLS = ['unit', 'cycle'] + [f'os{i}' for i in range(1,4)] + [f's{i}' for i in range(1,22)]
train = pd.read_csv("train_FD001.txt", sep=r'\s+', header=None, names=COLS)

3. 분석 파이프라인

Step 1. 데이터 로드
Step 2. RUL 레이블 생성
Step 3. 센서 선택 (분산 기반)
Step 4. 전처리 (정규화 + 이동평균)
Step 5. 머신러닝 모델 학습/비교
Step 6. 피처 중요도 & 정비 권고
Step 7. 조기경보 개선 (가중치 조정)
Step 8. LSTM 딥러닝 적용

4. 핵심 전처리

RUL 레이블 생성 (Piecewise Linear)

RUL_CLIP = 110  # 클리핑 기준

# RUL = 고장 사이클 - 현재 사이클
max_cycle = train.groupby('unit')['cycle'].max()
train['RUL'] = (max_cycle - train['cycle']).clip(upper=RUL_CLIP)

클리핑을 적용하는 이유는 엔진 초기에는 열화가 거의 없기 때문이다.
RUL이 200이든 110이든 모델 입장에선 똑같이 "아직 멀쩡함"이라서
125 이상은 전부 125로 잘라줬다. (이후 110으로 최적화)

센서 선택 (분산 기반 필터링)

sensor_std = train[SENSOR_COLS].std()
SELECTED_SENSORS = sensor_std[sensor_std > 0.1].index.tolist()
# 21개 → 11개로 축소

21개 센서 중 값이 거의 변하지 않는 센서는 열화 정보가 없으므로 제거했다.

이동평균으로 노이즈 제거

# 5사이클 이동평균 추가
df[f'{s}_ma'] = df.groupby('unit')[s].transform(
    lambda x: x.rolling(5, min_periods=1).mean()
)

5. 머신러닝 모델 비교

3개 모델을 비교했다.

모델 RMSE 조기경보

선형 회귀 20.67 40.0%
랜덤 포레스트 18.51 68.0%
그래디언트 부스팅 17.23 68.0%

RMSE는 목표(30)를 달성했지만 조기경보 68%로 목표(85%) 미달.


6. 조기경보 개선 시도

가중치 조정

# RUL ≤ 30 구간에 더 높은 가중치 부여
sample_weight = np.where(y_train <= 30, 5.0, 1.0)
model.fit(X_train, y_train, sample_weight=sample_weight)

결과: 72%까지 상승했지만 85% 달성 실패

한계 발견

머신러닝의 근본적인 문제를 발견했다.

머신러닝: 사이클 150의 센서값 1개 → RUL 예측
LSTM:    사이클 101~150, 50개 흐름 → RUL 예측

RUL 후반부는 한 시점의 스냅샷이 아니라 열화 추세로 봐야 한다.
LSTM(딥러닝)으로 전환 결정


7. LSTM 딥러닝 적용

LSTM이 뭔가?

딥러닝의 한 종류로, 시계열 데이터의 흐름을 학습할 수 있다.
여러 층(Layer)을 쌓아서 패턴을 추출한다.

AI > 머신러닝 > 딥러닝 > LSTM

모델 구조

model = Sequential([
    LSTM(256, return_sequences=True),  # 시계열 패턴 추출
    Dropout(0.2),                       # 과적합 방지
    LSTM(128, return_sequences=False),  # 패턴 압축
    Dropout(0.2),
    Dense(64, activation='relu'),
    Dense(32, activation='relu'),
    Dense(1)                            # RUL 수치 출력
])

시퀀스 데이터 생성

SEQ_LEN = 50  # 최근 50사이클을 보고 예측

# 50사이클 단위로 슬라이딩 윈도우
for i in range(len(engine) - SEQ_LEN + 1):
    X.append(data[i:i + SEQ_LEN])
    y.append(RUL[i + SEQ_LEN - 1])

조기경보 구간 가중치 세분화

sample_weight = np.where(y_train <= 15, 10.0,   # 긴급 구간 10배
                np.where(y_train <= 30,  5.0,   # 경보 구간 5배
                1.0))                            # 정상 구간 1배

8. 최종 결과

성능 비교

모델 RMSE 조기경보

그래디언트 부스팅 (베이스라인) 17.23 68.0%
LSTM (초기) 11.40 72.0%
LSTM (최종 튜닝) 9.40 96.0%

성공 기준 달성

지표 목표 결과 상태

RMSE ≤ 30 9.40  달성
조기경보 ≥ 85% 96.0% 달성

9. 정비 권고 시스템

예측 RUL을 4등급으로 분류해서 정비 우선순위를 자동 산출했다.

등급 조건 조치

🔴 긴급 정비 RUL ≤ 15 즉시 운항 중단
🟠 경보 발령 RUL ≤ 30 정비 일정 즉시 수립
🟡 주의 관찰 RUL ≤ 60 집중 모니터링
🟢 정상 운항 RUL > 60 정상 운항 유지

10. 배운 것

기술적으로

  • RUL 클리핑이 모델 안정성에 핵심적인 역할을 함
  • Data Leakage 주의: 정규화는 반드시 Train 기준으로 fit 후 Test에 transform
  • 머신러닝의 한계: 행 단위 학습으로는 시계열 흐름 반영 불가 → LSTM 필요
  • 가중치 조정: 중요한 구간(고장 임박)에 높은 가중치를 주면 해당 구간 성능 향상

분석 프로세스로

  • 성공 기준을 수치로 명확하게 정의하고 시작하는 게 중요
  • 딥러닝이 항상 답이 아님. 머신러닝으로 먼저 베이스라인 잡고 한계 확인 후 전환
  • RMSE가 좋아도 비즈니스 관점(조기경보) 이 안 되면 실패