#!/usr/bin/env python
# -*- coding: utf-8 -*-
""" @author : sword
@date : 2020/5/28
@time : 下午 14:22
@version : v1.0
@file : knn_new.py
@describe :
"""import numpy as np
import operator
defcreate_dataset()
:# 建立4個樣本,特徵矩陣為 4 * 2
group = np.array([[
1.0,
1.1],[
1.0,
1.0],[
0,0]
,[0,
0.1]])
labels =
['a'
,'a'
,'b'
,'b'
]return group, labels
defclassify
(test_x, dataset, labels, k)
:"""
:param test_x: 待測樣本的特徵向量
:param dataset: 訓練樣本集的特徵矩陣
:param labels: 訓練樣本的標籤
:param k: 前k個最近鄰
"""dataset_size = dataset.shape[0]
# 計算待測樣本test_x與每個訓練樣本的距離
# 計算每一維特徵的差值,diff_mat中每個元素表示(x1 - x2)
# 然後對diff_mat中的每個元素求平方,再按行累加再開根號得到與當前
# 樣本的距離
diff_mat = np.tile(test_x,
(dataset_size,1)
)- dataset
distance_mat =
(diff_mat **2)
.sum
(axis=1)
**0.5
# 根據距離排序,返回索引值
sorted_dist_index = distance_mat.argsort(
) class_count =
for i in
range
(k):
# 根據距離對比返回的前k個近鄰獲取其索引值
# 然後根據索引值獲取該近鄰的標籤
# 並利用字典來統計k個近鄰的標籤出現次數
vote_label = labels[sorted_dist_index[i]
] class_count[vote_label]
= class_count.get(vote_label,0)
+1# 將字典按照值進行排序,返回乙個(label, count)元組,然後返回第乙個元組對應的標籤
# 第乙個元組存放著出現次數最多的標籤
sorted_class_count =
sorted
(class_count.items(
), key=operator.itemgetter(1)
, reverse=
true
)return sorted_class_count[0]
[0]def
file_2_matrix
(path)
:"""
根據檔案路徑將檔案資訊儲存為特徵向量矩陣和標籤列表
檔案內容的格式為: 特徵1 特徵2 特徵3 標籤
大小為:(1000, 3)
"""with
open
(path,
'r')
as f:
lines = f.readlines(
)# 宣告乙個全零矩陣,用於存放特徵值
# 首先獲取該矩陣的大小,總共3列特徵
size =
len(lines)
feature_matrix = np.zeros(
(size,3)
)# 宣告乙個列表,存放標籤
label_list =
# 按行讀取資料,每一行的前3維是特徵,最後一維是標籤
# 宣告乙個變數來記錄當前是第幾行
index =
0for line in lines:
value = line.strip(
).split(
'\t'
)# 取出前3維的特徵,存放到特徵矩陣中
feature_matrix[index,:]
= value[0:
3]# 取出最後一維的標籤,存放到標籤列表中
int(value[-1
]))# 存完一行(即表示存了乙個樣本)就增加1
index +=
1return feature_matrix, label_list
defnormalize
(dataset)
:"""
將特徵值轉化為0-1區間內的值
new_value = (value - min) / (max - min)
"""# 獲取特徵矩陣中每一列的最小值和最大值
# 0表示獲取每一列的最小值
# 1表示獲取每一行的最小值
# 因為物件是特徵矩陣(1000, 3), 所以返回的min_value和max_value的大小為(1, 3)
min_value = dataset.
min(0)
max_value = dataset.
max(0)
range
= max_value - min_value
# 將特徵矩陣的每個元素都按照公式進行轉化
matirx_size = dataset.shape[0]
# 矩陣中每個元素 - min_value
feature_matirx = dataset - np.tile(min_value,
(matirx_size,1)
)# 矩陣中每個元素 / (max - min) ==> 分母相當於range
feature_matirx = feature_matirx / np.tile(
range
,(matirx_size,1)
)return feature_matirx
defpredict
(test_size=
0.1)
:"""
對測試樣本進行測試,測試樣本從資料集中的第乙個開始選取,直到滿足條件為止
這樣方便將後面的所有樣本作為訓練資料
:param test_size: 測試樣本的比例
"""# 根據檔案路徑獲取訓練資料和標籤
# 並對特徵值進行轉換
file_path =
'./data/datingtestset.txt'
train_data, train_label = file_2_matrix(file_path)
train_data = normalize(train_data)
# 獲取訓練資料的數量以及測試樣本的數量
train_data_num = train_data.shape[0]
test_num =
int(test_size * train_data_num)
# 宣告乙個變數用於記錄分類錯誤的樣本數
error_count =
0# 根據測試樣本的數量進行迴圈
# 每次取出乙個樣本進行測試
for i in
range
(test_num)
: predict_result = classify(train_data[i,:]
, train_data[test_num:train_data_num,:]
, train_label[test_num:train_data_num],3
)print
("the classifier came back with:%d, the real answer is:%d"
%(predict_result, train_label[i]))
if predict_result != train_label[i]
: error_count +=
1 accuracy =
100.*(
1-(error_count / test_num)
)print
("test accuracy is:%.2f%%"
% accuracy)
if __name__ ==
'__main__'
: file_path =
'./data/datingtestset.txt'
predict(
)
KNN簡單實現
knn算是機器學習入門演算法中比較容易理解的了,要注意和k means的一些區別 knn k means 1.knn是分類演算法 2.監督學習 3.餵給它的資料集是帶label的資料,已經是完全正確的資料 1.k means是聚類演算法 2.非監督學習 3.餵給它的資料集是無label的資料,是雜亂...
KNN(一) 簡單KNN原理及實現
原文 1.knn演算法介紹 鄰近演算法,或者說k最近鄰 knn,k nearestneighbor 分類演算法可以說是整個資料探勘分類技術中最簡單的方法了。所謂k最近鄰,就是k個最近的鄰居的意思,說的是每個樣本都可以用她最接近的k個鄰居來代表。knn演算法的核心思想是如果乙個樣本在特徵空間中的k個最...
KNN(一) 簡單KNN原理及實現
原文 1.knn演算法介紹 鄰近演算法,或者說k最近鄰 knn,k nearestneighbor 分類演算法可以說是整個資料探勘分類技術中最簡單的方法了。所謂k最近鄰,就是k個最近的鄰居的意思,說的是每個樣本都可以用她最接近的k個鄰居來代表。knn演算法的核心思想是如果乙個樣本在特徵空間中的k個最...