在本文中,通过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))