분류 전체보기 (336)

반응형

Nested case-control study

우선 nested case-control study란, 코호트 데이터에서 질병 상태에 따라 case-control을 뽑아내서 case-control study를 하는 것을 말한다. 예를 들어 어떤 코호트 스터디에서  10년간 추적관찰을 하였는데 10만명의 사람중 2천명이 유방암에 걸렸다고 하자. 이 때, case와 control을 적절하게 추출해 gene expression의 차이를 보고 싶다고 하자. 이것이 nested case-control study의 예라고 할 수 있다. 만약 cohort 초기에 gene expression 데이터셋을 구축하고자 한다면, 10만명의 사람들의 피를 추출해 gene expression DB를 구축해야할 것이다. 하지만 nested case-control study 방법으로 한다면, 보통, case의 1-4배 정도 되는 control을 추출해 gene expression을 분석하면 되기 때문에 시간과 비용을 아낄 수 있다. 실제로 nested case-control study는 biomarker를 이용하는 연구에서 많이 사용하는 방법이다. 


Retrospective cohort study

retrospective cohort study(후향적 코호트 연구)란 cohort study의 크게 두 가지 범주(전향적, 후향적 코호트 연구) 중 하나로, 연구 시점이 코호트 데이터를 모은 '후' 가 되는 연구를 말한다. 이는 nested case-control study와 비슷한데, 마찬가지로 연구 시점이 코호트 모집 전이 아니라 후이기 때문이다.  하지만 후향적 코호트 연구의 경우, 기본적으로 코호트 연구이며, case-control처럼 질병 상태에 따라 연구 집단을 뽑지 않는다는 차이가 있다. 예를 들어, 광산에서 일하는 광부들을 10년간 추적 관찰했다고 하자. 추후에 이 광부들을 대상으로 lung cancer으로 인한 사망률을 일반 인구집단과 비교해 알아보고 싶은 경우, 이것이 후향적 코호트 연구의 예가 될 수 있다. 이 광부 코호트로 nested cohort study를 하는 경우는 lung cancer에 따라 case-control을 추출 한 후, 이 case-control을 대상으로 exposure을 비교하는 경우이다.


참고 

https://en.wikipedia.org/wiki/Nested_case-control_study

http://epidemiologyclass.blogspot.kr/2004/10/difference-between-nested-case-control.html

반응형
반응형

Pandas (Python Data Analysis Library)



앞선 포스팅에 이어 Pandas 중고급 문법 튜토리얼입니다. 본 포스팅은 해당 포스팅을 참고하였습니다.


5. 컬럼명, 인덱스명 수정하기


df = pd.DataFrame(data=np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]), columns=['A', 'B', 'C'])
display(df)

# Define the new names of your columns
newcols = {
    'A': 'new_column_1', 
    'B': 'new_column_2', 
    'C': 'new_column_3'
}

# Use `rename()` to rename your columns
df.rename(columns=newcols, inplace=True)

# Rename your index
df.rename(index={1: 'a'})



이번엔 기본기를 넘어 pandas의 고급 문법들을 살펴 보자.



6. 데이터 Formatting


Replace


dataframe의 특정 문자열을 바꾸고 싶을 때는 replace를 이용한다.


df = pd.DataFrame(data=np.array([["Awful", "Poor", "OK"], ["OK", "Acceptable", "Perfect"], ["Poor", "Poor", "OK"]]), columns=['A', 'B', 'C'])
display(df)

display(df.replace("Awful", "Nice"))

# Replace the strings by numerical values (0-4)
display(df.replace(['Awful', 'Poor', 'OK', 'Acceptable', 'Perfect'], [0, 1, 2, 3, 4]))



String의 일부 제거


map function과 lambda를 이용해 특정 컬럼의 모든 데이터에 함수를 적용시킬 수 있다. 


df = pd.DataFrame(data=np.array([[1, 2, "+6a"], [4, 5, "+3b"], [5, 5, "+2C"]]), columns=['A', 'B', 'result'])

# Check out your DataFrame
display(df)

# Delete unwanted parts from the strings in the `result` column
df['result'] = df['result'].map(lambda x: x.lstrip('+-').rstrip('aAbBcC'))

# Check out the result again
display(df)



7. 열 또는 행에 함수 적용하기


map 또는 apply 함수를 이용한다.

df = pd.DataFrame(data=np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]), columns=['A', 'B', 'C'])
doubler = lambda x: x*2
print(df.head())
print(df['A'].map(doubler))
print(df.apply(doubler))
print(df.iloc[1].apply(doubler))
  A  B  C
0  1  2  3
1  4  5  6
2  7  8  9
0     2
1     8
2    14
Name: A, dtype: int64
    A   B   C
0   2   4   6
1   8  10  12
2  14  16  18
A     8
B    10
C    12
Name: 1, dtype: int64



8. 빈 데이터 프레임 만들기 (Creating empty dataframe)


가끔 빈 데이터 프레임을 만들고, 그 곳에 값을 채워야할 경우가 있다. 이것을 하기 위해서는 인덱스와 컬럼을 만든 후, np.nan 을 채워주면 된다.

df = pd.DataFrame(np.nan, index=[0,1,2,3], columns=['A'])
print(df)

그 속에 값을 채워넣고 싶으면 아래처럼 할 수 있다.

df.loc[1, 'A'] = "A"


9. 데이터 임포트시, 날짜, 시간 parsing 하기


