2017년 12월 29일 금요일

아이패드 와이파이 안테나 교체

심한 충격을 받은 뒤 와이파이 수신이 잘 되지 않던 아이패드를 드디어 수리하였다. 와이파이 안테나가 내부에서 끊어졌을 것으로 짐작하고는 있었지만  게으름 탓에 몇 년 동안을 방치한 상태였다. 아마도 한 2 년? 수리를 위해 찾아간 곳은 사설 서비스 센터인 아이픽스 대전점이었다. 고장의 원인은 정확히 예상한 바와 같앗다.

수리를 마치고 나니 와이파이 신호가 너무나 잘 잡힌다. 개인적으로 그렇게 스마트한 생활을 하지 못하는 입장이라 모바일 기기를 여러개 들고 다니면서 철저하게 활용하지는 못한다. 아직까지도 다이어리에 만년필로 직접 기록을 하는 것을 좋아하니 말이다. 대신 이 아이패드는 음악 감상용으로는 아주 제격이다. 오디오 앰프(AIWA)를 연결한 뒤 인터넷 라디오 앱인 TuneIn을 구동하였다. 이 AIWA 마이크로 Hi-Fi 시스템은 USB host 기능이 있어서 PC 등을 직접 연결하는 것이 가능하다. 음원이 담긴 USB 매체를 꽂아서 재생하는 일반적인 오디오 앰프와는 조금 다르다. 아이패드용 카메라 연결 키트는 이럴 때에 매우 유용하다.


오랫동안 쓰지 않다가 인터넷에 연결을 하였으니 업데이트할 앱이 많다. 내장 메모리가 16GB에 불과한 구형 모델이라서 요즘의 기준에서는 미디어 기기로 100% 활용하기에는 어려움이 많다. 그러니 인터넷 서핑이나 유튜브, 인터넷 라디오 재생 정도의 용도라면 아주 적당할 것이다.

