본문 바로가기

Programming

집단지성 프로그래밍 1(Machine Learning, Euclidean Distance, Pearson Correlation Coefficient)

Machine Learning에 대해서 공부가 하고 싶어 책을 찾아보다가 토비 세가란 저, 윤종완 역의 '집단지성 프로그래밍' 책을 알게 되었고 이 책을 읽으며 개인적으로 공부를 하고 정리하며 블로그에 올리려고 한다.

아래 내용과 추후 업로드 될 몇몇 글들은 위의 책에 나오는 글들을 나름의 해석으로 요약한 내용이며, 안의 예제 코드들은 책에 나오는 코드들이다.

Machine Learning

기계학습(machine learning)는 컴퓨터가 스스로 학습하게 하는 알고리즘에 관련된 인공지응의 한 영역이다. 대부분의 경우 기계학습은 주어진 데이터의 집합을 이용해서 데이터의 속성에 관한 정보를 추론하는 알고리즘을 말한다. 이러한 정보를 갖고, 기계학습을 통해 사람이 분석하기 힘든 방대한 데이터에서 패턴을 추출하여 새로운 데이터의 미래에 대한 예측을 할 수 있다.

하지만 기계학습이 만능은 아니다. 알고리즘들의 법칙화 능력이 패턴에 따라 다르며, 전에 나타나지 않은 패턴의 경우 해석 오류가 발생될 확률도 높다. 새로운 정보에 대한 판단을 해야 할 경우, 인간은 거대한 문화지식과 경험, 뛰어난 유사 상황 인식력을 십분 활용한다. 반면, 기계학습 기법들은 일단 한 번 경험한 데이터만을 기반으로 법칙화한다. 이 조차도 제한된 방식 내에서만 수행된다.

Machine Learning의 사례
  • 생물공학 염기분석과 선별기술의 발전으로 다양한 종류의 대량 데이터 세트가 생성된다. DNA 순열, 단백질 구조체, 복합물 선별, RNA 발현 데이터 세트가 그 예다. 생물학적 진행 과정에 대한 이해 증진을 위한 패턴들을 발견하기 위한 노력 차원에서 이런 데이터에 기계학습 기법들이 적극적으로 활용된다.

  • 금융사기 검출 신용카드 회사는 사기성 있는 거래를 검출하는 새로운 방법을 지속적으로 찾고 있다. 신경망과 귀납논리와 같은 기술을 거래를 검사하고 오용 예를 검출하는 데 적용하고 있다.

  • 컴퓨터 비전 비디오 영상 내 이미지 해석은 군사, 감시용으로 활발히 연구되고 있는 영역이다. 자동 침입자 검출, 이동체 식별, 안면 인식 등에 다양한 기계학습 기법들이 사용된다. 대용량 데이터 세트에서 흥미로운 특징을 찾는 독립요소분석(independent component analysis)과 같은 무감독 학습 기법들을 사용한다.

  • 제품 마케팅 오랫동안 인구통계와 동향 이해는 과학이라기 보단 예술로 간주되어 왔다. 최근 들어 고객 데이터 수집 능력의 향상으로 기계학습을 적용할 기회가 열렸다. 이것은 시장 내 고객 분류와 미래 동향에 대한 정확한 예측을 위해 이용된다.

  • 공급망 최적화 대규모 기업체는 지역 간 제품별 정확한 수요 예측과 효율적인 공급망 관리를 통해 수백만 달러를 절약할 수 있다. 구성 가능한 공급망은 매우 다양해서 수요에 영향을 미치는 요인들이 다수 있게 된다. 이러한 데이터 세트를 분석하는 데 최적화와 학습 기법들이 자주 사용 된다.

  • 주식시장 분석 주식시장이 만들어진 이후로 사람들은 수학을 사용해서 돈을 버는 방법을 찾고자 했다. 참가자들이 보다 정교해질수록 보다 큰 데이터 집합을 분석해야 하므로 고급 패턴 검출 기법들이 사용되고 있다.

  • 국가안보 전세계에서 국가정보원들이 수집한 수많은 정보는 컴퓨터를 사용해서 패턴을 검출하고, 그것을 내재된 위협들과 연계하는 방식으로 분석한다.


추천 시스템 만들기