만약 날짜 시간으로된 컬럼을 datatime 으로 parsing 하기 위해서는 read_csv 메소드의 parse_dates 를 이용할 수 있다.

import pandas as pd
dateparser = lambda x: pd.datetime.strptime(x, '%Y-%m-%d %H:%M:%S')

# Which makes your read command:
pd.read_csv(infile, parse_dates=['columnName'], date_parser=dateparse)

# Or combine two columns into a single DateTime column
pd.read_csv(infile, parse_dates={'datetime': ['date', 'time']}, date_parser=dateparse)  


10. 데이터프레임 재구성하기


pivot 함수를 통해 index, column, values 를 지정하여 재구성할 수 있다.

import pandas as pd

products = pd.DataFrame({'category': ['Cleaning', 'Cleaning', 'Entertainment', 'Entertainment', 'Tech', 'Tech'],
        'store': ['Walmart', 'Dia', 'Walmart', 'Fnac', 'Dia','Walmart'],
        'price':[11.42, 23.50, 19.99, 15.95, 55.75, 111.55],
        'testscore': [4, 3, 5, 7, 5, 8]})

print(products)

pivot_products = products.pivot(index='category', columns='store', values='price')
print(pivot_products)
 category    store   price  testscore
0       Cleaning  Walmart   11.42          4
1       Cleaning      Dia   23.50          3
2  Entertainment  Walmart   19.99          5
3  Entertainment     Fnac   15.95          7
4           Tech      Dia   55.75          5
5           Tech  Walmart  111.55          8
store            Dia   Fnac  Walmart
category                            
Cleaning       23.50    NaN    11.42
Entertainment    NaN  15.95    19.99
Tech           55.75    NaN   111.55


Stack & Unstack


pivot 함수를 이용할 수도 있지만, stack 과 unstack 함수를 이용하여 pivoting 을 할 수 있다. stack 은 column index를 raw index로 바꾸어 데이터프레임이 길어지고, unstack 은 raw index를 column index로 바꾸어 데이터프레임이 넓어진다. 


Stack 과 Unstack 의 개념도


본 포스팅에서는 간단한 개념만 설명하며, 테이블 pivoting 관련해서는 이 페이지 (https://nikgrozev.com/2015/07/01/reshaping-in-pandas-pivot-pivot-table-stack-and-unstack-explained-with-pictures/) 가 정리가 잘 되어있으니 참고하시면 좋을 것 같다.


melt 함수


melt 함수는 column 을 row로 바꾸어준다. 녹으면 흘러내리니까 column 이 raw로 흘러려 column 이 짧아지고 raw 는 길어진다고 이해하면 쉽다. 

# The `people` DataFrame
people = pd.DataFrame({'FirstName' : ['John', 'Jane'],
                       'LastName' : ['Doe', 'Austen'],
                       'BloodType' : ['A-', 'B+'],
                       'Weight' : [90, 64]})

print(people)

# Use `melt()` on the `people` DataFrame
print(pd.melt(people, id_vars=['FirstName', 'LastName'], var_name='measurements'))
FirstName LastName BloodType  Weight
0      John      Doe        A-      90
1      Jane   Austen        B+      64
  FirstName LastName measurements value
0      John      Doe    BloodType    A-
1      Jane   Austen    BloodType    B+
2      John      Doe       Weight    90
3      Jane   Austen       Weight    64



11. 데이터 프레임 반복하기


iterrows 함수를 이용하여 iteration 할 수 있다. 매우 유용하다.

df = pd.DataFrame(data=np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]), columns=['A', 'B', 'C'])

for index, row in df.iterrows() :
    print(row['A'], row['B'])
1 2
4 5
7 8


반응형
반응형

Pandas (Python Data Analysis Library)


파이썬을 통해 데이터 분석을 할 때, Pandas를 빼놓고 이야기할 수 없다. 온전히 통계 분석을 위해 고안된 R 과는 다르게 python은 일반적인 프로그래밍 언어(general purpose programming language) 이며, 데이터 분석을 하기 위해서는 여러가지 라이브러리를 사용할 수 밖에 없다. 이 패키지들 중 R의 dataframe 데이터 타입을 참고하여 만든 것이 바로 pandas dataframe이다. pandas는 dataframe을 주로 다루기 위한 라이브러리이며, dataframe을 자유롭게 가공하는 것은 데이터 과학자들에게 중요하다. 물론 pandas의 문법을 외우지 않고, 필요할 때마다 책이나 웹에서 찾아가면서 해도 좋지만 자주 사용하는 조작법을 외운다면 안 그래도 귀찮은 데이터 핸들링 작업을 빠르게 할 수 있다.


그래서 본 포스팅에서는 pandas dataframe을 다루는 법을 간단하게 정리해보고자 한다. 

본 포스팅은 이 튜토리얼을 참고하였다. 



Tabular Data type


Pandas Dataframe은 테이블 형식의 데이터 (tabular, rectangular grid 등으로 불림)를 다룰 때 사용한다. pandas dataframe의 3요소는 컬럼, 데이터(로우), 인덱스가 있다. 그리고 파이썬의 기본 데이터 타입으로 list, tuple, dictionary가 있다는 것도 다시 한 번 떠올리고 바로 튜토리얼을 해보자. 본 튜토리얼은 jupyter notebook, python3 환경에서 작성되었다.


1. Pandas Dataframe 만들기


