논문을 쓸 때 다른 부분은 그냥 tab으로 들여쓰기 하면 문제가 없었으나

Reference 부분에서 일정한 간격으로 들여써야 할 때 모든 항목의 단을 똑같이 맞추기에 

어려움을 겪었었다.


워드 위 쪽에 화살표 모양의 단락 조절 버튼이 보인다. 저 버튼을 마우스로 조절하다 보면

모든 항목의 들여쓰기를 일정하게 하기가 쉽지 않다.

그 때 기준으로 삼을 항목의 화살표 중 아래 그림에서 동그라미친 버튼을 마우스 오른쪽 버튼으로 두 번 클릭하면 새로운 대화 상자가 열린다.



아래와 같은 대화 상자가 열리면 들여쓰기에 왼쪽 부분을 보면, -0.18 글자라는 걸 볼 수있다.

정말 특이하게 글자라는 단위가 있다. 

이걸 복사해서 이 기준 항목과 동일하게 들여쓰고 싶은 항목들에 저 값을 붙여 넣으면 모두 깔끔하게 정열된 것을 확인할 수 있다.



Simulator를 구현하다 보니 시간을 처리해야 할 일이 생긴다. 프로그램 진행 중에는 코드 시작 시각을 기준으로 얼마나 지났는지만 표현하면 되지만 프로그램이 종료 된 후의 결과는 사람에게 익숙한 형태여야 분석이 용이하다.

이번에 새롭게 시작하게 된 기업과제에서 반도체 공장의 Simulator를 제작해야해서 예전에 구현해 놓은 Simulator code를 오랜만에 열어 보았다. 그 때의 코드는 시간을 다음과 같은 코드를 이용해서 표현하고 있었다.


 
결과는 다음과 같이 출력된다. Sun Feb 20 12:00:00 KST 3916
연도, 월, 날짜, 시각 순인데, 여기서 월은 0부터 시작이다. 예제에서는 1이니까 2월인 것이다.


그런데 이 Date(year, monte, date ... ) 류의 생성자는 Deprecated로 Annotation이 되어있다. 그리고 권장되는 Date의 생성자는 Date() 또는 Date(long arg0) 이다. Date()로 Date의 instance를 생성하면 현재 시각에 해당하는 instance가 생성된다. 생성자가 long 형태로만 input을 받기 때문에 원하는 시각에 해당하는 instance를 생성하려면 'the milliseconds since January 1, 1970, 00:00:00 GMT' 즉 unix time으로 변환해주어 그 값을 input으로 사용할 수 밖에 없다. 


보다 더 직관적인 연도, 월, 날짜 등을 입력 받는 방식에서 이렇게 바뀌었는지 그 이유는 모르겠지만 급한 경우를 제외하고는 권장하는 방향으로 코딩을 할 생각이다.


