전체 글 (317)

반응형

Keras - CNN ImageDataGenerator 활용하기


keras에서는 이미지데이터 학습을 쉽게하도록 하기위해 다양한 패키지를 제공한다. 그 중 하나가 ImageDataGenerator 클래스이다. ImageDataGenerator 클래스를 통해 객체를 생성할 때 파라미터를 전달해주는 것을 통해 데이터의 전처리를 쉽게할 수 있고, 또 이 객체의 flow_from_directory 메소드를 활용하면 폴더 형태로된 데이터 구조를 바로 가져와서 사용할 수 있다. 이 과정은 매우 직관적이고 코드도 ImageDataGenerator를 사용하지 않는 방법에 비해 상당히 짧아진다. 환경은 keras tensorflow backend를 이용하였다.



1. 라이브러리 임포트

# Part 1 - Building the CNN # Importing the Keras libraries and packages from keras.models import Sequential from keras.layers import Conv2D from keras.layers import MaxPooling2D from keras.layers import Flatten from keras.layers import Dense

2. 모델 작성


ImageDataGenerator 클래스를 이용하는 것과 독립적으로 CNN 네트워크를 만들어준다. Input Image의 크기는 64x64이며, Conv-Pool-Conv-Pool-Fully Connected Layer로 이어지는 아주 간단한 구조의 CNN 모델이다. 데이터는 binary 데이터이기 때문에 activation function은 sigmoid함수 이며 손실 함수로 binary_crossentropy, 최적화 함수로는 adam을 사용한다.

# Initialising the CNN
classifier = Sequential()

# Step 1 - Convolution
classifier.add(Conv2D(32, (3, 3), input_shape = (64, 64, 3), activation = 'relu'))

# Step 2 - Pooling
classifier.add(MaxPooling2D(pool_size = (2, 2)))

# Adding a second convolutional layer
classifier.add(Conv2D(32, (3, 3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))

# Step 3 - Flattening
classifier.add(Flatten())

# Step 4 - Full connection
classifier.add(Dense(units = 128, activation = 'relu'))
classifier.add(Dense(units = 1, activation = 'sigmoid'))

# Compiling the CNN
classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])

3. ImageDataGenerator를 통한 트레이닝, 테스트 데이터 만들기


