분류 전체보기 (321)

반응형


Decorator는 무엇인가? 


- 다른 function의 기능을 조작하여 새로운 function을 만드는 것.

- 이 방법은 코드를 더욱 간결하게 만들며, 더욱 Pythonic 한 코드를 만들 수 있다

- 이러한 형태의 일종의 코드 Refactoring 및 중복 줄이기는 소프트웨어 공학에서 매우 중요하다!


Decoration을 안 한 초보 파이썬 코더의 코드


# 기존의 코드를 사용 안 하고, b_function()을 새롭게 정의함.
# 이렇게 하면 문제가, my foul smell을 삭제하고 싶으면, 함수 2개에서 모두 삭제해야한다. 
# 코드의 중복이 생김.
 
def a_function_requiring_decoration(): 
    print("I am the function which needs some decoration to remove my foul smell") 
 
def b_function(): 
    print("I am doing some boring work before executing a_func()") 
    print("I am the function which needs some decoration to remove my foul smell")   
    print("I am doing some boring work after executing a_func()")
 
b_function()

- 이 방법의 문제점은 코드의 중복이 생겨 수정이 필요할 시에 두 함수 모두를 수정해야한다는 것이다. 


간단한 Decoration의 구현 


# 아래 함수를 기능을 추가해서 decoration 해주는 함수 def a_new_decorator(a_func):


# 함수 안에 함수를 정의하고 함수를 리턴한다 def wrapTheFunction(): print("I am doing some boring work before executing a_func()") a_func() print("I am doing some boring work after executing a_func()")   return wrapTheFunction   # 이 함수를 decoration (기능을 추가) 하고 싶음 def a_function_requiring_decoration(): print("I am the function which needs some decoration to remove my foul smell")

a_function_requiring_decoration = a_new_decorator(a_function_requiring_decoration) a_function_requiring_decoration()

결과


I am doing some boring work before executing a_func()

I am the function which needs some decoration to remove my foul smell

I am doing some boring work after executing a_func()


- 이를 해결하는 방법이 바로 decoration 이다. 

- a_new_decorator 함수에 a_function_requiring_decoration 함수를 넘기는 방법을 통해 내용이 한 번만 쓰이게 된다. 

- 이를 통해 코드의 중복을 줄일 수 있다.



@ 키워드를 통한 decoration


# @를 붙임으로써 a_function_requiring_decoration = a_new_decorator(a_function_requiring_decoration) 이걸 안 해도 된다. @a_new_decorator def a_function_requiring_decoration(): """Hey you! Decorate me!""" print("I am the function which needs some decoration to " "remove my foul smell")   a_function_requiring_decoration()   # 근데 함수명이 이상하게 나옴. wrapTheFunction print(a_function_requiring_decoration.__name__)

- @ 키워드를 통해 a_function_requiring_decoration를 재정의 하지 않아도 된다.

- @ [함수명] 을 decoration 하고 싶은 함수 위에 붙여주면 된다. 

- 근데 함수 명이 wrapTheFunction 으로 decoration 한 함수의 이름이 그대로 나오게 된다. 

- 이를 해결하기 위해 wraps 를 이용한다.


# wraps를 이용해 함수명이 제대로 나오게 할 수 있음
from functools import wraps
# 최종적인 decorator의 일반적인 형태
# a_function_requiring_decoration을 a_new_decorator로 decorating 한다는 것이다. 이 때 decorate 할 함수는 a_func에 지정하고 이를 wraps로 받아서 그 아래 함수로 decoration 함
 
def a_new_decorator(a_func):
    @wraps(a_func)
    def wrapTheFunction(): 
        print("I am doing some boring work before executing a_func()") 
        a_func() 
        print("I am doing some boring work after executing a_func()")
 
    return wrapTheFunction
 
@a_new_decorator 
def a_function_requiring_decoration(): 
    """Hey you! Decorate me!"""
    print("I am the function which needs some decoration to " "remove my foul smell")
 
a_function_requiring_decoration() 
 
print(a_function_requiring_decoration.__name__)  # a_function_requiring_decoration


- 이렇게 decorator에 wraps를 붙여주면, 그 함수를 decoration 해주는 함수로 인식을 하게 된다. 

- 함수명도 기존의 함수 명인 a_function_requiring_decoration 을 따르게 된다.


Decoration 활용의 좋은 예 - Authentication


authentication_check라는 함수를 만들고 이곳에서는 웹어플리케이션서의 사용자 인증을 체크한다고 하자. 만약 다른 함수를 실행할 때, 그 함수의 위에다가 위에다가 @authentication_check 만 붙이면, authentication을 알아서 해주게 된다. 즉, Authentication - function 실행 순으로 알아서 만들어 준다.  이것이 좋은 점은 각 함수마다 authentication check를 안해도되고, authentication check logic을 딱 한 번만 쓰면 된다. 이런건 Java에서는 보통 상속을 이용해서 하는데, python에서는 decorator로 할 수 있다.


""" Use case : Authorization Now let’s take a look at the areas where decorators really shine and their usage makes something really easy to manage. Decorators can help to check whether someone is authorized to use an endpoint in a web application. They are extensively used in Flask web framework and Django. Here is an example to employ decorator based authentication:   """   # decorator 함수 def requires_auth(f): @wraps(f) def decorated(*args, **kwargs): auth = request.authorization if not auth or not check_auth(auth.username, auth.password): authenticate() return f(*args, **kwargs) return decorated

- 위 require_auth 함수는 어떤 함수 f를 받아서 그 전에 authorization 과정을 수행해주는 decorator이다. 



참고 - Intermediate Python

반응형
반응형

머신러닝, 딥러닝, 인공지능


머신러닝, 딥러닝, 인공지능 이 용어들의 차이는 무엇일까? 인공지능 하면 인간에게 도움을 주는 아이폰의 시리와 같은 인공지능 비서를 떠올릴 수도 있고, 또는 영화 아이로봇의 로봇처럼 인간을 위협하는 존재가 떠오를 수도 있다. 딥러닝하면 얼마전 이세돌을 바둑으로 격파한 알파고의 학습 방법으로 많은 사람들이 기억한다. 하지만 이러한 개념들이 서로 간에 어떠한 관계를 갖고 있는지에 대해 모호하게 느껴질 수도 있다. 본 포스팅에서는 인공지능이 머신러닝과 다른점, 그리고 머신러닝과 딥러닝의 차이점에 대해서 구체적으로 살펴보아 이들의 차이점이 궁금한 분들에게 도움이 될 수 있는 포스팅을 해보고자 한다. 


인공지능에 대한 인류의 오랜 꿈


피그말리온과 갈라테아 (출처)


사실, 인공지능이라는 개념은 최근에 와서 생긴 개념이 아니다. 역사적으로 생각하는 물체를 만든다는 것은 인류의 오랜 꿈이였다. 그리스 로마신화에 나오는 피그말리온과 갈라테아 그 한 예이다. 이 이야기는 독신으로 살던 한 조각가가 상아로 조각상을 만들고 아프로디테에게 간절히 빌어, 아프로디테가 이 남자를 딱하게 여겨 조각상에 생명을 불어넣고 조각상이 여인으로 변했다는 이야기이다. 넓은 의미의 인공지능은 기계를 인간처럼 보이게 만드는 모든 기술을 총칭한다. 갈라테아는 본래 조각상이었지만 인간처럼 생각하고 행동할 수 있게 되었다. 이러한 이야기를 통해 우리는 옛 사람들에게도 기계에 생명을 불어넣어 인간처럼 만드는 '환상' 이 있었음을 짐작할 수 있다.


하지만 오늘날, 이러한 신화처럼 인공지능이 어느날 갑자기 생기지는 않을 것이다. 우리는 인공지능을 구현하기 위해서 컴퓨터 프로그램을 활용한다. 프로그램은 인공 지능을 구현하는 방법이다. 즉, 현대에서 말하는 인공지능이란 컴퓨터 프로그램을 통해 인간처럼 이해하고, 추론하고, 사고하게 할 수 있는 방법이다. 다른 말로 인공지능이란 인간의 "인지기능" 을 모방하는 시스템을 말한다. 인지 기능이란 무언가를 배우고 이를 통해 문제를 해결할 수 있는 인간의 능력이다. 


"artificial intelligence" is applied when a machine mimics "cognitive" functions that humans associate with other human minds, such as "learning" and "problem solving".


출처 - Deep learning, Youshua Bengio et al. (2016)

인공지능은 머신러닝, 딥러닝을 포함하고 있는 상위 개념이다. 


인공지능을 구현하는 두 가지 방법


IBM - Deep blue (1996)