(서울대) 대학원(생)을 위한 영어 논문 글쓰기에 도움 되는 강의/책 추천

  작년부터 본격적으로 논문을 쓰기 시작하면서 영어로 논문을 쓰는 것의 어려움을 직접 몸으로 느끼고 있는 중이다. 처음엔 내가 영어로 글 쓰는 것에 익숙하지 않다는 점과 영어 글쓰기 실력의 부족함 때문에 논문을 제대로 못쓰고 진도도 느리다고 생각했다. 하지만 시간이 지날수록 느낀 것은 문제는 영어 실력이 아니라 더 본질적인 것에 있다는 것을 깨달았다. 그것은 바로 글쓰기 능력이다. 영어로 써야 하니까 어려운 점이 물론 존재하지만 그것에 앞서서 근본적으로 문제인 것은 논하는 글인 논문을 쓸 때 필요한 기본적이면서 필수적인 글쓰기 방법을 제대로 배워보거나 연습해본 적이 없다는 것이었다.

  그래서 논문 쓰다가 집중력이 바닥을 보이는 때 틈틈이 대학원 입학 후 도움 되었던 강의와 책을 공유하고자 글을 쓰고자 한다. 아직도 글을 쓰는 능력이 많이 부족하지만, 어둠 속에서 정처없이 해매이던 나를 그나마 비슷한 방향이라도 잡게 해준 강의/책 들이다.

  •  영어논문 작성법 (기초/심화) - 올바른 과학기술논문 어떻게 작성하는가? -
    서울대학교 교수학습개발센터에서 몇 년전부터 여름에 개설하고 있는 강의다. 인하대학교 김형순 교수님이 강사로 오신다. 강사님이 논문을 많이 써본 사람이 아니라면 굳이 심화 과정은 들을 필요가 없다고 말씀하시는데, 둘다 들어본 결과 어떤 말씀인지 공감이 됐다. 기초 과정 강의에서는 '논문'이라는 글의 일반적인 구조와 각 부분의 체계적인 작성 방법을 배울 수 있다.

      사실 논문을 막상 쓰려고 하면 이러한 형식의 글을 많이 써보지 않은 사람은 갈피를 잡기가 쉽지 않다. 나 역시 그랬었다. 그래서 연구실 선배님에게 물어가며 도움을 받으면서 조금씩 글을 써나가고 있었는데 이 강의를 통해서 논문 쓰는 법에 대해 제대로 된 체계가 잡힌 교육을 받은 느낌이 들었다. 아마 매년 여름마다 열리는 것 같으니 대학원 입학을 앞두고 있거나 대학원생들에게 강력히 추천한다. 강사님이 본인의 강의를 여러 번 듣는 사람이 심심치 않게 보인다고 하는데 (심지어 다른 대학교 교수들 까지도) 나도 내년에 시간이 된다면 또 들을까 생각 중이다.
  • 논증의 탄생 -조셉 윌리엄스-
      위의 강의의 강사님이 글을 쓸 때 혹은 영어로 글을 쓸 때 도움이 될만한 책들을 여러 권 추천해주셨다. 논증의 탄생은 그 중에서도 강사님이 강력 추천한 책이다. 그래서 강의를 듣고 바로 구입을 했고 지금도 읽고 있는 중인데 일단 재미가 있다. 어떻게 보면 딱딱한 주제일 수 있는 글쓰기에 대해 이야기 하면서도 독자에게 흥미를 잃지 않게 해주는 것 같다.
     
      이 책은 논증하는 글이 가져야 할 바람직한 구조를 설명하고 각 부분이 어떤식으로 연결이 되고 각 부분을 어떻게 작성해야 하는지 예제와 함께 설명해준다. 거의 모든 부분에서 예시가 등장하기 때문에 저자가 설명하는 논증하는 글쓰기의 방법이 이해가 잘 된다. 게다가 지금 논문이라는 글을 쓰고 있는 나의 경우, 내가 쓰고 있는 글을 저자가 말하는 구조에 맞춰보면서 내 글이 제대로 쓰여지고 있는지 아닌지 점검 할 수 있는 기회를 얻을 수 있다는 점도 좋았다.
     
      여튼 이 책은 논문 뿐 아니라 누군가를 '설득'해야 하는 글을 써야 하는 사람이라면 반드시 읽어보면 좋을 책이라고 생각한다. 아직 책을 다 읽지도 않았지만, 많은 도움이 되고 있기 때문에 주변에 글을 쓸 때 막막함을 느끼는 사람들에게 공유하고 싶은 마음이 들어 이렇게 글을 쓰게 되었다.
  • 영어논문작성법 (기본/심화) 과정 - 강사: 민양기
      앞서 언급한 김형순 교수님의 강의명과 그 이름이 같다. 강의들을 수강할 때는 몰랐었는데 이 포스트를 작성하면서 알게 된 사실이다. 여튼 이 강의는 경력개발센터에서 열리는 강의이며, '영어'에 좀 더 초점을 맞춘 강의이다. 김형순 교수님의 강의가 전체적인 논문의 구성과 논문을 구성하는 각 부분의 작성 방법에 대해 설명했다면, 민양기 교수님은 영어로 문장을 만들 때의 문법, 단어사용 등의 세세한 부분을 주로 강의하신다.
     
      교수님이 의학을 연구하시는 분이라 대부분의 예제가 그 쪽 분야에 관련된 문장으로 구성되어 있는 것이 살짝 아쉽지만, 이공계 논문에 자주 쓰이는 문장들(비교, 수치 표현, 제안 방법 서술 등)을 영어로 작성할 때 주의해야 할 점에 대해 자세히 가르쳐 주신다. 교수님께서는 우리가 문과가 아니고 이공계 연구자이기 때문에 영어 표현의 형식들을 잘 익히고 암기하기만 하면 영어 논문 쓰는 것은 그리 어려운일 아니게 된다고 말씀하신다.

      실제로, 교수님이 그간 SCI 저널에 발표하신 논문의 편수가 100편이 훨씬 넘으니 말과 행동이 일치하시는 분이라 할 수 있겠다. 기본 과정을 수강하면 '이공계 연구자를 위한 영어과학논문 작성 메뉴얼' 이라는 책을 무료로 나눠준다. 심화 과정에서는 기본 과정의 내용을 빠르게 복습하고 수강생들을 몇 개의 그룹으로 나누어 좋지 않은 표현으로 작성된 논문을 올바르게 고치는 실습시간이 있다.
  • 이공계 연구자를 위한 영문과학논문 작성메뉴얼 -민양기-
      민양기 교수님이 쓴 책으로 위에서 언급했던 강의의 기본과정을 수강하면 무료로 얻을 수 있는 책이다. 기본 과정을 수강하면 받게 되는 강의노트 유인물을 책의 형태로 출판한 것이라고 생각하면 된다. 강의 노트의 내용과 함께 다양한 예제가 수록되어 있으며, 영어에 관련된 내용 뿐 아니라 논문을 해외 저널에 출판할 때의 전체적인 프로세스(커버레터, 리뷰어와 소통하는 등의 내용도 포함)에 대해 자세한 설명이 포함되어 있다. 논문을 한 번도 써보지 않은 초보 연구자가 한 번 읽어보기에 좋은 책이라 생각한다.

 

