Machine Learning in Action ch.2.1 K-NN
두번째 장에서는 k-최근접 이웃 알고리즘에 대해 공부할 것이다.
def classify0(inX, dataSet, labels, k):
dataSetSize = dataSet.shape[0]
diffMat = tile(inX, (dataSetSize,1)) - dataSet
sqDiffMat = diffMat**2 sqDistances = sqDiffMat.sum(axis=1)
distances = sqDistances**0.5
sortedDistIndicies = distances.argsort()
classCount={}
for i in range(k):
voteIlabel = labels[sortedDistIndicies[i]]
classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1 sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)
return sortedClassCount[0][0]
2. tile() : 동일한 행렬을 반복적으로 만들어 또 하나의 행렬을 만듦
ex) B = np.array([0, 1])
3. argsort() : 데이터를 정렬하려하려면 어떤 순서로 나열해야 하는지 알려주는 성수 색인이 담긴 배열을 얻고 싶을 때 사용한다.
예시를 보면 이해가 더 쉽다.
ex) val = np.arr([5,0,1,3,2])
index = val.argsort()
index
--> array([1,2,4,3,0])
val[index]
--> array([0,1,2,3,5])
4. .get() : x 라는 key에 대응되는 value를 돌려준다.
5. .sorted() : sorted라는 파이썬 내장 함수와 list 객체 내의 sort 함수가 있는데 이 둘의 차이점은 sorted는 정렬된 새로운 객체를 생성하는데 반해, list.sort() 함수는 해당 리스트 자체의 순서를 바꾸는 차이가 있다.
이 알고리즘은 분류하는 알고리즘인데 예를 들면, 영화 장르를 나누어 영화를 분류하는 것과 비슷하다고 할 수 있다.
그렇다면 어떻게 장르를 구분할 수 있는가?
영화의 장르가 로맨스라면 이성 혹은 동성간의 사랑에 대한 애틋한 장면 혹은 키스 장면들이 다른 장르보다 많을 것이다. 이와 같이 액션 영화라면 발차기가 로맨스보다 많이 나올 것이다.
이렇듯 키스나 발차기 같은 것들을 판단 기준으로 삼는다면 k-nn 알고리즘을 통해 자동적으로 장르를 분류할 수 있을 것이다.
2.1 거리 측정을 통해 분류
kNN의 동작 원리는 이렇다.
1. 기존에 훈련 집합이었던 예제 데이터 집합이 존재한다.
2. 모든 데이터는 분류 항목 표시(Labels)가 붙어 잇으며, 따라서 각각의 데이터가 어떤 분류 한복으로 구분되는지 알 수 있다.
3. 이후 분류 항복 표시가 붙어 있지 않는 새로운 데이터가 주어졌을 때, 기존의 모든 데이터와 새로운 데이터를 비교한다.
4. 그리고 가장 유사한 데이터의 분류항목 표시를 살펴본다. 이 때, 분류 항목을 이미 알고 있는 데이터 집합에서 상위 k개의 가장 유사한 데이터를 살펴보게 된다. (가까운 거리)
5. 마지막으로 k개의 가장 유사한 데이터들 중 다수결을 통해 새로운 데이터의 분류 항목을 결정하게된다.
def classify0(inX, dataSet, labels, k):
dataSetSize = dataSet.shape[0]
diffMat = tile(inX, (dataSetSize,1)) - dataSet
sqDiffMat = diffMat**2 sqDistances = sqDiffMat.sum(axis=1)
distances = sqDistances**0.5
sortedDistIndicies = distances.argsort()
classCount={}
for i in range(k):
voteIlabel = labels[sortedDistIndicies[i]]
classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1 sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)
return sortedClassCount[0][0]
위 함수는 4 가지 입력을 받는다.
1. inX : 분류를 위한 벡터
2. dataSet : 훈련을 위한 예제의 전체 행렬
3. labels : 분류 항목을 표시한 벡터
4. k : 투표에서 사용하게 될 최근접 이웃 수
1. inX : 분류를 위한 벡터
2. dataSet : 훈련을 위한 예제의 전체 행렬
3. labels : 분류 항목을 표시한 벡터
4. k : 투표에서 사용하게 될 최근접 이웃 수
위 코드에서는 3가지의 일을 한다.
1. 거리 계산 (중학교 때 배운 유클리는 거리 계산법 사용)
2. 가장 짧은 k 거리를 투표
3. 아이템 정렬
모르는 함수들
1. shape() : 배열 모양을 나타냄 ex) (2 , 4) -> 2행 4열2. tile() : 동일한 행렬을 반복적으로 만들어 또 하나의 행렬을 만듦
ex) B = np.array([0, 1])
np.tile(B, (2, 3))
array([[0, 1, 0, 1, 0, 1],
[0, 1, 0, 1, 0, 1]])
3. argsort() : 데이터를 정렬하려하려면 어떤 순서로 나열해야 하는지 알려주는 성수 색인이 담긴 배열을 얻고 싶을 때 사용한다.
예시를 보면 이해가 더 쉽다.
ex) val = np.arr([5,0,1,3,2])
index = val.argsort()
index
--> array([1,2,4,3,0])
val[index]
--> array([0,1,2,3,5])
4. .get() : x 라는 key에 대응되는 value를 돌려준다.
5. .sorted() : sorted라는 파이썬 내장 함수와 list 객체 내의 sort 함수가 있는데 이 둘의 차이점은 sorted는 정렬된 새로운 객체를 생성하는데 반해, list.sort() 함수는 해당 리스트 자체의 순서를 바꾸는 차이가 있다.
댓글
댓글 쓰기