13장 시각화·대시보드·기계학습 맛보기
이번 주의 도구: ⑨ 공정 데이터 대시보드
다음 상황을 생각해 보자. 어느 공장의 신입 엔지니어가 매일 아침 전날의 조업 데이터 CSV를 받아 그래프 여덟 장을 만들어 회의에 올린다. 스크립트를 실행하고, 그림을 저장하고, 보고 자료에 붙여 넣는 일을 매일 반복한다. 회의 중 팀장이 "지난주 같은 요일과 겹쳐 보여 줄 수 있나?"라고 물으면, 자리로 돌아가 코드를 고치고 다시 그려 오는 데 반나절이 걸린다.
더 곤란한 순간도 있다. 화면에 띄운 그래프를 보고 누군가 "이 세로축 단위가 뭔가요?"라고 묻는데 축에는 숫자만 있고 단위가 없다. 그래프를 만든 본인도 즉답하지 못한다. 이 장은 이 두 가지 문제를 다룬다. 그래프를 검증 가능한 주장으로 만드는 문법, 그리고 질문이 나오는 순간 그 자리에서 조건을 바꿔 보여 주는 대시보드다. 끝에서는 12장의 회귀가 신경망이라는 더 큰 세계로 어떻게 이어지는지 맛본다.
이 장에서 다루는 것
- 공학 그래프의 필수 4요소를 점검하는 눈을 익힌다
- 증기압 곡선으로 로그축이 필요한 상황을 확인한다
- matplotlib 스크립트를 Streamlit 대시보드로 바꾼다
- 훈련/시험 분리로 과적합을 잡아낸다
- DFT와 기계학습 포텐셜이라는 연구 현장의 기계학습을 엿본다
학습목표 이 장을 마치면 다음을 할 수 있다.
- 그래프에서 축 라벨·단위·범례·축 스케일의 결함을 찾아 교정할 수 있다.
- 지수적으로 변하는 데이터에 로그축을 써야 하는 이유를 설명할 수 있다.
- matplotlib 스크립트를 위젯이 있는 Streamlit 대시보드로 전환할 수 있다.
- 훈련 오차와 시험 오차를 구분하고 과적합을 판별할 수 있다.
- 회귀와 신경망을 모델–손실–학습의 공통 구조로 설명할 수 있다.
- 도구⑨와 서브프로젝트 v1을 완성 기준에 따라 점검할 수 있다.
이번 주 실습에서는 §13.1~13.2를 사용해 도구⑨ 공정 데이터 대시보드를 만들고, 남은 시간은 서브프로젝트 스프린트(순회 컨설팅 + 페어 상호 코드리뷰)에 쓴다. 최종 시험 주제 예시 중 하나가 "학번별 실험 데이터 회귀 + 이상치 자동 탐지 리포트 생성기"다. 12장과 이 장이 그 직접 대비 범위다.
13.1 공학 그래프의 문법
과학 계산의 목적은 숫자가 아니라 통찰이다. 계산이 쏟아 낸 수백 개의 숫자를 사람이 이해하려면 그림이 필요하고, 그래서 시각화는 해석의 시작 단계다. 그리고 그래프는 "이 온도에서 압력이 이만큼이다"라는 주장이고, 주장에는 근거가 붙어 있어야 한다.
공학 그래프가 갖춰야 할 최소 요건은 네 가지다. 첫째, 두 축에 물리량 이름과 단위를 적는다. 단위 없는 축은 검증 루틴 중 단위 체크를 원천적으로 불가능하게 만든다. 둘째, 곡선이 둘 이상이면 어느 선이 무엇인지 밝힌다. 여러 데이터 계열을 구분하는 이름표를 범례(legend)라 한다. 셋째, 데이터의 성격에 맞는 표현을 고른다. 측정한 데이터는 점(마커)으로, 모델이나 상관식은 선으로 그린다. 측정점 열두 개를 실선으로만 이어 버리면 측정하지 않은 중간값까지 측정한 것처럼 주장하는 셈이 된다. 넷째, 데이터의 분포에 맞는 축 스케일을 고른다.
넷째 요건이 낯설 수 있으니 8장의 증기압으로 확인해 보자. 물의 증기압은 NIST 상수의 유효범위인 379~573 K 사이에서 약 1 bar에서 약 70 bar까지, 70배 가까이 변한다. 이것을 눈금이 일정한 보통 축(선형축)에 그리면 고온부의 큰 값이 축 전체를 차지해 저온부 곡선은 바닥에 붙은 0처럼 보인다. 눈금 한 칸이 일정한 배수(10배)를 나타내는 축을 로그축(logarithmic axis)이라 한다. 로그축에서는 1 bar와 70 bar가 같은 비중으로 보이고, 저온부의 변화도 읽을 수 있다.
증기압에 로그축이 어울리는 것은 우연이 아니다. Antoine 식 자체가 log10 p*를 온도의 함수로 쓰는 식이므로, 세로축을 로그로 잡으면 곡선이 완만하게 펴진다. 데이터를 만든 물리가 지수적이면 축도 로그로 잡는다. 이것이 스케일 선택의 원칙이다.
예제 13.1-1 AI가 그린 증기압 곡선 채점하기
문제 물의 Antoine 상수(NIST WebBook, log10(p*/bar) = A − B/(T + C), A = 3.55959, B = 643.748, C = −198.043, 유효범위 379~573 K)를 사용해 증기압 곡선을 그리는 코드를 AI로 생성하고, 생성된 그래프를 4요소 기준으로 채점·교정하라.
풀이 전략 작도 코드는 AI에게 맡기고, 그래프 채점과 온도 범위의 결정은 직접 한다. 먼저 일부러 정보를 덜 준 프롬프트로 시작해, 생성된 그래프의 결함을 찾는 훈련을 겸한다(AI 협업 사이클 ③~④).
물의 증기압 곡선을 matplotlib으로 그려 줘. Antoine 식 써서. 상수는 A=3.55959, B=643.748, C=-198.043이고 압력은 bar야.
import numpy as np
import matplotlib.pyplot as plt
A, B, C = 3.55959, 643.748, -198.043
T = np.linspace(300, 600, 100)
p = 10**(A - B/(T + C))
plt.plot(T, p)
plt.show()
✔ 실행은 되고 곡선도 나온다. 그러나 4요소 채점 결과: 축 라벨과 단위 없음, 범례 없음, 선형축이라 400 K 아래 구간이 바닥에 붙어 보이지 않음. 결정적으로 온도 범위 300~600 K는 AI가 임의로 고른 것인데, 상수의 유효범위(379~573 K)를 양쪽으로 벗어난 외삽이다. 8장에서 373 K에서조차 25%나 낮은 값이 나오는 것을 보았다. 그보다 더 먼 외삽 구간을 곡선에 포함하면 안 된다.
결함 네 가지를 그대로 나열해 교정을 요구하면 다음을 얻는다.
고칠 것: ① 온도 범위를 유효범위 379~573 K로 제한 ② 축 라벨에 물리량과 단위 표기 ③ 범례 추가 ④ 세로축을 로그축으로. 주석은 한국어로, 물리량 변수에는 단위 주석을 달아 줘.
import numpy as np
import matplotlib.pyplot as plt
# NIST WebBook: 물, 유효범위 379~573 K
# log10(p*/bar) = A - B/(T + C)
A, B, C = 3.55959, 643.748, -198.043
T = np.linspace(379, 573, 100) # 온도 [K] — 유효범위만
p = 10**(A - B/(T + C)) # 증기압 [bar]
plt.semilogy(T, p, label="물 (NIST 상수)") # 세로축 로그
plt.xlabel("온도 T [K]")
plt.ylabel("증기압 p* [bar]")
plt.legend()
plt.grid(True)
plt.savefig("vapor_curve.png", dpi=150)
✔ 4요소 충족 확인. 곡선은 로그축에서 거의 직선으로 펴진다. Antoine 식이 log10 p*의 식이므로 예상과 일치한다.
- 단위 체크: 가로축 T [K], 세로축 p* [bar]로 식의 입출력 단위와 일치
- 대조값: 곡선의 저온 끝(379 K = 약 106 °C)에서 값이 약 1.0 bar로, "물은 1 atm(= 101.325 kPa) 부근에서 100 °C에 끓는다"는 상식과 어긋나지 않는다
- 극한값 sanity: 온도가 오를수록 증기압이 단조 증가하고, 573 K에서 약 70 bar다. 감소 구간이 있다면 코드나 상수를 의심해야 한다
분석 그래프의 결함은 코드의 결함보다 발견하기 어렵다. 문법 오류는 실행이 멈춰서 저절로 드러나지만, 라벨 없는 그래프와 외삽된 곡선은 멀쩡한 그림으로 출력되기 때문이다. 그래서 채점 기준(4요소)을 명시적으로 들고 있어야 잡는다. 특히 "AI가 임의로 고른 축 범위"는 이 장 이후 모든 그래프에서 반드시 확인할 항목이다. 학번별 물질의 상수로 같은 곡선을 재생성하고, 로그축을 껐을 때 저온부가 어떻게 보이는지 비교해 보라.
스스로 점검
- 축 라벨에 단위가 없으면 검증 루틴 3종 중 어느 것부터 불가능해지는가?
- 측정 데이터 12점을 마커 없이 실선으로만 이어 그렸다. 이 그래프가 하는 부당한 주장을 한 문장으로 말하라.
13.2 스크립트에서 대시보드로: Streamlit 최소한
13.2.1 일단 띄워 보기
먼저 손을 움직여 보자. 터미널에서 pip install streamlit으로 라이브러리를 설치한 뒤, 다음 다섯 줄을 app.py로 저장한다.
import streamlit as st
st.title("나의 첫 대시보드") # 페이지 제목
T = st.slider("온도 [K]", 379, 573, 400) # 슬라이더 (최소, 최대, 초기값)
st.write(f"선택한 온도: {T} K") # 화면에 출력
실행은 python app.py가 아니라 streamlit run app.py다. 브라우저가 열리고, 슬라이더가 있는 웹 페이지가 나타난다. 슬라이더를 끌면 아래 숫자가 즉시 바뀐다. (아무것도 뜨지 않으면 터미널에 출력된 주소를 브라우저에 직접 입력해 보라.)
방금 만든 것에 이름을 붙이자. 데이터와 계산 결과를 한 화면에 모아 사용자가 직접 조작하며 보게 만든 것을 대시보드(dashboard)라 하고, 슬라이더·선택 상자처럼 사용자 입력을 받는 화면 요소를 위젯(widget)이라 한다. Streamlit은 파이썬 스크립트를 이런 웹 대시보드로 바꿔 주는 라이브러리다.
동작 원리는 하나만 알면 된다. 위젯 값이 바뀔 때마다 Streamlit은 스크립트 전체를 위에서 아래로 다시 실행한다. 새로운 프로그래밍 모델을 배우는 것이 아니라, 지금까지 쓰던 "위에서 아래로 흐르는 스크립트"가 위젯 값만 갱신된 채 반복 실행되는 것이다. 그래서 5장부터 만들어 온 함수들을 고치지 않고 그대로 가져다 쓸 수 있다.
13.2.2 화공 도구의 대시보드화
이제 8장의 증기압 계산기를 대시보드로 옮겨 보자. 핵심은 두 가지다. 계산 함수는 새로 짜지 않고 재사용하며, 위젯의 범위를 상수의 유효범위로 제한한다.
예제 13.2-1 증기압 대시보드
문제 예제 13.1-1의 Antoine 상수를 사용해, 슬라이더로 온도를 고르면 증기압과 곡선 전체를 보여 주는 대시보드를 만들어라. 슬라이더는 유효범위 밖을 선택할 수 없어야 한다.
풀이 전략 전환 작업은 AI에게 맡기되, 프롬프트에 재사용할 함수, 위젯 범위, 표시할 항목 세 가지를 못 박는다. 유효범위 제한을 코드가 아니라 위젯 자체에 심는 것이 이 예제의 요점이다(사이클 ③~⑥).
이 Antoine 증기압 계산 코드를 Streamlit 대시보드로 바꿔 줘. 요구사항: ① 온도는 st.slider로 받되 범위를 유효범위 379~573 K로 제한 ② 선택 온도의 증기압을 크게 표시 ③ 그 아래 유효범위 전체의 증기압 곡선 ④ 주석은 한국어, 물리량 변수에 단위 주석.
import numpy as np
import streamlit as st
# NIST WebBook: 물(379~573 K), log10(p*/bar) = A - B/(T + C)
A, B, C = 3.55959, 643.748, -198.043
st.title("증기압 대시보드 — 물")
T = st.slider("온도 [K]", 379, 573, 400) # 유효범위로 제한 [K]
p = 10**(A - B/(T + C)) # 증기압 [bar]
st.metric("증기압", f"{p:.2f} bar") # 숫자 카드 표시
T_arr = np.linspace(379, 573, 100) # 곡선용 온도 [K]
p_arr = 10**(A - B/(T_arr + C)) # 증기압 [bar]
st.line_chart({"p* [bar]": p_arr})
✔ 슬라이더 범위가 379~573으로 제한됨을 확인. 다만 st.line_chart의 가로축이 온도가 아니라 배열 순번(0~99)으로 표시된다. 4요소 위반이므로 "가로축을 온도 값으로 표시하라"고 후속 요청해 pandas로 인덱스를 온도로 지정하게 했다. 이런 후속 교정까지가 전환 작업이다.
- 단위 체크: 슬라이더 입력 K, 표시 출력 bar로, 함수의 입출력 단위와 일치
- 대조값: 슬라이더를 최저 379 K로 내리면 1.00 bar로, 끓는점 상식(100 °C 부근, 1 atm)과 정합
- 극한값 sanity: 슬라이더가 유효범위 밖으로 아예 내려가지 않는다. 외삽 실수를 인터페이스가 차단
분석 대시보드의 이득은 편리함보다 검증을 인터페이스에 심을 수 있다는 데 있다. 스크립트에서는 사용자가 유효범위 밖 온도를 넣는 실수를 코드 안의 검사문으로 막아야 했지만, 대시보드에서는 그런 입력이 아예 불가능하도록 위젯을 설계할 수 있다. What-if: 슬라이더 범위를 300~600 K로 풀어 보라. 어떤 위험이 되살아나며, 사용자는 그 위험을 화면 어디에서도 알 수 없다는 점을 확인하라.
생각해보기 도구⑤~⑧ 중 하나를 골라 대시보드로 만든다고 하자. 어떤 값을 위젯으로 열고, 어떤 값을 코드에 못 박아 두겠는가? "사용자가 바꿔도 안전한가"를 기준으로 나누고 근거를 말하라.
13.3 회귀에서 신경망으로: 모델·손실·학습
13.3.1 두 얼굴의 오차
12장에서 데이터에 직선과 다항식을 맞추는 회귀(regression)를 다뤘다. 그 작업을 세 부분으로 나눠 이름을 붙이면 기계학습 전체의 뼈대가 된다. 모양을 가진 함수(모델), 모델이 얼마나 틀렸는지 재는 함수, 그리고 틀림이 줄어들도록 모델의 매개변수(parameter)를 조정하는 절차(학습)다. 틀림을 재는 함수를 손실 함수(loss function)라 한다.
가장 기본적인 손실 지표는 평균절대오차(mean absolute error, MAE)다. 데이터 n개에 대해 다음과 같이 정의한다.
MAE = (1/n) Σ |yi − ŷi| (13.1)
여기서 yi는 실제 값, ŷi는 모델의 예측값이다. MAE는 오차의 평균 크기를 그대로 알려 주고, 제곱을 쓰는 RMSE는 큰 오차를 더 무겁게 벌준다. 모델 성적을 눈으로 보려면 가로축에 실제 값, 세로축에 예측값을 찍는다. 이런 산점도를 패리티 플롯(parity plot)이라 하며, 완벽한 모델이라면 모든 점이 대각선 위에 놓인다.
성적의 기준선도 필요하다. 모든 입력에 대해 평균 하나만 답하는 상수 모델은 뜻밖에 유용한 기준선이다. 이보다 못한 모델은 아무것도 배우지 못한 것이다. 그런데 여기에 함정이 하나 있다. 지금까지처럼 갖고 있는 데이터 전부로 피팅하고 같은 데이터로 성적을 매기면, 그 성적은 무엇을 말해 주는가? 모델을 만드는 이유는 아직 보지 못한 데이터를 예측하기 위해서다. 그래서 데이터를 둘로 가른다. 모델을 맞추는 데 쓰는 부분을 훈련 데이터(training data), 성적을 매기기 위해 감춰 두는 부분을 시험 데이터(test data)라 한다. 학생이 시험 문제를 미리 보고 공부하면 점수가 실력을 말해 주지 않는 것과 같은 이치다.
예제 13.3-1 훈련 오차와 시험 오차는 다르게 움직인다
문제 반응 온도 60~100 °C에서 수율(%)을 측정한 가상 조업 데이터 16점을 난수로 생성하고, 훈련 12점/시험 4점으로 나눠 1차·2차·9차 다항식을 피팅하라. 차수별로 훈련 MAE와 시험 MAE를 비교하라.
풀이 전략 참 관계를 우리가 직접 심은 가상 데이터를 쓴다. 그래야 어떤 모델이 "맞는" 모델인지 답을 알고 채점할 수 있다. 코드는 12장에서 쓴 polyfit 그대로라 AI 없이 직접 짠다.
import numpy as np
rng = np.random.default_rng(1) # 재현 가능한 난수 시드
T = np.linspace(60, 100, 16) # 반응 온도 [degC]
y = 20 + 1.5*T - 0.008*T**2 # 우리가 심은 참 관계 (2차) [%]
y = y + rng.normal(0, 1.0, T.size) # 측정 잡음 [%p]
idx = rng.permutation(T.size) # 순서를 무작위로 섞는다
train, test = idx[:12], idx[12:] # 훈련 12점 / 시험 4점
for deg in [1, 2, 9]:
coef = np.polyfit(T[train], y[train], deg) # 훈련 데이터로만 피팅
err_tr = np.polyval(coef, T[train]) - y[train] # 훈련 오차 [%p]
err_te = np.polyval(coef, T[test]) - y[test] # 시험 오차 [%p]
print(f"{deg}차: 훈련 MAE {np.mean(np.abs(err_tr)):.2f}, "
f"시험 MAE {np.mean(np.abs(err_te)):.2f}")
실행 결과는 다음과 같다.
1차: 훈련 MAE 1.19, 시험 MAE 0.87
2차: 훈련 MAE 0.52, 시험 MAE 0.45
9차: 훈련 MAE 0.23, 시험 MAE 2.71
훈련 MAE만 보면 9차가 최고다. 차수를 올릴수록 훈련 오차는 반드시 줄어든다. 유연한 곡선일수록 점들을 더 바짝 통과할 수 있기 때문이다. 그러나 시험 MAE는 정반대의 이야기를 한다. 9차의 시험 오차는 2차의 여섯 배다. 9차 곡선은 측정 잡음까지 통째로 외워 버렸고, 그 암기는 새 데이터 앞에서 무너진다.
- 단위 체크: 수율과 오차 모두 %p이므로 온도(°C)와 섞이지 않았는지 확인
- 대조값: 2차 피팅의 계수가 우리가 심은 참 관계(20, 1.5, −0.008)에 가까운지 출력해 비교하라(가상 데이터의 특권이다)
- 극한값 sanity: 9차 곡선을 범위 밖 55 °C로 외삽해 보라. 수율이 물리적으로 불가능한 값으로 발산한다
분석 훈련 데이터의 잡음까지 외워 새 데이터에서 오히려 나빠지는 현상을 과적합(overfitting)이라 한다. 유연한 모델일수록 같은 문제라도 훈련 데이터가 조금만 달라지면 전혀 다른 곡선을 내놓는다. 그 민감함이 과적합의 정체다. 그리고 2차가 이긴 이유를 눈여겨보라. 데이터를 만든 참 관계가 2차였다. 데이터의 물리를 아는 사람이 모델의 모양을 잘 고른다. 화공 엔지니어가 기계학습에서 갖는 이점이 여기에 있다. What-if: 시드를 학번 뒷자리로 바꿔 세 차수의 순위가 유지되는지 확인해 보라.
실무 데이터에는 참 관계가 없으므로 결정계수(coefficient of determination, R²) 같은 지표로 판단을 보조한다. 화학공학의 실측 데이터에서는 R²가 0.9를 넘으면 대체로 훌륭한 수준이고, 0.95를 넘으면 오히려 과적합을 의심하라는 경험칙이 있다. 높은 점수가 항상 좋은 소식은 아니다.
13.3.2 신경망: 모양을 데이터가 정하는 함수
직선 모델의 매개변수는 기울기와 절편 2개다. 9차 다항식은 10개다. 이 수를 더 늘리면 무슨 일이 생기는가? 신경망(neural network)은 "입력의 가중합을 구하고 단순한 비선형 변환을 거치는" 작은 함수를 층층이 쌓아 만든, 매개변수가 대단히 많은 유연한 함수다. 다항식에서는 사람이 차수라는 모양을 골랐지만, 신경망은 모양 자체를 데이터가 정하게 한다.
그렇다고 새 수학이 등장하는 것은 아니다. 신경망의 학습도 손실 함수가 작아지는 방향으로 매개변수를 조금씩 반복 조정하는 절차이고, 성적은 시험 데이터의 MAE나 패리티 플롯으로 매긴다. 12장의 회귀에서 배운 모델–손실–학습의 3요소가 규모만 커진 채 그대로 있다. 1장에서 만난 대형 언어 모델도 다음 토큰을 예측하도록 이 절차로 훈련된 매우 큰 신경망이다. 학기 내내 함께 일한 AI가 사실은 이 절의 주제였던 셈이다.
유연함에는 대가가 따른다. 매개변수가 많을수록 과적합의 위험이 커지고, 필요한 데이터가 많아지고, 왜 그런 답이 나왔는지 해석하기 어려워진다. 그래서 신경망에서는 훈련/시험 분리를 반드시 지켜야 한다. 예제 13.3-1에서 9차 다항식이 보여 준 붕괴는, 매개변수가 수백만 개인 모델에서는 더 조용하고 더 그럴듯한 모습으로 일어난다.
생각해보기 어떤 모델의 시험 MAE가 상수 모델(평균만 답하는 기준선)보다 나쁘게 나왔다. 모델을 더 키우기 전에 의심해야 할 것은 무엇인가? 힌트: 입력 열과 정답 열의 순서가 서로 어긋나 짝이 깨진 데이터는 어떤 모델로도 배울 수 없다.
① 문제 정의 → ② 분해 → ③ 프롬프트 → ④ 생성 코드 읽기 → ⑤ 테스트 → ⑥ 화공 검증
대시보드는 ⑤·⑥을 화면 위로 끌어올린다. 위젯 범위가 곧 유효범위 검증이고, 실시간 그래프가 sanity 체크다. 기계학습에서는 ⑥이 "시험 데이터로만 채점한다"는 규칙이 된다.
13.4 칼럼: 화공 연구 현장의 기계학습, DFT와 MLIP
이 장에서 배운 3요소가 연구 현장에서 어떻게 쓰이는지 잠깐 엿보자. 새 촉매를 찾는 계산화학 연구에서는 반응물 분자가 촉매 표면에 얼마나 강하게 붙는지(흡착 에너지)가 성능을 가르는 핵심 물성이다. 이 값은 양자역학으로 분자와 재료의 에너지를 계산하는 밀도범함수이론(density functional theory, DFT)으로 구하는데, 계산 한 건에 많은 시간이 든다. 그래서 연구자들은 이미 수행된 대량의 DFT 결과를 훈련 데이터 삼아, 새 촉매 후보의 흡착 에너지를 곧바로 예측하는 기계학습 모델을 만든다. 이 분야에서는 실용적 의미가 있으려면 흡착 에너지의 MAE가 0.1~0.2 eV 수준이어야 한다는 목표가 통용된다. 모델의 성패를 가르는 잣대가 결국 시험 데이터의 MAE라는 점이 이 장의 예제와 같다.
한 걸음 더 나아간 도구도 있다. 원자들의 배치를 입력받아 에너지와 힘을 출력하도록 훈련된 신경망을 기계학습 포텐셜(machine-learned interatomic potential, MLIP)이라 한다. DFT의 정확도에 가까운 답을 훨씬 적은 비용으로 내는 것이 목표이며, 전지 소재나 촉매처럼 원자 수가 많은 시스템의 시뮬레이션에 쓰인다. 여기서도 뼈대는 모델–손실–학습 그대로이고, "훈련 범위 밖의 원자 배치에서는 믿을 수 없다"는 외삽 경고까지 Antoine 상수의 유효범위와 같은 논리로 따라온다. 13주차 이론 세션에서 담당 교수의 실제 연구 사례로 이 두 주제를 소개한다.
13.5 실습 13: 도구⑨ 공정 데이터 대시보드 + 서브프로젝트 스프린트
이번 실습(2시간)의 권장 배분은 도구⑨ 제작 45분, 서브프로젝트 스프린트 60분, 퇴실 전 위키 기록 15분이다. 도구⑨는 이번 학기 도구 사다리의 마지막 칸이다.
준비물
pip install streamlit설치 확인 (터미널에서streamlit hello가 브라우저를 열면 성공)- 스타터 repo의 공정 조업 데이터 CSV (시간·온도·압력·유량·수율 열)
- 재사용할 이전 도구: 12주차 이론에서 다룬 pandas 로딩·피팅 코드, 그리고 도구⑤~⑧ 중 계산 함수 1개 이상을 import한다
과제
- 실습 13.1 CSV를 pandas로 읽어 화면에 표로 표시하는 대시보드 뼈대를 만들어라. (성공 시
streamlit run dashboard.py로 브라우저에 데이터 표가 뜬다) 여기서 1차 커밋하라. - 실습 13.2 열 하나를 골라 시간에 대한 그래프를 추가하고, 4요소(축 라벨+단위·범례·마커/선·스케일)를 점검하라. (성공 기준: §13.1의 4요소 채점을 스스로 통과)
- 실습 13.3 위젯 2개를 달아라: 표시할 변수를 고르는 선택 상자 1개, 표시 구간을 자르는 슬라이더 1개. (성공 시 위젯 조작에 따라 그래프가 실제로 바뀐다) 여기서 2차 커밋하라.
- 실습 13.4 이전 도구의 계산 함수 1개를 연결하라. 예: 온도 열에 도구⑤의 증기압 함수를 적용해 파생 열을 만들고 함께 그린다. 위젯 범위는 그 함수의 유효범위로 제한하라. (성공 기준: 유효범위 밖 입력이 화면에서 불가능)
- 실습 13.5 README에 검증 3종(단위·대조값·극한값) 수행 기록과 대시보드 스크린샷 1장을 넣고 최종 커밋하라.
완성 기준 (통과/재도전 2단계. 재도전은 다음 실습 전까지)
streamlit run dashboard.py가 오류 없이 페이지를 띄운다- 위젯 2개 이상이 그래프를 실제로 바꾼다
- 모든 그래프가 4요소 점검을 통과한다
- 이전 도구의 함수 1개 이상을 import해 재사용했다
- README에 검증 3종 기록 + 스크린샷 1장
- 커밋 3회 이상 (기능 단위 메시지)
막혔는가?
- "
streamlit run을 실행했는데 브라우저에 아무것도 안 뜬다. 터미널 출력 전문을 붙여넣을 테니 원인 후보 3개와 각각의 확인 방법을 알려 줘." - "이 matplotlib 코드를 Streamlit 대시보드로 바꿔 줘. 위젯은 변수 선택 상자 하나만. 코드 전체를 다시 쓰지 말고 바뀐 부분과 그 이유만 설명해 줘."
- "CSV 열 이름 때문에
KeyError가 난다. 에러 메시지 전문과df.columns출력을 붙여넣을 테니 어느 쪽을 고쳐야 하는지 알려 줘."
서브프로젝트 스프린트 가이드 (60분)
9주차에 선언한 서브프로젝트의 v1을 오늘 만든다. v1은 완성이 아니라 핵심 기능 하나가 입력부터 출력까지 끊기지 않고 작동하는 상태를 말한다. 다음 네 가지를 점검하라.
- 핵심 기능 1개가 end-to-end로 작동하는가. 화면이 아니라 실행으로 보여라.
- 본인의 사다리 산출물 2개 이상을 재사용했는가 (서브프로젝트 공통 요건). import 문이 그 증거다.
- 검증 루틴 중 1종 이상이 내장돼 있는가.
- README 골격(문제정의·실행법·검증)이 잡혀 있는가.
스프린트 중 순회 컨설팅에서 물어볼 질문 1개를 미리 준비하라. "코드를 봐 달라"가 아니라 "이 설계 결정이 맞는지"를 물어야 60분이 산다. 페어 상호 코드리뷰는 다음 순서로 한다. 상대의 3분 EiPE 설명을 듣고, "이 줄을 바꾸면 어떻게 되는가" 질문을 하나 던지고, 검증 증빙을 확인한다. 이 형식은 14주 발표와 최종 시험 구술 방어의 리허설에 해당한다.
퇴실 전 기록 오늘 만든 것·막힌 것·틀린 것 중 1건을 위키에 커밋해야 퇴실한다. 추천 소재: 위젯이 그래프를 바꾸지 않던 순간의 원인, 또는 훈련 MAE와 시험 MAE가 갈라지던 실행 결과.
요약
S 13-1 공학 그래프 4요소: ① 축 라벨+단위 ② 범례 ③ 측정은 마커, 모델은 선 ④ 데이터에 맞는 축 스케일(지수적 변화는 로그축). AI가 그린 그래프는 항상 이 기준으로 채점한다(축 범위가 유효범위 안인지 포함해서).
S 13-2 MAE = (1/n) Σ |yi − ŷi|, 식 (13.1). 성적은 반드시 시험 데이터로 매긴다. 훈련 오차는 모델을 키우면 항상 줄지만 시험 오차는 그렇지 않다. 갈라지는 지점이 과적합의 시작이다.
S 13-3 대시보드 전환 프롬프트 패턴: "기존 함수를 import해 재사용하고, 위젯 범위는 유효범위로 제한하고, 주석은 한국어·단위 명기." 검증을 인터페이스에 심는 것이 대시보드의 본질이다.
| 항목 | 회귀 (12장) | 신경망 |
|---|---|---|
| 모델의 모양 | 사람이 고른다 (직선·다항식·Antoine) | 데이터가 정한다 (유연한 층 구조) |
| 매개변수 수 | 몇 개~십수 개 | 대단히 많다 |
| 필요한 데이터 | 적어도 된다 | 많이 필요하다 |
| 결과 해석 | 계수의 물리적 의미를 읽을 수 있다 | 직접 해석이 어렵다 |
| 공통점 | 모델–손실–학습의 3요소, 시험 데이터로 채점, 훈련 범위 밖 외삽 금지 | |
도구 사다리가 완성됐다. 단위환산에서 시작해 물성 조회, 증기압, T-xy, 물질수지, 압력강하, 데이터 피팅을 지나 대시보드까지, 아홉 개의 도구가 서로를 import하는 하나의 도구상자가 됐다. AI 협업 사이클로 보면 이 장은 ⑤ 테스트와 ⑥ 화공 검증을 화면 위로 끌어올린 주였다. 이제 만들기는 끝났고, 남은 것은 보여 주기다. 14장에서 이 도구상자를 3분 안에 설명하는 법을 다룬다.
용어 정리
- 범례(legend)
- 그래프에서 여러 데이터 계열을 구분해 주는 이름표.
- 로그축(logarithmic axis)
- 눈금 한 칸이 일정한 배수를 나타내는 축. 수십 배 이상 변하는 데이터에 쓴다.
- 대시보드(dashboard)
- 데이터와 계산 결과를 한 화면에 모아 사용자가 조작하며 보게 만든 것.
- 위젯(widget)
- 슬라이더·선택 상자처럼 사용자 입력을 받는 화면 요소.
- 회귀(regression)
- 데이터에 함수를 맞춰 변수 사이의 관계를 추정하는 방법.
- 매개변수(parameter)
- 모델의 모양을 결정하는 조정 가능한 수. 직선 모델이라면 기울기와 절편.
- 손실 함수(loss function)
- 모델의 예측이 실제와 얼마나 다른지를 하나의 수로 재는 함수.
- 평균절대오차(mean absolute error, MAE)
- 예측 오차의 절대값 평균. 식 (13.1).
- 패리티 플롯(parity plot)
- 실제 값 대 예측값의 산점도. 완벽한 모델이면 점이 모두 대각선 위에 놓인다.
- 훈련 데이터(training data)
- 모델의 매개변수를 맞추는 데 쓰는 데이터.
- 시험 데이터(test data)
- 모델 성적을 매기기 위해 피팅에서 감춰 두는 데이터.
- 과적합(overfitting)
- 훈련 데이터의 잡음까지 외워 새 데이터에서 성능이 오히려 나빠지는 현상.
- 결정계수(coefficient of determination, R²)
- 데이터 변동 중 모델이 설명하는 비율. 1에 가까울수록 설명력이 높다.
- 신경망(neural network)
- 가중합과 비선형 변환으로 이뤄진 작은 함수를 층층이 쌓은, 매개변수가 많은 유연한 모델.
- 밀도범함수이론(density functional theory, DFT)
- 양자역학에 기반해 분자·재료의 에너지를 계산하는 방법.
- 기계학습 포텐셜(machine-learned interatomic potential, MLIP)
- 원자 배치로부터 에너지와 힘을 예측하도록 훈련된 신경망.
연습문제
Q군: 개념·읽기 (AI 없이 풀 것)
- Q13.1 어떤 그래프가 세로축에 "P"라고만 적혀 있고, 측정점 10개가 실선으로만 이어져 있으며, 곡선 두 개에 범례가 없다. 4요소 기준으로 결함 세 가지를 지적하고 각각의 교정 방법을 쓰라.
- Q13.2 코드 13-3의 목적과 동작을 한국어 2~3문장으로 설명하라. 슬라이더를 움직이면 이 코드의 어느 부분이 다시 실행되는지도 말하라.
- Q13.3 예제 13.3-1처럼 극단적인 9차 다항식을 쓰지 않고도 과적합을 일부러 만드는 방법을 두 가지 제시하라. 각 방법이 검증 루틴 또는 훈련/시험 비교 중 무엇에 걸리는지 설명하라.
P군: 제작·계산 (AI 사용 전제)
- P13.1 도구⑨에 이동평균 창 크기를 고르는 슬라이더를 추가하고, 원본과 이동평균 곡선을 범례로 구분해 함께 그려라. 창 크기를 극단(1, 데이터 길이)으로 밀었을 때의 결과를 README에 기록하라.
- P13.2 학번별 물질의 Antoine 상수로 예제 13.2-1의 대시보드를 다시 만들어라. 슬라이더 범위를 그 물질의 유효범위로 제한하고, 검증 3종 수행 기록(상수 출처 포함)을 README에 남겨라.
- P13.3 과적합 탐험기를 만들어라: 코드 13-5의 데이터에 대해 다항식 차수를 슬라이더(1~12)로 고르면 피팅 곡선과 훈련/시험 MAE 두 값이 실시간 갱신되는 대시보드. 훈련 MAE와 시험 MAE가 갈라지기 시작하는 차수를 찾아 README에 보고하라.
위키 기록 과제 (이번 주 의미 커밋 1회 이상이 채점 지표다)
- 이 장 핵심 1페이지 정리(#seed): 그래프 4요소 + 모델–손실–학습 3요소 + "성적은 시험 데이터로"를 자기 언어로.
- "내가 틀렸던 것" 1건: 위젯·KeyError·과적합 등 오늘의 실수를 에러 화면 스크린샷과 함께.
- 타 과목 연결 1건: 화공양론이나 유체역학 실험 데이터 중 대시보드에 올리고 싶은 것 하나와 그 이유.