린 라디오(http://linnclassical.radio.net/app/)를 설치하려고 앱스토어에 접속하였다. iOS 버전이 10.0 이상이어야 한다면서 설치가 되지 않았다. 현재의 버전은 9.3.5(15G36)이다. 설정->일반->소프트웨어 업데이트에서도 이 버전이 최신이라고 표시되었다. 혹시 내 아이패드는 iOS 10으로 업그레이드가 되지 않는 구닥다리가 되고 말았나? 구글을 뒤져보았다.

내 아이폰·아이패드로 iOS10 쓸 수 있을까?

아! 아이패드 4세대부터 가능하구나! 내 아이패드는 3세대이다. 그냥 사파리로 접속하여 들어야 되겠다. 아이패드의 화면을 꺼도 사파리에서 재생하는 린 클래식 라디오는 재생이 된다. 하지만 TuneIn에서 듣는 것이 더 편하지 않을까? TuneIn 앱을 가지고 방송국을 찾으려고 만지작거렸다. 아하, 이미 favorites에 린 재즈, 린 라디오, 린 클래시컬을 전부 등록해 놓은 상태였었다. 얼마나 오랫동안 아이패드를 쓰지 않았으면 이런 것을 다 잊어버렸을까...

다음에 구입할 장난감은 아마도 블루투스 리시버가 아닐까? 어쩌면 아이패드의 이어폰 잭에서 앰프로 line in으로 직결하는 것이 음질 면에서는 더 나을지는 모르겠지만 말이다.

2017년 12월 28일 목요일

2017년의 마지막 주를 보내며

여름 무렵부터 한달에 15회 이상의 블로그 포스팅을 하자는 목표를 세웠다. 업무, 영화감상, 독서, 취미 등 일상에서 접하는 일들에서 기록으로 남길만한 거리를 뽑아내고, 대략 스토리를 정리하고, 컴퓨터 앞에 앉아서 키보드를 두드리고... 목표를 세우니 달성하는 데에는 큰 어려움이 없었다. 일년 동안 쓴 글의 수를 헤아려 보면 2015년이 186편으로 가장 많았고, 지금 쓰는 글은 2017년 160번째의 글이므로 그 기록을 넘기기는 힘들다. 2014년 말에 23개월 동안 머물렀던 부서를 나와 심리적으로 여유를 갖게 되면서 2015년에 많은 글을 블로그에 올릴 수 있었던 것으로 기억된다.


12월 28일(목)은 2017년의 마지막 주가 맞는가?

이를 명확하게 하려면 한 주의 시작은 일요일인가 혹은 월요일인가에 대한 질문부터 해결해야 한다. 달력에서는 관습적으로 일요일이 한 주의 시작인 것으로 표기하지만, ISO 공적표준에 따르면 한 주의 시작은 월요일이다. 따라서 위에 보인 2017년 12월 달력 그림에서는 31일은 2017년 마지막 주의 마지막 날인 것이다. 그러면 좀 더 복잡한 문제를 따져보자. 어느 주에 그 달(M)이 끝나고 새 달(M+1)이 시작한다고 가정하자. 그 주는 M달의 마지막 주인가, 혹은 M+1달의 첫 주인가? 이것에 대한 명확한 정의가 내려져야만 '5월 세번째 주 목요일에 만납시다'를 둘러싸고 문제가 생기지 않는다. 혹은 가장 흔한 예로써 마트의 휴무일(둘째 주 및 넷째 주 일요일)을 정확히 결정하는 문제도 그러하다. 정답은 그 주의 목요일이 M달이냐 혹은 M+1달이냐에 따라 달려있다. 다시 말해서 주의 과반(4일)이 어느 달에 속하느냐에 달린 것이다. 물론 이 물음은 한 주의 시작 요일이 무엇이냐가 명확함을 전제로 한다(일요일이 아니라 월요일이다!). 만약 목요일이 M달의 마지막 날이면, M달은 그 주의 날을 4일(즉 과반) 포함하고 있으므로 그 주는 M달의 마지막 주가 된다. 마찬가지로 목요일이 M+1달의 1일이라면, 그 주는 M+1달의 첫 주가 된다. 원칙은 이러하지만 혼동을 피하려면 몇째 주 무슨 요일이라는 표현보다는 '몇번째 무슨 요일'이라고 하는 것이 더욱 바람직하다. 예를 들어 미국의 추수감사절은 11월의 네번째 목요일인 것처럼. 생각해보니 네번째 목요일은 자동적으로 넷째주 목요일이 된다. 목요일은 어느 달의 첫째 주의 기준이 되니 말이다. 따라서 어느 달 1일이 토요일로 시작하는데 이를 그 달의 첫주라고 생각해서는 안된다. 이는 모두 국가표준(KS X ISO8610 "데이터 요소 및 교환 포맷-정보교환-날짜 및 시각의 표기")에 잘 나타나 있다.

두 줄 요약

  • 일주일의 시작은 일요일이 아니고 월요일이다.
  • 어느 달의 첫째주는 반드시 목요일을 포함해야 한다.

완벽한 개인의 입장에서 블로깅을 하는가?

컴퓨터라는 문명의 이기 덕분에 일과 놀이, 근무지와 집의 경계가 많이 허물어졌다. 나름대로의 철학을 갖고서 업무 영역과 사생활 영역을 엄격하게 분리하는 사람도 물론 있을 것이다. 예를 들어서 철저하게 익명으로 개인 블로그를 운영하면서 자기가 생계를 위해 어떤 일을 하는지는 절대로 드러나지 않게 하는 경우를 말한다. 만약에 공직에 있는 사람이라면 이를 더욱 철저하게 분리하는 것이 옳을 것이다. 정부기관에서 공적으로 추진하는 일에는 많은 사람들의 이해관계가 복잡하게 얽히게 되는데, 아직 기획 단계에 불과한 것을 비공식적인 통로를 이용하여 섣불리 공개했다가는 큰 문제가 될 수 있다.

반면 정치인들은 인터넷을 매우 적극적으로 사용한다. 새로운 주장, 정책 아이디어, 놀라운(?) 폭로, 대중에게 전하는 메시지 등을 열심히 쏟아내고, 언론은 이를 받아 적어서 뉴스로 만들어낸다. 각자 필요에 의해서 인터넷을 이용할 뿐이다. 개인적인 심정을 토로한 것인지, 혹은 참모진들과 회의를 거쳐서 면밀한 계산을 통해 준비된 글을 써 내려가는 것인지는 일반 대중이 알기 어렵다. 대중은 이를 '진심'으로 믿고 싶어하지만, 실제로는 다음 선거를 의식하여 의도적으로 쓴 글일지도 모른다.

이런 측면에서 나는 어떤 자세를 취하는 것이 가장 옳은 일일까? 나는 공무원은 아니지만(대신 잘못을 저지르면 공무원에 준하는 처벌을 받는다) 국가 차원의 연구 업무에 종사하는 사람이다. 큰 연구과제를 기획하거나 이를 주무르는 입장과는 전혀 관계가 없는, 말하자면 연구계에서는 일종의 '소시민'과 같은 사람이다. 내가 블로그에 글을 쓰는 행위와 관련하여 떠오르는 생각을 한번 가감없이 나열해 본다.

  • 근무 시간 중에 블로깅을 하는 것은 있을 수 없는 일이다. 직무 태만이다.
  • 연구와 관련된 정보는 특별한 결정이 내려지지 않는 한 기밀로 취급하는 것이 맞다. 이런 공개된 곳에 적어서는 안된다.
  • 생명정보학 교육 자체가 우리 조직의 중요한 업무 내용 중 하나다. 유전체학 동향이나 생명정보학 관련 실무 지식을 쉽게 풀어서 블로그에 쓰는 것은 업무의 연장이라고 볼 수 있다.
  • 나 자신도 업무를 위해서 리눅스/파이썬/R 등등을 쓰다가 막히는 부분이 생기면 구글링을 통해서 문제를 해결한다. 내 블로그를 통해서 일반에게 도움을 주는 것은 업무의 연장이라고 볼 수 있다.
  • 정당한 업무의 연장이라면 연구소 웹사이트를 이용해야 하는 것 아닌가?(그렇다면 공인의 영역에 있는 사람이 페이스북이나 트위터를 이용하는 것도 문제시해야 된다)
한가지 부정할 수 없는 사실은 나는 쓰고자 하는 에너지가 많은 사람이라는 것이다. 이러한 특성은 사람을 직접 대면하면서 발휘되는 사회성·사교성과는 별 관계가 없다. 여러 사람이 모인 자리에서 볼썽사납게 대화의 주도권을 쥐려는 사람이 있는가 하면(내가 대단히 혐오하는 사람의 유형), 비교적 조용히 있다가 돌아와서 컴퓨터 앞에 앉아 조곤조곤 키보드를 두드리는 것을 즐기는 사람도 있으니 말이다.

허용된 것만을 할 것인가, 금지하지 않은 일을 자유롭게 할 것인가 - 결국 이것으로 문제가 귀결된다. 나의 직장은 개별 직원이 실명으로 블로그를 운영하는 것을 금지하지도, 허용하지도 않았다. 금지하지 않은 일이고, 공공의 이익에 현저하게 해를 끼지는 것도 아니니 업무에 실질적인 지장을 주지 않는 범위 내에서 지금까지 해 온 그대로 에너지를 발산하련다.

2017년 12월 23일 토요일

LM1876 앰프 개조

납땜인두를 잡지 않고 할 수 있는 자작 앰프의 개조라면 기껏해야 스크류 터미널을 다시 조이거나 기판 고정 방법을 바꾸는 것 정도일 것이다. PCB 서포트가 적당하지 않아서 거의 1년 가까이 해체된 상태였던 LM1876 앰프를 재조립하였다(참조 글 - 또 만든 앰프, LM1876). 일반 PCB 서포트는 두꺼운 나무판 위에 적용하기가 어렵다. 간단하게 개조가 끝날 것으로 생각했었는데 새로 구입한 PCB 서포트와 방열판이 서로 닿아서 이를 개선하느라 애를 먹었다. 서포트를 갈아낼 수는 없는 노릇이라 방열판을 위쪽으로 높이 올려 달았다.


이번 개조 작업을 위해 디바이스마트에서 구입한 부품들이다. 아이디어 상품인 'PCB서포트 플라스틱 - L자형'과 스티커형 고무받침대이다. 이 서포트는 대전 소재의 케이스포유에서만 보이더니 이제는 여러 곳에서 판매한다.


재활용한 나사못을 돌리다가 목 부분이 부러지고 말았다. 자작인이 해결하기 가장 어려운 상황이다. 만약 고가의 알루미늄 샤시에 조립작업을 하다가 볼트의 목이 부러지면 벌어지면 정말 해결하기가 곤란하다. 바닥판은 대나무로 만들어진 것이라서 서포트를 살짝 돌려서 다른 위치에 나사못을 박았다. 대나무로 이런 판재를 만들 수 있다는 것이 놀랍지 않은가? 바닥판으로 쓰인 재료는 원래 휴대폰·메모판 거치대로 쓰이는 뱀부스테이션 제품이다.

뒷모습은 이러하다. 방열판, 뒷면 패널로 사용한 알루미늄판, 전원 트랜스포머 모두 버려진 브리츠 5.1 스피커에서 떼어내어 재활용을 한 것이다.


침실에서 무려 3 종의 앰프를 골라서 들을 수가 있게 되었다! 왼쪽은 이영건 선생님의 PCL86(14GW8) 초삼결 앰프이다. 오른쪽 아래의 것은 Sanken SI-1525HD 하이브리드 IC를 사용한 앰프인데 이번에 구입한 고무받침을 붙여서 전원 스위치를 조작할 때 뒤로 밀리지 않게 하였다. 만약 세심한 제작자라면(나는 아니다!) 이런 것을 감안하여 부품 선정을 했을 것이다. 


전원을 넣으니 파일럿 LED에 불이 켜진다. 침실에서 사용하기에 충분한 음량은 물론 볼륨을 높여도 잡음은 거의 느껴지지 않는다. 재활용한 방열판에 너무 구멍을 많이 뚫어서 보기에 흉하다. 오디오 자작용 방열판을 국내에서 온라인으로 살 곳이 마땅하지가 않다. 평강전자의 100x50mm 방열판(상품코드 HS1-1050) 정도가 눈에 뜨인다.


적은 수의 부품으로 간단하게 만들어서 음악을 즐기기에는 게인클론 종류의 앰프만한 것이 없다. 고급 부품으로 구성된 게인클론 키트를 팔던 chipamp.com 사이트가 없어져서 의아하게 생각하고 있었는데 AudioSector라는 새로운 이름으로 계속 활동 중이다. 저가 중국제 진공관 앰프(보드 혹은 키트)에 대한 관심을 접고 차라리 LM3875 앰프를 정성들여 만들어 보는 것이 나을 것이다.

LM3886을 이용한 Hi-Fi 앰플리파이어 제작 완벽 가이드를 발견하여 소개한다. Power에 맞춘 전원부 및 부품의 선정 등 설계 단계에서부터 PCB 레이아웃까지 그야말로 모든 정보가 전부 담긴 좋은 자료이다.


2017년 12월 22일 금요일

독서 기록(소설책 2권) - 밈:언어가 사라진 세상, 그 개와 같은 말

일부러라도 소설을 읽어야 하겠다고 생각을 할 때가 많다. 내가 주로 읽는 책은 과학기술, 사회과학, 자기계발 등에 심하게 편중되어서 순수문학에 해당하는 소설은 거의 펼치지 않는다. 어찌보면 등장인물, 복잡한 플롯, 문학적인 묘사 등에 내가 매우 약한지도 모르겠다. 외국 영화 한 편을 보아도 스토리가 헷갈리는데 소설은 오죽하겠는가. 등장인물의 이름을 따로 메모를 하면서 읽어나가지 않는다면 서로 뒤엉켜서 전개되는 소설의 전체적인 모습을 파악하는 것이 쉽지 않다. 예전보다 드라마·영화·소설의 구조가 한층 복잡해진 것도 원인이 될 것이다.

우리가 외국인의 얼굴을 개인별로 구별하는데 어려움을 겪듯이(외국인이 한국인에 대해서도 마찬가지일 것이며, 이는 심리학이나 인지과학에서도 이미 잘 알려진 이야기이다 - 링크), 외국 영화를 볼 때에도 마찬가지의 상황이 펼쳐진다. 오로지 상상으로만 이미지를 그려내야 하는 소설은 이러한 어려움이 더 크다고 생각한다. 특히 등장인물이 많고 전개 방식이 복잡하다면 말이다.


밈: 언어가 사라진 세상(원제: Word Exchange)

앨리너 그래이든 지음, 황근하 옮김. 인터넷 광고를 보고 구입하여 단숨에 읽은 책이다. 500 쪽이 약간 넘는 적지 않은 분량의 소설인데, 위에서 설명한 나 특유의 어려운 점은 있었지만 긴장감을 놓지 않고 흥미롭게 읽었다. 밈(Meme)은 원래 리처드 도킨스의 '이기적 유전자(1976)'에서 처음 등장한 개념으로 위키백과의 설명을 인용하자면 '한 사람이나 집단에게서 다른 지성으로 생각 혹은 믿음이 전달될 때 전달되는 모방 가능한 사회적 단위를 총칭하는 것'이다. 이 소설책에서 밈은 휴대폰이나 태블릿 PC 같은 최첨단 IT 기계로서 사람의 마음을 읽어서 표시하고 인터넷으로도 연결을 하는 장비이다. 예를 들어 '택시를 타고 집에 가야지'라고 생각을 하면 저절로 택시가 와서 행선지가 선택되고 계좌로부터 요금을 자동으로 지불해 주는 기계이다. 잔고가 부족하면 이를 알려주고, 식당에 가도 그냥 마음으로 먹고 싶은 것을 생각하면 디스플레이에 주문할 음식이 표시되는 것이다.

소설 속에서는 세상이 이렇게 돌아가니 사람들의 언어 능력이 현저하게 떨어진다. 글을 쓰기는커녕 읽으려고 애를 쓸 필요가 없다. 그러니 어휘 실력이 부족해져서 이런 상황에서 어떤 말을 써야 할지 고민스러울 때, '워드 익스체인지'라는 새로운 서비스가 등장한다. 사용자가 생각하는 것과 유사한 단어들을 뜻과 함께 나열하여 선택하게 하되 단어 몇십개에 몇 센트라는 요금을 받는 것이다. 워드 익스체인지는 궁극적으로 언어를 독점하기를 원한다. 전 세계에 하나밖에 남지 않은 사전 편찬회사로부터 판권을 사들여서 오로지 워드 익스체인지를 통해서만 유료 서비스를 하도록 만든다. 게다가 신조어를 만들어서 멋진 뜻을 붙인 사람에게 상금을 주는 경연대회도 주최를 하여 '단어'를 시장화하고 독점하려는 야심을 갖고 있다.

밈의 다음 버전은 이마에 어떤 장치를 부착하게 되어 있는데, 이것은 실제 사람의 신경세포와 연결되어 작동한다. 이 과정에서 유전체 내에 잠들어있던 레트로바이러스 유전자가 활성화되면서 사람들은 급격히 언어 능력이 상실되는 바이러스 질환에 걸린다...

이것이 대략적인 줄거리이다. 허무맹랑한가? 아니, 충분히 있음직한 시나리오이다. 이미 컴퓨터와 스마트폰의 등장으로 글을 직접 손으로 쓰는 것은 물론 긴 글을 주의깊게 읽는 능력이 줄어들었다고 한다. 단지 우리가 얕은 수준으로 읽어넘기는(손가락으로 쓸어넘기는...) 정보의 양은 과거에 비해 엄청나게 증가했을 뿐, 정말로 깊게 생각하고 유용한 정보를 추려내고 심사숙고하여 판단을 내리는 일은 얼마나 줄어들었는가? 이제 이러한 일은 인공지능(AI)에게 맡기려고 하지 않는가? 

얼마 전 힘겹게 마늘 한 접을 다듬던 아내가 이렇게 말했다. 깐 마늘 가격이 비싸다고 하는데, 이 수고를 생각하면 그게 절대 비싼 것이 아니라고. 아는 이렇게 대꾸했다. 로봇과 인공지능이 우리의 직업을 빼앗아가도, 마늘 까기는 절대 자동화가 되기 어려운 일이니 계속 살아남을 직업이라고. 그렇다. 많은 지식에 기초한 엄정한 판단을 요하는 일과, 로봇이 대체 가능한 일을 제외하면 이제 인간에게 남은 일자리는 단순한 일뿐이다.

이 소설의 저자 앨리너 그래이든은 나도 읽었던 니콜라스 카의 <생각하지 않는 사람들>을 많이 참조하였다고 했다. 니콜라스 카의 의견에 나도 동의한다. 당장 어제 서점에서 니콜라스 카의 2014년 작 <유리 감옥>을 구입하였다(인터뷰 기사).

레이 커즈와일이 내다보았듯이 특이점(singularity)으로 표현되는 미래는 과연 희망적일까? 아니면 이 소설과 니콜라스 카의 예측처럼 걱정스러울까? 우리의 손과 머리를 사용하여 계속 일을 할 수 있는 세상이 남아있어야만 한다고 생각한다.

임현 소설집 <그 개와 같은 말>

소설가 임현은 2014년 <현대문학>으로 등단하여 <2017 제8회 젊은작가상> 대상을 수상하하였다. 소설을 좀 읽어야 되겠다는 생각에 도서관 새로 들어온 책 코너에서 고른 책이다. <가능한 세계>에서 시작하여 <불가능한 세계>로 끝나는  총 10편의 단편 소설 묶음인데 생각보다 어렵다. 쉽게 말해서 전달하려고 하는 바가 무엇인지를 알기가 어려웠다는 뜻이다. 뒷편의 작품 해설을 살펴보고 다시 한번 읽어야 되겠다고 다짐했다. 이래서 나는 소설을 읽어야만 한다...

책 뒤의 작품해설은 평론가 임현경이 쓴 것이다. 문학평론가가 이런 글을 쓸 때, 오직 작품을 읽은 것만으로 써 내려가는 것일까, 혹은 작가를 직접 만나서 인터뷰를 하기도 할까? 기자가 아닌 이상, 후자의 방법을 택하지는 않을 것으로 생각한다. 작가는 작품으로 말하면 된다. 작가가 인터뷰 등의 방법을 통해서 자기의 의도를 설명해야 한다면, 작품이라는 것을 고통스럽게 창작하여 전할. 평론가와 독자의 입장은 분명 다를 것이다. 하지만 평론가 역시 작품을 통해서 작가가 전달하고자 하는 바를 알아내고 비평적인 글을 쓰는 것이 목표일 것이다. 일반 독자를 위한 <해설>을 쓰는 것이 문학 평론의 목적은 아닐 것이다. 작품에 대한 철저한 해설을 위해서 작가를 직접 만나고 싶은 생각도 들겠지만, 평론가가 작품을 분석하는 방법은 일반인이 작품을 읽는 방법과 판이하게 다른 도구를 통해서는 아닐 것 같다.

10편의 작품 중 어느 하나도 편안하고 쉬운 것이 없었다. 시간을 옮겨다니는 이야기 전개(<가능한 세계>), 2인칭 대상에게 이야기하듯 회상하는 구조의 <고두(叩頭)> 등. 작품해설을 보니 특히 <고두>는 문학동네의 2017 제8회 젊은작가상 수상작품집1에 수록되면서 화제가 되었다고 한다. 왜냐하면 이 작품은 2016년 말 '문단 내 성폭력' 고발(관련 기사 링크)이 시작되기 직전 발표되어 많은 오해를 샀기 때문이다. 원래 이 사건은 기성 작가의 성폭력 실태를 피해 여성들이 고발하면서 불거진 일이었다. 그런데 작품 <고두>에서 남교사와 학생의 부적절한 관계가 중요한 관계로 다루어지면서 공방이 벌어졌던 모양이다. 실제로 이러한 공방이 독자와 평론가들 사이의 설전으로 끝났는지, 혹은 작가 임현까지 나서서 뭔가 변명을 해야 하는 상황이 벌어졌는지는 모르겠다. 

문단 내 성폭력 사건은 '권력'을 가진 기성 작가가 상대적으로 약자인 신인 작가 또는 문학강좌 수강생을 상대로 저지른 불법적인 행동이 피해자의 고발을 통해서 수면으로 떠오른 것이다. 엄밀히 말하면 작품에서 다루어지는 불편한 내용을 가지고서 작가를 고발하고자 함은 아니다. 임현경이 쓴 작품 해설의 일부를 발췌해 본다.
문학이라는 이름으로 이런 이야기를 쓰는 짓은 그만하라는 말을 하고 싶은가... 재현에 있어서 문제는 '무엇을'이 아니라 '어떻게'다. 포르노냐 아니냐를 결정하는 것은 '어떤 섹스'를 하는지가 아니라 '어떤 카메라' 앞에서 섹스를 하는지다...이런 소설을 썼다는 건 결국 평소에도 이런 상상을 하다는 것 아니겠냐고 말을 하고 싶은가. 그런 당신은 살인자가 주인공인 소설을 읽을 때면 작가가 막 당신을 죽일 올 것 같고 그런가.
소설을 읽자. 동시대에 나온 단편 소설을.

주1) 젊은작가상이란 문학동네에서 2010년에 제정한 상으로, 등단 10년 이내의 젊은 작가들이 한 해 동안 발표한 중단편소설 중 일곱 편을 선정하여 시상하는 것이다. 선정된 작품은 단행본으로 매년 출간된다(출처).

2017년 12월 20일 수요일

요즘의 책상-Fi(Desk-Fi) 풍경

개인 사무실을 사용하는 장점 중 하나는 음악을 틀어놓고 일을 할 수 있다는 것이다. 쉽게 해체 가능한 패널로 사무실 벽을 만들어 놓아서 방음이 잘 되지는 않는다. 따라서 옆방 근무자에게 피해를 주어서는 안되니 주로 재즈나 클래식 음악 위주로 잔잔하게 음악을 듣는 편이다. 그러다가 옆 사무실 동료의 퇴근이 확인된 늦은 시간이나 휴일 근무 때에는 맘놓고 음량을 높인다.

왼쪽 위에 놓인 것은 LM1876 앰프 보드.

자작 TDA7265 앰프에 진공관(12AU7)_-MOSFET 헤드폰 앰프/프리앰프를 연결하였다. 프리앰프가 굳이 필요하지는 않은 상황이지만 진공관을 사용한 앰프가 주는 플라시보 효과인지 소리가 좀 더 찰지고 섬세해진다는 느낌이 들어서 항시 연결하여 사용하기로 했다. 이 진공관 앰프는 일종의 class A 앰프라서 발열이 상당하다. 반도체 소자에 가까이 놓인 불리한 입지조건으로 인하여 늘 열을 받고 있는 커패시터의 전해액이 바짝 말라버리지는 않을지 걱정이 된다.