pandas dataframe은 다양한 데이터 타입으로부터 만들 수 있다. ndarray, dictionary, dataframe, series, list의 예를 들고 있다.(IPython의 display 함수는 IPython 쉘 환경에서 pandas dataframe을 테이블 형식으로 표현해준다.)


# 1. Create Pandas Dataframe
from IPython.display import display
# Take a 2D array as input to your DataFrame 
my_2darray = np.array([[1, 2, 3], [4, 5, 6]])
display(pd.DataFrame(my_2darray))

# Take a dictionary as input to your DataFrame 
my_dict = {"a": ['1', '3'], "b": ['1', '2'], "c": ['2', '4']}
display(pd.DataFrame(my_dict))

# Take a DataFrame as input to your DataFrame 
my_df = pd.DataFrame(data=[4,5,6,7], index=range(0,4), columns=['A'])
display(pd.DataFrame(my_df))

# Take a Series as input to your DataFrame
my_series = pd.Series({"United Kingdom":"London", "India":"New Delhi", "United States":"Washington", "Belgium":"Brussels"})
display(pd.DataFrame(my_series))


01

1

abc
0112
1324
A
04
15
26
37
BelgiumBrussels
IndiaNew Delhi
United KingdomLondon
United StatesWashington


Series의 경우 pandas에서 제공하는 데이터타입인데, index가 있는 1차원 배열이라고 생각하면 좋다. 문자, 논리형, 숫자 모든 데이터타입이 들어갈 수 있다. dataframe의 한 컬럼, 한 컬럼이 series이다.


Dataframe 간단하게 살펴보기


df.shape를 통해 dataframe의 row와 column 수를 알 수 있다. .index를 통해 index를 알 수 있으며, len을 통해 dataframe의 길이(row의 갯수)를 알 수 있다.


df = pd.DataFrame(np.array([[1, 2, 3], [4, 5, 6]]))

# Use the `shape` property
print(df.shape)

# Or use the `len()` function with the `index` property
print(len(df.index))


(2, 3)
2


list(df.columns)


[0, 1, 2]



2. Dataframe에서 특정 컬럼이나 로우(인덱스) 선택하기


실무적으로 가장 많이 사용되는 부분중 하나는 바로 Dataframe에서 특정 컬럼이나 로우를 선택하여 그 값을 보는 것이다. pandas에서는 상당히 다양한 방법들이 있다. 대표적으로 iloc, loc, ix 등을 통해서 할 수 있다. 필자는 column을 조회할때 df['column'], row를 조회할 때는 df.ix[index]를 많이 사용한다. 가장 짧고 기억하기 쉽다.


우선 파이썬 기본 데이터 타입인 dictionary 데이터 타입을 통해 dataframe을 만든다. 


df = pd.DataFrame({"A":[1,4,7], "B":[2,5,8], "C":[3,6,9]})


# Use `iloc[]` to select a row
display(df.iloc[0])
display(df.loc[0])
display(df.ix[0])

# Use `loc[]` to select a column
display(df.loc[:,'A'])
display(df['A'])

# 특정 row, column을 선택하기
display(df.ix[0]['A'])
display(df.loc[0]['B'])


A    1
B    2
C    3
Name: 0, dtype: int64

A 1 B 2 C 3 Name: 0, dtype: int64

A 1 B 2 C 3 Name: 0, dtype: int64

0 1 1 4 2 7 Name: A, dtype: int64

0 1 1 4 2 7 Name: A, dtype: int64

1

2


3. Dataframe에 컬럼, 로우, 인덱스 추가하기


2에서는 Dataframe의 특정 컬럼, 로우에 접근하는 방법을 알아보았고, 이제 데이터를 추가하거나 수정, 삭제하는 실제 작업 방법을 알아보자.


인덱스 설정하기


pandas는 기본적으로 row에 인덱스를 0부터 차례대로 자연수를 부여한다. 이를 변경하는 방법은 set_index 함수를 이용하는 것이다. 아래의 df.set_index('A')는 A 컬럼을 인덱스로 지정하는 것을 뜻한다. 그러면 3개의 row에 대하여 인덱스가 1,4,7이 부여된다. 


# Print out your DataFrame `df` to check it out
df = pd.DataFrame({"A":[1,4,7], "B":[2,5,8], "C":[3,6,9]})
display(df)

# Set 'C' as the index of your DataFrame
df = df.set_index('A')
display(df)


 

A

B
 0 1 2 3
 1 4 5 6
 2 7 8 9
BC
A
123
456
789

인덱스 접근하기 (ix와 iloc의 차이점)

인덱스를 접근하는 방법에 여러가지가 있다. ix, loc, iloc 등을 쓸 수 있다. 필자는 ix를 주로 쓴다. ix와 iloc의 차이점은 iloc은 인덱스와 상관 없이 순서를 보고 row를 불러온다. 아래 코드에서 ix[7]은 index가 7인 로우를 불러오는 것이며, iloc[1]은 1번째 로우를 불러오는 것이다. (0번째 로우부터 시작) 근데 ix의 경우 주의할점은 index가 integer로만 이루어진 경우에는 index로 접근하지만, index에 문자가 껴있으면 순서로 접근한다는 점이다.  

print(df.ix[7])
print(df.iloc[1])

B    8
C    9
Name: 7, dtype: int64
B    5
C    6
Name: 4, dtype: int64


예를 들어, 아래 코드를 보면, 인덱스를 문자와 숫자가 혼합된 형태로 주었다. 이 때 ix[2]로 로우를 부르면 인덱스가 아니라 순서로 로우를 불러오게된다. 


