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時,演算法便成了最近鄰演算法,即尋找最近的那個鄰居。為何要找鄰居?打個比方來說,假設你來到乙個陌生的村莊,現在你要找到與...