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

PythonでKNN分類アルゴリズムを実装

この記事では、Python KNN分類アルゴリズムの具体的なコードを共有し、皆様の参考にします。具体的な内容は以下の通りです。

KNN分類アルゴリズムは、機械学習の中で最もシンプルな分類アルゴリズムの一つと考えられています。KNNとはKのことです。-最寄り傍の近隣(K個の最も近いサンプルノード)。分類を行う前にKNN分類器は、分類の参照データとして多くの分類ラベルを持つサンプルデータを読み込みます。未知のカテゴリのサンプルに対して分類を行う際には、現在のサンプルとすべての参照サンプルの差異の大きさを計算します;この差異の大きさは、データポイントがサンプルの特徴の多次元空間における距離で測定されます。つまり、2つのサンプルポイントがその特徴データの多次元空間における距離が近いほど、2つのサンプルポイントの差異は小さくなり、同じカテゴリに属する可能性が高くなります。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=[]#各サンプルのデータ情報を保存
 ラベル=[]#サンプルのラベルを保存
 while line:
 line=f.readline().strip()
 if(not line):
 
 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を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 つ近傍の地域で:
クラス: Iris-setosa カウント: 20
結果: Iris-setosa
k つ近傍の地域で:
クラス: Iris-setosa カウント: 20
結果: Iris-setosa
k つ近傍の地域で:
クラス: Iris-setosa カウント: 20
結果: Iris-setosa
k つ近傍の地域で:
クラス: Iris-setosa カウント: 20
結果: Iris-setosa
k つ近傍の地域で:
クラス: Iris-setosa カウント: 20
結果: Iris-setosa
k つ近傍の地域で:
クラス: Iris-versicolor カウント: 20
結果: Iris-versicolor
k つ近傍の地域で:
クラス: Iris-versicolor カウント: 20
結果: Iris-versicolor
k つ近傍の地域で:
クラス: Iris-versicolor カウント: 20
結果: Iris-versicolor
k つ近傍の地域で:
クラス: Iris-versicolor カウント: 20
結果: Iris-versicolor
k つ近傍の地域で:
クラス: Iris-versicolor カウント: 20
結果: Iris-versicolor
k つ近傍の地域で:
クラス: Iris-setosa カウント: 18
クラス: Iris-versicolor カウント: 2
結果: Iris-setosa
正確予測率 0。909090909091

KNNでは距離の計算方法がたくさんあります。異なる方法は異なるデータセットに適しています。このコードでは、ユラ距离とマンハッタン距離の2つの計算方法を実装しています;テストデータセットのデータは元データセットから抽出されています。データ量はそれほど多くありません。結果はKNNの性能をよく示していないため、プログラムの実行結果は参考程度にしてください。

これでこの記事のすべての内容が終わりました。皆様の学習に役立つことを願っています。また、ナイアラベクトル教程を多くのサポートをお願いします。

声明:この記事の内容はインターネットから取得しており、著作権者は所有者であり、インターネットユーザーが自発的に貢献し、アップロードしたものであり、このサイトは所有権を持ちません。また、人工編集は行われておらず、法的責任も負いません。著作権侵害が疑われる内容がある場合は、以下のメールアドレスにご連絡ください:notice#oldtoolbag.com(メールを送信する際は、#を@に変更してください。報告を行い、関連する証拠を提供してください。一旦確認がついたら、このサイトは即座に侵害疑いのコンテンツを削除します。)

おすすめ