ImageDataGenerator를 만들 때 아래와 같이 rescale, shear_range, zoom_range, horizontal_flip을 설정해줌으로써 해당 데이터의 전처리를 어떻게 할지를 정해준다. 이 때 파라미터가 무엇을 뜻하는지를 정리하면 아래와 같다. (https://keras.io/preprocessing/image/)

  • shear_range: Float. Shear Intensity (Shear angle in counter-clockwise direction as radians)
  • zoom_range: Float or [lower, upper]. Range for random zoom. If a float,
  • horizontal_flip: Boolean. Randomly flip inputs horizontally.
  • rescale: rescaling factor. Defaults to None. If None or 0, no rescaling is applied, otherwise we multiply the data by the value provided (before applying any other transformation).
# Part 2 - Fitting the CNN to the images
from keras.preprocessing.image import ImageDataGenerator

train_datagen = ImageDataGenerator(rescale = 1./255,
                                   shear_range = 0.2,
                                   zoom_range = 0.2,
                                   horizontal_flip = True)

test_datagen = ImageDataGenerator(rescale = 1./255)

training_set = train_datagen.flow_from_directory('dataset/training_set',
                                                 target_size = (64, 64),
                                                 batch_size = 32,
                                                 class_mode = 'binary')

test_set = test_datagen.flow_from_directory('dataset/test_set',
                                            target_size = (64, 64),
                                            batch_size = 32,
                                            class_mode = 'binary')

classifier.fit_generator(training_set,
                         steps_per_epoch = 300,
                         epochs = 25,
                         validation_data = test_set,
                         validation_steps = 2000)

또한 flow_from_directory 메소드를 사용하면 폴더구조를 그대로 가져와서 ImageDataGenerator 객체의 실제 데이터를 채워준다. 이 데이터를 불러올 때 앞서 정의한 파라미터로 전처리를 한다. 마지막으로 fit_generator 함수를 실행함으로써 fitting이 이루어진다. 이 예제의 경우 ImageDataGenerator 객체를 사용하였기 때문에 fit_generator 함수를 통해 fitting한다. steps_per_epoch은 한 번 epoch 돌 때, 데이터를 몇 번 볼 것인가를 정해준다. [트레이닝데이터수/배치사이즈]를 사용하면 되는듯하다. validation_steps는 한 번 epoch 돌 고난 후, validation set을 통해 validation accuracy를 측정할 때 validation set을 몇 번 볼 것인지를 정해준다. 이 때도 마찬가지로 [validation data수/배치사이즈]를 사용하면 된다. 즉 ImageDataGenerator를 쓴 경우, fit_generator를 사용하면 된다고 기억하면 된다. 폴더 구조는 아래와 같이 하면 된다. flow_from_directory에 넣어준 경로(dataset/training_set) 밑에 이런식으로 class(cats, dogs) 별로 폴더를 만들고 폴더 밑에 이미지들을 넣어준다. 그러면 알아서 labeling을 하게 된다.





4. 테스트셋 예측하기


output = classifier.predict_generator(test_set, steps=5)
print(test_set.class_indices)
print(output)
{'cats': 0, 'dogs': 1}
[[ 0.58327454]
 [ 0.08756679]
 [ 0.44407782]
 [ 0.66460747]
 [ 0.38810217]
 [ 0.52190965]
 [ 0.67696238]
 [ 0.67470866]
 [ 0.77020335]
 [ 0.68121213]
 [ 0.66256768]
 [ 0.82018822]
...


반응형
반응형

Spatial Transformation Network


CNN을 통해 이미지 분류를 할 때, 특정 부분을 떼어내서 집중적으로 학습시키는 것은 Spatial Transformation Network라고 한다. 이미지 분류 문제에서는 spatial invariance(이미지가 변환되어도 그 이미지로 인식하는 것. 고양이를 90도 회전시켜놓아도 고양이로 인식하는 능력)가 중요한데 일반적인 CNN에서는 이를 해결하기 위해 max pooling layer가 필요하다. Spartial Transformation은 max pooling layer보다 더 좋은 spatial invariance 능력을 갖게 하기 위해 이미지의 특정 부분을 자르고 변환해서 그 부분만 떼어서 트레이닝을 시킨다. 이 변환하는 과정을 affine transformation이라고 하는데 아래 그림을 보면 이해할 수 있다. 



CNN 안에 하나의 layer로 spartial transformation module이 들어가는데 이 layer는 위의 affine transformation을 하는데 필요한 parameter을 배운다. 이는 일반적인 regression 과정이다. 정교하게 하기 위해서는 많은 트레이닝 데이터가 필요하다.



위 그림은 DeepMind에서 Spartial Transformation Network 관한 논문을 낼때 들어간 그림인데 일부러 지저분하게 변경한 MNIST 데이터에 이 spatial transformation을 적용해서 원하는 부분을 잘라내서 변환하는 것을 보여주고 있다. MNIST 같은 simple한 데이터셋에서는 큰 효과가 없을지 몰라도 원하는 데이터에 여러가지 잡음이 있는 경우 spartial transformation이 좋은 성능을 보여줄 것으로 기대된다.


참고

https://adeshpande3.github.io/adeshpande3.github.io/The-9-Deep-Learning-Papers-You-Need-To-Know-About.html

https://www.slideshare.net/xavigiro/spatial-transformer-networks?from_action=save

https://github.com/oarriaga/spatial_transformer_networks/blob/master/src/mnist_cluttered_example.ipynb

반응형
반응형

Pandas 변수 정렬하기


Python에서 데이터 핸들링시 가장 많이 이용하는 Pandas 패키지를 이용하여 변수를 정렬하는 예제입니다. 예를 들어 아래와 같은 데이터셋이 있다고 합시다.


cluster  org      time
   1      a       8
   1      a       6
   2      h       34
   1      c       23
   2      d       74
   3      w       6 
cluster org time 1 a 8 1 a 6 2 h 34 1 c 23 2 d 74 3 w 6

출처: http://3months.tistory.com/195 [Deep Play]
import pandas as pd
data = pd.DataFrame({"cluster" : [1,1,2,1,2,3], "org":['a','a','h','c','d','w'], "time":[8,6,34,23, 74,6]})


출처: http://3months.tistory.com/195 [Deep Play]
import pandas as pd
data = pd.DataFrame({"cluster" : [1,1,2,1,2,3], "org":['a','a','h','c','d','w'], "time":[8,6,34,23, 74,6]})


출처: http://3months.tistory.com/195 [Deep Play]


이를 pandas DataFrame 객체로 읽기 위해서는 아래와 같은 구문으로 읽으면 됩니다.

import pandas as pd
data = pd.DataFrame({"cluster" : [1,1,2,1,2,3], "org":['a','a','h','c','d','w'], "time":[8,6,34,23, 74,6]})


이후에는 DataFrame 객체에 있는 sort_values를 호출하면 해당 변수에 대해 정렬을 할 수 있습니다. ascending 파라미터는 오름차순으로 정렬할지 여부를 결정합니다. 또한 여러개의 변수에 대해서 정렬하고 싶으면 list 자료구조에 변수를 넣어주기만 하면 됩니다.

data = data.sort_values(["time"], ascending=[False])

cluster org time
4 2 d 74
2 2 h 34
3 1 c 23
0 1 a 8
1 1 a 6
5 3 w 6


그러면 이와같이 결과가 나오는데 인덱스가 뒤죽박죽이 되어있다는 것을 알 수 있습니다. 기존 데이터셋의 인덱스를 그대로 갖고 있는 것입니다. 이로인해 plot을 할 때 문제가 생길 수 있으므로 인덱스를 초기화 하는 작업을 해줍니다. default는 drop=False인데 이렇게 하게 되면 기존의 인덱스가 하나의 컬럼으로 남게 됩니다. 많은 경우 기존의 인덱스는 필요없으므로 drop=True로 설정해줍니다.


data = data.reset_index(drop=True)

cluster org time
0 2 d 74
1 2 h 34
2 1 c 23
3 1 a 8
4 1 a 6
5 3 w 6


반응형
반응형

PANDAS 그룹별 평균 구하기



통계분석에서 전체 평균을 구하는 것뿐만 아니라, 그룹간의 평균을 구하고 이를 비교하는 것은 매우 중요한 주제중 하나라고 할 수 있습니다. sas에서는 proc means by 구문을 통해 구할 수 있고, R에서는 aggregates 함수 등을 이용해 구할 수 있는데요. 파이썬에서는 R의 Data.Frame 과 비슷한 형태로 자료를 핸들링 할 수 있는 pandas라는 패키지가 있습니다. 이 패키지 함수를 통해 그룹별 평균을 구하는 방법을 알아보겠습니다.


cluster  org      time
   1      a       8
   1      a       6
   2      h       34
   1      c       23
   2      d       74
   3      w       6 


예를 들어, 위와 같은 데이터가 있다고 가정합시다. 참고로 이걸 파이썬에서 읽어오는 방법은 아래와 같이 하시면 됩니다.


import pandas as pd
data = pd.DataFrame({"cluster" : [1,1,2,1,2,3], "org":['a','a','h','c','d','w'], "time":[8,6,34,23, 74,6]})


아래 구문은 'cluster' 변수를 그룹으로 하여 모든 숫자형 변수의 평균을 계산해 줍니다. as_index=False 구문은 이 그룹을 인덱스로 지정할 것인지 여부인데, 인덱스로 지정하면 두 번째 테이블처럼 그룹이 인덱스로 들어가게됩니다. 


data.groupby(['cluster'], as_index=False).mean()


cluster time
0 1 12.333333
1 2 54.000000
2 3 6.000000



time
cluster
1 12.333333
2 54.000000
3 6.000000

아래 구문은 cluster와 org를 그룹으로 하여 평균을 계산해줍니다. 예를 들어, cluster가 지역, org가 성별이라고 생각해볼 수 있습니다. 그러면 이 구문은 지역과 성별 별로 변수들의 평균을 구하는 구문이 됩니다.

data.groupby(['cluster', 'org'], as_index=False).mean()

cluster org time
0 1 a 7
1 1 c 23
2 2 d 74
3 2 h 34
4 3 w 6


반응형
반응형

Python으로 빈도표 만들기 (Pandas Crosstab)



파이썬에서 빈도표(Frequency Table)를 만드는 방법은 여러가지가 있지만, 그 중 하나가 pandas의 crosstab 함수를 이용하는 방법이다. 아래처럼 dataframe의 컬럼(Series 데이터타입)을 파라미터로 넘겨주면 빈도표를 만들어준다.

import pandas as pd

raw_data = {'regiment': ['Nighthawks', 'Nighthawks', 'Nighthawks', 'Nighthawks', 'Dragoons', 'Dragoons', 'Dragoons', 'Dragoons', 'Scouts', 'Scouts', 'Scouts', 'Scouts'], 'company': ['infantry', 'infantry', 'cavalry', 'cavalry', 'infantry', 'infantry', 'cavalry', 'cavalry','infantry', 'infantry', 'cavalry', 'cavalry'], 'experience': ['veteran', 'rookie', 'veteran', 'rookie', 'veteran', 'rookie', 'veteran', 'rookie','veteran', 'rookie', 'veteran', 'rookie'], 'name': ['Miller', 'Jacobson', 'Ali', 'Milner', 'Cooze', 'Jacon', 'Ryaner', 'Sone', 'Sloan', 'Piger', 'Riani', 'Ali'], 'preTestScore': [4, 24, 31, 2, 3, 4, 24, 31, 2, 3, 2, 3], 'postTestScore': [25, 94, 57, 62, 70, 25, 94, 57, 62, 70, 62, 70]} df = pd.DataFrame(raw_data, columns = ['regiment', 'company', 'experience', 'name', 'preTestScore', 'postTestScore']) df


2x2 테이블


regiment를 기준으로 하여 company의 빈도를 구한다.

pd.crosstab(df.regiment, df.company, margins=True)


company cavalry infantry All
regiment


Dragoons 2 2 4
Nighthawks 2 2 4
Scouts 2 2 4
All 6 6 12



변수 3개 테이블


company, experience를 기준으로하여 regiment의 빈도를 구한다.

pd.crosstab([df.company, df.experience], df.regiment,  margins=True)



regiment Dragoons Nighthawks Scouts All
company experience



cavalry rookie 1 1 1 3
veteran 1 1 1 3
infantry rookie 1 1 1 3
veteran 1 1 1 3
All
4 4 4 12



만들어진 crosstab에 접근하는법


crosstab을 통해 생성한 객체는 dataframe 타입이고, regiment를 제외한 company와 experience는 multi index로 지정되어있다. 따라서 인덱스 값으로 해당 인덱스의 원소값을 얻는 loc 함수를 통해 crosstab 원소에 접근할 수 있다.


cross_tab = pd.crosstab([df.company, df.experience], df.regiment, margins=True)
cross_tab.loc[[('cavalry', 'rookie')]]


참고

https://chrisalbon.com/python/pandas_crosstabs.html

반응형
반응형

데이터베이스 정규화 1NF, 2NF, 3NF, BCNF



데이터베이스 정규화란 데이터베이스의 설계를 재구성하는 테크닉입니다. 정규화를 통해 불필요한 데이터(redundancy)를 없앨 수 있고, 삽입/갱신/삭제 시 발생할 수 있는 각종 이상현상(Anamolies)들을 방지할 수 있습니다. 



데이터베이스 정규화의 목적은 주로 두 가지입니다.


1. 불필요한 데이터(data redundancy)를 제거한다.

2. 데이터 저장을 "논리적으로" 한다.


여기서 2번 데이터 저장을 논리적으로 한다는 것은 데이터 테이블의 구성이 논리적이고 직관적이어야한다는 것입니다.


우선 정규화를 안 했을 때의 문제점에 대해서 알아보겠습니다.




위와 같이 정규화가 되지 않은 구조의 테이블(Adam이라는 학생이 두 번 들어가 있습니다.)의 경우, 데이터 핸들링시 다양한 이상현상이 발생하게 됩니다.


1. Update : Adam의 Address가 변경되었을 때, 여러줄의 데이터를 갱신해야합니다. 이로인해 데이터의 불일치(inconsistency)가 발생할 수 있습니다.


2. Insert : 만약 학생이 아무 과목도 수강하지 않는다고 하면, Subject_opted 컬럼에는 NULL이 들어갈 것입니다.


3. Deletion : 만약 Alex 학생이 과목 수강을 취소한다면 Alex의 레코드가 아예 테이블에서 지워져버립니다.


위와 같이 정규화가 제대로 되지 않은 테이블의 경우 갱신/삽입/삭제 시 다양한 문제점이 발생할 수 있습니다. 이를 테이블의 구성을 논리적으로 변경하여 해결하고자 하는 것이 바로 정규화입니다.


정규화의 법칙(Normalization Rule)은 1차정규화, 2차정규화, 3차정규화, BCNF, 4차정규화, 5차정규화로 나눌 수 있는데, 실무적으로 4차, 5차 정규화까지 하는 경우는 많지 않다고 합니다. 따라서 이 포스팅에서도 BCNF까지만 알아보겠습니다.



1. 1차 정규화


1차 정규형은 각 로우마다 컬럼의 값이 1개씩만 있어야 합니다. 이를 컬럼이 원자값(Atomic Value)를 갖는다고 합니다. 예를 들어, 아래와 같은 경우 Adam의 Subject가 Biology와 Maths 두 개 이기 때문에 1차 정규형을 만족하지 못합니다.



위의 정보를 표현하고 싶은 경우 이렇게 한 개의 로우를 더 만들게 됩니다. 결과적으로 1차 정규화를 함으로써 데이터 redundancy는 더 증가하였습니다. 데이터의 논리적 구성을 위해 이 부분을 희생하는 것으로 볼 수 있습니다.



2. 2차 정규화


2차 정규화부터가 본격적인 정규화의 시작이라고 볼 수 있습니다. 2차 정규형은 테이블의 모든 컬럼이 완전 함수적 종속을 만족하는 것입니다. 이게 무슨 말이냐면 기본키중에 특정 컬럼에만 종속된 컬럼(부분적 종속)이 없어야 한다는 것입니다. 위 테이블의 경우 기본키는 (Student, Subject) 두 개로 볼 수 있습니다. 이 두 개가 합쳐져야 한 로우를 구분할 수가 있습니다. 근데 Age의 경우 이 기본키중에 Student에만 종속되어 있습니다. 즉, Student 컬럼의 값을 알면 Age의 값을 알 수 있습니다. 따라서 Age가 두 번 들어가는 것은 불필요한 것으로 볼 수 있습니다.


Student Table



Subject Table


이를 해결하기 위한 방법은 위처럼 테이블을 쪼개는 것입니다. 그러면 두 테이블 모두 2차 정규형을 만족하게 됩니다. 위 테이블의 경우 삽입/갱신/삭제 이상을 겪지 않게됩니다. 하지만 조금 더 복잡한 테이블의 경우, 갱신 이상을 겪기도하는데 이를 해결하는 것이 바로 3차 정규화입니다.


3. 3차 정규화



이와 같은 데이터 구성을 생각해봅시다. Student_id가 기본키이고, 기본키가 하나이므로 2차 정규형은 만족하는 것으로 볼 수 있습니다. 하지만 이 데이터의 Zip컬럼을 알면 Street, City, State를 결정할 수 있습니다. 또한 여러명의 학생들이 같은 Zip코드를 갖는 경우에 Zip코드만 알면 Street, City, State가 결정되기 때문이 이 컬럼들에는 중복된 데이터가 생길 가능성이 있습니다. 정리하면 3차 정규형은 기본키를 제외한 속성들 간의 이행적 함수 종속이 없는 것 입니다. 풀어서 말하자면, 기본키 이외의 다른 컬럼이 그외 다른 컬럼을 결정할 수 없는 것입니다.


3차 정규화는 2차정규화와 마찬가지로 테이블을 분리함으로써 해결할 수 있는데, 이렇게 두 개의 테이블로 나눔으로써 3차 정규형을 만족할 수 있습니다. 이를 통해 데이터가 논리적인 단위(학생, 주소)로 분리될 수 있고, 데이터의 redundancy도 줄었음을 알 수 있습니다.




4. BCNF


BCNF는 (Boyce and Codd Normal Form) 3차 정규형을 조금 더 강화한 버전으로 볼 수 있습니다. 이는 3차 정규형으로 해결할 수 없는 이상현상을 해결할 수 있습니다. BCNF란 3차정규형을 만족하면서 모든 결정자가 후보키 집합에 속한 정규형입니다. 아래와 같은 경우를 생각해보면, 후보키는 수퍼키중에서 최소성을 만족하는 건데, 이 경우 (학생, 과목) 입니다. (학생, 과목)은 그 로우를 유일하게 구분할 수 있습니다. 근데 이 테이블의 경우 교수가 결정자 입니다. (교수가 한 과목만 강의할 수 있다고 가정) 즉, 교수가 정해지면 과목이 결정됩니다. 근데 교수는 후보키가 아닙니다. 따라서 이 경우에 BCNF를 만족하지 못한다고 합니다. 3차 정규형을 만족하면서 BCNF는 만족하지 않는 경우는 언제일까요? 바로 일반 컬럼이 후보키를 결정하는 경우입니다.


학생

과목

교수

학점

 1

AB123

 김인영

 A

 2

 CS123

 Mr.Sim

 A

 3

 CS123

 Mr.Sim

 A


 위와 같이 테이블이 구성된 경우에 데이터가 중복되고, 갱신 이상이 발생합니다. 예를 들어 Mr.Sim이 강의하는 과목명이 바뀌었다면 두 개의 로우를 갱신해야합니다. 이를 해결하기 위해서는 마찬가지로 테이블을 분리합니다.


교수 테이블


교수

과목

 김인영

AB123

 Mr.Sim

CS123


수강 테이블


학생

과목 

학점

 1

 AB123 

 A

 2

 CS123 

 A

 3

 CS123 

 A




참고

http://www.studytonight.com/dbms/database-normalization.php

http://pronician.tistory.com/922

반응형
반응형

Stacking을 위한 패키지 vecstack


stacking을 쉽게 할 수 있는 패키지가 있을까 해서 찾아보았는데 역시 이미 여러개가 있었다.. 여러가지 패키지중에 vecstack이 사용하기 쉬워보였는데, 매우 간단한 코드로 stacking을 구현할 수 있었다. vectstack은 아래와 같이 선택된 모델마다 "K-fold  averaging prediction" (이 명명법이 맞는지 모르겠지만, K-fold로 K번 prediction을 한 후 이 예측치들의 평균을 결과 예측치로 내놓는 방법을 뜻한다.) 을 한 후 이 결과를 앙상블하여 최종 예측 결과를 내놓게 된다. 결론적으로 stacking에 5개의 모델이 쓰이고 3-fold라면 총 15번 fitting을 하고 5개의 모델에 대한 5번의 예측결과가 나오고 다시 이것을 최종 classifier에 통과시켜 최종 prediction을 만들게 된다. 이러한 과정을 실제 코드로 구현하기는 어렵지는 않지만 코드의 양이 많아질 수도 있다.




이러한 stacking을 vecstack은 간단하게 구현한다. 단순히 모델을 정의하고, 모델들의 리스트와 train_x, train_x, test_x만 넣어주면 된다. 그러면 그 안에서 모델들에 대해 k-fold averaging prediction을 수행하며, 이를 통해 트레이닝셋과 테스트셋에 대해 각각 예측 결과 4개씩을 내놓는다. 그게 S_train, S_test이며 다시 이를 최종 classifier로 학습시켜 최종 예측 결과를 내놓게 된다. 하지만 sklearn 형식의 모델만 stacking에 활용할 수 있는 것 같다. 그것이 단점이지만 sklearn의 패키지만으로도 충분히 좋은 예측 결과를 내놓을 수 있기 때문에 stacking을 간단하게 적용해보기에 좋은 패키지인 것 같다.

from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score from sklearn.ensemble import ExtraTreesClassifier from sklearn.ensemble import RandomForestClassifier from xgboost import XGBClassifier from vecstack import stacking # Load demo data iris = load_iris() X, y = iris.data, iris.target # Make train/test split # As usual in machine learning task we have X_train, y_train, and X_test X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 0) # Caution! All models and parameter values are just # demonstrational and shouldn't be considered as recommended. # Initialize 1-st level models. models = [ ExtraTreesClassifier(random_state = 0, n_jobs = -1, n_estimators = 100, max_depth = 3), RandomForestClassifier(random_state = 0, n_jobs = -1, n_estimators = 100, max_depth = 3), XGBClassifier(seed = 0, n_jobs = -1, learning_rate = 0.1, n_estimators = 100, max_depth = 3)] # Compute stacking features S_train, S_test = stacking(models, X_train, y_train, X_test, regression = False, metric = accuracy_score, n_folds = 4, stratified = True, shuffle = True, random_state = 0, verbose = 2) # Initialize 2-nd level model model = XGBClassifier(seed = 0, n_jobs = -1, learning_rate = 0.1, n_estimators = 100, max_depth = 3) # Fit 2-nd level model model = model.fit(S_train, y_train) # Predict y_pred = model.predict(S_test) # Final prediction score print('Final prediction score: [%.8f]' % accuracy_score(y_test, y_pred))

코드 출처

https://github.com/vecxoz/vecstack



실행결과

task:   [classification]
metric: [accuracy_score]

model 0: [ExtraTreesClassifier]
    fold 0: [0.93548387]
    fold 1: [0.96666667]
    fold 2: [1.00000000]
    fold 3: [0.89655172]
    ----
    MEAN:   [0.95000000]

model 1: [RandomForestClassifier]
    fold 0: [0.87096774]
    fold 1: [0.96666667]
    fold 2: [1.00000000]
    fold 3: [0.93103448]
    ----
    MEAN:   [0.94166667]

model 2: [XGBClassifier]
    fold 0: [0.83870968]
    fold 1: [0.93333333]
    fold 2: [1.00000000]
    fold 3: [0.93103448]
    ----
    MEAN:   [0.92500000]
    
Final prediction score: [0.96666667]



반응형

'Domains > Kaggle' 카테고리의 다른 글

Stacking 사용할 때 가이드  (0) 2017.10.15
반응형

R 언어의 중요한 기초 개념 정리 


Vectorization


d <- 1:5

d.r <- c(2,1,4,5,3)

d-d.r # -1 1 -1 -1 2 (element-wise operation)

d-mean(d) # -2 -1 0 1 2 (평균인 3이 5개인 vector를 알아서 만들어서 element-wise operation을 수행한다.)


x <- c(2,3,5,7,11)

var(x) # 12.8


* 분산을 구하는 코드를 작성할 때, 일반적인 프로그래밍이라면 벡터안에 있는 원소의 수 만큼 for문을 돌면서 평균을 구하고 분산을 구한다. 하지만 R의 경우 일반적인 프로그래밍처럼 구하지 않는다. 우선, R에서 for문을 사용하는것은 좋지 않다. R은 C로 구현되었는데 for문으로 계속 연산을 실행하면 이 연산 실행하는 수만큼 C 컴파일러와 정보를 주고받는다.


xbar = mean(x)

numer = sum((x-xbar)^2)

n=length(x)

variance = numer/(n-1)


따라서 위와같이 벡터단위로 함수를 실행하여 구하는 게 일반적이고, 효율적인 방법이다.


HELP


객체의 정보를 알아보기 위해 help 함수를 활용하자.


help("mean")

help.search("mean")

apropos("mean") # mean이 포함된 함수를 모두 출력



데이터 구조와 접근법 개요


Series

1:10 # 1 2 3 ... 10


Arithmetic Series

seq(1,9,by=2) # 1,3,5,7,9

seq(1,9,length=5) # 1,3,5,7,9 (1,9를 처음과 끝으로 하여 5개의 수를 만든다.)


Repeated Vector

rep(1,10) # 1 1 1 1 1.... 1

rep(1:3, 3) # 1 2 3 1 2 3 1 2 3

rep(1:3, each=3) # 1 1 1 2 2 2 3 3 3


Assessing data with index (만든 데이터의 원소를 어떻게 불러오나)

d <- 1:5

d[2] # 2

d[1:3] # 1 2 3

d[c(1,3,5)] # 1 3 5


Negaive Index

d[-1] # 2 3 4 5

d[-c(4:5)] # 1 2 3


Replace data

d[1] <- 10

d # 10 2 3 4 5


d[1:3] <- c(10,20,30)

d # 10 20 30 4 5


Get data from logical value

d <- c(1,2,3,4,5)

d > 3.5 # FALSE FALSE FALSE TRUE TRUE

which(d>3.5) # 4 5

d[c>3.5] # 4 5 (TRUE인 원소만 값을 불러온다.)


NA


a <- c(0,1,0,NA,0,0)

a > 0 # FALSE TRUE FALSE NA FALSE FALSE (NA는 어떤 수학적인 연산을 할 수 없다.)

is.na(a) # FALSE FALSE FALSE TRUE FALSE FALSE

mean(a) # NA

mean(a, na.rm=TRUE) # 0.2



Data Type


vector, matrix, array, data.frame, list 5개가 있다.


* matrix와 vector는 비슷하다.


x <- 1:10

attr(x, 'dim') <- c(2,5)

attributes(x) # $dim [1] 2 5

x # 2x5 matrix가 된다.

class(x) # matrix

dim(x) # 2 5


* 따라서 matrix는 vector에 dimension이 추가된 것으로 볼 수 있다.

* 또한 vector는 원소의 타입이 다 같아야한다. 이는 matrix와 array도 마찬가지이다.

* dataframe와 list는 "데이터를 폴더형태로 모아놓은 환경" 이라고 볼 수 있다. 근데 차이는 dataframe은 데이터들의 길이가 같아야하고 list는 데이터의 길이에서 자유롭다. 

* R에서 $는 무엇인가? 서로 다른 환경에 접근할 때 $라는 기호를 사용한다. 예를 들어 datat$var 과 같이 data라는 dataframe 내의 var라는 환경에 접근할 수 있다. 이는 list도 마찬가지이다.


x <- data.frame(a=1:10)

x$b <- 11:20 # 해당 컬럼에 값 할당

x$c <- rep(c('a','b'),5)) 

x$c <- as.factor(x$c) # 이렇게하면 factor로 변경된다.


* 처음 dataframe을 생성하고 변수값을 초기화할 때 string vector를 지정하면 그 string들은 자동으로 factor로 변환된다. 이 때, stringAsFactors=F로해야지 자동으로 factor로 변하지 않고 string으로 저장된다.


class(x) <- NULL

class(x) # list


으로 만들면, x의 class는 list가 된다.


Attach


search()

현재 존재하는 모든 공간을 나타내준다.


attach(x)

이러고 만약 x가 데이터프레임이고 a라는 컬럼이 있다면, 커맨드에 a만쳐도 a 컬럼에 있는 데이터에 접근할 수 있다. 만약 매번 x$a로 접근하는 것이 불편하다면 attach(x)를 통해 서치 공간에 a 컬럼을 추가할 수 있다.


detach(x)

서치공간에서 x를 제거한다.


Data Export


write.table(data, 'x.txt', sep='\t', quote=F, col.names=F, row.names=F) # quote는 문자열에 기본적으로 "를 넣을 것인가? col.names와 row.names는 각각 컬럼 이름과 로우 이름을 출력할지 말지를 나타낸다. 저장되는 위치는 getwd를 통해 알 수 있으며, setwd를 통해 현재 작업디렉토리를 변경할 수 있다.


Data Import


scan(file='a.txt') # (권장하지 않음)

read.table('a.txt', header=TRUE) # 일반적으로 이렇게 읽으며, 데이터프레임으로 읽는다. 또한, 문자열은 자동으로 factor로 변환한다.


만약 데이터를 임포트할 때, 경로를 찾기가 귀찮다면, file.choose()를 이용한다. 그러면 파일 탐색기 창이 뜨고 여기서 파일을 클릭하면 자동으로 해당 경로가 문자열로 나타나게 된다.


함수


f <- function(x, y) {

return(x+y)

}



R의 함수의 기본 문법은 위와 같다. 함수의 종류에도 여러개가 있는데 그 중 하나가 제네릭 함수이다. 예를 들어, summary(f)를 하면 그 함수에 대한 설명이 나온다. 반면, summary(c(1,2,3,4,5))를 하면, 해당 벡터를 연속형 변수로 치고 분포 관련 정보를 보여주게된다. 이는 methods(summary)를 통해 알 수 있다.


> methods(summary)
 [1] summary.aov                    summary.aovlist*             
 [3] summary.aspell*                summary.check_packages_in_dir*
 [5] summary.connection             summary.data.frame           
 [7] summary.Date                   summary.default              
 [9] summary.ecdf*                  summary.factor               
[11] summary.glm                    summary.infl*                
[13] summary.lm                     summary.loess*               
[15] summary.manova                 summary.matrix               
[17] summary.mlm*                   summary.nls*                 
[19] summary.packageStatus*         summary.PDF_Dictionary*      
[21] summary.PDF_Stream*            summary.POSIXct              
[23] summary.POSIXlt                summary.ppr*                 
[25] summary.prcomp*                summary.princomp*            
[27] summary.proc_time              summary.srcfile              
[29] summary.srcref                 summary.stepfun              
[31] summary.stl*                   summary.table                
[33] summary.tukeysmooth*         

이렇게 입력 클래스로 무엇이 들어오느냐에 따라 다른 실행을 한다. lm 클래스가 들어오면, 회귀분석 결과에 관한 요약을 해주고, aov가 들어오면 분산분석 결과에 관한 요약을 해준다.


히스토그램 그리기


x <- rnorm(5000, 1, 5000) # 임의 데이터 생성

> dd <- hist(x)
> class(dd)
[1] "histogram"
 
class(dd) <- NULL # 클래스를 NULL로 바꾸면 dd가 list가 된다.
dd # 이 dd 안에는 histogram을 그리기 위한 정보들이 들어있다.


$breaks
 [1] -18000 -16000 -14000 -12000 -10000  -8000  -6000  -4000  -2000      0
[11]   2000   4000   6000   8000  10000  12000  14000  16000  18000  20000

$counts
 [1]   4   9  33  75 155 269 512 665 763 803 619 526 292 156  79  29   8   2
[19]   1

$density
 [1] 4.00e-07 9.00e-07 3.30e-06 7.50e-06 1.55e-05 2.69e-05 5.12e-05 6.65e-05
 [9] 7.63e-05 8.03e-05 6.19e-05 5.26e-05 2.92e-05 1.56e-05 7.90e-06 2.90e-06
[17] 8.00e-07 2.00e-07 1.00e-07

$mids
 [1] -17000 -15000 -13000 -11000  -9000  -7000  -5000  -3000  -1000   1000
[11]   3000   5000   7000   9000  11000  13000  15000  17000  19000

$xname
[1] "x"

$equidist
[1] TRUE

반응형

'Tools > R' 카테고리의 다른 글

R - 랜덤포레스트 실습  (0) 2017.11.11
우분투에 R과 Rstudio Server 설치  (0) 2017.11.05
R - 질적변수의 교호작용을 고려한 회귀모델  (0) 2017.05.21
R - 단순회귀분석  (0) 2017.05.21
R - (10) 리스트(List)  (0) 2017.03.04
반응형

Ecological Fallacy


https://www.britannica.com/topic/ecological-fallacy


Ecological fallacy, also called ecological inference fallacy, in epidemiology, failure in reasoning that arises when an inference is made about an individual based on aggregate data for a group. In ecological studies (observational studies of relationships between risk-modifying factors and health or other outcomes in populations), the aggregation of data results in the loss or concealment of certain details of information. Statistically, a correlation tends to be larger when an association is assessed at the group level than when it is assessed at the individual level. Nonetheless, details about individuals may be missed in aggregate data sets. There are a variety of examples of ecological fallacy; three are described in this article.


In a third example, researchers found that death rates from breast cancer were significantly increased in countries where fat consumption was high when compared with countries where fat consumption was low. This is an association for aggregate data in which the unit of observation is country. Thus, in countries with more fat in the diet and higher rates of breast cancer, women who eat fatty foods are not necessarily more likely to get breast cancer. One cannot be certain that the breast cancer cases had high fat intakes.


우선, 생태학적 연구란 관찰연구이며 risk factor와 health outcome 사이의 관계를 인구집단 단위로 보는 것이다. 생태학적 오류(Ecological Fallacy)란 하지만 이러한 인구집단별 차이가 개개인의 risk-outcome 관계를 추론하는데 실패하는 경우를 이르는 경우를 말한다. 생태학적 연구의 결과는 집단의 평균에 관한 것이며 이를 개인으로 일반화 시키면 안된다는 것을 말한다.


예를 들어, A 국가와 B 국가의 지방섭취량과 유방암 사망률을 조사해서 지방섭취량이 많은 나라가 유방암 사망률이 더 높다는 결론을 얻었다 하자. 하지만 이러한 결론을 개인화화여 "지방섭취량이 많으면 유방암 사망률을 높인다." 와 같이 결론을 내릴 수는 없다. 이 국가중 한 나라를 집어서 개인별로 지방섭취량과 유방암 사망률의 관계를 조사한 결과 이러한 생태학적 연구 결과와 상관없이 지방섭취량과 유방암의 관계는 없었다고 한다. 이처럼 생태학적 연구의 결과를 개인에 적용하면 안되며, 심지어 생태학적 연구의 결과와 이를 개인에 적용했을 때의 결과는 반대일 수도 있다.


그러면 일반화의 오류(hasty generalization)과 생태학적 오류는 어떻게 다를까? (https://enviropaul.wordpress.com/2016/04/03/logical-fallacies-and-the-environment-hasty-generalization-and-the-ecological-fallacy/) 일반화의 오류는 작은 데이터로 전체를 판단하는 오류이다. 이는 집단의 평균적 특성을 개인에 적용하면 안된다는 생태학적 오류와는 다소 다르다.


* 2017/10/17 추가


생태학적 연구로 risk-outcome의 관계에 대해 결론을 내릴 수 없다면 생태학적 연구는 왜 하는 것일까? 이유는 생태학적 연구를 통해 가설을 생성(hypothesis genetraing) 할 수 있기 때문이다. 생태학적 연구를 통해 어떠한 risk가 outcome의 잠재적인 원인이 될 수 있다는 가설을 세울 수 있고, 이를 RCT 등의 연구를 통해 검증할 수 있다. 또한 생태학적 연구의 장점은 비용과 시간이 적게 들며, 개인으로는 쉽게 얻을 수 있는 데이터를 쉽게 얻을 수 있다는 점이다. 예를 들어 개인의 알코올 섭취량과 어떤 질병의 관계에 관한 연구에서, 개인의 정확한 알코올 섭취량을 얻기는 힘들다. (설문지 등을 이용하여야하기 때문에 이로 인해 bias가 생길 수  있음) 하지만, 생태학적 연구를 통해 집단별로 연구를 하게 되면 그 지역의 주류세 등을 이용해 알코올 섭취량과 질병의 관계를 집단 단위로 수행할 수 있게 된다.


반응형
반응형

IGV Tutorial


IGV(Intergrative Genomics View)는 게놈 데이터를 시각화하고 인터랙티브하게 볼 수 있는 생명정보학 툴이다. 또한 다양한 포맷의 데이터를 로드할 수 있어 매우 편리한 것 같다. array-based 데이터, ngs 데이터, annotation 데이터 모두 로드할 수 있다고 한다.


1. 다운로드


http://www.broadinstitute.org/software/igv/download

실행은 다운받은 폴더에서 igv.bat 을 실행하면 된다.


2. reference fasta 파일 로드


Genomes - Load Genome From File을 통해 reference file을 로드한다. 필자는 hg19 13번 염색체 fasta 파일을 로드하였다.


3. bam 파일 로드


File - Load from File에서 bam 파일을 로드한다. 이 때 bam 파일 인덱스 파일도 필요하다. IGV에서 로드하기 전에 samtools를 통해 bam 파일의 인덱스 파일을 만든다. bam 파일은 reference 에 mapping된 시퀀스 데이터를 나타내주기 때문에 이처럼 reference 파일과 같이 로드해야한다. bam 파일은 ENCODE 데이터 중에서 아무거나 가져와서 로드했다. 용량은 91.6Mb 정도 됐던 것 같다.





둘 다 로드를 완료하면 위 화면과 같이 나온다. 매핑된 부분이 옅은 회색으로 나오는 것을 볼 수 있다. 짙은 회색은 coverage를 나타낸다. bam 파일에는 어떤 reference 데이터에 매핑되어있는지를 이름으로 나타 내는데 만약 이 이름이 다르다면 bam 파일을 로드할 수 없다. 예를 들어, 앞서 로드한 reference fasta 파일의 >chr13 부분을 다르게 변경하면 bam 파일을 로드할 수 없다. 왜냐하면 bam 파일에는 chr13이라는 이름으로 align 되어있기 때문이다. 이 데이터는 ENCODE에서 받았는데 시퀀스가 이어져있지않고 조각조각 흩어져있다. "특정 기능" 을 하는 부분만 시퀀스 된 정보로 볼 수 있다. 저 회색 부분에 마우스를 올려보면 아래와 같은게 뜬다.



이는 그 리드의 기본적인 정보(이름, 길이)와 reference sequence에 매핑된 위치와 CIGAR 정보를 나타내준다.



참고

TreeGenes_IGV_Tutorial.pdf


반응형

'Domains > Bioinformatics' 카테고리의 다른 글

Chip-seq 데이터를 통한 binding motif 분석 [rGADEM]  (0) 2018.01.13
Variant calling 이란?  (0) 2017.11.20
Sam File  (0) 2017.10.16
K-MERS 란  (2) 2017.10.12
Chip-seq 관련 정리 - 데이터 받기  (1) 2017.10.07
반응형