컴퓨터 프로그램을 통해 인공지능을 구현하는 방법에는 두 가지가 있다. 하나는 규칙기반 시스템(Rule-based system) 이다. (이는 expert system, Knowledge base system 등으로 불리기도 한다.) 이 방법은 기계가 인간처럼 사고하도록 하기 위해서 Rule을 이용한다. 얼마 전, 바둑은 인간의 영역이라고 여겨졌던 바둑에서 최정상 선수인 이세돌과 커제를 각각 4:1, 3:0으로 꺾었다. 하지만 그로부터 약 20년 여년전 체스가 먼저 컴퓨터에게 정복 당했는데,  IBM에서 만든 Deep blue라고 하는 체스용 컴퓨터가 체스 챔피언을 접전 끝에 4:2로 이긴 것이다. Deep blue는 1초에 20억개 이상의 경우의 수를 계산하여 최고의 수를 두는 당시대의 최고의 기술이었다. 이러한 경우의 수를 구하는 것은 프로그래밍을 통해 체스의 규칙을 컴퓨터에 입력해주고, 이 규칙하에서 Deep blue가 가능한 경우의 수를 조회하는 것이다. 즉, 체스 게임의 Rule을 이용한 것이다. 


인공지능을 구현하는 두 번째 방법은 바로 머신러닝(Machine Learning)이다. 이 방법인 인간이 컴퓨터에게 규칙을 입력해주는 것이 아니라, 기계 스스로 배우도록 한다. 이게 무슨말이냐 하면, 데이터를 주고 이 데이터에서의 정답을 알려주면 기계가 새로운 데이터가 들어왔을 때 정답을 예측한다는 것이다. 고양이 사진 100개를 보여주고 새로운 고양이 사진을 보여주면 기계가 이 사진을 고양이라고 맞춘다는 원리이다. 이 방법의 놀라운 점은 사람이 학습하는 방법과 같다는 것이다. 태어난지 얼마 안 된 아이는 고양이가 무엇인지 모른다. 하지만 사람들이 그것을 고양이라고 부르기 때문에 새로운 고양이를 보았을 때 지금까지의 경험을 토대로 그것을 "고양이" 라고 말할 수 있게 된다. Knowledge from experience 즉, 경험으로부터의 지식이 머신러닝의 핵심이라고 할 수 있다. 


A computer program is said to learn from experience E with respect to some class of tasks T and performance measure P if its performance at tasks in T, as measured by P, improves with experience E. Mitchell, T. (1997)



현대의 인공지능 예를 들어, 자율 주행차, 컬링 로봇, 의료 진단 시스템 등은 대부분 머신러닝을 활용한다. 하지만 규칙기반 시스템이 아예 쓰이지 않는 것은 아니다. 규칙기반 시스템은 풀고자 하는 문제에 따라서 유용하기도 하다. 특히, 세계관이 좁은 문제의 경우. 예를들어 체스의 경우 경우의 수가 바둑에 비해 적기 때문에 인간이 모든 규칙을 일일히 입력하는 것이 어렵지 않다. 또 게임 캐릭터의 인공지능도 규칙기반 시스템을 사용한다. 하지만 인공지능에 대한 연구는 대부분 머신러닝을 어떻게 하면 더 잘할 수 있을지에 대한 것이다. 


딥러닝


Deep learning (also known as deep structured learning or hierarchical learning) is part of a broader family of machine learning methods based on learning data representations, as opposed to task-specific algorithms. Learning can be supervised, semi-supervised or unsupervised.


딥러닝은 생물의 뇌 회로에서 영감을 받은 머신러닝 모델이다. 인간처럼  인간은 어떻게 생각하고, 사고하고, 기억을 저장할까? 



인간의 뇌는 1000억개의 뉴런100조개의 시냅스로 이루어져 있다. 시냅스에서 뉴런에 전기적 신호를 보내면 뉴런은 이 전기적 신호에 반응하여 이 신호를 다음 뉴런으로 전달한다. 이러한 뉴런-시냅스라는 작은 단위가 이루어진 뇌를 통해 인류는 이해하고 사고하고 고차원적인 사고를 할 수 있는 것이다. 딥 러닝은 이러한 뇌의 신호 전달 과정에서 영감을 얻어 고안되었다. 


딥러닝에서 뉴런을 모방한 것은 퍼셉트론(Perceptron)이라고 하며, 이는 1958년 Rosenblatt에 의해 처음 제안되었다. 퍼셉트론은 x1~xn의 인풋을 받아들이고 이 인풋들의 곱의합(weighted sum)을 계산하고, 활성화 함수(activation function)에 대입하여 최종 y를 예측한다. 하지만 이러한 기본적인 퍼셉트론 만으로는 복잡한 문제를 해결하기 어렵다. 


Multi-layer perceptron (MLP) Hidden layer라는 layer를 도입해 인풋을 한 차원 높은 단계의 특징, 즉 representation으로 나타낸다. 퍼셉트론의 y를 그 다음 layer의 input으로 넣어준다는 것이다. 이것이 딥러닝을 Representation learning의 한 종류라고 말하는 이유이다. 



1986년 hidden layer를 포함한 신경망 모델을 효율적으로 트레이닝 할 수 있는 방법, Backpropagation이 등장한다.


우리가 길거리의 고양이를 보고 왜 고양이라고 생각을 할까? 우리는 분자 단위로 고양이를 읽어들여 뇌에서 직접적으로 이 정보를 이용하여 고양이라고 판단하지 않는다. 우리는 눈에 보이는 고양이의 형체를 전체적으로 보고, 이곳에서 고양이로 판단할만한 유용한 정보를 추출(extract)한다. 이 정보는 예를 들면, 뾰족한 귀, 갈색 털, 날카로운 눈빛, 네 개의 발과 같은 것이다. 분자 단위의 고양이의 형체에서 이러한 정보를 인간은 자동적으로 추출하는 능력이 있는 것이다. 이 때, 뾰족한귀, 갈색 털과 같은 고양이의 특징을 representation 이라고 한다. 딥러닝 모델에 Hidden layer를 추가한다는 것은 이러한 representation을 추출해내는 한 개의 층을 더 추가한다는 것이다. 층을 깊게 쌓을 수록 기본적인 특징을 조합하여 한 단계 위의 고차원 적인 특징을 추출해낼 수 있는 능력을 갖게 된다. 


머신러닝과 딥러닝의 차이점은 바로 이부분이다.  고전적인 머신러닝 알고리즘을은 인풋 특징들 (예를 들면, 고양이의 분자단위)를 바로 매핑시켜 이를 통해 고양이인지 여부를 판단하고자 한다. 딥러닝이란 Deep 이라는 말에서 알 수 있듯, 매우 추상적인 분자단위의 고양이에서 유용한 정보를 추출하여 이를 통해 고양이를 판단할 수 있는 고차원 적인 Feature로 변환하는 Representation learning 과정이 그 알고리즘 자체에 내재되어 있다. 


딥러닝은 이러한 Deep 한 구조를 통해 인간이 쉽게 할 수 있는 것이지만 형식화하여 설명하기는 힘든 영역, 직관적이며 고차원적인 인간 고유의 영역에 도전하고 있다. 


The true challenge to artificial intelligence proved to be solving the tasks that are easy for people to perform but hard for people to describe formally—problems that we solve intuitively, that feel automatic, like recognizing spoken words or faces in images. (Deep learning, Yoshua bengio et al, 2016)

AI의 종류의 그 차이점 (Deep learning, Yoshua bengio et al, 2016)


딥러닝은 오로지 데이터로만 배우고, 데이터의 규칙을 찾아내는 수많은 파라미터들을 통해 구현되기 때문에 수많은 데이터가 필요하다. 예를 들어, 고양이를 찾아내는 딥러닝 시스템을 만들어본다고하자. 기계가 고양이 사진을 보고 고양이임을 알아내기 위해서는 많은 고양이 사진이 필요하다. 고양이와 비슷하게 생긴 여우, 삵 등을 고양이와 구분하는 것은 그 작은 디테일의 차이를 기계가 구분하는 것은 쉽지 않을 것이다. 따라서 수많은 데이터셋이 뒷받침 되지 않으면 아무리 좋은 딥러닝 모델을 구현하더라도 무용지물이다. 


한 편, 딥러닝이 뇌과학에서 영감을 얻은 것은 사실이지만, 반드시 뇌과학적 지식을 그대로 적용하지는 않는다. 딥러닝은 다소 공학적인 면이 있다. 실제로 biological relevance가 없더라도, 그것이 성능 향상에 도움이 된다면, 유용하게 쓰인다. 


결론


1. 인공지능 > 머신러닝 > 딥러닝

