在本文中,通过python实现KNN算法,而非简单的调用sklearn库,并通过iris鸢尾花数据集进行训练和测试。 详情参见以下代码: if __name__ == '__main__': trainX, trainY, testX, testY=loadSplitDataSet() preY=KNN(testX) evaluateKNN()
#下载iris鸢尾花数据集 # 和切分数据集为训练集和测试集 # 训练集:trainX、trainY; # 测试集:testX、testY; def loadSplitDataSet(): #随机生成训练集和测试集 不能确定比例 iris = datasets.load_iris() randArray=np.random.randint(2,size=len(iris.data)) print(len(randArray)) trainX = iris.data[randArray==0] trainY=iris.target[randArray==0] testX = iris.data[randArray == 1] testY=iris.target[randArray == 1] return trainX, trainY, testX, testY def loadSplitDataSet(rate=0.8): iris = datasets.load_iris() #确定训练集和测试集的比例 shuffleIndex=np.random.permutation(len(iris.data)) trainSize=int(rate * len(iris.data)) trainX= iris.data[shuffleIndex[:trainSize]] trainY=iris.target[shuffleIndex[:trainSize]] testX= iris.data[shuffleIndex[trainSize:]] testY = iris.target[shuffleIndex[trainSize:]] return trainX, trainY, testX, testY
#KNN算法实现 #testX为测试样本及 # k为邻近的样本点数量 def KNN(testX,k=5): predY = [] for x in testX: # 计算样本点训练集的欧氏距离 distance = [np.sqrt(np.sum(np.power(x_train - x, 2))) for x_train in trainX] # 从小到大排序,每个数的索引位置 indexSort = np.argsort(distance) # 获得距离样本点最近的K个点的标记值y nearK_y = [trainY[i] for i in indexSort[:k]] # 统计邻近K个点标记值的数量 cntY = Counter(nearK_y) # 返回标记值最多的那个标记 y_predict = cntY.most_common(1)[0][0] predY.append(y_predict) return predY
#计算测试的准确率 def evaluateKNN(): cnt = np.sum(preY == testY) acc=np.divide(cnt,len(testX)) print("the accurate of knn:",round(acc,4))