English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Python으로 KNN 분류 알고리즘 구현

이 문서는 Python KNN 분류 알고리즘의 구체적인 코드를 공유하여 참고하게 합니다.

KNN 분류 알고리즘은 기계 학습에서 가장 간단한 분류 알고리즘 중 하나로 간주될 수 있습니다. KNN는 K로 알려져 있습니다.-가장 가까운 이웃(최대 K개의 가까운 이웃 노드). 분류 전에 KNN 분류기는 분류 참조 데이터로 사용할 수 있는 많은 수의 표본 데이터를 읽습니다. 그런 다음, 그것이 카테고리가 불명확한 표본을 분류할 때, 현재 표본과 모든 참조 표본 간의 차이 크기를 계산합니다. 이 차이 크기는 데이터 포인트가 표본 특성의 다중 차원 공간에서의 거리로 측정됩니다. 다시 말해, 두 표본 포인트가 그들의 특성 데이터의 다중 차원 공간에서의 거리가 더 가까울수록, 이 두 표본 포인트 간의 차이가 더 작아지고, 이 두 표본 포인트가 같은 카테고리에 속할 가능성이 더 큽니다. KNN 분류 알고리즘은 이 기본적인 인식을 활용하여, 예측 표본 포인트와 참조 표본 공간의 모든 표본 간의 거리를 계산하고, 가장 가까운 K개의 참조 표본 포인트를 찾아, 가장 가까운 K개의 표본 포인트 중에서 가장 많이 차지하는 카테고리를 통계적으로 계산하여, 이 카테고리를 예측 결과로 사용합니다.

KNN 모델은 매우 간단하며, 모델 훈련을 포함하지 않습니다. 예측할 때마다 모든 알려진 데이터 포인트와의 거리를 계산해야 하므로, 참조 샘플 셋의 수가 증가함에 따라 KNN 분류기의 계산 비용도 비례적으로 증가합니다. 또한 KNN는 샘플이 적은 샘플 셋에 적합하지 않습니다. 그리고 KNN가 제안된 이후로 많은 사람들이 여러 개선 알고리즘을 제안했습니다. 이들은 알고리즘 속도와 정확성을 향상시키기 위해 제안되었습니다. 그러나 모두 '근접한 것은 유사할 가능성이 크다'는 원칙에 기반하고 있습니다. 여기서는 Python을 사용하여 KNN의 가장 원래 버전의 알고리즘을 구현했습니다. 데이터셋은 인공지능 학습 과정에서 매우 많이 사용되는莺尾花 데이터셋을 사용했으며, 또한 원본 데이터셋에 소량의 잡음 데이터를 추가하여 KNN 알고리즘의 견고성을 테스트했습니다.

데이터셋은莺尾花 데이터셋을 사용하고 있습니다다운로드 링크.

데이터셋은 포함하고 있습니다90개의 데이터(훈련 데이터), 그 중2개의 분류, 각 분류45개의 데이터, 각 데이터4개의 속성 

Sepal.Length(꽃萼 길이), 단위는 cm입니다;
Sepal.Width(꽃萼 너비), 단위는 cm입니다;
Petal.Length(백합 꽃잎 길이), 단위는 cm입니다;
Petal.Width(백합 꽃잎 너비), 단위는 cm입니다;

분류 종류: Iris Setosa(산鸢尾), Iris Versicolour(杂色鸢尾)
이전에는 C를 주로 사용했습니다++최근에 배운 Python을 이용해 KNN를 구현해보려고 하고, 아래 코드를 올립니다:

#coding=utf-8
import math
#定义鸢尾花的数据类
class Iris:
 data=[]
 label=[]
 pass