D3를 이용하여 svg에 데이터를 시각화 하고나면 그 결과를 공유해야 할 일이 생길 때가 있다. 가장 간단한 방법은 웹 사이트의 링크를 공유하는 것이지만, 때에 따라 문서에 첨부하거나 파일로 저장하여 공유해야 할 수도 있다. 보통 이러한 경우 캡처 프로그램을 사용하면 아주 간단하게 원하는 작업을 수행할 수 있으나, 이미지의 크기가 한 화면에 들어오지 않거나 저장해야 하는 이미지의 개수가 많으면 캡처 프로그램으로만으로는 한계가 있다. 따라서 이번 포스트에서는 d3로 만들어낸 svg 형태의 image를 우리에게 익숙한 png image로 출력하여 저장하는 방법을 정리하고자 한다.

이 작업을 위해서 구글링을 해보니 아래와 같은 링크를 발견할 수 있었다.

http://techslides.com/save-svg-as-an-image

  svg를 png로 export 하는 방법에 대해 아주 잘 정리 되어 있었다. 그러나 위의 링크 만으로 모든게 해결 되었다면 이 post를 작성하지 않았을 것이다. 위의 링크에 제시된 예제 코드를 그대로 실행하면 아무런 오류 없이 원하는 결과를 얻을 수 있었다. 그래서 작업 중이었던 코드에 삽입해서 image로 추출하는 것을 시도해보았으나 에러가 발생했다. 이럴 때마다 느끼는 거지만 정말 코딩 할 때 딱 한번에 잘 되는 경우가 잘 없다. 에러는 파이썬에서도 날 정말 많이 괴롭혔던 '인코딩'이 원인이었다. 아래의 코드에서 8번 째 줄이 에러를 발생 시키는 부분이다


  btoa 함수는 아마 binary to ascii 의 약자로 추정되며 svg 데이터를 base64로 encoding 해주는 함수이다. 웹 브라우저에서 image는 'base64'로 인코딩된 포멧이기 때문에 data를 전송하기 위해서 binary data를 base64로 인코딩을 해줘야 한다. (출처) 그런데 btoa 함수에서 에러가 발생하는 것이다. 에러 메세지를 구글에서 검색해보니 인코딩 문제라고 한다. 예제 코드에는 없지만 내 코드에는 있는 것. 바로 한글의 존재 때문에 에러가 발생하는 것이다. 

  btoa 에 인자로 들어가는 html은 script 부분에 작성된 모든 코드를 통째로 긁어온 string 헝태인데 (), 여기에 한글이 들어가면 btoa는 utf-8 형식을 인식하지 못하기 때문에 에러가 나는 것이다. 그래서 저 부분을 해결하기 위해 stackoverflow에서 발견한 페이지에서 하라는 함수를 만들어서 전처리를 해보았다. 에러는 발생하지 않았으나 여러번 변환이 된 탓인지 뒤 쪽 코드의 그림을 그리는 부분에서 아무런 결과를 산출하지 못했다. (이 부분은 조만간 다시 한 번 시도해 보려고 한다.) 그래서 다른 방법을 찾던 중 utf-8 을 그대로 이용하는 코드를 발견했다. 이 코드는 image를 단순히 같은 화면에 복제 시킨 후 우클릭으로 그림으로 저장하는 방식으로 image를 추출하고 있었다. 그래서 위의 링크에 나온 방법과 이 코드의 앞 부분을 섞어서 드디어 원하는 결과를 얻을 수 있었다. 코드는 다음과 같다.


  Blob 이라는 자료형을 사용하는 방법이다. Blob에 대해서는 정확히 모르겠지만 utf-8 로 주소를 편하게 읽어올 수 있다는 것이 장점인 듯 하다. url을 utf-8 형식 그대로 읽고 나서 그 후의 방식은 가장 위에 첨부했던 링크에 나와 있는 방법과 거의 흡사하다. script에 이 code를 작성하기 전에 html의 body 부분에 두 개의 준비물이 필요한데 하나는 일반적인 <div> 이고 나머지 하나는 <canvas>이다. 코드의 진행과정은 다음과 같다. button을 클릭하면 svg를 미리 만들어둔 <div>에 image로 변환해 놓고 <canvas>에서 이 image를 읽어와서 파일의 형태로 만들어서 저장할 수 있게 한다. 이 때, <div>의 style을 display: none으로 해주어야 화면에는 아무런 변화가 없이 깔끔하게 추출만 할 수 있다.