한동안 납땜질을 잊고 살았다. 연말이 되니까 납땜인두의 열기와 플럭스가 녹을 때 피어오르는 연기(몸에 해롭다 - 집에서 취미로 납땜질을 하더라도 환기를 하고 작업 후에는 꼭 손을 씻어라!)가 그리워진다. 올해 초 OCL 앰프보드 조립의 실패(링크)로 말미암아 큰 좌절감을 맛본 이후로는 의욕을 상당히 상실한 것이 사실이다. 언젠가는 하드 와이어링으로 간단한 진공관 앰프를 만들어 보겠다는 원대한 희망은 이 일을 계기로 사그러들고 말았던 것이다.

요즘 관심을 끄는 것은 진공관 프리부와 audio power amplifier IC를 갖춘 하이브리드 앰프 보드이다. AC 18 V 전원 트랜스를 연결하도록 되어있는 것으로 보아 진공관은 저전압으로 동작하는 것으로 생각된다. 다만 6.3 V의 히터 전압은 어떻게 만들어내는지는 잘 모르겠다.


아니면 다음 그림처럼 요즘 많이 보이는 2x6J1 + FU32 싱글 앰프(3W + 3W)는 어떨까? 독특한 모양의 FU32는 오디오 전용은 아니고 송신용 쌍4극관이다.

https://www.aliexpress.com/store/product/Music-Hall-Latest-APPJ-Assembled-FU32-Tube-Amplifier-Audio-Single-Ended-Class-A-Power-Amp-Board/1034564_32802960421.html

그렇지만 LM1876 앰프 보드를 파워트랜스포머 및 단자대와 함께 제대로 고정하는 일이 선행되어야 할 것이다. 상자 모양으로 짜지 말고 적당한 크기의 자작나무 합판에 보드를 그대로 올리는 방식을 택할 예정이다.

2017년 12월 19일 화요일

아이핀(i-PIN)? 뭐 이런 게 다 있지?

한겨레신문사와 관련이 있는 어떤 웹사이트에 회원 가입을 하러 들어갔다. 본인 인증을 반드시 해야만 되는 것은 이해가 된다. 그런데 보통 제공하는 휴대폰 본인 인증은 없고 오로지 아이핀을 통한 인증만 된다는 것이다. 뭐 어려울게 있을까 싶어서 시작을 했는데...

정말이지 애꿎은 컴퓨터를 집어던지고 싶은 마음이었다. 우선 신규 발급 화면 자체의 문제를 보자. <아이핀> <공공IPIN> 이게 다 뭐란 말인가? 벌써 첫화면부터 사람을 혼란에 빠뜨린다.

비밀번호를 입력하는데 사용할 수 없다는 오류 메시지가 나온다. 숫자+영문자+특수문자를 섞어서 분명히 8자 이상을 만들었는데 왜 이런 것인가? [비밀번호 생성규칙]이라는 버튼이 있어서 클릭을 하니 다음은 보안상 취약해서 쓰지 못한다는 것이다.
<, >, (, ), #, ’, /, |
살다보니 별 규칙을 다 보겠다. 어쨌든 여기를 통과하니 이제는 또 두번째 인증 수단을 정하란다. 공인인증서는 유료로 발급받은 것만 되고, 2차 비밀번호는 무려 10글자가 넘어야만 한다. 

어찌어찌 신규 아이핀을 받았나 싶었더니 이제는 휴대폰에서 앱을 받아서 QR 코드와 번호 중 선택을 하여 입력을 하란다. 플레이 스토어에 들어갔더니 아이핀과 관련된 앱이 하나가 아니다. 나이스 아이핀, 사이렌24-아이핀, KCP 아이핀... 으아, 뭘 깔아야 한단 말인가!

휴대폰의 사이렌24-아이핀에서도 간편 암호와 2차 암호의 두 개를 설정해야 했고.. 정작 험한 과정을 거쳐서 아이핀을 받은 후 원래의 목표였던 웹 사이트 회원 가입을 위해 인증 버튼을 누르니...


끙... ID+비번+캡챠(난 캡챠가 너무 싫다! 알아보기가 매우 어렵다!)로 인증을 받는 것 말고도 그 아래에 간편인증이라는 것이 있다. 뭘 해야 하는 거지? 한참을 생각한 다음에 겨우 상황이 파악되었다. ID와 암호로 인증을 받든지, 아니면 중간의 <간편인증>을 클릭하면 새로 생성되는 창에서 QR 코드를 스캔하거나 번호를 3분 이내에 입력하여 인증을 받을 수 있다는 뜻이다. 아까 가입 과정에서 QR 코드가 나왔던 것은 아마도 간편인증 버튼을 잘못 클릭해서 그런 것 같다.

도대체 아이핀은 왜 만들어진 것인가? 주민등록번호를 사용하지 않고 본인 인증을 하기 위해 만든 것이라 하는데 그 종류가 서너가지나 되는 데다가, 사용이 저조하니 회원이 일정 수 이상인 사이트는 의무적으로 아이핀을 쓰게 만들었다고 한다. 전형적인 규제 발굴의 한 사례이다. 정상적인 지능을 지니고 모든 수준의 교육을 받을 만큼 받은 내가, 게다가 늘 컴퓨터 앞에서 일을 하는 내가 이렇게 쓰기 힘든 시스템이라면 얼마나 많은 사람이 아이핀 발급과 사용 앞에서 골탕을 먹고 있을까? 정말 정부는 이 시스템을 다시 한번 생각해 보기 바란다. 인터넷으로 신용카드로 뭐 하나라도 결제를 하려고 들면 이제는 겁부터 난다. 나도 모르게 깔리는 프로그램이 수두룩하고, 또 선택할 프로그램도 많고, 카드 종류도 선택해야 하고(외국 사이트는 16자리 번호/CVC 코드만 입력하면 되는데), 잘못 클릭하면 월 사용료가 나가는 프로그램을 써야 하니 말이다.

[하루에 한 R] 그래픽스 생기초 - plot area와 margin 등의 이해

R GUI에서 그림을 그리면 기본적으로 정사각형의 창이 뜨면서 그림이 그려진다. 백문이 불여일견이니 한번 해 보자.
> plot(1:10)

창의 가장자리에 마우스를 대고 적당히 끌어서 크기와 종횡비(aspect ratio)를 조절한 다음 화면을 캡쳐하든지(해상도가 낮은 그림이라면 이 정도로도 무방), 혹은 마우스 오른쪽 버튼을 눌러서 나오는 팝업 메뉴에서 복사(메타파일 또는 비트맵)를 하거나 파일로 저장(메타파일 또는 eps)을 하면 된다. 메타파일로 복사를 하면 파워포인트에서 붙여넣기를 할 수 있다.

그런데 마우스로 드래그하여 조정한 상태를 유지하면서 다른 종류의 그래픽 파일(png, pdf...)로 출력하려면 어떻게 해야 하는가? 조정한 상태의 전체 크기와 마진이 얼마인지를 알아야 이것이 가능하다. 그러면 먼저 마진(margin)의 개념을 이해하도록 하자. 마진이란 위에서 보인 그림에서 네모로 둘러친 부분(내부는 plot region)을 둘러싼 바깥 네 부분의 여백을 뜻한다. 마진은 X-/Y-축 설명과 타이틀 등이 위치하는 곳이다. outer margin도 있지만 기본 크기는 0으로 정의된다.

기본적으로 생성되는 그래픽 창의 크기는 7 x 7인치이다. 이것을 어떻게 알아내는가? dev.size() 또는 dev.size("cm")라고 입력한 뒤 출력되는 값을 보면 된다. 앞의 것은 인치, 뒤의 것은 센티미터 단위이다. dev.new()를 입력하여 그래픽스 창을 하나 띄운 다음 마우스로 드래그하여 크기를 바꾼 뒤 dev.size()를 실행해 보라. 조정된 크기가 R prompt에 나타날 것이다.

만약 랜드스케이프 형태(레터 용지의 크기)의 그림을 얻고 싶다면 다음과 같이 하라. 단위를 mm 또는 cm로 바꾸는 방법도 어디엔가는 있을 것이다. width와 height를 지정하는 숫자에 따옴표를 둘러싸는 실수를 하면 안된다.
> dev.new(width=11.0,height=8.5) # letter landscape
> dev.new(width=11.692,height=8.267) #A4 landscape
Plot을 파일로 저장하려면 그래픽스 디바이스를 연 뒤 다음과 같이 하면 된다.
> png("file.png")
> plot(...)
> dev.off()
마진의 크기는 mar(단위는 라인) 또는 mai(단위는 인치) 벡터로 확인할 수 있으며, plot region의 크기는 pin(단위는 인치) 벡터로 같은 일을 할 수 있다. 마진 벡터의 각 원소는 plot의 아래쪽으로부터 시계방향으로 돌아가면서 크기를 나타낸다. 즉 아래, 왼쪽, 위, 오른쪽의 순서인 것이다. 7 x 7 인치의 기본 그래픽스 디바이스를 띄운 다음 마진과 plot region의 크기를 확인해 보자.
> graphics.off()
> par()$mar
[1] 5.1 4.1 4.1 2.1
> par()$mai
[1] 1.02 0.82 0.82 0.42
> par()$pin
[1] 5.759999 5.149582
그래픽스 화면을 드래그하면 이들 수치는 어떻게 될까? 일단 창 안에 그림이 있어야 하니 간단하게 plot(1:10)이라고 입력을 하여 플롯을 얻은 다음 마우스로 창의 크기를 이리저리 바꾸어 본다. 그 다음에 par()$mai와 par()$pin을 각각 입력해 보라. 어떤가? 마진은 그대로이지만 plot region의 크기를 나타내는 pin의 값은 변했다. 실제 마우스로 그림의 크기를 변화시키면 마진의 크기, 글꼴, 라벨 등은 그대로인데 plot region 내부만 변형이 됨을 알 수 있다. 즉 마진의 설정이 우선하는 것으로 생각하면 된다. 그림을 너무 작게 줄여서 위 아래 마진의 합이 그림의 높이보다 큰 상태가 되면(좌우 마진도 마찬가지) ""figure margins too large"라는 메시지가 그래픽 디바이스 창에 나타난다. 그림을 줄여도 마진 영역은 그대로 지켜야 하니 plot region이 확보되지 않음을 의미하는 것이다.

마구 조정을 한 다음의 그림 전체 크기는 얼마일까? par()$fin으로 확인 가능하다. 그래픽스 디바이스를 끈 다음 다음의 명령을 실행해 보자. 기본 그래픽스 창의 크기를 표시할 것이다.
> par()$fin
[1] 6.999999 6.989582
그렇다. 대략 7 x 7인치에 해당하는 것이다. 이상의 작업을 통해서 내가 그리려는 적절한 그림의 크기와 마진을 알아냈다고 가정하자. 그러면 이를 par() 함수에 설정해 넣으면 된다. 마진의 기본 크기는 (5,4,4,2) + 0.1이다(단위는 인치가 아님). 다음의 예제에서는 크기와 마진을 임의로 설정한 플롯을 그려서 pdf 파일에 출력하는 방법을 보여주고 있다.
pdf("test.pdf",width=11,height=8.5)
par(mai=c(4,4,2,2))
plot(1:10,xlab="x label",ylab="y label",main="Main title",sub="sub title")
dev.off()
빨간 숫자는 마진의 크기를 나타낸다.

ggplot2를 쓰면 화려한 그림을 통해서 복잡한 데이터에 숨은 의미를 찾는 길이 더욱 쉬워진다. 그렇다 하더라도 plot의 크기와 마진에 대한 기본적인 조작 방법을 파악하는 것도 중요하다. 

gplots에서 heatmap.2() 레이아웃 변경


Moving color key in R heatmap.2를 참조하면 color key의 위치와 크기를 변경할 수 있다. Row 및 Col label을 잘 보이게 하려면 cexRow/cexCol 인수를 줄이는 것도 좋지만 heatmap.2(x, margins=c(5,20))과 같이 margins 인수를 써도 된다. 앞의 것은 바닥 마진, 뒤의 것은 오른쪽 마진의 크기이다. heatmap.2()로 만들어진 그림은 마우스를 대고 드래그를 한다고 해서 마진 부분이 늘어나서 가려졌던 라벨이 보이거나 하지는 않는 것 같다. key의 위치를 변경하거나 크기를 바꾸는 등 상세한 편집 작업을 하고 싶다면 Moving color key in R heatmap.2를 참조하라.

참고 사이트


2017년 12월 18일 월요일

독서 기록 - 통계의 힘(니시우치 히로무 지음/신현호 옮김)

2014년 12월에 구입해서 거의 다 읽었다가 마지막에 집중력이 흐려져서 독서를 마무리하지 못했던 책을 다시 붙들고 처음부터 꼼꼼하게 읽었다. 책의 정식 제목은 '통계의 힘'이지만 부제를 붙이면 '빅테이터를 지배하는 통계의 힘'이다. 요즘은 AI(인공지능)·4차 산업혁명에 약간 가리워진 느낌이 없지는 않으나 방대한 데이터로부터 의미를 추출하는 과정에서 통계의 중요성은 말할 나위가 없다.


