KNN演算法 K 近鄰

2021-09-11 18:28:56 字數 4247 閱讀 2021

1、特點

(1)是監督學習演算法

(2)不需要訓練模型,但是如果資料龐大,時間複雜度將是o(n2)

(3)對於屬性值較大的屬性需要進行歸一化,否則該屬性將在計算距離的時候佔據主導權。

2、**

import numpy as np

import types

import pandas as pd

from collections import counter

from sklearn.metrics import accuracy_score

from sklearn.metrics import classification_report

def knn(train_set, test_set, k):

""":param train_set: [[1, 2, 3, a],[4, 5, 6, b],[7, 8, 9, c]....], 陣列格式

:param test_set: [[10, 11, 12], [13, 14, 15]],陣列格式

:param k: 為test_set中的每乙個物件選擇k個最近的鄰居

:return: 根據投票原則為test_set中的每乙個物件**分類,返回predict_label_list

"""# train_set和test_set必須是陣列

if isinstance(train_set, list):

train_set = np.array(train_set)

if isinstance(test_set, list):

test_set = np.array(test_set)

# 得到訓練資料集中的標籤列表

labels = train_set[:, -1]

print('labels: \n', len(labels))

# 過濾掉訓練資料集中的標籤方便計算距離

# 因為標籤可能是字元資料,所以導致整個陣列的資料格式都是字元,所以切片後需要轉化資料格式為float

print(train_set[:, :-1])

train_set = train_set[:, :-1].astype(np.float)

test_set = test_set.astype(np.float)

# 因為第一列的資料值太大,它會佔據距離計算的主導權,但是每個屬性是平等的,所以必須進行歸一化處理

train_set = normalization_process(train_set)

test_set = normalization_process(test_set)

# print('train_set: \n', train_set)

# 計算test_set中的每乙個物件到train_set中每個物件的距離

# predict_label = 儲存**結果

predict_label_list =

for test_obj in test_set:

# print('test_obj: \n', test_obj)

dist_list =

dist_lab = {}

for train_obj in train_set:

# print('train_obj: \n', train_obj)

temp = (test_obj - train_obj)**2

# print('temp: \n', temp)

distance = (np.sum(temp, axis=0))**0.5

# 以的格式生成字典,方便篩選k個最近鄰

# print('dist_list: \n', len(dist_list))

for i in range(len(labels)):

dist_lab[dist_list[i]] = labels[i]

# sorted()返回的是排序後的key列表, 預設從小到大排序

key_list = sorted(dist_lab)

# 根據排序後的key列表得到相應的標籤列表

label_list =

for i in key_list:

# 擷取前k個標籤

label_list = label_list[:k]

# counter方法可以快速得到列表中某個出現次數最多的值

max_fre_label = counter(label_list).most_common(1)[0][0]

return predict_label_list

def process_text_data(file_path, fea_num):

""":param file_path: 檔案路徑

:param fea_num: 屬性的個數

:return: 由文字資料得到的訓練陣列

"""try:

f = open(file_path)

try:

data = f.readlines()

# 得到文字資料的行數

row_num = len(data)

# 初始化乙個值全為0的陣列,用來儲存文字資料

# 因為最後一列是標籤屬於字串格式,所以初始化的陣列中的資料必須也是字串格式

# 否則沒辦法賦值

return_array = np.zeros((row_num, fea_num)).astype(str)

index = 0

for line in data:

# 去掉字串首尾的換行符、空白符、製表符(\t),總之去掉首尾的空白

line = line.strip()

# 按製表符(\t)劃分每行資料的list

line_list = line.split('\t')

return_array[index, :] = line_list

index += 1

return return_array

finally:

f.close()

except ioerror as e:

print('error: \n' + str(e))

# 歸一化處理

def normalization_process(data_set):

""":param data_set: 輸入乙個陣列或者dataframe

:return: 返回歸一化之後的陣列

"""if type(data_set) is not types.frametype:

data_set = pd.dataframe(data_set)

data_set = (data_set - data_set.min())/(data_set.max() - data_set.min())

data_set = np.array(data_set)

return data_set

if __name__ == '__main__':

# 得到文字資料陣列

file_pth = 'f:/machinelearning/ml_chapter2/datingtestset.txt'

data_array = process_text_data(file_pth, 4)

print('data_array: \n', data_array)

# 得到訓練集和測試集

from random import shuffle

shuffle(data_array)

train_set = data_array[:int(len(data_array)*0.8), :]

test_set = data_array[int(len(data_array)*0.8):, :]

test_set = test_set[:, :-1]

test_labels = test_set[:, -1]

# **

predict_result = knn(train_set, test_set, 100)

print('result: \n', predict_result)

# 計算準確率

accu = accuracy_score(test_labels, predict_result)

print('accu: \n', accu)

# 生成結果報告

# report = classification_report(test_labels, predict_result)

# print('report: \n', report)

K 近鄰演算法 KNN

knn k nearest neighbor 假設訓練集有記錄 r1 r2,rn共n條,訓練集的特徵向量及其對應的類別都是已知的,每個記錄的特徵向量為 t1 t2,tk共k個特徵,待測試的記錄為ru 1 計算ru 的特徵向量與訓練集的每條記錄 即r1 r2,rn 的特徵向量的歐式距離,選取距離最小的...

k近鄰演算法 kNN

核心思想 前k個最相似資料中出現次數最多的類別,作為新資料的類別。核心函式 計算距離函式,投票函式 coding utf 8 import random import sys from collections import counter from operator import itemgette...

K近鄰演算法 KNN

k近鄰演算法 knn 何謂k近鄰演算法,即k nearest neighbor algorithm,簡稱knn演算法,單從名字來猜想,可以簡單粗暴的認為是 k個最近的鄰居,當k 1時,演算法便成了最近鄰演算法,即尋找最近的那個鄰居。為何要找鄰居?打個比方來說,假設你來到乙個陌生的村莊,現在你要找到與...