사람들이 영화를 보고 각 영화에 대해 평점을 매긴 정보들을 갖고 있다면, 각 사람들의 유사도 측정 혹은 다양한 분석을 통해 각 사람들에게 맞는 새로운 영화들을 추천할 수 있다. 이를 간단한 데이터 셋을 만들어두고 여러 방법을 통해 추천 시스템을 만들어 보도록 한다.

데이터 셋

critics = {
    'Lisa Rose': {
        'Lady in the Water': 2.5,
        'Snakes on a Plane': 3.5,
        'Just My Luck': 3.0,
        'Superman Returns': 3.5,
        'You, Me and Dupree': 2.5,
        'The Night Listener': 3.0
    },

    'Gene Seymour': {
        'Lady in the Water': 3.0,
        'Snakes on a Plane': 3.5,
        'Just My Luck': 1.5,
        'Superman Returns': 5.0,
        'The Night Listener': 3.0,
        'You, Me and Dupree': 3.5
    },

    'Michael Phillips': {
        'Lady in the Water': 2.5,
        'Snakes on a Plane': 3.5,
        'Superman Returns': 3.5,
        'The Night Listener': 4.0
    },

    'Claudia Puig': {
        'Snakes on a Plane': 3.5,
        'Just My Luck': 3.0,
        'The Night Listener': 4.5,
        'Superman Returns': 4.0,
        'You, Me and Dupree': 2.5
    },

    'Mick LaSalle': {
        'Lady in the Water': 3.0,
        'Snakes on a Plane': 4.0,
        'Just My Luck': 2.0,
        'Superman Returns': 3.0,
        'The Night Listener': 3.0,
        'You, Me and Dupree': 2.0
    },

    'Jack Mattheuws': {
        'Lady in the Water': 3.0,
        'Snakes on a Plane': 4.0,
        'The Night Listener': 3.0,
        'Superman Returns': 5.0,
        'You, Me and Dupree': 3.5
    },

    'Toby': {
        'Snakes on a Plane': 4.5,
        'You, Me and Dupree': 1.0,
        'Superman Returns': 4.0
    }
}

유사 사용자 찾기

각 사용자들의 평점 점수와 유클리디안 거리점수, 피어슨 상관계수 방법을 이용해 각 사용자의 유사도를 분석한다.

유클리디안 거리점수(Euclidean Distance)

가장 간단한 유사도 계산 방법이다. 유클리디언 거리를 이용해 각 사용자의 유사도를 측정하는 방법은 영화의 종류를 \(n\) 차원의 축으로 놓고, 사용자에 따른 평점들을 좌표로 하여 공간에 표시한 후 각 점 사이의 거리를 통해 유사도를 측정한다. 이 점 사이의 거리가 짧을수록 유사하다고 할 수 있다.

예를 들어, 영화 중 'Snakes on a Plane'과 'You, Me and Dupree'란 2개의 영화에 대해 좌표 평면을 만들어보자. 현재 영화 2 종류를 택했기 때문에 2차원 평면에서 진행하면 된다.

euclidean distance graph

위의 그림을 보면 Toby는 Snakes 영화 축에서 4.5점, Dupree 영화 축에서 1.0점에 위치한다. 이때 Toby와 가까이 있을수록 Toby와의 유사도가 증가한다. 위의 그림에서는 LaSalleToby와 가장 유사하다. 이는 두개의 영화 종류를 이용해 2차원에서 표현한 것이고 \(n\)개의 영화 종류가 존재한다면, \(n\)개의 축을 이용해 각각의 거리를 구해 유사도를 측정할 수 있다.

\(n\) 축은 사람의 머리속에선 잘 상상이 안가지만, 컴퓨터로 하면 계산할 수 있다...

이 때, 각 점 사이의 거리를 구하는 공식은 아래와 같고, \[ \sqrt{(x_1-x_2)^2+(y_1-y_2)^2} \]

Python에서는 아래와 같이 코드를 사용할 수 있다.

>>> from math import sqrt
>>> sqrt(pow(x1-x2) + pow(y1-y2))

위의 공식을 이용해 나온 결과 값은, 거리 값이므로 작을수록 유사도가 높아진다. 이를 직관적으로 이해하기 위해 아래의 코드와 같이 역수를 취해 값이 클수록 유사도가 커지는 형태로 변환한다.

>>> 1/(1+sqrt(pow(x1-x2) + pow(y1-y2)))

이제 위의 코드들을 일반화 하여, 처음 나온 데이터 셋에 대해 적용할 수 있도록 코드를 작성해 recommendation.py에 추가한다.