마지막 37번 째 줄처럼 context를 clear해주지 않으면 데이터 변화에 따른 시각화의 변화가 갱신되지 않고 누적되기 때문에 꼭 저렇게 clear를 해주어야 한다.

인코딩 문제를 해결하고 그림을 추출하는 것까지는 성공했으나.. style sheet 정보까지 image에 포함시켜 추출시키는 것은 여전히 모르겠다. 즉, script 안에서 여러 가지 method로 선언해준 것들은 image에 포함이 되나 style 부분에서 지정해준 것은 전혀 반영이 되지 않는다. 이 문제까지 해결하면 svg의 image 파일 추출은 거의 온전하게 할 수 있을 것 같은데 쉽지가 않다.



D3를 이용하는 목적은 여러가지가 있겠지만 아무래도 interactive 한 시각화가 요구 될 때 시각화 도구로 D3를 많이들 사용하게 된다. 특히 특정 버튼을 눌렀을 때 내부의 데이터가 바뀌면서 화면도 시시각각 바뀌는 것이 그 대표적인 예라고 할 수 있다. 이 때, 이러한 조작을 가능하게 해주는 것이 D3의 enter, update, exit 개념이다. 이 개념은 D3의 핵심 개념으로 화려하고 다양한 D3의 여러가지 기능을 쫓다보면 놓치기 쉽다. 나 역시 이 개념을 간과하고 신나게 코딩하다가 D3정말 D3답지 않게 코딩했다가 코드를 전면 수정한 적이 있다. 혹여 D3를 시작하는 사람이라면 이 개념을 꼭 짚고 넘어가는 것이 좋다. 이 개념에 대한 설명은 다양한 웹문서에 잘 나와 있으니 참고하길 바란다.

