"아레니우스 방정식(Arrhenius Equation)"을 이용한 속도 상수와 활성화 에너지(E_a) 도출 문제입니다.
겉보기에는 지수 함수(k = A e^{-E_a / RT}) 형태라 2차 곡선처럼 보이지만, 양변에 자연로그(ln)를 취해 선형(1차식)으로 변환한 뒤 np.polyfit을 사용하는 방식입니다. 공학 데이터 분석에서 데이터 변환(Linearization) 후 피팅하는 아주 중요한 테크닉을 배울 수 있습니다.
💡 교재용 이론 배경 (학생 설명용)
화학 반응 속도 상수(k)는 온도(T)가 높아질수록 커지며, 그 관계는 아레니우스 방정식으로 나타납니다.
k = A \cdot e^{-\frac{E_a}{RT}}
이 식의 양변에 자연로그(\ln)를 취하면 다음과 같이 직선 방정식(y = ax + b) 형태로 변환됩니다.
\ln(k) = \left( -\frac{E_a}{R} \right) \cdot \left( \frac{1}{T} \right) + \ln(A)
X축 데이터: 온도의 역수 (\frac{1}{T}, 단위: 1/\text{K})
Y축 데이터: 속도 상수의 자연로그 (\ln(k))
기울기(a): -\frac{E_a}{R} \rightarrow 이 값으로부터 활성화 에너지(E_a)를 역산합니다.
기체 상수(R): 8.314 \text{ J/(mol·K)}
1. 준비할 데이터 파일 (4_data.csv)
온도(섭씨, ^\circ\text{C})에 따라 실험으로 측정된 반응 속도 상수(k) 데이터입니다.
Temp_C,Rate_Constant_k
25.0,0.012
35.0,0.034
45.0,0.089
55.0,0.218
65.0,0.5042. 화학 반응 데이터 분석 및 활성화 에너지 역산 코드(4_main.py)
아래 코드의 ## 여기를 채워주세요 (세 곳)을 채워서 완성 후 결과와 그래프가 출력되도록 디버깅 해 두세요.
import matplotlib.pyplot as plt
import numpy as np
class EngineeringDataReader:
def __init__(self, file_path):
self.file_path = file_path
self.x = np.array([])
self.y = np.array([])
def load_data(self):
temp_x = []
temp_y = []
try:
with open(self.file_path, "r") as file:
header = file.readline()
for line in file:
parts = line.strip().split(",")
if len(parts) == 2:
temp_x.append(float(parts[0]))
temp_y.append(float(parts[1]))
self.x = np.array(temp_x)
self.y = np.array(temp_y)
print(
f"[SUCCESS] {self.file_path}에서 {len(self.x)}개의 데이터를 성공적으로 로드했습니다."
)
except FileNotFoundError:
print(f"[ERROR] 파일이 존재하지 않습니다: {self.file_path}")
return self.x, self.y
# 1. 데이터 로드 (X축: 섭씨 온도, Y축: 속도 상수 k)
reader = EngineeringDataReader("4_data.csv")
temp_c, k_constant = reader.load_data()
if len(temp_c) > 0:
# 기체 상수 R (J/mol·K)
R = 8.314
# [중요] 2. 데이터 선형화 변환 (Linearization)
# 아레니우스 공식을 적용하기 위해 온도를 절대온도(K)로 바꾸고 역수를 취합니다.
T_kelvin = temp_c + 273.15
x_transformed = ## 여기를 채워주세요
# 속도 상수에 자연로그를 취합니다.
y_transformed = np.log(k_constant)
# 3. NumPy 분석: 변환된 데이터로 1차 직선 피팅 (y = a*x + b)
slope, intercept = np.polyfit(## 여기를 채워주세요)
# 4. 화학적 역산 (Physics/Chemistry Inversion)
# slope = -Ea / R => Ea = -slope * R
# intercept = ln(A) => A = exp(intercept)
calculated_Ea = -slope * R / 1000 # kJ/mol 단위로 변환하기 위해 1000으로 나눔
calculated_A = np.exp(intercept)
print("\n[화학공학 분석 및 아레니우스 법칙 역산 결과]")
print(f" - 선형화 방정식: ln(k) = {slope:.1f}*(1/T) + {intercept:.2f}")
print(f" - 역산된 활성화 에너지 (Ea): {calculated_Ea:.2f} kJ/mol")
print(f" - 역산된 빈도 인자 (A): {calculated_A:.2e} 1/s")
# 5. 예측 문제: 특정 온도(예: 50도)에서의 반응 속도 상수 k 예측하기
target_temp_c = 50.0
target_T_k = target_temp_c + 273.15
# 피팅된 직선 방정식을 이용해 ln(k) 예측 후, exp()로 원래 k값 복원
predicted_ln_k = ## 여기를 채워주세요
predicted_k = np.exp(predicted_ln_k)
print("\n[예측 문제 해결]")
print(
f" - 문제: 온도가 {target_temp_c} °C 일 때 반응 속도 상수 k의 값은?"
)
print(f" - 정답: {predicted_k:.4f}")
# 6. Matplotlib 시각화 (Arrhenius Plot)
# 추세선을 그리기 위한 촘촘한 1/T 데이터 생성
temp_c_trend = np.linspace(20, 70, 100)
x_trend = 1.0 / (temp_c_trend + 273.15)
y_trend = slope * x_trend + intercept
plt.figure(figsize=(8, 5))
# 1) 실험 데이터 산점도 (변환된 축)
plt.scatter(
x_transformed,
y_transformed,
color="black",
s=50,
zorder=5,
label="Experimental Data",
)
# 2) 선형 피팅된 아레니우스 추세선
plt.plot(
x_trend,
y_trend,
"b-",
linewidth=2,
label=f"Arrhenius Fit ($E_a = {calculated_Ea:.1f}$ kJ/mol)",
)
# 3) 50도 예측 지점 표시
plt.scatter(
1.0 / target_T_k,
predicted_ln_k,
color="red",
marker="*",
s=150,
zorder=6,
label=f"Prediction at {target_temp_c}°C (k={predicted_k:.3f})",
)
# 그래프 서식 설정
plt.title("Arrhenius Plot: ln(k) vs 1/T", fontsize=14)
plt.xlabel("Inverse Temperature 1/T (1/K)", fontsize=12)
plt.ylabel("Natural Log of Rate Constant ln(k)", fontsize=12)
plt.grid(True, linestyle=":", alpha=0.6)
plt.legend(loc="upper right")
plt.show()
else:
print("[ERROR] 데이터를 로드하지 못했습니다.")