이 책은 통계학 입문서나 교재가 절대로 아니다. 일반 독자에게 통계한 이런 것임을 보여주기 위한 교양 서적이다. 그럼에도 불구하고 회귀분석, 일반화 선형모델(generalized linear model), 빈도론자와 베이즈론자의 대립 등 그동안 피상적으로만 이해했던 중요한 개념들을 알기 쉽게 설명하였다. 특히 현대 통계학의 기반을 마련한 로널드 피셔와 그의 유명한 밀크티 일화가 소개되어 흥미를 돋우고 있다. 밀크티를 만들 때 홍차에 우유를 넣었는지, 혹은 그 반대로 우유에 홍차를 넣었는지를 정확하게 알아맞힌다는 어떤 부인의 주장을 검증하기 위하여 피셔는 세계 최초의 임의화 비교실험을 수립하였다. 그 과정은 피셔가 1935년에 쓴 책 <실험계획법(The Design of Experiments)>에 잘 소개되었다고 한다. 피셔는 비료가 작물의 생산성이 효과를 주는지를 알아보기 위하여 경작지를 어떻게 구획하고 각각 어떻게 처리를 해야 하는지를 상세하게 연구하였다고 한다. 말하자면 현대 통계학은 생물통계학의 역사와 그 뿌리가 같은 셈이다. 통계학이 먼저 확립되고 난 다음에 생물학 분야에 적용된 것이 아니라는 뜻이다.

55쪽의 도표 5에서는 빅데이터 관련 전문용어를 설명하고 있는데, 맨 마지막 칸에 보인 R언어에 대한 설명이 재미있다. '오픈소스의 통계해석용 언어'. 유료 소프트웨어를 살 수 없는 비교적 가난한 학자들이 사용하는 언어인데, 최근 갑자기 주목을 받고 있다. 엑사데이터나 그린플럼, 나아가 SPSS로부터도 직접 R 라이이브러리를 호출할 수 있게 되었다.'

이 책의 결론은 다음의 도표 한 장으로 나타낼 수 있다. 설명변수가 몇개인지 여부에 상관없이 일반화 선형모델을 사용하여 (거의) 모든 통계적 분석을 감당할 수 있다는 것이다.


문맹(文盲)보다 더 무서운 것이 통계맹이라는 말도 있다. 요즘은 새로운 주장을 하기 위한 근거로서 여러 수치 자료를 제시하는 경우가 많은데, 통계학적 관점에서 볼 때 오류가 있거나 심지어는 의도적으로 자료의 의미를 왜곡하는 일이 벌어지고는 한다. 오죽하면 '세상에는 두 가지 거짓말이 있으니 하나는 새빨간 거짓말이요, 나머지는 통계'라는 말까지 있지 않은가. 통계는 정확히 쓰여야 하고 어떤 주장을 일방적으로 지지하기 위한 목적으로 악용되어서도 안된다. 또한 단순한 집계와 통계를 구별할 줄 알아야만 한다. 수학적 리터러시(literacy - 읽고 쓰는 능력 또는 특정 분야의 지식), 특히 통계 리터러시가 있어야 이러한 근거를 이용한 잘못된 주장을 제대로 파악하고 대처할 수 있는 것이다.