어쨌든, 이 개념을 이용해서 코딩을 하려고 하는데 간혹 'exit is not a function' 이라는 에러 메세지를 마주 하게 되었다. 아래 코드는 이런 에러메세지를 발생 시키는 코드 예제이다.


이 코드가 포함된 동적 시각화를 웹 페이지에서 조작해보면 exit() 함수 부분에서 에러가 난다. Stackoverflow를 찾아보니 enter()에 바로 이어서 append로 어떤 객체를 붙이면, barElements는 enter() 로 subselection된 노드가 되고 이 노드들은 정의에 따라 exit() 함수를 가질 수 없다고 한다. (http://stackoverflow.com/questions/27596908/d3-typeerror-link-exit-is-not-a-function-link-exit-remove-what-am-i-doing)

코드를 고쳐서 바로 작성하면 다음과 같다.

올바른 코드는 enter()와 append()를 data()함수에 계속 이어서 하지 말고 위의 코드에서 처럼 한 번 끊어서 해주는 것이다. 이렇게 해주면 전체 data-bound selection을 먼저 한 후 sub-selection에 대해 작업을 하게 되는 코드가 된다고 한다. 솔직히 원리는 완벽하게 이해가 되지는 않지만 코드 상으로 뚜렷한 차이가 보이기 때문에 다음부터는 확실히 구분지어 해야겠다는 생각이 든다. 여튼 알면 알수록 신기하고 헷갈리기도 하는 D3의 enter, update, exit 개념이다.


예전에 연구실 선배에게 논문에 포함될 heatmap을 Matlab으로 그려보는 것이 어떻겠냐는 제안을 받았었다. Matlab에는 heatmap을 그리기 위한 라이브러리가 포함되어 있었는데 당시에 그 라이브러리를 사용해서 heatmap을 그려보려 했는데 의도한대로 잘 되지 않았던 경험이 있었다. 작년 하반기에 d3를 공부하면서 d3로 heatmap을 제대로 그려보고자 했다. 그런데 당연히 있을 것이라 생각했던 heatmap 라이브러리가 d3에는 없었다.

아래는 2014년 방영되었던 KBS 대하 드라마 정도전의 데이터를 이용하여 heatmap을 시각화 해본 것이다. 주인공 정도전이 50회 동안 총 만난 횟수가 10번 이상이 되는 등장인물들만 나타냈다. (등장인물의 수가 많아서 모바일로 보면 몇 명과의 관계까지만 볼 수 있음)

<javascript 코드 추가예정..>

Raw data는 다음과 같이 구성되어 있다.

ep char value
1 이지란 0
1 남은 0
1 업둥이 0
1 이숭인 1
.

.
2 이지란 0
2 남은 0
2 업둥이 0
2 이숭인 0
2 이방과 0
.

.

차례로 회차, 등장인물 이름, 정도전과 만난 횟수를 각각 의미한다.
이 데이터를 chart 영역에 입력하고 heatmap을 그리는 핵심코드는 다음과 같다.



여기서 chas는 heatmap에 나타나는 등장인물들을 raw data의 순서에 맞게 저장해 놓은 array이다. 우선 사각형을 회차와 각 등장인물에 맞게 메트릭스 형태로 잘 그려준다. 하나의 행은 하나의 회차에 대응되고 하나의 열은 한 명의 등장인물에 대응된다. (attr('x') , attr('y') 부분이 표현하고자 하는 heatmap에 적당하게 사각형들의 위치를 설정하는 부분이다.)

그리고 약간의 애니메이션 효과를 위해 처음에는 가장 기본색으로 색칠을 한 후 1초 후에 미리 정해놓은 colorScale에 맞추어 색칠을 해주면 별다른 라이브러리 없이 d3의 기본적인 기능만으로 heatmap을 그릴 수가 있다.

코드 출처: http://scikit-learn.org/stable/auto_examples/tree/plot_iris.html#example-tree-plot-iris-py 

 저번 포스팅이 data를 tree를 생성하기에 적합하게 데이터를 load하는 것에 관한 것이었다면 이번 포스팅은 tree를 생성하고 그것을plotting 하는 것까지의 내용을 담고 있다. 또한 그 과정에서 나타나는 다양한 python 사용법에 대한 설명도 함께 정리한다.

######################################### print(__doc__)

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier

# Parameters
n_classes = 3
plot_colors = "bry"
plot_step = 0.02
# Load data
iris = load_iris()
#########################################

Decision tree를 생성하기 전에, data를 불러오고 그래프를 그리기 위한 설정을 하는 부분이다. plot_colors = "bry"는 코드 뒷부분에 'blue', 'red', 'yellow' 라는 색을 나타내기 위해 쓰이며 plot_step은 축의 단위를 설정해주는 부분이다.

#########################################
for pairidx, pair in enumerate([[0, 1], [0, 2], [0, 3],
[1, 2], [1, 3], [2, 3]]):
# We only take the two corresponding features
X = iris.data[:, pair]
y = iris.target
#########################################

 enumerate는 입력값으로 시퀀스자료형(리스트, 터플, 문자열)을 입력으로 받아 enumerate객체를 리턴한다. enumerate객체는 첫번째로 그 순서값, 두번째로 그 순서값에 해당되는 시퀀스 자료형의 실제값을 갖는 객체이다. (출처: https://wikidocs.net/32) iris의 feature dimension은 4이다. 4개의 feature를 2개씩 짝지어 비교하여(4C2) 그래프를 그리고 그 그래프들을 한 화면에 나타나기 위해 enumerate 함수를 사용했다. 
 X = iris.data[:, pair]의 경우 하나의 pair에 들어가는 값이 만약 [0, 2] 라면 첫 번째, 세 번째 feature만 선택해서 X에 할당하겠다는 의미이다.

#########################################     # Shuffle
idx = np.arange(X.shape[0]) np.random.seed(13) np.random.shuffle(idx) X = X[idx] y = y[idx]

# Standardize
mean = X.mean(axis=0)
std = X.std(axis=0)
X = (X - mean) / std
    # Train
clf = DecisionTreeClassifier().fit(X, y)
#########################################

현재 X(Data), Y(Target)은 class 순서대로 정렬이 되어 있으므로 shuffle을 해준다. 사실 shuffle을 하나 하지 않으나 plotting 결과는 동일하다. 꽃받침과 꽃잎은 길이의 scale 차이가 있으므로 표준화 작업을 해준다. DecisionTreeClassifier는 코드 윗 부분에서 이미 import해서 바로 쓸수 있고 fit에는 (Data, Target) 형식으로 입력을 해주면 Decision Tree를 return 한다.

#########################################
# Plot the decision boundary
plt.subplot(2, 3, pairidx + 1)

x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, plot_step),
np.arange(y_min, y_max, plot_step))

Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
cs = plt.contourf(xx, yy, Z, cmap=plt.cm.Paired)
#########################################