위의 코드를 이용하면 아래와 같은 결과를 얻을 수 있다.

>>> import recommendations
>>> for item in recommendations.critics:
...     print "Toby and", item, recommendations.sim_distance(recommendations.critics, 'Toby', item)
...
Toby and Gene Seymour 0.258245699761
Toby and Mick LaSalle 0.4
Toby and Claudia Puig 0.356789172325
Toby and Lisa Rose 0.348331477355
Toby and Toby 1.0
Toby and Michael Phillips 0.472135955
Toby and Jack Mattheuws 0.267478890389

피어슨 상관계수(Pearson correlation coefficient)

Euclidean Distance에서 조금 더 발전한 피어슨 상관계수(Pearson correlation coefficient)라는 방법이 존재한다. 이 피어슨 상관계수는 두 개의 데이터 집합이 한 직선으로 얼마나 잘 표현되는가를 나타내는 측정값이다. Euclidean Distance 보다 조금 더 복잡하지만, 잘 정규화되지 않은 데이터의 경우에도 훨 나은 결과를 제공한다. 예를 들어 평론가들의 영화 평점은 일반적으로 평균보다 더 엄격하여 점수를 극단적으로 주는 경우 피어슨 상관계수가 더 적합하다.

Euclidean Distance와 같이 Mick LaSalleGene Seymour의 평점 정보를 이용해 피어슨 상관 분석 그래프를 만들어 본다.

pearson graph

위의 그래프에서 직선은 최적 맞춤선(best-fit line) 이라고 부르며, 차트 내 모든 항목들과 가능한 가장 가까운 직선임을 의미한다. Mick LaSalleGene Seymour 두 평론가가 모든 영화를 동일하게 평가했다면 이 선은 대각선이 될 것이고, 이 선 위에 모든 항목들이 있게 된다.

이 피어슨 상관계수에서 만일 한 평론가가 다른 평론가에 비해 더 높은 혹은 극단적인 점수를 주었어도, 그들 간의 점수 차이가 일정하다면 두 사람은 완벽한 상관도를 가질 수 있다. 하지만 Euclidean Distance 에서는 실제 비슷한 취향을 가진 사람들 간에도 다른 사람에 비해 더 가혹하게, 극단적으로 평가한다면 결과적으로 두 평론가가 다르다고 나올 수 있다.

피어슨 상관계수를 구하는 순서는 아래와 같다.

  1. 두 평론가가 공통으로 평가한 영화들을 찾는다
  2. 각각의 평론가가 평가한 영화 점수들을 합한다
  3. 각각의 평론가가 평가한 영화 점수의 제곱의 합을 구한다
  4. 두 평론가가 평가한 영화 점수의 곱의 합을 구한다
  5. 아래의 공식을 이용해 피어슨 상관계수를 구한다

\[ r = \frac{\sum{(x_i-\bar{x})(y_i-\bar{y})}}{\sqrt{\sum{(x_i-\bar{x})^2}}\sqrt{(y_i-\bar{y})^2}} \] \[ \bar{x} = \frac{1}{n}\sum\limits_{i}^n{x_i} \] \[ \bar{y} = \frac{1}{n}\sum\limits_i^n{y_i} \] 이 때, r은 -1 ~ 1 사이의 값을 가질 수 있고, \(x\)와 \(y\)가 완전 동일하면 1, 전혀 다르면 0, 반대 방향으로 완전 동일하면 -1 값을 가진다.

Python에서 코드를 통해 결과를 보기 위해 recommendations.py에 아래의 코드를 추가한다.

추가한 코드를 이용해, 각각의 평론가들의 피어슨 상관 계수를 구하면 아래와 같은 결과를 구할 수 있다.

>>> import recommendations as re
>>> for item in re.critics:                                                     
>>> ...     print "Lisa Rose and", item, re.sim_pearson(re.critics, "Lisa Rose", item)
...
Lisa Rose and Gene Seymour 0.396059017191
Lisa Rose and Mick LaSalle 0.594088525786
Lisa Rose and Claudia Puig 0.566946709514
Lisa Rose and Lisa Rose 1.0
Lisa Rose and Toby 0.991240707162
Lisa Rose and Michael Phillips 0.622543017479
Lisa Rose and Jack Mattheuws 0.747017880834

recommendations.py여기에서 받을 수 있다.