데이터가 말하려는 것은 무엇인가? 이것을 정확하게 파악하는 것이 통계학의 중요한 목표 중 하나라고 본다. 데이터가 말하는 바를 귀담아 듣고 판단을 내리는 것은 결코 쉬운 노릇은 아니다. 그래서인지 지금은 이 과정 자체를 AI가 하도록 내버려 두는 것 같다. 가까운 예로 각종 인터넷 구매 사이트에서 내 구매 성향을 파악하여 쇼핑할 거리를 제안하는 서비스가 그렇다. 이렇게 판단 자체를 인공지능에 맡기고 남는 시간에는 더 가치있는 일을 하겠다는 멋진 전제와 함께 말이다. 그런데 과연 미래는 커즈와일이 예측한 대로 그렇게 장미빛으로만 돌아갈까? 최근에 읽은 소설 <밈:언어가 사라진 세상>(독후감은 곧 블로그에 쓸 예정)과 니콜라스 G. 카의 주장(IT doesn't matter (2003) - 하바드 비즈니스 리뷰, 2016년 블로터의 논평; 2014년 <유리 감옥, 자동화와 우리> 출간 직후의 인터뷰)을 보면 걱정이 밀려온다.
이 책(유리 감옥)은 소프트웨어 개발자를 포함 많은 직종이 '디스킬(Deskill, 일을 처리하는데 필요한 숙련도 수준이 낮아짐)' 될 수 있다고 경고한다. 업무 프로세스의 상당 부분이 기계로 넘어간다는 이유에서다.
그렇다고 러다이트(Luddites, 신기술 반대자)를 옹호하는 책은 아니다. 이보다는 우리를 대체할 시스템이 초래할 결과와 파장을 훌륭히 탐구하고 있는 책이다. 연방 항공청(FAA)의 항공 자동화에 대한 경고, 전자 의료 기록이 초래할 수 있는 비용 상승과 건강 악영향 등에서 카가 우려하는 부분을 확인할 수 있다.

통계학 자체는 가치 중립적인 도구이다. 이 점은 명심해야 한다. 통계적 결론을 악용하는 것, 그리고 최종 판단을 내리는 주체 역할을 하지 않으려는 것, 이 두가지를 경계해야 할 것이다.

Statistics for Biologists

과학잡지 Nature에서는 생물학자를 위한 통계학 정보 콜렉션을 운영한다.


Statistics in biology, practical guides, points of significants 및 other resources로 구성되어 있으니 통계학 입문서 단행본을 읽다가 지루해지면 종종 방문해 보도록 하자.

2017년 12월 15일 금요일

DataCamp의 온라인 데이터 과학 강좌

해들리 위컴의 강의를 온라인으로 들으라고? R 관련 강좌를 웹에서 둘러보다가 DataCamp라는 곳을 발견했다. R, python, ggplot2, machine learning 등 총 98개의 강좌가 서비스되는 중이다. 한 달에 29 달러를 내면 모든 강좌를 무제한으로 수강할 수 있으며, 연 단위로 결제하면 한 달에 25달러로 할인이 적용된다. 영어 수강에 자신이 있다면 충분히 들을 만한 강좌가 아닐까 한다.


늘어나는 데이터 과학자의 수요에 맞춘 유용한 서비스라고 생각된다.

대표적인 MOOC 서비스로 잘 알려진 Coursera에서도 데이터 과학 분야 아래에 data analysis, machine learning 및 probability & statistics 소분야로 나누어서 261개 강좌를 서비스한다. 존스홉킨스대에서는 Coursera 내에 총 10개 강좌로 구성된 Data Science Specialization를 제공한다.

MOOC에 대해서는 2015년 내 블로그에 작성한 글이 있다.

UST 교수법 워크숍을 다녀와서 - MOOC와 Flipped learning

한국형 MOOC를 표방하는 K-MOOC에서도 비슷한 성격의 강좌를 다수 서비스한다. 2015년 10개 대학이 참여하여 27개 강좌로 시작하여 2017년 12월 현재 개설된 강좌는 총 570개로 꽤 큰 규모로 성장하였다. Coursera는 2,000개가 넘는 강좌를 제공하고 있다. K-MOOC의 강좌 분류는 Coursera와 약간 달라서 '데이터 과학'과 같이 트렌디한 분류명은 없다.


데이터 과학에 해당하는 K-MOOC의 강좌는 어떤 대분야에 속해 있을까? 몇 가지를 조사해 보았다. 생각보다 다양한 대분야로 분산된 모습을 볼 수 있다.

  • [A.I. Series] R을 이용한 통계학개론 -> 자연
  • Machine learning for data science -> 공학
  • 인공지능 및 기계학습 -> 공학
  • 빅데이터의 세계, 원리와 응용 -> 사회과학
  • 빅데이터 첫걸음 -> 공학
  • 통계학의 이해 -> 자연
  • 데이터 과학을 위한 Python 입문 -> 공학
  • 바이오헬스 빅데이터 마이닝 -> 인문과학
  • 텍스트 마이닝 실전 및 분석 -> 공학
이제는 학교나 학원에 다니지 않고서도 이렇게 학습을 할 수 있는 기회가 널리 제공되고 있으니 기초 통계학이나 스크립트 언어 사용법을 배울 기회가 없었다고 변명을 하기는 점점 곤란해질 것이다. 앞으로 KOBIC의 차세대생명정보강좌에서도 이러한 점을 감안해야 할 것이다. 그리고 기존에 IT나 통계 실무 분야에서 교육 서비스를 제공하던 회사와의 상생 방안도 마련되어야 할 것으로 보인다.

2017년 12월 14일 목요일

[하루에 한 R] 매트릭스에서 특정 값을 갖는 row 추출하기

[작성 후 추가한 글] 제목이 잘못되었다. 엄밀히 말해서 매트릭스가 아니라 데이터프레임이다.

해들리 위컴(Hardley Wickham)은 뉴질랜드의 통계학자 및 데이터 사이언티스트이자 저명한 R 개발자이다. RStudio의 Chief Scientist이기도 한 그는 ggplot2(), dplyr 등 데이터 처리와 시각화에 탁월한 R 패키지를 다수 개발하였고 활발한 저술과 강연활동도 펼치고 있다. 그가 개발한 패키지들은 GitHub 사이트에서 볼 수 있다. Quora에는 이런 질문도 있었다. '어떻게 해들리 위컴은 패키지 개발을 통해 그렇게 R에 많이 기여할 수 있었나요?'

이 질문에 대해서 위컴 자신이 답을 달았다. 다른 사람이 쓴 답이 무슨 소용이 있으랴.

  • 나는 많이 씁니다. 침대에서 일어나자마자 매일 아침 60-90분 정도를 씁니다(코드? 아티클?)
  • 나는 많이 읽습니다. 300개 정도의 블로그를 팔로우하고, 트위터와 스택 오버플로우에서 R이라는 태그가 달린 글을 계속 봅니다. 물론 모든 글을 깊이있게 읽지는 못하고 훑어보는 수준이지만 나에게 큰 도움이 됩니다.
  • Chunking(덩이 짓기?). '컨텍스트 스위칭'은 비용이 많이 듭니다(여기에서 context switching이란 소프트웨어 개발에 관한 용어가 아니라 어떤 일을 하다가 다른 일로 전환하는 것을 의미하는 것으로 보인다). 동시에 여러 패키지를 작업하면 아무것도 되지 않습니다. 새로운 기능에 대한 문제점과 아이디어를 꾸준히 축적하고 있다가 임계 질량에 다다르면 이 패키지에 며칠을 보내는 식으로 일을 합니다.
한마디로 말해서 참 멋진 사람이다. dplyr 패키지에 대한 국문 소개는 양우성님의 웹사이트를 참조하면 좋다. 내가 여기까지 흘러들어오게 된 것은 인하대 유동현 교수님 덕분이다.

오늘은 데이터프레임에서 특정 조건에 맞는 행을 뽑아오는 방법에 대해 공부해 보려고 한다. 숫자를 가지고 조건에 맞는 행을 뽑는 것이 아니라, 캐릭터 값을 가지고 일을 하려는 것이다. 몇 천 유전자에 대한 blast 결과를 테이블로 출력하여 R로 읽어들여 데이터프레임으로 만든 다음 내가 관심을 갖고 있는 몇십, 혹은 몇백개의 유전자에 해당하는 hit row를 쏙 빼내려는 것이다. Genes of interest는 별도의 벡터에 저장된 상태라고 가정하자. Perl에서는 hash를 사용하여 if (exists $seen{$item}) {...}으로 늘 하던 일이다. 여담이지만 내가 Perl애소 이 기법을 처음 접한 것은 phred/phrap/consed 패키지의 phredPhrap 스크립트를 뜯어보면서였다.

dplyr 패키지를 쓰면 오늘 논하는 것을 포함하여 더욱 정교한 작업을 할 수 있을 것이다. 그러나 이 글을 작성하는 목적은 R base package의 기본 기능을 최대한 활용해 보자는 것이다. 핵심이 되는 것은 which() 함수와 %in% 연산자이다. 이 특수 연산자에 대한 도움말을 띄워 보자. 함수에 대한 도움말을 찾을 때만 help() 또는 ? 명령어를 쓰라는 법은 없다.
> ?"%in%"   # 또는 help("%in%")
a %in% b라고 입력하면 a 벡터의 모든 원소에 대해서 이 값이 b 벡터에도 존재하는지를 TRUE or FALSE로 출력하는 것이다. 실제 사례를 보자.
> a = c("A","B","C","D","E")
> b = c("C","D","E","F","G")
> a %in% b
[1] FALSE FALSE  TRUE  TRUE  TRUE
which() 함수를 이용하면 a 벡터의 원소 중 b에도 있는 것, 그리고 a에만 있는 것을 다음과 같이 출력할 수 있다.
> a[which(a %in% b)]
[1] "C" "D" "E"
> a[-which(a %in% b)]
[1] "A" "B"
벡터에 대하여 방법을 알아보았으니 어제 글에서 활용한 샘플, 즉 blast 결과 파일을 파싱한 데이터프레임에 대해서 이 일을 해 보자. 'd'라고 명명한 데이터프레임의 구조는 다음과 같다. head() 함수를 이용하여 앞부분만 발췌하였다.


추출할 유전자는 벡터 e(for extract)에 넣어두었다. 몇 개 되지 않으면 손으로 입력해도 되지만, 그 수가 많다면 파일로부터 읽어들이는 것이 현명할 것이다.
> e
[1] "BfmR" "CsuB" "PgaB" "EntA" "PlcD"
d$V1 컬럼의 값 중 e 벡터에 존재하는 것을 찾아서 그 row를 추출하면 된다. 코드는 다음의 한 줄이다. 각괄호 안의 쉼표를 빼먹어서는 안된다.
> d[which(d$V1 %in% e), ]
실제 실행 화면을 보자.


너무나 간단해서 내가 다 미안할 지경이다. 다음에는 데이터프레임의 row 혹은 column을 그룹 단위로 조작하는 방법에 대해서 공부해 보련다.

2017년 12월 13일 수요일

독서 기록 - 1코노미 외 4 권


1코노미(부제: 1인 가구가 만드는 비즈니스 트렌드)

이준영 지음. 1인 가구가 보편화하면서 나타날 새로운 비즈니스 기회에 대하여 쓴 책이다. 나는 이에 대해서는 다소 부정적이다. 1인 가구 구매력의 국가적 총합은 과연 과거 다인 가구의 그것을 월등히 초과할 수 있을까? 주택 구매나 육아 및 교육에 돈을 쓰지 않으니 '나'를 위해서 더 많은 지출을 할 수 있을까? 인구가 줄면 경제 전반에 활력이 떨어지고 소득 자체가 늘어나기 힘들다. 더군다나 사회 구성원이 재생산되지 않음으로 인해 획기적인 경제 체질 개선이 일어나지 않으면 더욱 밝은 전망을 하기 어렵다. 1인 가구가 늘어나는 것은 자발적인 선택도 있지만 가정을 꾸릴 경제적 여건이 되지 못하여 불가피하게 이를 선택하는 면도 있다. 이러한 현상을 골고로 고려하지 않고 지나치게 낙관적으로 쓴 책이라는 생각이 들었다. 그리고 지나치게 많은 신조어를 소개함으로써 책을 읽는 것이 아니라 인터넷 기사를 넘기는 느낌이었다.

고독력, 관태기(관계권태기), 자뻑, 포미족, 탕진잼, 0.5가구, 혼행, DD(Do not Disturb족), 혼놀족...

커피가 죄가 되지 않는 101가지 이유

로잔느 산토스, 다르시 리마 지음. 김정운 옮김. 커피(카페인)만큼 건강에 미치는 긍정적 효과와 부정적 효과에 대한 상반되는 연구 결과가 꾸준히 발표되는 기호식품도 없을 것이다. 커피 수십 잔 분량에 해당하는 카페인을 갑자기 섭취하면 당연히 좋을 리가 없다. 카페인은 인체에 가벼운 흥분을 일으키는 물질임은 분명하지만, 커피에는 폴리페놀의 일종인 클로로겐산(chlorogenic acid) 등 유익한 성분은 더욱 많다. 커피 원산지의 농부들이 과연 합당한 노동의 댓가를 받고 있는지는 좀 더 고민해 봐야 되겠지만, 커피를 마시는 것이 그들에게 도움이 됨은 분명하다. 즐겨 마시자! 단, 탄산음료나 에너지 드링크 등에 합성 카페인을 지나치게 많이 넣는 것은 법으로 규제를 하면 좋겠다.

어떤 경제를 만들 것인가(지금의 시대정신은 '행복한 경제 만들기'다)

김동열 지음. 34개 OECD 회원국 중 우리나라 국민의 행복감은 꼴찌 수준이다. 경제 규모는 세계 11위 수준이라고 하지만 고용 불안, 노후 불안, 소득 불평등이 우리를 짓누르고 있다. 한국 경제가 추구해야할 새로운 모델을 알아본 책이다. 이에 대한 방안으로서 통일 대비, 한일 FTA, 연금의 확충, 주택연금,세금 마일리지 등을 예로 들었다.

정서적 협박에서 벗어나라(부제: 내 마음을 옭아매는 영혼의 감옥)

저우무쯔 지음, 하은지 옮김. '네가 어떻게 나한테 이럴 수 있어!' 가장 가까운 사이에서 오히려 흔한 정서적 협박은 개인을 파멸에 이르게 한다. 일단 그 상황을 벗어나고, 거절할 줄 알아야 한다. 호의를 마땅한 권리라고 여기는 사람들에게 정서적 경계선을 세우고 단호하게 대해야 한다.

리얼리스트를 위한 유토피아 플랜(부제: 우리가 바라는 세상을 현실에서 만드는 법)

뤼트허르 브레흐만 지음, 안기순 옮김. 단연코 이번 독서의 하이라이트, 먼저 지난 10월 한겨레 신문 인터뷰 기사를 보자("주 15시간 일한다는 게 왜 비현실적인 거죠?"). 1988년 생으로 이제 서른살도 안된 젊은이가 그동안 우리가 굳건하게 믿어왔던 자본주의의 토대 - 가난은 나태·노력 부족에서 기인한다 - 를 허무는 급진적인 주장을 한다면 우리 사회에서는 이를 과연 받아들일까? 인류가 경험한 많은 실험 사례에서 기본 소득은 충분히 긍정적 효과가 있음이 입증되었다. '돈을 이리저리 옮기면서' 돈을 버는 금융 부문은 과감히 개혁하고, 노동 시간을 줄이고, 가치 있는 직업을 갖도록 노력하고, 기본 소득 지급을 통해서 현실 세계에서의 유토피아에 다가갈 수 있을 것으로 저자는 내다보고 있다. 다시 한번 더 읽고 싶은 책이다.

[하루에 한 R] BLAST tabular output에서 best hit 뽑아내기

BLAST+(최신 버전)가 완전히 정착된 것이 언제인데 나는 아직도 'legacy' BLAST(v2.2.26)를 즐겨 사용한다. blastall 커맨드 라인 사용법에 너무나 길들여져 있기 때문이다. BLAST+의 옵션 설명서를 인쇄하여 책상 앞에다 붙여놓아야 겨우 익숙해질까?

예전, 하지만 그렇게 오래 전도 아니던 시절, 미생물 유전체의 functional annotation을 하려면 Swiss-Prot이나 NCBI NR 데이터베이스를 로컬 컴퓨터에 받은 다음 수천 개의 query를 blastp로 날리는 일을 수시로 했었다. 요즘은 RAST server에 올려 버리거나, 로컬 머신을 쓴다 하여도 Prokka를 쓰면 단 몇 분에 해결이 되이 큰 용량의 공개 단백질 서열 DB에 대해서 BLAST를 직접 돌릴 일이 많지 않다. 또 그럴 일이 있으면 유료 서비스에 가입한 Blast2GO에서 검색을 수행하면 된다.

그래도 간혹 연구 목적을 위해 특별한 목적으로 만든 서열 데이터베이스에 대해서 BLAST를 실행할 일이 있다. 그 결과물을 파싱하는 프로그램을 직접 구현하는 것이 예전에는 매우 보편적인 생명정보학 실습 과제이기도 했다. 누가 그랬더라? 이제 제발 그런 거 하지 말라고...

사람의 눈으로만 보기 편한 BLAST 결과물을 컴퓨터에게 읽히려고 하니 프로그래밍으로 처리하기에 얼마나 불편하겠는가? 사실 내가 tabular output format(blastall -m 8 또는 -m 9; BLAST+에서는 -outfmt 6)에 관심을 가진 것도 얼마 되지 않았다. 이를 엑셀로 불러들이면 완벽하지는 않더라도 대량의 결과를 처리하기에 좋으니까 말이다. 엑셀의 귀재라면 각 query에 대한 hit 중에서 best를 골라내는 방법을 함수로 구현할 수 있을지도 모른다.

R을 사용하면 BLAST의 tabular format output으로부터 각 query에 대한 best hit을 쉽게 뽑을 수 있을 것이라는 생각을 오랫동안 하고 있었다. 사실 R 환경 자체에서 BLAST를 실행할 수 있는 rBLAST라는 패키지가 있으니 이 환경 안에서 best hit을 찾을 수 있을 것이고 또 더 검색을 해 보면 다른 도구가 있을 것이다. 범위를 좀 더 넓힌다면 reciprocal best hit을 찾아주는 유틸리티도 있을 것이다. 하지만 나는 좀 더 '하등한' 수준의 해결 방법을 알고 싶었다.

[SEQanswers] How to output only best-hit result using standalone blast <= 심지어 sort 명령어를 사용한 방법도 있다. one-liner를 즐기는 사람에게는 좋은 소일거리가 될 것이다.

그러면 본론으로 들어가서, blastall -m 9(tabular with comment lines; #으로 시작) 명령으로 작성한 결과물을 R에서 읽어들여서 best hit을 찾는 방법을 공부해 보자. 예전에 마이크로어레이 자료 분석을 공부하면서 control spot 때문에 한 유전자에 대한 형광 측정값이 여럿 존재하는 경우 이것의 median 값을 취하도록 R 코드를 짰던 것 같은데 도저히 기억이 나질 않는다. 아마 apply() 혹은 by() 계열의 함수를 쓰지 않았었나 생각한다.

그런데 구글링을 계속 해 보니 base R만을 이용한 아주 원초적인 방법을 제시한 글이 있어서 소개하고자 한다. 이 안에는 외부 패키지와 함수를 이용한 복잡한 방법도 포함되어 있다. 공부를 위해서 나머지 방법도 따라서 해 보아야 한다.

[Stack Overflow] Extract the maximum value within each group in a dataframe

blastall -m 9 옵션을 사용하여 출력 파일(tblastn.m9,.txt)을 만든 뒤 각 query에 대한 best hit을 뽑아보자.
> d = read.table("tblastn.m9.txt",sep="\t",comment.char="#",header=F)
> d
             V1   V2     V3  V4 V5 V6  V7  V8   V9  V10      V11    V12
1          BfmR bfmR 100.00 238  0  0   1 238    1  714 8.0e-156  423.0
2          BfmR bfmS  30.56  36 25  0  21  56 1437 1330  2.3e-01   22.3
3          BfmS bfmS  99.82 549  1  0   1 549    1 1647  0.0e+00 1083.0
4          BfmS bfmS  27.78  54 39  1 133 186  658  533  7.1e+00   18.9
5          BfmS  nfu  38.46  13  8  0 117 129  442  480  8.1e+00   18.5
6          CsuA csuA 100.00 192  0  0   1 192    1  576 2.0e-129  353.0
7          CsuA csuE  43.75  16  9  0 177 192  970 1017  4.5e-01   20.8
8          CsuB csuB 100.00 172  0  0   1 172    1  516 4.0e-114  312.0
...중간 생략
> do.call(rbind, lapply(split(d,d$V1), function(x) {return(x[which.max(x$V12),])}))
                       V1   V2     V3  V4 V5 V6 V7  V8 V9  V10    V11  V12
BfmR                 BfmR bfmR 100.00 238  0  0  1 238  1  714 8e-156  423
BfmS                 BfmS bfmS  99.82 549  1  0  1 549  1 1647  0e+00 1083
CsuA                 CsuA csuA 100.00 192  0  0  1 192  1  576 2e-129  353
CsuB                 CsuB csuB 100.00 172  0  0  1 172  1  516 4e-114  312
CsuC                 CsuC csuC 100.00 277  0  0  1 277  1  831  0e+00  568
CsuD                 CsuD csuD 100.00 832  0  0  1 832  1 2496  0e+00 1650
CsuE                 CsuE csuE 100.00 339  0  0  1 339  1 1017  0e+00  666
EntA                 EntA entA 100.00 256  0  0  1 256  1  768  0e+00  502
EpsA                 EpsA epsA  99.73 366  1  0  1 366  1 1098  0e+00  727
NfuA                 NfuA  nfu 100.00 212  0  0  1 212  1  636 2e-162  438
OmpA_partial OmpA_partial ompA 100.00 315  0  0  1 315  1  945  0e+00  592
pgaA                 pgaA pgaA 100.00 747  0  0  1 747  1 2241  0e+00 1544
PgaB                 PgaB pgaB  99.80 510  1  0  1 510  1 1530  0e+00  980
PgaC                 PgaC pgaC 100.00 392  0  0  1 392  1 1176  0e+00  805
PgaD                 PgaD pgaD 100.00 154  0  0  1 154  1  462 6e-101  278
PlcD                 PlcD plcD 100.00 487  0  0  1 487  1 1461  0e+00 1018
Ptk                   Ptk  ptk 100.00 727  0  0  1 727  1 2181  0e+00 1372
V1(query)의 값이 동일한 hit group에 대해서 V12(bit score)가 최대인 것을 출력하는 것이다. 어떻게 이보다 더 간단명료할 수 있겠는가?

[하루에 한 R] order() 함수의 이해

어떤 벡터가 있을 때 sort() 함수를 적용하면 그 원소들을 다음과 같이 오름차순으로 정리하여 출력한다. 내림차순으로 정동하고 싶으면 decreasing=T를 설정하면 된다.
> x = c(1,5,3,2,4)
> sort(x)
[1] 1 2 3 4 5
order() 함수는 벡터의 원소를 이 인덱스 번호순으로 놓으면 값이 정렬된다는 것을 의미한다. Character 타입의 벡터를 사용하여 설명하는 것이 이해하기 쉬울 것이다. 이를 이해한다면 아래에서 보인 마지막 명령이 무엇을 뜻하는지도 납득할 수 있다.
> y = c("a","c","e","b","c")
> sort(y)
[1] "a" "b" "c" "c" "e"
> order(y)
[1] 1 4 2 5 3
> y[order(y)]
[1] "a" "b" "c" "c" "e"
order(y)를 사용하여 알 수 있는 것은 벡터 y의 원소를 값에 따라서 순서대로 나열하려면 첫번째, 네번째, 두번째, 다섯번째, 그리고 세번째 원소의 순서대로 놓으면 된다는 것이다.

order() 함수를 이용하면 행이나 열을 name에 따라서 정렬하는 것도 가능하다. 연습용 4x3 매트릭스를 만들고 colnames()로 각 열에 이름을 붙인 뒤 이것에 따라서 컬럼을 정렬하는 연습을 해 본다. 컬럼의 위치만 바뀔 뿐 각 컬럼 내의 값은 원래의 행 번호를 그대로 지킨다.
> z =  matrix(c(4:1,12:9,5:8),4,3)
> z
     [,1] [,2] [,3]
[1,]    4   12    5
[2,]    3   11    6
[3,]    2   10    7
[4,]    1    9    8
> colnames(z) = c("A","C","B")
> z
     A  C B
[1,] 4 12 5
[2,] 3 11 6
[3,] 2 10 7
[4,] 1  9 8
> z[, order(colnames(z))]
     A B  C
[1,] 4 5 12
[2,] 3 6 11
[3,] 2 7 10
[4,] 1 8  9
apply()와 join() 계열의 함수를 잘 써야 하는데... 아직도 멀었다!

2017년 12월 12일 화요일

Pseudomolecule을 만들 때 사용할 space sequence

Pseudomolecule 혹은 pseudo-molecule이란 contig sequence의 사이에 적당한 spacer sequence를 넣어서 이어 붙인(concatenation) 염기서열을 말한다. 말하자면 가상의 염색체에 해당하는 염기서열인 셈이다. Contig들의 연결 순서는 reference sequence와 비교했거나 혹은 pair end sequencing read의 alignment를 이용하여 사실에 가깝게 결정해 놓은 다음 연결하는 것이 가장 바람직할 것이다. Spacer의 길이는 실제 sequence gap을 반영하도록 설계하면 더 좋을 것이다. 그러나 항상 이러한 행운이 따르는 것은 아니라서, 연결 정보가 마련되지 않은 contig 서열을 그냥 이어 붙이는 경우도 종종 있다. Contig의 순서는 어떻게 할 것인가? 특별히 따라야 할 규칙은 없지만 가장 긴 서열을 앞에 오도록 정렬한 다음 붙이기도 한다.

가장 바람직한 spacer sequence는 무엇일까? 이것에 대해서 특별히 심각하게 생각해 본 일은 없다. Pseudomolecule이 필요할 때 그저 50~100개 정도의 N을 삽입하여 연결하는 것이 다반사였다. 하지만 컴퓨터를 이용하여 pseudomolecule로부터 gene prediction을 하게 되면 spacer를 내부에 갖는 무의미한 유전자가 예측될 수도 있다.

논문을 읽다가 6개 프레임 전부에서 stop codon을 만나게 되는 36-bp 서열을 spacer sequence로 쓴 사례를 보게 되었다. 대단히 현명하다. 이렇게 pseudomolecule을 만들면 최소한 spacer를 사이에 두고 양 contig를 가로지르는 무의미한 유전자는 나타나지 않을 것이다. 이 방법을 인용한 다른 논문도 최소한 두 편을 확인하였다(아르헨티나 국적의 동일 저자 논문임).
The contig sequences of each strain were concatenated with the sequences NNNNNCACACACTTAATTAATTAAGTGTGTGNNNNN, which puts stop codons in all six reading frames...
[출처] Pyrosequencing-based comparative genome analysis of the nosocomial pathogen Enterococcus faecium and identification of a large transferable pathogenicity island. BMC Genomics 2010 11:239 https://doi.org/10.1186/1471-2164-11-239. Pan-genome 개념을 창시한 H. Tettlin이 이 논문의 공저자이다.

하지만 실제로 해당 genome에 존재하지 않는 서열을 spacer sequence로 사용한다는 점이 약간 불편하다. N을 제외한 중간 염기서열(palindromic 26 bp)을 NCBI BLAST site에서 검색해 보았다. DB는 RefSeq Genome으로 택하였다. 이 서열과 100% 동일한 것을 보유한 genome이 54개였고, Cronobacter의 어느 스트레인을 시퀀싱한 것에는 여러 차례 출현한다. 이 서열을 spacer로 사용하여 이어 붙인 pseudomolecule을 NCBI에 등록했을 가능성이 크다. 실제로 하나를 클릭하여 GenBank record에서 match가 일어나 서열을 보니 좌우에 N이 5개씩 존재한다.

대규모의 comparative genomic analysis를 하는 사람은 이것을 기억해 두는 것이 좋겠다.

2017년 12월 9일 토요일

어서와, 갤럭시 S6 엣지+는 처음이지?

3 년 동안 사용한 팬택 팝업노트에 이어서 이번에는 삼성 갤럭시 S6 엣지+(2015년 10월 2일 최초 통화)를 쓰게 되었다. 지인이 중고로 처분하려고 액정과 배터리를 교체하여 놓은 것을 호의로 그냥 얻게 된 것이다. 이것은 LG U+용 단말기이지만 최근의 모델들은 타 통신사의 유심을 꽂아도 된다는 정보를 확인하였기에 별 주저함이 없었다. 주말 외출하러 나가는 길에 동네 휴대폰 판매점에 들러서 팝업노트에 사용하던 SKT용 유심을 잘라서 꽂았다. 재부팅을 하는 것으로 완벽하게 작동이 되었다.



내가 처음으로 접한 삼성 갤럭시는 아래에서 보인 갤럭시A(SHW-M100S, 2011년 8월 제조)이다. 2013년에 중고나라에서 구입하여 잠시 사용한 일이 있다. 오른쪽은 오늘 젤리 케이스를 끼운 갤럭시 S6 엣지+. 제조연도는 고작 4 년밖에 차이가 나지 않지만 IT 기기에게 이는 엄청난 시간이 아닐 수 없다.

삼성 갤럭시A와 S6엣지+.
돌이켜보면 나는 휴대폰에는 그렇게 큰 투자를 하지 못했다. 공짜로 풀리는 기계나 출시된지 오래된 마이너 브랜드의 공기계를 구입하여 개통하여 쓰는 것이 다반사였기에, 팬택 팝업노트는 일종의 사치나 다를 바가 없었다. 그러다가 비록 중고이지만 한때는 플래그쉽 모델이었던 것을 처음 쓰게 된 셈이다.

팝업노트의 불편한 점은 회사가 완전히 몰락하면서 사후 서비스를 받을 길이 없다는 것이다. 아직 교체용 배터리는 구입이 가능하지만 안드로이드 버전을 업그레이드하는 것은 불가능하다. 그리고 카메라 모듈에 문제가 있다는 것을 초반에 미처 발견을 하지 못해서 한쪽 1/4 정도의 초점이 매우 불량한 사진을 찍어야만 했었다. 액정이 깨져서 사설 업체에서 수리를 한 일도 있었다.

이전 단말기에서 쓰던 앱들을 새로 설치하면서 공인인증서와 관련한 미스테리에 빠지고 말았다. 직장에서는 USB 보안이 매우 까다와서 공인인증서를 설치한 USB 메모리를 외부의 컴퓨터에 쓰는 것이 더욱 힘들어졌다(사실 바람직한 것은 아니다). 그래서 최근에는 휴대폰인증서비스인 유비키를 이용하여 공인인증서를 휴대폰에 담아서 쓰고 있었다. 우리나라 공인인증서 서비스의 문제점에 대해서는 너무나 잘 알려져 있으니 이 글에서 재차 강조하지는 않겠다. 월 990원의 요금이 나가는 것도 사실은 큰 불만이다. 앱 내 저장과 토큰(USIM) 저장은 또 무엇이 다른가?

나는 아직 스마트폰에서 은행 업무를 보지는 않는다. ISP/페이북을 이용하여 간혹 카드 결제는 하는 편이다. 이렇게 된 이유는, 휴대폰과 관련한 공인인증서 저장 시스템이 도대체 이해가 되지를 않기 때문이다. 유비키를 이용하여 휴대폰에 공인인증서를 재발급해 둔 것은 사실이나, 이것은 PC 뱅킹만을 위한 것 같다. 모바일 뱅킹용 앱인 KB스타뱅킹을 실행하면 저장된 인증서가 하나도 없다고 나온다.

  • 재발급을 받아야 하나?
  • 가져오기를 해야 하나? 어디서? PC에는 이미 없다.


그래서 새로 발급을 하면 되나 싶어서 해당 메뉴를 들어갔더니...


아휴, 이게 다 뭐란 말인가. 이중에서 뭘 써야 하나? 공인인증서가 아닌 것을 택하면 타행용 모바일 뱅킹 앱에서는 같이 쓰지 못할 것만 같다. 그러면 이렇게 발급받은 공인인증서는 유비키 앱과는 또 무슨 관계란 말인가? 도대체 뭘 이렇게 어렵게 만들어 놓은 것인지...

모바일 뱅킹 앱의 인증센터 기능을 이용하여 공인인증서를 만들어 보았다. 그랬더니 이젠 PC 뱅킹에서는 접속이 안된다. 폐기된 공인인증서라는 것이다. 도대체 이건 어떻게 되는 건지 알 수가 없다...

민감도와 특이도(sensitivity and specificity)

민감도(sensitivity)와 특이도(specificity)는 양성 또는 음성과 같이 두 가지 결과가 나오는 분류 방법(테스트 또는 검사 방법이라고 불러도 좋음)의 정확성을 평가하는 지표이다. 실제 상황에서는 양성이지만 검사 결과 음성으로 나오는 경우(위음성, false negative, FN)와 음성이지만 검사 결과 양성으로 나오는 경우(위양성, false positive, FP)가 있다. 따라서 검사 대상자는 다음과 같이 4 가지 구획 중 어느 하나에 놓이게 된다.

출처 http://blog.minitab.com/blog/the-statistics-of-science/getting-fit-and-proving-it

나는 이것을 조금 다른 방법으로 그림을 그려서 설명해 보고자 한다. 위의 그림같이 완벽한 2x2 매트릭스 그림으로 설명하는 것보다 나는 이게 더 마음에 든다. 인터넷을 아무리 뒤져보아도 이렇게 그림을 그려서 설명하는 사례는 본 적이 없었다.

어떤 도시에 신종 감염병이 유행하게 되었다. 이를 감별하기 위한 새로운 검사 방법이 개발되어서 그 정확성을 평가하려고 한다.


이 상황에서 민감도와 특이도를 계산하는 식은 다음과 같다. 원칙에 충식한 식이라서 내 그림 방식에서 수식이 달라질 일은 없다.

가장 간단한 성능 척도인 정확도(accuracy)는 (TP+TN)/(TP+TN+FP+FN)으로 정의한다.

그러면 좋은 검사 방법과 나쁜 검사 방법의 실례를 내 방식의  그림을 이용하여 그려 보겠다.


가장 정확한 검사 방법은 E에 해당한다. 실제 병에 걸린 사람과 테스트 상으로 양성이 나온 집단이 거의 일치한다. 민감도와 특이도는 약 1이다. 가장 나쁜 검사 방법은 A이다. 실제 음성인 사람을 정반대인 양성으로 판정하는 것이다. 극단적인 결과, 즉 전 조사대상이 양성이라고 판정하는 경우(B)와 전체가 음성이라고 판정하는 경우(D)도 있을 수 있다.

만약 이 감염병이 대단히 위험한 병이라면, 과다 치료를 하는 문제가 있다 하더라도 민감도가 최대가 되는 테스트가 낫다. 심지어 검사를 하지도 않고 집단 전체에 다 치료제를 투여하는 것이 안전할 수도 있다. 통계학적 용어를 빌어서 말하자면 귀무가설(H0)은 '모든 시민은 이 감염병에 걸리지 않았다'임에도 불구하고 감염병에 걸린 것으로 간주하는(즉 대립가설 (H1)을 받아들임) 검사 방법을 택하는 것이 나을 수도 있다는 것이다. 즉, 제1종 오류가 좀 높은 검사 방법을 택하는 것도 가능하다는 것이다.

보통은 제1종 오류를 최소화하는 방법을 택하는 것이 정석이다. 형사 재판을 흔히 그 예로 든다. 즉 '피고인은 무죄다'라는 귀무가설이 옳음에도 불구하고 피고인에게 유죄 판결을 내리는 제1종 오류가 발생하는 일을 대단히 위험한 것으로 보는 것이다. 증거를 통해서 입증되기 전에는 피고인에게 죄가 없다는 기본 가정을 받아들이자는 것이다. 심각한 질환 여부를 검사하는 방법에 있어서는 제1종 오류보다는 제2종 오류, 즉 병이 있음에도 불구하고 정상으로 판정하는 상황을 더 위험한 것으로 간주하여 검사 시 유의 수준을 매우 높게 설정하는 것이 일반적인 가설의 검정과는 다르다. 밑줄을 친 부분은 내 독자적인 의견이 아니라 어느 자료에서 읽은 것인데 도대체 출처를 기억해내지 못하겠다.

민감도와 특이도 수치는 검사법 자체의 특징이 될 수 있다.

민감도가 유난히 높은 검사법이라면

  • 음성 판정을 받았다면 안심해도 좋다.
  • 양성으로 판정이 나왔다고 해도 너무 걱정은 하지 마라. 위양성(FP)으로 판정된 정상인일 수도 있으니까.

특이도가 유난히 높은 검사법이라면 

  • 양성 판정을 받았다면 진짜 환자일 가능성이 크다.
  • 테스트 결과 음성이라고 해도 너무 안심하지 마라. 위음성(FN)으로 판정된 진짜 환자일 수도 있으니까.
마지막으로... 민감도와 검출 한계(detection limit)는 분명히 다른 개념이다. 검출 한계는 얼마나 작은 신호값까지 잡아낼 수 있는지를 나타내는 지표이다.

오늘 블로그에 쓴 자료는 통계학자인 인하대학교 유동현 교수의 감수를 받은 것이다. 물론 유 교수는 제1종 오류를 범하는 위험성이 더 크다고 보았다.

2019년 4월 28일 업데이트

데이터과학 입문을 읽다가 265쪽(9장 데이터 시각화와 사기 탐지 - 9.5 데이터 과학과 위험 - 9.5.3 성능 추정의 어려움)에서 읽은 사항을 소개하기로 한다.

정밀도(precision) = TP / (TP+FP)

재현율(recall) = TP / (TP+FN)

정밀도는 양성으로 판정된 사람 중에서 진짜 병에 걸린 사람의 비율이고, 재현율은 진짜 병에 걸린 사람 중에서 양성으로 판정된 사람의 비율이다. 위키피디아의 정밀도와 재현율을 설명한 글 항목에 표시된 그림은 내가 여기에서 소개한 것과 거의 똑같다. 하지만 내 그림은 보통 설명에 사용하는 2x2 table이 별로 감동적이지 못해서 다른 방법을 찾다가 스스로 생각해 낸 것이지 결코 위키피디아의 것을 보고 나서 흉내낸 것이 아니다^^ 굳이 따지자면 convergent evolution에 해당하는 것이다.

2017년 12월 8일 금요일

NCBI에 유전체 서열 올리다가 고생한 경험담

매번 미생물 monoisolate의 유전체 정보만 등록을 하다가 이번에는 동일 환경에서 분리된 두 종류의 미생물을 multiisolate로 등록하게 되었다. 이는 BioProject 등록 단계에서 multiisolate임을 지정하는 것으로 시작된다. 등록할 미생물 두 종은 어떤 곤충의 애벌레 장에서 분리한 것으로, PacBio RS II로 유전체 해독을 완성하였다. 미생물 한 종의 유전체는 완성된 염색체, 나머지 하나는 완성된 염색체와 플라스미드로 구성된 것이다.

등록 웹사이트에서 genome sequence를 올리면 파일 업로드가 끝난 후 자동으로 서열 ID를 보여주면서 어느 것이 염색체고 어느것이 플라스미드인지를 기입하라는 폼이 나온다. 그런데 이번에는 그런 것이 없이 그냥 지나가는가 싶더니 곧바로 에러 메시지가 뜨는 것이었다.

Error: ********.fna: File didn't pass validation for option 1 (non-wgs genomes)
Level    Message
ERROR    Location of sequence ''>chromosome\n'' is not defined
FATAL    Chromosome sequence was not found

Error: ********.fna: File didn't pass validation for option 1 (non-wgs genomes)
Level    Message
ERROR    Location of sequence ''>chromosome\n'' is not defined
ERROR    Location of sequence ''>plasmid\n'' is not defined
FATAL    Chromosome sequence was not found

이건 처음 보는 오류였다. 도무지 이해가 가지 않아서 genomes @ ncbi로 문의 이메일을 보냈다. 언제나 친절하게 문제를 해결해 주는 Leigh A. Riley 박사로부터 답장이 왔다.


웹사이트를 아무리 둘러봐도 IMPORTANT: Additional... 에 해당하는 링크는 보이지 않았다. 그러나 두번째 단락의 설명대로 업로드할 염기서열 FASTA file에 해당되는 정보를 넣으면 될 것 같았다. 예전에 tbl2asn으로 sequin(asn.1) 파일을 만들 때 많이 하던 일이다. 그래서 이 지시에 따라서 필요한 정보를 서열 description 라인에 삽입하여 수정한 파일을 다시 업로드하였다.

염색체는 이제 제대로 처리가 되기 시작하였다. 그런데 plasmid는 여전히 오류를 토해낸다.

ERROR: valid [SEQ_DESCR.BioSourceInconsistency] Plasmid location set but plasmid name missing. Add a plasmid source modifier with the plasmid name. Use unnamed if the name is not known. DESCRIPTOR: BioSrc: ******** BIOSEQ: gnl|NCBIFILE|SUB********/unnamed: raw, dna len= 70706

https://www.ncbi.nlm.nih.gov/sites/genbank/genome_validation 웹사이트를 참조해 보라고 나왔지만 여기에는 SEQ_DESCR.BioSourceInconsistency라는 메시지에 해당하는 설명이 없다. 나는 Leigh가 시키는대로 [plasmid=name]을 추가한 죄밖에 없는데? 물론 name은 적절한 플라스미드 이름으로 바꾸었었다. >name으로 해 보아도 에러가 발생하고,  [plasmid=unnamed]로 해도 에러가 멈추질 않는다. Plasmid 서열의 description line을 계속 이리저리 바꾸어 가면서 여덟번 정도를 제출해 보았지만 계속 에러 메시지가 나왔다.

으으윽... 도대체 어디가 잘못된 것일까. 도저히 모르겠다고 다시 이메일을 보내 놓은 다음 Prokaryotic and Eukaryotic Genomes Submission Guide 페이지를 샅샅이 뒤지기 시작하였다. non-WGS, 즉 완성 수준의 유전체 서열을 batch submission할 때 plasmid 이름을 지정하는 것과 관련된 다른 지시사항이 있는지를 알아보기 위해서였다.

아하! 이 웹사이트 안에 Leigh가 알려준 IMPORTANT: Additional requirements for batch submission이라는 섹션이 있었다. 이걸 클릭하여 펼치니 비로소 플라스미드 또는 세포내 소기관의 유전체 서열에 대한 설명이 나타났다.


Leigh의 실수는 1) IMPORTANT... 정보가 있는 페이지의 주소를 알려주지 않은 것 2) [plasmid-name=pBR322]라고 써야 정확한 것을 [plasmid=name]으로 잘못 알려준 것이었다. 이를 설명에 맞게 고친 뒤 다시 업로드를 하였다. 비로소 문제없이 잘 프로세싱이 된다.