plt.subplot(행, 열, index) 로 지정해주면 해당 index 위치에 plot이 생성된다. x_min, x_max 부분은 plot의 처음과 끝 값을 지정해주기 위한 부분이다. np.meshgrid(x(1d_array), y(1d_array) 함수는 두 개의 2D matrix들을 return한다. xx행렬은 x가 y의 dimension 크기의 행의 개수 만큼 반복되어 있고 yy행렬은 y가 x의 dimension 크기의 열의 개수 만큼 반복 되어 있다. xx.ravel() 함수는 행렬의 1행부터 순차적으로 원소 값을 불러와서 1차원 array를 만드는 함수이다. Reshape 함수를 사용하여 Z를 xx와 같은 차원으로 만들어 준다. clf에는 위에서 형성한 decision tree가 할당되어 있다. predict 함수를 쓰면 새로운 인풋에 대해 그 인풋이 갖는 class가 어떤 값인지 return한다. contourf 는 xx, yy가 각각 x축, y축 좌표에 해당하며 Z에 해당하는 값을 cmap에서 지정해준 색으로 mapping해주는 함수이다. 이 경우 xx, yy가 매우 촘촘하게 되어 있어서 색칠을 하는 역할을 한다. (그런데 왜 2D matrix가input이 되는 지는 좀 더 살펴 봐야 할 거 같다.)

#########################################
plt.xlabel(iris.feature_names[pair[0]])
plt.ylabel(iris.feature_names[pair[1]])
plt.axis("tight")

    # Plot the training points
for i, color in zip(range(n_classes), plot_colors):
idx = np.where(y == i)
plt.scatter(X[idx, 0], X[idx, 1], c=color, label=iris.target_names[i],
cmap=plt.cm.Paired)

plt.axis("tight")

plt.suptitle("Decision surface of a decision tree using paired features")
plt.legend()
plt.show()
#########################################

plt.axis("tight")는 어떤 기능인지 좀 더 조사를 해봐야 한다. plt.scatter는 위에서 색칠한 영역에 training data를 표시해준다. 위의 코드를 전부 실행하면 다음과 같은 결과를 얻는다.



Decision Tree로 classification을 수행하기 위해서는 Tree에 data를 preprocessing하여 전달해야 한다. 아래 그림은 http://scikit-learn.org/stable/modules/tree.html page에서 예시로 들고 있는 decision tree의 예이다. 이 post에서는 load_iris() 함수가 어떤식으로 tree에 data를 전달하는지 살펴보려고 한다.

>>> from sklearn.datasets import load_iris
>>> from sklearn import tree
>>> iris = load_iris()
>>> clf = tree.DecisionTreeClassifier()
>>> clf = clf.fit(iris.data, iris.target)

def load_iris():

"""Load and return the iris dataset (classification).
The iris dataset is a classic and very easy multi-class classification
dataset.
===============================
Classes 3
Samples per class 50
Samples total 150
Dimensionality 4
Features real, positive
===============================
Returns
-------
data : Bunch
Dictionary-like object, the interesting attributes are:
'data', the data to learn, 'target', the classification labels,
'target_names', the meaning of the labels, 'feature_names', the
meaning of the features, and 'DESCR', the
full description of the dataset.

Examples
--------
Let's say you are interested in the samples 10, 25, and 50, and want to
know their class name.
>>> from sklearn.datasets import load_iris
>>> data = load_iris()
>>> data.target[[10, 25, 50]]
array([0, 0, 1])
>>> list(data.target_names)
['setosa', 'versicolor', 'virginica']
"""
module_path = dirname(__file__)
with open(join(module_path, 'data', 'iris.csv')) as csv_file:
data_file = csv.reader(csv_file)
temp = next(data_file) n_samples = int(temp[0])         n_features = int(temp[1]) target_names = np.array(temp[2:]) data = np.empty((n_samples, n_features)) target = np.empty((n_samples,), dtype=np.int)

#########################################

With와 as 구문을 사용하여 .csv 파일을 여는 구문이다. join 함수는 나중에 다루기로 하자. 여기서 next는 읽어온 파일의 첫 번째 줄을 읽어오는 기능을 하는 함수이다. 위의 코드를 보면 n_samples, n_features에 첫 줄의 첫 번째, 두 번째 값을 저장하고 있다. 참고로 iris.csv의 첫 번째 줄은 150,4,setosa,versicolor,virginica 이다. Sample의 갯수 150개, feature의 dimension은 4, 그리고 class들의 이름이 나타나있다. numpy (as np)를 이용하여 data[150 X 4], target[150] 배열을 만든다.

#########################################

for i, ir in enumerate(data_file):

data[i] = np.asarray(ir[:-1], dtype=np.float)
target[i] = np.asarray(ir[-1], dtype=np.int)

with open(join(module_path, 'descr', 'iris.rst')) as rst_file:
fdescr = rst_file.read()

return Bunch(data=data, target=target,
target_names=target_names,
DESCR=fdescr,
feature_names=['sepal length (cm)', 'sepal width (cm)',
'petal length (cm)', 'petal width (cm)'])

#########################################

enumerate를 이용해서 data, target array에 값을 넣어준다. data_file의 경우 위에서 next(data_file) 처리를 했기 때문에 가장 첫 행은 이 반복문에 포함되지 않는다. 마지막에는 Bunch 형태로 return 한다.


The submodules often need to refer to each other. For example, the surround module might use the echo module. In fact, such references are so common that the import statement first looks in the containing package before looking in the standard module search path. Thus, the surround module can simply use import echo or from echo import echofilter. If the imported module is not found in the current package (the package of which the current module is a submodule), the import statement looks for a top-level module with the given name.

When packages are structured into subpackages (as with the sound package in the example), you can use absolute imports to refer to submodules of siblings packages. For example, if the module sound.filters.vocoderneeds to use the echo module in the sound.effects package, it can use from sound.effects import echo.

Starting with Python 2.5, in addition to the implicit relative imports described above, you can write explicit relative imports with the from module import name form of import statement. These explicit relative imports use leading dots to indicate the current and parent packages involved in the relative import. From the surround module for example, you might use:

from . import echo
from .. import formats
from ..filters import equalizer

Note that both explicit and implicit relative imports are based on the name of the current module. Since the name of the main module is always "__main__", modules intended for use as the main module of a Python application should always use absolute imports.


출처: https://docs.python.org/2/tutorial/modules.html


1. Series

Series는 다음과 같은 방식으로 생성할 수 있다.

In [20]: sdata = {'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Utah': 5000}

In [21]: obj3 = Series(sdata)

In [22]: obj3

Out[22]:

Ohio 35000

Oregon 16000

Texas 71000

Utah 50000

아래와 같이 index를 따로 지정할 수 있으며 index에 없넌 Utah는 나타나지 않으며 index에는 있지만 dictionary에 없는 California는 값을 갖지 않은체로 표시 된다. 

In [23]: states = ['California', 'Ohio', 'Oregon', 'Texas']

In [24]: obj4 = Series(sdata, index=states)

In [25]: obj4

Out[25]:

California NaN

Ohio 35000

Oregon 16000

Texas 71000

2. DataFrame

DataFrame은 다음과 같은 방식으로 생성할 수 있다.

data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'],

'year': [2000, 2001, 2002, 2001, 2002],

'pop': [1.5, 1.7, 3.6, 2.4, 2.9]}