2. 인공지능을 구현하는 방법은 크게 규칙기반 시스템과 머신러닝으로 나눌 수 있다. 즉, 머신러닝은 인공지능을 구현하는 한 방법이다. 

3. 머신 러닝은 사람이 일일히 규칙을 정의하지 않아도 데이터를 통해 배우는 것이 핵심이다. 즉, Knowledge from experience로 인공지능을 구현한다. 

4. 딥 러닝은 생물체의 뇌 구조에서 영감을 얻은 머신러닝 기법 중 하나로 핵심 원리는 다계층 구조를 이용한 Representation Learning을 통해 스스로 데이터속에서 유용한 feature를 찾아내는 것이다. 딥 러닝은 기존 머신러닝과는 다르게 인간 고유의 영역, 이미지 분석, 언어 인식과 같은 직관적이고 고차원적인 사고를 요하는 분야에 강점이 있다.


참고

https://www.techrepublic.com/article/understanding-the-differences-between-ai-machine-learning-and-deep-learning/

Deep learning, Yoshua bengio et al, 2016


반응형
반응형


Python 중고급 - map, filter, reduce 


파이썬의 기초를 익힌 후, 파이썬의 중고급 문법을 선택적으로 배운다면 기본 문법으로도 구현할 수 있는 로직들을 더욱 쉽고, 간편하게 구현해볼 수 있습니다. 이번 포스팅에서는 list를 다루는 함수인 map, filter, reduce에 대해 간단하게 정리해보겠습니다. 물론 map, filter, reduce를 안 쓰고 코딩하는 것도 가능하며, 그것이 편하시면 그렇게 하셔도 좋습니다. 하지만 이를 사용하는 프로그래머나 데이터 분석가들이 꽤 있기 때문에 이러한 문법들을 알아두면 기존의 코드를 이해하는데 큰 도움이 될 수 있을 것입니다. 


Map


map의 경우, list의 element에 함수를 적용시켜 결과를 반환하고 싶을 때 사용합니다. 만약, 어떤 리스트의 원소를 제곱한 새로운 리스트를 만들고 싶다면, 일반적인 C언어 스타일의 해결법은 아래와 같습니다. 


# Map function
# 문제와 일반적인 해결법
items = [1, 2, 3, 4, 5]
squared = []
for i in items:
    squared.append(i**2)

하지만 map function을 통해 짧게 구현할 수 있습니다. map함수의 구조는 map(function_to_apply, list_of_inputs) 입니다.


items = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, items))

위 코드는 items 리스트의 element 각각에 대해 제곱을 해서 새로운 리스트를 만들어 반환합니다. filter와 reduce도 이와 같은 구조를 갖습니다. 


이 때, map 앞에 list 함수를 통해 list 자료형으로 바꾸는 이유는 map 이 반환하는 것이 실제로는 list 자료형이 아니기 때문입니다. map 함수는 Iterator 를 반환하는데, 이를 list로 변환해서 list 자료형으로 만드는 것입니다. Iterator는 next() 함수를 갖는 파이썬 객체로 꼭 메모리에 올릴 데이터만 올려서 메모리를 효율적으로 이용할 수 있는 파이썬의 대표적인 객체입니다. 바로 list로 반환하는 것이 아니라 Iterator로 보다 상위의 객체를 리턴하는 것은, 다른 map 함수의 리턴값을 리스트가 아닌 다른 자료구조로 변환시킬 수도 있도록 하기 위해서입니다. 예를 들어, set 자료구조로도 변환시킬 수 있습니다. 


map_it = map(lambda x: x**2, items)
next(map_it)

map 함수의 결과는 Iterator 이므로, next 함수를 위와 같이 실행할 수 있습니다. 위 코드의 결과는 1입니다.


Iterator 에 대해서는 다음에 다루어 보도록 하겠습니다. 



Filter


Filter의 경우, list의 element에서 어떤 함수의 조건에 일치하는 값만 반환하고 싶을 때 사용합니다. 


As the name suggests, filter creates a list of elements for which a function returns true.


만약 어떤 리스트에서 '음수만 골라내고 싶다' 라고 할 때, filter 함수를 사용한 코딩 방법은 아래와 같습니다. 


number_list = range(-5, 5)
less_than_zero = list(filter(lambda x: x < 0, number_list))
print(less_than_zero)

이 때, less_than_zero 는 -5, -4, -3, -2, -1 을 갖습니다. 


만약 Map과 Filter를 보고 저거 list comprehension 으로 할 수 있는 거 아니야? 라고 생각하실 수 있습니다. 맞습니다. Map과 Filter가 자신과 맞지 않다고 생각하는 경우 list comprehension 만으로도 위 코드들을 훨씬 더 간결하게 구현할 수 있습니다.


# Map을 list comprehension으로 구현 items = [1, 2, 3, 4, 5] squared = list(map(lambda x: x**2, items)) print(squared)   squared = [x**2 for x in items] print(squared)   # Filter를 list comprehension으로 구현 number_list = range(-5, 5) less_than_zero = list(filter(lambda x: x < 0, number_list)) print(less_than_zero)   less_than_zero = [x for x in number_list if x <0] print(less_than_zero)  

위 코드처럼 list comprehension 만을 통해 map, filter가 하는 것을 할 수 있습니다. 


Filter가 마음에 들지 않는 경우, list comprehension을 쓸 수도 있습니다 하지만, map, filter가 있다는 것을 알아 두면 좋습니다.


Reduce


reduce는 어떤 list에 대해서 computation을 해서 결과를 내보낼 때, 즉 결과를 어떤 함수로 computation해서 결과를 축약하기 위해서 사용됩니다. 이 때, reduce함수에 input으로 들어가는 함수는 두 element를 연산하는 로직을 넣어야 합니다. 이것은 list comprehension으로 하지 못하는 것입니다. 


아래 코드는 reduce함수를 이용하는 것을 포함하여 파이썬으로 1-100 까지의 합을 구하는 총 3가지 방법입니다. 


# 1-100 까지의 합을 구하라   # C 언어 스타일의 해법 sum_value = 0 for i in range(1, 101) : sum_value += i print(sum_value)   # python 스러운 해법 sum_value = reduce((lambda x,y : x+y), [x for x in range(1,101)]) print(sum_value)   # 하지만 Data scientist가 가장 먼저 생각해는 해법 import numpy as np print(np.sum([x for x in range(1,101)])


참고 