단일 유전체를 올릴 때에는 각 서열이 염색체 또는 플라스미드 중 어느것에 해당하는지 웹사이트 안의 양식에 직접 기입하게 하면서 왜 batch submission에서는 업로드하는 FASTA file의 서열 description 라인에 쓰게 하는 것일까? 아마도 샘플이 많을 경우를 대비한 배려가 아닌가 싶다.

이것 말고도 RNA-seq raw data와 관련한 BioProject 및 SRA 등록과 관련한 오류를 고쳐 나가는 중이다. GEO에는 고전적인 microarray data를 올려본 경험밖에 없어서 제출을 위한 processed file(read count data, raw 및 normalized)을 준비하기 전에 내 나름대로 genome sequencing을 위한 것과는 별도의 BioProject를 등록하고 SRA에 raw sequencing read 파일을 먼저 올려 두었었다. 그런데 정작 SRA에 processed file을 올렸더니 GEO와 연관된 raw data file은 GEO team에서 등록을 해 준다는 것이었다. 그리고 내가 이와 관련하여 등록한 BioProject 역시 잘못되었다고 알려주었다. 이것은 어떤 남세균의 두 가지 morphotype에서 각기 확보한 RNA-seq data를 등록하기 위함이었는데, GEO에서는 이를 두 개의 BioSample로 구분하라는 것이었다.

