From c0a1931321b3264aaef93861301c3b1931516918 Mon Sep 17 00:00:00 2001 From: haotian <2421912570@qq.com> Date: Wed, 5 Feb 2025 17:19:24 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90--KNN=E5=88=86=E7=B1=BB?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ml.md | 33 ++++++++++++++++++++++++++++++++- knn_classification.py | 41 +++++++++++++++++++++++++++++++++++++++++ output/knn_c.png | Bin 0 -> 24033 bytes 3 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 knn_classification.py create mode 100644 output/knn_c.png diff --git a/docs/ml.md b/docs/ml.md index 97bc22d..81938f0 100644 --- a/docs/ml.md +++ b/docs/ml.md @@ -234,4 +234,35 @@ 特征选择: 在特征数量非常庞大的情况下,随机森林能够通过其特征重要性评估功能,自动筛选出对预测有重要贡献的特征。 非线性关系: - 当数据中的特征和目标变量之间存在复杂的非线性关系时,单棵线性模型(如线性回归)可能表现不佳,但随机森林可以通过多棵树的集成来捕捉这些复杂的非线性关系。 \ No newline at end of file + 当数据中的特征和目标变量之间存在复杂的非线性关系时,单棵线性模型(如线性回归)可能表现不佳,但随机森林可以通过多棵树的集成来捕捉这些复杂的非线性关系。 + +K近邻(KNN):基于实例的学习方法,通过测量样本之间的距离来进行分类或预测 + 原理: + 距离度量: + KNN通过计算样本之间的距离来判断样本的相似性. + 欧式距离: + 曼哈顿距离: + 分类: + 对于一个待分类的样本,KNN算法会找到与该样本最相似(距离最近)的K个样本。 + 然后,根据这K个样本中多数的类别来决定待分类样本的类别。投票机制:选择出现次数最多的类别。 + 回归: + 对于回归任务,KNN则会根据这K个最近邻样本的输出值进行平均,得到预测值。 + K的选择: + K值(邻居的个数)是KNN算法的一个重要超参数。如果K值过小,可能会导致模型过拟合;如果K值过大,可能会导致模型欠拟合。 + 通常K值的选择依赖于交叉验证。 + 优缺点: + 优点: + · 简单易懂:KNN算法实现非常简单,易于理解和解释。 + · 无模型假设:KNN是非参数化算法,不需要做出关于数据分布的假设。 + · 适用范围广泛:可以用于分类和回归任务,适用性广。 + · 良好的性能:对于小数据集,KNN可以达到很好的分类效果。 + 缺点: + · 计算量大:KNN的预测阶段需要计算待预测样本与所有训练样本的距离,因此计算复杂度较高,尤其在数据量很大的时候,时间开销大。 + · 存储需求高:KNN需要存储所有的训练数据,这对于数据量大的情况可能会成为瓶颈。 + · 对异常值敏感:KNN算法对噪声和离群点非常敏感,因为它只是通过邻居的类别来决定预测值,容易受异常值影响。 + · 特征维数 curse of dimensionality(维度灾难):随着特征维度的增加,计算距离变得不那么准确,KNN算法的表现会显著下降。高维数据使得样本之间的距离差异缩小,影响模型的判断。 + 适用场景: + 图像分类:例如手写数字识别、物体分类等任务。 + 推荐系统:通过用户相似性或物品相似性来推荐内容。 + 语音识别:通过语音特征和其他样本之间的相似性来分类不同的语音命令。 + 医疗诊断:例如根据症状数据预测患者是否患有某种疾病。 \ No newline at end of file diff --git a/knn_classification.py b/knn_classification.py new file mode 100644 index 0000000..b77a80c --- /dev/null +++ b/knn_classification.py @@ -0,0 +1,41 @@ +# 导入必要的库 +from sklearn.datasets import load_iris +from sklearn.model_selection import train_test_split +from sklearn.preprocessing import StandardScaler +from sklearn.neighbors import KNeighborsClassifier +from sklearn.metrics import classification_report, accuracy_score +import matplotlib.pyplot as plt + +# 1. 加载数据集 +iris = load_iris() +X = iris.data # 特征数据 +y = iris.target # 目标标签 + +# 2. 划分数据集(80%训练,20%测试) +X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) + +# 3. 特征标准化(很重要,KNN对特征尺度敏感) +scaler = StandardScaler() +X_train = scaler.fit_transform(X_train) +X_test = scaler.transform(X_test) + +# 4. 构建KNN分类模型(这里K=3) +knn = KNeighborsClassifier(n_neighbors=3) + +# 5. 训练模型 +knn.fit(X_train, y_train) + +# 6. 预测 +y_pred = knn.predict(X_test) + +# 7. 评估模型性能 +print("Accuracy:", accuracy_score(y_test, y_pred)) +print("Classification Report:") +print(classification_report(y_test, y_pred)) + +# 可视化(仅用于二维数据的情况) +plt.scatter(X_test[:, 0], X_test[:, 1], c=y_pred, cmap='viridis', marker='o', label='Predictions') +plt.xlabel("Feature 1") +plt.ylabel("Feature 2") +plt.title("KNN Classification (Predictions)") +plt.savefig("./output/knn_c.png") diff --git a/output/knn_c.png b/output/knn_c.png new file mode 100644 index 0000000000000000000000000000000000000000..d83b8f6a479ce5bae4be7dafc7a517f077a1cfe8 GIT binary patch literal 24033 zcmd?RbySt{)-L+eEg&f!ix7~IMoK^gR6wK~q(n-jyFo$$MMYE)q)S1%Qxs590TBeG zyHo1U*S*j8?S1Zd&iKZ?s{~q#hlN4o@f5l^Rjind&|{DR8U$_ zM9|Iku7`*Kn}dgk+g%wUA?N>inxLz@y$~jjLIEyCRVy339 za#7dk`SLGsAL{;N{55Z{hfc&p5s9bRF}Or>)GZ;&xY$H&VPUZe9MfSwG%eV>ez$Z= zI4)hfsG>+AKz;F1+*cYEKW$15ISMsi_PTl7-NWOUA=WFzX~ILlmg>`I&#-#W^nBWN z`p|e)nv;kfHwONxiRe}ehM+$c#bG6)zp$c5?!kBJsQ-f=Qez|}Xy3klD=~chJ^u!~ zdh$^H#DsPI@t;LPBBD@@Y^9UqBP=8tW3})-U%&Lu+?Q7l-}93Ct4tQgTf*J$+-d2E zqjT18d*QV@N~WIt#(&r4n{16mE)BoFVlu|G+U;WHY|(vqPL@?$6fZCDn_J8(;t5!Z zdDz(sYSHAZ5^1I1=D)nXdAYi_)_QTE7&%t>fs2dFCMj9fb64E)J0ZEk;hP~@^<*~n z(=(r5++MHbPk#CGzJWy`O;S>lo40p#bTq-wD%S^RMD5r_MZdMO40o29=q;A}Z?HOh;$uGkKw8Ow0TC z1iNFw3Xjj3;AizYv^f^K3=|ptsJ@d`+@1I3%PZyUhK4Z@6pnukWK;ADTvVAhZVaeF z*iJFa*gVVqHm~yjK69jM7Ntq0lSps+dD~co4TPANc2KFTXP@1qGYC zyZcJ*ax9aqkM`c5Kg0$G1|rt&gl`@CIM6SVfIYY0zkjp)ZOvIZGEz}-T3cHS1QOX8 z=;~rNHa2=@bz2C^maWr z*48MLqe#z+HdR*}PEAh}W%c=xr+l2;9<-o)_3D+^b&~7XezPcYkl5PVva_>esjI6S zHU-J~Z7=BMT+`L1p6N*qudkPldnwAtM?612Z&>ehr^4}LPfvT+19{>K8W@s^4ix>hN7%SI;|}nVJ2bnzG6M zc${8dE-J>5&|gJ@bUzWg+!jT)-i$;3$Oy(F(mp+q_Otwf08Bc~(r^_y8G~4JYb42a zU0vOk%`*wAQ?s*!YQ^qNnvN9=aD7`%$~TcbFMY7-gv{IFt(?q=uP0a`m@-8#FNxDs zRCl)Kt`}J}u>}6vI$QN?>chh%SbUe_XpOe&&1yX^R=NCI`*dN|kcq){cl|vpr?@!H z=1i}$jg3v}G!_Qqf4s5ESuQbri>nnAuN`zJen#q{@y@@#35uC=APDBZ+;k4(BpK8)nrzJ2-W|~yF&_=R(dwa{S zHRE)B_|USwIM`d+Qp?{C;{t&Xv> zu&}J{?!M8Dj;m;iB4U4ewa1pPiALnz$+dDfmZMz@uZGKjuq@yE%Tl!vV!Ma+%shL`wT7DvIqeW4XieHcGlnXuE)g3t2jFH4HTP1kBpdBS67dZ)Z9hqktO)>PDErR zyPO;|Yw)26gqpS4^k5DtDf-@L;%!^=-$Z;jY~mTjiOJ=*D3FZ1v!AA23fb zkEmfmm$vS5z+O3f_N)Vp8`tX78o2DmV*Rw`i@$2_@-!a*xs5Kfwe9UoS*i(%u;&O^ ze442#jt&pknof?$+oH*%%}d``-<7cQ)_4$V~v5d+i7|FW!oYS9R7NKEanal zd2U`_w2YE2MQ@zvr9%cwE$IArmMD?-df&~f-TX2HZc9JjDiN|zOiZX)T4r?h_KFYh z{Q87dWKvb)@GU2yBd~UpsTuP2b!~0Sff=|f4mLJLbfe|?LhLX5;#iRhQ{Fo30(&`C zel&l}v$i}3w(g@_B#Kv4&v$J3tc|xQW$UCIJbU!AFeN=*h!j73sBClgGf9FfXO337 z%QJ%^=@3W=lo0%L-ovd@Bkl2LM0#y&CkQ%5KQ4|c?d8#S^|^JqR7HVKAl zNIe7ra;CX08Y| z=;j;`f6gwPV`~2T`EY-8Hj+Zgw9e}qeDau=a{kX6a!Kd};hBIBddyi7>*DcH zOyzAg-WxkRo%g7C-2QCMI}YBU%<79l!>8+5BRp9-bvirxsyG9gZb7obZTxU7N!L-8 z7c!n--rc%UeyrO8*d#;0a2=LeYHzx*6?O#09$*=J2?criQKwRUh*6MC?yQW|XjI+Z zoVkW5{;KutHVaz#eilM#%jeJJ=(Z+c4F~}^@<=)!;6?aMZ(14)3HzI%BfqWXVLBy3 zbmYajFc`($Z>i>K=S(WuczL^=9+cJ9)!lM6vmGe4AXiTow*C0%e0RZJ^Rb=fVH6nM zne0p*y@Ak6yJOxNpKClh_AlRogws;~S^l=)(!@mAedY_#8dgR}N2>$&&jV=k7+fAK zHlc$ZJZ;{uHAM*Udu3wsfkISV90?@fr036_`egLTJo(^iSv%UCbaob_2%r<*DUX^p^bNU1BYtIz3`kDs^>4JiS_8=1X{JB8` z*g(b2%`G*<%rEcHr}aM!5>AFQ(hCE{aggwg-pSp0?;DxTAnq99JX~o7k>W?4x6s$G zU)O$lkF^XA4i=di8a^GGgcXn8$d$(eB6wY2Z$Z9AGz8nvE?-emQAuqccz5et-9X^Z zk`XQeLEHQH?=yo&ugx#|%~qP3no_W^n9q2+e#y9)TDuzXYs_bo46r%@^93)JhuqhM zA>|R1Z$54$-*LN6eEpgwf~k#zDZSbK_*_?axAFrPIk)+**>xq~DsCGfZSFLn%-+rM=hI{(gT==7B*f|npIyz!X->e#Q(TyEFf zy0<>r2k#tkyg$45JDT;4^RNV@-&V)T>HPi$_gMq#C5@DqtcKUMx7OAa0|I1gy;tuG zn$1O?3e9qFChoo|e=WU7a^qyn%Sw3@~+Z09gU=jb`q68&|n7x3;ytwQ9qc-5t5Brltlr7f_=d4dEmMw(8zo)&n<~ zufs{!lje^p{C8%0&fH*RWo0F0lpwVTSjU6U5CM_6+g*|z)~Q2<@gYD&?`17hQzrSN ztsA5aVuW)3J1TI|)I!z5G6NnlF=~Sn)3fEd+c3L1)9$v7{wcIo1aVL<_bc8Gz6N45Sw zKI0#F(%UztyOWZW!(iWA0y?*qhv=SOx)z4vxZI4W*}OurN1RY&bE>F4q&UI`bBkLC z!#FRpZ@x{5>g2le*zkMM)?6PUF)<)Rs-UNxSoCea%Q+)}w(^{le~uCl$8` z0T1*$y@X;8G4y!yXtcq<%~II%cWa~_dY2GwJ~ES+$t(<(K1fWYh+93jJ_{uT77o7U z(Vy*U{JG&1k#BY0uBJ8acn|OYG(~2QVeI7xEX8Xd-C%I6EMp4B`!2I~ z@T3QX0XAZJAiF^bo5R@7a&j2mN_Xzup;ZV**OImM8~e{JaX-bu;RtHt_UA($nOPDm9hh@=-UoE;?r z@j)e#0o%{vO9qypd3_Aj0m$|1*K-;$aGRH%oQiIdRsa^d2_fERy@T%DO0X?pzevDw zlp-P`^x}@x&%|#>0p7A+{#k*BrTT`3b@Xi^@z6^+(aU(R#E%7^FvBxceSE5i?ux_K zhxiP|ng~=SP=khQzK}_g4nD;@)XhLg7ae?ZFjnpM8~f+GTjA)tq)9lp0t(|}?tEPU z;WXN{aUWla(CD+=!D{eH9K?oKFz;wWcqZw3KR%w6NzRXYxXM*>xq=aXNh@d?(-KZF z37{BVRsdtiS5|@so!dJ)e%H*tY&%$Odhjh*i&I2|5{dy7x&Z*XnjQ}M<|b^`r;@HL z0Qo6tX`|4)^p%HQa`l-Q5nvo;YikY`-ziEA56>jjo2^H?W3FB;(b;}GOZS?a6(Ks| zL479WyYcrP(8B!1r0-N0B|6>!0`x}luNPY#kvzEP82vHI+84419)b>BTxKRmxs~OL zu8hhh+qUMBlC4S;8s|D$*te9W^&7F(tBnT{g@uJcOwcV4SJ8>ue}eV(sp#==bf^eJ zf;F%S9AaX+4q^;_mCh#XkRejeOrX=33AJzQ*q8;1RRA`}218hxSm-azkr1`(p@2wF z4b#%v+j|WKP_RQ|p|ZP?=6?oXm5?1)1}{E2i@@RGVFZj5%$ha8#hh188=IRQuvb;I zwG*Klp@NE)@?dvWXqVOp=It~rAv#S>O*`e*ks)vPh^~(xPop0J3P{>dpFU-(KjgLs zP-p8xqu=Mxz`$U<@`cA+#&0VRVGBCmw~sT=x}f(ikUc_8ON$QTD-DnUtwTdbxcK<7 z5J}=7U_7m;^I6aInM%4G0l)#kJPnFPf7E&|nnj0FX4)9OlD<0=)77O0`;h}~UIoh1 z_9V{BSDj%xxqy%0gYpU&`L^gjD=eH1i-nhilQR-vI8=`mH#_4gq5LkJ+pa0^1WLxx zWBI2Zlond(*jC@Ux&HHZX=>o*2nv+lpde$Em?|FcdZn&3GTmdt!BO@M?lBGDl6#S# zmsb&L4Bbl8nmjeixQD@`?5k8NG+V`Fm+89ty7ETIx)O4!IDB zWGcjM|KmHN1`l5glm7G9|I@<@p(8ke@E|}#A#`Kl`T=l^c{7CUiBJcQk6Y&HejK6e zM106gOl!g*xS2e;2v_Tel+6WfP4j^54_usaIo<~EDX1X<1v#6NQBqPGDU}X#VleGX zEMGL*;Kdr`2aXlS_=*6Eja5J7x}M!^mV~Dzg+cyXooQz?F&S|mCv0|i1c4^p$B6V!XUu>TMIlzvS-U%Wl11%s4IBboKP z^a-{Wt{fcx7!`Syor9FB56^Je_q?y2A`P*jQ79QPbJ^q1)+u}wxUHpMl;?Hfoj6g= zpL&g9(#L z|CN48d`#XmQx@Jc8+bI!0@_%bz3kGG6?S^3fI2VA-0fO{C*r5nE?w444sp>^h#4?T z8_p>Esa~vqb0jk^5(d2UIEVn}Fpo0I~ugdMZ`nmGU>tn^P9QAt2 z<@>!X4q-KQxmmtqCn;A|D&nRX2=Z5QL%uNwH$Bf{+b@cm`Z^#HDb1$-=v1ewUe4em zO2fU-Bq-Luz3A?ku++n3y2pvf$0N@1Gpgm%q|;)uV?!K|5a;HzQ$b`4?A3QNio4l4 zYV9-kNG*F1-O$A645NXOeB-N9xqh;p@LT|12{SIRY8&~PF#A&e!=!$SaQr6rm*$S`{w_=h_{r+%AS zUA0iALAUV`L2jL7J~PT^007tXl?x6I_VM@cwxB>a_Y3!@av}XRz{X@`umM!VfgD-x zDUDuS{FBuVqOYf|O+hPU9uK8gMn(pLVs$4cfm2LUA;3$d)M;M4h(%0HeD%S$Uqi)5 zE-0{*6RdG8A)WTUn?D(I%mI={%6~@yEtK>M^;7CTp}dsyPqEu6XaLmZqz)$B^MYK} z4hf3SRQ}di%$$eJH%PWz{Q8&S85r`86)XWQ9i7u*VPSlxC4CMVeGWy2aPO2!hfLgv zoxOe9a>Iq-W7*{7X?K7G_%rn;phPhY5|c92}8A z6Qd95{||k5=P9xWq}D4ag;35J7-;~4W`jcw{*pf{ZW91C91}xWWcW6-a}gbF4Hzzl#wmYICr+3 zFo(BTzVTFtiLiU_WENuj&mCYi60|y7T8yCCY zS3SKK^udchK{XFU1BHG7ij(EaG${1Yi<>o-DA3cv{RTw5?S4p*1&4RqsUNC>#S^Eqn<#nT2vXFie{~aeE zU*FW6zsX<4%X*ORAVbIC(DOV)ywuv!bx2Z0hBWZ(eQHJo2L}fv2p0((eer*Vn}d@?c&s5q5Y1x2{Z<;w=u z_f@li;?JM|nnz3QFhw5TVt9+uK7s08qcOi8yi8XldI;y~ix&y6Ut>Ty!{R+N!v!P& z5VwfN&L|m+?2o@ip_KOulX>uw=W`iPV%ESd%D)8e#z+22-gL*BJ$u#y5AqC1MJt~@ zA`35^U;)6XoE64e1Mb*ixboc3N@o&;ULi;peu(?i1r4o4^e*#mLR0;Rt) zAXZ`T6;s&rkCdCWE54Jhb#98L3wo!1RL66c(;|KOCnBW~))`+q=3|{xl0fEvhWW?Q zJA^-K1L*Xx9WV^)xF85dU1^Jxd95|fijZ)-{EnxJ3hvr2qa{+$bBJ8`g%$FN+f32i zOMXF;NU0&Cwo(ufn@ii6E1m_elI{&CYoEO%sq#F74y*gqyMHy~uJiv3^!Go3!T;E1K8Wf7^t^=iuN>uGBO&rbd;s%^b({R3R159^-?^srXY*EJpDg@9@# z%zy_Us+zpQbb2?Nr(0AO6Jfu;5K_q;I6*g;^6uT~$a2toVv$Pbsj64Ngdv?+m%=YAnC* zyx*^2@|Mqc*>qF%yCzNWInoYQr<226Aw**(3h3)Gv|F@_If7cVMD0G@M~yIlJIc!$QbHOR8?| z&sh$Rf(8H_*2$PxpYwe3zNfHqT=Qv6qbW=_Xx;q9C)ZxAQ~1SRm;4j~B!LPB^iwty z1ycU#Ds82Zatp8!i!XAWE|~fzTqciyf7N8=e2Q^ovuY5%@Ua!Y0qi@B5WZr;>EZ`G zv`cCCp7O{jFTa-P-QC%3ed?<$;`r&VM3E*-){Ja)-`(iu;jwNpt>xFMJyb8=T8>?H z2;@^B)l^ZjS;e$;pDDanI@s3TO(OH+lyULEz_j6ul_-|8JU4z%EX2oDTG@qup`@mx znRNP!M?FLL%BuX&+J@e!|5cT#m`BG4WNVsi9^~}_6%N~plRzMFwp@F%; zg3bN^I*pAIMa0aV;wiOg3;o`WglKLvW~8P!CGZ1+paVG6H}YY6ezSm8& zL(V&#qHgQPuIM1=U*U|zFsqu-pJ28o~ zJ}YI?bJU=LI7#_pKk-NvCcJK!dXdodtF86X2P%oY_!zaIQ#1&gK*Yc}0DS%2_k5~T zEV71H!~d`&lz-^&?~m<2og_Epw(z;Ga=$Z70;V+-KtpNcA7aog-ak5f!wocFU}Nz? zpR4v-HjZ2b5MbKi*Dq#P@6#7cLzN`=p{x7SP+;(h7Sh$#U9JxZOZ=l1_Be<&!tPUQ zDE|kw_4|pAxZf))_d$l#tGCnO~my9T6#e$msIC3R&X*E~#q>olLbQp}SlG%!*H z(x)g9Kqq&AhG>8PK5Zsnmk++*1pft1$rA{{U%qHZL`0zUgw&nPjZOdm$T04t;l}U6 z-ag+v(Kr*?eB+$4$y*2z&n79b)&Oe?)05inj6-T-J9n;l#PgYib1dAF6`;C3;Crp0 zTCTZkZwfw!*5#g;a*XEY<~e6E7?pt_ilk+X>PR#JW7Ok1I&Cg>pFAtx(;Ux!WSr;V z*q2s8itf+NIgql*(gPzEbMIaYfVJ`2*=Rsx)vcaDq~pHOw0{O9s7*)gy*zH|eBHgN z-^V`k1Dy0J$O)m2V)vg3#CY;Q*z7pwaD)eaqQZFvBj zV7$cybOf3wfQ`6e#h9Rqlc0K6tKxLh(N`(y-xlN@)+0D(ZX2o}@N9Ymj()E!1w0YI z7vo45y*FC~LIP?I0ZjUI2GoC`MR0(7qm_$pv22FSavxyuGros0jzr$}_V36G9_(D) zK64z?#V*~>qWCu@MUkEfL*X(o9ENW!u|NzKcKRWVG=ur&dQ(s!I%0@$;2#fE@rL-M zXlKWbIv;??vu=-}tX#qeRC+z(E?_0l1}A_bdn)UD9>f6(K z^Ynkq#MEikiRD2Jb?c9lWh>LB=UA@6=W4fB3B9!>O`cp*5m%$v2@R7A;YFT5!xDVK zrk-5f&8JLX9vZeBvd*1BjB8q_oNVfBMoX!OgOkBL1lg7Lfkh~jnV_yC4S*%F6$aAO z9Sr{c;2(m)6ft>!B1GtvPPh|Kj>hg{5LHEHVjrQ9sgc&l)2W2)AtSaFMyps|mp`;{ za%Pm`_#87PA0UhdYASji%FSNZvvmGwmEP4ijg7#ykqovf1TEuTN5`xodZ^hc5ytcc zWAB?FF-^J2t8%1I*v`L<{U8$((a35KF&->Yvdgc zkY!hRg3NEFea;Dp46DaRGlzJ|oUrzu=vAwa@st$%6w+6U&GgPFO)1+nS@@6qNnd$qjZ38piY?_1E6)|B@jI!dCH`c8)g) z&72&_kB+fvK^zFSB+CVyyq_qvs_6RDyS_SX2(IcT(6))R=Ci7|wW{l3I2Rr>)d5e$ zX59bq^L~sYRxW<^V!CC%AYy-8_l5{syyFczF{@zs@f9yn4DeAWWHDUK<~!lDP){Bo z&S3f3KJ=a@RK;TzQ-y_)ro7X}S_yXw-frr~;ZknQ$du6yxp7zR)3stF8p>asaEbM= z(VQ9XI?CA+!B;RTxN6PSmpEVP8+bLs2jWh?akKeopZIYBmM4xHOIwlg4PT5pnfe7X zF08dr6nWU=xat=={zOvt$yp)qsCu)~tVdtYI}GIC8#-JYc(u1WAla9%<@A zBLF9P7Ne-QT3MqRa@$o+-r}N;?{I;bX!32Q*R|=`n%+y(ckhQyl`|w?F&U;-1xkr1 z&B9vWe}3B!Ao9iBZx;*uKkn2Ue9HO#XF6?dXIIHVl;m?0d#3S~7>DHlt%Y3(m0=roz0>y zVR9iODyp0xXSalW_`fXghOjNo%~^IMW>FyN8 zcU{*oBHZNu?~g+sK7YPnoDE{m*j}$+^aBCMOoLu7p?(u~^oRR7PD!vqA zRjUXvBBozo_pxdbmXhAogthIevf>w0lp4~d`r#rECt{%XQV3_|vvM*9;)aHeP}5i? z<_eQ&(k^p^OF(2d*XLm64SMU2*cgo;ZL3wqci85PSH7v=Mu?`P6cEFMm8!1# z5`NL({&y9^4Dq(DtROh8O~(GJJ{+V;E#%_Jrf4Nh63^X`7+OtXV&Uc}yonTblsv!I zHlH>7k?c-3#Iqpt;ASWD`+@`nl}wR++UxAT03yvSmL3-CbLc$H#5DUeD2mFvA;G==R;4bx;OTgg)*t*`}VZ+WtB2(xTOWW{*I%2&aa^El&JNs zooIP4liGXNb1>sT)a;d4fsb5@hSFg<`3HS|%Cm7(Bh+q=QL({x7}#FbvX;GNF>|hE z1kFGSy#i7R=zvaeeEy|tnsctDO^s4x?Y*xHe|5+EEF<>GsOa9rLEGO zCZDMah?U0Ij6P?$gjDqaJWE#lnU8$uJ-ES%mB@B0_hRyQ{nEG?n^PfiwCDcH$sqNC ztqJ5%1OY|sEf_o$5D`v5uKyDh$_lVPfhNNb^1t41si+-+ zcSbk?Z-QwvCybx=x_-eBJ{)X_eW`5SZT7kJqFjAbFfGg6w^1i1!IP-Qr)%>hK8Jdz zMz5*ts=D7I`Cv~r&ScxzeD<`?FD>?(&Y{p2eL6lm=>3VK zsHCJ6xr~J}k$w%MPH2oOaJFd}S_H!Y*!T>=s;NvE3bQzYs?snjZ$0L9q$O=<{sC%H z3t<{~X+uC^1nv@iI5o@PzJBE!`6ny+&R^&$1jnu@8?q2i)%cLKG{(_@&1+LLGZXW< z>8ilRj`{;uU=V{$IMn`H{h@Hs;mO#b&OdaOC?H%YDfM1BVZ8y@*zJL$i@*xK^qn~a zujjaMp>Bjkcxq;Gkpxs|fT`vC;BWP72z3g*n2Y(C&Gqc%>3}95dWh_hJJ!mR@z_W>(Nnv6|A{d5FHBIbjKJ;mjgI}tD`j;zN)-Sq@(;BIi2XGTZ5A2GtQgmw8` z>#|;A+KXs$QOWU%dso&rzD?u@%f6!kUS$iuz~&KB%bsyB5+gnMV<)ETxQhV+oz`f614gL3 zM*7e2SM|d6?F)=|4q6UbAFnFKeFC5BO1_(W^0qT~8N+oCY>vB3men!Iw+A%jr&=q> zG0UWCeBLIHy+8lga8_w_nTS(m$6xW24swat_gX@TF5TKQtPd5@MZ=sN2V9HNApq^g z{Y`asBmQB+Yz7Yc%$YOp&L0JTv`OPy9Pcs){3#Wu5p<;uWE~xo{1!_?`9Yc5BBFYT zmBJT^_ZHB@5;SA$H#5%i|LB-Zfju!mnBm6yaXEboKYvtJO>=|UNW`vzWJ=(y{XJa8 zFx}l7YR?4AoF89Q!fPwUDF-WxolzHi?7rWA7W*3G7od3(hNFI-&w-yzxuv2E7ZmbT^-|@y1wD z4ZKavQd$w#8`*2m#9F{AU{Qa#(JkI^wnG}~8|o>V(TZOSbrC8Y{+toWh6Glg(-b1E zGHQ1_1#_j#P1!yUQyvXPiLy*pDG}LV+#z#?%lC2r*G6^rzrA(5=sE4_+Ztdcc&@6L_D!Ma5*0kZOA*=3|4&rMLObno_ zsoufex`CB+<06ju_y!xM!gJ-frb;E(BD*E@B1oJe#ebchZ3S6@ka*&$hqzU1+1nJs zRq^@@^?@nAkyQOI$?rEqYO(lao#u~aF}a=k#p;^>6L_B*emRA&evtn4vTYSljndaf z_F>ose{ZOTlqL)p9wme#|fBJ$q&@NEfc}6+W;$m7-?n5KS-^t%9DH%3=*a57hWOoea#ioye1o;me;QvlmAP0@MVovh z;-8yBDg?avfRH1bn)cZvz$pqoi1c0T606`9E!B% zRwHanaA&Zqp9bMBaQBxzEjAfGPFZ=mh@TkwrN5FKjuG}aq;j?h)N%L#%;PQH-QDkc zz)A#IM9IVB9a9>b+A{qCk20ONAw<{&1V|xrMwOReozzETU(%9|9Dy)5cjwm0{{B9% zfLPPDR2{8%e^nEnGIQ={X=!n=NhyzykJrE=2loTA0{knJGr}3aUD^-@SF;Ap|HVPf zu-4-&Ag(Cz6`)ngr@vLnb@2~=gg#&^GOTgu0=t_CFc@eH0t8}32M1pLQu74+m%gf> zdeNJ?F5Xp3APm-3u#q4dpLV;ux)204*zG~q1mK50NAF<~mawcW6F9R75HO@nES5Im zYnR!786GzI*SCapBo%Zh1$78&uRyJ(P;#hTzfK8oiDxz^hDp;dh$TqYAOBAnw%FE& zl4+KkRAGOm;1vmcu>0hiwx`CYt-0N~7+`pF&)4S%%6nf*-ZpRcuJu{xxX&aV2HMR# z7w3jyCL@wnE;V;y;?Vu3m9}KgXl)xYB`$SgVk}kz$)1H#963hGx1RTQmj=6^2p_*c zr`G)`N+bDdRYE|4?d_{8471u7pTsP&1~=UnMrLMb+xq(}xL^KsS;J9r_pu-QY#1kV`Zqee(WajV4Q`6Tu;VIvu}=KNQJQBjvm>T>fKHr_HR1I zzA62ioOgb*_92hkihk5K2`7h+FwAyOs_0wm4&wUFPZz*tEYj;bRL1pK(2Nfq%+>+X z;1)|U{pyjJWI2bkwO0%KF+716vAoQr2$Z=97``V*^aj5uvj&m_a~lDx9M@w3qcE6x z{Dt99^RRHqG+#`x`ea_PotafGu00rB(+_H-DM+%=zlgQsb^jjpT@+;>adH$CL)^>H z&xhs1D>~*NmYJ6a5QwzjW1=3?0tlv;SCY z{}!{BZ=dyXigIfH9+{SGf{WGf>Ocj{H@Q5c_qCe4ymp6+Bse&-lWm!rK}lzaFrdQ~ z?aM^@o{~eFh}~^rhRlYBI-^m4F>$uTtouV}WY5*=3m39#(iL=x57I8G?1VOronOXs z`uduv#G=W??+_?OaHgBx&*j!3RZsrXGf2+7DCyP(?v-N}&o6I-aNcc^Tkdgkl(9pM zdU1iW%4sMJ9O%+7pTXS4*l+_LLGh{0i49RmGA2d(yS=(f?V9R<^$2qc%4RyWjI*mk= zp0VE98?sMNnY?w*ePc=;5GM_^`6$5`g0KdxVWFN%XsV-YX=$M;Sp+i& zhie6ffY?}^zOuL3>FMy@v0a?_a^Qsq&xazx&6A3@3cLyYt)OySkGX0TplLU$0FjAXo)V#@75TLY+>`&B0i^Ae5r%YY4$ zm_f`T1nkj<^=6}25}niuL$w|-x71tgvNu)J^QnhjC-kYU9`7x=<5TZ@#pH?4=i}Zz&moo~mfLOI_)Eb?4T93rf9w;~?lD=D zXB4klP}uPAcU+pQ_7DM?jNgfBY5rb%)cuH$vEI{3-hR$!W*X1wo4>SO-Z*#L z-j$dPpPD|F-}xp5b}DV-DRB)$o$yzk-FavK^VwZr3oRG@2RBGEXzHNKi95tH9TUapZm{#wV% z*vUKXJNFaH<)2xN1BD>mW;*+e?d01}7kvD^!<12Ap^jtFym+oKg;SC%U?AoZsLXkf z7iekk(;VSH8ru9SAxvm-%IEZQSeUbJs%*X4uQw~}xnFYCZ%F-;c0Q6CEx;{D zf3t1jI9($fJ0KV_m3eHIcZwh&I6`CEdAoLMYA#)zgKI)qcsJxp(!&O+hj*wX@7|>} zd{6aibhJ|Nvey~k8mWg#SP2iQjQ94_@Raqr?!xJhsREuzwB^*w0I4OA3-WnRpo1MAOlEA6` zzN2Hn7OqYMS3mpZr@~2de7YAqtn0rUuzK0Om7mhx0)6ETdJAX(GVN;`;{O zUK<->nz`Wvt#=D!mOga!Tzze8|LSGk1&)A)p;{&mjzaK@fs0n>owloMgrEO#Eh)VI z{Qo1ZJ(@5CY~(7lpI(5Re9D#Ny%?2}<;K(p2-smjYE4W|-T^!RvvZHo6naWZ1rY$= z4Y!CflJ{+1ISV5BPgcLXqcqSqO7wv<#%to_+<*as9mF;mKkf&>V;&e#>aT!J()L0exutqFVCL z0b4!B;3gVB{%UC1-~<^H+9-2;K~F|ycra91SRn#nw!U~VbpEY*Y3aH#7)P8g#c&WF zU1eLn0;f*kHWTJyW0guLioI|$W!HP6%!FN1@a~-$qNu1CGISUcf_y96_!o`(wJPc? zE8}`~K%TgZhj40OXS}ruU1w-7o@I|ceq-h7A+#icK$A3OGDc4ZDA$h#;=oK0fgxWE zl$H+#!;qrOXs-vH>KX&Tfj7tqz}_fu?#M0 zXb^)tE-^V7JG>?2A1*BR3m1mJb3@}6+F^pgF$?jGlBb|ept))+C=PAs0L~QUH~;Le zx@MV!K0HLOZpNB(_n2=AJ8!`_izzwv*9ulqEDCFZKopg80dXC%1Vj;&kbs8(FQg28 ze?QSPAka?hyz5zssj2s%Wsm||Q6izcLGLy?a92u>LW;ckZ)M<{vW8-6jEXVI50n#d z9Gsah!%AdI?J^=x+SZi5@;#(L@U#tFv&j-Ll6i$QYi* zekP^1JuvWb?J^hB#NUwCPx>Jc8Q{mHkSM%o9slEYE;=ZGb- zoLZ4m;}rH8tbD<7ah&Aa2CoWvmr(@jNbhW-vr)1+rpmNTFV^7X;J*pS6ue@rsWJ3ha;xbE02k^VJaoJN zS(gY=+ch?Oqf1w=9H)s7`r%O~U4z6r^aZUC*LGhvZO~&K2AyO6TOq2PDi|j~qBI!j z|3S7D>A`ZLz+p=w`}Zo4J=(4Z*Rti(C64ka5_S%Mv|~(}?42>SK^XxBf9wGbQ)f zH`lCGY&?@Gg2`q6Z;tT1$5cw=-+LLm_;?iqi)pvz_ER&Tu}2`W53!Q)@)nhK2!?Ah z9EB6BlB>8%Hj-c_6tz$QGZir$Q8LbSYwe_~f zhci8+;1mS)oZ;HFN2n#+ z#(;?f(S)9NQ~fkU|rwxeIuO+DIMoX}{f;Fe>(oozh_j8K%*DZ46UaWjEp1*6p2xq zxj0B(zvCfL(R)kfpV8n7eBIX45S44gHZA!&(27ZI4%3}xu@Sgv_Fro99&?&0uQbkaxY1GBuyk+qFwa)LBs8@ugi#H+S z#w=k&@Rojlx9a@b=aazbhms}ATc`xsj;fLKZyE0I9pHj6LJf@=Ny;@Z)50$< zHnmzvx*|w?aI^xlH$Q<#I#kVa2|s+97>FJmz>`zj`pjBNs^%=DN{@`}D6pF>uDsvb zv`5|9Nk`B~%@JL8JViv`O%$B1n;emlt7#0@I*x-ju<@R{WRPev@18{g9>5A6aTS#v zfTJ-?8i88pUTZuq7AovlR55bKQycKu7X>X5$&S`@nSOWt7Er7j{zT@|yEwx$XOPN52n&2$1(X|Mn1DL@Z1m7QaL=rXWG(a19z*uJk8j~Jdi`Ye0)j) z0rj`cZEP@T$NjB;MUPKP9XOI-=ugHTg!@)MiJ8-^IHp*80R}-hbz%=W*?X_R=kySG z8#+2V=#NS3B_||Q{L9<){)@%2qzq73Oi?GWEA98F*wuBi(NNSgpnmPzC2Qy(g@aMz znWS}gp8boN5py5`uZeMd_KOAkC8(wldW~tZmVpV6}FElh1 zrc%YuE@#NR`5$IR{py#04fk*Jf?yqS`2QzALtAkT-WGZxP`~1I_Y?3b2fVifx&iGx z1plICa|jj^0tX;Lcw&>0`STLRU>s%kUjBqXbWk=nA>k5w5)y<>)Mlu5<%;NqCqi(@ z3LKM#9y5b9gL@cSW8Q;w{Py;sAW8$l^OZrM=rBOgh}y63RY&ke2Sn#K;E~**on6eq zGN{60o=_6VI|y8=E-NQvCwGqz_qFqN>4hy3aG)k8CWbta|I<}a@i!=kDc{F&IQJI- zqCHVnIRAipnFUt=h*M9EgHL6gOJR|lWxj|GcJaJZ7~Q{iPf{gguz2?kE~%*zg0Xb!3(w=S^!t%V9!wf@oXtTp47Yc05QY{N z3BVZ&W1dTvm!VU0R}oG%Ipde}NWai?PU!a8oo{d7q~BL23dH@Pb@^s*5TEB~i?ga`8epSMSlmL z9PnYqrSLUK>dnu_((r$*cLi&-eo^H@(4To8RFnZCH4#GuhX~X!%0RAHh4UMrFAM61 zP_RvZ_j$2fP;fNT;P0KftCNfY4bmug+!6Jptu&nkp{Ejzjj@6ZdfDB5!)&n7d8~I~ zt6U;T@-`#B;+cOUkoQkTZWg>VhfRfcc06l@vwau}v|0M+Xa9HA=`MWsmo0Ek3VLJ& zO6#K%l(6IXyt)!e@L8AdZocpyeXCUQcpr7v1ReUI69#Sjm!MY!U6;29OHzi9pI8L7 zphqjg@J)i#0=4KsVFcEky|#}j2G{fsh#rmjj_>R)gQG>isCofC?gj ze^1T;@(_Zo3J}MUi{Cp}?L7YweQ#W~E9O*_0GgT(5<6`L^Ld+?IWSoy4BWUOunhQ% z8sY}pd7a~%nwqKvox^ZqKqfwaQ6m@*Zy*#vqMq+P7&|%U!Kj~xjZahZf7NpK(NO1m z9RHPAEyc*7PPd1<)m^l;dXgA4k((W57iFf1Y!4=rt%wlnss^Q6BQi&b23$5v6B83*@rtAT$4ZEj0Eq+2Vrzc>5(4Tl#-J1B7kh}t4`>>{ zj%^<5-y^!qiC-g!sd0F8G#9fZ;wK%@lm);1`pfW%v7=Zu3*oI=r9==S?GqG0B42(r zP6?yX&`|WXe_XZP(QzKMeqbeC59?6Lw%r4S1>_l0=A4&Ewl`@7R{&CTOPOmEJs%bv zv^}h2=95pWc^-p%?Hf9#BW-~qzp-&6hMLe8QD&C8_F&Z=n5lzh&jA)UK4GVs4666dZOAAt7<~&!)%)vw| z{4CYuMTsqR{CnQ$Or6>{RF)~1%U7H}lbM+b$D&to1CSD{94E&P_o)>IptBIwU;tTO zb6AO4$-!g8VO@QIxgqLxq3j+?N9`G}wlSRLDQzm#2nUJkMl zATGB)_jzpqL;}|6O;CCWNe90@VtzGD=_0=jS6oN^8$`u#q3&mYFFX6R;ctBPmc=o) zqK4XL-Bua)Q5S$VMe+vJ{jAxu`Gvjn(a(7?xgA&>yxd&ids<=Mqs+Mw%*KpY*UF3K z*{bkSyA!}$ap4^$G7H-EIrvFctiO~GnUXjqWeo?gp_K%hz^1Z53Y#{=I#()G%Pmnc z2&3T4+ndRWHbYaW2G1hIH+}bml;0&||LLIFt_ZhWUH3Tlbt(Ui1!Mi`f6M33_~-<9 z46Vf6gCQCi{H;x74*01>_rH1j5WDHbx+H*0lZMn*=sgJA-Y%p%B5u}AVE)sg+LIq$6c;L;CZU)r|Sl9hy zesyiq-3zABb-741b|6ja?$qBSe(JFuTF&_F?D@!k3cfGLE9*vSv}b+o9N}NG0|Nu0 z2creVJHF*cOE*YxJ{7x0{P}7nToVv4b|J+fBnT6L#vUe^d7gU{QG77PBcuFzNL%Eg zPv@bSa>f{I%Eh^-+HMAYfE%ek)RLHzg6C&Xe#xdX+E*>F- z&nb9vCnq z)>hQmyzRTSC(tNNLI_F3E>47wQcVA+e>hjYBoG%Q0j8k;PhLdDh_tmbu5xYML|JRa zu~N|7vi3c`lK4=myzOKA3g?C?S3EiKuCfZs04(uMRP*G(!Seg1OL>4ww&fU@ZQ}7v z@iExg_{LZeY;@>YTR4LkgWn?ya>e$jM%OaIn44*Lcq1>{(QmF}j4x0r{`BiG3rj|2 zrIs4(jsb6tf+dbDF$GEx>)et0C8K}1Fu_>Kd6x+>V^02f#j(+Z)YQ~S94FP-2-PtB zBmgNvPfn!LO-4w^pPU5~(Vt*-E?9f0M@(JMufoIGV3QU5n7^{JwyuBMp|gNA40sPq zh`y0vysPVeVi%YtD-})=uQCb$0UBNghSXPvaX`b;Vus$C!pD5+7pmCCY^R+e?LT~u zV_q;eG1}jy{qs&Ut4r=7Pb)gM`u!k7k*yE=@l8b2-~8VfC6fKZZvB5dSTXu`VLo07 zb!+_-J;HvL7<0wYls&q&cS~n)?;kR=vRomj1A67k3%5FdA4N9zqM`1a?8z}VG;{R< zb;D*}hQq6HXAHZ&?5LN+;1jPLoDN)>Dha68^pow_u#!Rh#fx2utbr&=7a>Wyj{iaRbdN3E~%ZUZlaLmP-4{Q|qc|H5VZGsW+N%#dA8UDLZpHa`N6? z5TPkMx=$r#gJEP0ajv<4jL+|b%jgAgNyPk=M+y?F8 zm_gMx7_^Q<0}ZXu42DEP2-kX`YLa*dd>pAft~_e63OqlWkk<_ep$&b2Q^T0$Q=@d6 zJVTHkY>=7_Mw|qi*McX>#9MmhF;LjEHF1;20FdlNppWc4X+ALW@&++?xQJ_{%;sHo zn2iZ46OUNpoqr0)&@P-8@N*SfPTP#{kt7H;$HBf<8&q2+z<^pHBPv_YupX5gy&X?e@OeX4QL-fnS+b&^YZ#(V?I*-6MHuW82a={O) z?p}^-GVdJ6!GU3F&dsku+#tqg(+afVQJO;rO#A?_j0nzo5G6P2TvKy%$tRWD0Ji&d zJZ|&mnT?k@$w)hcdLCZL!&tZ)L!&#rA{MKbIt6_hfL&of)%~PIR|)TVpf%{+CH~)k z{y7Pc zx!?=M#<#%jRcUb%8}Wf`@)Xx7L=l%LO$qezG+o{4wzjqx&Yxef71T9Gj2}){pP9!I z5JiYF_R8b2xcV0|GOPfNvc$e4*4};47wgLPdr(O177EIv6p+H3EL*lL2kyNb)Em3- zT-ZZ_sK2H9EOQRCp@cLx{jqgwO-fRFfQQpZluD9~=T0=@`_ N+2p#}rHC7F;vYRVb?E>A literal 0 HcmV?d00001