df = pd.DataFrame(data=np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]), index= [2, 'A', 4], columns=[48, 49, 50])

display(df)
# Pass `2` to `loc`
print(df.loc[2])

# Pass `2` to `iloc`
print(df.iloc[2])

# Pass `2` to `ix`
print(df.ix[2])



48

49

50 

 2

 1 2 3
 A 4 5  6
 4 7 8 9
48    1
49    2
50    3
Name: 2, dtype: int64
48    7
49    8
50    9
Name: 4, dtype: int64
48    7
49    8
50    9
Name: 4, dtype: int64


로우 추가하기


ix의 경우 df.ix[2]를 입력하면 index=2인 곳의 row를 교체한다. 만약 index=2인 row가 없다면 position=2에 row를 추가하게 된다. loc을 사용하면 새로운 index=2인 row를 만들고, 그 곳에 row를 추가하게 된다. 


df = pd.DataFrame(data=np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]), index= [2.5, 12.6, 4.8], columns=[48, 49, 50])
display(df)

# There's no index labeled `2`, so you will change the index at position `2`
df.ix[2] = [60, 50, 40]
display(df)

# This will make an index labeled `2` and add the new values
df.loc[2] = [11, 12, 13]
display(df)


Append를 이용해 로우 추가하기


때론 인덱스를 신경쓰지 않고 그냥 데이터의 가장 뒤에 row를 추가하고 싶을 수도 있다. 이 경우에는 append를 사용하면 좋다. 아래는 df 데이터프레임에 a를 추가하여 row를 추가하는 코드를 보여준다. row를 추가한 후에 reset index를 통해 index를 0부터 새롭게 지정한다. 이는 실제 작업할 때 많이 쓰는 테크닉이다. 


df = pd.DataFrame(data=np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]), columns=[48, 49, 50])
display(df)

a = pd.DataFrame(data=[[1,2,3]], columns=[48,49,50])
display(a)

df = df.append(a)
df = df.reset_index(drop=True)
display(df)




48 

4950
 0  1 2 3
 1 4 5 6
 2 7 8 9
484950
0123



48 4950
 0  1 2 3
 1 4 5 6
 2 7 8 9
 3 1 2 3



컬럼 추가하기


컬럼을 추가하는 방법도 여러가지가 있다. 아래는 loc을 통해 추가하거나, df['column']을 통해 추가하는 방법이다.


df = pd.DataFrame(data=np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]), columns=['A', 'B', 'C'])

# Study the DataFrame `df`
display(df)

# Append a column to `df`
df.loc[:, 'D'] = pd.Series(['5', '6', '7'], index=df.index)

# Print out `df` again to see the changes
display(df)

df['E'] = pd.Series(['5', '6', '7'], index=df.index)
display(df)



 A BC
 0 1 2 3
 1 4 5 6
 2 7 8

ABCD
01235
14566
27897

ABCDE
012355
145666
278977



4. Dataframe의 인덱스, 컬럼, 데이터 삭제하기


인덱스 삭제


인덱스를 지워야할 경우는 그렇게 많지 않을 것이다. 주로 reset_index를 이용해서 index를 리셋하는 것을 많이 사용한다. 혹은 index의 이름을 삭제하고 싶다면 del df.index.name을 통해 인덱스의 이름을 삭제할 수 있다. 


컬럼 삭제


drop 명령어를 통해 컬럼 전체를 삭제할 수 있다. axis=1은 컬럼을 뜻한다. axis=0인 경우, 로우를 삭제하며 이것이 디폴트이다. inplace의 경우 drop한 후의 데이터프레임으로 기존 데이터프레임을 대체하겠다는 뜻이다. 즉, 아래의 inplace=True는 df = df.drop('A', axis=1)과 같다.


df = pd.DataFrame(data=np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]), columns=['A', 'B', 'C'])
display(df)

# Drop the column with label 'A'              
# drop axis의 경우 column이면 1, row이면 0이다.
df.drop('A', axis=1, inplace=True)
display(df)




A

B

 0 1 2
 1 4

6

 2 7 8
BC
023
156
289


로우 삭제


- 중복 로우 삭제


drop_duplicate를 사용하면 특정 컬럼의 값이 중복된 로우를 제거할 수 있다. keep 키워드를 통해 중복된 것들 중 어떤 걸 킵할지 정할 수 있다.


df = pd.DataFrame(data=np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [40, 50, 60], [23, 35, 37]]), 
                  index= [2.5, 12.6, 4.8, 4.8, 2.5], 
                  columns=[48, 49, 50])

display(df)

df = df.reset_index()
display(df)

df = df.drop_duplicates(subset='index', keep='last').set_index('index')
display(df)




48

49 50
 2.5 1 2 3

12.6 

 5 6
 4.8 7

8

 4.840 50 60 
 2.523 35 37 

index484950
02.5123
112.6456
24.8789
34.8405060
42.5233537

484950
index
12.6456
4.8405060
2.5233537


- 인덱스를 통한 로우 삭제


drop 명령어를 통해 특정 index를 가진 row를 삭제할 수 있다. df.index[1] 명령어는 1번 째 위치에 있는 index를 가져온다. 가져온 이 index를 drop에 인풋으로 넣어주면 해당 index를 가진 row를 삭제할 수 있다.


# Check out your DataFrame `df`
df = pd.DataFrame(data=np.array([[1, 2, 3], [1, 5, 6], [7, 8, 9]]), columns=['A', 'B', 'C'])
display(df)