밥 먹듯이 하는 서열 데이터 등록이지만 이렇게 매번 새로울 수가 없다. 등록을 위한 웹사이트는 매번 조금씩 진화한다. 그것도 조금씩 나은 방향으로 말이다. 이메일로 질문을 하면 거의 항상 하루 안에 답장이 온다. 그리고 담당자 역시 변동 없이 일정하다. 우리나라처럼 3년 주기로 부서를 바꾸거나, 승진을 하여 더 이상 실무를 맡지 않거나, 혹은 이직을 하는 일이 그렇게 많지 않은 것 같다. 이러니 안심을 하고 편안하게 등록을 하는 것 아니겠는가? 데이터 등록자의 열린 마음(정보를 공유하고자 하는), 그리고 서비스 제공자의 신뢰성이 한데 어우러져서 공공 유전체 DB가 점점 성장한다. 수치로 나타나는 실적·성과와는 큰 관계가 없지만 분명한 것은 데이터 규모는 꾸준히 성장하고 있으며 그 유용성에 대해서도 말할 나위가 없다.

늘 이런 고민을 하고는 한다. 우리나라 연구자가 우리나라 연구비(곧 우리나라 국민의 지갑에서 세금으로 지원된 것이다)로 생성한 유전체 관련 정보를 꼭 우리나라 웹사이트에 등록을 하는 것이 옳은가? 그리고 이것이 얼마나 활용되고 있는지를 수치화한 성과로 보고하는 일이 그렇게 중요할까? 나는 그래야 한다고 주장해야 하는 조직에 근무하고는 있지만 이에 대해서는 늘 회의스러울 때가 많다.

2017년 12월 6일 수요일

BLASTX보다 20,000 배나 빠른 DIAMOND?

블로그에 LS-BSR에 관한 글(링크)을 쓰면서 프로그램을 설치하고 테스트 데이터를 돌리기 위해 매뉴얼을 보는 중에 diamond라는 프로그램을 발견하였다. 다이아몬드? 이건 뭐하는 프로그램인가?

Fast and sensitive protein alignment using DIAMOND. Nature Method (2015)

어이쿠, 2015년에 나온 논문이었다. 나의 게으름을 탓하자... 저자는 독일 튀빙겐 대학(튀빙엔? University of Tübingen) 소속이다. 튀빙겐 대학교는 1477년에 설립된 대학으로서 1869년 Friedrich Miescher가 처음으로 DNA를 분리한 곳이 아닌가! 당시에는 이를 고름에서 분리한 백혈구의 핵에서 추출하였으므로 nuclein이라고 불렀다. 이것이 유전물질이라는 것은 몰랐지만, 획기적인 연구 성과가 아닐 수 없다. 생명과학의 역사에서는 매우 유명한 이야기인데, 논문화된 자료가 있어서 인용해 본다.

Friedrich Miescher and the discovery of DNA. Developmental Biology (2005)

이야기가 옆으로 많이 새고 말았다. 새로운 sequence search program이 지속적으로 나오는 것도 참으로 놀랍다. NGS로 인하여 워낙 많은 서열 조각이 생산되고 있으니 새롭고 빠른 프로그램의 개발 수요는 여전한 모양이다. 논문을 읽어보자. DIAMOND는 double index alignment of next-generation sequencing data의 약간 억지스러운 acronym이다. Double indexing이 무엇인지는 모르겠지만, 대용량의 sequence read를 단백질 reference database에 대하여 검색하는 프로그램이라 하니 shotgun metagenomic sequence read의 분석에 매우 유용할 것으로 생각된다.

DIAMOND 공식 웹사이트: http://ab.inf.uni-tuebingen.de/software/diamond/

할 일도 많은데 왜 새로운 프로그램은 계속 나오는가!

BLAST score ratio(BSR)을 이용한 유전체 비교 분석

BLAST score ratio(BSR)는 2005년에 논문을 통해 소개된 개념으로서 생물학적 서열의 계산에서 활용되는 매우 고전적인 방법이라 할 수 있다(Rasko 등, Visualization of comparative genomic analyses by BLAST score ratio, BMC Bioinformatics doi:10.1186/1471-2105-6-2). 당시의 논문을 보면 BSR을 이용한 사례로서 박테리아 세 종(겨우!)의 비교를 들었으니 그 사이에 일어난 기술의 발전은 실로 놀랍기만 하다. 서열 사이의 관계를 알아보고 싶을 때 아직까지도 가장 널리 쓰이는 것은 BLAST이다. 그러면 data parsing을 위하여 사용할 지표, 즉 hit를 줄세우기할 때에는 무엇을 참조하는 것이 가장 좋겠는가? E-value는 database의 크기와 match 길이에 영향을 받는다. 이러한 bias는 BLAST raw score를 씀으로써 해결되지만, 이것 역시 정렬된 서열의 길이의 similarity에 따라 달라진다. Rasko 등은 이 문제를 해결하기 위해 BSR라는 개념을 도입하였다.

그 방법을 간단히 설명하자면 이러하다. 세 종류의 박테리아에서 유래한 단백질 서열의 집합(proteome)을 각각 Reference, Query1, 및 Query2라고 가정한다. Reference peptide을 자신에게 BLAST하였을 때 산출되는 raw score를 reference score라 부르자. 그 다음 reference peptide를 Query1, 및 Query2에 대하여 BLAST를 실시하여 query score를 얻는다. BSR은 각 peptide에 대한 query score를 reference peptide로 나눈 것이다. Query 집합이 두 개이므로, 각 reference peptide에 대하여 (BSR1, BSR2)의 값을 얻게 된다. 모든 peptide에 대해서 이렇게 얻은 값을 plotting하면 결국 세 개의 proteome을 구성하는 개별 단백질들이 공유 관계에 따라 어떻게 분포하는지를 파악할 수 있다.

출처: http://www.biomedcentral.com/1471-2105/6/2 (그림 1)

