'데이터분석'에 해당되는 글 5건

  1. 뇌영상 데이터 분석 - Create Brain Mask
  2. 뇌영상 데이터 분석 - Matlab Index scheme
  3. Topological Data Analysis with R, (토폴로지 데이터 분석) (5)
  4. Slice Timing Correction
  5. 맥미니 몽고디비 분산 시스템 (4) - Replica Set (3)

MATLAB을 이용하여 뇌영상 데이터를 분석하다 보면, 뇌영역에 해당되는 부분의 마스크Mask를 만들어야 하는 경우가 있습니다. 이러한 경우에는 뇌영상 데이터 분석 - Matlab Index scheme 강의에서 처럼 MATLAB의 index 기능을 이용하면 회색질, 백색질, 뇌척수액 등에 해당되는 뇌 영역을 indices 값을 얻을 수 있고, 각각의 인덱스 값의 합집합을 이용하면 전체 뇌영역에 해당되는 마스크Mask를 얻을 수 있습니다.

위에 그림은 회색질(Grey Matter, GM), 백질(White Matter, WM), 뇌척수액(Cerebro-spinal Fluid, CSF)의 3차원 공간에서의 확률 분포를 보여주고 있습니다. 각각의 영상은 SPM (Statistical Parametric Mapping)을 설치하면 자동으로 설치되는 영상파일 입니다.

이제 다음의 MATLAB 명령어를 통해서 뇌마스크(Brain Mask)를 만들어 보겠습니다. 다음과 같이 한줄씩 MATLAB 명령창(Command Window)에 입력해 보시면서, 각각의 명령어가 의미하는바가 무엇인지 결과를 확인해 보시면 많은 공부가 될것 같습니다. 

>> % Specify file path >> fn_GM = fullfile(spm('dir'),'tpm', 'grey.nii'); >> fn_WM = fullfile(spm('dir'), 'tpm', 'white.nii'); >> fn_CSF = fullfile(spm('dir'), 'tpm', 'csf.nii'); >> >> % read volume header information >> vo_GM = spm_vol(fn_GM); >> vo_WM = spm_vol(fn_WM); >> vo_CSF = spm_vol(fn_CSF); >> >> % read 3D volume image data >> GM = spm_read_vols(vo_GM); >> WM = spm_read_vols(vo_WM); >> CSF = spm_read_vols(vo_CSF); >> >> % find indices of brain matter mask (idbrainmask) >> idx_gm = find(GM>0.5); % GM mask with Prob(GM>0.5); >> idx_wm = find(WM>0.5); % WM mask with Prob(WM>0.5); >> idx_csf = find(CSF>0.5); % CSF mask with Prob(CSF>0.5); >> >> % Set operation to compute union of two indices >> idbrainmask = union(idx_gm, idx_wm); >> idbrainmask = union(idbrainmask, idx_csf); >> >> % Fill ones for ROI >> IMG = zeros(size(GM)); % create zeros matrix >> IMG(idbrainmask) = 1; >> >> % Write 3D image >> vout = vo_GM; % copy header information >> vout.fname = 'brainmask.nii'; >> spm_write_vol(vout,IMG);

ex1.m

위의 프로그램을 실행하기 위해서는 확률맵(grey.nii, white.nii, csf.nii)이 필요한데, 이 파일들은 위에 설명되어 있듯이 SPM을 설치하고 MATLAB에서 Set Path로 SPM의 경로를 설정해 주어야 접근 가능한 파일들입니다.

신고

매틀랩으로 데이터 분석을 하다보면 find() 명령어를 통해서 특정 index를 찾고, 해당되는 index 값에 대해서만 여러 연산을 수행하는 과정이 필요합니다. 매틀랩에서 행렬을 생성하게 되면 아래의 그림과 같이 Subscript space에서는 A(1,1) 또는 A(1,2) 등의 과정을 통해서 행렬의 각 요소에 있는 값을 얻어올 수 있습니다. 하지만, Subscript space에서 Index space로 변환을 하게 되면 A(1,1)은 A(1)로 접근이 가능하고, A(1,2)는 A(11)을 통해서도 행렬의 값을 얻을 수 있습니다.

가령 아래와 같은 10x20의 행렬 A를 생각해 보겠습니다. 숫자는 행렬의 index를 의미하는 것이고 색깔은 행렬 요소의 값을 의미합니다. 파란색은 0이고 빨간색은 1을 나타냅니다. 이제 Matlab의 find() 명령어를 이용해서 행렬의 값이 1인 요소들의 index 값들을 찾아보도록 하겠습니다.

