{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "### 一.原理介绍\n", "这一节介绍基于密度聚类的代表DBSCAN(Density-Based Spatial Clustering of Applications with Noise),它的思路也很直观自然,即将高密度聚集的样本看做一个簇,定义高密度,必然要考虑两个指标: \n", "\n", "(1)距离:只有距离近才有可能形成高密度区域; \n", "\n", "(2)数量:只有样本达到一定的量才有意义,比如两个点虽然相距很近,但说这两个点是高密度区域确有些迁强; \n", "\n", "所以,DBSCAN定义了两个超参数$(\\epsilon,min\\_sample)$对簇做约束:$\\epsilon$用于控制距离,$min\\_sample$用于控制数量,然后在此超参数的基础上,我们进一步定义另外几个概念,方便我们后续的算法推导,假设我们有样本$D={x_1,x_2,...,_m}$\n", "\n", "#### $\\epsilon-$领域\n", "对$x_j\\in D$,其$\\epsilon-$领域表示与其距离在$\\epsilon$内的其他样本点所组成的集合,表示为$N_{\\epsilon}(x_j)=\\{x_i\\in D\\mid dist(x_i,x_j)\\leq \\epsilon\\}$\n", "#### 核心对象\n", "若样本点的$\\epsilon-$领域至少包含$min\\_sample$,即$\\left|N_{\\epsilon}(x_j)\\right|\\geq min\\_sample$,则该样本$x_j$就是一个核心对象\n", "#### 密度直达\n", "若$x_j$位于$x_i$的$\\epsilon-$领域内,且$x_i$是核心对象,则称$x_j$由$x_i$密度直达(注意有两个前提条件)\n", "#### 密度可达\n", "若存在样本序列$x_{q_1},x_{q_2},...,x_{q_k}$,使得如下关系存在 \n", "\n", "$$\n", "x_i\\rightarrow x_{q_1}\\rightarrow x_{q_2}\\rightarrow\\cdots \\rightarrow x_{q_k}\\rightarrow x_j\n", "$$ \n", "\n", "其中,$x_p\\rightarrow x_q$表示$x_q$由$x_p$密度直达,那么称$x_j$由$x_i$密度可达\n", "\n", "#### 密度相连\n", "对$x_i$与$x_j$,若存在$x_k$使得$x_i$与$x_j$均由$x_k$密度可达,则称$x_i$与$x_j$密度相连\n", "\n", "如下图,虚线表示$\\epsilon-$领域,$x_1$是核心对象($min\\_sample=3$),$x_2$由$x_1$密度直达,$x_3$由$x_1$密度可到,$x_3$与$x_4$密度相连\n", "![avatar](./source/18_聚类_DBSCAN1.png)\n", "\n", "那么,基于这些定义如何去造一个簇呢?DBSCAN的定义是:由密度可达关系导出的最大的密度相连样本集合。这句话读起来拗口,翻译成直白话就是: \n", "\n", "**以核心对象为圆心,$\\epsilon$为半径(欧氏距离),画一个超圆,若超圆内的其他点也是核心对象,那么继续以该点为圆心,$\\epsilon$为半径画超圆,...,直到画不动为止,所有这些超圆内的样本点组成一个簇** \n", "\n", "于是,DBSCAN的思路差不多就有了: \n", "\n", "(1)找出所有的核心节点; \n", "\n", "(2)随机挑一个核心节点,画超圆...画....画...,组成第一个簇(注意:这个簇内还可能包含有其他的核心节点),然后从剩下的核心节点(不在第一个簇中)再随机挑选一个核心节点画超圆...组成第二簇,重复该步骤,直到没有核心节点\n", "\n", "需要注意一点的就是,可能存在不在所有簇中的样本点,显然这样的样本点离其他的样本点距离都较远,所以我们可以将这样的点看做是离群点或者异常点" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 二.算法流程\n", "\n", ">输入:样本集$D=\\{x_1,x_2,...,x_m\\}$,领域参数$(\\epsilon,min\\_sample)$; \n", "\n", ">过程: \n", "\n", ">(1)初始化核心对象集合$H=\\{\\}$ \n", "\n", ">(2)对$j=1,2,...,m$\n", ">> 如果$\\left|N_{\\epsilon}(x_j)\\right|\\geq min\\_sample$,那么$H=H\\bigcup \\{x_j\\}$ \n", "\n", ">(3)初始化聚类簇数$k=0$ \n", "\n", ">(4)初始化未访问样本集合$W=D$ \n", "\n", ">(5)while $H\\neq \\{\\}$ \n", "\n", ">> (5.1)记录当前未访问样本集合$W_{old}=W$ \n", "\n", ">> (5.2)随机选择一个核心对象$o\\in H$,初始化队列$Q=$ \n", "\n", ">> (5.3)$W=W/ \\{o\\}$ \n", "\n", ">> (5.4)while $Q\\neq <>$ \n", "\n", ">>> (5.4.1)取出队列$Q$中的首个样本$q$; \n", "\n", ">>> (5.4.2)如果$\\left|N_{\\epsilon}(q)\\right|\\geq min\\_sample$,则: \n", "\n", ">>>> 令$\\Delta=\\left|N_{\\epsilon}(q)\\right|\\bigcap W$ \n", "\n", ">>>> 将$\\Delta$中的样本加入队列$Q$; \n", "\n", ">>>> $W=W/\\Delta$ \n", "\n", ">> (5.5)$k=k+1$,生成聚类簇$C_k=W_{old}/W$; \n", "\n", ">> (5.6)$H=H/C_k$ \n", "\n", ">输出,簇划分$C=\\{C_1,C_2,...,C_k\\}$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 三.代码实现" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "\"\"\"\n", "DBSCAN密度聚类的代码实现,封装到ml_models.cluster\n", "\"\"\"\n", "import numpy as np\n", "from queue import Queue\n", "\n", "\n", "class DBSCAN(object):\n", " def __init__(self, eps=0.5, min_sample=3, dist_method=None):\n", " \"\"\"\n", " :param eps:epsilon领域半径\n", " :param min_sample: 核心对象的epsilon领域半径内的最少样本量\n", " :param dist_method:样本距离度量,默认欧氏距离\n", " \"\"\"\n", " self.eps = eps\n", " self.min_sample = min_sample\n", " self.dist_method = dist_method\n", " if self.dist_method is None:\n", " self.dist_method = lambda x, y: np.sqrt(np.sum(np.power(x - y, 2)))\n", " self.label_ = None # 记录样本标签,-1表示异常点\n", "\n", " def fit(self, X):\n", " rows = X.shape[0]\n", " self.label_ = np.ones(rows) * -1\n", " M = np.zeros(shape=(rows, rows))\n", " # 计算样本间的距离\n", " for i in range(rows - 1):\n", " for j in range(i, rows):\n", " M[i, j] = self.dist_method(X[i], X[j])\n", " M[j, i] = M[i, j]\n", " # 记录核心矩阵\n", " H = set()\n", " for i in range(0, rows):\n", " if np.sum(M[i] <= self.eps) >= self.min_sample:\n", " H.add(i)\n", " # 初始化聚类簇数\n", " k = 0\n", " # 初始化未访问样本集合\n", " W = set(range(rows))\n", " while len(H) > 0:\n", " # 记录当前未访问样本集合\n", " W_old = W.copy()\n", " # 随机选择一个核心对象\n", " o = np.random.choice(list(H))\n", " # 初始化队列\n", " Q = Queue()\n", " Q.put(o)\n", " # 未访问队列中去掉核心对象o\n", " W = W - set([o])\n", " while not Q.empty():\n", " # 取出首个样本\n", " q = Q.get()\n", " # 判断是否为核心对象\n", " if q in H:\n", " # 获取领域内样本与未访问样本的交集\n", " delta = set(np.argwhere(M[q] <= self.eps).reshape(-1).tolist()) & W\n", " # 将其放入队列\n", " for d in delta:\n", " Q.put(d)\n", " # 从未访问集合中去掉\n", " W = W - delta\n", " # 获取聚类簇idx\n", " C_k = W_old - W\n", " k_idx = list(C_k)\n", " self.label_[k_idx] = k\n", " k += 1\n", " # 去掉在当前簇中的核心对象\n", " H = H - C_k\n", "\n", " def fit_predict(self, X):\n", " self.fit(X)\n", " return self.label_" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 四.测试" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "from sklearn import datasets\n", "import matplotlib.pyplot as plt\n", "%matplotlib inline" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "#造伪数据\n", "X, _ = datasets.make_moons(noise=0.01)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "#训练\n", "dbscan = DBSCAN(eps=0.2, min_sample=3)\n", "lable = dbscan.fit_predict(X)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAX8AAAD8CAYAAACfF6SlAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMS4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvNQv5yAAAIABJREFUeJzs3Xd4VGX2wPHvmT5JSOhFECmCiq4VELD3sih2xcW2dtayuir6s3fXriv2hroK2BH7imABlGBHEREUQUogIW363PP74wZIMhNakrnJzPt5Hh4yd27mnlDO3Hnf855XVBXDMAwjt7icDsAwDMPIPJP8DcMwcpBJ/oZhGDnIJH/DMIwcZJK/YRhGDjLJ3zAMIweZ5G8YhpGDTPI3DMPIQSb5G4Zh5CCP0wE0pGPHjtqrVy+nwzAMw2hVZs+evVJVO23ovBab/Hv16kVxcbHTYRiGYbQqIvL7xpxnhn0MwzBykEn+hmEYOcgkf8MwjBxkkr9hGEYOMsnfMAwjB5nkbxiGkYNabKmn0bqpVQmR90DLwbc74v2L0yEZhlFLkyR/EXkaGA6sUNUd0jwvwAPA4UAIOF1Vv2qKaxstj8Zmo2VngVpAHPCigf2RonsQWf+HTdUkYCHizUSohpGzmmrY51ng0PU8fxjQr+bXOcAjTXRdo5moxtDEfNQqXc85ETTyHhqagCYW1RxLomX/AK0GwkDC/j06BSLvrPve5BKsqkewKu5EY19iJSuwVl+OLt8RXf4XrFUnoPF5dhyhV7BK/45VdjEa/aJ5f3DDyBFNcuevqp+ISK/1nDICeE7t3eJnikhbEemmqkub4vpG07JCE6HyDsACTaD+PZGiuxFXwdpzNP4dWnpGzTkWYKF5J4H/cCCa+qIaRsOvIMHhWOF3oXwMkATiaOi/ID7QEPYnBSD+DbrqRPD0guQC0LD9MrGpaP75uArOQzUC4bfR2HRwd0eCJyCeHs35R2MYWSNTY/7dgT9qPV5cc8wk/xZGo59DxS1AZN3B6Gfo6kuh6EaIFaNSBOVXgFbW/ebQRHB1Wc+LW6hVDeVX1n19wmuTe11RSPyM/elhzWuEoWosVuAwKDsHrGU13+tFq8dBu0cQ/7BN/bENI+dkKvlLmmOacpLIOdjDQvTs2bO5YzLS0OonqJuYAWIQ+wQtOQjEC5pMcw5AGGKzgHTj9UEk7xiIfQniTvO3n04i/WHxQuXdkFxixwbYnxjiaPkV0OmTDc4tGEauy9T/kMXAlrUe9wD+rH+Sqj6uqgNVdWCnThtsSmc0h+SyBp6wgFjNWH66xL9GDGn7AEgQCAACkgf+oRA4wk78G81Ng/cN8W9Zl/hrh1mJJuai0Rn20JRu1LuMYeScTN35TwIuEJHxwO5AuRnvb6F8QyC8iAbvutcriASPRPxDodPHEJ6MWqvtx96BiAjqG9LA97qwk3281uM87ARfbw5BgiBtgXRvVDFYdRIqHsACaQftn0A8W689Q60QxL8DVwF4tscuRjOM3NJUpZ4vAfsCHUVkMXA9NZ/9VfVR4B3sMs/52KWeZzTFdY3No5qE2OeQXAHenRBvv7XPScG5aGRyzR1+suaoC/vOPx13zXl54NsJAsPt13G1h/xTU+7bRXzQdiy6+jxQWXeN4AmAFyKvgkbBvxfS5io0NgMqbgbxAAqSj7R7Co19C5W3YlcUrX31mjgj64aVNIyWng6dpiHixgq9UvN6bvtcVwdo9yTi6b0Zf5KG0XpJS/1YPHDgQDX9/JueJhajpSfbk7VqAQr+fZG29yE1QzKa/BOtegRi0+0JXHdfiLxJynCP5EHwFNAKxL8v+Pde+xobjMOqhOiHYFWBf0/E02c951ZB/CuQfPDugogLVQstv8ouH5Wa4SHVmhjrvVFJPtL2EXC1QVeNrPdzCLi6Ip0+NvMERlYQkdmqOnBD55kVvjlGV18E1grqJMjoNDT0EpI/CgBxb4EU3bzuezSCJuZAYgH2Bzc34IXCO3AF17e8o2HiagPBYzby3ALw7133mLiQtv9GE+dD/BtwdUZDL0D0f+leAbQcDb1F6jyBglZAfDb4Bm3Wz2IYrZFJ/llM43Mh8RO4twLvLmAth8QvpA7hhCH8EtQk//pEAtBhPETeQ6Mfg6szknfieu/WM0U8vey1AADJZWjs89SyUY2BdzcIv0ba4StVtOJO1FoCri5IwflI4OBmjtwwnGWSfxZSjaFl50GsGNYMZbh7QuGtpK+ewR5nXw8RHwSPRIJHNm2wTSk4HELP13xCWfMGEISCsxF3R/AfgEZnUneeACAEiW/tL62V6OrL0DaX4co/NXOxG0aGmeSfBTTxB1r9tF3B4u0HeGvq7aPrJj4T86H6UXC1B6t+la0PAodnNuhmIOKDDuPR0Kv2XICrEMn7G+Lfwz4hOAJCL0DiN9aN+6+ZsK4tAlX3oXkn2a9pGFnIJP9WTuPz0NITa+7cE5D4kdRkhv1c9GNo9zSsPrdmoVbMnrR1dUXyz8ls4M1ExI/knwz5J6d9jg4T0dArEHkXXEUQ+wo0Xf8iheRS8GzV/EEbhgNM8m/ltPL2mrLMNdIl/rVnI94doeMHaPgVSC5GfEMgcFjO3OGKBOyJ7Zr5DWvVSIinSf6asD8lGUaWMsm/FVFVsFaBBBFXvn0wNnvjX8CzHeLKA/KQgn80S4ytjRSMRssuoO48QMB+Q3S1AWrWRST/sIeRzBuCkSVMYXMrodHP0ZL90JJ90RWDscoutGvlaxJUesGa3/0gBUjRrZkItVUR/15QeH3NiuEA4Ifg8LWlrlb4fXTFMHTVUeiKvbFK/45aZY7GbBhNwSzyamE0sQitegBiM8HVDsk/G/UMgFXHUffu1AfencC/F1Q9TN2FS34IHAnebewaeM/Wdrtjd8fM/jCtiGoCrBKQoppPR6DxH9BVJ1P3z9YD3h1xdRjvSJyGsSFmkVcrpMml6Kqja8bwLbBK0PLrwNOb1MVJMYh/D4U32kMS4TdB/HZNu38fpOg6e4ITU664MUQ84O5W55hWP0Pqn3sC4j+iiQUtYp2DYWwuk/xbEK16smaBUu2FSGF7oVa6HsjiRaxlSNGtaMElkFwI7i0Rd9cMRZzlkotJ39PIg1aNQ+NfAHEIHIHkn1VnsxvDaOlM8m9J4l+Svpvmmr+meN3DGgXPNgD2kI4Z1mlavqEQn0Pq3X81RF5jbbfR6qfQ6EfQ4TWz97DRapgJ35bE3ZP0K3Clpj9+7b+uIASPRdxm34PmIvmn1kyo175H8mMvDKu9IjpqD71FP8pofIbRGCb5tyD2Qit/vaM+8A1FOr5ZsxlKe7tXT5srkMLrnQgzZ4irPdLhTQieCK4e4NmhZiV0ms6lGkJjuVegYLReZtinBRHfTmjR3VB5g93qGAv8ByBFtyGufKTtXU6HmHPE3RkpWvcmq5EP0OgHaXohBcDVPbPBGUYjmOTfwriCB6OBA+0OnNLGTCK2NP597SG4+hPz4kbyRjgVlWFsMjPs0wJocgkaegWNvIdqxO5V7+5mEn8LJOJD2r8Enm0BH+C3h+EKb7NLQJMlTodoGBulqbZxPBR4AHsw9ElVvaPe8z2BcUDbmnOuVNV3muLarZ1VcQ+Enl23GxUC7Z5GfDs7HJnREPFshXR8A00uR61yKL8Byseg4gWNosFjkcLrzc5gRovW6H+dYu/bNxY4DBgAjBSRAfVOuwaYqKq7ACcBDzf2utlAo9Mh9Bx26+WQvbhLq9Cyc1CNb/D7DWeJuwtU/QcS32HvG1wJxCD8Bhp6ae15qkm0/gYzhuGwprg1GQzMV9UFqhoDxgP1Bz8VKKz5ugio31A+J2n4ZVI3FgGI2xuxGC2aWtUQnULqOoAwhJ5FNY5VcTu6fBd0+a5YJQeh0c+cCNUwUjRF8u8O/FHr8eKaY7XdAIwSkcXAO8CF6V5IRM4RkWIRKS4pyZ6xU1ULq3oi1sojsFbsj1VxG2qVgkYa+A6hbh250SJpmAZ3RrMq0fJrIfQSdm+gJCR/R8tGo/HvMhikYaTXFMk/3b/++r0IRgLPqmoP4HDgeUkzIKqqj6vqQFUd2KlT9ixe0orroPJWSPwM1mII/RddeTT4D7A3U0n5hgR4zWbiLZ6rA7jSrap2gW93iEymblM4gCha9WgGgjOM9WuK5L8Y2LLW4x6kDuucCUwEUNUZ2L1zc6IXgSaXQPgN6g7vxMFaDValvbH42jcADxCAwpvX9es3WiwRqWmTHWTdwi8fSCHkHQNpN8hRSMxHY1+h8e9QTdc7yDCaX1NU+8wC+olIb2AJ9oRu/T30FgEHAM+KyHbYyT97xnXWJ/6DnQQ0zbhw/Auk3RMQ+wSNfASuIiR4LOLp7UioxqYT/x7Q8VW7A2hiIfgGI3mjQAINTNq7ILkYLTsLsEAKoN2jiHeHTIdu5LhGJ39VTYjIBcD72Lc/T6vqHBG5CShW1UnAv4AnROQS7CGh07WlbiTQ1FxdaKgzJO6edjmgf1/Ev2+GAzOaini2TrtRjuadAqH/UvdTn2X/0qqak0Jo6enQ+TNEAhmI1jBsTVLnX1Oz/069Y9fV+vpHYI+muFar490JXN0g+Rt199f1IHmpm4wb2UPaXI66u0L1U2CV2V1Xk8tI7dyahMgUCB7uRJhGjjKrUJqZiCDtx4F3F+wVoUFwdUHaPYJ4ejkcndGcRARX/qm4Ok/D1fU78O9P2pbdmgBdnfH4jNxmevs0I1W1F/uEngKrHHxDIP8MxDcMkQZKBI2sJb490PAr9oK+us+Ab7AjMRm5y9z5NyOtvB0q/233etcKiH0Kqy8Ea6nToRlO8O8Nnr/U7M2wRhCCRyCerR0Ly8hN5s6/mahVVrPAp/ZiLbV7v1Q9hRRd61RohkNE3ND+aQi/jobfBPEheSeA/9A656mGwQqBq735hGg0G5P8m0tiQU2JZ/2VunGIf+VISIbzRLyQd4Kd9OtRK4RWXAuR9+0Drg5QdBPi3yfDURq5wAz7NAG1StHQeLT6STQ+1z7o7p6mth/ABaaO30hDV/+zJvHH7F/WUrTsQjT+o9OhGVnIJP9G0ugn6Ip90Yrb0cp70VUnYJVfb9f3+/cgdVtGP5J/lhOhGi2YJv+E2AxSm8TF0OonnAjJyHIm+TeCagRdfRF2/5YwdhlfxG7nEPsUaXtfzZ6vPsALru5Iu4cQb/2O10bOS/7ZQDsICxK/ZToaIweYMf/GiM0k/ftnGA2/jsu/N9L236jeZJf3SVszgWek59m6gWFCD/h2y3g4RvYzd/6Nsd4OFeueE/EjrnYm8RsNEldbyPtbvTJQF0gQyT/TsbiM7GXu/BvDP4S0fXskiATMZt7GppE2Y1B3Lwg9XbMocHekzb8QdzenQzOykEn+m0gT89HKByH+Lbi3hLyzofox7DeBBIjfrts2jdqMTSQiSP5JkH8SgF3lk5iHihdxb+FwdEa2Mcl/E2j8Z7T0xJoduCx7pW78O2gzBiGOWpWIf2/Et5PToRqtmFplaOlZkJwPuEFjaHA4UnirvVDMMJqASf6bQCvvrtm6r/ZYfwSqH4JOn+NK3ZzMMDaZrh4DiZ+o0wQu/C7qGYDkn+pYXEZ2MdlqU8S/JXWHSsCqAqs04+EY2UetKoh9Tmr3zzCEnnciJCNLmeS/kVRjsL7NNlxtMheMkb3Wtym8Vmc0FCO7NUnyF5FDReRnEZkvIlc2cM4JIvKjiMwRkReb4rqZoskStORge0OOFAEIHotI/ZW8hrEZXB3B3TnNEx7w75fxcIzs1ejkL/YM1FjgMGAAMFJEBtQ7px9wFbCHqm4P/LOx180krbgJrBXU7dAJ4ILgcKTw/5wIy8hCIoIU3o69KfyaKbkASBF4+mOVnY9VPgaNfe1glEY2aIoJ38HAfFVdACAi44ERQO1uVGcDY1W1DEBVVzTBdTMnOoW0OzDhwlV0W6ajMbKc+HeHjpPQ0PP2pvDe3SD6MVTei91GRNDwe2ibf+LKP8PpcI1WqimGfboDf9R6vLjmWG39gf4i8rmIzBSRQ8kKZsrEaB7i2QpX4TW42j+FeHpAYh7rNoJX++vKe1HLbP9obJ6myF7pZqfql8R4gH7AvsBI4EkRaZvyQiLniEixiBSXlJQ0QWhNxH8gqR+SPBA40IlojByjkfdYl/hrES/Evsx4PEZ2aIrkvxjYstbjHsCfac55U1XjqroQ+Bn7zaAOVX1cVQeq6sBOnTo1QWhNQwqvBXc3kHzsfiv54O6GtDG7cRkZ4Coi/X9VBSnIdDRGlmiKMf9ZQD8R6Q0sAU4CTq53zhvYd/zPikhH7GGgBU1w7WahVsjuwunqYE/AuTtCx/fscdfEr+DpC/797F2ZDKOZSfAkNPw2duvw2k8EzMbvxmZrdPJX1YSIXAC8D7iBp1V1jojcBBSr6qSa5w4WkR+BJHC5qq5q7LWbmlpVaPnVEP3IPuDqAEU32y0bxAuBg50N0MhJ4tsJbXMZVN5lD/WQtDvKuvtBeJLd+iHtXgCG0TDR9bYlds7AgQO1uLg4o9e0Ss+A2Czq7qYUQDpMRLzbZjQWw6hPrXK06pGalb4J7GGfILh7IR3GI3XaQRu5SkRmq+rADZ1nylVqaGIRxIpJv43eU06EZBh1SQDCE4A4a2sqNAyJhWhoopORGa2QSf5rmG30jJYu/j3pi+siEHk309EYrZxJ/mt4+zewjZ4X/IMyHo5hpJA80m4eBKbqx9hkpqVzDXG1R/0HQPQ91v0HE3tXrrzTnAzNMGye7ezeP8k/qLOURoJI3t8cC8tonOryat575mN+mvkLvbbvweFnH0j7ru2a/bom+dfQyJSaNg6176zcUPQA4u7iVFiGsZaIQLvH0dLTQKvsgxqH4KlIwDR9a41KFq9i9MAxhKvCREMxZgS8vHzPW9w77Sb67tSrWa9tkj+gqmjF9aTUUZOE8H8hsIcTYWUNy7KY8uJnTH7sA2LhGPuN3JMjRx+CP2g6oW4q8fSBTlPtqjQtQ1Ug/ArWyuHgG4bkn4Wk7QpqtESPX/4cFasqsZL2TWcsEicWiXPv2Y8y9ss7mvXaJvkDaFkD7Zq1pvTTaIx7z3qEaS/PIFJtd0Vd9NMSpk6YzgOf34LHa/4JbioRN/iHYIVegYqbWHvTkliIht+EjpPMp9VW4st3v16b+Gub//VCIqEogbzmu0EyE75Q07ahAa72mYsjCy2au4SPJ0xfm/gBouEYi35azOdvmDfWzaUag8rbqPtpNQ5aiVY95lRYxiby+dN3CXC5BLenedOzSf5gb8QSPAKo/y4bhPyznAgpa/zw2Vx7rLqeSHWU2R9+60BEWSLxG2m3FCUBsU8zHIyxuQ476wB8gbpvAB6fh6EjBuH1NW/7GJP8a0jh9eDfF/DXlM35If80JHicw5G1bm07F+JypyZ/r89Dpx7mU9Vmc7WzJ3vTPmfG/FuLUdcdz477bI8/z0ewIEAg30+v7bfkksfObfZrmwHXGiIBpN1/0ORKsJbZS+Zdpna6sQYdujP+oI9IVYTanURcHjeHnG4qVDaXuDuhvsEQ+wJ7xe8aQcR8Wm01fH4vt797NQu//51fv/2dLbbuyna790v7abmpmTv/esTdEfHuYBJ/E/H6vNwy+Sq69ulCIM9PsCBAYcc23PDa5XTu2XLadrdG0vZ+8A1i3afVILT5pyn7bIV6/2UrDhy1NwOG9M9I4occvvNXqwwNvWRvhuHujeSfYpfRGU1m8bw/ufO0h5j31QJUlX679OHU649nt0N2wu12Ox1eqyeuQqT9s2hyKVgrwd0XceU5HZaxGZKJJK/e/zZvPfI+0VCMYSMGcdpNJ9Kuc1GzXTMnu3pqchm68ijQauxN2d2AD2n3KOIf2izXzDWhyjCn9BlNZWk1a/6Nudwu2ndty3O/PtTsk1mG0ZrcdMI9fPnOV0RDdosZt9dNuy5FPDXnfvLabFq3VtPVcz206n7QcuzED/YWA2G0/P9oqW+Grc3UCdOJReJ1/jytpEWoIszMyV85GFl2UlU09g1a9RgamohaFU6HZGykRXOX8MXb6xI/QDKepKq0mg/GTW226+Zk8ic6DTvh12OV2B+fjUZb+uuyOrX9a0QjMZYtXOFARNlLNYmuvgAtPQ2tuh+tvBUt2QeNmTfZ1mD+Vwtwu1NTcSQU5ftPf2q26+Zm8m+wA2LN5hhGo/XbrQ/BgkDKcZ/fS9+de2U+oGwWmQTRz7A3eU/aPf61Gl39D1TT3OQYLUrnrdIXPnh9Hrbs363ZrtskyV9EDhWRn0VkvohcuZ7zjhMRFZENjkc1q7xTgfpJ3gv+vUyVTxMZNmIQHbu3x+tbV1Pg9XvZcrvu7LL/Dg5Gln009Cp24q//RAQSczIej7Fpth+2DZ17dsTtqVsE4fZ5OPycg5rtuo1O/iLiBsYChwEDgJEiMiDNeW2Ai4AvGnvNxtDEAkiuBHcP7GKnfCAA3gFIUfM2UsolHq+HB6bfymFnH0hRp0LadSniqAsP5e4pN2SslC13rGeeysxhtXgiwl1TbmDn/bbH4/Pg9Xvp3q8b/37/Gjpv2bH5rtvYCU4RGQrcoKqH1Dy+CkBVb6933v3A/4DLgMtUdb2lPM1R7WOFJkDFLdjj/UnAD96doM3VuHxmj95MiMfiREMx8ovyzJtAE9HQa2jFjaTc/Ut7pPPndiM4o1WoLq8mFonTtnPRZv//yGS1T3fgj1qPF9ccqx3MLsCWqjq5Ca63WdQqrUn8UdZufk0E4t8husqpsHJGLBLjvnMf46i2p3F8lzM5pc8/+PLdr50OKzsEjwT/kJqdvgQIgOQh7f5jEn8rk1+UT7subTNyY9QUi7zSRbn244SIuID7gNM3+EIi5wDnAPTs2bMJQqslOh37x61fgRJGI+8gftOzvzndefpDzJg0m1jEbkWw/PcSbjr+bu6ZehPbDOzrcHStm4gH2j4K8WJ70aKrHQQOh+QyNPIxeLdD3F2dDtNoQMWqSv73309YumAF2w/tzx5HD87IOpimSP6LgS1rPe4B/FnrcRtgB2BqzbtZV2CSiBxZf+hHVR8HHgd72KcJYltHPPbbVMqrugCz4Kg5lS1fzYxJxWsT/xqxcJzxd7zO9a9c5lBk2UNE7FYPvkH26vXSMyExH8QNGkODxyCFN2DfixktxfyvF/Kv/a4nGU8SDcd4/+kpvHDzKzww/VbyC5t3tXZT/EuYBfQTkd4i4gNOAiateVJVy1W1o6r2UtVewEwgJfE3O99epJ8Y8yHBozMaSq5ZsWgl3jR9y1WVxT//meY7jMbQ1ZdD4icgXLPdYwzCb6KhiU6HZtRz+6gHCVWEiYbtBV7hqgh//rqMF299rdmv3ejkr6oJ4ALgfeAnYKKqzhGRm0TkyMa+flMRVz7S9j/YJZ55QADwQ8F5iG8nZ4PLcj36dyMeTW0/7Pa42HZIPwciyl5qlUNsJva8Vm1hCD3rQERGQ1YtLWPpguUpx+PRBB+P/6zZr98kjd1U9R3gnXrHrmvg3H2b4pqbQ/x7QefPIPqRXQPt3wtxd9/wNxqNkl+Uz1EXHsakse8TCdlzLiLgC/oYeaX51NWkNEz6aTjWbfputAhuj6vBUtxMbG+ac109xdUGgkc5HUbOOeuOUXTt3ZmX736L8pWV/GWvbTnrjlFs0ddMRDYpVxd761Frab0nPOA3rZ5bkradiui7S2/mzZqPZa17E/AFfRx65v7Nfv2c6eqpyZWQXAyenojZl9cxlmXhcplJx+ak0c/RstFAjLXrWVxtkA5vIG6zy1dLsnThci7Z61pClWESsSRuj4vthvTn1rev2uyKn42t88/6O3/VOFp+NUTeAfGBxtHgCKTwRlMDnUHvPvURz147ntJlq+nYvT1n3DqSg0/d1+mwspL494COr6HVL0DyN/BsC8k/0JVHoK5CyDsdyRtpKn8c9tucP/h4/GfsN3JP2nVuiy/opf/AvhnbySv7k3/lfRB5D4iB1rRMDU9C3VsgBaMdjS1XvPv0R4y9+Om1LWtXLinlwdFP4Ha7OeBvezkcXXYST1+k6Ho0WYKuPBy0ErAgWQaVd6KJ+UjR9U6HmbNeuW8yz1zzEsl4Aiup+II+Dj/rAI664LCMxZDVb/2qCuEXgUi9ZyJQPc6JkHLSuOsm1OlVDhANxXj22pcciih3aOhZ0BBg1ToahvDL9lCokXEli1fxzNUvEgvHSCYsVJVoKMo7T37Ez7PmZyyOrE7+oDXVD+meqsxsKDlKVVn1Z1na51b8YdpqNLtYMXU3eK8hfkjMy3g4BsycPDvtsE4sHOOTV2ZkLI6sTv4iLvBsk/5J746ZDSZHiUiDnQm79jaTj83O05u0/801DqbM2REerxtxpSZ/l1vSLoZsLlmd/AFo83+An3U/qttuelV4jYNB5Za/334y/jxfnWP+oI8zbzvZoYhyh+SdCfjqHfWBbxfEs5UTIeW8YSMG1SntXMPt9bDfSZnrMZbVyd8Kfwir/4H9Ywr2hi0HIB1eQ7xmQ5FMOeDkvbjsqdF069sFt8dN937dGPP8Rex93FCnQ8t64u2HtHsEpAt2fYcX/Psjbcc6HVrOKupYyBXPXoAv4COQ78cf9OELeDnztpFsNWDLDb9AE8naOn9NLEBXHkXdyV4BVyek0zRT5mnkBLWq0NUXQWyW3dxQE1BwPi5T6ea48pUVTH9zFol4kiHDd6NTjw5N8ro5X+evoQmk9jdR0Gq794lp4WzkAC2/wm7zTAy0pp151WOouxcSPNzR2HJdUcdCDjvzAMeun73DPtYKUpM/di8NqzTj4RhGpqm1GqKfYK/0rS2MVj/hREhGC5K1d/7i3xuNTklT6pkE326OxGTYyldWMHPybFRhyPBdadupyOmQspNVATQwvGlugHJe9t75B/4K7l7YrZtrSBDyTkLcWzgVVc778PlpnNzzPB668CnGXvQUf9vqfD54bqrTYWUn9xZ2PX/qE+AflvFwjLpWl5Rz68j7ODx4MocHR3LzifdStnx1xq6ftRO+AKphtPoliLwNrnwk72/gP9hsHO6QksWrOL3/hSk7evmCPp6Z+0CD6wGMzWeFJ0P51azb3N0Dko90fMO0M3dQMpHk79tdzPJFK0nGkwC4PW46dm/PMz8/0KhtHDPbUuWUAAAgAElEQVS5gXuLJRLEVfB3XB1fxdX+OSRwiEn8Dvr0lZlpj6ulfPJy5lY25hJXcDjS/hnw728veMw7Gen4lkn8Dps5eTZlK8rXJn6w3xAqVlUy/Y1ZGYkha8f8jZYnHkuQTFopx62kRSKWZnLeaBLi2xXxPep0GEYtv/+4mGh1NOV4uCrC7z8uzkgMTXLnLyKHisjPIjJfRK5M8/ylIvKjiHwnIh+JiFlamIOGHLEbbk/qBKTb62bokRv8lGoYWaPndt3x56fOxwTbBOi5XWY+lTU6+Yu9WmoscBgwABgpIgPqnfY1MFBVdwReAe5s7HU3RDWKxueiyZLmvpSxkbbargfHXTocf54PcQniEvx5Po65+PCMrmzMZWqVorHZaHKF06HktCHDd6OoY2GdmyG3x0WbdgUMO2pwRmJo9ISviAwFblDVQ2oeXwWgqrc3cP4uwEOqut5VVo2Z8LWq/wtVd9sPNA6+oUjb+xBXwWa9ntG0fi7+lak1G1TveewQVi4uZdGPi+m5XXeGHTWoUZNdRnqqSbTiBgi/blcAaRQCByJFdyJSv/eP0ZySySQ/fDaXFYtW8ulrM5n17jegypDhA7ngoTPp0K1do14/kyt8uwN/1Hq8GNh9PeefCbzbBNdNS6OfQuWdrKtuAGIz0NWXIO3NwpaWYJuBfdlmYF/Klq/moqFXU76ygnBVhGBBgMeveJ4HZ9zW6P8ARl1a/QSE36TOpkaRKajrTtPkMIN+m/MHVx5yM+HKCAgkYgnOuHUkx196RMaLUZpizD9dxGk/TojIKGAgcFcDz58jIsUiUlxSsnnDNfbKxfoLu2L2G4AZAmpRxl78DCWLVxGusvsvhasirPqzlIcueMrhyLJQ6DnSbmoUmohq6iS80fQsy+KqQ29h1Z9lhCrDhCrCxCJxnrt+InM+n5vxeJoi+S8Gag/Y9gD+rH+SiBwIXA0cqaqp09yAqj6uqgNVdWCnTp02L5rksvTHxQuW2TykJZn+5iySiWSdY8mExczJxbTU9SetltXQ5kUx0rZBMZrcjzPmUV0RSjkeC0eZ9MgHGY+nKZL/LKCfiPQWe/DwJGBS7RNqxvkfw078zTvT5BtGg6NZnt7NemnDaLF8O6c/7u5rxvwzJFQRTju0owqVZVUZj6fRyV9VE8AFwPvAT8BEVZ0jIjeJyJE1p90FFAAvi8g3IjKpgZdrNCk4D6SAum8AQSi4DEm71N1wyp5HD04p/XR73Aw9cpBZjNfEpM3VIHms6/XjAgkiRTc4GFVu2X5YfxKxZMrxQL6fvY8dkvF4srK9gyaXoVWPQmw6uLsi+Wcj/r2aOEKjsVaXlHPR0KtZXVJOtDqKP99PUYdCHpxxK+26tHU6vKyjiUX2nFj8O/D0R/LPQbz9nA4rp0x6+D0ev+J5YpE4aimBfD9bDejBvZ/cjK+JtnDc2GqfrEz+RuugqhS//w0v3z2J6oowe4wYxAlXjMDjNQvPm5MmFqOhcRCfC74dkbxTEHdXp8PKGXO//IXJj35A+cpK9jxmd/YbuWeTJX4wm7kYLZyqcu/ZjzJ1wudEqqOICL//uJhwVYQzb/+b0+FlLY3/gJaOste/EIf412joJegwEfFs7XR4OWHbwf3YdrDzn7iyurGb0XL99MUvfDzeTvxgvxlEQ1Fee+BtFv+y1OHospeWXw8aAtZ0Vo2BVqMVtzkZVtZLJpJ8O3UOs97/hkgobbFjxmX9nb8mFtp3Nsk/wbcHkncUIkGnw8p5X0yeTSxcf4cp25fvfEWPi/+a4Yiyn2oSEj+ke6Zmq0ejOfw4cx7XHnEHibhdUmslLS57ajT7nODsngpZnfw1Og0tuxC7jjkB0U/R0NPQ4TXE1cbp8HJaoCCA2+MiEa9b/eByuwjkBxr4LqNxXIAPSHPnKXmZDiYnREJR/u+wW6kur1vff9cZY+m3Wx+26OvcXEvWDvuoJtHVY7BXNa5ZxBKG5FK0+mkHIzMA9jtpD1xpOnyqpex5dGYaW+UaEYHgMUD9kucA5J3kREhZ74vJs7Gs1KKaZCLJB+OmZj6gWrI2+ZNcSOpydoAYRJqttZCxkbr26swlj5+LL+gj2CZAXpsggTw/Y567gBlvFTPu+glpVwAbjSOFV4JvMOAHaWP/7t8HKbjA6dCyUnV5CCvNHhaJeNKRhV21Ze+wjwRBG0gckp/ZWIy0Dvzb3gz5627M/uBbXG4X3fp0ZswhtxALx4hURwkWBOjSqxP3f3YL+YVmWKIpiASR9k9hRb+E0Di75YmnF1irwd3Z6fCyzs7774Baqck/UBBg98N3cyCidbL2zl/c3cGzNak/YhDJP8WJkIw0Ctrms88Jw9jr2CE8MPpJKldVra0ACldFWDJvKc/fONHhKLOLxufA6nMh+jHEv4LqZ9CVh6GJBU6HlnW26NuVI0YfQqDWxi2BfD9/2XNbBh6yk4ORZfGdvyYWgWcHSCwAktg/ahKCR0FghMPRGfVVl1cz/6sFKQ3d4rEEU178jPPuOd2ZwLKQll8HWl3rSAw0jlbchrR/0rG4stW5d53KbgftxLtPfkQ0HOOAk/dknxOG4XI5e++dlclfo1+gZedgT/TGAZ/d1bP9f3F5t3c4OiOt9fTyMX1+mo5qYj3lnjMzHk8uSMQTuN0uDjvrAHbcezv8wZbRYyzrkr+qouVjqNvTPwZqQfg1MMm/RcovzGObwVvz04x5daojvH4vB4za28HIso2bhss9zfqXpvbt1DnccMxdWDXj/mopV75wEcOOHORwZNk45m8tbaBvfwIiH2Y8HGPjjRl3IUWdiwgWBHC5XQQLAvTaYUtOue44p0PLGna55whMuWfzqy6v5poj76BqdTWhCnvzlnBVhNtG3s/KJc7vLZJ1d/5IgAY2EjNVPi1ctz5deGHhw0x/40uWLVzB1rv2YdcD/+L42Gi2kcKr0eQSiM0G8dh9fvx7IQUXOh1aVvn0tS/tZv31WJbFRy9+xomXOzv3mHXJX1ztUd8uECvGnuhdIwB5o5wKy9hIPr+XfU/cw+kwsppd7vmMXd2T+A08WyOenk6HlXVC5aG061Ti0QRVZdVpviOzsi75A0jRvWjpqfYQEAKagMChSN5Ip0MzNtHcL39h+puz8Aa87HfSnvTo183pkLKGePqAp4/TYWStgnb5JBNpavzz/Qw+bBcHIqorK5M/VgnknwUaBVdbxLuDubNpZVSV/1z4FB88O5VYOIbL42L8HW8w+v7T+evZBzkdnmGs17gbJvLy3ZNSVvcG8v0MOnQXdthzW4ciW6dJBlNF5FAR+VlE5ovIlWme94vIhJrnvxCRXk1x3fpUo1ilp6OrToLKm6HqTqh+BEwTt1Znzudz+fDZqURDUVSVZDxJLBzj4YufoWxFudPhZQW1Qmj4dbTqCTQ2O2WNhbF5Vvyxkol3vkG0Xutml9vFURcezjUTLmkR5cuNTv4i4gbGAocBA4CRIjKg3mlnAmWqujVwH/Dvxl43Ha16yJ7EImL3LNcQJBag5dc2x+WMZjTt5RlE07R8dnnczHr3awciyi4a/wkt2RstvxGtug8t+ztadiaq8Q1/s7FeX3/0PS53amq1khYVqypaTAFDU0QxGJivqgtUNQaMB+pPY48AxtV8/QpwgDTHW1/oZVLrl+MQnYIdmtFauD1uSPMvRNY8Z2w2VUVXXwhaAYSABGgYYsVoaLzT4bV6eW2CuFyp/3jdHhcFbQsciCi9pkj+3YE/aj1eXHMs7TmqmgDKgQ71X0hEzhGRYhEpLikp2YxQGkrwSt3KH6OlO+Bve+ELpO5raiUtdv/rrg5ElEWSv0Ey3f+vCIRfznQ0WWfw4bsgae7uPV4PB5++b+YDakBTJP90d/D1Bw835hxU9XFVHaiqAzt16rTpkfj3w17BWI9ngNm9q5Xpt2sfRl55NL6AF1/ASyDfjz/oY8zzF1HQ1qzXaJzUCpR1zLh/Y/mDfm59+/8oaJdPXmGQvMIgvqCPC8eexVbb9XA6vLWaotpnMbBlrcc9gD8bOGexiHiAIqC0Ca5dh7S5HI3NAKsau72DH8SLFN3a1JcyMuCI0YcQjyf4btqP9Oi/BafecAIdt2jvdFitn7sPuNqBFa73RAACRzsSUrbZftg2vLzsSb6dOodoOMZO+27f4tqSN0XynwX0E5HewBLgJODkeudMAk4DZgDHAVO0GUoLxN0VOn6Ahl+H+Lfg6YsET0DcKSNMRgv367e/cek+15FMJImGYsz/aiHff/IT/5l5m7nzbyQRgXYPoqWn2T2vCNvbOHoGIPlmIeTmUlVKl60mrzBIMD+Ax+tht4Ocbdu8Po1O/qqaEJELgPexx1yeVtU5InITUKyqk4CngOdFZD72HX+zNRERV0FNv37Ts781u+OU/xCqWHdnGq6KsOy3Fbxw8yucd89pDkaWHcS7I3SaCpF30OQKxLcb+IYh0jIqUVqb6ZNm8eD5T1BZVoUq7HXs7vzzsXMJtuD9qKWl1vYOHDhQi4uLnQ7DcMDqknJGbnkeiVgi5bkOW7Rj/OLHHYjKMNKb++UvXLb/DURD6wpOfAEvux28Eze9MSbj8YjIbFUduKHzzNu80eKkq5Few+PNzkXpRus14c43idVbkxKLxJn9wbctontnQ0zyN1qcwvZt2GZQ35Q3AV/Qx6F/38+hqAwjvSW/LE3XvBOP30vJ4iava2kyJvkbLdJVL1xMhy3aEWwTWFvqOWBof0644iinQzOMOv6y13a4vakl5olonJ7bbuFARBvHfIY2WqQuW3Xi+V/H8uW7X7P89xL6D+zLdrv3axE9UQwDIJlMsmpJKUeOPoSP/vspocowWrMLXSDfzzEX/5X8opZbmWaSv9FiuT1uhh6xbt6quryad578iO+m/Uj3/t0YMfpQuvXp4mCERq766MVPefjiZ4iGo1hJZdChO+NyC99/Opeijm044bIRLWo1bzom+RutQumyMkYPHEPV6mqioRger5u3H/uQWyZfxU77mH2Zjcz55uMfuO+cR+tU9xS//w1DRwzileVPORjZpjFj/kar8NwNE1m9omLtf7hEPEmkOso9Zz5sWhEbGfXiba/VSfxgV/dMf2MWFasqHYpq05nkb7QKM96anXZLvJV/lrFqaZkDERm5avlvK9Ie9/jclC5bneFoNp9J/karECxIv1JSLSWQ589wNEYu236PbdOuRVFL6danswMRbR6T/I1W4cjRh+DP89U55vG62Xm/7U2vH6NZxSIxZrxVzLSJ06lYVcmoa48jkOdHavXs9+f5OeX64/EHW8+NiJnwNVqFERccyi9fLeCTl2fg8XmwkhZbbN2VMc9d6HRoRhb74bOfuOaIO+wNcGq2Ez337lMZO+sOnr1uAt9/8iPtu7XjpCuPZp/jhzod7iYxvX2MVmXpwuX8MnsBXbbqRP+BfdfW/cciMaZNnMF3n/5I975dOeSM/WjXpa3D0RqtWTQc5YRuZ9dpMAjgD/p4cMZt9NlxK4ciW7+N7e1j7vyNVqVb7y506123tr+yrIoLd7+KVUvLiFRH8QW8vHjba9z10fVsM2hrhyI1WrtZ732Tdm+beCzBe89MYfR9Z2Q+qCZkxvyNVu+/t7zK8kUriVTb+zfHInHCVRHuOOVBUwZqbLZIdTTtvx8raaV8GmiNTPI3Wr1PXp6Rtv3z8kUrTRmosdl2PfAvJNKUFwcKAux1zO4ORNS0TPI3Wj2vP/3opZW0+G7qHMpWlGc4IqM1W/bbCqa/OYvykgpOu/FE/Hm+tZU9gYIAO++3A4MO28XhKBuvUWP+ItIemAD0An4DTlDVsnrn7Aw8AhQCSeBWVZ3QmOsaRm1/Pecgxt0wMaWnupW0eGD0E8SjCY67dDhn3DLSNIYzGpRMJLnrjLF8+upMPD4PyYRF35224qY3x/DJyzMJV0XY5/ihDDliN1yu1n/f3KhqHxG5EyhV1TtE5EqgnaqOqXdOf0BV9RcR2QKYDWynqutdCmeqfYyNlYgnuPHYu/l6yg+AEovE13ZXXCOQ72fMcxey59Gt/+O60Twm3vUmz904sU7rBo/Pw9AjB3LdxH85GNmmydROXiOAcTVfjwNSmq2r6jxV/aXm6z+BFUCnRl7XMNbyeD3cPOlK7v/sZk7+v2PxeFJ7q0eqo7z+wNsORGe0Fm8+/F5Kz55ELMGMScVEQlGHomo+jU3+XVR1KUDN7+td2ywigwEf8Gsjr2sYKbbeuTeDD9sFr9+b9vnKsuoMR2S0JuHKSIPPxSKxBp9rrTaY/EXkfyLyQ5pfIzblQiLSDXgeOENVrQbOOUdEikWkuKSkZFNe3jAA2Gr7HnWW3a/hDXjZ4+jBDkRktBZ2T/7UlNi1d2cK27dxIKLmtcHkr6oHquoOaX69CSyvSeprknvadnciUgi8DVyjqjPXc63HVXWgqg7s1MmMDBmbzuvzcslj5+LP8+GqeRPwBbzkF+axeN5SHv7n0yz47neHozRaojNvO5mCdvn4AvYnR4/XTSDfz7+ePN/hyJpHYyd87wJW1Zrwba+qV9Q7xwe8C7ylqvdv7GubCV+jMeZ/s5A3H3qPFYtKKFm8ipI/VhGpjuJyu/D6PJx33+kMP+cgp8M0WpjylRW89egHzPl8Lj237cGICw5li75dnQ5rk2zshG9jk38HYCLQE1gEHK+qpSIyEDhPVc8SkVHAM8CcWt96uqp+s77XNsnfaAqfvDKDu84Yu3b17xq+gJfxSx6nTbsChyIzWool85cy691v8Of52OPowa1+iCcjvX1UdRVwQJrjxcBZNV+/ALzQmOsYxuaa9vKMlMQPdgnfNx/PyYqVmsbme+a68bxyz1ugisvtYuzFT3PN+EsZMnw3p0Nrdq1/pYJhrEewINDgwi63W5g64XNeu/9tfp41P8ORGU77ccbPvHrvZGLhGLFInEh1lGgoxi0n3UeosvX37tkQ09XTyGqHnXkAUydMJ5qmTvvuMx8hEU+QiCVwe9zstN8O3Pja5bjTrBMwskcsEiMeS/Dh85+krAoHcLtdFL//DXsf17r6828qc+dvZLXth23D3645Fm/AS7AgQF5hkLyiIAVt86kqqyJcGSEeTRCpjvLNlO+Z/PiHTodsNJOK0kpuPPZuRrQ9jWM7/p2pEz5P27VTgWQibTV6VjGbuRg5oXRZGV/973vy2gTp3r8b/xg0JmU1J0DfnXvx6Fd3ORCh0ZxUlX8MvpKF3y9K2wG2Nl/Ax/glj7XaYgCzmYth1NK+azsOHLU3AH/8vKTBeYBkmha+Rus3b/YC/pi7JCXxi0twuV1YCQu314XL7eaih89qtYl/U5jkb+ScHv23oE37Nqnln0EfB47am1BlmGQimRMJINvEonHefeojpvz3U/x5foafexB7HTuEZQuWp+3EqZay/Z7bMGDYNgTy/ew/ck+69emS5pWzj0n+Rs4REa4Z/0+uPOQWkkmLWDhGsCBA937d+PLdr3n22vEA9BzQgzHjLmyxe7UadSUTSS7f/wZ+/fa3tUN6P82cx9dTfuCYiw9PuzGLP+hj9+G7csJlm9StJiuYCV8jJw0Yug3PLxjLmbefzPGXHcGY5y+ksrSKHz6bSyKeJBFPsuDb37l0n+uoKK10OlxjI0yfVMyC7xfVmcuJVEf54NmPcbldDDp0Z/xB39rnXG4XwTZBDjszZalSTjDJ38hZRR0LOeaiv3LOnafi83upKK3EStat8kjEEnwwbqozARqbZNZ7XxOpSu3M6XK7+G7aj1wz/hJOuupoOmzRnoK2+ex70h48XPzvnB3eM8M+hgEsW7gCK015XzQcY8akWUwa+x6ly1az9c69OeeuUxgwdBsHojTWp33Xtnh8bhKxusM74nJR1LEQj9fDqGuOY9Q1xzkUYcti7vwNA+i3W5+0raDdPjc/zfiFpQtWEA3FmDP9Z6446CbmzTZbUrQ0h5yxH2536gI9r8/DoMN2diCils0kf8MAthm0NdsO7re2nS+A2+PCilvE65UHRkMxxl1ntqFuabr17sI1Ey4lv20eeYVBggUBOvfsyN1TrsfrS7/BTy4zi7wMo0YsEuOl21/nvaenkIgl2PWgHfn8jS/TLgZr360dE5Y87kCUxoYk4gnmFf+KL+Cj7869GlzTka3MIi/D2ES+gI/TbjyR0248EYBIKMrnr3+Z9tzu/VpXj/dc4vF6zJzMRjDDPobRgECen+HnHYw/z1/nuD/o45TrjkdV+XrK97x0++t8MG4q4eqG94A1jJbG3Pkbxnqcfeco/Hk+Xn/wHWLhGB22aM/5953O9ntsy7/2u4FfvlpALBzDH/Tx6KXPcs+0m+i9Q0+nw85JsWic+V8vJFgQoNf2W+bccM+mMmP+hrERLMsiGo4RyPMjIoz/9xu8cNPLROu1BO65XQ+emnOfQ1FmtyXzl/LSba/x0xfz2XKbboy86hi2GbQ1YG/ac+/ZjwBgJS06du/AzW9dSY9+3ZwM2RGZ2saxPTAB6AX8BpygqmUNnFsI/AS8rqoXbOi1TfI3WrK/b3cxf/z8Z8pxX9DHY9/cjQi069KWvDZBB6LLPgt/WMTFw64mGo5hJS1EwBf0c+3ES+naqxP/GHRlnTdiEaFj9/a88NvDaXv6ZLONTf6N/VO5EvhIVfsBH9U8bsjNwLRGXs8wWoSG7pmSiSTn7XI55+96Bcd3OZP7zn2MeCye2eCy0BNXvECkOrJ2BbYqRENR/nPBk7z16Acp5biqSlV5Nd9N+9GJcFuFxib/EcC4mq/HAUelO0lEdgO6AB808nqG0SIcdNo++Gr1iVnDSlhEQ1HCVRFikTgfvfAJj132nAMRtk7T35zF6EFjOL7rWVw34t8s/P53AOZMn5v2DXfVklJW/L4ypS0HgCCUl1Q0d8itVmOTfxdVXQpQ83vn+ieIiAu4B7i8kdcyjBbjuEuGs/XOvQgWBAAI5PsRl6TsDBUNx3j3qSnEoubuf0MmP/4ht/3tAX6ZvYDVK8qZObmYi4Zdw8IfFlHYoU3a73G5XQw5YjcC+f6U5xLxBNvvYUo+G7LB5C8i/xORH9L82tgeqKOBd1T1j4241jkiUiwixSUlJRv58oaReb6Aj/s+vZnrXrmMU284gdH3n0F+UV7ac9WyCFWEMhxh65JMJHnyyhfq7LW8Zmjn2WvHc8LlR6aU3PqCPg4+fT8OHLU33fp0qfNJLJDvZ8QFh9Gxe4eM/QytzQZLPVX1wIaeE5HlItJNVZeKSDdgRZrThgJ7ichooADwiUiVqqbMD6jq48DjYE/4buwPYRhOcLlcDDx4JwYevBMAn7wyk+L3v0k5r6BtfoN3roZt5ZLSlIZsYI/d//TFL9zw2uUs/30lrz/wNh6fh3g0wR5HDeb8+07H5/fywPRbmfzoB0ybOIP8ojyOHH0Iw0YMcuAnaT0aW+1zF7BKVe8QkSuB9qp6xXrOPx0YaKp9jGz067e/8c89ryEaiq0d/vHn+bj0ifPY8+jdefmeSbz/7FSspMWBo/Zmr+OGMvmR9/nlqwVsvUtvjr/sSLpvnXuliQDh6gjHdfo7sUjq8Ni2g7fmPzNvB6C6IsSf85fRacsOtO1UlOkwW4VMlXp2ACYCPYFFwPGqWioiA4HzVPWseuefjkn+RhZb+MMinrt+InNnzadbn86MuuY4djngL/xrvxv4edZ8YjXliB6fh2QiicslJBMWbo8Lb8DHPR/fQP/d+jr8Uzjj/vMf43/PfVKnZNOf5+ea8ZcwZPhuDkbWumQk+Tcnk/yNbPHttDlcM/z2lD2D09luSD8enH5bynFVzboVq+HqCO88/iGfvPoFhe0L+Ou5BzJz8mw+HDcNcQlev5dz7jwlZ3fa2lymsZthtBA/fzmfeDSx4ROBuV/Or/P4w+en8fTVL7JycSkde7TnjFtGcvCp+zZDlOn98fMSKlZV0WenrQjmBxr9eqtLynnnyY/4+ctf+HHGPEIV4bVDPd98/AMnXjGCV1c+Q2VpFe27tsXtSe3PbzQNk/wNo5l12rIjvoCXcFXqhGZ9a0pHAf73wjQeOP+JtRUwKxeX8uDoJxERDjplnwZfo7oiRKQ6SvuubTf708LKP0u57sg7WDR3CW6Pm2TC4pw7R3Hk6EM36/UAFv+ylAuHXEUsHEs7th+pjvLS7a8z/LyD6dTDVOk0t9xa92wYDtjjqEH4g74NJmJ/0McR5x+y9vEzV4+vU/oIdunjY5c9x9k7/otD/Sdx8lbn8+7TH6GqVJZVce2If3Nc5zM5pe8/GNVnNF999P1mxXztEXew4LvfiYZihCrCRENRHr/iBb6dOme93/frt78x5cVP+eWrBSnPPXTBk1SvDqVN/Gt4fB5+nD5vs2I2No258zeMZrZmTcAtI+9j0Y9LQKBb78506dWZb6b8gC/gJRaJM2zEIE6/6cS131eyZFXa1ysvqVi7crXkj5WMvegZwlURpk2YzrzZC0jUtDpY8ftKrh/xb8YW/5ue23bf6HgXzV3CHz8vIVlvT+NoKMqr90+m/8A+fPLKTFb8vpL+g/oy8JCdiEcTXHPE7cz9Yj4ut6CW0nenXtz27tVr+xt98/GclEVw9akqhR1yc0P1TDPJ3zAyoEf/LXh09l2ULivDspSOW7QH7OGVJfOW0r1f15QFSV16dmTZbxte7GgvhJqAlUyuTfxrxKJxrvnrbaxathqPx83+J+/J2XeeUqfhnKry08x5LPuthH679qa8pAK31wOk7mC27LcVjOo9mlg0QaQqQrAgQI/+3eg/qC8/zZhX565+3uxfeeSSZ/nXk+cDbHDoS0QobN+GAcPMqtxMMNU+htFCfTz+c+456+G020jW5/a48Of5CVWE13ue1++h945b8dDM2xERVpeUc/kBN7LstxJEhGQ8wcBDd6b4vW9Shmd8AS/5bfNZvXx1nT47voAXK2mRiKcmdq/fy9uh/yIi/OfCJ3nvqSkpr+v2uvH6PHTYoh23vjFYeSkAAAeHSURBVP1/ObvWoamYah/DaOX2O2kPRODpq19i+e8ldNmqI1ZSWf576qcBb8C3URVF8WiCRT8tYc7nc9lhz+2487Sx/DH3T5KJdYl79gf/397dx0hR33Ecf3/uuIdQoB5cKSBwcIWANnfpUUup0AbQaiFGqtRY2lQxYCVNtTRtAi1pY7RJS0NrYiwRqiaSGGqqtqUWYvRO+5QAEp4Oj3jy4MnlgENtr/K0e7f36x87rPewezfcw87szveVbG5253dz3+/8dr8385vZmUPM+Wo1B2qPpI45FJUWMWbcaP7b2tbrAmt9jeF3tHekTlO9f+N3aGpo9oaGCuhMdDKjZhrf3rCcsRPLqKyuyLvTWcPMir8xIbbw7vksvHt+6vneXQd45K5N3fYGSkaW8K2f3smZk63UPvfPjw8SC0izY+8SnZysf4/p1RUcqKvvVvgBYhfjvFv/Ho/uWMeLj73Mf862Me+2z7NoxXy+W/WjtHEWlxbRHu/AdX78ByWo+vJ1qevpl44sYVPtw5w43ERTQzNTZk9ixuemD3DNmMGy4m9MDpm7pIZ12x5i64+3cebdVsaUj2bFT+5g+drbcM5RWT2VPz2+iwttF5lQOZ6TB5uIXe4+bFRQWMDkWZNoj7WTaUP78sUYNYurqFlc1e31aVVTObb/ZLcDt8WlRSxZtZi67f8mdilO/FKc4tIiikqLeGjz/b2WXVldQWV1xeBXhhkUG/M3JkclEgkKCzN/CepC2wXumfkgH314PrVFPqKokMmzJrH10G+QlPaOZIUjCrn1vkX8cMsDvZbZ3NjC2gU/I345TuxijJKRJUy9fjKb6h4mfinOzqdqadx3nBk101iy+mbKxtv1d7LNLu9gjKHl+Bkee2ALh//eQEGBWHDnF3nwidWpq4w27G5k3S2Pkoh30B7voGRkMaPKRrH5zV8xdkJZ2mXGLsX410t7Odt0jllf+Aw1N1VF7laJYWbF3xiTkkgkkJS2SLeeep+/bXmVU40tVC2YzS0rF/GJMenvTWDCz872Mcak9DU8NH5KOff9YkUWozFhYPtqxhgTQVb8jTEmgqz4G2NMBFnxN8aYCLLib4wxEWTF3xhjIsiKvzHGRFBov+Ql6RzQNMjFlAPvD0E4YZAvuVge4WJ5hMtQ5FHhnPtUf41CW/yHgqR9fr7plgvyJRfLI1wsj3DJZh427GOMMRFkxd8YYyIo34v/1qADGEL5kovlES6WR7hkLY+8HvM3xhiTXr5v+RtjjEkjr4q/pLskvSWpU1LGI+aSvibpbUnHJK3PZox+SBor6VVJ73g/095VQ1JC0kHvsSPbcWbS3/qVVCLpeW/+HknTsh9l/3zksVLSuS59sDqIOPsj6RlJrZKOZJgvSY97eR6WNCfbMfrhI4+Fktq69MfPsx2jH5KmSHpd0lGvXv0gTZvh7xPnXN48gOuAWcAbwA0Z2hQCx4FKoBg4BFwfdOw9Yvw1sN6bXg9szNDufNCxDmT9At8DnvSmvwk8H3TcA8xjJfBE0LH6yOUrwBzgSIb5S4FdJG/5Pg/YE3TMA8xjIfBy0HH6yGMiMMebHg00pnlvDXuf5NWWv3PuqHPu7X6azQWOOedOOOfiwB+AZcMf3VVZBjzrTT8LfD3AWK6Wn/XbNb8XgJukTLcSD0wuvE98cc79A/iwjybLgG0uaTdwjaSJ2YnOPx955ATn3Gnn3H5v+iPgKHBtj2bD3id5Vfx9uhY41eV5M71XfNA+7Zw7Dck3CjA+Q7tSSfsk7ZYUln8QftZvqo1zrgNoA8ZlJTr//L5Plnu75S9ImpKd0IZcLnwm/PqSpEOSdkn6bNDB9Mcb8qwB9vSYNex9knO3cZT0GjAhzawNzrm/+FlEmteyfspTX3lcxWKmOudaJFUCdZLqnXPHhybCAfOzfkPRB/3wE+Nfge3OuZikNST3ZhYPe2RDLxf6w4/9JC9tcF7SUuDPwMyAY8pI0ijgRWCtc+5/PWen+ZUh7ZOcK/7OuZsHuYhmoOsW2mSgZZDLvGp95SHprKSJzrnT3q5ea4ZltHg/T0h6g+QWRNDF38/6vdKmWdII4JOEb3e+3zyccx90efp7YGMW4hoOofhMDFbXAuqc2ylps6Ry51zorvkjqYhk4X/OOfdSmibD3idRHPZ5E5gpabqkYpIHHENzpoxnB3CvN30v0GuPRlKZpBJvuhyYDzRkLcLM/Kzfrvl9A6hz3lGuEOk3jx5jsLeTHLvNRTuAe7wzTOYBbVeGHXOJpAlXjh1Jmkuyvn3Q929lnxfj08BR59xvMzQb/j4J+sj3EB9Fv4Pkf8wYcBZ4xXt9ErCzx5H0RpJbyRuCjjtNHuOAWuAd7+dY7/UbgKe86RuBepJnodQDq4KOu6/1CzwC3O5NlwJ/BI4Be4HKoGMeYB6/BN7y+uB1YHbQMWfIYztwGmj3Ph+rgDXAGm++gN95edaT4Uy5oB8+8vh+l/7YDdwYdMwZ8lhAcgjnMHDQeyzNdp/YN3yNMSaCojjsY4wxkWfF3xhjIsiKvzHGRJAVf2OMiSAr/sYYE0FW/I0xJoKs+BtjTARZ8TfGmAj6PwPa2wbrfyycAAAAAElFTkSuQmCC\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plt.scatter(X[:, 0], X[:, 1], c=lable)\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.4" } }, "nbformat": 4, "nbformat_minor": 2 }