지금 기준으로 본다면 대단히 소박한 시각화 방법이다. 상식적으로 3개 집합을 비교한 벤 다이어그램을 그리면 7개의 구획이 나와야 한다. BSR을 이용한 위 그림에서는 3 개 집합 중에서 어느 하나를 "Reference"로 놓았기 때문에 마치 단백질 집합이 4 개의 구획으로 나오는 것처럼 여겨진다. 하지만 여기에서 중요한 것은 시각화 방법이 아니라 BSR이라는 개념 자체이다. 즉 방금 생성된 대용량의 미생물 유전체 조립물이 있을 때, 어떠한 reference protein set이 각각의 유전체 샘플에 존재하는지의 여부를 적절한 BSR cutoff 값(0.5? 0.6?)으로 결정할 수 있다는 것이다. (O, X)의 문제로 환원하는 것이 부담스럽다면 [0, 1] 사이에 분포하는 BSR 값을 가지고 heatmap을 그려서 시각화를 하면 샘플 유전체 전체를 꿰뚫는 insight를 주는데 도움이 될 것이다. 2005년도 논문의 저자들은 전부 TIGR(The Institute for Genomic Research)  소속이었고, 제1저자인 David A. Rasko는 많은 TIGR 과학자들이 그러했듯이 매릴랜드 의대로 소속을 옮겼다(현재 Rasko 소개 웹사이트). 2005년의 BSR 논문에 쓰인 펄 스크립트와 데이터파일은 여기에 남아있다.

BSR을 계산하는 파이썬 패키지인 blast-score-ratio 1.0.6이라는 것도 있어서 흥미를 끈다.

Large-scale blast score ratio(LS-BSR)

요즘 '뜨는' 다제내성 감염균의 하나인 Acinetobacter baumannii의 병원내 분리균주에 대한 대용량 유전체 비교 분석 논문(무려 254종의 isolate를 다루었고, 그 중에 203개가 A. baumannii였음)을 보다가 LS-BSR을 이용한 그림을 접하였다. Rasko는 이번에는 공저자로서 'The large-scale blast score ratio (LS-BSR) pipeline: a method to rapidly compare genetic content between bacterial genomes'(PeerJ 2016)라는 논문을 발표하였고, 여기에 소개된 프로그램(LR-BSR; GitHub)이 A. baumannii 논문에 쓰인 것이다. 대용량 유전체 데이터를 이루는 모든 CDS의 연관성을 일목요연하게 보일 수 있도록 매트릭스 형태의 LS-BSR을 계산하는 파이프라인으로 확장이 된 것이다. 2005년 논문과 비교하여 달라진 점이 있다면 단백질을 query로 하여 유전체 서열을 검색하는 것이 일반적인 상황이므로 TBLASTN을 적용하고, BLAST raw score가 아니라 bit score를 쓴다는 점이다. 시각화 도구로는 Multiple Experiment Viewer(이 또한 고전적!)이나 R을 쓰면 된다.

LS-BSR의 특징은 ortholog의 clustering, pan-genome의 계산의 용도로도 쓰일 수 있다는 것이다. 즉 pan genome analysis tool로 내가 애용하는 Roary와 많은 부분이 겹친다. 2016년 논문의 제1저자이자 LS-BSR 개발자인 Jason W. Sahl(링크; 머리카락이 좀 덜 빠지고 약간 야윈 제이슨 스테이섬을 떠오르게 하는...)은 GitHut의 위키 페이지에서 Roary와 LR-BSR을 비교한 글 "Some thoughts on comparing Roary to LS BSR"을 기고하였다. 두 소프트웨어는 활용 목적이 분명히 다르고, 기본 알고리즘도 역시 상이하다. 따라서 어느 것이 더 빠르고 정확하다고 쉽게 단정지어 이야기하는 것은 바람직하지 않다. 내가 이해하는 수준에서 말하자면 LS-BSR은 적극적인 클러스터링 도구는 아니다. 또한 Roary는 genome annotation 정보가 있어야만 돌아간다.

마침 논문을 통해서 찾은 virulence gene의 존재 여부를 100여개 미생물 유전체에서 확인하여 시각화하는 방법을 고민하는 중이었다. 이것이 LS-BSR의 첫 경험이 될 것이다. Reference protein은 genome level이 아니라 20개 남짓한 수준의 것을 별도로 준비한다는 점이 LS-BSR의 기본 전제 조건과는 약간 다르다.

2017년 12월 5일 화요일

나에게 주는 선물 - 시계 'Maverick'

블랙 프라이데이를 맞아서 국외 사이트에서 세일 중인 시계를 구입하였다. 아내 것과 내 것으로 각각 하나씩. 왼쪽의 것이 이번에 구입한 시계이고 오른쪽의 것은 비교를 위하여 같이 찍은 시계이다. 요즘 손목시계가 과거와 비교하여 얼마나 커졌는지를 알 수 있다. 오른쪽 시계는 여성용이 결코 아니다! 직경이 거의 1 cm나 차이가 난다.


블랙 프라이데이에만 세일을 하는 줄 알았더니, 미국 시간으로 금요일이 지난 후에도 '사이버 먼데이' '사이버 위크' 등의 이름으로 며칠간 더 이어지다가 지금은 원래 가격으로 돌아간 것 같다. 모델명은 Victorinox Swiss Army Classic Maverick GS Dual Time 241441이다. 배송료를 포함하여 시계를 두 개나 사고도 관세·부가세 한도인 200 달러를 넘기지 않았으니 무척 싸게 산 셈이다. 직접 시계줄을 줄이다가 약간의 흠집을 내고 말았지만 손톱 광택용 버퍼로 문질러서 없앴다. 생물학 전공자라서 buffer라고 하면 자꾸 완충용액, 완충기가 떠오른다. 제법 무겁지만 내가 좋아하는 diver's watch 스타일로서 매우 마음에 든다. 세일 가격을 생각하면 이 가격에 이렇게 마감이 좋은 시계를 앞으로 사는 것은 불가능할 것이다.

구글 검색창에 'maverick 뜻'이라고 치면 다음과 같이 나온다. 오래 전에 나도 이 낱말의 뜻을 독수리로 알고 있었다. Maverick에 정말로 '독수리'라는 뜻이 있는가?


그런데 'maverick meaning'이라고 치면, 그 어디에도 독수리라는 뜻은 나오지 않는다.


나무위키를 찾아보면 원래 매버릭이란 미국 서부에서 낙인이 찍히지 않아 누구의 소유인지 알 수 없는 가축을 뜻하는 낱말이라고 하였다. 여기에서 '이단아', '독불장군'이라는 의미가 파생되었을 것이다.  바로 생명공학계에서 Craig Ventor를 종종 매버릭이라고 부르기도 하였다. 1987년도 영화 탑건에서 톰 크루즈가 매버릭이란 별명으로 나왔었다.

도대체 왜 구글 검색에서조차 maverick이 독수리라고 번역이 되는 것일까? 다른 그 어떤 사이트에서도 이렇게 번역할 근거를 찾지 못하였다.

2017년 12월 4일 월요일

EzBioCloud 제대로 사용하기

[참고] 쉽게 쓴 원핵생물(prokaryote)의 종 동정 이야기

천랩의 대표적 서비스인 EzTaxon은 16S rRNA 유전자 서열을 이용하여 원핵생물(prokaryote = bacteria and archaea)의 종을 동정하는데 매우 널리 쓰이고 있다. 우리나라에서 개발된 생명공학/생물정보학 웹사이트 중에서는 가장 활용도가 높은 것이라 해도 과언이 아닐 것이다. 유전체 시대를 맞이하여 EzTaxon은 잘 선별되고 가공된 16S rRNA 유전자와 유전체 서열을 통합한 EzBioCloud(논문, 웹사이트)로 확장되기에 이르렀다. 현재 종 동정은 표준 균주(type strain)와 시험용 균주의 유전체 서열 비교를 통해서 이루어지는 것이 표준 방법으로 여겨지고 있기 때문이다. 두 원핵생물 유전체 서열 사이의 ANI, 즉 average nucleotide identity가 일정 cutoff(보통 95~96%) 이상이면 동일 종으로 간주한다.

하지만 아직까지는 EzBioCloud 안에서 유전체 서열을 다루는 방법에 익숙하지 않아서 천랩이 제공하는 튜토리얼(Identifying a bacterial strain using a genome sequence, 튜토리얼 전체 모음 페이지)과 이메일 상담을 통해서 이를 익혀나가는 중이다. 두 차례에 걸쳐 꼼꼼하게 답변을 보내준 천랩 학술사업부 이혜원님에게 고맙다는 뜻을 전하고 싶다. 천랩이 제시하는 방법을 요약하면 다음과 같다.

  1. Genome FASTA file를 ContEst16S(논문웹사이트)에 업로드하여 오염 여부를 점검(raw sequencing read가 아니라 contig 서열을 업로드해야 함)
  2. ContEst16S 오염이 발견되지 않았다면, 여기에서 예측한 16S rRNA sequence를 복사함. ContEst16S를 사용하지 않았다면 Prokka 등의 다른 genome annotation 방법을 통해서 16S rRNA gene을 뽑아냄
  3. 이를 EzBioCloud의 Identify에 제출하여 분석을 실시함. Similarity 계산식은 여기를 참조
  4. Identify 결과 중에서 similarity ≥98.8%인 것의 유전체 서열을 다운로드하여 샘플 genome fasta file과 함께 orthoANI에 업로드
  5. 샘플과 type strain의 유전체 서열 사이에서 계산된 ANI 값이 95~96% cutoff를 넘으면 같은 종으로 판정
ContEst16이 자동 생성한 16S rRNA gene fragment의 ML tree.
4번 과정은 약간의 설명이 필요하다. 내가 천랩에 직접 이메일을 보내서 상세한 방법을 문의한 것도 바로 이 과정이었다. 전형적인 Identify의 결과표는 다음과 같다(너무 길어서 오른쪽 컬럼은 잘라냄).


Hit taxon name이 일반적인 학명이 아닌 CP017181_s로 표시된 것이 보인다. 이것은 천랩에서 NCBI의 유전체 서열을 점검하면서 이름이 잘못 붙은 것에 따로 매긴 taxon 이름이다. 즉 완성된 유전체 서열이지만 알려진 type strain의 유전체 서열과 비교하여도 OrthoANI > 97%로 매치하지 않아서 이런 임시 taxon 명칭을 붙인 것이다. 여기에서 보인 사례는 genome accession이 CP017181인 바로 자신이 나와주었지만, 이것과 동일 종으로 엮인 CP017181_s는 오늘 날짜 기준으로 총 60개나 된다(링크). 이들의 original label을 보면 잘못된 명칭이 붙은 유전체가 얼마나 많은지를 알 수 있다. CP017181_s가 종(species) level의 putative taxon의 이름으로 선택된 것은 CP017181의 assembly status가 'complete'였기 때문이다.

OrthoANI에 업로드할 genome의 서열을 다운로드하는 방법은 다음 중 하나를 따라가면 된다.
  1. Identify 결과창 왼쪽 컬럼 'Task' 중 동그라미('View genomes') 클릭 -> Browse EzBioCloud public genome database가 열리면 Browse 클릭 -> 오른쪽 Download 탭 클릭 -> CLG, contig FASTA, CDS 중에서 원하는 것을 클릭하여 다운로드
  2. Identify 결과창에서 Hit taxon name 클릭하여 다음 그림이 나오면 genome(빨강색 박스) 클릭 -> Browse EzBioCloud public genome database가 열리면 Browse 클릭, 이하는 (1)번 경로와 같음


NCBI에서 미생물 유전체 서열을 받을 때면 늘 이 균주가 type stain인지의 여부를 명쾌히 알려주지 않아서 논문을 일일이 찾아보아야 했었다. 그런데 EzBioCloud를 사용하면 type 균주 여부는 물론이거니와 16S rRNA 유전자와 genome sequence 측면에서 정확한 종 명칭이 부여되었는지를 확인한 유전체 서열을 손쉽게 다운로드할 수 있어서 얼마나 편리한지 모르겠다. 이렇듯이 EzBioCloud 데이터베이스에서는 16S rRNA 유전자 검색을 통한 접근뿐만 아니라 검색창에 균주 명칭을 입력하면 공개된 유전체 서열 중 천랩의 점검을 통해서 해당 종으로 판정된 것들의 목록이 얻어지고 다운로드 기능까지 이어진다.

키워드 검색을 통하여 EzBioCloud를 이용한 사례를 살펴보자. 검색창에 'Paenibacillus polymyxa'를 입력하면 다음과 같은 결과가 얻어진다. 기본으로 보여지는 것은 taxonomy이고 genome과 16S rRNA를 클릭하여 각각에 대한 상세한 정보를 얻을 수 있다.

다음으로는 'E681'을 입력해 보자. 이 균주는 처음에 Paenibacillus polymyxa로 동정된 뒤Sanger 기술을 이용하여 유전체 해독을 완료하였던 것이다(CP000154.2). Paenibacillus polymyxa의 type strain인 ATCC 842의 유전체 서열을 나중에 해독하여 서로 비교를 해 보니 E681은 Paenibacillus polymyxa가 아닌 다른 신종으로 다루어야 함을 알게 되었다. 하지만 균주의 특성에 대한 다른 실험이 수반되어야 하는 관계로 새로운 종을 제안하고 E681을 여기에 type strain으로서 재분류하는 일을 아직 하지는 못한 상황이다. EzBioCloud의 검색창에 'E681'을 넣어 보았다. CP000154_s라는 putative taxon의 대표(reference) 서열로 등록이 되어 있었다. 


CP000154_s로 분류된 유전체 정보는 총 21건(링크)로서 original label은 Paenibacillus polymyxa, Paenibacillus peroriae 및 Paenibacillus sp.였다.