위의 그림에서 오른쪽에 나와 있듯이 Matlab에서 (>> idx = find(A>0)) 이란 명령어를 통해서 값이 0보다 큰 행렬 요소들이 어느 위치에 있는지 알 수 있습니다. 

신고
국가수리과학연구소에서 병역특례로 근무하는 동안 (2011-2014) 다양한 수학자들을 만나 수 있었습니다. 그 중에서 위상수학(Topology)를 공부하신 박사님과 한 팀에서 일을 할 수 있게 되었는데, 이때 처음으로 토폴로지 데이터 분석 (Topological Data Analysis, TDA)라는 방법을 알게 되었습니다.

토폴로지 데이터 분석의 핵심은 고차원 위상공간의 매니폴드에서 얻은 포인트 클라우드 데이터를 간단하게 추상화 하여 그래프의 형태로 표현하는 것입니다. Filtration에 의해서 샘플된 데이터는 Simplicies를 구성하기 위해 사용되고, 이거한 simplicies들을 선으로 연결하여 매니폴드를 추상화 합니다. 

또한, 대수적 토폴로지(Algebraic Topology)를 이용하면 여러 매니폴드로부터 대수적으로 동일한 해석을 주는 그룹을 찾을 수 있습니다. 가령, 다양한 차원의 매니폴드에서 홀Holes 의 갯수를 알고 있다면 매니폴드의 토폴로지를 특징화 할 수 있습니다. 가령 컵과 도너츠는 홀Hole이 하나라는 점에서 토폴로지가 같다고 할 수 있습니다. 이렇게 토폴로지가 같은 특성을 갖는 것을 호몰로지 그룹이라고 하는데, 고차원 데이터에서 이러한 호몰로지 그룹의 특성을 파악 한다면 다양한 분야의 사람들이 데이터에 대해서 새로운 시각을 얻을 수 있을 것입니다.

지금까지는 대수적 위상수학의 기본에 대한 것만 설명했습니다. 위상수학이 실제 데이터 분석 분야에서 혁명적인 진보를 이를 수 있었던 것은 ‘Persistent Homology’ 때문이 아닐까? 생각해 봅니다. Persistent 호몰로지 알고리즘은 토폴로지적인 불변량을 다양한 스케일에서 볼 수 있게 해 준다. 여기에서는 특정 스케일에서의 Hole의 갯수가 중요하기 보다는 Hole의 갯수가 동일하게 유지되는 스케일의 구간이 어디인지? 가 더 중요한 질문입니다. 

바코드 형태의 그래프는 호몰로지 그룹을 계산함과 동시에 시각화가 가능합니다.바코드 그래프에서 주요한 관심은 x축 선상에서 길게 유지되는 그래프입니다. Bar의 길이가 짧은 것은 대부분 토폴로지 잡음에 해당되는 경우 입니다. Bar의 길이가 길게 유지되는 bit이 데이터의 특징을 설명해 줄 수 있는 호몰로지 그룹입니다. 다음의 코드는 R의 phom packages를 이용하여 iris data의 바코드를 그려줍니다.

install.packages("phom") # phom 설치   library(phom) # phom 설치 확인 data = as.matrix(iris[,-5]) head(data) max_dim = 0 max_f = 1 irisInt0 = pHom(data, dimension=max_dim, # maximum dimension of persistent homology computed max_filtration_value=max_f, # maximum dimension of filtration complex mode="vr", # type of filtration complex metric="euclidean") plotBarcodeDiagram(irisInt0, max_dim, max_f, title="H0 Barcode plot of Iris Data")

위에 그림으로부터 3~4개 정도로 iris 데이터를 클러스터링 할 수 있을 것으로 생각할 수 있을 것이다. Filtration value가 0에서 1로 변하는 동안 계속해서 유지 되는 클러스터가 2개이고 0-0.7 동안 유지되는 바코드는 4개 정도이기 때문이다.


신고

Slice Timing Correction

