From a0de5c6cf166173a0e2c59b0eebca119fe87901f Mon Sep 17 00:00:00 2001 From: JiaYanhao <2474840061@qq.com> Date: Wed, 28 Sep 2022 23:43:10 +0800 Subject: [PATCH] add demo --- .idea/.gitignore | 8 ++++++ .idea/OpenBaseLab-Edu.iml | 8 ++++++ .../inspectionProfiles/profiles_settings.xml | 6 +++++ .idea/misc.xml | 4 +++ .idea/modules.xml | 8 ++++++ .idea/vcs.xml | 6 +++++ BaseML/Classification.py | 24 +++++++++++++++++- BaseML/__init__.py | 6 ++++- BaseML/__pycache__/AdaBoost.cpython-39.pyc | Bin 0 -> 1939 bytes BaseML/__pycache__/CART.cpython-39.pyc | Bin 0 -> 1196 bytes .../__pycache__/Classification.cpython-39.pyc | Bin 0 -> 3983 bytes BaseML/__pycache__/GaussianNB.cpython-39.pyc | Bin 0 -> 2276 bytes .../__pycache__/KNNClassifier.cpython-39.pyc | Bin 0 -> 1564 bytes BaseML/__pycache__/PCA.cpython-39.pyc | Bin 0 -> 1184 bytes BaseML/__pycache__/Perceptron.cpython-39.pyc | Bin 0 -> 1221 bytes BaseML/__pycache__/Regression.cpython-39.pyc | Bin 0 -> 2700 bytes BaseML/__pycache__/SVM.cpython-39.pyc | Bin 0 -> 1843 bytes BaseML/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 505 bytes demo/kemans.py | 12 +++++++++ 19 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/OpenBaseLab-Edu.iml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 BaseML/__pycache__/AdaBoost.cpython-39.pyc create mode 100644 BaseML/__pycache__/CART.cpython-39.pyc create mode 100644 BaseML/__pycache__/Classification.cpython-39.pyc create mode 100644 BaseML/__pycache__/GaussianNB.cpython-39.pyc create mode 100644 BaseML/__pycache__/KNNClassifier.cpython-39.pyc create mode 100644 BaseML/__pycache__/PCA.cpython-39.pyc create mode 100644 BaseML/__pycache__/Perceptron.cpython-39.pyc create mode 100644 BaseML/__pycache__/Regression.cpython-39.pyc create mode 100644 BaseML/__pycache__/SVM.cpython-39.pyc create mode 100644 BaseML/__pycache__/__init__.cpython-39.pyc create mode 100644 demo/kemans.py diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/OpenBaseLab-Edu.iml b/.idea/OpenBaseLab-Edu.iml new file mode 100644 index 0000000..08fc73f --- /dev/null +++ b/.idea/OpenBaseLab-Edu.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..45d5172 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..29a39d1 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/BaseML/Classification.py b/BaseML/Classification.py index ecac105..1137280 100644 --- a/BaseML/Classification.py +++ b/BaseML/Classification.py @@ -8,10 +8,12 @@ from sklearn.neighbors import KNeighborsClassifier from sklearn.model_selection import train_test_split from sklearn.svm import SVC +from sklearn.cluster import KMeans +from sklearn.metrics import silhouette_score, silhouette_samples import joblib class cls: - def __init__(self, algorithm='KNN', n_neighbors=5, n_estimators=100, ): + def __init__(self, algorithm='KNN', n_neighbors=5, n_estimators=100, N_CLUSTERS=5): self.algorithm = algorithm self.cwd = os.path.dirname(os.getcwd()) # 获取当前文件的绝对路径 self.file_dirname = os.path.dirname(os.path.abspath(__file__)) @@ -29,6 +31,9 @@ def __init__(self, algorithm='KNN', n_neighbors=5, n_estimators=100, ): self.model = DecisionTreeClassifier() elif self.algorithm == 'AdaBoost': self.model = AdaBoostClassifier(n_estimators=n_estimators, random_state=0) + elif self.algorithm == 'Kmeans': + self.n = N_CLUSTERS + self.model = KMeans(self.n) def train(self, seed=0, data_type='csv'): if self.algorithm == 'AdaBoost' or 'SVM' or 'NaiveBayes': @@ -57,21 +62,38 @@ def train(self, seed=0, data_type='csv'): self.model.fit(self.x_train, self.y_train) acc = self.model.score(self.x_test, self.y_test) print('准确率为:{}%'.format(acc * 100)) + + elif self.algorithm == 'Kmeans': + self.dataset = pd.read_csv(self.dataset_path) + self.x_train = self.dataset.drop('省级行政区', axis=1) + self.x_train = self.x_train.drop("城市", axis=1) + self.x_np = np.array(self.x_train) + self.model.fit(self.x_np) def inference(self, data): if self.algorithm == 'AdaBoost' or 'SVM' or 'NaiveBayes': pred = self.model.predict(self.test_set['data']) acc = accuracy_score(self.test_set['label'], pred) print('准确率为:{}%'.format(acc * 100)) + elif self.algorithm == 'KNN': result = self.model.predict(data) print(result) print("分类结果:{}".format(self.dataset['target_names'][result])) + elif self.algorithm == 'CART': self.model.fit_transform(data) print(self.model.n_features_) print(self.model.n_samples_) + elif self.algorithm == 'Kmeans': + labels = self.model.labels_ # 获取聚类标签 + print(silhouette_score(self.x_np, labels)) # 获取聚类结果总的轮廓系数 + print(self.model.cluster_centers_) # 输出类簇中心 + for i in range(self.n): + print(f" CLUSTER-{i+1} ".center(60, '=')) + print(self.dataset[labels == i]) + def load_dataset(self, path, test_size=0.2, dataset=''): self.dataset_path = path self.test_size = test_size diff --git a/BaseML/__init__.py b/BaseML/__init__.py index 412a05e..3cffca0 100644 --- a/BaseML/__init__.py +++ b/BaseML/__init__.py @@ -5,6 +5,8 @@ from .AdaBoost import AdaBoost from .GaussianNB import GaussianNB from .SVM import SVM +from .Classification import cls +from .Regression import reg __all__ = [ @@ -14,4 +16,6 @@ 'GaussianNB', 'KNN', 'PCA', - 'Perceptron'] + 'Perceptron', + 'cls', + 'reg'] diff --git a/BaseML/__pycache__/AdaBoost.cpython-39.pyc b/BaseML/__pycache__/AdaBoost.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6d40a4877fa7bf3920c6bb479378137c3393d13c GIT binary patch literal 1939 zcmZ8izi%8x6rS1NcRo9gaY8I15d=gWN^B`efDj6h2xyEc5JK8!wceSF*V)@UX66ER z_9{E13I!bzgickt_NX!1rc-Cns~-H^1JzdGo#Ry~`IDyA17z->(;6 zMU4GPle5jo!E8FtbRXP+_=i13h! z@W4yEf`7sK(Fts^t-fcM@}iiiyx7ZhF;dd53}s$t`s+!qq{yUFBh}}2|5%4Sr_oA`U)%YvW5TmEPDb^S!*@$wwQXk7a!mMmF>9Yaffr28}=4+?YYRKHjr% zrL0SnWgVE%JqYHl@QZwjNBHfZpX<)_92$6!zFSaKXN``}Bk>rM7WW2tbJif%cRclm z@ppmrZV2ST!H52CH1(Zc-1tt9ILq$SZgAflcx$Ygtpqgl*ff}ih+POPolDGg8~=c> zvI9Pi8t}Y{aEjwp*pA(ac$zdp6Or9^uN|*35&cBbUx2ON(P9%f$+1V-fyl>OY7K9A z%C8~~d@aW|+L5`C>f}GPla>%Rpb*)x%C}|JU$R~ewU!kW7%8kb7HOhzFaum_1r}{| zH?JmA+gR^R27^jkzpRaVfwufg)@l_ab>2+}rRjIn1zLC&BJI$1nb{jl@T(<%AN@_M}cZxZY; z%}Lu>k@AAEAKW>4J$0%oIVOs3zT{avmgvCaKkwUsFB6>e`p|Am^ zC(;~etd9a|g9`SZ2ewnz1F2+P$X9SyFF`QA0&tfBFUkFR*<7EiK6&&bwLd<1CbQ^r za_Sa7y$sP%T?2fOsP$kgN3nM7ay;t$EobPT!!11TTdx{{k*5rLldMwRVU+F{=8-fC0(I)X3sd_{Bc>4yx%_K20dC6j&Q|At>^y_DeBpE literal 0 HcmV?d00001 diff --git a/BaseML/__pycache__/CART.cpython-39.pyc b/BaseML/__pycache__/CART.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..31318c1b1a837ad0bbc052db8ef0a17de1fed008 GIT binary patch literal 1196 zcmZWp&2AGh5VpO$+3j{yXb~0Vz!4D%8i_MPh4OPLL89fdLbBZ00f)_QupMZt-r5US zo}fAQHFykPIq?ddm~oOSYAty@o|&DWZ^kRy?VP~+_4{f6XGF*!yeuz}ksa9fArMI< zt;mR$lp@b6R#M}nyzi#)VRmOIQS{#e|i)gy<$Etn_e)h!Slh<<6MgHAh z7opi6AA5+dYwb91!RIz~JlbHJv_%Vg(hgP&iyKJd1Oy}>0CP%)T2THh!QI?l^&8--XE8t-YZh_v%*uCqiujqQ9jDiBuhegN<;0#Ewg#xbB zH;TYQ0@T={QyfNkX8UB8CJk`TBM1I^;G$}Tg}rC?b)85 zNmb3_U1lXT`{_sR=X4J38VXItvlJCG9c_Pi=mmyafG>At)`=EQ5+9M z6mN$z?g_3NT^?nje02~B&O$CkPc&^^z7!3lOrorH0j0+CEV|I^Np&%eU|mZ%wV8W? z$B9gO*)_rWLp3v(TRd6cSnUbkEeLj5_S72moY8pqauwe_j5T{ZXF1K1o9=beY5HV@vhje-`;+21e7}`TCw3OX( z_6y41cMq%svUp<)?7k`<*v1+#sw){;HnPH;@3^p4@lN2a;hh{>9RO$35vi&V9p>I7 zuc=HJy9fIZRAbLFwpWbJhwW`OJ+gh%*ov_ITFs1X=Z!6Z?GI{pSYRbqzUi1A&X}4C zYW^~$nartqSmyT3n9RbiR9pA$vrSjnSni{u1{)5tl7-p$@ab@`>T)Yew)ll;n@jCp zeEy|tIvC^0^no+4W+5<PKor z7g-{*sEc;%T*cpGI5&u5v?@(?5Qb|>%EM4s&3D|o$|4m>u0qqQltVJv;X24wu5|Hw zXz;3iD43ouZjTL6U=T$tS$o|c$EV zOgoB})@u%A@ik}7S+oGh+)|{HW9_=To+_~by_6R$RT&oc>=|p%-t~uwutOhSHoVY3 z>BghD8vwjM^_$n_`l7{3w+QB-S7&0sHY^T<1IMW^_#9C@H9r5!8=P7qCPO1)q%A$OCuT!5escP za|h0DNg)93FAPhpF@um{#%rU_V$){4+sfTH`)C3Og@nn@BAY=#n>ECxo~L1<5I3?Q z{G1}I@i+}FpTlWdmm%_eOU&Ug#WaZ-5}$*(Z$Ak#79{U$e}hMii=&V591-17;Sy)G zmqx3=`z$#T=fxKxw67uo0v^8m4n2Q-cEoJ)32Lzb@gKtd-8Wu8JoxS5TW|dR_MLxy z`0n?29~XpHu?R7kggCtQ!^1nj`p3bW_ul^f-8b(bp19HVL=FgfcYpEL-P=EEo-s7i zPKHV5fr8k@nRfb22LjU$fn9M99@^iE(gDIwQEm*@)>5tuNv6!4bRp%LcpQzyr>SLO zEdjwtK|y^7Kq&nwvZiVS)8kI{^Qy&J&0RXPl~C{%_#c9f}9FLe)9-QNw8k*&UGzhHg$^SeIgF@a!Go40;uvB{qo z_NVCPaPYvZIP`|dzl#V^w)N^gL$t=nh<1F$;;Y!p9RI|l!4$;ZAHRP1yAKXO`02g( zZW)5;YEG<>a-7UrM{L9iXrp;0i*?{7m&685kFiNv&Gy>GXg z1rts3SVlXB8<3&!8R!qJk50at_7ICkAtgdnNyMR~jFgLwlS?NX#1v%559!Bu%g0bq z_?ux6iS!9f7MR1pu$zTZIQLpRr&pq_BwIggZX;*o4IXdydkA83X=!O^YH4ZtfoZ9~ znI2JYM|ch5UKb}KCDuf+(0-@4nkK6VTmw`Pf|_=|TDqW|2s5sXw)h%s((EcWevwZKg?Y&&rOKavF-V>-M}ZrZI#D#u{3$ET^ZNPt**J~KA7f+|K^^X#|2uqIZU(Q|F=gvcsk$i XuhG#+x)le2PtM*d7(D*f?ZEjT!H?sM literal 0 HcmV?d00001 diff --git a/BaseML/__pycache__/GaussianNB.cpython-39.pyc b/BaseML/__pycache__/GaussianNB.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b7246da0604827c643ebddc665e40ae705326d9e GIT binary patch literal 2276 zcmZ`*&2Jk;6rb5|JI;6dB@jeKR9FIsLwhNuR6)RjVh$A-Usju)ak9>OZD!Vixb`V6 zJ(W8ZhvbBM;fxUC&c85MKvhoMdjNiKHc6cd#@aU@@4cBfzxOdt=I84S?T1gVr&mM9 zey7Q7b1}JtPq#q?6Fg@fZhNQW+TQDUw)Z|9q=@yGqeMv&OQi;?$xZ!}WTbVL z6z$EFG-unHots#d*2az_xNsgY*tsHn5j^0qbX7#6hLJDU#GGhg6o`4T0I5(ciY4@s zScYvEl!uK{K63_*eS9C{(;tJBtj7R;7;a@SS@SFfg&L(i@uA|;6-JUmLJzqE!UXR^gFm54})hfTeyUq-^mF15?7tWVqnzQzvtG?*ZiCjqoLv=GiTwi@9y zns}3d_N{o;_zDxj_YV0Jdo>Q{C*dSIa$qZF@NC#tmvM{d{B6XztL4xHJ2DYc9sh%N zOdx>ak)w>CCtEUaE*PhPm`VyU=#zV-FwRhzNI@|MU}_0kCfG~zk<=#CJELwlm&VPC zQY{n9&1IohFj9+l+Re&lO|8+wRa&UgadEjnl!&t`MAU1-rAo2_4i)liQ?Dl0 zz7vME(uPY#E|QXOaj3;&L?Hh8=$mIpKR)~R(H}qk{MRo}?oZ!57Faf}lH23x z?m+9C>-VS4umU?AqF!ZbS>aFjGX7A(H74i|R6i*dg?rPt?l2xDDpDRg#zh4*UXJ}< z2Dg?KU8!V|%4^Wo3m}ZI0N^D+Omw_91M8XavnStC`|X2s8AivGS+<5zBu%Iq0YFfc z^?U3oM?JPNW}~U;R*{3Jf!T$Zt!v~1#N|mG5p;-O9=r6KAf^2F_?3IfURG?c+cLMF?#Og^H~_}F)oP8GTdj>3OReE5{XkjMzHU-D-H`Iggcm|%$Nm1y+_gp6MR-F>xAngNkJAe}|Mo6AHMt-dT(mTE=!v&qp} nJ!KV1wkPAQWM68#vm!A6%OVrqsxEh%pg1)Pxe+-_yy5-}1VtK0 literal 0 HcmV?d00001 diff --git a/BaseML/__pycache__/KNNClassifier.cpython-39.pyc b/BaseML/__pycache__/KNNClassifier.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1feab1f0c27787db4eeadd0cab0a11221f3c5648 GIT binary patch literal 1564 zcmZuxy>A>v6rY*>yz?0xV-kV@Aw?;+z=u*Ggb*MiM3HbvAet4@XuLCL@3FUg%*+XV zoU2#~O(>uuAml4)kmwMhqT^qf7J}u9o+i9E>vPT#vwCmdzWMz9-g_g~*SiGT*S}vY zz6%NY6Mt4)06%Ymm}{UUk+dRXnp284tJpZm18)aan1}BY8OrF8$mkZ!BN=>1viJnn zk&L>n8v|AD?(H<%T(5*N<*-y5{2Nw_vgTG9%gv-J?V!LFtL^L#+u&6sr;_AMu1O|? zLz)NenRzHOq z!=(rOk&PGBdlQLcsbn9A(04$(AZs8!yFRBfxQpXYNCIbv0|!b|*!?jDxYuf4FA2$> zbgVHhoCv$;5?Sh6jFpRbl`TG#E-ct>S8c} zRhR599bkY%BX$>!8>y;{xzMO;s1xx0Nc1J>{(ZIokx|<8N2S;o^`2<@?@v_yHtc>= z?7Z}joc7Uv?`9vEeH6>>$-aZjm33)3$L);ItZI-1$r|>s2MWdC*g?h_7Cc3Pxi-(OK3!5>05xs#Z z3Qtk1p7Aq1*|^fgpa|WBZ`MJqe&k%%VJ4qt-OKO;U=S$e)&a9@&Jc!W04#u!P_oNp z4ssqIUi-n9w~v3me|-O&zkm4N!*e|=G$ahi)G=Aq!b~Pw$+EEed03-gK(zrX3tBuO z=8TKAGSkXF4y;qwL#0(+C`^h|a6OvR**bzd8$AaQBZ)NlvU&xKIhF&l7)y9O01oy5 zN&2$A8~QSWD02YJv7{njI`KeXfz>WSjIa98uMJ<~#H&$4c z#U7wWqTBfTm|~E9U{532PC{HOk?d8Cko>fao`bPd%rSfR;cNpjuTB_bRAVT!1hXDl zhm!1a4rMiM%aij@r=n^{^kqEjMO0T&WvCvV?=4Ix4R5d~&=*h2$iwbh8l{o+Q3*!&h^DY3cV>&7q`KVauj&iAa|_|KE`=eZ9T&8(5MabB{utgZ}`tr*o$O literal 0 HcmV?d00001 diff --git a/BaseML/__pycache__/PCA.cpython-39.pyc b/BaseML/__pycache__/PCA.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dcfbf14019cff27403e15aabf44391774cc8f6ed GIT binary patch literal 1184 zcmZuw&2AGh5VpO$$>y(=0u>0s5wQmni8HEz3UMg~3318Aa@P*su<j6R znqyys$MBUCufPRnoF7FkUhQ~1Gai4Q`7C<9Hi7Zu=hOT$BIFk?HV4?qbNKBe5Ryn* zk_jC$iaIN!Vf32FNXF+x#%F9uC3{b@j?`|#U65RQ!L1#{#gnv*%5 z5gxBBU{73QPJ^{63HVaino&u=V_aJjIENhq{I2GCHK{ADw6j^qv&#Co7Vg+LWnr|K zDBt*~T>e%12t`vI+2Bq&9~GtI+;_vgif&5bgjLS>>RfQ6A4BXCCbSYjvH&tdkV}0H*xZKT733Bq)^=2xiP;6S?`S?!!cC2`+_yEi zVp5l&XDs0LF*fZg>Q9mI=)P3p>DU4Z9=v7?_v7CG SCHCpF1+qOPW1vEprqMsk9+EM^X1GKlfh~;fvsuh~UJ_sqo&DEc^|=B%?NcCsiR^qndhH;8}Ngu-SpBAA*ns z?vmUS5aE>M{yb(Lh)_hZ4@E2zSR=6l@l%C&3kqU6P!D0gfT>@BFl0>6JVVa>8JW>z z!h+=qoQEcwQFj^(v?ap(=)t-IGc~Ix1lFD)@RUEaB=Z!8cOvUsuhBMWx!Jd|C{@iT z(ng=8DZUBoqlo#QcIJe!QCUgGY|pJr?^tldwKO(9U`Fw>wh<^&8|$}H*>KVbS)EfG zXjzTUiQ0h2|2!Fd&{FBaxa5bt-sjEWZ7b{N5NDU~J$fmo1JvK_4*o&D-5y%Vp{z^8 zScJg1R{QJT7L90+9&L1dmwuN}MFKcf?|^bl#^ekT8+$WKiScni4o*Nvw9e@;3)LF< zS$|X-)k7_8RaqN*OCGcp)G7u0%2mnhLNdio*)Vkt++2}!vFUC(U@(*pKoEL`9<6oK zb>;$TupFpg+5+cg-hId$n^NmhqbBMmnCxoJMv|MU zlA77HW|~jh3UuJbI@$y5=l=z)l=Vm|31wafAC2%6z#LHD?38igbg2|9$H9(0J4TW^ zi08>t2kqj0r~m(auWGnp3!>eI5ZYlyk8X5c@A?e07|DWk2EwL{0Sl*d@-p^i%B#6W zVKoW^s=Fxep+JIm1UAt9Q2dZO0g=!oO~NE}r&*A1>d%$rs@|@E5M1F~vT{as6)$7U XI{{sMM~md?JgsN=AssV%H1Yoet^gGe literal 0 HcmV?d00001 diff --git a/BaseML/__pycache__/Regression.cpython-39.pyc b/BaseML/__pycache__/Regression.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2935c9cb760db4d1b535438172040a3511b8ef9c GIT binary patch literal 2700 zcmZuz&2J>d74Pb=>1of{vtI9p6<-cQQ3k;{f)J!=Ly{$cM2uOn%B3%@a#xMrZ>SaV}nt`v(x^V4ouX4=!Bz1L~RsT8Y1455VtLd%Rvmwfc3{`>2oie(zQDen0il z{`dFa7r#UA|1`MX0u26wS0952Pq50%=<8Rk_A{TgydVpmEXrbhgQ`;}S=Y(JDy`SD zwYrz}>VDRDyr^2QH?j@akE=m_Bip>3=Vo^ELr-)>^3W5>nV)S5_P`rhbs>F zk%=#u<93!LO9aubqv_I{B*H)P)qS&e-n;N1={K)AZUC+@>t`+Rw&R81EzHK!7tte{ zr7t|}G~Ro{wynSWsiK{!1caQ{2sc0TLx!r%R6JI@e&EUjA6xK z6}5e5(K$_);Sy=QlC}LiNX!5Fz(@~s_0QLron>-?^lx5uXGo5G{q3d1n{3eT%z(y| z8)xV{T%~)ek29-RK%TJIhrSK8oZ0wLav{~@AJHC@-yjGH5H_m#zO1gHaMOj=`VFiU zZ^X2wXiH)JnLvhPo*XV$&tVc9AMof}Q#%bfW-J@XvgJEE3^)OdzA+H6v#m zA;cdzTNEA_U;-zbB&1{7e)lTaoy%Zf`C^gmPPP8y_PXyw|Dv6N3fuSCNkf%4<01tV*#}<9^?Umkl|M`;IH-9e3v8zUXa=ddi)dyFV z;Yj2PTLz%W&j;RDY;PDiWI7Bwpscn^Yd_`we51W;3S3_z^Bt(_7{qh+XEC51URNk6 zgI10DSM`RlWKeBfxKM3e$bGuc9tD>f8tpBff54B+=3v`Z*zMv_7DuxwazT$qqs5KU zXy++wG&`yu(-nc+A)&j0$}`T?Mr|_PugZO7@*DyR@Q}5E`5D?n&5z}uAlJ^T0Qv%% zd@v&RGl(W9(`wGqRM~MsvKEQtVD$l5LtlM_4@H~{3|x*n_ddI-`WRaG@M@PcmrIh- z9<1n(NUedOPcC#73;p-0Pr_lB?ghH@aI2*`{YcE)8!pfB*HN_+^=s0P0dnzq?)j(!p$UxAoDxA>v6rY*>KHu4nF#$__BuGRY0$WN)Kmic}jbn-kifdNuow@ifdwa*sp25yu zbq=YZpd+HNOB!l~Qql1*Obf_zMehRmy;<9GGN*kr^FC(Yyx)88vQDSPFn;*`X1*LU z_9tyF4-cD<@R?6RB$K>gJ?>`F^W5zBe9WQ#=9q?d5^8I!&Y4www) zqSuoA9_xlDIE!s{g%<}gEWz(gExXMINFvBSBb4tey!WFVr;BG$*LV2 z$$>7jk+R`^Rpnnx>k)~vZR5mon)U~UN>kf*^O?5x;g}6ZW2p+;mRXe{)m*C;;;&uwX=w3aqZV3o!iKo^%|4mPlE8nS?$A49o6xXpo|8N z(UyJ*Z#d=eAay;XCN|trnN<4ZKa3L!0R%n)V}l~wRz-KwiV|u%E9H1Za42cTMA}%x zFh#iZGOTR4n-x=KY-Dz({eGdWHz+H8g+yMVO1*-WUUJ+1pz0?21!7z$Mnc!6)!sxQ ztD2P1uafjNk}gy_8rod z=B45p*NMDGsaduq_<=q6e`o@`bbrJkQ+_m na(ML?&P8T-s{eW zm$=q@!jm5HtoMa4ed1dmh(HD;us#%_3`uBxBqAA;*!ox`azF+ctx%P`V=}A;OOy@2 z%-v9idv7vY+!=LmiUMRl85v3DT$Oy?skSjyG^*IRZFL7b*KDJ8&6;8i?aPN5NGUXk z;;SrH@P{e_1b`6W0z7~Zhyn0UMV8urlA7};f|=;2nydZ(zaYr%4}LpK*41re<4CgL zE5%KKS%Bz1q?8Fk=?79NoCo+m&F?i=I)ACzjy2D$&2QJd88gkN?D6=j+T`G8)11<} bsXIzf*1JABmu