From f24648a40f89638684274e5d18486c59544bfd68 Mon Sep 17 00:00:00 2001 From: jcong Date: Tue, 22 Oct 2019 19:03:48 +0800 Subject: [PATCH] knn: fix incorrect label updating in building kdtree Change-Id: I74740ae3ad13c2aede8e752e7dfbf2ece0d1bbc1 --- knn/KNN.ipynb | 75 ++++++++++++++++++++++++++++++++--------------- knn/knn_kdtree.py | 20 ++++++++----- 2 files changed, 64 insertions(+), 31 deletions(-) diff --git a/knn/KNN.ipynb b/knn/KNN.ipynb index 53677eb..750a14c 100644 --- a/knn/KNN.ipynb +++ b/knn/KNN.ipynb @@ -73,22 +73,22 @@ "name": "stdout", "output_type": "stream", "text": [ - "model = knn, dataNum = 30, takeTime = 0.00391\n", - "model = kdtree, dataNum = 30, takeTime = 0.00417\n", - "model = knn, dataNum = 500, takeTime = 0.03806\n", - "model = kdtree, dataNum = 500, takeTime = 0.00856\n", - "model = knn, dataNum = 1000, takeTime = 0.05203\n", - "model = kdtree, dataNum = 1000, takeTime = 0.01386\n", - "model = knn, dataNum = 2000, takeTime = 0.1387\n", - "model = kdtree, dataNum = 2000, takeTime = 0.02863\n", - "model = knn, dataNum = 5000, takeTime = 0.28177\n", - "model = kdtree, dataNum = 5000, takeTime = 0.07277\n", - "model = knn, dataNum = 10000, takeTime = 0.47404\n", - "model = kdtree, dataNum = 10000, takeTime = 0.16433\n", - "model = knn, dataNum = 50000, takeTime = 2.0887\n", - "model = kdtree, dataNum = 50000, takeTime = 0.93545\n", - "model = knn, dataNum = 400000, takeTime = 16.82156\n", - "model = kdtree, dataNum = 400000, takeTime = 11.85994\n" + "model = knn, dataNum = 30, takeTime = 0.001\n", + "model = kdtree, dataNum = 30, takeTime = 0.00201\n", + "model = knn, dataNum = 500, takeTime = 0.02202\n", + "model = kdtree, dataNum = 500, takeTime = 0.008\n", + "model = knn, dataNum = 1000, takeTime = 0.035\n", + "model = kdtree, dataNum = 1000, takeTime = 0.013\n", + "model = knn, dataNum = 2000, takeTime = 0.067\n", + "model = kdtree, dataNum = 2000, takeTime = 0.02404\n", + "model = knn, dataNum = 5000, takeTime = 0.18897\n", + "model = kdtree, dataNum = 5000, takeTime = 0.05904\n", + "model = knn, dataNum = 10000, takeTime = 0.3523\n", + "model = kdtree, dataNum = 10000, takeTime = 0.13304\n", + "model = knn, dataNum = 50000, takeTime = 1.77306\n", + "model = kdtree, dataNum = 50000, takeTime = 0.83014\n", + "model = knn, dataNum = 400000, takeTime = 13.71175\n", + "model = kdtree, dataNum = 400000, takeTime = 10.00363\n" ] } ], @@ -111,19 +111,21 @@ "name": "stdout", "output_type": "stream", "text": [ - "\n", - "\n", - "\n" + "\n", + "\n", + "\n" ] }, { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ - "" + "
" ] }, - "metadata": {}, + "metadata": { + "needs_background": "light" + }, "output_type": "display_data" } ], @@ -134,6 +136,33 @@ "plot_knn_predict(model, dataList[0], labelList[0], point)" ] }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.9666666666666667" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# verify\n", + "iris = load_iris()\n", + "iris_data = iris.data\n", + "iris_label = iris.target\n", + "X_train, X_test, y_train, y_test = train_test_split(iris_data, iris_label, test_size=0.2)\n", + "model = KNNKdTree()\n", + "model.fit(X_train, y_train)\n", + "model.score(X_test, y_test)" + ] + }, { "cell_type": "code", "execution_count": null, @@ -158,7 +187,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.4" + "version": "3.7.1" } }, "nbformat": 4, diff --git a/knn/knn_kdtree.py b/knn/knn_kdtree.py index e2506c2..a59a846 100644 --- a/knn/knn_kdtree.py +++ b/knn/knn_kdtree.py @@ -20,21 +20,25 @@ def __init__(self, dataSet, label): self.KdTree = None self.n = 0 self.nearest = None - self.create(dataSet, label) + label = np.reshape(label, (len(label), 1)) + # the last column of combined data set is label + combDataSet = np.concatenate((dataSet, label), axis=1) + self.create(combDataSet) # 建立kdtree - def create(self, dataSet, label, depth=0): - if len(dataSet) > 0: - m, n = np.shape(dataSet) + def create(self, data, depth=0): + if len(data) > 0: + m, n = np.shape(data) + n -= 1 self.n = n axis = depth % self.n mid = int(m / 2) - dataSetcopy = sorted(dataSet, key=lambda x: x[axis]) - node = Node(dataSetcopy[mid], label[mid], depth) + dataSorted = sorted(data, key=lambda x: x[axis]) + node = Node(dataSorted[mid][:-1], dataSorted[mid][-1], depth) if depth == 0: self.KdTree = node - node.lchild = self.create(dataSetcopy[:mid], label, depth+1) - node.rchild = self.create(dataSetcopy[mid+1:], label, depth+1) + node.lchild = self.create(dataSorted[:mid], depth+1) + node.rchild = self.create(dataSorted[mid+1:], depth+1) return node return None