frame = DataFrame(data)

In [38]: frame

Out[38]:

pop state year

0 1.5 Ohio 2000

1 1.7 Ohio 2001

2 3.6 Ohio 2002

3 2.4 Nevada 2001

4 2.9 Nevada 2002

특정 column이나 row에 있는 값들을 호출하고 싶을 땐 다음과 같이 하면 된다.

In [40]: frame2 = DataFrame(data, columns=['year', 'state', 'pop', 'debt'],

....:                                index=['one', 'two', 'three', 'four', 'five'])

In [41]: frame2

Out[41]:

year state pop debt

one 2000 Ohio 1.5 NaN

two 2001 Ohio 1.7 NaN

three 2002 Ohio 3.6 NaN

four 2001 Nevada 2.4 NaN

five 2002 Nevada 2.9 NaN


In [42]: frame2.columns

Out[42]: Index([year, state, pop, debt], dtype=object)


In [43]: frame2['state']                 In [44]: frame2.year

Out[43]:                                     Out[44]:

one Ohio                                     one 2000

two Ohio                                      two 2001

three Ohio                                    three 2002

four Nevada                                 four 2001

five Nevada                                  five 2002

Name: state                                 Name: year


In [45]: frame2.ix['three']

Out[45]:

year 2002

state Ohio

pop 3.6

debt NaN

Name: three

+ Recent posts