#定义一个读取莺尾花数据集的函数
def load_dataset(filename="Iris_train.txt"):
 f=open(filename)
 line=f.readline().strip()
 propty=line.split(',')#属性名
 dataset=[]#保存每一个样本的数据信息
 label=[]#保存样本的标签
 while line:
 line=f.readline().strip()
 if(not line):
 break
 temp=line.split(',')
 content=[
 for i in temp[0:-1]:
 content.append(float(i))
 dataset.append(content)
 label.append(temp[-1])
 total=Iris()
 total.data=dataset
 total.label=label
 return total # 데이터셋 반환
# Knn 분류기 클래스 정의
class KnnClassifier:
 def __init__(self,k,type="Euler"): # 초기화할 때 정수 K와 거리 계산 방식을 정의
 self.k=k
 self.type=type
 self.dataloaded=False
 def load_traindata(self,traindata): # 데이터셋 로드
 self.data=traindata.data
 self.label=traindata.label
 self.label_set=set(traindata.label)
 self.dataloaded=True # 데이터셋을 로드한지 여부 표시
 def Euler_dist(self,x,y): # 유라리거리 계산 방식, x, y는 벡터입니다
 sum=0
 for i,j in zip(x,y):
 sum+=math.sqrt((i-j)**2)
 return sum
 def Manhattan_dist(self,x,y): # 맨해튼 거리 계산 방식, x, y는 벡터입니다
 sum=0
 for i,j in zip(x,y):
 sum+=abs(i-j)
 return sum
 def predict(self,temp): # 예측 함수, 예측 샘플 데이터를 읽어들이는 temp은 벡터입니다
 if(not self.dataloaded): # 훈련 데이터가 있는지 확인
 print "No train_data load in"
 return
 distance_and_label=[]
 if(self.type=="Euler"): # 판단 거리 계산 방식, 유라리거리 또는 맨해튼 거리
 for i,j in zip(self.data,self.label):
 dist=self.Euler_dist(temp,i)
 distance_and_label.append([dist,j])
 else:
 if(self.type=="Manhattan"):
 for i,j in zip(self.data,self.label):
 dist=self.Manhattan_dist(temp,i)
 distance_and_label.append([dist,j])
 else:
 print "type choice error"
 #K개 가장 가까운 샘플의 거리와 분류 레이블을 가져옵니다
 neighborhood=sorted(distance_and_label,cmp=lambda x,y : cmp(x[0],y[0]))[0:self.k]
 neighborhood_class=[]
 for i in neighborhood:
 neighborhood_class.append(i[1])
 class_set=set(neighborhood_class)
 neighborhood_class_count=[]
 print "In k nearest neighborhoods:")
 #이 K개 가장 가까운 점 중 각 분류의 개수를 계산
 for i in class_set:
 a=neighborhood_class.count(i)
 neighborhood_class_count.append([i,a])
 print "class: ",i," count: ",a
 result=sorted(neighborhood_class_count,cmp=lambda x,y : cmp(x[1],y[1))[-1][0]
 print "result: ",result
 return result#예측된 분류를 반환
if __name__ == '__main__':
 traindata=load_dataset()#training data
 testdata=load_dataset("Iris_test.txt")#testing data
 #Knn 분류器的 K를 새로운 Knn 분류자를 생성20, 기본적으로 유라리아 거리 계산 방식
 kc=KnnClassifier(20)
 kc.load_traindata(traindata)
 predict_result=[]
 #예측 테스트 데이터 testdata에 있는 모든 예측 가능한 샘플의 결과
 for i,j in zip(testdata.data,testdata.label):
 predict_result.append([i,kc.predict(i),j])
 correct_count=0
 #예측 결과와 정확한 결과를 비교하여 이번 예측의 정확률을 계산
 for i in predict_result:
 if(i[1==i[2]:
 correct_count+=1
 ratio=float(correct_count)/len(predict_result)
 print "정확 예측 비율", ratio

시험 데이터에서11개의 시험 샘플 포인트의 분류 결과:

k 가까운 인접 지역에서:
클래스: 아이리스-셋오사 카운트: 20
결과: 아이리스-셋오사
k 가까운 인접 지역에서:
클래스: 아이리스-셋오사 카운트: 20
결과: 아이리스-셋오사
k 가까운 인접 지역에서:
클래스: 아이리스-셋오사 카운트: 20
결과: 아이리스-셋오사
k 가까운 인접 지역에서:
클래스: 아이리스-셋오사 카운트: 20
결과: 아이리스-셋오사
k 가까운 인접 지역에서:
클래스: 아이리스-셋오사 카운트: 20
결과: 아이리스-셋오사
k 가까운 인접 지역에서:
클래스: 아이리스-버스콜러 카운트: 20
결과: 아이리스-버스콜러
k 가까운 인접 지역에서:
클래스: 아이리스-버스콜러 카운트: 20
결과: 아이리스-버스콜러
k 가까운 인접 지역에서:
클래스: 아이리스-버스콜러 카운트: 20
결과: 아이리스-버스콜러
k 가까운 인접 지역에서:
클래스: 아이리스-버스콜러 카운트: 20
결과: 아이리스-버스콜러
k 가까운 인접 지역에서:
클래스: 아이리스-버스콜러 카운트: 20
결과: 아이리스-버스콜러
k 가까운 인접 지역에서:
클래스: 아이리스-셋오사 카운트: 18
클래스: 아이리스-버스콜러 카운트: 2
결과: 아이리스-셋오사
정확 예측 비율 0.909090909091

KNN에서 거리 계산 방법이 많이 있으며, 다른 방법은 다른 데이터 세트에 적용됩니다. 이 코드는 오일러 거리와 맨해튼 거리 두 가지 계산 방식만 구현했습니다. 테스트 데이터는 원 데이터 세트에서 추출된 것이며, 데이터량이 많지 않기 때문에 결과는 KNN의 성능을 잘 반영하지 못합니다. 따라서 프로그램 실행 결과는 참고만 하세요.

이것이 이 문서의 전체 내용입니다. 많은 도움이 되었기를 바랍니다. 또한, 나는呐喊 튜토리얼을 많이 지지해 주셔서 감사합니다.

성명: 이 문서의 내용은 인터넷에서 가져왔으며, 저작권자에게 속하며, 인터넷 사용자가 자발적으로 기여하고 자체로 업로드한 내용입니다. 이 사이트는 소유권을 가지지 않으며, 인공 편집을하지 않았으며, 관련 법적 책임을 부담하지 않습니다. 저작권 문제가 있는 내용을 발견하면, notice#w로 이메일을 보내 주세요.3codebox.com(보고할 때는 #을 @으로 변경하십시오. 관련 증거를 제공하고, 실제로 확인되면, 이 사이트는 즉시 의심스러운 저작권 내용을 제거합니다。)

당신이 좋아할 수 있는