ELISA 분석하기

4PL은 ELISA 실험에서 standard curve를 그릴때 가장 흔하게 사용되는 방법입니다.오늘은 ELISA 데이터에 사용되는 4 Parameter Logistic(이하,4PL) Regression을 파이썬을 가지고 해보겠습니다.

0. ELISA?

Enzyme-linked immunosorbent assay의 약자인 ELISA는 항체 항원 반응을 이용해 목적 단백질의 활성이나 결합력을 정량적으로 측정하는 방법입니다. 아주 긴 역사와 전통을 가지고 있는 것으로 자세한 내용은 위키피디아를 참고 하세요.

1. Four Parameter Logistic (4PL) Regression

많은 생물학적 데이터들은 간단한 선형회귀 모델과는 맞지 않습니다. 그래서 보다 복잡한 모델인 4PL이 더 잘 맞습니다. 4PL은 dose response 나 receptor-ligand binding 시험과 같은 실험에 적합합니다. 그래서 유용하죠. 이름에서 알 수 있듯 4개의 매개변수가 필요합니다. 그리고 S형태의 모양을 띄고 있습니다. 수식으로 표현하면 아래와 같죠.

$$ y = \frac{A-D}{1.0+(\frac{x}{C})^B} + D $$

  • x = 독립 변수(예; 처리한 시료량)
  • y = 종속 변수(예; 시료량에 따른 실험결과 값)

4개의 매개 변수가 뜻하는것은 다음과 같습니다.

  • A = 최솟값 (예; 시료를 처리하지 않았을때의 수치)
  • B = 커브의 경사 기울기
  • C = 커브의 중간점 (예; 경사가 급해지는 부분)
  • D = 최고값

위의 수식을 뒤집으면 실험에서 얻은 결과 값(y)로 부터 넣어준 미지의 시료의 값(x)를 알아낼 수 있습니다. 공식은 다음과 같습니다.

$$ x = C\left(\frac{A-D}{y-D}-1.0\right)^\frac{1}{B} $$

2. 실제 응용

ELISA 실험에서 얻은 데이터를 가지고, Standard curve를 그려 4개의 매개 변수값을 구해보겠습니다. 그런 다음 실험 측정값(y)을 통해 거꾸로 사용한 시료의 양(x)을 구해보겠습니다.

2.1. Standard curve 그리기

사용할 라이브러리를 불러옵니다.

In [1]:
# load modules
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
import pandas as pd

ELISA reader에서 얻은 데이터를 csv파일로 정리해서 불러옵니다.

In [3]:
# read data
df = pd.read_csv("./data/20171121_4PL_standard.csv")
df = df.iloc[::-1]  # reverse row
df
Out[3]:
Sample Conc Value
14 St15 0.010 -0.009
13 St14 0.031 -0.025
12 St13 0.094 -0.021
11 St12 0.282 -0.015
10 St11 0.847 -0.031
9 St10 2.540 -0.019
8 St09 7.621 -0.009
7 St08 22.862 0.019
6 St07 68.587 0.045
5 St06 205.761 0.094
4 St05 617.284 0.214
3 St04 1851.852 0.432
2 St03 5555.556 0.636
1 St02 16666.667 0.919
0 St01 50000.000 1.047

간단하게 설명하면 Standard 물질을 500,000 ng/ul에서 3배씩 연속희석하여 총 15번 희석했습니다. 각각의 시료에서 얻은 OD 결과값은 value값이고, 농도는 Conc열에 포함되어 있습니다. 그런다음 4PL 함수을 정의합니다.

In [4]:
# define 4pl logistic
def logistic4(x, A, B, C, D):
    """4PL logoistic equation."""
    return ((A - D) / (1.0 + ((x / C) ** B))) + D

scipy.optimizecurve_fit 기능을 이용해서 수식의 매개변수를 구하고, 각각의 4개 변수를 나타내면 다음과 같습니다.

In [5]:
xdata = df["Conc"]
ydata = df["Value"]
popt, pcov = curve_fit(logistic4, xdata, ydata)
print(popt)
[ -1.93893872e-02   7.36156893e-01   4.39117217e+03   1.23620082e+00]

이제 시각화를 통해 얼마나 curve fitting이 잘되었는가를 확인해보겠습니다. 아래와 같이 numpy를 이용해 선그래프를 그리기 위한 데이터를 만들어봅니다.

In [6]:
import numpy as np

x_fit = np.linspace(0.01, 50000, 50000)
y_fit = logistic4(x_fit, *popt)
y_fit
Out[6]:
array([-0.01930128, -0.01676145, -0.01503393, ...,  1.05665527,
        1.05665753,  1.0566598 ])

이제 실제 데이터는 점으로 표시하고, curve fitting은 선으로 표시하겠습니다.

In [7]:
plt.plot(xdata, ydata, "o", label="data")
plt.plot(x_fit, y_fit, label="fit")
# plt.legend()
Out[7]:
[<matplotlib.lines.Line2D at 0x7f38d743b9b0>]
No description has been provided for this image

앞쪽의 값들은 너무 좁아서 잘 보이지 않네요. 이럴때는 x축을 로그스케일로 변경하면 좀 더 편하게 볼 수 있습니다.

In [8]:
plt.plot(xdata, ydata, "o", label="data")
plt.plot(x_fit, y_fit, label="fit")
plt.xscale("log")
No description has been provided for this image

거의 절반의 샘플에서 0에 수렴하는 결과를 얻었지만, 전체적으로 curve fitting이 잘 된것을 확인할 수 있습니다.

2.2 미지의 샘플농도 구하기

이제 실험 값(y)을 가지고 standard curve에 대입해서 농도값(x)을 알아보겠습니다. 이것이 진짜 ELISA 실험을 하는 이유입니다.

먼저 아래와 같은 함수를 정의합니다.

In [9]:
# 역수를 구해서 OD값에서 conc 값 알아내기
def solvex(y, A, B, C, D):
    """rearranged 4PL logoistic equation."""
    return C * (((A - D) / (y - D) - 1.0) ** (1.0 / B))

위에서 정의한 함수를 가지고 y값이 1.0일때 x축의 값을 계산해보도록 하겠습니다.

In [10]:
solvex(1.0, *popt)  # OD가 1.0일때 Concentration 값
Out[10]:
32007.229532820107

정리하며,

결과값이 32000정도 나왔는데요, Standard curve에 대입해보면 얼추 맞는 것 같습니다.