# Drop the index at position 1
print(df.index[1])
print(df.drop(df.index[1]))
print(df.drop(0))



A

 B

C
 0 1 
 1 1 5 6
 2 7


   A  B  C
0  1  2  3
2  7  8  9
   A  B  C
1  1  5  6
2  7  8  9

데이터 수정하기


특정 컬럼, 로우의 데이터를 수정하고 싶으면 ix 를 이용하면 편하다. 아래 코드는 인덱스=0, 컬럼=A의 데이터를 0으로 수정한다. 


df = pd.DataFrame(data=np.array([[1, 2, 3], [1, 5, 6], [7, 8, 9]]), columns=['A', 'B', 'C'])
display(df)

df.ix[0]['A'] = 0
display(df)




A

 B

C
 0 1 
 1 1 5 6
 2 7
ABC
0023
1156
2789


반응형
반응형

유명하고 많이 사용하는 R 패키지 정리

가장 유명하고, 많이 다운로드 되는 R 패키지들을 그 목적에 따라서 정리하였습니다. 본 포스트는 이 포스트를 참고하였습니다.

데이터 로드

RMySQL, RPostgresSQL, RSQLite - 데이터 베이스로부터 직접 데이터를 읽을 때 사용하는 패키지들이다. R[데이터베이스명] RMySQL은 MySQL의 데이터들을 직접 R로 불러올 수 있다.

XLConnect, xlsx - 이 패키지들은 Microsoft사의 엑셀을 R로부터 직접 읽어올 수 있게 한다. 물론, write도 가능하다.

foreign - SAS, SPSS 데이터셋을 읽어올 때 사용한다. 예를 들어, SAS의 경우 sas7bdat 확장자로 되어있는 파일인데, 이를 읽어올 때 foreign 패키지를 활용할 수 있다.


일반적인 텍스트 파일을 로드할 때, R에서는 별다른 패키지가 필요하지 않다. read.csv, read.table, read.fwf를 이용하면 된다. 이외의 독특한 자신만의 데이터셋을 불러오고 싶다면 CRAN guide에 데이터 import, export에 관하여 문의할 수도 있다. 

데이터 핸들링

dplyr - 데이터 subsetting, summarizing, rearranging, joining에 대한 더 쉬운 길을 제공한다. dplyr는 빠른 데이터 핸들링을 위하여 반드시 사용하는 패키지이다.(go to package) 

tidyr - 데이터셋의 레이아웃을 바꿀 때 유용한 툴이다. 데이터를 tidy format으로 바꾸기 위해 gather이나 spread 함수를 사용할 수 있다.

stringr - 문자열 다루는 것과 정규 표현식 관련 패키지이다. 

lubridate - date와 time을 더욱 다루기 쉽게 만드는 툴이다.

데이터 시각화

ggplot2 - R의 매우 유명한 시각화 패키지이다. grammar of graphics 를 활용하여 layered, customizable plot을 만들 수 있다는 장점이 있다.

ggvis grammar of graphics을 기반으로 동작하는, 대화형, 웹베이스의 그래픽 라이브러리이다.

rgl - Interactive 3D 시각화를 위한 라이브러리이다. 

htmlwidgets - 자바스크립트 기반의 interactive 시각화를 위한 툴이다. 이 패키지는 아래와 같은 htmlwidget들을 구현하고 있다.

googleVis - R에서 데이터 시각화를 위해 구글 차트를 이용할 수 있게한다. 구글 차트 툴은 Gapminder라고 불리기도 한다. 이는 시각화 소프트웨어로, Hans Rosling의 TED 출연으로 유명해졌다.


데이터 모델링

car - car 패키지의 Anova 함수는 type2, type3 아노바 테이블을 만드는데 유명하다.

mgcv - Generalized Additive Models

lme4/nlme - Linear, Non-linear 혼합효과모형

randomForest - 머신러닝의 랜덤 포레스트

multcomp - 다중비교를 위한 툴

vcd - 범주형 변수의 시각화와 분석을 위한 툴이다.

glmnet - Lasso, elastic-net 회귀분석을 cross validation과 함께 해준다.

survival - 생존분석

caret - 회귀분석 및 분류 모델의 트레이닝을 위한 툴이다.


데이터 리포트

shiny - 인터랙티브한 웹앱을 쉽게 만들어준다. 프로그래머가 아닌 일반 사람들에게 데이터 exploring과 sharing을 쉽게 만들어준다.

R Markdown - Reproducible reporting을 위한 툴이다. R 코드를  markdown 에 쓰고, render을 하면 R Markdown은 코드를 코드 실행 결과와 함께 HTML, pdf, word 형식으로 export를 해준다. 결과를 정리하는 다른 과정 없이 자동화된 리포팅을 알 수 있게 된다. R Markdown은 RStudio와 통합된다.

xtable - xtable 함수는 R Object(예를 들어, dataframe)를 통해 latex이나 HTML 코드로 리턴해준다. 이를 통해 문서에 붙여넣기를 쉽게할 수 있다. 

공간 데이터 

sp, maptools - shapefile을 비롯한 공간 데이터를 로딩할 수 있는 툴이다.

maps -  맵에 다각형을 쉽게 그려주는 툴이다.

ggmap -  Google map으로 부터 street map을 다운로드 받고, ggplot의 background로 쓸 수 있다.

시계열, 금융 데이터

