[PostgreSQL, Greenplum] 상관관계 분석 (Correlation Coefficients using SQL, MADlib)
Greenplum and PostgreSQL Database 2020. 11. 29. 23:48예제로 사용하도록 연속형 데이터 4개 칼럼과 범주형 데이터 1개를 가지고 iris 샘플 데이터를 테이블로 만들어보겠습니다.
-- Iris data table
|
(1) SQL 로 두개 연속형 변수간 상관계수 구하기 |
공분산(Covariance)은 두 변량이 각각의 평균으로부터 변화하는 방향 및 양에 대한 기대값입니다. PostgreSQL, Greenplum DB에서 모집단의 공분산(Population Covariance)는 COVAR_POP(Y, X) 함수를 사용하며, 샘플 공분산(Sample Covariance)은 COVAR_SAMP(Y, X) 함수를 사용합니다.
(* 공분산, 상관계수 참고: https://rfriend.tistory.com/126)
피어슨 상관계수(Pearson's Correlation Coefficient)는 공분산을 표준편차로 나누어서 표준화해준 값으로서, -1~1 사이의 값을 가집니다. 1에 가까울수록 두 변수간에 양의 선형관계가 있고, -1에 가까울수록 음의 선형관계가 있으며, 0이면 선형관계가 없다고 해석합니다. PostgreSQL, Greenplum DB에서는 CORR(Y, X) 함수를 사용합니다.
----- b/w Y and X
|
(2) SQL 로 다수의 연속형 변수간 상관계수 행렬(Correlation Matrix) 구하기 |
------ Correlation Coefficients among multiple variables -- (a) Calculating pairwise correlation using corr(Y, X) function 1 AS column_position , 'sepal_length' AS row , 'sepal_width' AS col , CORR(sepal_length, sepal_width) AS corr_coef FROM iris UNION SELECT 1 AS column_position , 'sepal_length' AS row , 'petal_length' AS col , CORR(sepal_length, petal_length) AS corr_coef FROM iris UNION SELECT 1 AS column_position , 'sepal_length' AS row , 'petal_width' AS col , CORR(sepal_length, petal_width) AS corr_coef FROM iris UNION SELECT 2 AS column_position , 'sepal_width' AS row , 'petal_length' AS col , CORR(sepal_width, petal_length) AS corr_coef FROM iris UNION SELECT 2 AS column_position , 'sepal_width' AS row , 'petal_width' AS col , CORR(sepal_width, petal_width) AS corr_coef FROM iris UNION SELECT 3 AS column_position , 'petal_length' AS row , 'petal_width' AS col , CORR(petal_length, petal_width) AS corr_coef FROM iris; |
위의 SQL query를 sub query 로 넣고, manual 하게 테이블을 Pivot 하여 우리가 원하는 상관계수 행렬 (correlation matrix)를 만들어보겠습니다. 대각행렬에서 우상단에만 상관계수를 나타내고 좌하단에는 0으로 채워넣기를 하였습니다.
-- (b) Pivoting the table to get a correlation matrix SELECT |
원하는 상관계수행렬을 구하기는 했는데요, SQL query가 엄청 길어지고 또 복잡해졌습니다. 분석의 대상이 되는 연속형 데이터 칼럼 수가 늘어날수록 query가 더 길어지고 복잡해지는 구조여서 더 좋은 방법이 없을까 고민하게 됩니다. 짜잔~! 이럴때 PostgreSQL, Greenplum DB에서 쉽고 편하고 또 빠르게 분석하는데 쓸 수 있는 SQL 기반의 오픈소스 분석툴인 Apache MADlib이 있습니다!
(3) MADlib으로 다수의 연속형 변수간 상관계수 행렬 구하기 |
위의 (2)번에서 pure SQL로 했던 상관계수 행렬 구하기를 Apache MADlib의 madlib.correlation() 함수를 사용하면 아래처럼 단 3줄이면 끝납니다! 비교할 수 없을 정도로 SQL query가 간소해졌습니다!
----- Correlation Matrix using MADlib /* SELECT * FROM iris_corr_output ORDER BY column_position; |
(4) MADlib으로 다수의 연속형 변수간 그룹별로 상관계수 행렬구하기 (Correlation Matrix by Group using Apache MADlib) |
PostgreSQL, Greenplum DB에서 Apache MADlib을 사용했을 때 코드가 간소해지는점 말고 또 좋은 점 중의 하나는 그룹별 연산을 하기에도 굉장히 편리하다는 점입니다.
아래 예제는 class_name ('iris-setosa', 'iris-versicolor', 'iris-virginica') 의 그룹별로 상관계수 행렬을 구하기(correlation matrix by groups using MADlib) 입니다. 위의 (3)번 예제어서 'grouping column' 위치에 "class_name" 칼럼 이름만 추가하면 끝입니다. MADlib이 이처럼 "simple & powerful" 합니다. (만약 (2)번 방법으로 SQL로 일일이 group by 넣어서 query 짠다고 상상을 해보면 끔찍하지 않나요? ^^;)
-- Correlation Matrix by Groups using MADlib SELECT * FROM iris_corr_grp_output ORDER BY class_name, column_position; |
* Apache MADlib: https://madlib.apache.org/docs/v1.0/group__grp__correlation.html