From 53c89eb3a19d8299f9fd4c1b2926d1d731973feb Mon Sep 17 00:00:00 2001 From: bushuhui Date: Thu, 16 Dec 2021 19:03:42 +0800 Subject: [PATCH] Improve knn classification --- 2_knn/knn_classification.ipynb | 70 ++++++++++++++++++++++++----------------- 2_knn/knn_test_data.pdf | Bin 0 -> 9022 bytes 2_knn/knn_train_data.pdf | Bin 0 -> 10374 bytes 3 files changed, 41 insertions(+), 29 deletions(-) create mode 100644 2_knn/knn_test_data.pdf create mode 100644 2_knn/knn_train_data.pdf diff --git a/2_knn/knn_classification.ipynb b/2_knn/knn_classification.ipynb index 686830d..ae6ea5d 100644 --- a/2_knn/knn_classification.ipynb +++ b/2_knn/knn_classification.ipynb @@ -62,7 +62,7 @@ "source": [ "### 1.1 距离计算\n", "\n", - "要度量空间中点距离的话,有好几种度量方式,比如常见的曼哈顿距离计算、欧式距离计算等等。不过通常 KNN 算法中使用的是欧式距离。这里只是简单说一下,拿二维平面为例,二维空间两个点的欧式距离计算公式如下:\n", + "要度量空间中点距离的话,有好几种度量方式,比如常见的曼哈顿距离计算、欧式距离计算等等。不过通常 kNN 算法中使用的是欧式距离。这里只是简单说一下,拿二维平面为例,二维空间两个点的欧式距离计算公式如下:\n", "$$\n", "d = \\sqrt{(x_2 - x_1)^2 + (y_2 - y_1)^2}\n", "$$\n", @@ -72,7 +72,7 @@ "d(p, q) = \\sqrt{ (p_1-q_1)^2 + (p_1-q_1)^2 + ... + (p_n-q_n)^2 } = \\sqrt{ \\sum_{i=1,n} (p_i-q_i)^2}\n", "$$\n", "\n", - "这样我们就明白了如何计算距离。kNN 算法最简单粗暴的就是将 `预测点` 与 `所有点` 距离进行计算,然后保存并排序,选出前面 k 个值看看哪些类别比较多。" + "kNN 算法最简单粗暴的就是将 `预测点` 与 `所有点` 距离进行计算,然后保存并排序,选出前面 k 个值看看哪些类别比较多。" ] }, { @@ -82,7 +82,7 @@ "\n", "## 2. 机器学习的思维模型\n", "\n", - "针对kNN方法的提出机器学习的思维模型,在给定问题的情况下,是如何思考并解决机器学习问题\n", + "针对kNN方法从原理、算法、到实现,可以得出机器学习的思维模型,在给定问题的情况下,是如何思考并解决机器学习问题。\n", "\n", "![machine learning - methodology](images/ml_methodology.png)\n", "\n", @@ -112,7 +112,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "metadata": {}, "outputs": [ { @@ -146,7 +146,7 @@ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "\n", - "# data generation\n", + "# 生成模拟数据\n", "np.random.seed(314)\n", "\n", "data_size1 = 100\n", @@ -158,7 +158,7 @@ "y2 = [1 for _ in range(data_size2)]\n", "\n", "\n", - "# all sample data\n", + "# 合并生成全部数据\n", "x = np.concatenate((x1, x2), axis=0)\n", "y = np.concatenate((y1, y2), axis=0)\n", "\n", @@ -167,7 +167,7 @@ "x = x[shuffled_index]\n", "y = y[shuffled_index]\n", "\n", - "# split train & test\n", + "# 分割训练与测试数据\n", "split_index = int(data_size_all*0.7)\n", "x_train = x[:split_index]\n", "y_train = y[:split_index]\n", @@ -175,12 +175,14 @@ "y_test = y[split_index:]\n", "\n", "\n", - "# plot data\n", + "# 绘制结果\n", "plt.scatter(x_train[:,0], x_train[:,1], c=y_train, marker='.')\n", "plt.title(\"train data\")\n", + "plt.savefig(\"knn_train_data.pdf\")\n", "plt.show()\n", "plt.scatter(x_test[:,0], x_test[:,1], c=y_test, marker='.')\n", "plt.title(\"test data\")\n", + "plt.savefig(\"knn_test_data.pdf\")\n", "plt.show()\n" ] }, @@ -209,38 +211,31 @@ "import operator\n", "\n", "def knn_distance(v1, v2):\n", + " \"\"\"计算两个多维向量的距离\"\"\"\n", " return np.sum(np.square(v1-v2))\n", "\n", "def knn_vote(ys):\n", - " method = 1\n", - " \n", - " # method 1\n", - " if method == 1:\n", - " vote_dict = {}\n", + " \"\"\"根据ys的类别,挑选类别最多一类作为输出\"\"\"\n", + " vote_dict = {}\n", " for y in ys:\n", " if y not in vote_dict.keys():\n", " vote_dict[y] = 1\n", " else:\n", " vote_dict[y] += 1\n", + " \n", + " method = 1\n", + " \n", + " # 方法1 - 使用排序的方法\n", + " if method == 1:\n", " sorted_vote_dict = sorted(vote_dict.items(), \\\n", " #key=operator.itemgetter(1), \\\n", " key=lambda x:x[1], \\\n", " reverse=True)\n", - " \n", " return sorted_vote_dict[0][0]\n", " \n", - " # method 2\n", + " # 方法2 - 使用循环遍历找到类别最多的一类\n", " if method == 2:\n", - " maxv = 0\n", - " maxk = 0\n", - " \n", - " vote_dict = {}\n", - " for y in ys:\n", - " if y not in vote_dict.keys():\n", - " vote_dict[y] = 1\n", - " else:\n", - " vote_dict[y] += 1\n", - " \n", + " maxv = maxk = 0 \n", " for y in np.unique(ys):\n", " if maxv < vote_dict[y]:\n", " maxv = vote_dict[y]\n", @@ -248,6 +243,14 @@ " return maxk\n", " \n", "def knn_predict(x, train_x, train_y, k=3):\n", + " \"\"\"\n", + " 针对给定的数据进行分类\n", + " 参数\n", + " x - 输入的待分类样本\n", + " train_x - 训练数据的样本\n", + " train_y - 训练数据的标签\n", + " k - 最近邻的样本个数\n", + " \"\"\"\n", " dist_arr = [knn_distance(x, train_x[j]) for j in range(len(train_x))]\n", " sorted_index = np.argsort(dist_arr)\n", " top_k_index = sorted_index[:k]\n", @@ -255,8 +258,7 @@ " return knn_vote(ys)\n", " \n", "\n", - "#a = knn_predict(x_train[0], x_train, y_train)\n", - "\n", + "# 对每个样本进行分类\n", "y_train_est = [knn_predict(x_train[i], x_train, y_train) for i in range(len(x_train))]\n", "print(y_train_est)" ] @@ -275,6 +277,7 @@ } ], "source": [ + "# 计算训练数据的精度\n", "n_correct = 0\n", "for i in range(len(x_train)):\n", " if y_train_est[i] == y_train[i]:\n", @@ -298,6 +301,7 @@ } ], "source": [ + "# 计算测试数据的精度\n", "y_test_est = [knn_predict(x_test[i], x_train, y_train, 3) for i in range(len(x_test))]\n", "n_correct = 0\n", "for i in range(len(x_test)):\n", @@ -317,7 +321,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -325,19 +329,26 @@ "import operator\n", "\n", "class KNN(object):\n", - "\n", " def __init__(self, k=3):\n", + " \"\"\"对象构造函数,参数为:\n", + " k - 近邻个数\"\"\"\n", " self.k = k\n", "\n", " def fit(self, x, y):\n", + " \"\"\"拟合给定的数据,参数为:\n", + " x - 样本的特征;y - 样本的标签\"\"\"\n", " self.x = x\n", " self.y = y\n", " return self\n", "\n", " def _square_distance(self, v1, v2):\n", + " \"\"\"计算两个样本点的特征空间距离,参数为:\n", + " v1 - 样本点1;v2 - 样本点2\"\"\"\n", " return np.sum(np.square(v1-v2))\n", "\n", " def _vote(self, ys):\n", + " \"\"\"投票算法,参数为:\n", + " ys - k个近邻样本的类别\"\"\"\n", " ys_unique = np.unique(ys)\n", " vote_dict = {}\n", " for y in ys:\n", @@ -349,6 +360,7 @@ " return sorted_vote_dict[0][0]\n", "\n", " def predict(self, x):\n", + " \n", " y_pred = []\n", " for i in range(len(x)):\n", " dist_arr = [self._square_distance(x[i], self.x[j]) for j in range(len(self.x))]\n", diff --git a/2_knn/knn_test_data.pdf b/2_knn/knn_test_data.pdf new file mode 100644 index 0000000000000000000000000000000000000000..56aad6184604dda2696b487848ad070fec925ef1 GIT binary patch literal 9022 zcmV-EBf;DyP((&8F)lO;C9K>atGWs?ATS_rVrmLJJRmPnVP|D?ATl5@AW|SNRC#b^ zATL8c;Wgs*lFd$MOFGg=} zbRaVzFd$MOFHm80bY*gGAT=N`AW{l1P;zf$Q)P4@TOcn`L`EPlRAqQ{ATLR6VP|DR zATLR6VP|DSATLR6VP|DYAYC9YQ)ppiX>MmAHXtw{QVK6vPhx6iV{{-lATS_OAU-|{ zWo~3|VrmL8F(5D?Z(?c+JUk#TL2hnubaNmvFd#4>QXnrwZ*FvDZgg`XIUq0~QVK6e za&L8TAUr%EFGEuxFGOW_X=7zlM?xSkQy?!?a$#G&3?FGB`LOT_7(|VRB_|bRaSyFd$MOFH&W5Z*_8G zWpf}nATS_OATLyTaAhDbP+@0fAU-|{Wo~3|VrmLGATS_rVrmLJJRmPdX>4?5av(28 zY+-a|L}g=dWMv>POl59obZ8(kG9WM@QXoD)3UhRFWnpa!c$~eNPjehM4#n^NDR|r* zh9U_P0FQBHG?hf0K+&e?=I34r&ugiz!`}83l9~9|vZ?(Ao$LsV{`aRuz z-Bu@aQ!Ax&z<;+mkT!cA>5n(qe#_tI<;q<@yuAJn<`L7asn(wR^fLOC*;6f&tGC+4 z`mE{I`*ibCi`Z8C{Chsk;Vn z;;2*>u1#en8`B-?gN5v}Zv^XTxwQz`ls?j7jx1UT>hx+GA;i@&ovF>)2;s=h<}6j1 z%dQcuz2;s>f0nLz8k#5hNcB@28*U$@X7{qjTRe5ms-%LpF~`mUuYioUG7EW2&bopr z1IMklT_fn6R4>xi37OZ-BDT&HWNY06ZLD-5M_tpfEVI^HW;n4C?%G=JwnBno_Ml({ zPxkJk?;CF!xk$4iF5w6+XYE79RW>uF5i=u`Osb|PSQUoZ5iHD30l* zWA{=vgGkxW)~ahae2KSHJ{3f7+flTv(rc-cX)$!}A3lcFG54*uI`XKh6jzx>@e%ye z;*9FvfK?p2DZZi(2vi}X#*no2FKYR(jtW&U$?B?ONFY+ra0{tM_Q=L^8mwtm>d;tB z6#$8>(gKO^4MAir8HnRP){yoLEJ2-0ne3Zbl&4v#+F3zQ(?N{^M%VU8(wxIM_)}_i z3Gk#MMzyZBx4N_Rh`cj_KRTf1h>4zuvi#Mi?VEb6+iibf6gA=1Q|bVJ?G3MU3^mGq6~O z2LKeHRmiYOQc(w5Lf&pMxMUGxMpppg*OL1vC}5QM&LJf0ii$z-$k~~PA+wpX?HfPD zNw8RH4XsT4)`FHfngJ&p@uPhJerdPrDrqb?mYwPmy(DN9t11YGHTE5}7*O}V{a4^p zqva{a%4>4MO$*tX_1LU1I7iM`{pzo4RK(ZqxPdU%)HX0(f^_={mYjJaa7SK1xaA&bs7`EnUHQc zO)G6$0BZ@X8K^222375w)$S1jx?R}2j39C1CPm4?zH^~fr6ZM6*X;{A0vG889WvZn zof`M6Kunb4>bk-|R9lyQR|iPI2_lHpp_K+N&_KxYx^pLBmZQp08ze|NOya{+9vdrL z@oOGHPh(fSM2Z1(jgk4*PSHUeBw5{Bs1CT-p*weKtLdd+{p1~889c&MrZ(<NI9x>{v05#eGfe@QW zE%xNJMTIOcZqv=T5u$+cm`^)mr^tbj^`d7OBZu$Ey&aBp#*pi`tEB9v4$CvEJ zj9Ulur^Db+G2Ax{BVLFPDSBu4Y<$shpRocUHL~SNhIPa69I=bqPKM9M7Y$F8R`r3D z@Tbk#|JQJ%EY;QT4WExM8E#yGP-*B&d)ka^*{}@rnynjMN6Tm9iRBV01<~1KxL*&&C%mBMSxqf+lWHobyJ4 z0kRs}dMGsUei;R84=1+l_LB8ziQYpeSlx<0uZ}TFj?(vylg-okx=BYvw5GIeVCnN} zc*N%uLe{05+?zc+bKP)-P>p4#_UcNg&nV)s9M;s(AScTYXa0}nuCeijplH7K9M7oY zux!Vc#pcQK!cbqIgoVjjUXbUIg#Y!FVOcNl+QmKFF!tfUw;4P z_hl|_e1txpy}N1anX>wD`jEWR^dna2+^TfkJT>E~v&pr`ll%1gwjATS_rVrmL8I5aQ{Wo~3|VrmL8Fd#4>Z(?c+ zTOeHuWo~3|VrmL8I3O?}Z(?c+JUk#TMrmwxWpW@dMr>hpWkh9TZ)9a4FHB`_XLM*F zGcY$GK0XR_baG{3Z3=jtJ(5dq12GIk_dbO#5WxD`p7W$Ax|rU7+b1RIiX7P%MQWD1 zOj%PNkTjEof9ddWv7PceY|mz9;98=WiRF~%&=q3tqI}uRMqODa#p;A+I=ARiITr^u zO{$-(ET!Epcn;Slo?G@2KfKVO9@I512{&|Cqh%>HW2*aq(tG@jGT>@VU2IaTdmlVr zL{;eM2Shp zWkh9TZ)9a4FHB`_XLM*FGBYtCK0XR_baG{3Z3=jtHBUK`1R)H|d4)bORT$eqzo)0R zHrV-px{{erknkbN(-R$;c$p(3ux7{GT4W$*;8RS+zxK2b6RP*%9wL;B3t@(laMrBj zZk~=8|8|wnSO@Pm_=;Ix5ZJ;@)>js1F53lTX`IA4$!?5Y6S0kTt*291M=+rbgmkvU zlpu3dr1Z&-GUn(wktd#u@Alg)b~%0y>kBrGArO z=p`T<2^Q8-V(y&fgkQaObRM-R5_3YDK`s*^&FLzp5Smb|v!kF=QE;g~r|7Jof8}3X zEed6BWOHZ(?c+JUk#TMrmwxWpW@dMr>hpWkh9TZ)9a4 zFHB`_XLM*FGBi0LK0XR_baG{3Z3=jtJy1K2L?I08IfXCqB=RG09!9GzX7Asw1DYvN zOn$aAB+wCoM+`BPuj3`HpssJ>($aQc{V@ zrJt0_KW)mC3OZ)d1S}G{;A9g`ILo_9Qj8gtGU^_tb|QVOJjkOu=wwaKtRtD((@)!( z_#AMzU)p3&mB(}*%=nzN&VxA>y7%LWHU~|O+UV@}6KN_hQo9{moqlx^mE9QU7!sFf ze;MCo|M>_0hgu>EWo~41baG{3Z3<;>WN%_>3NkSuFd%PYY6?6&ATLH~Y;fWg-RDRYHy6C3u7Gg3A6=5ZAiod>OcTQ?37fkkd9|06TcPR zXJQ;+=h3nOt{GHBmV4~Sh^fw~jJ!m|K2J^hD3(kuR>p2q8DIRAjMRK|1uCgD@|5z> zRkP3wSc!QO_Bs4W_~+JaA%;3`*7AwvA2Y==63$>tIbfle<454zS#=Sv9l5y9bb%k0 z)^JR;>wd`fPyTeWN%_>3NkVvFd%PYY6?6&ATLH~Y;AU-|{b98cLVQmU{oJEbn5x^h_1pib)2?`3@PbQOx z_Wz9#GJIg?4(@~n3$}Si9|e^rUKLmeN@Ltmk3hZQaxKZ+1rKm1f7;MgoR-sfX^}}) zDcqzIdH)V)CXlFk(PN$W3uF5uJPKuQWOHhpWkh9TZ)9a4FHB`_XLM*FI5QwVJ_>Vma%Ev{3V57FjJplMFbG6@ zreFkqCiXs2l)~P>4G<-6xF_8`TpbCSDQ+{vLk6AzmATS_rVrmLJJRmPd zX>4?5av(28Y+-a|L}g=dWMv>POl59obZ8(mGc+JRJ_>Vma%Ev{3V56?QcH5hAPn1c z3SFQx_y^=X>2$hyz5lk7lSM`jVDvHNhKWjiSs=Hg*2K4s%s_?VudB?3&q&+II*7}V zi@1_4g?mISfw=+p*>%K^_nZkKpIJ5o?Q)ab!C(m-C)Ts#X zv1d!r&^fN2y_Q*Mbej{rq=e7LPESt0S2OD&ITZ=1Vp>WN%_>3NkeyFd%PYY6?6&ATLH~Y;8_nJ*P0)X((jI;e0;pMh5hw-g(^gGm5`YWN2pr86K<=Rn50Vlq+#f+W~;X>kaN zawds?q`aQrC#|HR^gUUb%iohrrO+KsPUr!}%Ed{bT}k<%nV3pMl9%g!u|o8Qz>+*Z zM={BO>^6yQq6H@B9;GGB#1uNP#{#@&n$=b4V8R}UDU4SOv#1_y@>>&?q#do}8QC!2 z%P>=7q2aIv)aGJkg6`$xHLt>m?NO6m!*K4F&36dVX#N`(%HU%al7L62u@VhwIKYU& zo?bY`Uh@+<4#0?Goti8RV`wI)dX9;}(4MoUVaCTETJ`e}ROx(&3T19&b98cLVQmU! zZe(v_Y6>zoATS_rVrmLJJRmPdX>4?5av(28Y+-a|L}g=dWMv>POl59obZ8(kI3PYg z3UhRFWnpa!c$_mfv`{dB!xTfVGyomu15yfQZe(+Ga%Ev{3T19&Z(?c+GB+SFAa7!7 z3Oqa@FGgu>bY*fNFGg%(bY((PyfSqm=V?Bjbfw_XAJuYhlofRJ;8Mg7asg{mKSw2*H zQdSSi;D@Zn%OTvLEbxL!Duy9YizqATS_rVrmLJ zJRmPdX>4?5av(28Y+-a|L}g=dWMv>POl59obZ8(lH8CJQJ_>Vma%Ev{3V56?QAu(G zK?u9gEA)hBr{80jD~II&*9gi71`UfqbXww|jGrJZSG?tst7yaDGckhS1&4ks*KJtj zKvW<}V^B4rcJX@j9@uf13Cxq$uncCb5B!WN+~~#OF&SsK*JacY>|L)tnL){{T*M_4 z7fjV*BWDgjnKCZ4b3Hd8=SEnUVUTWC8Z#1(G=)eZg{qsR&ICacjIKtFHgXjEr7w?k zhE<9p4?^1@VL#hce|KsMFl-@J(9`;4#W=lT2tUtn8^3T19&b98cLVQmU!Ze(v_ zY6>zrATS_rVrmLJJRmPdX>4?5av(28Y+-a|L}g=dWMv>POl59obZ8(lF*P7QJ_>Vm za%Ev{3V56~Q8^9+Aq?#I75+dZj4yakqA1P&zs-!%Rvy7zhP0F+netMTs3GN3K6;rh zoVwiC%xW~}mb5K%fVj52FRhZmiDrm{!D*Pd0h&AkL)X!$Q9~CV(A1?bn4&8bBb7H!Wbq&2@@iyPjT?cK;zrN)*Rfd&CqI2_mL*YK4+ zPbSfH6*APTHOm+Y6Gb9C`HrU56YE+u(lQd%#u2P)1H3!^Firpf6LHG|WS>fuv*g5Y zvGlVBSNi?|pGQ=d3T19&b98cLVQmU!Ze(v_Y6>wnATS_rVrmLJJRmPZVRL0hZ*FuT zFGOW(VODihVQzCEFGFZya!_(_V{;%eHy|(|QVK6cZewp`X>MmAJUj|7L}_MbWpZV1 zV`Xz7TOczsATM)pVPj<=G&mqHdS!BNATMujWgstfcW)pyG9WKzZ*_7YH8dbEb7^=W zH8vnGWoc(FfK4K zF(5D?Fd$tZFHB)`bVF!iav(A_H6SleVQpm~FGOW(VODihVQzB@FH?15ba`-PATLyT zaAh+fFI0JOWgss`Z*FuTFIQ<~bZB!RF*G1BAW|ScJ_==SWN%_>3NbYxFd%PYY6?6& zATL34V`Xl1AUQHQATL8GXFIY%rX=iA3ATS_4J_==SWN%_>3NbVwFd%PYY6@E*HZU+CHZU+C zHZU+CHZU+CHZU+CHZU+CHZU+CHZU+CHZU+CHZU+CHZU+CHZU+CHZU+CHZU+CHZU+C zHZU+CHZU+CHZU*>HZU+CHZU+CHZU+CHZU+CHZU+CHZU+CHZU+CHZU+CHZU+CHZU+C zHZU+CHZU+CHZU+CHZU+CGch8NAU8KPAU8EKATl{M3Nkr0AT~8NAT>2NAUHNNAU8BPAU8NS zAT}^FAU8NSAT~KQAT~2KAT}{EAU88IAT~HOAUQZWAT~HPAT}{EAT~HPATv2IATu*J z3Ntw{AUHEPAT=;BAT=;BAT}{GAT~2KAT>2GAT~2KAT}{IATu>GAT~2KAT~2JATl>N zATl>NAT>8RATl>NAUQWQAT~2JAT}{F3N|w}AT~2KAT%*CAT=^EATv2KAT~2JAT>EM zAUH8NAT>EMAT>EMAT=^IAT~2LATu*JAT~2LAUHEPAT}^CAT~2LAT}^CATu#I3Ntk_ zAT=>KATcm7Fd#KBFd#KBFd#KBFd#8AG%_GIGc_PIFfbr7FgGwDHZU+CHaImPHZU+C zHZU+CGch2GAT}{IAT}{I zAT}{IAT}{IATl>NATl>NATl>NATl>NAT}{FAT~2J3N|q^AT}{FAT}{FAT}{FAT}{F zAUHEPAT}{FAT~2JAT~2JAT~2JAT~2JAT>EMAT~2KAT>EMAYBS&Ze(v_Y6>woATS_r zVrmLJJRmP&ATc-~Fd$MOFJvGwIUq0~QXns7ATlr@Fd$MOFJ)RC#b^ATLFD zbVpNkVRU66FJoaKF(5uZAU-|{Wo~3|VrmLCATS_rVrmLJJRm+k3T19&Z(?c+HXtw{ zZ(?c+JUk#iJ_==SWN%_>3O67yAa7!73Oqa@FHkTbF*6`AAW|ScJ_==SWN%_>3NbSv zFd%PYY6?6&ATL5fZ+IYEAT2U3H6SfAE;S%BE;S%BE;S%sATLH~Y;}d}NCNLpx=zK@&xq`?nKA01>CLy#41z+?&`v>0=;1 zx{KI{k`InOW}kBjS%dJ962*z<#3^Z}JC$Y)qg|z#qy}nz3Y^KWXlXicaaU!wZbY?} z_Bk*jSTM|RY`bA>jQtSUOY!F)uwTP38-4i~(MdO>%SiePWo~41baG{3Z3<;>WN%_> z3Nj!tAa7!73Oqa@FGFv2Zge0qATLX4WOE=}ATco@Fd$MOT_7)1d2nSQFHm7;Wpf}t zJ_==SWN%_>3NtVuFd%PYY6?6&ATL95Wnpw_Z*D|kbY&nYL^?7sGBGhSF*Y$cGBh+X zD=;`GFfb=63NJ%)Wnpx0av&&8VRUe8Z***FVjy-iE;KGPEFfrfbZ~PzFE4FjbZ~5M zbZlv2E^l&YDGD!8a&KgHV`Xw6C{1B>aBOdMY-wU3aAam6Vqs%zWo~33b~7$CE;A`0 zK0XR%Ze(v_Y6^IAWo8O6ATu!vFfcGMFfcGMFfbrCH8nFeAZ8#6FfcGMFfcGMF*YDD zFfcGMAZ{QEFfcGMFfceVFg74CFfcGMAZ{QEFfcGMFfcbZGdCbGFfcGMAZ{QEFfcGM zFfcbZHaQ?LFfcGMAZ{QEFfcGMFfcbaHaH+KFfcGMAZ{QEFfcGMFfcbaI5{9NFfcGM zAZ{QEFfcGMFfcbbF)$!7FfcGMAZ{QEFfcGMFfcGMHZ>qHFfcGMAZ{QEFfcGMFfcGP zI5;3MFfcGMAZ{QEFfcGMFfcMRGBhACFfcGMAZ{QEFfcGMFfcGOFgPGEFfcGMAZ{QE zFfcGMFfcMRFf$-9FfcGMAZ{QEFfcGMFfcbbG%_GCFfcGMAZ{QEFfcGMFfcYWGBO}A zFfcGMAZ{QEFfcGMFfcYUGBO}AFfcGMAZ{QEFfcGMFfcVZG&dkHFfcGMAZ{QEFfcGM zFfcbXH#HzIFfcGMAZ{QEFfcGMFfcMRG&CSEFfcGMAZ{QEFfcGMFfcMVGBhACFfcGM zAZ{QEFfcGMFfcPPGB_YGFfcGMAZ{QEFfcGMFfcPSH83DBFfcGMAZ{QEFfcGMFfcPX zF*qPFFfcGMAZ{QEFfcGMFfcPYI5Z$IFfcGMAZ{QEFfcGMFfcSRGdUnIFfcGMAZ{QE zFfcGMFfcSVG&UeGFfcGMAZ{QEFfcGMFfcSZGdUnIFfcGMAZ{QEFfcGMFfcVRGC3eH zFfcGMAZ{QEFfcGMFfcVTGc_PEFfcGMAZ{QEFfcGMFfcVWH8~(KFfcGMAZ{QEFfcGM zFfceVHZ~wIFfcGMAZ{QEbaG*7Y-Mr^JUk#TNp5CuATux^Fd$MOFH&!BbRaPxFd$MO kFH>oHWgs&#AU-|{b97;Hba--QW(qhnGBXM#B}Gq03jdEwhyVZp literal 0 KcmV+b0RR6000031 diff --git a/2_knn/knn_train_data.pdf b/2_knn/knn_train_data.pdf new file mode 100644 index 0000000000000000000000000000000000000000..fe9887c2c1f22a95a5d85f7251ebd54997a74922 GIT binary patch literal 10374 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 literal 0 KcmV+b0RR6000031