zoo - 시계열 데이터를 저장하기 위한 가장 유명한 포맷을 다룰 수 있다.

xts - 시계열 데이터를 다루기 위한 툴

quantmod - 금융 데이터를 다운로드하고, 그래프를 그리고, 분석할 수 있는 툴이다.

높은 성능을 내기 위한 R 코드 작성

Rcpp - C++을 call하는 R function을 사용한다. 

data.table - 데이터셋을 빠르게 조작하기 위한 다른 방법을 사용한다. "빅 데이터"에 유용하다.

parallel - 큰 데이터 셋을 다루기 위한 병렬 프로세싱을 사용한다.

웹으로 작업하기

XML - R을 통해 XML 문서를 읽고 만드는 패키지

jsonlite - R을 통해 JSON 데이터를 읽고 만드는 패키지

httr - HTTP Connection을 통한 작업을 위한 라이브러리

R 패키지 만들기

devtools - 코드를 R 패키지로 만들기

testthat - 프로젝트의 유닛 테스트를 위한 쉬운 방법을 제공한다.

roxygen2 - R 패키지의 도큐먼트를 만들기 위한 빠른 방법. roxygen2는 코드의 코멘트를 도큐먼트로 만들고, 패키지의 네임스페이스를 만든다.


반응형
반응형


Python 중고급 - 정규표현식, 클래스



정규 표현식


파이썬에서 정규표현식을 이용하는 것은 re 라이브러리를 이용하면 된다. import re 구문으로 re 라이브러리를 임포트할 수 있다. 


print(all([not re.match("a", "cat"), # cat은 a로 시작하지 않는다.
          re.search("a", "cat"), # cat에 a가 존재하기 때문에 
          not re.search("c", "dog"), # c가 dog에 존재하지 않기 때문에
          3 == len(re.split("[ab]", "carbs")), # a,b로 나누면 'c', 'r', 's' 를 원소로 하는 list가 생성된다.
          "R-D-" == re.sub("[0-9]", "-", "R2D2")])) # sub를 통해 숫자를 -로 대체


객체 지향 프로그래밍


Stack 자료구조를 파이썬의 객체 지향을 이용해서 간단하게 구현하였다. add 함수는 stack에 데이터를 저장하고, pop 함수는 stack의 가장 위에 있는 데이터를 삭제한다. stack은 파이썬의 기본 자료구조인 list를 이용하여 구현하였다. 


class stack : 
    def __init__(self) : 
        "이것은 생성자이다."
        self.list = []
        self.length = 0
        
    def add(self, value) :
        self.list.append(value)
        self.length += 1
    
    def pop(self) : 
        del self.list[self.length-1]
        
    def __repr__(self) : 
        """ 파이썬 프롬프트에서 이 함수를 입력하거나 str()으로 보내주면
            Set 객체를 문자열로 표현해줌 """
        return "Stack : " + str(self.list)


my_stack = stack()

my_stack.add(value=3)
print(my_stack)


Stack : [3]


my_stack.add(value=5)

print(my_stack)


Stack : [3, 5]


my_stack.pop()

print(my_stack)


Stack : [3]


반응형
반응형

문자 변수를 날짜 변수로 변환하기


R에서 시계열 데이터를 다룰 때, 변수를 날짜 타입으로 변환한다면 플롯을 하는데 간편한 점이 많다. R의 날짜 데이터 타입으로는 "POSIXct" 가 있으며, as.POSIXct 함수를 통해 문자 변수를 POSIXct 타입으로 변환할 수 있다. 반대로 POSIXct 타입을 문자 타입으로 바꾸는 것은 format이나 as.character를 이용한다.  


# create POSIXct variables
as.POSIXct("080406 10:11", format = "%y%m%d %H:%M")
## [1] "2008-04-06 10:11:00 CDT"

as.POSIXct("2008-04-06 10:11:01 PM", format = "%Y-%m-%d %I:%M:%S %p")
## [1] "2008-04-06 22:11:01 CDT"

as.POSIXct("08/04/06 22:11:00", format = "%m/%d/%y %H:%M:%S")
## [1] "2006-08-04 22:11:00 CDT"
# convert POSIXct variables to character strings

format(as.POSIXct("080406 10:11", format = "%y%m%d %H:%M"), "%m/%d/%Y %I:%M %p")
## [1] "04/06/2008 10:11 AM"

as.character(as.POSIXct("080406 10:11", format = "%y%m%d %H:%M"), format = "%m-%d-%y %H:%M")
## [1] "04-06-08 10:11"


만약 어떤 dataframe의 column이 POSIXct 타입이라면, 내부적으로는 정수를 저장하고 있기 때문에 Plot을 할 때는 숫자 형태로 변환하여 데이터를 순차적으로 나타내준다. 



그래프 그리기


data <- read.csv("C:\\workspace\\r\\data\\data.csv")
plot(data$dateFormat, data$value)



이렇게 기본 내장함수인 plot을 사용해도 x축을 시간으로 하여 괜찮은 모양으로 그려주는 것을 확인할 수 있다. 만약 x축 값의 포맷을 지정하거나, 적절한 간격을 주고 싶다면 ggplot2 패키지를 이용하는 것도 좋다.


GGPLOT2 라이브러리를 통한 그래프 그리기


library(scales)

