机器学习-kNN算法
Posted fierydragon
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了机器学习-kNN算法相关的知识,希望对你有一定的参考价值。
1、前沿
K最近邻(k-Nearest Neighbor,KNN)分类算法可以说是最简单的机器学习算法了。它采用测量不同特征值之间的距离方法进行分类。它的思想很简单:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。
选择k个最相似数据中出现次数最多的分类。其算法描述如下:
K-近邻算法的一般流程
(1): 收集数据:提供文本文件
(2):准备数据:使用 Python 分析文本文件
(3):分析数据:使用 Matplotlib 画二维扩散图。
(4):测试算法:使用文本文件的部分数据作为测试样本,计算错误率。
(5):使用算法:错误率在可接受范围内,就可以运行k-近邻算法进行分类。
理解可参考大神博客:https://blog.csdn.net/zouxy09/article/details/16955347
2、kNN基础实践
from numpy import *
def createDataSet(): group = array([[0, 0], [0, 0.1], [1.0, 1.1], [1.0, 1.0]]) labels = [‘A‘, ‘A‘, ‘B‘, ‘B‘] return group, labels def kNNClassify(newInput, dataSet, labels, k): numSamples = dataSet.shape[0] diff = tile(newInput, (numSamples, 1)) - dataSet squaredDiff = diff ** 2 squaredDist = sum(squaredDiff, axis=1) distance = squaredDist ** 0.5 sortedDistIndices = argsort(distance) # 给出每个点在列表中大小的排列 例如:列表[7,9,5,10],结果为[1,2,0,3] classCount = {} for i in range(k): voteLabel = labels[sortedDistIndices[i]] classCount[voteLabel] = classCount.get(voteLabel, 0) + 1 # 如果能够取到那么便加 1,如果取不到便为 0。 maxCount = 0 for key, value in classCount.items(): if value > maxCount: maxCount = value maxIndex = key return maxIndex if __name__ == ‘__main__‘: dataSet, labels = createDataSet() testX = array([1.2, 1.0]) k = 3 outputLabel = kNNClassify(testX, dataSet, labels, k) print(outputLabel)
# 自行理解基础,挺简单的。
3、根据网上修改凯伦约会网站
import numpy as np
import matplotlib.pyplot as plt
"""
准备数据 大神博客:https://www.cnblogs.com/asialee/p/9307337.html
"""
def file2matrix(filename):
with open(filename, ‘r‘) as f:
array_lines = f.readlines()
number_lines = len(array_lines)
return_mat = np.zeros((number_lines, 3))
# 返回的分类标签向量
class_label_vector = []
index = 0
for line in array_lines:
line = line.strip()
list_from_line = line.split(‘ ‘)
# 将数据前三列提取出来,存放到return_mat的NumPy矩阵中,也就是特征矩阵
return_mat[index, :] = list_from_line[0:3]
# 根据文本中标记的喜欢程度进行分类,1代表不喜欢。2代表魅力一般。3代表急剧魅力。
if list_from_line[-1] == ‘didntLike‘:
class_label_vector.append(1)
elif list_from_line[-1] == ‘smallDoses‘:
class_label_vector.append(2)
elif list_from_line[-1] == ‘largeDoses‘:
class_label_vector.append(3)
index += 1
return return_mat, class_label_vector
"""
分析数据,数据可视化,使用 Matplotlib 创建散点图
"""
def show_data(return_mat, class_label_vector):
fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(return_mat[:, 1], return_mat[:, 2], 15.0 * np.array(class_label_vector),
15.0 * np.array(class_label_vector))
plt.show()
"""
准备数据:归一化数值。
因为四组数据中,获取的飞行常客里程数对于计算结果影响远远大于其他两个特征,但这三个特征是同等重要的,
因此作为三个等权重的特征之一,飞行常客里程数并不该如此严重的影响到计算结果。因此我们通常采用的方法是数值归一化,将取值范围
处理为0到1之间。
new_value = (old_value-min)/(max-min)
"""
def auto_norm(data_set):
# 获得每列数据的最小值和最大值
min_value = data_set.min(0)
max_value = data_set.max(0)
# 最大值和最小值的范围
ranges = max_value - min_value
m = data_set.shape[0]
# 原始值减去最小值
norm_data_set = data_set - np.tile(min_value, (m, 1))
# 除以最大和最小值的差,得到归一化数据
norm_data_set = norm_data_set / np.tile(ranges, (m, 1))
# 返回归一化数据结果,数据范围,最小值
return norm_data_set, ranges, min_value
"""
KNN算法分类器
in_x:用于分类的数据(测试集)。
data_set:用于训练的数据(训练集)。
labels:训练数据的分类标签。
k :kNN算法参数,选择距离最小的 k 个点。
sorted_class_count[0][0] 分类结果。
"""
def knn_classify(in_x, data_set, labels, k):
data_set_size = data_set.shape[0]
diff_mat = np.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_indices = distances.argsort()
class_count = {}
for i in range(k):
vote_label = labels[sorted_dist_indices[i]]
class_count[vote_label] = class_count.get(vote_label, 0) + 1 # 如果能够取到那么便加 1,如果取不到便为 0。
max_count = 0
for key, value in class_count.items():
if value > max_count:
max_count = value
max_index = key
return max_index
"""
测试算法,计算分类器的准确率,验证分类器
"""
def dating_class_test():
file_name = ‘F:KNN-masterdatingTestSet.txt‘
dating_data_mat, dating_labels = file2matrix(file_name)
ho_ratio = 0.1
norm_data_set, ranges, min_value = auto_norm(dating_data_mat)
m = norm_data_set.shape[0]
num_test_vec = int(m * ho_ratio)
error_count = 0.0
for i in range(num_test_vec):
class_fire_result = knn_classify(norm_data_set[i, :], norm_data_set[num_test_vec:m, :],
dating_labels[num_test_vec:m], 4)
print(‘分类结果:%d 真实类别:%d‘ % (class_fire_result, dating_labels[i]))
if class_fire_result != dating_labels[i]:
error_count += 1.0
print(‘错误率:%f%%‘ % (error_count / float(num_test_vec * 100)))
"""
使用算法,构建完整可用系统
"""
def classify_person():
# 输出结果
result_list = [‘不喜欢‘, ‘有些喜欢‘, ‘非常喜欢‘]
# 三维特征用户输入
f_miles = float(input(‘每年飞行常客里程数:‘))
percent_game = float(input(‘玩游戏所消耗时间百分比:‘))
ice_cream = float(input(‘每周消费的冰淇淋公升数:‘))
file_name = ‘F:KNN-masterdatingTestSet.txt‘
dating_data_mat, dating_labels = file2matrix(file_name)
norm_data_set, ranges, min_value = auto_norm(dating_data_mat)
in_arr = np.array([f_miles, percent_game, ice_cream])
# 测试集归一化
nor_min_arr = (in_arr - min_value) / ranges
classifier_result = knn_classify(nor_min_arr, norm_data_set, dating_labels, 3)
print("你可能%s这个人" % (result_list[classifier_result - 1]))
if __name__ == ‘__main__‘:
return_mat, class_label_vector = file2matrix(‘F:KNN-masterdatingTestSet.txt‘)
show_data(return_mat, class_label_vector)
dating_class_test()
classify_person()
kNN算法实现起来还是可以实现的,数据集大神博客有连接的可自行去下载。
以上是关于机器学习-kNN算法的主要内容,如果未能解决你的问题,请参考以下文章
机器学习实战☛k-近邻算法(K-Nearest Neighbor, KNN)
以❤️简单易懂❤️的语言带你搞懂有监督学习算法附Python代码详解机器学习系列之KNN篇