하나의 3차원 뇌영상 데이터는 여러개의 단면영상(Slice Image)으로 구성되어 있다. 기능자기공명영상(functional magnetic resonance imaging, fMRI)의 경우에는 보통 매2초마다 하나의 3차원 볼륨 영상을 획득하게 된다. 다시 말해서 2초동안 여러개의 단면영상을 획득하게 되는데, 그중에서 제일 처음에 획득한 단면영상과 맨 마지막에 획득한 단면영상 간에는 최고 2초 정도의 시간 차이가 발생하게 된다. 이러한 시간 차이를 보정해 주는 것이 Slice timing correction이라 물리는 전처리 과정이다. SPM의 경우에 slice timing correction 을 적용하게 되면 'a'를 어두로 하는 새로운 뇌영상 파일이 생성된다.

단면영상의 순서(slice order)는 각 단면영상이 획득된 순서를 의미한다. 단면영상에서 순서로 정의해준 순서는 각 단면영상이 획득된 시간 순서를 의미한다. SPM에서 order of slices를 확인하기 위해서는 SPM Display에서 보고자 하는 뇌영상을 선택하고, cross-hairs를 z=1인 위치로 이동시키면 볼륨 영상의 첫번째 단면 영상을 가르키게 된다.

Slice timing 을 통해서 동일한 볼륨 영상 내에 서로 다른 시간에 획득된 단면 영상들이 마치 동일한 시간에 획득된 것 처럼 보정을 하게 된다. 보정 과정은 sinc-interpolation을 이용하고, 이것은 시계열 데이터를 lagging하는 효과를 낸다.

개념을 명확히 하기 위해서 예를 들어 설명해 보고자 한다. 가령 연속되는 단면 영상에 어떤 신경활동이 있다고 가정해 보자. A 단면영상의 값들은 t=0s에 획득되었고, B 단면영상의 값들은 t=1s에 획들되었다. 보정이 없다면 B 단면영상에 있는 혈류동역학 반응(hemodynamic response)은 사실상 B 영상이 획득되기 1초 전에 발생한 신호를의미한다. 이것을 보정하기 위해서는 B 단면영상에 있는 값들을 1초 전에 발생한 시점의 값들로 shifting 해야 한다.

Slice timing correction에서 중요한 점은 뇌영상 데이터를 획득한 순서를 명확히 알아야 한다는 것이다. 만약 잘 모른다면 뇌영상 획득에 도움을 준 방사선사 선생님들께 문의해서 영상 획득 순서를 숙지하고 있는 것이 좋다. 보통은 ascending (from bottom to top), descending (from top to bottom), interleaved (odd number slices and then even number slices)등의 순서로 획득된다.

지멘스Siemens MRI로부터 .ima 파일로 데이터를 저장했다면, MATLAB에서 다음과 같은 명령어로도 order of slice를 확인하는 것이 가능하다.

>>hdr = spm_dicom_headers(’dicom.ima’); >>slice_times = hdr.Private_0019_1029


이 경우 단면영상의 순서는 아래쪽으로부터 위쪽으로 증가하는 방향이다.


신고

1. Replica Sets + Sharding 시스템 구성

대용량 처리를 위한 분산 확장이 가능하고 안전성과 높은 가용성 보장을 위해 다음 그림과 같 이 Replica Sets을 구성하고, 이것을 토대로 Sharding 시스템을 구성할 수 있습니다.

4대의 맥미니를 이용하여 Replica Sets + Sharding 시스템을 구성 하는 것을 설명해 드리고자 합니다. 우선 각각의 노드에 다음과 같이 Config 서버와 Replica Set 서버 가 작동하도록 설정해 줍니다. Replica Set1은 모두 10001번 포트를 사용하고, Replica Set2는 모두 10002번 포트를 사용하며, Replica Set3은 모두 10003번 포트를 사용하도록 설정합니다.

node1: 192.168.3.1

$ mkdir /data/config1 /data/replset1 /data/replset3
$ mongod --dbpath /data/config1 --port 20001 &
$ mongod --dbpath /data/replset1 --port 10001 --replSet replset1 --oplogSize 1000 & 
$ mongod --dbpath /data/replset3 --port 10003 --replSet replset3 --oplogSize 1000 &

node2: 192.168.3.2

$ mkdir /data/replset1 /data/replset2
$ mongod --dbpath /data/replset1 --port 10001 --replSet replset1 --oplogSize 1000 & 
$ mongod --dbpath /data/replset2 --port 10002 --replSet replset2 --oplogSize 1000 &

node3: 192.168.3.3