ggplot(data = data, aes(x = date, y = value)) + 
    geom_line(size=2) + ylim(0,1000) + xlab("Time") + ylab("㎍/㎥") + 
    scale_x_datetime(breaks = date_breaks("1 hour"), minor_breaks=date_breaks("1 hour"), labels=date_format("%H:%M"), limits=xlim) +
    ggtitle("title") + theme_bw() + theme(text = element_text(size = 25))


ggplot 명령어 설명 


aes : (x축, y축에 사용될 변수를 지정한다.)

geom_line : line plot. size 키워드를 통해 선의 굵기 지정

ylim : y축의 범위를 지정함

xlab : x축 label

ylab : y축 label

scale_x_datetime : x축의 간격, 포맷을 지정함. (library(scales) 이후에 사용할 수 있다.)

ggtitle : title 지정

theme_bw() : 해당 테마 지정 (black & white style)

theme : 그래프의 전반적인 속성을 지정한다. 위에서는 텍스트 사이즈를 25 조정함




특정 날짜 범위에 있는 데이터만 골라내기


아래 코드는 date가 2018/01/16 인 row만 골라서 subset으로 저장한다. 이처럼 format을 통해 POSIXct 데이터 타입을 character 타입으로 변환할 수 있다.


subset <- data[(format(data$date, "%m/%d/%Y") == "01/16/2018")]



참고

http://biostat.mc.vanderbilt.edu/wiki/pub/Main/ColeBeck/datestimes.pdf

반응형
반응형


인공지능, 머신러닝은 더 이상 현실 세계와 동떨어진 이야기가 아니다. 헬스케어 분야를 리드하는 기업들은 인공지능, 머신러닝 기술들을 자신의 분야에 이미 적용시키고 있다. 이는 AI 기술들이 헬스케어 분야에 실용적으로 적용되고 있다는 것을 뜻한다. 회사들은 AI를 활용하여 자신들의 서비스를 개선하고, 수익을 증대하며 발생할 수 있는 리스크를 줄인다. 본 포스팅에서는 AI가 헬스케어 분야에 적용되어 불러올 수 있는 사회적 가치와 응용 사례를 살펴보려고 한다.


AI FOR GOOD


기술은 그 자체로도 중요하지만 사회적으로 그 기술을 활용하여 무언가의 이득을 얻을 때 그 가치가 가장 크다고 생각한다. 예를 들어, 기존에 해결할 수 없던 문제를 해결한다거나, 어려웠던 문제를 더 쉽게 만든다거나, 돈을 더 벌어준다더가 하는 것이다. AI FOR GOOD 이라는 말은 이러한 여러 사회적 가치 중 "공익"에 관한 것이다. 인공지능이 헬스케어분야에 적용하는 것의 가장 큰 가치는 바로 공익의 증진이다. AI의 헬스케어 적용은 기존의 헬스케어 분야에서 기존의 해결하기 어렵거나, 해결하는데 시간이 오래걸렸던 문제를 해결하고, 가속화하여 공익의 증가에 기여한다. 


AI-based Medicine을 통한 의학 분야의 돌파구


Accenture에 따르면, 현재 가장 큰 가치를 갖고 있는 기술들은 로봇 보조 수술, 가상 환자 돌봄 서비스(virtual nursing assistant), 행정 보조 기술 등이다. 이는 빅데이터, 인공지능 등의 키워드가 뜨기전부터 의학 분야에 적용되어온 기술들이다. 하지만, 의영상 분야도 큰 가치를 갖고 있다. 왜냐하면 취약 계층의 경우, 질병을 진단 받을 때, 의영상 진단 기술의 도움을 받기 힘들다. 전문가의 진단은 비싸며, 일정 수준 이상의 수요를 필요로하기 때문이다. 이러한 취약 계층에 AI 기반의 의영상 진단 기술이 적용될 경우, 공익에 큰 기여를 할 수 있다. 본 포스팅에서는 AI 기반 의료의 실제 사례를 몇 가지 살펴보려고 한다. 


AI 기반 의료의 실제 사례


- 개발 도상국 국가에서 X-RAY를 결핵 환자 발견



의영상 이미지에서 무언가의 패턴을 찾는 것은 가장 유망하며, 실제로 AI가 많이 적용되고 있는 분야이다.  많은 연구자들이 이러한 AI 기반의 의영상 진단 기술을 연구하고 있다. (원논문) 이러한 기술들이 개발 도상국 국가에서 활용된다면, 영상의학 전문의의 도움 없이도 결핵에 걸린 환자를 발견해 낼 수 있다. 또, 한 국가의 여러 지역에서 이런 기술을 적용한다면, 결핵 취약 지역을 발견해 낼 수 있다. 만약 결핵 예방, 치료 사업을 한다고 하면, 이러한 방식의 접근 법을 통해 정책의 우선순위를 결정할 수도 있다.



- 응급실에서의 환자 뇌출혈 발견


이스라엘의 회사인 MedyMatch와 IBM Watson은 응급실에서 환자의 뇌출혈을 확인하는데 인공지능을 활용하고 있다. 




- 피부 사진을 통한 암 진단


암진단에도 종종 AI가 응용된다. CT, MRI, X-ray 등이 암진단을 위한 의영상 기술로 적용되고 있지만, 이 기술들을 통해 암 진단을 하지 못할 경우, 치명적이다. 암환자가 아닌데 암환자로 진단하는 경우 (false positive, 1종 오류) 보다 암환자인데 암환자로 진단하지 못한 경우(false negative, 2종 오류), 환자의 생명에 영향을 주는 치명적인 판단 오류라고 볼 수 있다. 또한 false negative를 위해 false positive를 늘리는 소위 과잉진료로 인한 문제도 심각하다. 이는 환자에 생명에 영향을 주진 않지만, 잘못된 진단 결과로 인해 의료 비용을 높이고 환자의 심적 부담을 증가시킨다. 따라서 정확한 암 진단 기술이 중요하며, 이 진단 과정에 AI가 적용되어 진단의 속도와 정확성을 높이려는 시도가 이루어지고 있다. 


