用python建立kd树,然后实现knn算法,数据集为白酒品质
机器学习课程第二次作业part1,程序借鉴了很多别人的内容,自己目前还是个菜鸡,入门机器学习,道阻且长!
白酒数据集下载地址
(不知道为什么正确率很低,无奈~~)
import numpy as np
import pandas as pd
from random import *
from sklearn.model_selection import train_test_split
import time
class Node(object):
def __init__(self, values=None, label=None, split=None, parent=None, left_child=None, right_child=None):
self.values = values # 结点值
self.label = label # 结点标签
self.split = split # 进行分割的维度
self.parent = parent # 父节点
self.left_child = left_child # 左子树
self.right_child = right_child # 右子树
class Kd_Tree(object):
def __init__(self, values, labels):
self.__length = 0 #kd树结点的数目
self.root = self.__create(values, labels) # kd树的结点
def __create(self, values, labels, parent = None): # 建树
m, n = values.shape #m为行数(样本数目),n为列数(特征数目)
labels = labels.reshape(m, 1)
if m == 0:
return None # 空(子)树
var_list = [np.var(values[:, column]) for column in range(n)] # 计算每一列的方差
pos = var_list.index(max(var_list)) # 找到方差最大的列的下标,作为分割的维度
index_list = values[:, pos].argsort() # 获得将该列的特征值升序排列的下标序列
median = index_list[m//2] # 找到中位数的下标
if m ==1:
self.__length += 1
return Node(values=values[median], label=labels[median], split=pos,
parent=parent, left_child=None, right_child=None) # 样本数为1时,返回自身
node = Node(values=values[median], label=labels[median], split=pos,
parent=parent, left_child=None, right_child=None) #生成一个结点
# 建立有序的子树
left_tree_values = values[index_list[:m//2]] # 左子树的所有值
left_tree_labels = labels[index_list[:m//2]] # 左子树的所有标签
left_child = self.__create(left_tree_values, left_tree_labels, node)
if m == 2:
right_child = None #只有左子树,没有右子树
else:
right_tree_values = values[index_list[m//2+1:]] # 右子树的所有值
right_tree_labels = labels[index_list[m//2+1:]] # 右子树的所有标签
right_child = self.__create(right_tree_values, right_tree_labels, node)
# 左右子树递归调用自己,返回子树的根结点
node.left_child = left_child
node.right_child = right_child
self.__length += 1
return node
def transfer_list(self, root_node, kd_list=[]):
# 将kd树存储的信息放入一个列表中嵌套字典的列表中
if root_node