$ mkdir /data/config2 /data/replset1 /data/replset2 /data/replset3
$ mongod --dbpath /data/config2 --port 20001 &
$ mongod --dbpath /data/replset1 --port 10001 --replSet replset1 --oplogSize 1000 & 
$ mongod --dbpath /data/replset2 --port 10002 --replSet replset2 --oplogSize 1000 & 
$ mongod --dbpath /data/replset3 --port 10003 --replSet replset3 --oplogSize 1000 &

node4: 192.168.3.4

$ mkdir /data/config3 /data/replset2 /data/replset3
$ mongod --dbpath /data/config3 --port 20001&
$ mongod --dbpath /data/replset2 --port 10002 --replSet replset2 --oplogSize 1000 & 
$ mongod --dbpath /data/replset3 --port 10003 --replSet replset3 --oplogSize 1000 &

각 노드별 설정이 끝나면, Replica Set을 초기화해야 한다. Replica Set을 구성할 때 Primary 서버와 여러 대의 Replica 서버로 구성된 환경에서 Primary 서버에 장애가 발생하면 MongoDB는 10초 이내에 다음 Primary 서버가 되어야 할 노드 하나를 선택해 줍니다. 이 경우, 아비타 Arbiter 서버가 활성화 되어 있으면 아비타가 적절한 서버를 선택해 주지만 사용자가 각 서버 에 대한 우선순위를 설정해 둔 경우에는 가장 높은 값을 부여받은 서버가 Primary 서버가 됩니다.

node1 - setting replica set1 (arbiter server: node3)

$ mongo 192.168.3.1:10001/admin MongoDB shell version: 2.2.5 connecting to: 192.168.3.1:10001/admin > db.runCommand( {"replSetInitiate" : {"_id" : "replset1", "members" : [ {"_id" : 1, "host" : "192.168.3.1:10001"}, {"_id" : 2, "host" : "192.168.3.2:10001"}, {"_id" : 3, "host" : "192.168.3.3:10001", arbiterOnly:true} ] } } )

node2 - setting replica set2 (arbiter server: node4)

$ mongo 192.168.3.2:10002/admin MongoDB shell version: 2.2.5 connecting to: 192.168.3.2:10002/admin > db.runCommand( {"replSetInitiate" : {"_id" : "replset2", "members" : [ {"_id" : 1, "host" : "192.168.3.2:10002"}, {"_id" : 2, "host" : "192.168.3.3:10002"}, {"_id" : 3, "host" : "192.168.3.4:10002", arbiterOnly:true} ] } } )

node3 - setting replica set3 (arbiter server: node1)

$ mongo 192.168.3.3:10002/admin MongoDB shell version: 2.2.5 connecting to: 192.168.3.3:10002/admin > db.runCommand( {"replSetInitiate" : {"_id" : "replset3", "members" : [ {"_id" : 1, "host" : "192.168.3.3:10003"}, {"_id" : 2, "host" : "192.168.3.4:10003"}, {"_id" : 3, "host" : "192.168.3.1:10003", arbiterOnly:true} ] } } )

이제 Config 서버를 설정하고 Replica Set을 Sharding으로 구성하는 과정이 남았습니다. 우선 node1, node3, node4 에 설정되어 있는 Config 서버들을 mongos로 연결시켜야 합니다. mongos 프로세스 설정을 위해서 node2에 접속 한 후에 다음과 같은 방법으로 mongos 프로세스를 설정할 수 있습니다.

$ mongos --configdb 192.168.3.1:20001,192.168.3.3:20001,192.168.3.4:20001 --port 27017 --chunkSize 64

이제 node2의 mongos 프로세스에 접속해서 ‘addShard'를 통해서 Replica Sets을 Shard 서버로 등록하면 시스템 구축이 모두 마무리 됩니다.

$ mongo 192.168.3.2:27017/admin mongos> mongos> db.runCommand( {addShard : "replset1/192.168.3.1:10001,192.168.3.2:10001, 192.168.3.3:10001"} ) // add replset1 as shard server mongos> db.runCommand( {addShard : "replset2/192.168.3.2:10002,192.168.3.3:10002, 192.168.3.4:10002"} ) // add replset2 as shard server mongos> db.runCommand( {addShard : "replset3/192.168.3.3:10003,192.168.3.4:10003, 192.168.3.1:10003"} ) // add replset3 as shard server mongos> mongos> use config // Config 설정에서 샤딩과 관련된 사항을 확인할 수 있다 mongos> db.shards.find() // Shard 서버 목록 확인 mongos> sh.status() // Shard 서버의 상태 확인


신고