用最簡單的資料分類例子實現KNN演算法

2021-09-14 03:37:34 字數 2757 閱讀 4001

k-鄰近演算法(knn)的工作原理是:已知乙個帶標籤的已分類資料集合,輸入未分類的新資料之後,計算新資料到資料集中的每個資料的歐幾里得距離,篩選出前k個最近的點,選擇這k個點**現次數最多的分類,即作為新資料的分類標籤

問題描述:已知4個帶標籤的座標點a1(1.0,1.1),a2(1.0,1.0),b1(0.0,0.0),b2(0.0,0.1),輸入乙個新資料後,輸出它是屬於a類還是b類

實現流程:

1、匯入數值計算庫numpy和備胎模組opetator

#knn.py

from numpy import *

import operator

2、建立帶標籤的資料,之後直接呼叫這個方法就能返回我們的資料集

#用於建立資料

def create_data_set():

group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])

labels = ['a','a','b','b']

return group, labels

3、knn演算法的核心實現

def classify0(in_x, data_set, labels, k):

data_set_size = data_set.shape[0]#獲取陣列的第一維度的維數,即獲取資料量

diff_mat = tile(in_x, (data_set_size,1)) - data_set#計算距離,首先獲取座標差

sq_diff_mat = diff_mat**2#對座標差進行分別平方

sq_distances = sq_diff_mat.sum(axis=1)

distances = sq_distances**0.5

sorted_dist_index = distances.argsort()

class_count={}#建立乙個字典

for i in range(k):

vote_i_label = labels[sorted_dist_index[i]]

class_count[vote_i_label] = class_count.get(vote_i_label,0)+1

sorted_class_count = sorted(class_count.items(), key=operator.itemgetter(1),reverse=true)

return sorted_class_count[0][0]

**筆記:a.shape(0)函式獲取陣列a的第乙個維度,常常用於計算資料量

tile(a,3)函式將a重複3次,若第二個引數輸入的是陣列的形式,如tile(a,(3,2)),那就是生成一樣的三組,每組都兩個a這樣

命名規範上,python方法名和變數名都是小寫,單詞之間用下劃線分隔開來

書寫習慣上,運算子+-*/=左右都加乙個空格(若=在方法的引數列表中則不加,後面如果是字元加乙個空格(若是數字則不加)

計算歐幾里得距離的處理方法也太高效簡潔了。把輸入資料重複四次,四個資料點合併成矩陣處理,之後減去帶標籤的原來那四個點,然後對結果矩陣中的每個元素進行分別做平方運算 ,sum(a,axis=1)對矩陣a的行向量進行相加合併,axis=0則會對列向量進行相加合併;計算行向量的和的結果之後開根號計算距離

.argsort()函式獲取排序序列,它會比較陣列中的元素,將其從小到大做乙個排序,提取其對應的index(索引),然後返回此索引排序結果

for i in range(k):迴圈處理 i的值0~(k-1)

python中的花括號{}代表dict字典資料型別,字典是python中的對映型別,由鍵值對組成,沒有特殊的順序;使用.get(a,0) 函式返回指定鍵a的值,如果值不在字典中返回預設值,第二個引數表示我設定的預設值是0;使用.items()方法獲取字典中所有項(仍然是無序的)

sorted函式,第乙個引數表示要排序的列表主體,第二個引數key表示排序的標桿,第三個引數reverse為true的話表示要逆序成從大到小進行排列。sorted函式以陣列的形式返回排好的序列,(陣列是有序的,列表是無序的),所以後續可以用index索引的方式獲取想要的資訊

使用operator模組的itemgetter(0)方法 ,獲取鍵值對的第1個值

測試**:

在命令列中切換到knn.py檔案所在目錄並進入python開發環境。匯入knn.py檔案後首先呼叫create_data_set方法建立帶標籤的資料集,接著呼叫classify0方法,引數依次為要測試的資料、資料集及其標籤、設定的k值,在**無誤的情況下就能獲取測試資料的分類了

bug記錄:

在呼叫classify0方法的時候遇到過第30行object is not iterable的報錯資訊,隨即想起在operator模組的學習資料裡描述過,它常見於使用在某些迭代器中被呼叫。那報錯的原因就應該是operator的作用物件是不可迭代的,檢查發現果然是在對字典資料型別呼叫items()方法獲取其列表時寫錯了

tensoflow實現最簡單的分類

import numpy as np import tensorflow as tf import random import pickle from collections import counter import nltk from nltk.tokenize import word toke...

redis 收發資料最簡單的例子

首先第一步鏈結redis rediscontext context redisconnect 127.0.0.1 6379 if context err 第二和第三步可以不寫 2 校驗密碼 char auth test123 redisreply reply redisreply rediscomm...

資料庫的最簡單實現

所有應用軟體之中,資料庫可能是最複雜的。mysql的手冊有3000多頁,postgresql的手冊有2000多頁,oracle的手冊更是比它們相加還要厚。但是,自己寫乙個最簡單的資料庫,做起來並不難。reddit上面有乙個帖子,只用了幾百個字,就把原理講清楚了。下面是我根據這個帖子整理的內容。第一步...