Stanford의 AI 팀은 피부 이미지를 통해 피부암을 진단하는 AI 기술을 내놓았다. 이 AI 기술은 21명의 피부과 의사들과 비교해 진단 능력이 떨어지지 않았다. 



- CT 사진을 통한 폐암 진단


Enlitic은 회사는 폐 CT 사진을 통해 폐암을 진단하는 AI 기술을 개발하였다. 딥러닝을 활용해 병변의 존재와 그 위치를 파악하는 것이다. 회사는 정확도가 영상의학전문의의 50% 이상이라고 주장한다. 




역사상 많은 기술들이 과대 선전되어 왔다. 누군가는 인공지능 기술이 과대 포장되고 실체는 별로 없는 기술이라고 생각할 수 있다. 또한 누군가는 인공지능이 실제로 산업에 적용되어 가치를 불러올 수 있을까하는 의문을 제기할 수 있다. 인공지능이 인간을 완전히 대체하는 것은 어려울지도 모른다. 오로지 데이터 기반 접근법이라는 문제로 인해, 적절한 수의 훈련 데이터 없이는 동작할 수 없으며, 과적합의 가능성이 있다. 또한 AI의 경우 기기별 차이를 감안하여 모든 기계에 대해 robust한 모델을 만드는 것이 아직까지는 완벽하지 않은 경우가 많다. 하지만, 확실한 것은 특정한 제한된 범위의 태스크에서는 AI가 인간보다 나을 수 있다는 것이다.  현재 의료 산업 분야에 활발히 적용되고 있는 인공지능 기술과, 인공지능 스타트업에 투자되고 있는 금액의 규모가 인공지능의 의료분야에서의 가능성을 보여준다.


참고

https://sigmoidal.io/artificial-intelligence-and-machine-learning-for-healthcare/

반응형
반응형


Python “SSL: CERTIFICATE_VERIFY_FAILED” Error 해결법


Keras에서 ResNet의 weight를 다운 받다가 이러한 에러가 났다. 환경은 리눅스, 파이썬 3 버전이다.


base_model = ResNet50(weights='imagenet', pooling=max, include_top = False) 


이 코드를 실행시키다가 에러가 났는데 h5 파일을 다운 받아야하는데, SSL certificate 문제가 있다면서 다운을 받지 못하는 문제이다. 

http://blog.pengyifan.com/how-to-fix-python-ssl-certificate_verify_failed/


위 링크를 보고 해결하였는데, 


첫번째 해결법은 PYTHONHTTPSVERIFY 환경변수를 0으로 설정하는 방법이다.


export PYTHONHTTPSVERIFY=0
python your_script


두 번재 해결법은 대안적인 방법으로 문제가 있는 코드 앞에 아래 코드를 넣는 방법이다. 


import os, ssl
if (not os.environ.get('PYTHONHTTPSVERIFY', '') and
    getattr(ssl, '_create_unverified_context', None)):
    ssl._create_default_https_context = ssl._create_unverified_context


반응형
반응형

R - 특정 버전의 패키지 설치하기


우선 패키지의 버전을 알아보는 방법은 R을 실행 시킨 후, 


library(package_name)

sessionInfo()


를 입력하면 패키지의 버전을 알 수 있다.


특정 버전의 R 패키지를 설치하는 방법은 우선, Install.packages("devtools")로 devtool을 설치한다.


require(devtools)
install_version("ggplot2", version = "0.9.1", repos = "http://cran.us.r-project.org")


위와 같은 방식으로 특정 버전의 CRAN 패키지를 설치할 수 있다. 이미 패키지가 설치된 상태에서도 install_version 을 활용하면 버전이 바뀌어 다시 설치되기 때문에, 패키지를 다운그레이드 시킬 때도 유용하게 쓸 수 있다.

반응형
반응형



Python - Pandas isin 구문


Python에서 테이블 형식의 데이터를 읽고 처리할 때 가장 많이 쓰이는 pandas 라이브러리에서는 다양한 데이터 처리 기능을 구현하고 있다. 이 중에 isin 구문은 열이 list의 값들을 포함하고 있는 모든 행들을 골라낼 때 주로 쓰인다. 


예를 들어, 아래 예제를 보면


df = DataFrame({'A': [1, 2, 3], 'B': ['a', 'b', 'f']})
df.isin([1, 3, 12, 'a'])


이와 같이 이진값을 반환한다. 

       A      B
0   True   True
1  False  False
2   True  False

이를 그대로 쓰는 경우보다 Dataframe의 컬럼에서 어떤 list의 값을 포함하고 있는것만 걸러낼 때 isin 구문이 유용하다.


이러한 데이터프레임이 있을 때

df = pd.DataFrame({'A': [1, 2, 3], 'B': ['a', 'b', 'f']})

AB
01a
12b
23f


A 컬럼의 값이 [1,3,12]를 포함하는 것만 골라낸다.

df[df['A'].isin([1, 3, 12])]
AB
01a
23f


반응형