Intermediate python (http://book.pythontips.com/en/latest/)

반응형
반응형

case/control 디자인에서 샘플 수를 계산하는 방법 


샘플 수를 계산한다는 것의 의미  


실제로 노출 여부가 case/control 여부에 영향을 줄 때, (association이 있을 때) 해당 샘플 수에서 이를 충분히 detection 할 수 있는가?


이는 다음과 같은 귀무가설/대립가설 하에서 가설 검정할 수 있습니다. 



p0 = Control에서 expose된 사람의 비율
p1 = Case에서 expose된 사람의 비율


즉, Control에서 expose된 사람이랑 case에서 expose된 사람의 비율이 같은지를 검정하는 것이죠.

이를 검정하기 위해서는 p0, p1, OR을 알아야 합니다. 근데 p0, p1, OR 중에 2개를 알면 1개를 아래와 같은 식으로 구할 수 있습니다. 




따라서 일반적인 샘플 수 구하는 공식처럼, 유의수준, 검정력, p0, p1 을 주고 샘플 수를 구할 수가 있습니다. 한가지 더 주어야할 것은 case/control 디자인에서는 보통 case/control의 비를 1 이상으로 맞추기 때문에 r이라고 하는 case/control ratio를 주어야합니다.  


이 때, Kelsey의 공식에 따르면 필요한 case의 숫자는 아래와 같이 계산됩니다. 


Kelsey의 방법 



이 때, x = (p1+rp0) / (r+1) 라고 놓고, p=x(1-x) 로 계산됨 



참고문헌

Kelsey J.L., Whittemore A.S., Evans A.S.,and Thompson W.D. Methods in Observational Epidemiology. Oxford University Press, 1996. Print.

http://www.openepi.com/PDFDocs/SSCCDoc.pdf

반응형
반응형

 

여드름을 유발하는 7개의 식품군

 

여드름은 전세계에서 10% 이상이 갖고 있는 아주 흔한 피부 질환입니다. 많은 사람들이 어떤 식품을 먹고 여드름을 발생된 경험을 많이 하신 만큼, 여드름과 식품의 연관성은 학계에서도 논란이 되어왔는데요. 최근, 지금까지의 식습관-여드름의 관련성을 분석한 여러 논문들을 메타분석한 연구결과에 따르면 (1) 일부 식품군의 경우 여드름에 영향을 준다고 보는 것이 상당히 설득력이 있었다고 합니다. 본 포스팅에서는 연구 결과에 기반하여 여드름과 관련이 있다고 알려진 7개의 식품군에 대해서 다루어 보겠습니다.

 

 

1. 정제된 곡식 그리고 설탕

 

 

정제된 탄수화물을 많이 먹는 사람은 그렇지 않은 사람에 비해 여드름을 더 많이 갖고 있었습니다. (2) 

정제된 탄수화물(refined carbohydrates)이란 아래와 같이 탄수화물(밀, 쌀, 설탕 등)을 정제한 식품을 말합니다.

 

1. 빵, 크래커, 시리얼, 밀가루로 만든 디저트

2. 파스타

3. 흰쌀, 국수

4. 탄산음료 등의 설탕이 첨가된 음료

5. 메이플 시럽, 꿀 

 

한 연구에서 설탕 첨가물을 자주 섭취하는 사람은 그렇지 않은 사람에 비해 여드름에 대한 상대 위험도가 30% 높았고, 페이스트리, 케이크를 섭취하는 사람은 위험도가 20% 높았습니다. 이러한 식품들은 당을 많이 포함하고 있기 때문에 섭취시 매우 빠른 속도로 혈당(blood sugar)을 높이며, 이것이 체내 인슐린 농도를 높여 여드름에 발생에 기여하기 때문입니다. 인슐린은 남성호르몬인 안드로겐을 활성화시키며 insulin-like growth factor 1 (IGF-1)를 증가시킵니다. 이러한 것들이 피부 세포를 빠르게 성장하게 만들며, 피지 분비를 많게 만들어 여드름을 유발하게 됩니다. 

 

 

2. 유제품

 

 

여러 연구에서 청소년기의 우유 섭취가 여드름에 영향을 준다는 연구 결과가 발표되었습니다. (3)(4) 이러한 연관성은 성인에게서도 마찬가지로 발견이 되었는데요, 우유와 아이스크림을 꾸준히 섭취하는 사람은 여드름이 발생할 위험도가 4배에 달했습니다. (5) 하지만 이러한 연관성이 인과성이 아닐 수도 있는데, 유제품이 왜 여드름에 형성에 영향을 주는지 명확하게 밝혀져 있지 않기 때문입니다. 

 

몇 가지 가설을 소개하면 다음과 같습니다. 

 

1. 우유는 혈당으로 인해 인슐린이 올라가는것과는 독립적인 경로로 체내 인슐린 수치를 증가시킨다고 알려져 있습니다. 따라서 위 1번에서의 메커니즘과 동일하게 피지 분비가 많아지며 여드름이 발생한다는 것입니다.

2. 우유는 간을 자극하는 아미노산을 함유하고 있는데 이 아미노산이 간을 자극하게 되면 IGF-1 의 생성이 많아지게 되고 이는 여드름의 발생에 기여한다는 것입니다. 

 

하지만 유제품에 관해서는 정확히 어떤 유제품을 어느정도로 먹었을 때 여드름이 유발되는지 아직 명확하게 밝혀지지 않아 더 많은 연구 결과가 필요합니다. 

 

 

3. 패스트 푸드

 

 

 

다음은 패스트푸드입니다. 소위 말하는 "서양식 식습관", 고칼로리 고탄수화물 고지방식의 대표적인 식품이 바로 패스트푸드인데요. 이러한 햄버거, 너겟, 감자튀김, 핫도그, 탄산, 밀크쉐이크 등의 서구식 식습관은 여드름과 매우 강한 연관성을 갖습니다 (6). 한국과 인종적으로 비슷한 중국 청소년 5,000 명을 대상으로한 여드름 연구에 따르면, 고지방식 및 패스트푸드의 정기적인 섭취는 여드름의 발생을 각각 43%, 17% 증가시켰습니다. 또한 터키인을 대상으로한 연구에 따르면 햄버거와 소시지를 빈번하게 먹는 사람은 여드름의 위험도가 24% 높았습니다. 

 

하지만 아직까지 패스트푸드가 왜 여드름을 유발시키는지에 대해서는 위에서 언급한 인슐린의 증가로 인한 효과 이외에는 명확하게 밝혀진 바가 없는데요. 한가지 가설로는 서양식 식습관이 "유전자 발현량 (gene expression level)" 을 변화시키고, 이로 인해 체내 호르몬 수치에 이상이 생겨 여드름을 유발한다는 것입니다 (7)

 

 

 

Potential role of FoxO1 and mTORC1 in the pathogenesis of Western diet-induced acne (Exp Dermatol. 2013)

 

하지만 이러한 연구 결과는 실험자에게 음식을 먹은 후에 여드름이 발생하는 것을 직접 관찰하는 방식의 "실험연구" 가 아니라 설문지를 기반으로한 연구이기 때문에 서양식 식습관을 주로 하는 사람들이 여드름의 발생이 많다 라는 결론을 내릴 수는 있지만, 서양식 식습관이 여드름의 발생에 원인이 된다고 단정짓기는 어렵습니다. 따라서 정확한 원인을 파악하기 위해서는 더욱 연구가 필요합니다. 

 

 

4. 오메가-6 지방산이 많은 식품

 

 

 

오메가 지방산? 그거 몸에 좋은거 아니야? 라고 생각하시는 분도 있으시겠습니다. 하지만 몸에 좋다고 알려져 있는 것은 호두, 등푸른 생선 등에 많이 함유되어있는 오메가-3 지방산이며 이와 다르게 서구식 식습관에 많이 포함되어 있는 오메가-6 지방산의 섭취는 여드름의 발생과 관련성이 있다는 연구 결과가 많이 보고되었습니다. 

 

서구식 식사는 옥수수와 대두유(soybean oil)같이 오메가-6 지방산이 많이 들어있는 식품은 다양한 반면 오메가-3 지방산을 포함한 식품은 적다는 특징이 있습니다. 이러한 오메가-3와 오메가-6 지방산의 불균형은 몸을 염증에 취약한 상태로 만들며, 이로 인해 피부에 여드름 발생이 더욱 쉽게 일어나게 됩니다. 

 

오메가-6 지방산을 포함한 식품

 

1. 가금류 (닭, 오리 등)

2. 계란

3. 호두, 땅콩

4. 참기름

5. 시리얼

 

하지만 오메가-6 지방산의 과다로 인한 오메가-3 지방산과의 불균형은 부족한 오메가-3를 보충해줌으로써 해결할 수 있는데요, 오메가-3 지방산 영양제를 섭취하는 것은 여드름 정도를 조금은 감소시키는데 기여하였습니다 (8). 이처럼 오메가-6 지방산의 과다가 여드름을 유발한다는 것은 아직 실험연구가 없긴 하지만 어느정도 명확해보입니다.

 

 

5. 초콜렛

 

 

다음으로는 달콤한 맛이 매혹적인 초콜렛입니다. 대부분의 초콜릿들이 과다한 설탕이 포함되어 있는 경우가 많기 때문에 초콜릿이 여드름 발생에 기여한다는 것은 예상이 되는데요. 하지만 다크초콜렛은 어떤지에 대해서가 논쟁거리였습니다. 

 

최근 여드름이 있는 사람에 대해 다크초콜렛의 연관성을 연구한 연구결과에 따르면 99% 다크초콜렛을 매일 25g씩 섭취한 사람은 2주 후 여드름 발생 지역이 증가하였다는 결과가 보고되었습니다 (9). 다른 연구에서는 연구 참여자를 두 그룹으로 나누어 한쪽에는 100%의 코코아 파우더를 다른 한쪽에는 가짜약인 플라시보를 주어 1주 후에 여드름 발생을 평가하였는데요. 1주 후에 코코아를 준 그룹에서 여드름이 더 많이 관찰되었다고 합니다 (10)

 

 

Double-blind, Placebo-controlled Study Assessing the Effect of Chocolate Consumption in Subjects with a History of Acne Vulgaris. (J Clin Aesthet Dermatol. 2014)

 

하지만 초콜렛의 경우도 마찬가지로 어떤 기전으로 인해 여드름 발생에 영향을 주는지는 정확하게 알려져 있지 않은데요. 한 가지 가능성은 초콜릿을 먹는것이 여드름을 발생시키는 박테리아에 대한 면역 체계의 반응을 촉진시키고, 이것이 여드름의 발생에 기여한다는 것입니다 (11)

 

 

6. 단백질 파우더

 

 

 

단백질 파우더에는 류신, 글루타민 같은 아미노산이 많이 포함되어있는데 이러한 아미노산은 피부세포를 분열을 빠르게 만듭니다. 그리고 정상보다 빠르게 피부세포가 분화하는 것은 여드름 발생의 원인이 됩니다. 또한 단백질 파우더에 있는 아미노산은 인슐린의 분비도 증가시키기 때문에 이로 인해서도 여드름이 발생하게 됩니다 (12).  

 

한 남성 운동선수들을 대상으로한 사례 연구에서는 단백질 파우더 섭취를 하는 운동선수의 경우 여드름이 많이 나며 여드름 치료제와 약을 사용함에도 여드름이 치료되지 않는 경우가 많았다고 합니다. 하지만 단백질 파우더 섭취를 그만하였을 때는 이런 여드름 증상이 대부분 깔끔하게 사라졌다고 합니다. (13)

 

다른 관찰 연구에서도 마찬가지로 헬스장에 다니는 성인남녀를 대상으로 연구를 하였는데 단백질 파우더 섭취 일수가 증가할 수록 여드름 발생 지역이 증가하였다고 보고하였습니다. 이러한 경향성은 여성여드름 가족력이 없는 사람에게서 더 심하게 나타났다고합니다. 

 

 

Incidence of acne vulgaris in young adult users of protein-calorie supplements in the city of João Pessoa--PB. (An Bras Dermatol. 2013)

 

하지만 위 연구들은 대부분 규모가 작은 연구이기 때문에, 단백질 파우더와 여드름의 정확한 인과관계 규명을 위해서는 더 많은 대상자를 대상으로한 규모가 큰 연구가 필요해 보입니다. 

 

 

7. 개인적인 알러지가 있는 식품

 

 

여드름은 염증성 질환으로 알려져있습니다. 그렇기 때문에 항염증성 약이 여드름 치료에 효과적인 것이죠. 염증이란 상해에 대한 생체 조직의 면역 반응입니다. 만약 어떤 사람이 A 라는 식품에 민감한 특성이 있다면 A 식품을 먹으면 피부가 이를 항원으로 여겨 면역 체계를 발동시키게 되고 이것이 피부에 염증을 일으켜 여드름이 되는 것입니다 (14)

 

하지만 이러한 면역 반응으로 인해 여드름을 유발하는 식품이 무엇인지에 대해서는 사람마다 다른 것이기 때문에, 개인이 이를 파악하기 위해서는 일상생활에서 먹은 음식과 이후에 여드름이 발생하는지를 기록해 먹지 말아야할 식품을 검출하는 식으로 알 수 있습니다. 이를 제외식이법 (elimination diet) 라고도 하는데요 식품 알러지를 치료할 목적으로 식품을 하나씩 제외해가면서 증상을 확인하는 것을 말합니다. 

 

알러지를 유발할 수 있는 식품은 매우 많기 때문에 이러한 알러지로 인한 여드름의 발생은 아직까지 많은 부분이 알려지지 않았습니다 (15). 따라서  스스로 자신에게 알러지를 유발하는 음식을 파악하고 이러한 식품들을 피하는 식습관을 유지하는 것이 여드름을 줄이는데 중요하다고 할 수 있겠습니다. 

 

 

참고

https://www.healthline.com/nutrition/foods-that-cause-acne

반응형
반응형


PBC 데이터를 통한 생존분석


PBC 데이터 다운받을 수 있는 사이트

http://www4.stat.ncsu.edu/~boos/var.select/pbc.html

http://www4.stat.ncsu.edu/~boos/var.select/pbc.dat.txt


이 데이터셋은 mayo clinic에서 수집된 데이터로 일차성 담즙성 간경화증(primary biliary cirrhosis) 환자들의 생존에 대한 데이터입니다. 


데이터 핸들링

library(survival)

data <- read.table("pbc.dat")

# Column rename
colnames(data) <- c('id', 'futime', 'status', 'drug', 'age', 'sex', 'ascites', 'hepato', 'spiders', 'edema', 'bili', 'chol', 'albumin', 'copper', 'alk_phos', 'sgot', 'trig', 
                   'platelet', 'protime', 'stage')

head(data)


id
futime
status
drug
age
sex
ascites
hepato
spiders
edema
bili
chol
albumin
copper
alk_phos
sgot
trig
platelet
protime
stage
1400212146411111.014.52612.601561718.0137.9517219012.24
24500012061710110.01.13024.14547394.8113.528822110.63
31012212559400000.51.41763.48210516.096.105515112.04
41925211999410110.51.82442.54646121.860.639218310.34
51504121391810110.03.42793.53143671.0113.157213610.93
62503222420110100.00.82483.9850944.093.0063.11.03

생존분석 자료의 기본 자료 구성


1. Survival 데이터에서는 time을 나타내는 변수와 event를 나타내는 변수가 있다. 

2. time은 event 까지의 시간을 나타내며, 

3. event 변수는 우리의 관심 event (예를 들어, 사망) 혹은 censoring을 나타낸다. (이는 주로 0, 1로 나타내어진다.)


PBC 데이터에서는  status = 0=alive, 1=liver transplant, 2=dead 인데,  0,1을 중도 절단된 censoring, 2 를 관심 event로 코딩을 해봅시다.

data$status[(data$status == 1)] = 0
data$status[(data$status == 2)] = 1


drug = 1 : 페니실린

drug = 2 : 플라시보이므로 , 해석상의 이점을 얻기 위해

drug = 1 페니실린, drug = 0은 플라시보로 재코딩해줍니다.


data <- data[data$drug != '.', ]
data$drug <- as.character(data$drug)
data$drug[(data$drug == 2)] = 0
data$drug <- factor(data$drug)


1. KM estimation


우선 Survival function을 추정하는 비모수적인 방법으로 많이 쓰이는 Kaplan-Meier analysis 를 해보겠습니다.


# event, censoring 구분
Y = Surv(data$futime, data$status)

# KM estimation
fit = survfit(Y~data$drug)
summary(fit)


우선 Surv라는 함수를 통해 무엇이 time과 event인지를 알려줍니다. 그리고 drug에 따라 생존을 분석할 것이므로 ~data$drug를 입력하면 아래처럼 lifetable을 만들어줍니다.


Call: survfit(formula = Y ~ data$drug)

                data$drug=0 
 time n.risk n.event survival std.err lower 95% CI upper 95% CI
   51    154       1    0.994 0.00647        0.981        1.000
   77    153       1    0.987 0.00912        0.969        1.000
  110    152       1    0.981 0.01114        0.959        1.000
  130    151       1    0.974 0.01282        0.949        0.999
  186    150       1    0.968 0.01428        0.940        0.996
  191    149       1    0.961 0.01559        0.931        0.992
  207    148       1    0.955 0.01679        0.922        0.988
  216    147       1    0.948 0.01788        0.914        0.984
  264    146       2    0.935 0.01986        0.897        0.975
  304    144       1    0.929 0.02075        0.889        0.970
  321    143       1    0.922 0.02160        0.881        0.965
  326    142       1    0.916 0.02240        0.873        0.961
  460    141       1    0.909 0.02317        0.865        0.956
  549    140       1    0.903 0.02389        0.857        0.951
  552    139       1    0.896 0.02459        0.849        0.946
  597    138       1    0.890 0.02525        0.841        0.941
  611    137       1    0.883 0.02589        0.834        0.935
  708    136       1    0.877 0.02650        0.826        0.930
  733    135       1    0.870 0.02709        0.819        0.925
  769    134       1    0.864 0.02765        0.811        0.920
  786    133       1    0.857 0.02820        0.804        0.914
  790    131       1    0.851 0.02873        0.796        0.909
  797    130       1    0.844 0.02925        0.789        0.903
  850    128       1    0.837 0.02975        0.781        0.898
  853    127       1    0.831 0.03024        0.774        0.892
  859    126       1    0.824 0.03071        0.766        0.887
  890    125       1    0.818 0.03116        0.759        0.881
  930    124       1    0.811 0.03160        0.751        0.875
  943    123       1    0.804 0.03203        0.744        0.870
  974    122       1    0.798 0.03244        0.737        0.864
 1080    118       1    0.791 0.03286        0.729        0.858
 1165    115       1    0.784 0.03328        0.722        0.852
 1212    114       1    0.777 0.03370        0.714        0.846
 1217    111       1    0.770 0.03411        0.706        0.840
 1356    103       1    0.763 0.03459        0.698        0.834
 1413    101       1    0.755 0.03506        0.690        0.827
 1427     98       1    0.748 0.03554        0.681        0.821
 1444     95       1    0.740 0.03603        0.672        0.814
 1487     93       1    0.732 0.03651        0.664        0.807
 1536     91       1    0.724 0.03698        0.655        0.800
 1786     79       1    0.715 0.03763        0.645        0.792
 1847     76       1    0.705 0.03829        0.634        0.784
 2090     69       1    0.695 0.03908        0.622        0.776
 2419     56       1    0.683 0.04030        0.608        0.766
 2466     53       1    0.670 0.04155        0.593        0.756
 2503     51       1    0.657 0.04276        0.578        0.746
 2769     40       1    0.640 0.04473        0.558        0.734
 2796     38       1    0.623 0.04662        0.538        0.722
 2847     35       1    0.605 0.04857        0.517        0.709
 3090     32       1    0.587 0.05060        0.495        0.695
 3170     29       1    0.566 0.05275        0.472        0.680
 3244     28       1    0.546 0.05460        0.449        0.664
 3358     26       1    0.525 0.05640        0.425        0.648
 3395     24       1    0.503 0.05814        0.401        0.631
 3428     22       1    0.480 0.05983        0.376        0.613
 3445     21       1    0.457 0.06119        0.352        0.595
 3762     15       1    0.427 0.06427        0.318        0.573
 3839     13       1    0.394 0.06719        0.282        0.551
 3853     12       1    0.361 0.06916        0.248        0.526

                data$drug=1 
 time n.risk n.event survival std.err lower 95% CI upper 95% CI
   41    158       1    0.994 0.00631        0.981        1.000
   71    157       1    0.987 0.00889        0.970        1.000
  131    156       1    0.981 0.01086        0.960        1.000
  140    155       1    0.975 0.01250        0.950        0.999
  179    154       1    0.968 0.01393        0.941        0.996
  198    153       1    0.962 0.01521        0.933        0.992
  223    152       1    0.956 0.01637        0.924        0.988
  334    151       1    0.949 0.01744        0.916        0.984
  348    150       1    0.943 0.01844        0.908        0.980
  388    149       1    0.937 0.01937        0.900        0.975
  400    148       1    0.930 0.02025        0.892        0.971
  515    147       1    0.924 0.02108        0.884        0.966
  673    145       1    0.918 0.02187        0.876        0.962
  694    144       1    0.911 0.02263        0.868        0.957
  750    141       1    0.905 0.02337        0.860        0.952
  762    140       1    0.898 0.02408        0.852        0.947
  799    139       1    0.892 0.02476        0.845        0.942
  824    138       1    0.885 0.02541        0.837        0.937
  904    134       1    0.879 0.02607        0.829        0.931
  971    132       1    0.872 0.02671        0.821        0.926
  980    131       1    0.866 0.02732        0.814        0.921
  999    130       1    0.859 0.02791        0.806        0.915
 1000    129       1    0.852 0.02848        0.798        0.910
 1012    128       1    0.846 0.02902        0.791        0.904
 1037    127       1    0.839 0.02955        0.783        0.899
 1077    126       1    0.832 0.03005        0.775        0.893
 1083    125       1    0.826 0.03054        0.768        0.888
 1152    124       1    0.819 0.03101        0.760        0.882
 1170    122       1    0.812 0.03148        0.753        0.876
 1191    121       2    0.799 0.03236        0.738        0.865
 1235    117       1    0.792 0.03279        0.730        0.859
 1297    114       1    0.785 0.03323        0.723        0.853
 1350    111       1    0.778 0.03368        0.715        0.847
 1360    110       1    0.771 0.03411        0.707        0.841
 1434    105       1    0.764 0.03456        0.699        0.834
 1492    100       1    0.756 0.03505        0.690        0.828
 1576     97       1    0.748 0.03554        0.682        0.821
 1657     93       1    0.740 0.03606        0.673        0.814
 1682     92       1    0.732 0.03655        0.664        0.807
 1690     91       2    0.716 0.03748        0.646        0.793
 1741     87       1    0.708 0.03794        0.637        0.786
 1827     82       1    0.699 0.03845        0.628        0.779
 1925     78       1    0.690 0.03899        0.618        0.771
 2055     72       1    0.681 0.03960        0.607        0.763
 2081     71       1    0.671 0.04019        0.597        0.755
 2105     70       1    0.661 0.04074        0.586        0.746
 2224     65       1    0.651 0.04137        0.575        0.738
 2256     63       1    0.641 0.04198        0.564        0.729
 2288     61       1    0.630 0.04259        0.552        0.720
 2297     60       1    0.620 0.04315        0.541        0.710
 2386     54       1    0.608 0.04385        0.528        0.701
 2400     53       1    0.597 0.04450        0.516        0.691
 2540     47       1    0.584 0.04533        0.502        0.680
 2583     42       1    0.570 0.04634        0.486        0.669
 2598     41       1    0.556 0.04725        0.471        0.657
 2689     38       1    0.542 0.04822        0.455        0.645
 3086     28       1    0.522 0.05023        0.433        0.631
 3222     24       1    0.501 0.05264        0.407        0.615
 3282     22       1    0.478 0.05495        0.381        0.599
 3574     18       1    0.451 0.05795        0.351        0.580
 3584     17       1    0.425 0.06032        0.322        0.561
 4079      8       1    0.372 0.07247        0.254        0.545
 4191      7       1    0.319 0.07922        0.196        0.519


par(mai=c(1,1,1,1))
plot(fit,main="KM Curve", xlab="Time(Week)", ylab=expression(paste(hat(S),"(t)")))

# Log rank test (difference between groups)
log_rank = survdiff(Surv(data$futime, data$status) ~ data$drug, data)
log_rank

결과를 보시면 플라시보와 페니실린 처방군간에 생존률에 큰 차이가 없는 것을 확인할 수 있습니다.


두 군간에 차이가 있는지 검정하는 방법인 log_rank 테스트에서도 p value > 0.05로 두 군간에 차이가 유의하지 않습니다.


Call:
survdiff(formula = Surv(data$futime, data$status) ~ data$drug, 
    data = data)

              N Observed Expected (O-E)^2/E (O-E)^2/V
data$drug=0 154       60     61.8    0.0513     0.102
data$drug=1 158       65     63.2    0.0502     0.102
 

Chisq= 0.1 on 1 degrees of freedom, p= 0.7



2. Cox regression


생존분석을 다변수로 할 때, Cox regression을 주로 활용합니다. 이는 Cox proportional hazard model로 불리기도 합니다.


Cox regression은 다음과 같은 이유로 많이 쓰입니다.


1. 다양한 변수들의 계수와 hazard ratio를 추정하는데 좋다. -> 이를 통해 변수별 생존에 대한 중요도를 비교하기 쉽다.

2. Cox regression은 robust 하다. (참에 매우 근접한 값을 추정해준다.)

3. 계산된 hazard가 양수이기 때문에 타당한 값이다.

4. baseline hazard를 몰라도 회귀계수, hazard ratio를 추정할 수 있다.


Cox regression의 이론적 배경에 대해서는 다음에 기회가 있을 때 다루어보도록 하겠습니다. 


R에서 Cox regression을 수행하는 것은 매우 간단한데, 앞서 정의한 event, time 변수인 Y를 종속변수로 놓고 분석대상인 변수들을 ~ +로 연결하면 됩니다.  

# Cox regression
cox = coxph(Y~data$drug + data$age + data$sex + data$stage + data$edema + data$bili + data$albumin)
summary(cox) 
Call:
coxph(formula = Y ~ data$drug + data$age + data$sex + data$stage + 
    data$edema + data$bili + data$albumin)

  n= 312, number of events= 125 

                   coef  exp(coef)   se(coef)      z Pr(>|z|)    
data$drug1    2.569e-02  1.026e+00  1.855e-01  0.138 0.889882    
data$age      6.736e-05  1.000e+00  2.651e-05  2.541 0.011057 *  
data$sex     -5.940e-01  5.521e-01  2.550e-01 -2.330 0.019832 *  
data$stage1  -2.248e+00  1.056e-01  1.023e+00 -2.197 0.027992 *  
data$stage2  -8.573e-01  4.243e-01  2.950e-01 -2.906 0.003659 ** 
data$stage3  -4.884e-01  6.136e-01  2.186e-01 -2.234 0.025487 *  
data$stage4          NA         NA  0.000e+00     NA       NA    
data$edema    9.740e-01  2.649e+00  3.148e-01  3.095 0.001971 ** 
data$bili     1.263e-01  1.135e+00  1.529e-02  8.263  < 2e-16 ***
data$albumin -9.288e-01  3.950e-01  2.556e-01 -3.634 0.000279 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

             exp(coef) exp(-coef) lower .95 upper .95
data$drug1      1.0260     0.9746   0.71322    1.4760
data$age        1.0001     0.9999   1.00002    1.0001
data$sex        0.5521     1.8112   0.33497    0.9101
data$stage1     0.1056     9.4656   0.01423    0.7844
data$stage2     0.4243     2.3568   0.23801    0.7564
data$stage3     0.6136     1.6296   0.39979    0.9419
data$stage4         NA         NA        NA        NA
data$edema      2.6486     0.3776   1.42921    4.9083
data$bili       1.1347     0.8813   1.10117    1.1692
data$albumin    0.3950     2.5315   0.23936    0.6519

Concordance= 0.839  (se = 0.029 )
Rsquare= 0.427   (max possible= 0.983 )
Likelihood ratio test= 174  on 9 df,   p=<2e-16
Wald test            = 186.2  on 9 df,   p=<2e-16
Score (logrank) test = 287  on 9 df,   p=<2e-16


그러면 이렇게 회귀계수와 회귀 계수의 exponential을 돌려주게 됩니다. Cox regression이 좋은 점은 회귀계수에 exponential을 취했을 때, 해당 변수가 1단위 증가했을 때의 hazard ratio가 됩니다. 예를 들어, age의 경우, 다른 변수들을 보정하고, 1살 증가했을 때, hazard가 1.0001배 증가한다. 라고 볼 수 있습니다. sex의 경우, 다른 모든 변수를 보정했을 때, 남자에 비해 여자가 hazard가 0.55 배라고 볼 수 있습니다 (이 데이터에서 0=male, 1=female로 코딩이 되어있기 때문에). p-value를 보면 어떠한 변수가 생존에 영향을 크게 끼치는 지를 비교해볼 수 있습니다.  



반응형

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

R igraph 설치 오류 해결  (0) 2018.12.28
R Default library path 바꾸기  (2) 2018.12.28
Jupyter notebook에서 R을 이용하기 (IRkernel)  (6) 2018.10.05
R 패키지 설치시 gfortran 컴파일 오류  (0) 2018.07.06
R 유명한 패키지 정리  (0) 2018.03.19
반응형

Jupyter notebook 에서 R을 이용하기


데이터 분석을 할 때, PythonR을 동시에 이용하시는 분들이 많습니다.

저 같은 경우도 머신러닝, 딥러닝 등을 할 때는 Python을, 데이터 처리, 가공, 통계분석을 할 때는 R을 선호하는데요. 이 경우 Jupyter notebook 등의 Python 개발 환경과 R studio 를 번갈아가면서 이용해야해서 불편한 점이 많았습니다. 


본 포스팅에서는 Jupyter notebook이라는 하나의 개발 환경에서 R과 Python을 같이 이용할 수 있게 해주는 IRkernel을 설치하는 것을 포스팅해보았습니다.


IRkernel을 이용하면 Jupyter notebook에서도 현재 컴퓨터에 설치된 R 커널을 이용할 수 있게 해줍니다.

IRkernel은 R 커널을 Jupyter notebook에서 이용할 수 있게 해주는 패키지입니다. 

https://github.com/IRkernel/IRkernel


우선 당연히 선행적으로 Jupyter가 설치되어있어야하며,


주의할 점은 conda 가상환경 쓰시는 분들은

이걸 jupyter notebook이 설치된 conda 가상환경을 키고 IRkernel 설치를 진행하여야합니다.


먼저 devtools를 설치합니다.

install.packages('devtools')


다음 devtools를 이용해 IRkernel을 설치합니다.


devtools::install_github('IRkernel/IRkernel')

# or devtools::install_local('IRkernel-master.tar.gz')

IRkernel::installspec()  # to register the kernel in the current R installation



이렇게 R kernel이 생기게 됩니다.



저는 R version 3.5.1을 이용중이었는데 동일한 버전을 Jupyter notebook에서도 이용할 수 있습니다.


---- 추가 (2020-09-28)

conda install r-irkernel

위 conda 커맨드로 anaconda 가상환경 밑에 R 과 IRKernel 을 동시에 설치할 수도 있습니다. 


특정 R 버전에 설치하기 위해서는 아래 참고 (2020-10-16 추가)

http://salvatoregiorgi.com/blog/2018/10/16/installing-an-older-version-of-r-in-a-conda-environment/

반응형
반응형


주피터 nbextension 설치


우선 가상환경을 쓰시는 분들은 가상환경을 activate하시기 바랍니다.


source activate [가상환경이름]


pip install jupyter_nbextensions_configurator jupyter_contrib_nbextensions

jupyter contrib nbextension install --user

jupyter nbextensions_configurator enable --user


위 커맨드를 입력하시면 nbextension이 설치됩니다. 원래는 Clusters 옆에 nbextension 탭이 생기게 됩니다.



저의 경우에는 왜 인지는 모르겠지만 자동으로 nbextension 탭이 안 생겼는데

[아이피]:[포트]/nbextensions 로 들어가니까 아래처럼 nbextension 메뉴를 볼 수 있었습니다. 


메뉴에서 사용 가능한 extension 들이 나와있고, 클릭을 통해 enable/disable을 할 수 있습니다.

처음 사용하실 때는 각각의 모듈들을 설치하셔야 합니다.


주피터 테마 설치


주피터 테마

https://github.com/dunovank/jupyter-themes


마찬가지로 가상환경 activate 후에


pip install jupyterthemes


커맨드 옵션은 아래와 같습니다.


jt  [-h] [-l] [-t THEME] [-f MONOFONT] [-fs MONOSIZE] [-nf NBFONT]

    [-nfs NBFONTSIZE] [-tf TCFONT] [-tfs TCFONTSIZE] [-dfs DFFONTSIZE]

    [-m MARGINS] [-cursw CURSORWIDTH] [-cursc CURSORCOLOR] [-vim]

    [-cellw CELLWIDTH] [-lineh LINEHEIGHT] [-altp] [-altmd] [-altout]

    [-P] [-T] [-N] [-r] [-dfonts]


jt -l 로 적용가능한 테마들을 볼 수 있습니다.


저의 경우에는 onedork 테마가 마음에 들어서


jt -t onedork -fs 95 -tfs 11 -nfs 115 -cellw 70% -T

이러한 옵션으로 사용중인데, 폰트 사이즈도 적절하고 화면이 주피터 노트북 default보다 조금 넓은 정도여서 편리하게 사용하고 있습니다.


각각의 옵션이 무엇을 뜻하는지에 대한 설명은

https://github.com/dunovank/jupyter-themes 을 참조하시면 됩니다.


또 테마를 설치한 후, output화면에서 왼쪽이 약간 잘려 나오는 문제가 있었는데

~/.jupyter/custom/custom.css 에서

div.output_area {
display: -webkit-box;
padding-left: 20px;
}

를 추가하여 해결하였습니다. 위 파일을 수정하면 jupyter notebook의 css 설정을 직접 바꾸어 자신만의 테마를 만들어 볼 수도 있습니다.


반응형
반응형

 

데이터과학이란 무엇인가?

 

데이터 과학이란 무엇인가? 사실 모든 학문, 산업 분야에서 "데이터" 는 필수적이다. 그런데 왜 "데이터" 과학이라는 이름을 따로 붙이는 걸까? 거기에 Science라니. 보통 Science라는 것은 새로운 지식을 찾는 활동, 즉, New finding에 대한 것을 Science라 한다. 하지만 데이터 과학에서 주로하는 것은 데이터를 처리하고 클리닝 하여 저장하고는 것, 즉 무언가를 개선 시키는 활동인 Engineering에 그치는 것 아닌가? 

 

데이터 과학자는 통계학자보다 컴퓨터를 잘하고, 컴퓨터과학자보다 통계학을 잘하는 사람이라는 우스갯 소리가 있다. 물론 어느 정도 맞는 부분이 있지만 데이터 과학은 단지 어떤 학문 분야들의 중간에 있는 것이 아니라 기존 학문들에서 다루지 않는 부분을 다루기도 한다. 데이터 과학의 정의, 기존 학문과의 차별점에 대해 짚어보자. 

 

최근 떠오르는 학문 분야들에 대한 농담

 

Data science의 정의

 

The term “data science” describes expertise associated with taking (usually large) data sets and annotating, cleaning, organizing, storing, and analyzing them for the purposes of extracting knowledge. It merges the disciplines of statistics, computer science, and computational engineering.

 

데이터과학이란 보통 큰 데이터셋에 대해 어노테이션, 클리닝, 핸들링, 저장, 분석을 하여 그로부터 유용한 지식을 추출하는 것을 말한다. 이는 Informatics와 비슷하다. Informatics 란 정보학으로 모든 데이터를 처리 분석하여 유용한 정보를 얻는 것이다.

 

Informatics와 Data science의 차이점은 무엇인가?

 

간단하게 말해 Data science는 "빅데이터시대"에 정의된 학문 분야로서 기존에 보기 힘든 정도의 큰 데이터를 다룬다는 특징이 있다. 데이터 과학자는 컴퓨터 메모리에 올라가지 않는 규모의 큰 데이터를 다루며 이를 위한 기술적인 지식이 필요하다. 이전에는 Informatics를 위해서 컴퓨터 프로그래머를 고용하여 해결하였다고 한다. 하지만 데이터 과학은 단순히 "프로그래밍" 으로 해결할 수 없는 많은 부분을 포함하고 있다. Informatics와 Data science의 여집합은 바로 이 부분에서 나온다. 또한 Data science는 단순 프로그래밍이 아니라 해당 분야의 지식에 대한 깊은 이해를 기본 가정으로 한다. 즉, 이를 다시 한 번 정리해보자.

 

Informatics와 Data science의 차이점

 

 

1. 데이터과학자는 컴퓨터 메모리에 올라가지 않는 수준의 빅데이터를 다룬다.

2. 데이터과학자는 메타데이터 및 large-scale annotation이 필요하며, 데이터의 noise가 어디에서 발생되었는지에 대해 설명할 수 있어야 한다. 이는 도메인에 대한 이해를 필요로 하며 단지 데이터를 정리하고 가공하는 것과는 다르다.

3. 이러한 빅데이터를 분석할 수 있는 방법론인 머신러닝, 딥러닝 등을 이해하고 이를 해당 분야의 데이터에 적용시켜 유용한 가치를 찾는다.

 

 
최근 많은 학교 교육 및 직업 교육에서 domain-free 데이터과학을 가르친다. 금융, 헬스, 생물 어떤 분야에도 통용할 수 있는 데이터 처리 기술이다. 물론 그것은 데이터 과학을 시작할 수 있는 "기초 단계"로서 유용하다. 하지만 단지 domain-free 데이터 과학만을 배우면 단지 데이터를 가공하고 매니지하는 사람에 그쳐버릴 수도 있다. (협업자의 엄청난 도움이 없다면) 하지만 domain에 대한 specific knowledge가 있으면 그 분야에 전문가이면서 데이터를 직접 처리하고 가공, 분석 할 수 있는 사람이 될 수 있다.  

 

데이터과학자에게 도메인 지식이 필수적인 이유는 다음과 같이 정리해볼 수 있다. 

 

1. 데이터에 무언가 문제가 생겼을 때,이를 해결하기 위해 필요하다.
2. 데이터의 annotation을 하기 위해서는 도메인 지식이 필요하다.
3. 문제를 찾고 이를 해결하기 위해서는 도메인 지식이 필수적이다.
 
 

 

빅데이터 시대의 대표적인 분석 방법론, 머신러닝

 
 
좋은 데이터 과학자란, 기존 Informatics 방법론으로는 다루기 힘든 수준의 복잡한 빅데이터를 다루며, 충분한 도메인 지식을 바탕으로 해당 분야의 데이터를 스스로의 계획을 통해 처리, 가공을 하며, 메타 데이터 annotation을 직접하며, 해당 분야의 문제를 찾고 이를 해결할 수 있는 사람이다.  어떤 도메인을 깊게 공부하고 그 데이터에 대해 즉각적으로 이해하고 데이터를 어떻게 처리하고 굴려서 분석할지를 정하는 데에 좋은 결정력을 갖고 있는 사람이다. 어떤 한 분야의 domain 지식을 가질 때 그 분야의 문제를 찾고, 직접 데이터를 처리하고 적절한 분석 방법을 통해 분석하여 해결할 수 있는 사람이 된다. 
Biomedical Data science 를 예로 들어보자.

 

Biomedical science 분야는 Bio와 medical이 합쳐진 분야이다. 즉, 생물학과 의학이 합쳐진 분야로 생물학, 의학 분야의 "과학적 발견"을 주로 population health에 응용하는 응용학문이다. 이러한 Biomedical 분야는 데이터를 통해서 무언가를 할 수 있다. 따라서 Biomedical 분야를 연구하려면 기본적으로 데이터를 가공하고, 클리닝하고, 분석할 수 있어야한다. 그러면 Biomedical data science라는 용어는 왜 존재하는가? 

 

Biomedical 분야의 데이터를 다음 세 가지로 크게 나눌 수 있다.

 

1. DNA 시퀀싱 데이터 (NGS 데이터)

2. 센서 데이터 (심박수, electrocardiogram signal 등)

3. Electronic health record (개인의 건강 임상 정보)

 

이러한 종류의 데이터는 소위 말하는 4v(Volume, Variety, Velocity, Value)를 만족하는 "빅데이터" 이다. 이러한 정보를 가공하고 분석하기 위해서는 특별한 skill set이 필요하다. NGS 데이터를 예로 들어보자. NGS는 새로운 인간 DNA의 시퀀싱 방법으로 massive parallele sequencing이라고 하는 특별한 시퀀싱 방법을 통해 인간 DNA 서열을 "추측"한다. 이 기술의 상당한 발전이 이루어져 정확도는 상당히 높지만, 중요한 것은 뚝딱하고 ATCG로 이루어진 DNA의 서열이 나오지 않는다는 것이다. 또 DNA 서열은 30억개 정도가 되기 때문에 한 글자당 4비트라고 놓고 계산을 하더라도 1GB 이상의 크기이며, 실제 NGS 분석에서 나오는 Raw 데이터는 1인당 200GB에 이른다. (참고)  따라서 이러한 특별한 종류의 NGS 데이터를 통해 인간 DNA 서열을 조립하고, 이곳에서 변이(variant)를 탐색하고 질병과의 연관성을 분석하는 것은 상당한 도메인 지식을 필요로 한다. Biomedical data science란 이러한 종류의 데이터를 직접 가공, 클리닝하여 이를 분석하고 유용한 지식을 탐색하는 활동이라고 할 수 있다. 

 

Reference

[1] What is Biomedical Data Science and Do We Need an Annual Review of It ? - Annual review of biomedical data science, 2018

반응형
반응형

벅슨의 역설 (Berkson's Paradox)


벅슨의 역설은 병원 기반 데이터로 case-control 연구를 할 때 발생하는 현상으로 1946년 Joseph Berkson이 보고한 역설입니다. 


벅슨의 역설이 생기는 이유


A와 B 둘다 있는 사람이나, A와 B 둘다 없는 사람이 연구 대상에서 제외되었을 때, A-B 간의 가짜 관계가 생깁니다. 벅슨의 역설을 병원 기반 데이터로 보여줄 때는 주로, A, B 둘다 없는 사람이 연구 대상에서 제외되었기 때문에 발생합니다. 



간단한 예


이 예를 통해 전혀 상관 없어보이는 두 가지 질병, 인플루엔자와 맹장염의 가짜 연관성(spurious association)이 어떻게 생기는지를 보입니다. (이미지 출처)


우선, 병원에 입원한 환자가 100명이라고 했을 때 다음과 같이 가정합니다.


1. 전체 인구집단에서 인플루엔자의 유병률은 10% 이다.

2. 병원에 온 사람 중 인플루엔자로 입원한 사람은 30%이다.

3. 병원에 온 사람 중 맹장염으로 입원한 사람은 10%이다. 

4. 인플루엔자와 맹장염은 독립적이다. 즉, 맹장염으로 입원한 사람중 10%가 인플루엔자를 가졌다고 가정. (맹장염의 유병률이 매우 낮다고 가정) 




(파란색=인플루엔자, 빨간색=맹장염, 검은색=기타, 빨간색+파란색=인플루엔자, 맹장염을 동시에 가진 사람)


이 상황에서 인플루엔자 따른 맹장염의 발생 양상을 파악하기 위해, 인플루엔자를 가진사람과 안 가진 사람으로 나뉘어 맹장염에 걸린 사람을 나눠봅니다. 총 30명의 인플루엔자를 가진 사람 중  1명이 맹장염에 걸렸습니다. 총 70명의 인플루엔자를 안 가진 사람중 9명이 맹장염에 걸렸습니다. 



위 노란박스는 70명의 인플루엔자를 안 가진 사람 중 9명이 맹장염에 걸린 상황을 나타냅니다.


이 때, 인플루엔자를 기준으로 한 맹장염의 상대위험도는 (1/30)/(9/70) = 0.004 로 인플루엔자가 맹장염에 보호적인 효과가 있는 것으로 나옵니다. 이 때, 이런 가짜 연관성이 생긴 이유는 병원 데이터의 특성 때문입니다. 즉, 인플루엔자와 맹장염이 둘 다 없는 사람이 일반 인구집단과 비교하여 더 적기 때문에, 인플루엔자가 없는 사람 중 맹장염에 걸린 사람이 9/70 = 12% 로 과추정되었습니다. 


참고

http://www.statisticshowto.com/berksons-paradox-definition/

반응형
반응형