졸업작품_preparing..../python_작업

Python 협업필터링_알고리즘2

IT grow. 2018. 12. 31. 00:21
반응형

협업필터링 알고리즘 연습2

(Collaborative filtering _ algorithm)





피타고라스 공식을 이용한 유사도도출은 2차원, 즉 비교대상이 2개로 한정되는 한계가 있다.

그렇기 때문에 실제 추천 알고리즘을 구현하고자 하는 데이터에서는 사실상 사용될 일이 없다고 할 수 있다.

 

다차원에서의 거리를 구해 비교대상이 몇 개로 늘어나든 하나의 함수로 비교할 수 있어야 하고 , 그에 따른 유사도를 구할 수 있어야 한다 .

 

다차원간 거리를 구하는 데 사용되는 공식들은 다음과 같다.

1.     Euclidean distance

2.     City-block(Manhattan) distance

3.     Minkowski distance

4.     Cosine distance

5.     Jaccard’s distance

등이 있는데 , 우리가 다뤄 볼 것은 Euclidean distance ( 유클리디안 거리공식 ) 이다.

 



유클리디안 거리 공식은 무엇인가?

(What is the Euclidian distance formula?)


유클리디안 공식

(Euclidian formula)

 


식은 위와 같다.

i번째 비교대상 아이템의 값인 (xi-yi)의 제곱을 n번째 까지 모두 구해 더한 다음 제곱근을 취하는 방식이다.

 

일단 감이 안올수 있기 때문에 , 코드를 통해서 알아보자 .

 




유클리디안 거리공식을 통한 다차원에서의 두 사람간 거리구하기

(Obtain distance between two people in multi-dimensional through Euclidian distance formula)


여기서는 , 위 공식을 distance(data, name1, name2)로 정의한다.

파라미터의 data는 협업필터링1에서 사용한 critics 딕셔너리고 , name1 name2 가 비교대상이 될 것이다.

 

이중 딕셔너리 구조이므로 critics[name] 안에서 for문이 돈다면 딕셔너리 안에 존재하는 value값인 {‘guardians of the galaxy 2’:5,’christmas in august’:4 , ‘boss baby’:1.5} 의 형태로 값이 나오고 , 여기서 다시 key값인 영화 이름을 이용해 평점을 꺼내올 수 있다.

 

이를 함수로 만들면 아래와 같다 / pow는 제곱을 구하는 메서드

 

def distance(data, name1, name2):

    sum=0

    for i in data[name1]:

        if i in data[name2]:

            sum+=pow(data[name1][i]- data[name2][i],2)

    return 1/(1+sqrt(sum))

 

if i in data[name2]

혹여나 , 같은 영화를 보지 않아 엉뚱한 값이 도출될 수 있으므로 조건문을 통해 같은 영화를 봤을 때만 합을 누적하도록 제한했다.

합을 모두 구했다면 , 피타고라스공식을 사용했을 때와 마찬가지로 정규화를 통해 변수를 일정 범위내로 재설정하고 리턴한다.

 

위 함수를 사용해 chs leb의 유사도를 구하면 다음과 같다 .

 

distance(critics,'chs','leb')

è  0.2402530733520421

 

아이템이 몇 개가 되든지간에 두 사람간 유사도를 구할 수 있게 되었다.

 




위에서 도출한 distance함수를 통해 전체 데이터에서 거리가 가장 가까운 사람 구하기

 

이제 두 사람간 유사도를 구할 수 있게 되었다.

한 단계 더 나아가 딕셔너리 전체를 돌며 유사도가 가장 비슷한 사람을 구해본다.

지금은 4명 뿐이지만 , 사람이 몇 명이 되든 적용하도록 새로운 함수를 만들어본다.

 

코드를 통해서 이해를 해보자 .

 

li=[] # li는 전역변수로써 점수와 이름을 따로 추출할 때 사용할 것이다 .

def match(data,name,index=3,distance_function=distance):

    for i in data:

        if name != i: # 자기 자신은 제외

            li.append((distance_function(data,name,i),i))

            # 유사도 , 이름을 튜플에 묶어 리스트에 추가한다 .

           

    li.reverse() # 내림차순 정렬

   

    return li[:index]


match 라는 함수를 선언해 주게 되는데 , 각 변수들을 알아보자.


data=딕셔너리 ( 영화와 이름 )

name = 기준이 될 사람

index = 몇 위까지 출력할 것인지

distance_function은 위에서 구해 놓은 distance 함수가 된다.

 

Match 함수가 작동하는 과정은 다음과 같다 .

1.     반복문을 data의 사람수만큼 돌린다.

2.     (유사도, 이름)을 튜플로 묶어 빈 리스트에 추가한다 .

출력하면 [(점수,이름),(점수,이름)..] 의 형태가 될 것이다.

3.     마지막으로 보기 쉽게 내림차순 정렬 후 파라미터로 주어진 index 숫자만큼 인덱싱하고 return 한다.

 

그리고 위에서 정의한 distance 함수에서 같은 영화를 봤을 때 라는 조건이 붙어 있기 때문에 여기서는 자기 자신만 제외하는 조건만 붙이면 된다.

 

match(critics,'chs')

è  [(0.2402530733520421, 'leb'),

è  (0.2402530733520421, 'kmh'),

è  (0.4721359549995794, 'hhd')]

 

하나의 함수로 여러 개의 아이템을 비교했고 , chs hhd의 거리가 가장 가까운 것을 확인할 수 있다.

가장 가깝다는 것은 유사도가 높다는 것을 의미한다 .

 




BARPLOT을 통한 시각화

(Visualization with BARPLOT)


이제 시각화를 위해 bar plot을 사용해볼 것이다 .

그래프를 위해서 matplotlib.pyplotimport 한 뒤 , 플롯을 그리기 위한 함수 barchart(data, labels)를 정의한다 .

여기서 x축이 유사도가 되고 , y축은 이름이 되는 bar플롯이다.

 

파라미터의 data는 점수가 들어있는 리스트고 , labels는 이름이 들어있는 리스트가 될 것이다 .


def barchart(data, labels): # data , labels list 형태로 사용

    positions = range(len(data))

    plt.barh(positions, data, height=0.5,color='r') #가로

    plt.yticks(positions, labels)

    plt.xlabel('similarity') #x

    plt.ylabel('name') #y

    plt.show #출력

 

함수를 정의했으니 , 파라미터로 들어갈 data(점수) , label(이름) 를 구해보자

 

아까 위에서 match()에서 구한 리스트를 확인해 본다 .

[(0.2402530733520421, 'leb'),

(0.2402530733520421, 'kmh'),

(0.4721359549995794, 'hhd')]

 

여기서 반복문을 통해 이름과 점수를 분리해 한다 .

0번째 인덱스를 점수로 , 1번째 인덱스를 이름으로 분리한다.

 

score = []

names = []

 

for i in li:

    score.append(i[0]) #점수를 담는다.

    names.append(i[1]) #이름을 담는다.

 

점수와 이름을 개별로 리스트 형태로 저장이 잘 되었는지 확인해 보자 .

 

score

è  [0.2402530733520421, 0.2402530733520421, 0.4721359549995794]

names

è  ['leb', 'kmh', 'hhd']

barchart(score,names)

è   

 chs와 유사도 가장높은 사람은 hhd 라는 것을 한눈에 쉽게 알 수 있다. 



반응형