From 8dcc943668a0291a5c04303259826ec275c8fdb4 Mon Sep 17 00:00:00 2001 From: "rodrigo.arenas" <31422766+rodrigo-arenas@users.noreply.github.com> Date: Tue, 16 Nov 2021 20:49:16 -0500 Subject: [PATCH] Docs on GAFeatureSelectionCV --- README.rst | 55 ++++- docs/api/featureselectioncv.rst | 23 ++ docs/conf.py | 2 +- docs/images/basic_usage_accuracy_6.PNG | Bin 0 -> 7090 bytes docs/images/basic_usage_fitness_plot_7.PNG | Bin 0 -> 45423 bytes docs/images/basic_usage_train_log_5.PNG | Bin 0 -> 29441 bytes docs/index.rst | 11 +- docs/notebooks/Iris_feature_selection.ipynb | 260 ++++++++++++++++++++ docs/release_notes.rst | 24 ++ docs/tutorials/basic_usage.rst | 112 ++++++++- sklearn_genetic/_version.py | 2 +- sklearn_genetic/plots.py | 8 + sklearn_genetic/tests/test_plots.py | 41 ++- 13 files changed, 517 insertions(+), 21 deletions(-) create mode 100644 docs/api/featureselectioncv.rst create mode 100644 docs/images/basic_usage_accuracy_6.PNG create mode 100644 docs/images/basic_usage_fitness_plot_7.PNG create mode 100644 docs/images/basic_usage_train_log_5.PNG create mode 100644 docs/notebooks/Iris_feature_selection.ipynb diff --git a/README.rst b/README.rst index 3c6e4c0..39a78d6 100644 --- a/README.rst +++ b/README.rst @@ -25,9 +25,10 @@ Sklearn-genetic-opt ################### -scikit-learn models hyperparameters tuning, using evolutionary algorithms. +scikit-learn models hyperparameters tuning and feature selection, using evolutionary algorithms. -This is meant to be an alternative from popular methods inside scikit-learn such as Grid Search and Randomized Grid Search. +This is meant to be an alternative from popular methods inside scikit-learn such as Grid Search and Randomized Grid Search +for hyperparameteres tuning, and from RFE, Select From Model for feature selection. Sklearn-genetic-opt uses evolutionary algorithms from the DEAP package to choose the set of hyperparameters that optimizes (max or min) the cross-validation scores, it can be used for both regression and classification problems. @@ -37,7 +38,8 @@ Documentation is available `here `_ Main Features: ############## -* **GASearchCV**: Principal class of the package, holds the evolutionary cross-validation optimization routine. +* **GASearchCV**: Main class of the package for hyperparameters tuning, holds the evolutionary cross-validation optimization routine. +* **GAFeatureSelectionCV**: Main class of the package for feature selection. * **Algorithms**: Set of different evolutionary algorithms to use as an optimization procedure. * **Callbacks**: Custom evaluation strategies to generate early stopping rules, logging (into TensorBoard, .pkl files, etc) or your custom logic. @@ -82,8 +84,8 @@ The only optional dependency that the last command does not install, it's Tensor it is usually advised to look further which distribution works better for you. -Example -####### +Example: Hyperparameters Tuning +############################### .. code-block:: python @@ -134,6 +136,49 @@ Example print("Best k solutions: ", evolved_estimator.hof) +Example: Feature Selection +########################## + +.. code:: python3 + + import matplotlib.pyplot as plt + from sklearn_genetic import GAFeatureSelectionCV + from sklearn.model_selection import train_test_split, StratifiedKFold + from sklearn.svm import SVC + from sklearn.datasets import load_iris + from sklearn.metrics import accuracy_score + import numpy as np + + data = load_iris() + X, y = data["data"], data["target"] + + # Add random non-important features + noise = np.random.uniform(0, 10, size=(X.shape[0], 5)) + X = np.hstack((X, noise)) + + X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=0) + + clf = SVC(gamma='auto') + + evolved_estimator = GAFeatureSelectionCV( + estimator=clf, + scoring="accuracy", + population_size=30, + generations=20, + n_jobs=-1) + + # Train and select the features + evolved_estimator.fit(X_train, y_train) + + # Features selected by the algorithm + features = evolved_estimator.best_features_ + print(features) + + # Predict only with the subset of selected features + y_predict_ga = evolved_estimator.predict(X_test[:, features]) + print(accuracy_score(y_test, y_predict_ga)) + + Changelog ######### diff --git a/docs/api/featureselectioncv.rst b/docs/api/featureselectioncv.rst new file mode 100644 index 0000000..e263f27 --- /dev/null +++ b/docs/api/featureselectioncv.rst @@ -0,0 +1,23 @@ + +FeatureSelectionCV +------------------ + +.. currentmodule:: sklearn_genetic + +.. autosummary:: GAFeatureSelectionCV + GASearchCV.decision_function + GASearchCV.fit + GASearchCV.get_params + GASearchCV.inverse_transform + GASearchCV.predict + GASearchCV.predict_proba + GASearchCV.score + GASearchCV.score_samples + GASearchCV.set_params + GASearchCV.transform + +.. autoclass:: sklearn_genetic.GAFeatureSelectionCV + :members: + :inherited-members: + :exclude-members: evaluate, mutate, n_features_in_, classes_ + :undoc-members: True \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py index d123101..e7126d5 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -55,7 +55,7 @@ # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", "**.ipynb_checkpoints"] # -- Options for HTML output ------------------------------------------------- diff --git a/docs/images/basic_usage_accuracy_6.PNG b/docs/images/basic_usage_accuracy_6.PNG new file mode 100644 index 0000000000000000000000000000000000000000..cf71c5bf7fc57aecbaacf8357e81360ce12c502b GIT binary patch literal 7090 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 literal 0 HcmV?d00001 diff --git a/docs/images/basic_usage_fitness_plot_7.PNG b/docs/images/basic_usage_fitness_plot_7.PNG new file mode 100644 index 0000000000000000000000000000000000000000..7afb3b89e4aff80345b211bef6aac553522b2e04 GIT binary patch literal 45423 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 Tr{o*>-`-u;f9CISJM%vPe6o!` literal 0 HcmV?d00001 diff --git a/docs/images/basic_usage_train_log_5.PNG b/docs/images/basic_usage_train_log_5.PNG new file mode 100644 index 0000000000000000000000000000000000000000..f442f60737c46f96de23b78a3cbcbc6371b45462 GIT binary patch literal 29441 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 cpH za4*oYUIE{Q@)J<9$-UrrthgvPvNg4Y@LMA1TnD02!JDNlt59|qzq^dW{53k_#j*kv zifqo-l8x)HNDG;LI{)MTlDf6O;G0T@u9W1l7{Fv%(CsDT3j}U1G%Ih=E}6dX1_8r5 z(^X({JW*_BFF?r=!7(gYJEI)0B{U@rCGq_mg_ns_zYmGv&C*El?#fVfky}bV#mI?zByt~D@bXY z1|Dm+K{WxIvM@AnERx;!ONk0!ESe!BybWBcg1u{2>*G&&k2MkAp-OP59ybV8u(J2R zMAwuq2)UJ*zGi`s72ZCUhn8#B*JEI_=2l9`nS9zy2@=A+*xqqOm|gE2O|jkRa&WA_ z^O&0Wm!M?w%|+hmemS-D1e`~sW0ShA(X=G{u1wD3L_=!Bs2T2=tKs~z=Pjrsc-jl5 z=BGs-!ZQ}D9EplNj4m0w_7>&a1#FxB+|XI_`l+=f;qJhzSBoBs?ReUE#5AaIo-h;c z2KsPb&06zvyOGuyY9+iPii=q64j_^<&JRyu+>CB{MsOzVT8}7*R2`}rY3i3Z9rTbi zrTMfy%{2(bPKGmY-UENCf_;ruARaXZb!}TX;i^+z@>+I?5DDGSd;tCyQe4|^54E#Py36xI=mC_U3 zRU7bonHlj+Wcj$ED|Z1pXL_C0E)(I9?|5y^YMH>N424F>-PfkJsp_oinigK z`_UYBms4~sY*e|r>x~sNF&uQkgb`sp5A5WqA=)ir&@0LhY9i{#9y{p_>#((nKv*&2#uyl|r zqCz}CuxOM>KCPJ4dmx4Gj6b+&Dt-$zNn$NYq*P^KGNf2$u0HT zjKQb+=I_A)vt=W?rNGIhJ=9wzLW_9)%|Jij<^G~@9ynV`k#rlNxKD(0%$cgLXp?oz zxq$p+jer_NK<$aoTi!iWv*6aU>b;}De}8sznQ=A>{;{?>D-mZIq>}9OEglypA7yO2 zJXr}Bg!SPyf*BSKGPHY*9#xsnRfo>?#%}Egb^JuM$$Um7=?alAUvQ19n$#Rm$)6qF zu3_@GN|76ri~O~92x8eS8Gt;tIIG-7ddeU!_^z5;C{>cWLzq+ias&;elRvj)Y7POT zVKS=!meq+``Fkxlh2Ak8?4K@NU+z~etAT&dl2p$PbFMQSyi;i~Ds zRmzy73)0i9isNKj(2{M|Ukzs|3uQIv_sE;21*|k|k`jQ%z{>IqLJEEI$55KR)Kn?D#v-a=z|@hmhIB(L4At zb|&Uha%z~{b?=Nt`Py^FOcPIzPGwZXDjvDDFCDTowOcUsKlR(|S@@wM{!;*w(yXD8 zbGyqml|ao!z3`xDdxyN>t%GtuZ#>WO2V8isCqcZDIUSY+p0L`ZZkkn=z{Fg$6y9GZ^4F%fv@yPWzPJr>k!kLD*%r8#HrYE7kiaG29tK?J21s}ad zZB~BtXyl?KC=^!$To`av)=W%he{`F9QsMidqp;zz;>d}7=&m;i5f5n2gr){i2InCXpRFfOB&rJj`a>)TtoYrbdtgL!_^i z;-XMG#9891{d1`|m2PHOEO;}TZRMxcdv?0^eo)ih9KE1}%AGi~l0hKo!~6Qf zWJJKw5dmsF^S9Gy^CiXAb9IFW(_DAVotkir%M;lKQ;^TD#@gft%K6?;3>cv(w-)Q* z3F-6?=rE4Kk4v}0Gs;lG3T|;YGRKj5)6x{Lgm9D2EUGv~F+be2PGF9wF>k#5gbBMk zyvd1gpq1%OWG(^llNUS6MsP3S&K?Kk@wmDp<>!2+F4Xl4%2&uT)T$*>0EZ{;ZRcb- z8`?KEp7wNkv^hbA!n`|6ZSuL$TgHIl>`%4sW6R`KlnyIU+NyAl0`s8yEMHNiMdYOL zcT90)5k1&2iUV!D!=FEP;yUYE&%)D1q@=^n8G8|;$H0$;%&BU%BEAM1!V5_KMCH1t z$?Ic^T%^mITYRs6%jG;0W>aPK{nX=)iUAg@Qx6Nh)nd+D`bgE4IQA$vm80}6T#;{? z5GfR&^SvA9-33m7$fR2Sfqx*OQ=q0+Xk~7qx2crR!-XZ@cSVPAhI3?KK5anx2isV; z@W^)zkvi`=2PFI7Sw4|d#vaLl+UWQYD7zYRn@bqRs-^|dQtOU;{2zOJz~8-?|8Gy` z|KHzfu=rjx>mc-}IJ9zk^CD}t8Dm~PlKPd8vIRuHk4n^0rPjkM4-opwPdN z^+;z6C?Utre~xwti<=mAvsWCn&LooWs8Y%*Dj__?M4)Q}HR)+c*XM;1J+^mXS!8A? zdwz4IkE7wdz%(Jx4MSs-(pHQ@$$x#mXv8=($w!|?ApK&J9@Ap9wV3S8OhV;D;Zm~v?G}l!Kl=`q=#X=1?fDp?1j~$%9jTzGY(6x z6s+zL9)yI%3gL#Xd`gFNt8A7zsg1pb6?JQVdsHypu(i*|Wmj%e{G857d7IoPA#WFd z3UnO@mFOsH;RN2`47!r#?cSzR7~^-W%QVQZjPoyQdgs8#o%XWuy3GnH#Kf%{dN9&c zG6wEHYi#&$0tc2}ITfI%&Fk-o<~0vzJv;Jqm@E_{a`}W= zCg&%Np9Li#jZ}2I=}}_b64I!BvDpQeiVP&?`#*%Vu6P7SF3xR1OtJ2!nS$zL`o$2$ zvAn5u>*q0ktt&K^my2u=zw00QXXou6YYLi-1O8)@aA3_`~1@T$*nOV?-KNiatE;F#3fg6oK17p7r6>R(zy&aMz zaPJh-jW__h>SuEQ-Auyy2uem}7D=M$jO_KB0)>1Ka=Ql z=Z+RgpIit*O&|8l@78sIoa4(3wg9~+0HSNgJYZ~ZL=}*O0hWfNht@oFN8W@OO_#*2ZQs`=*LvFbh~hzLf9X0<50Vnt5ux)S|O0YZ-*6uD8qe0v46m zup7c2cA8AtZPD?|yy2Nzt4hUYxAN7y$Yfe@)=aCjh~{qiLvnK`>}Md=ZiV zMva_Zm=u|-yWFqLIL!;l??cOKEh#xNGuLenkhvQ=?aY5PTNy=nG1jId6H|eEHicC@&RWMc zzVtU84wuikmvdm{NoDU;ha*=`%+P=V)NA1U&?2-xn$c_PGDb`cu81ric8nZKb~E^X z>f4r7*j&27lv2jM?qddvIQ?}#oIT}hU#tmt&V#0d39XAiu zWylLUcFkn;2@d6Z??A4W!>axI*z5n7F|gT2Ptqn}Kx8|8ftkLTWdAMK`@5~>{Xu#J z63M;QI9k#i7yM}^$4&?;kUwHUS9oS~yG&?9(oC$nxL}k#NYJF5M)drHfPHxalSoQJ z$C4lNgo&{}McL-`Vz)@ENlW7Z6_c+hTJ zbMu9NFpJfIY-8QClN~Z9+v$E!iZX&R@oBr%(@=pgBjDRoX33FTt#h&RJr1OU-e7`V zUL@H5H7R-c;dQ0=o2dw0{C0(+m>15<8=E+tT1EJ2o5?ifXveyrcrYLev!sek_p{)||8$LLfi|Gq^pQ~SMY9H=iF3oj| zF#rOfn&{Q*f|B2AI?IV`Czno&QKA4zjz3H7fZn&gkDUk#x(3T{L3%vd5lk}+F|eQ+ zoH9P@ROKd_v#<~v*k{!iym1Z}vJ#a#Qjs`cyn1KMaKfvP^jTi=(c~yx1*jBy1lJ^| zVAJm90UfBfC~7q~H_NONar098+W`8_`q&_@{|o+r%TR;L;|ym+hDD;rPIPRPU6$8x zZ0%6@f}>WZuxwB`mj=7^tarX1MDpiNt(n&*A-942BTcoNYQBp7!G=$X2S)^|b8%IC zkow-fOf2@`1>|v5^2U%|9Tj9RT{qvgxmq6=Ea?;oWc?ubS-06ju4p(B|qL~j9E z(Rug&!ptH}e2$RPm$NXr>0LS%cNMt=c}HqQYV6-Q(};BlP)4=H8FQlin660i;a}S) zfiW?-6mmxuao*5bU(@es6HXnwW;jL3p7rMHsiUgNnQzbO^RmIw`OGZ^Ib1R6%B3Pu zoF@(})u?`D{4RY@xtT?Ifc8K33{>2Pa7cs{tGxV#ydF4Zl8+N3$+Q@h0Jp4zFFUyP zNqzr?dr?S=kk6FCbL#VZl804N>5=fcYKf~n9DtFNzNrjtdjG;wZ`_*urh6^g%~20R zK*@Bg!mt0fz*?`c!|EGSCLdLNIH1()HHR$nMwy-46&Un1+EoLC-+buV?U8wkW&DSR zTdB~2(C^~jJa|~7yYjj1oEOl###&FljWBPgHI4dC@4!J>2cyn5A=zRn&W+diX~Xj>oId!bmZoHhdi@HhtuTb4qV4V$tK{o#^sUe+)++*a_u{9I3(OW(p7x zVm~x3QRl?rcb9j-;(qGl$scvQW7J_;{YPp*abyD*-xo&BRJ~du;imcQfx8v7^BF8w zV~>HQC3g?swF?R&1gE59+taqXp&q$Ry$>6Ao2DwI9>G5=3U0*ofdO-@q^fsN;!PcQ z70wbjsle-d17+5UF_;YGMmzcNl$pH_4X9c>LTvMeke?>I?z+<9aNy{pn)o1bH^bY! zSwLv}LZ~!nc6jJ$W0YLiDS{C57Ag=a5inSISYDGdToJ{nymq(LSP|I3KHuqX+B_fF zktq?#v4wD*3|kc7y{6pcr{F+CzFRe&RByIk2SoGOWmf8Z{DPuC*Rb4iQTna@#(L5h zVi|}?b~lD}ER`s$t9rLpk;(u{t)@0#aqr5HXIzN~B^7fiyPn&YrD<-hWjU^#Ni&ua zG3=FDlWsaFn@e@_(W7#iZT%^%%Y@>r4X-hNbYcpxtHaZ=-pcE#@;deuzEOq9CYLC5 zPTfjcB{UR3LrvUOr^v&eGXE3?t!sk2t=smL^GfOW*Z$1KdL-3 z2>ET2lc+c77NHHFS|?30WHB9Hq$789D7D2B(%DT+K=dgL)#h{xE8#`bYJMrLZ9J`iu?P}69cX+~ zFEBi0@ss$=5}54Z(VScVOob2OHyw|_JGfeG{ON%nmkuuvvJ?LyoVVE*hkW^H({oi0 zuE%vx>JwYWGe{q*NAT>;mw(_&TghZkWoMRx9{?maBB8(uAqB&PZ&arG*-So#kW0gJ zHt%$DFI+Cp0G>PvLI&m6E4`|EkdMb+lI|3XK-2)RrTV+chr24PmNY4L8;I39wZF8X)L$A4!(5Y_pTus(E`g4i0iBp&cKvY z8pBS(1>LV;1Ghsw=K#0Q&UVU;wTe>|iGct`l()B$;gsikup*9mL}|(GOqEUZ{HZ3- z9(4^9e_-LZZsmdmaAiF0HwMA}@N91D)4jay{lx>}> zYHmK(3(ZORVVO1DNm#O58%*j&_2Zki4qKbG0eX!NMp@6St_N9qkfI29FH4GMyeUkE zhl=l&N?jf-LU#kBqH%Puy#%XKE2%RWB~d){l5NAA7fo;}Zpu|bX?_E<;yn&9AGsdV z%2-G+ERXq;MuV*N^t`P#Dl!6i%tInz26{4i*Kz@; z!fPO65WH4W6SqfmA5xlf@;XH36WhvWXdIu9Sfumhhcypw+p9n7Ex&XXGjsWsfJZv) zl+@|>p|}1S5id?^zP#a@!I&`NT>81g?giaKfsgDVc%6$(R?E!;E77{K4k`P@@73zJ~Wea0-AK^@RsldAYap4 zgBHFSWO5oP%M$?BjQY43)A=1prURaINVK^*;DP>JrWlHy;~PS}+S0^q`5Mk74}v46 zef7ryFDGl&S3N@4()AXlSo94Z7$*n*xHC(s%F9VAzE3`V!UWvqdwPi*XqWt(BO{6) zgalHW4xA0H_NWR6{l$?NZH2==bDg+3>wCX8+0F4}I24&1$(8sT+oQYjarX5he-JX% zbD#+Ri>#yM=X@M1aIKtfNdJc)ucZvpyLW#*h6tbcaaMkJ=CQB++F3d_db6vO!>0`}yZnU>Z7 z-8u!N#WuuWzp090z52D!bc3bqSA4a|-^4i2DeG7Ynt|4u@LN1?O=g9;#WBDJCB?5q zL3H-O4>a~Jbu*@?V@xO5iZ$ew=OXJjb_sL(N~jR^1p z-Yuiu*WwQ*rawKh))NuA=(MNy2Ni26i5<-VF3zs&c;`ZEBiomF(1bg<{}W^!m^8G} zm!i{TlHBdR(?ftc-HdskDLZ02VOXgVz7C~Z`e$k0n`ri~rCHWuqnS+iZnM;1W*NWy_h%lV}LVX5O&5V5QQEJV~nnepg9UzMeQd zRK@4@@040^^ZWgh9-7;!sN%Q>6K%u!DzeYD8@K=F)vdBF6{_u;!H=4rbQvwFeX9-! z@DkYv6l(y?8gieOH|Wx`Eeelbecf1IkL7L3YkwrOE8To?Y=>P)-G=vGn2pj*m%38U zh3;LUzn6;&2!Q!uH>e;L!ZBYKe$aMbVy>=atvr4YI6O;FU}pH+*<@pF!g|(sfJJi zJj`7lYsR+55vD%&AWcA@31#b(KmCX&fkEG(0U<_l-JdlN2B(0CBY76$TA%4|AfZ{h zDLq~N(^oyJRJZCTu{22f$SK->Vt1 zf#dC3#1AX1w)%u?-DM?IAIvHS6Ssu2vfj6*^V-Z)>p&CD5F1K|qTlf$idE#o6#!hB zs0ym7B2D<&-V+E~W@( zpB^|Q%3Mroc~xY6-cA2RE#`xid`x;#4d{{acEsX4HLLZ;YLvCCcULJjL9gSR_{?S3 zc5S~|BHWnX&0)FjRftnz0Xop5rOJDj&esS8A+5C5@|RDF3kE2+KuZptLulJg^KM0> z<@6;eR&kvAa&?~h|6RVR5{^MVAH04kHe=!92W|Q6pfu*%2L9rESc#7X0ThJd%F&#y zYu#c%K7GO0q(7?W$`_GePid8rV*Uk|(u3Jj@;gaxcNc(u%hZE7$)I=(GVUk!Xki9r z^hS9MFs~M5)4|yo(%H3>0$;aMEm~IuDvCnF6!Mh4o6Qlowxz;s5V$K-&vTpe<;UNO z2bHlVobSPyq#35(B{b@tX}03s^xpPM`Y=|IYhW&HPI%dv)qt8(is4XGj>jA4pPbon z$jXllM)u>O;X_Z1_^NQs3lNw1G@D|n2L<2`%xW|$ZUOMW0JfZgy&A&rag{cm14G7! zopf9-6{GyG*^IItsM}0hQ74F6`;N+4SXsTawawW)8YfYS2i!4D%w%+>KEF z3LwjpxPwvC`q;iwUixSfbq?tHT~N>Wy-@bxttLK3?7}-eQLoJuq4^g#Plp_t@T`cV zzw#kbaJhJyZJ!g~aQaWo69QiU0b6FjI?d&BL>Ocqm{)OZNCQO4BjC*zGYf{a02L}6< zYyH@sZYNd&AJ+XH{UVQ%Yke_PZ5Ze^^k8-Q9!rB10asQqhsf- zZ2*Zrz_Wz>(oz`w)oNWB3a>AdV|sQu5>OI&4pZt?AAB_3HV^D@Km{G~WCD9h2?p>t zF1E&FIcl1M@W+oVCvTAn^C8YX7F<9>W6PB0MeR0~xzQAu;Q`DZT4qO_4KhFtgGgbkxi=A#t4Y z(Jro%Uyw%liTXq=e)XyPjc1Beq&x(8VNHZB*HCH@PCOai?0Uznxr}RTCm&-tv8vU; z7UPzL&1t35Lq15R>Jtg0hy!7MM{^gd`?CQ*zjH-( ziw;e8E+MLa(8H7hpU>%HE&8jNXXU?USl%uG6{Xv0!NY9t7E~%oc%&HNbaz)}GCIsp zkj&oXV}>|gotF>!p552JE4lNP$9aM1ky41oUsWEQReJAvSXpP`9W~J7chZrZ<9QNa zw4^iL;Oxu(^>x7}~xJmS|4hdq;v0j8TTw7G`%s4Q+X| ztX#GlHA7>AGcqg04f>)mbDI^&tJ*J@_A5QS{46e|F~0e%{r<##+zadN&-0IxM%Ilb zot7%%*5P_x_=>lV+C}7$z_XEpjon}ZO5~fv6DhFqRgH%{Bpz^e=yziOrSbwHT z^<-!*a*I4OWmkvrDl3~B0IJcs5>_=mqdPR$w;P(a;Cg@oecfJTwFIE}3&HXw;e5PK zV<=luZJe@rR<{D2_Do&n_y9=!D(0K*5^zr)hXoVxI=rY&!>HP}V-t-u=cy_|J*Vn`KRS6i|ZKrN0;wdp*CBx@*+xGLvdf9Gw3fVb`E z?uR41VjE-eK(*R>_NgOZdGk?5v8}^$x*{DWzm4d#?7^poQ_m_^Yoz=*l17#=Q)jq| z*$=#ewl-&&W?7babK=Zhp&nhU3WFs$zl1(Xzh&x`m8%r}5L#q|vmo^`{>nG6u7tZl zGAzQ@TP7GgCpxn+K62W_a1=K(Phr#p@YXtv2mEWZ=t}", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAmMAAAJdCAYAAAB+uHCgAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/MnkTPAAAACXBIWXMAAAsTAAALEwEAmpwYAABWFUlEQVR4nO3dd3xUVf7/8fdMeg+EJPTekaaggK6ICIhS7OKq6FrXtayoq9hWxLLKuquurH5FV92fYmWxgLuI4uoqoKIgIAYCJISSkJ5MeiYz5/dHYCS0UDJzp7yej0cezNw75XNyk8ybc84912aMMQIAAIAl7FYXAAAAEMoIYwAAABYijAEAAFiIMAYAAGAhwhgAAICFCGMAAAAWIowBLaRPnz6aPHmypk6d6vm6//77JUlTp06Vw+FQRUWFpk+fbnGl2Llzp4YOHdrs47744gs9++yzkqRly5bp0Ucf9XZpIWPu3Ln67LPPJEnPPvusPvjgA2sLAiwUbnUBQDD55z//qdatWx+w/cMPP5TUGALWr1/v67JwjNavX6/y8nJJ0tixYzV27FiLKwoe3377rXr27ClJ+v3vf29xNYC1CGOAD/Tp00crV67Uvffeq9raWk2dOlULFy7UkCFDdMMNN2j58uUqKCjQ9OnTdfXVV0uS3nvvPb311ltyu91KTk7Wgw8+qB49euj777/XE088IbfbLUm68cYbNWHChENu35fb7dbjjz+utWvXqqqqSsYYPfroo+rdu7dGjx6tTz75RKmpqZKkSy65RDfffLNGjhypp556SqtWrZLL5VL//v31wAMPKD4+XmeeeaYGDRqkTZs26Y477lB4eLhefPFF1dfXq6SkROedd55uv/12SdK8efO0YMECxcXFadiwYVq2bJk+//xz1dfXH/L19/fCCy9o6dKlcrvd6tChgx566CFVV1dr2rRp+uqrrxQZGSmXy6UxY8bolVdeUXx8vGbNmqVdu3bJGKPzzjtP1113XZPXfO6551RaWqo//vGPTe5PnTpVb7/9tlwulxISEtSlSxd98sknevHFF7V79+6Dvu7OnTt19dVXa/To0Vq7dq3Ky8s1Y8YMnXPOOQe05bPPPtPcuXPlcrkUHx+ve++9VyeccILGjBmjuXPnauDAgZKkGTNmaPjw4fr1r3990Panp6fryiuvVFJSkrKysnTZZZfpyiuv9LyPy+XSnDlz9PnnnyshIUGDBg3S1q1b9frrr6uiokKPPfaYMjMz5XQ6NXLkSN19990KDw/XwIEDj/pnc+bMmSorK9OOHTt0xhln6KKLLtLs2bNVXV2tgoIC9e3bV88884wWLFign376SXPmzFFYWJiWLVumXr166dprr9X333+vOXPmqKamRhEREbr99tt1+umna+HChfr0009lt9uVk5OjiIgIPfnkk+rdu7eWLl2qF154QTabTWFhYbr77rs1fPjwo/kVBaxlALSI3r17m0mTJpkpU6Z4voqKijz7iouLzY4dO8yQIUOaPOf11183xhizfv16c8IJJ5ja2lrz7bffml//+temurraGGPMV199ZSZOnGiMMWb69Olm8eLFxhhjMjIyzKxZsw67fV+rV682t956q3G5XMYYY1588UVz4403GmOMufvuu83LL79sjDFmy5Yt5owzzjAul8s899xz5oknnjBut9sYY8xf/vIX89BDDxljjBkzZoyZO3euMcYYt9ttrrjiCpOdnW2MMWb37t2mX79+pri42Pzvf/8zEyZMMOXl5cbtdpt7773XjBkzxhhjDvv6+3r//ffN7bffbpxOpzHGmLfffttcd911xhhjLr/8cvOf//zHGGPMF198YaZNm+bZ/sorrxhjjHE4HGby5Mlm8eLFTY7D3/72N/Pwww973mff+/ve/te//mVuuOGGZl+3d+/e5vPPPzfGGLNkyRJzxhlnHNCWLVu2mFGjRpnt27cbY4xZsWKFOfXUU01FRYV59tlnPe9ZVlZmTj75ZONwOA7b/iuuuMLce++9B7yPMca89dZb5vLLLze1tbWmrq7OXHPNNeaKK64wxhgzc+ZM8//+3/8zxhjT0NBg7rrrLjNv3jxjzLH9bN5zzz3mqquu8rz3E088YT744ANjjDH19fVm0qRJZsmSJZ6a9x6ze+65x7z88sumpKTEjBw50vz444/GGGMyMzPNySefbLZv327+9a9/mZNOOsnk5eUZY4yZPXu2ufvuu40xxowdO9asWbPGU89zzz130O8F4K/oGQNa0KGGKQ9n79DXgAEDVF9fr+rqan3xxRfKycnRtGnTPI8rLy9XWVmZJk6cqNmzZ+vzzz/XqFGjdMcdd0jSIbfva+jQoUpKStLbb7+tHTt26Ntvv1VcXJwk6eKLL9bDDz+sa6+9Vv/61790wQUXyG6364svvlBFRYVWrFghSXI6nUpJSfG85rBhwyRJNptN//d//6cvvvhCixcv1tatW2WMUU1Njb788kudffbZSkxMlCRdfvnl+uabbySp2dff67///a/Wr1+vCy+8UFJjL19NTY2n9vfff19nn322Fi5cqIsvvljV1dVavXq1XnnlFUlSQkKCLrjgAv3vf//T4MGDj+oY7au5142IiNDo0aMlSf3791dZWdkBr/HNN99oxIgR6tSpkyRp5MiRat26tX766SddeOGFuuiiizRz5kwtXrxYY8aMUUJCwmHbv+9x2N+XX36pqVOnKioqSpJ06aWX6vXXX5fU+L1fv369FixYIEmqra1t8tyj/dmUpJNOOsmz/Q9/+IOWL1+ul156Sdu2bVNBQYGqq6sP+b1dt26dOnfu7Dk+vXr10oknnqjvvvtONptNAwYMUNu2bT3f208//VSSdO655+qWW27R6NGjdeqpp+r6668/5HsA/ogwBlhs74ekzWaTJBlj5Ha7NXXqVP3hD3+Q1PjBW1BQoKSkJE2bNk1jxozR8uXL9dVXX2nu3Ln66KOPDrk9ISHB815ffPGFHnvsMf3mN7/R2LFj1b17d3300UeSGj/MGxoatG7dOi1evFhvv/22573vu+8+T8CoqqpSXV2d5zVjY2MlNYaU888/X2eddZaGDRumCy+8UJ999pmMMQoPD5fZ5zK4YWFhntvNvf6+j7vuuuv061//WpJUX1/vmc919tln609/+pO2bt2qVatW6YknnpDL5Wrynntfo6Ghock2m83W5HFOp/Nwh0tut/uwrxsRESG73e557YPZ//l7tzU0NKhDhw7q37+/vvjiCy1cuFD33Xdfs+2XfjkO+wsPb/pnfm9te1/z2WefVY8ePSRJDoejSc1H+7O5fx133HGHXC6XJk6cqDPOOEN5eXkHbfu+9Rzq+xIREaHo6GjP9n2P24wZM3TRRRfp66+/1sKFCzVv3jwtXLiwSVsBf8ZPKuBD4eHhBw0J+zv11FP18ccfq6CgQJL01ltv6aqrrpIkTZs2TRkZGbrgggv0yCOPyOFwqLy8/JDb97V8+XKNGTNGv/71rzVw4EB99tlncrlcnv0XX3yxHnnkEfXp00ft27eXJJ122mmaP3++6uvr5Xa79eCDD+qvf/3rATXn5OSosrJSt99+u84880x99913nueMHj1aS5cuVUVFhSR5emKO5vVPO+00LViwQJWVlZIaz8C7++67JTWGhnPPPVczZ87U+PHjFRMTo/j4eA0ePFjz58+XJFVUVOiDDz7QqFGjmrxuq1attGHDBhljVF1dra+//tqzLyws7IDwdqSvezgjRozQ8uXLtWPHDknSypUrlZeX5+kRuuSSS/TSSy+ptrbW09N0uPYfzujRo/XRRx+pvr5eDQ0Nev/99z37TjvtNL322msyxqi+vl433XST3njjjcO+3uF+Nvf39ddf6+abb9Y555wjm82mtWvXen7eDva9HTx4sLKzs7Vu3TpJ0ubNm7Vq1SqdfPLJh6ynoaFBZ555pqqrq3XZZZfpoYce0tatWw94bcCf0TMG+FBqaqr69++viRMn6q233jrk4371q1/p+uuv1zXXXCObzab4+HjNnTtXNptNd911lx5//HE988wzstvtuuWWW9SxY8dDbt/XtGnTdNddd2ny5MkKCwvTsGHDPBPC7Xa7zjvvPP31r39tEoZ+97vf6cknn9T5558vl8ulfv36aebMmQfU3KdPH51xxhmaOHGiEhMT1blzZ/Xs2VM5OTn61a9+pUsuuUSXXnqpoqOj1atXL8XExBzV61988cXKz8/XJZdcIpvNpnbt2umJJ55osv+NN97QrFmzPNueeuopzZ49WwsXLlR9fb0mT56sCy64QLt27fI8ZsqUKfrqq680fvx4paena+jQoZ6wPHLkSN16662KiIjQgAEDjup1D6dnz5566KGHdMstt8jlcik6Olr/93//5+nFPPPMM/Xwww83GW5rrv2HcsEFFyg7O1vnnXeeYmNj1bFjR8/3/v7779djjz2myZMny+l0atSoUQec4LC/w/1s7m/GjBm6+eablZSUpJiYGA0fPlzbt2+XJI0ZM0ZPPvlkk57I1q1b69lnn9Ujjzyi2tpa2Ww2/elPf1K3bt20Zs2ag9YTHh6u++67T3fddZfCw8Nls9n0+OOPKzIystnvDeAvbKa5/6IDwHFav3691qxZ41lj7dVXX9XatWv1zDPPWFtYCPj6669VXFysqVOnSpIeffRRRUVFeYYZAViPMAbA6yorK3XfffcpKyvL06vzyCOPKD093erSgl5+fr5mzpyp4uJiuVwu9e3bV7NmzWoylxCAtQhjAAAAFmICPwAAgIUIYwAAABYijAEAAFiIMAYAAGChgF5nrLS0Sm63d88/SEmJV3FxpVffw1/R9tBsuxTa7Q/ltkuh3X7aHpptl7zffrvdplat4g65P6DDmNttvB7G9r5PqKLtoSuU2x/KbZdCu/20PXRZ2X6GKQEAACxEGAMAALAQYQwAAMBChDEAAAALEcYAAAAsRBgDAACwEGEMAADAQoQxAAAACxHGAAAALEQYAwAAsBBhDAAAwEKEMQAAAAsRxgAAACxEGAMAALAQYQwAAMBChDEAAAALEcYAAAAsRBgDAACwEGEMAADAQoQxAAAAC4VbXQAAAMDRchsjl8uoweWWy20av1xuNez51+Vq3Nbg3nN7z+MaXEYu997bjf+OGd7F0rYQxgAAgE85G1yqqHbu+aqXo7peFdVOz7+Ve25X1jjV4HI3Bqj9wpQxLVePSzadMahdy73gUSKMAQCA4+JscKtiT5Cq2C9Y7bt977baetdBXyfMblNCbIQSYiOVGBuhNknRigi3KzzMrjC7TWF2u8LCbAoP23PbbvtlX9g+t/fbHhZmV/g+z2/cbld4mE3hdrv69GijoqJKH3/XfkEYAwAAkiRjjOqdblXVOlVZ0/hVVdvwy+09X5U1TlXWOlVR5VRFTb1q6g4druJjI5QYG6mE2Ah1T05qErYS9mzfuz8mKlw2m83HrZYl77kvwhgAAEGoweVuDE61DZ4AVbUnRDXe/mV7XYNbZRW1qqxpUIPLfcjXjIywKz4mQvHREYqLiVC39jFKiIloDFhxkUqIiVRi3C8hK9aicBVoCGMAAASIBpdbjqp6lVXWq7yqTuVV9XJU1qu8au9XncorG+daHWooUGrssYqLidgTrMLVNiVWHVPjGu/HRCguOnyf2xF7HhuuiPAwH7Y2dBDGAACwkNsYVdY49wlVjSGrvLJejqp9glZlnapqGw76GvExEUqKi1RiXKR6dkhSfGxEkzC1b8iKi4lQdGRYkx6r1NQEFRZW+KrJ2A9hDACAI+R2Gzldbjkb9nztud2w936Dq+n+fR7jbHCrzun6JWDt6d1yVDnlPsipgZERdiXHRSkxPlLtUmLVt3OykuIilRQfpcS4yMbbewJYeBjLhgYywhgA4IgZY1Tf4FZtXYNq612qc7rkNkZud+O+xttGxjT2+Oz9d99tbreRUWOwaXxM4/M9t432PL7x9r6v67nvbrrP7Hm+57aMzJ7Xdxt5bh+uHnuYXdXV9QcNW3u/XO7jW0/BbrMpMS5CSXFRSoqPVKf0eE+oSoqPahKw9u+9QvAijAFAkHMbo7p6l2rrXaqtbwxRe8NUzd779S7V1DXIFmZXaXmNaut+eWzNnufV7NnWkus7HQ+bJLvdJpvNJrtNstltsu+9bbPt2aeDbGu8b7fbZJNNdnvjY6KiwmW32xQfGamIcHvjV5j9l9v73A8/7P4wRYTbFRm+z2P3PC5sz/sD+yKMAUCQMMZoV1GV1m8t1rqtxSooq1FNXYPq6l06kvxks0mxUeGKigxTdGS4YiLDFB0ZpuT4KEVH7dm259/oyDDFRIYrMsIu+94Q1CT87Llt33v7l9DTJAztve15TNPg5Lm95/m2fV67pUMN86ZgFcIYAASwOqdLG3NKtW5PACt21EqSOqXFa0DX1ocMUdGRYYqJavw3OjJM0VHhigy3Ky0tkUAC+BhhDAACTFFZjdbuCV8bt5fK2eBWVESY+ndtpUmjumhg9xS1Toy2ukwAR4gwBgB+rsHl1pad5Y29X1nFyi2qkiSlJcdo9OD2GtQzRX06tVJEOGfUAYGIMAYAfshRVa/1WcVau7VYG7JLVFPXoDC7Tb07Jev0Qe00qGcbtW0da3WZAFoAYQwA/IDbGOXsrtgz96tI2/IqZCQlxUdqWJ9UDerRRv27tlJMFH+2gWDDbzUAWKS6tkE/byvxDD86quplk9S9faKm/qqbBvdoo07p8bKzFAIQ1AhjAOADxhiVVtQpt6hKOwoqtT6rWJt3lsvlNoqNCtcJ3VtrUI8UndA9RYmxkVaXC8CHCGMA0II8oau4SrmFVdpVVNV4u6haNXW/XFewQ2qcxp/cSYN7tFGPDokKszP5HghVhDEAOAbGGJVV1mtXUaVyCxsD166iA0NXfEyEOrSJ04gB6erQJk7tU+LUPjWO3i8AHoQxADiMvaErt2hv2KpsNnS1T4lrDF6ELgBHgDAGAHs4G9z6MbNAG7YUKbeoyhPA9g9d7dvEaUT/dLVvsyd0tYlTYhyhC8CxIYwBgKStueV65eMM5RVXSzowdO0NXoQuAC2NMAYgpDkbXPrgq2wt+W67WiVEaeZVw9U2MUoJsREtfiFqADgYwhiAkJWV69A/Pv5ZecXVOn1wO10yppe6dGrFhbIB+BRhDEDIcTa49OHX2/Sfb3OUHB+lOy4ZrBO6p1hdFoAQRRgDEFKy8xz6x8cZyi2q0q8GtdOlZ/ZSbDR/CgFYh79AAEKCs8GtD7/O9vSGzbhksAbSGwbADxDGAAS9fXvDThvUTtPoDQPgR/hrBCBoORvc+mh5tv7zzXYlxUfq9osHa1APesMA+BfCGICglJ3n0CsfZ2hXUZVOG9hO08b2VGx0hNVlAcABCGMAgsqBvWGDNKhHG6vLAoBDIowBCBrbdjfODdtVSG8YgMBBGAMQ8JwNbi1aka1/r9yuxLgIesMABBTCGICAlrO7Qi9//LN2FVbp1BPaatpZvRRHbxiAAEIYAxCQGlxufbR8m/69MkeJcRH6/UWDNLgnvWEAAg9hDEDAydldoX98/LN20hsGIAgQxgAEjAaXW4uWb9PHK3OUEBeh2y4apCH0hgEIcIQxAAGhsTcsQzsLKzXqhLa6jN4wAEGCMAbAr7ndRv/5NkcffJWt+NgI3XbhIA3pRW8YgOBBGAPgtwrLavTy4p+1eWe5hvdN05UT+ig+ht4wAMGFMAbA7xhjtHz9br35WaZsNun6Sf01YkC6bDab1aUBQIsjjAHwKxXV9fp/Szbph8xC9emUrGsn9VObpBirywIAryGMAfAb67OK9crHGaqsceriMT00YXhn2e30hgEIboQxAJarc7r03n+36PPVu9ShTZxmXDJYndMTrC4LAHyCMAbAUtt2OzTvo5+1u6Ra44d30oWjuysiPMzqsgDAZwhjACzhcrv172+266Ovs5UYF6k/TBuifl1bW10WAPgcYQyAzxWU1ejlRT9ry65yndI/XVeM780CrgBCFmEMgM8YY/T1ujy9uWyz7DabbpjcXyMGtLW6LACwFGEMgE84quv1z/9s1JrNRerbOVnXnttfKUnRVpcFAJYjjAHwunVbi/TKvzequtapS8b01PiTO8nOAq4AIIkwBsCL6pwuvfv5Fv13zS51TI3TXZcOUce0eKvLAgC/QhgD4BXZeQ7NW/SzCkqqdfbJnXX+6d0VEW63uiwA8DuEMQAtyuV26+OVOVq0fJuS4iP1h8uGqm+XVlaXBQB+izAGoMUUlFbrpcU/a+suh0YMSNcV43orliUrAOCwCGMAjpsxRl+ty9Nbn21WmN2m304doJP7pVtdFgAEBMIYgOPiqKrXP5c0LlnRr0srXXtuP7VOZMkKADhShDEAx2xNZqFeW7JRNXUuTTuzp84azpIVAHC0CGMAjlp1bYPeWpap5et3q3N6vO6+rL86pLJkBQAcC8IYgKOyMadU//j4Z5VW1GvyqK6afGpXhYexZAUAHCvCGIAj4mxw6V9fZmnpqh1KbxWje688UT3aJ1ldFgAEPMIYgGZt2+3Qy4szlFtUpTNP7KCLz+ipqMgwq8sCgKBAGANwSPsu4JoYF6k7Lh2sE7qlWF0WAAQVwhiAg8orrtLLizOUnefQiP7punx8b8WxgCsAtDjCGIAm3MZo8ddZenXRBkWE21nAFQC8jDAGwKPEUatX/p2hn7eVamD3FP3mnL5Kjo+yuiwACGqEMQAyxuibn/P1xtJMud1GN180WCf2aC0bC7gCgNcRxoAQV1Fdr9c/2aTvNxWqZ4ckXTepnwb0TldhYYXVpQFASCCMASFs7ZYivfafjaqsceqiM3ro7JM7y26nNwwAfIkwBoSgmroGvfP5Fv1vba46psZpxiWD1Tk9weqyACAkEcaAEJO5o0wvL/5ZxeW1mjiis847rbsiwrmcEQBYhTAGhAhng1sffJWlJd9uV0pStO65/ET17pRsdVkAEPIIY0AI2J5foZcX/6ydhVUaPaS9LhnTUzFR/PoDgD/grzEQxNxuo/98m6MPvspWXEyEfn/RIA3u2cbqsgAA+yCMAUHIbYxWbyrUh8uztauwSsP6pOrKCX2UEBtpdWkAgP0QxoAgsn8Ia5cSq9+dd4JO6pPKAq4A4KcIY0AQOFgIu2FKf53cN511wwDAzxHGgAC2N4R9tDxbOwlhABCQCGNAANo/hLVtHasbJvfXyf0IYQAQaAhjQABxG6M1mYX68Ott2llYSQgDgCBAGAMCwP4hLL11rK6f3F+nEMIAIOARxgA/1hjCivTR8mztKCCEAUAwIowBfuiAENYqRtdP6q+T+6cpzM51JAEgmBDGAD9CCAOA0EMYA/yAMUZrNhfpo6+ztX1PCLtuUj+d0j+dEAYAQc6rYWzRokV64YUX5HQ6dfXVV+vyyy9vsv/LL7/UU089JUnq3bu3Zs+erbi4OG+WBPiV/UNYGiEMAEKO18JYfn6+nn76aS1cuFCRkZGaNm2aTjnlFPXs2VOS5HA4NHPmTL3++uvq2bOnXnrpJT399NN64IEHvFUS4DfKq+qVkVOiJd9s94Swa8/tpxEDCGEAEGq8FsZWrFihESNGKDk5WZI0YcIELVmyRLfccoskadu2bWrfvr0nnI0ZM0bXXXcdYQxBx22McouqtGVnuTbvLNfWXeUqKKuRJEIYAMB7YaygoECpqame+2lpaVq3bp3nfteuXbV7925t3LhRffv21X/+8x8VFRV5qxzAZ+rqXcrKc2jLrnJt2RO+qusaJEmJsRHq2TFZZwztoJ4dk9StXQIhDABCnNfCmDHmgG022y/rIiUmJurJJ5/Ugw8+KLfbrUsuuUQRERFH9R4pKfHHXeeRSE1N8Mn7+CPa3rzi8hr9nF2ijdtK9PO2EmXtKpfb3fjz37ltgn41tIP6dW2tft1aq11KXJPfA3/GsQ9dodx+2h66rGy/18JYenq6vv/+e8/9goICpaWlee67XC61bdtW7733niRpw4YN6tSp01G9R3FxpedDz1tSUxNUWFjh1ffwV7T9wLa73UY7Cys9vV6bd5ar2FErSYoMt6tbu0RNPKWzenVMUo8OSYqL3uc/GMaoqKjSV004Lhz70Gy7FNrtp+2h2XbJ++23222H7UDyWhgbNWqUnnvuOZWUlCgmJkZLly7VI4884tlvs9l0zTXX6L333lNaWppeeeUVnXPOOd4qBzgmNXUNjUOOO8u1ZWeZtuY6VFvvkiQlxUeqV4ckjRveSb06JqlTWrzCwxhyBAAcHa/2jM2YMUPTp0+X0+nURRddpEGDBun666/XbbfdpoEDB2r27Nm67rrrVF9fr5EjR+raa6/1VjnAEXNU1ev95eu1dlOBdhRWyhjJJqlDarxGDmirnh2T1KtDklKSogNmyBEA4L9s5mCTuwIEw5TeFYptr651as6ba5RbXK1eHZPUq2OSenZMUo/2SYqJCp01kkPx2O8Vym2XQrv9tD002y4F8TAlEGjqnC49u2CddhVV6Y/XjlCnlBirSwIAhAAmuACSGlxuPf/+T9qys1w3TBmgE/umNf8kAABaAGEMIc/tNnp58c9an1Ws6Wf30XCCGADAhwhjCGnGGL3xaaa+yyjQxWf00OghHawuCQAQYghjCGkL/5elL9bs0sQRnTVxRBerywEAhCDCGELWkm+36+OVORo9pL0uGt3D6nIAACGKMIaQ9L+1uXr3v1s0vG+arhzfh/XCAACWIYwh5Hy/sUD/XLJRJ3Rvresn95fdThADAFiHMIaQsiG7RPMWbVCP9km6+byBXL4IAGA5PokQMrbsKtdzC9epbes4/f7iQYqKDLO6JAAACGMIDTsLKvXse2uVHBelOy8drLjoCKtLAgBAEmEMIaCgrEZ/eedHRYTbdde0IUqKj7K6JAAAPAhjCGqlFXV66q01anC5dee0oWqTzPUmAQD+hTCGoFVZ49Rf3/1RFTVOzbhkiDq0ibO6JAAADkAYQ1CqrW/Qs++tVX5JtW67YKC6t0+0uiQAAA6KMIag42xw6+8L1ysrz6HfTj1B/bq2trokAAAOiTCGoOJyuzVv0QZt2Faq30zspxN7p1pdEgAAh0UYQ9AwxuifSzbph02Fmja2l04b1M7qkgAAaBZhDEHBGKN3/7tFX6/L05RTu2r88E5WlwQAwBEhjCEo/PubHH3y3Q6NPbGjpp7WzepyAAA4YoQxBLz/rtmlf32ZpRED0nXZuF6y2bjwNwAgcBDGENC+/Tlfb3yySYN7pOiac/rJThADAAQYwhgC1rqtRXp58c/q1SlZN513gsLD+HEGAAQePr0QkDJ3lOn5939Sx9R43XbhIEVGhFldEgAAx4QwhoCTs7tCzy5Yq9aJ0Zpx6WDFRodbXRIAAMeMMIaAkl9Sraff/VExUeG6a9oQJcZGWl0SAADHhTCGgPLGp5lyG+nOS4eodWK01eUAAHDcCGMIGFW1Tm3MKdXpg9urXUqc1eUAANAiCGMIGOu2FMvlNlxvEgAQVAhjCBirMwuVHB+pru0SrC4FAIAWQxhDQKh3urQ+u1hDe6eysCsAIKgQxhAQNmSXqN7pZogSABB0CGMICKs3Fyo2Klx9OiVbXQoAAC2KMAa/53K7tXZLsQb3TOGSRwCAoMMnG/xe5o5yVdY4GaIEAAQlwhj83prMQkWE23VCtxSrSwEAoMURxuDXjDFas7lQA7q2VlQkFwMHAAQfwhj8Wk5+hYoddQxRAgCCFmEMfm11ZpFsNmlIrzZWlwIAgFcQxuDX1mQWqk+nZMXHRFhdCgAAXkEYg9/KL6nWrqIqDWWIEgAQxAhj8FurMwslSSf2IowBAIIXYQx+a/XmQnVJT1BKUrTVpQAA4DWEMfilsso6bd3l0Im9mbgPAAhuhDH4pTWbiySJJS0AAEGPMAa/tCazUGmtYtS+TZzVpQAA4FWEMfid6toGZeSU6sTeqbLZbFaXAwCAVxHG4HfWbS2Sy20YogQAhATCGPzO6s1FSoqLVPf2iVaXAgCA1xHG4FecDS6tzyrW0F5tZGeIEgAQAghj8CsbtpWqrt7FECUAIGQQxuBXVmcWKiYqTH27tLK6FAAAfIIwBr/hdhv9uLlIg3q0UXgYP5oAgNDAJx78xuadZaqscTJECQAIKYQx+I3VmUUKD7PrhG6trS4FAACfIYzBLxhjtGZzofp3baWYqHCrywEAwGcIY/ALOwoqVVReyxAlACDkEMbgF1ZnFspmk4b0amN1KQAA+BRhDH5hdWaRenVIUmJspNWlAADgU4QxWK6grEY7CysZogQAhCTCGCy3elOhJBHGAAAhiTAGy63eXKjOafFqkxxjdSkAAPgcYQyWKq+q19ad5RpKrxgAIEQRxmCpHzcXyoghSgBA6CKMwVKrM4uUmhytjqlxVpcCAIAlCGOwTE1dgzJySjS0V6psNpvV5QAAYAnCGCyzPqtYDS7DECUAIKQRxmCZ1ZmFSoyNUM8OSVaXAgCAZQhjsISzwa11W4s1pFcb2e0MUQIAQhdhDJbIyClVbb2LIUoAQMgjjMESqzMLFR0Zpn5dWltdCgAAliKMwefcbqMfNxdqUI8URYTzIwgACG18EsLntuaWy1Ht1NBeDFECAEAYg8+tzixUeJhNg3qkWF0KAACWI4zBp4wxWp1ZqH5dWismKtzqcgAAsBxhDD61q7BKhWW1Gtq7jdWlAADgFwhj8KnVmYWyScwXAwBgD8IYfGp1ZqF6dExSUlyk1aUAAOAXCGPwmcKyGm0vqNSJ9IoBAOBBGIPPrNlcJEk6kfliAAB4EMbgM6szC9UxNU5prWKtLgUAAL9BGINPOKrrtXlnGdeiBABgP4Qx+MTazUUyhrMoAQDYH2EMPrE6s1ApidHqnB5vdSkAAPgVwhi8rqauQRu2lerE3qmy2WxWlwMAgF8hjMHrNmSXqMHl5ixKAAAOgjAGr1udWaj4mAj16phsdSkAAPgdwhi8qsHl1tqtxRrSq43sdoYoAQDYH2EMXrUxp1Q1dQ2sug8AwCEQxuBVqzcXKSoiTAO6tbK6FAAA/BJhDF7jNkZrNhdqYPfWiggPs7ocAAD8EmEMXpOV61B5Zb2Gsuo+AACHRBiD16zJLFSY3abBPVKsLgUAAL9FGINXGGO0OrNQfbu0Umx0hNXlAADgtwhj8Ircoirll9ZwYXAAAJpBGINXrN5cJEka0pNV9wEAOBzCGLxidWaherRPVKuEKKtLAQDArxHG0OKKy2uVs7uCIUoAAI4AYQwtbvXmQkliSQsAAI4AYQwtbk1modq3iVPb1rFWlwIAgN8jjKFFVdY4lbmjXCf2ZuI+AABHgjCGFvXj5iK5jdFQLgwOAMARIYyhRa3ZXKjWiVHq2jbB6lIAAAgIhDG0mLp6l37KLtHQXqmy2WxWlwMAQEAgjKHF/JRdLGeDmyUtAAA4CoQxtJjVmUWKiw5X705JVpcCAEDAIIyhRTS43Fq3tUhDerZRmJ0fKwAAjhSfmmgRGTmlqqpt0Il9GKIEAOBoEMbQIr7LyFdMVJhO6JZidSkAAASU8OYesGnTJn366afKzs6W3W5X9+7dNWHCBHXv3t0X9SEANLjcWp1ZpKG9UhURTr4HAOBoHPKTs6SkRLfddpvuvPNOVVdXa/jw4RoyZIgcDod+//vf6/bbb1dRUdFhX3zRokU655xzNG7cOM2fP/+A/Rs2bNCFF16oKVOm6MYbb5TD4Tj+FsHnNmSXqKauQSf3S7O6FAAAAs4he8buu+8+XXfddRo2bNgB++655x59++23uv/++/Xiiy8e9Pn5+fl6+umntXDhQkVGRmratGk65ZRT1LNnT89jHnvsMd12220aPXq0nnjiCf3jH//QjBkzWqBZ8KXvMgoUGxWu/l1bW10KAAAB55A9Y88///xBg9hep5xyil544YVD7l+xYoVGjBih5ORkxcbGasKECVqyZEmTx7jdblVVVUmSampqFB0dfbT1w2LOBpd+3FKoE3unKjyMIUoAAI7WIT897XuWJzj//PP13nvvqaam5pCPOZiCggKlpv5yZl1aWpry8/ObPGbmzJm6//77ddppp2nFihWaNm3aUTcA1vopu0Q1dS6GKAEAOEbNTuB/8MEH9c477+jZZ5/V+PHjddlll6lXr17NvrAx5oBt+14ip7a2Vvfff7/++c9/atCgQXr11Vd1zz33aN68eUdcfEpK/BE/9nikpobudRaba/u6TzKVEBupXw3rHHQ9Y6F83KXQbn8ot10K7fbT9tBlZfubDWMnnniiTjzxRDkcDi1atEg33XST0tLSdOWVV2rixImHfF56erq+//57z/2CggKlpf3Se5KZmamoqCgNGjRIknTppZfq2WefParii4sr5XYfGPpaUmpqggoLK7z6Hv6qubbXO136ZkOeTumXrtKSKh9W5n2hfNyl0G5/KLddCu320/bQbLvk/fbb7bbDdiAdUVeGw+HQhx9+qHfffVcJCQmaOHGiPvzwQ919992HfM6oUaO0cuVKlZSUqKamRkuXLtXpp5/u2d+lSxft3r1bWVlZkqRly5Zp4MCBR9ou+IH1WcWqq3dpOEOUAAAcs2Z7xu688059+eWXGjNmjGbNmqWhQ4dKki677DKNGjXqkM9LT0/XjBkzNH36dDmdTl100UUaNGiQrr/+et12220aOHCg/vSnP+n222+XMUYpKSl6/PHHW65l8LpVGwuUEBuhvp2TrS4FAICA1WwY69Wrl+6//361bt102YLw8HC99dZbh33u5MmTNXny5CbbXnrpJc/t0aNHa/To0UdTL/xEndOlH7cUadQJ7bgWJQAAx6HZT9EzzjhDM2fOlNS4Gv/UqVM9Q4s9evTwbnXwW+u2Fqve6dbwvgxRAgBwPJoNY7NmzdLFF18sSerTp49uvfVWPfTQQ14vDP5tVUa+EuMi1adTstWlAAAQ0JoNYzU1NRo3bpzn/llnnaXKykqvFgX/VlvfoHVbizWsT6rsdlvzTwAAAIfUbBiz2WzatGmT5/7WrVsPu9grgt/aLcWqb2CIEgCAltDsBP7f//73uuKKK9S7d29JUlZWlp566imvFwb/tWpjgZLiI9WLIUoAAI5bs2FszJgxWrJkiVavXq2wsDANHjxYKSkpvqgNfqimrnGI8owh7WW3MUQJAMDxOqLxxvz8fLVq1UoJCQnavHmz3n33XW/XBT/145YiNbjcLPQKAEALabZn7IEHHtCyZctUW1ur9PR0bd++XSeddJIuueQSX9QHP7Mqo0CtEqLUo0OS1aUAABAUmu0ZW7FihZYtW6bx48dr3rx5eu211xQdHe2L2uBnqmud+im7WMP7pjFECQBAC2k2jKWmpio2Nlbdu3dXZmamTj75ZJWWlvqiNviZNZuL1OAynEUJAEALajaMRUREaNWqVerRo4f+97//qaKigjAWolZtLFBKYpS6t0+0uhQAAIJGs2HsD3/4g95++22NHj1aGRkZGjFihKZMmeKL2uBHqmqd2pBdouF902VjiBIAgBbT7AT+n376SX/5y18kSe+9954cDocSE+kZCTWrMwvlchvOogQAoIU12zP21ltvNblPEAtNqzIK1CYpWl3bJlhdCgAAQaXZnrFu3brpgQce0LBhwxQbG+vZPn78eK8WBv9RWePUz9tKNeGUTgxRAgDQwpoNY2VlZSorK1NOTo5nm81mI4yFkNWZhXIbo5P7pltdCgAAQafZMPb666/7og74se8y8pXWKkad0+OtLgUAgKDTbBh79NFHD7r9gQceaPFi4H8c1fXKyCnVOSO6MEQJAIAXNDuBPzk52fMVFxenNWvW+KIu+InVmwpljHRyP4YoAQDwhmZ7xm655ZYm92+88UbdeOONXisI/uW7jHy1bR2rjqlxVpcCAEBQarZnbH+xsbEqKCjwRi3wM6WOWm3aUabhfdMYogQAwEuOas6YMUYbNmxQ9+7dvVoU/MOKdbl7hihZ6BUAAG9pNowlJyc3uT9lyhQuhxQivlqbq/Zt4tQhlbMoAQDwlmaHKW+88UZ17txZt9xyiy699FLV19c3WfwVwam0ok4/ZxdreF96xQAA8KZmw9js2bP1xRdfND7YbtcPP/ygxx9/3Nt1wWLfbyqQMSKMAQDgZc0OU65Zs0aLFy+WJKWkpOjZZ5/V1KlTvV4YrLVqY4G6tktU+zacRQkAgDc12zPmdDpVX1/vud/Q0ODVgmC9Ekettuws12lD2ltdCgAAQa/ZnrEzzjhD1157raZOnSqbzabFixdr9OjRvqgNFvl+Y+PSJacN7iDJWFsMAABBrtkwdvfdd+vNN9/UsmXLFB4ervHjx+vSSy/1RW2wyKqNBeqcFq8OqfEqLKywuhwAAIJas2HMGKOkpCS98MILKiws1Mcff+yLumCRovIabc116MLRrCUHAIAvNDtnbNasWZxNGUK+31goibMoAQDwlWZ7xn788UfOpgwhqzbmq0vbBKW1Yi05AAB8gbMp4VFQVqPsvAoufwQAgA9xNiU89p5FObwPYQwAAF85orMp58+f7zmbcty4cZo2bZovaoOPrcooUPf2iWqTHGN1KQAAhIxmw1hYWJimT5+u6dOne7ZVV1dzfcogk19arZz8Cl16Zk+rSwEAIKQ0G8Y+++wz/e1vf1N1dbWMMXK73SorK9OaNWt8UR98ZFXGniFKzqIEAMCnmg1jc+bM0e2336633npL119/vT777DPFxXG9wmDzXUaBenZIUuvEaKtLAQAgpDR7NmVMTIzOOeccDRkyRFFRUZo1a5a++eYbX9QGH8krrtLOwkp6xQAAsECzYSwyMlL19fXq3LmzMjIyZLfbmyx1gcC3amOBbJKGEcYAAPC5Zocpx44dqxtuuEFPPPGEpk2bph9++EHJyck+KA2+siqjQL06JqlVQpTVpQAAEHKaDWO//e1vNWXKFLVt21bPP/+8Vq1apUmTJvmiNvjArsJK7Sqq0uXjeltdCgAAIemQw5Tvvfee53b79u0lSf3799dVV12llJQUSdI777zj5fLgbXuHKE/qk2p1KQAAhKRDhrGGhgZdeumlmj9/vnJzcz3bd+3apbfeeksXXnihnE6nT4qEdxhjtGpjgfp0TlZyPEOUAABY4ZDDlJdddplGjx6tF198UXPnzlVFRYUkKTExUePHj9ezzz6rjh07+qxQtLxdhVXKK67WWSdxHAEAsMph54y1b99eDz/8sB5++GGVlpbKbrcrKSnJV7XBy77bmC+bTTqJa1ECAGCZZifw79WqVStv1gEfM8ZoVUaB+nZupcS4SKvLAQAgZDW7zhiC046CSuWX1mh4P3rFAACwEmEsRH2XUSC7zaaTenMWJQAAVjqqMLZjxw6tWrXKW7XARxrPosxXv66tlBDLECUAAFZqNoy9+eabuvPOO1VSUqJp06bpgQce0F/+8hdf1AYvycmvUGFZLdeiBADADzQbxhYsWKB7771XS5Ys0dixY/Xxxx9r+fLlvqgNXvJdRoHC7DadyBAlAACWazaM2Ww2tWnTRitXrtSIESMUHh4ut9vti9rgBXvPouzftbXiYyKsLgcAgJDXbBiLjIzUSy+9pO+++06nnnqq3nzzTcXExPiiNnhBVp5DxQ6GKAEA8BfNhrHHHntM27Zt05NPPqmkpCT98MMPevTRR31RG7xglWeIso3VpQAAAB3Boq/du3fXY489JqnxbMpp06apR48eXi8MLc9tjL7fVKATurVWbDRDlAAA+APOpgwhWbscKnHU6eR+6VaXAgAA9uBsyhDy3cZ8hYfZNaQXQ5QAAPgLzqYMEW5j9P3GAg3s3loxUUd8SVIAAOBlnE0ZIrbsLFdZZT3XogQAwM9wNmWIWJVRoIhwuwb3YIgSAAB/ckRnUz744IPKycmRMUaPPfaYoqOjfVEbWojb3XgW5aDuKQxRAgDgZ5rtGfvxxx911lln6cYbb1R+fr5Gjx6t1atX+6I2tJDMHWUqr2KIEgAAf9RsGJszZ45ee+01JScnq23btpozZ45n3TEEhnVZxQqz2zSoR4rVpQAAgP00G8Zqa2vVs2dPz/3Ro0fL5XJ5tSi0rI05perRPlHRkQxRAgDgb5oNY+Hh4SovL5fNZpMkZWVleb0otJzqWqdy8ivUt0srq0sBAAAH0WxXyU033aQrrrhCRUVFuuOOO7R8+XLNnj3bF7WhBWzaUSZjpH6EMQAA/FKzYWzMmDHq3r27li9fLrfbrd/97ndNhi3h3zJyShURblf39klWlwIAAA7iiCYRhYeHa8iQITLGqK6uThs2bNCAAQO8XRtawMacMvXskKSI8GZHpAEAgAWaDWN//vOf9cYbbygl5Zcz8Ww2m5YtW+bVwnD8KqrrtbOwUuef3t3qUgAAwCE0G8b+85//aOnSpUpPT/dFPWhBm7aXSZL6dWa+GAAA/qrZsat27doRxAJUxvZSRUWEqWu7BKtLAQAAh9Bsz9jIkSM1Z84cjR07tsllkJgz5v825pSqV6ckhYcxXwwAAH/VbBhbuHChJGnJkiWebcwZ839llXXKK67WaYPaWV0KAAA4jGbD2Jtvvqm2bds22bZ582avFYSWsXF7qSSpL/PFAADwa4ccvyorK1NZWZluuOEGlZeXq6ysTOXl5SoqKtLNN9/syxpxDDbmlComKlxd0pkvBgCAPztkz9idd96p5cuXS5JOOeUUz/awsDCNGzfO+5XhuGzMKVOfTsmy221WlwIAAA7jkGHsH//4hyTp3nvv1Z/+9CefFYTjV1xeq4KyGp15UkerSwEAAM04ZBjbunWrevTooSuuuEIbNmw4YD9nU/qvvfPFuB4lAAD+75BhbM6cOXrxxRd16623HrCPsyn9W0ZOqeJjItQhNc7qUgAAQDMOGcb69esnqTGUDRs2zGcF4fgYY7Rxe6n6dk6W3cZ8MQAA/N0hz6ZcvHix8vPzNXv2bM/ZlPt+wT8VltWoxFGnvgxRAgAQEA7ZM3bqqafqjDPOkDGmydmUUuMwZUZGhteLw9HLyGG+GAAAgeSQPWMPP/ywMjIydNJJJ2njxo1Nvghi/mvj9jIlxUWqbetYq0sBAABHoNmLFs6fP98XdaAFGGOUkVOqvl1aycZ8MQAAAgJXkA4iecXVclTVM0QJAEAAIYwFkV+uR5lsbSEAAOCIEcaCSEZOqVISo5SaHGN1KQAA4AgRxoKE2xht2l6mvp2ZLwYAQCAhjAWJnQWVqqxxsr4YAAABhjAWJDZuL5Mk9e1MGAMAIJAQxoLExpxSpSXHKCUp2upSAADAUSCMBQG322jTjjKGKAEACECEsSCQk1+hmroG9e2SbHUpAADgKBHGgsDGvdejZL4YAAABhzAWBDK2l6pdSqyS4qOsLgUAABwlwliAa3C5tXlHOfPFAAAIUISxALctr0J1ThdDlAAABCjCWIDL2HM9yj5cjxIAgIBEGAtwG3NK1SktXgmxkVaXAgAAjgFhLIA5G1zasqucVfcBAAhghLEAtnWXQ84Gt/oxeR8AgIBFGAtgG7eXymaTendKtroUAABwjAhjASwjp1Rd0hMUGx1udSkAAOAYEcYCVJ3TpaxcB0OUAAAEOMJYgNqys1wut2GxVwAAAhxhLEBl5JQqzG5Tr45JVpcCAACOA2EsQG3cXqpu7RIVHcl8MQAAAhlhLADV1DVoW14FQ5QAAAQBwlgAytxRJrcx6sclkAAACHiEsQCUkVOq8DCbenRgvhgAAIHOqxOOFi1apBdeeEFOp1NXX321Lr/8cs++jIwMzZw503O/pKRESUlJWrx4sTdLCgobt5eqZ4ckRUaEWV0KAAA4Tl4LY/n5+Xr66ae1cOFCRUZGatq0aTrllFPUs2dPSVK/fv304YcfSpJqamp08cUXa9asWd4qJ2hU1ji1I79SU0/rZnUpAACgBXhtmHLFihUaMWKEkpOTFRsbqwkTJmjJkiUHfeyLL76o4cOHa9iwYd4qJ2hs2l4mIzF5HwCAIOG1nrGCggKlpqZ67qelpWndunUHPM7hcOjdd9/VokWLjvo9UlLij6vGI5WamuCT9zkSOV9nKyoyTCcP6qCIcO9P+fOntvtaKLddCu32h3LbpdBuP20PXVa232thzBhzwDabzXbAtkWLFumss85SSkrKUb9HcXGl3O4D36clpaYmqLCwwqvvcTTWbCxQz/aJKiut8vp7+VvbfSmU2y6FdvtDue1SaLeftodm2yXvt99utx22A8lrXSvp6ekqKiry3C8oKFBaWtoBj/vss890zjnneKuMoOKoqteuoiqGKAEACCJeC2OjRo3SypUrVVJSopqaGi1dulSnn356k8cYY7RhwwYNHTrUW2UElY3bSyUxXwwAgGDi1Z6xGTNmaPr06TrvvPM0adIkDRo0SNdff73Wr18vqXE5i4iICEVFRXmrjKCyMadU0ZFh6to2tMf1AQAIJl5dZ2zy5MmaPHlyk20vvfSS53ZKSoqWL1/uzRKCSsb2MvXulKwwO2v1AgAQLPhUDxClFXXKL6lWP4YoAQAIKoSxALExZ898sc6EMQAAgglhLEBk5JQqLjpcndJ9s7YaAADwDcJYgNi4vVR9OreS/SBrtQEAgMBFGAsAhWU1KiqvVd/OyVaXAgAAWhhhLADsnS/G5H0AAIIPYSwAbNxeqsTYCLVvE2d1KQAAoIURxvycMUYZOaXq26XVQa/tCQAAAhthzM/ll9aorLKeJS0AAAhShDE/51lfjPliAAAEJcKYn8vIKVWrhCilt4qxuhQAAOAFhDE/ZozRxu2l6ts5mfliAAAEKcKYH9tVVKWKaidDlAAABDHCmB/zrC/G5H0AAIIWYcyPZeSUqk1StNokM18MAIBgRRjzU25jlLmjjCFKAACCHGHMT+3Ir1RVbQNDlAAABDnCmJ/KYH0xAABCAmHMT23cXqr01rFqlRBldSkAAMCLCGN+yOV2K3NHmfrRKwYAQNAjjPmhbbsrVFvvUt/OyVaXAgAAvIww5oc816Nk8j4AAEGPMOaHNuaUqkNqnBLjIq0uBQAAeBlhzM80uNzavLOcXjEAAEIEYczPZOU6VN/gZvI+AAAhgjDmZzbmlMomqQ+T9wEACAmEMT+TkVOqzukJiouOsLoUAADgA4QxP1LvdGlrbrn6dkm2uhQAAOAjhDE/snVXuRpchsn7AACEEMKYH8nYXiq7zabenZKtLgUAAPgIYcyPbMwpU9d2CYqJCre6FAAA4COEMT9RW9+g7DwHS1oAABBiCGN+YvPOcrnczBcDACDUEMb8xMacUoXZberZMcnqUgAAgA8RxvxERk6perRPVFREmNWlAAAAHyKM+YHqWqdy8ivUl/liAACEHMKYH9i0o0zGiMn7AACEIMKYH9iYU6aIcLu6t2e+GAAAoYYw5gcyckrVs0OSIsI5HAAAhBo+/S1WUV2vnYWVzBcDACBEEcYstml7mSTmiwEAEKoIYxbL2F6qqIgwdW2bYHUpAADAAoQxi2XuKFOvjkkKD+NQAAAQikgAFqqpa1BuYZW6t0+0uhQAAGARwpiFtudXyEiEMQAAQhhhzEJZeQ5JUtd2hDEAAEIVYcxC2bkOtUmKVmJspNWlAAAAixDGLJSd52CIEgCAEEcYs0h5ZZ2KHXXqxhAlAAAhjTBmkey8CkkijAEAEOIIYxbJynPIbrOpSzqLvQIAEMoIYxbJznOoQ2qcoiLDrC4FAABYiDBmAWOMsnMdDFECAADCmBUKSmtUXdfAmZQAAIAwZoW9i712p2cMAICQRxizQHauQ1ERYWrfJs7qUgAAgMUIYxbIznOoS9sE2e02q0sBAAAWI4z5WIPLrZz8SoYoAQCAJMKYz+0srFSDy61uTN4HAAAijPlcdm7j5P1u7VjsFQAAEMZ8LivPocTYCKUkRltdCgAA8AOEMR/LzqtQt3aJstmYvA8AAAhjPlVT16C8oirmiwEAAA/CmA9t210hIxZ7BQAAvyCM+VD2npX3uxLGAADAHoQxH8rOdSitVYziYyKsLgUAAPgJwpgPZeU5GKIEAABNEMZ8pLSiTqUVdepGGAMAAPsgjPnItj3zxTiTEgAA7Isw5iNZeQ6F2W3qnBZvdSkAAMCPEMZ8JDvPoY6p8YqMCLO6FAAA4EcIYz7gNqZx5X2GKAEAwH4IYz6QX1KtmroGLg4OAAAOQBjzgazcxsn7LGsBAAD2Rxjzgew8h6Iiw9QuJc7qUgAAgJ8hjPlAdp5D3domyG63WV0KAADwM4QxL3M2uLU9v5LFXgEAwEERxrxsR0GlXG5DGAMAAAdFGPOy7D0r73dnWQsAAHAQhDEvy8p1KCkuUq0SoqwuBQAA+CHCmJdl5znUrV2ibDYm7wMAgAMRxryoutap3SXVrLwPAAAOiTDmRdm7KySx2CsAADg0wpgXZe9Zeb8rl0ECAACHQBjzouw8h9JbxyouOsLqUgAAgJ8ijHmJMUZZuQ51p1cMAAAcBmHMS0or6lReVc9irwAA4LAIY16yd7FXzqQEAACHQxjzkqw8h8LsNnVOY5gSAAAcGmHMS7JzHeqcHq+IcL7FAADg0EgKXuB2G23bXcF8MQAA0CzCmBfklVSrtt5FGAMAAM0ijHnB3sVeuzN5HwAANIMw5gXZeQ7FRIUpvXWs1aUAAAA/Rxjzgqw8h7q2TZTdZrO6FAAA4OcIYy3M2eDSzoJKhigBAMARIYy1sO35lXK5DZP3AQDAESGMtbCsvSvvE8YAAMARIIy1sOw8h1olRKlVQpTVpQAAgABAGGth2bkOesUAAMARI4y1oMoap/JLa9StHdejBAAAR4Yw1oK27d6z2Cs9YwAA4AgRxlpQdq5DNkld2hLGAADAkSGMtaCsXIfapsQqNjrc6lIAAECAIIy1EGOMsvMcDFECAICjQhhrIcWOWjmqnerGyvsAAOAoEMZaSHZehSQWewUAAEeHMNZCsnMdCg+zqVNavNWlAACAAEIYayFZeQ51Tk9QeBjfUgAAcORIDi3A5XZr225W3gcAAEfPq2Fs0aJFOuecczRu3DjNnz//gP1ZWVm68sorNWXKFF177bUqLy/3Zjlek1dUrXqnmzMpAQDAUfNaGMvPz9fTTz+tN998Ux9++KHeeecdbdmyxbPfGKObbrpJ119/vT766CP169dP8+bN81Y5XpWV17jyPmdSAgCAo+W1MLZixQqNGDFCycnJio2N1YQJE7RkyRLP/g0bNig2Nlann366JOm3v/2tLr/8cm+V41XZeQ7FRoUrrVWM1aUAAIAA47Wl4gsKCpSamuq5n5aWpnXr1nnub9++XW3atNE999yjn3/+Wb1799aDDz54VO+RkuKbMxdTUw9/4e8dBVXq3aWV0tOCr2esubYHs1BuuxTa7Q/ltkuh3X7aHrqsbL/Xwpgx5oBtNpvNc7uhoUHfffed3njjDQ0cOFDPPPOMnnjiCT3xxBNH/B7FxZVyuw98n5aUmpqgwsKKQ+6vc7q0Lc+hc0Z2PuzjAlFzbQ9modx2KbTbH8ptl0K7/bQ9NNsueb/9drvtsB1IXhumTE9PV1FRked+QUGB0tLSPPdTU1PVpUsXDRw4UJI0adKkJj1ngWJ7foXcxnAmJQAAOCZeC2OjRo3SypUrVVJSopqaGi1dutQzP0yShg4dqpKSEm3cuFGS9Pnnn2vAgAHeKsdrsnP3TN4njAEAgGPgtWHK9PR0zZgxQ9OnT5fT6dRFF12kQYMG6frrr9dtt92mgQMH6u9//7seeOAB1dTUqG3btpozZ463yvGarDyHWidGKTk+yupSAABAAPJaGJOkyZMna/LkyU22vfTSS57bgwcP1oIFC7xZgtdl57HYKwAAOHaswH8cKqrrVVhWy2KvAADgmBHGjkN2XuOZF/SMAQCAY0UYOw7ZeQ7ZbFLXdqG9NgsAADh2hLHjkJ3nUPs2cYqO9OrUOwAAEMQIY8fIGKOsXCbvAwCA40MYO0ZF5bWqrHEyeR8AABwXwtgxys5jsVcAAHD8CGPHKCvXoYhwuzqkxlldCgAACGCEsWOUnedQl/QEhYfxLQQAAMeOJHEMXG63cnZXMEQJAACOG2HsGOwqrFJ9g1vd2rO+GAAAOD6EsWOwd/I+Z1ICAIDjRRg7Btl5DsVFhys1OcbqUgAAQIAjjB2DrNwKdWufKJvNZnUpAAAgwBHGjlJdvUu7iioZogQAAC2CMHaUtu12yBgWewUAAC2DMHaUsvMqJBHGAABAyyCMHaWsPIfaJEUrMS7S6lIAAEAQIIwdpexcB71iAACgxRDGjkJ5Vb2KHbWEMQAA0GIIY0fBs9hre8IYAABoGYSxo5Cd65DNJnVJ5zJIAACgZRDGjkJ2nkMd2sQrKjLM6lIAAECQIIwdIWOMsvMc6s7FwQEAQAsijB2hgrIaVdU2MHkfAAC0KMLYEcrObZy8TxgDAAAtiTB2hLLyHIoMt6tDapzVpQAAgCBCGDtC2XkOdWmboDA73zIAANBySBZHoMHlVs7uSoYoAQBAiyOMHYFdhVVqcLlZ7BUAALQ4wtgRyMpj8j4AAPAOwtgRyM51KD4mQm2Soq0uBQAABBnC2BFoXOw1UTabzepSAABAkCGMNaO61qncoiqGKAEAgFcQxpqxdWe5jJgvBgAAvIMw1ozM7aWSpG7tuCYlAABoeYSxZmTuKFVacowSYiOtLgUAAAQhwlgzMreXqRvriwEAAC8hjB1GWWWdispqmC8GAAC8hjB2GNl7FnvtThgDAABeQhg7jOw8h+x2mzqnx1tdCgAACFKEscPIznWoa7tERUaEWV0KAAAIUoSxQ3Abo+y8CvXu3MrqUgAAQBAjjB1CbZ1LNXUNGtCttdWlAACAIEYYO4TY6HDNvu4UjT6xo9WlAACAIEYYO4wObeK4ODgAAPAqwhgAAICFCGMAAAAWIowBAABYiDAGAABgIcIYAACAhQhjAAAAFiKMAQAAWIgwBgAAYCHCGAAAgIUIYwAAABYijAEAAFiIMAYAAGAhwhgAAICFCGMAAAAWIowBAABYiDAGAABgIcIYAACAhQhjAAAAFiKMAQAAWIgwBgAAYCHCGAAAgIXCrS7geNjttqB6H39E20NXKLc/lNsuhXb7aXvo8mb7m3ttmzHGeO3dAQAAcFgMUwIAAFiIMAYAAGAhwhgAAICFCGMAAAAWIowBAABYiDAGAABgIcIYAACAhQhjAAAAFiKMAQAAWIgwJmnRokU655xzNG7cOM2fP/+A/RkZGbrwwgs1YcIE3X///WpoaLCgSu+ZO3euzj33XJ177rmaM2fOQfePGTNGU6dO1dSpUw/6PQpU06dP17nnnutp29q1a5vsX7FihSZPnqzx48fr6aeftqhK73jvvfc87Z46dapOOukkzZ49u8ljgvHYV1ZWatKkSdq5c6ekIzvGubm5uvzyy3X22WfrpptuUlVVlS9LbjH7t/2dd97RpEmTNHnyZN17772qr68/4DkffPCBTjvtNM/PQCD/Huzf/nvvvVfjx4/3tO3TTz894DnB8vd/37Z/+eWXTX73R4wYoRtvvPGA5wTDsT/Y55tf/s6bELd7924zZswYU1paaqqqqszkyZPN5s2bmzzm3HPPNWvWrDHGGHPvvfea+fPnW1Cpdyxfvtxceumlpq6uztTX15vp06ebpUuXNnnMjTfeaFavXm1Rhd7jdrvNqaeeapxO50H319TUmNGjR5vt27cbp9NprrnmGvPFF1/4uErfyMzMNOPGjTPFxcVNtgfbsf/xxx/NpEmTzIABA8yOHTuO+BjfcMMNZvHixcYYY+bOnWvmzJnj69KP2/5tz8rKMuPGjTMVFRXG7Xabu+++27z66qsHPG/27Nlm0aJFvi+4he3ffmOMmTRpksnPzz/s84Lh7//B2r5XQUGBGTt2rMnOzj7geYF+7A/2+bZo0SK//J0P+Z6xFStWaMSIEUpOTlZsbKwmTJigJUuWePbv2rVLtbW1GjJkiCTpggsuaLI/0KWmpmrmzJmKjIxURESEevToodzc3CaP+emnn/TSSy9p8uTJmj17turq6iyqtmVlZWXJZrPp+uuv15QpU/TGG2802b9u3Tp16dJFnTp1Unh4uCZPnhxUx35fs2bN0owZM9S6desm24Pt2L/77rt66KGHlJaWJunIjrHT6dSqVas0YcIESYH7N2D/tkdGRmrWrFmKj4+XzWZT7969D/jdl6T169frgw8+0JQpU3TXXXepvLzc16W3iP3bX11drdzcXD344IOaPHmy/va3v8ntdjd5TrD8/d+/7fuaM2eOpk2bpq5dux6wL9CP/cE+37Zt2+aXv/MhH8YKCgqUmprquZ+Wlqb8/PxD7k9NTW2yP9D16tXL84dm27Zt+ve//63Ro0d79ldVValfv36655579P7778vhcOj555+3qNqW5XA4NHLkSP3973/Xa6+9prffflvLly/37G/uZyNYrFixQrW1tZo4cWKT7cF47B977DENGzbMc/9IjnFpaani4+MVHh4uKXD/Buzf9g4dOmjUqFGSpJKSEs2fP19jx4494Hmpqam69dZb9eGHH6pdu3YHDGUHiv3bX1xcrBEjRujxxx/Xu+++q++//14LFixo8pxg+fu/f9v32rZtm7777jtNnz79oM8L9GN/sM83m83ml7/zIR/GjDEHbLPZbEe8P1hs3rxZ11xzje65554m/0OKi4vTSy+9pC5duig8PFzXXHONvvzyS+sKbUFDhw7VnDlzFBsbq9atW+uiiy5q0rZQOfZvv/22fvOb3xywPZiP/V5HcoyD/ecgPz9fV111lS688EKdcsopB+z/+9//rsGDB8tms+m6667T//73PwuqbHmdOnXS3//+d6WkpCgmJkZXXnnlAT/fwX7s33nnHf36179WZGTkQfcHy7Hf9/Otc+fOB+z3h9/5kA9j6enpKioq8twvKCho0pW7//7CwsKDdvUGsh9++EFXX3217rzzTp1//vlN9uXm5jb536IxxvO/hUD3/fffa+XKlZ77+7etuZ+NYFBfX69Vq1bpzDPPPGBfMB/7vY7kGLdu3VqVlZVyuVySgutvwNatW3XZZZfp/PPP180333zA/oqKCr322mue+8H0M7Bp0yZ98sknnvsHa1uw//1ftmyZzjnnnIPuC5Zjv//nm7/+zod8GBs1apRWrlypkpIS1dTUaOnSpTr99NM9+zt06KCoqCj98MMPkhrPLtl3f6DLy8vTzTffrKeeekrnnnvuAfujo6P15z//WTt27JAxRvPnz9e4ceMsqLTlVVRUaM6cOaqrq1NlZaXef//9Jm0bPHiwsrOzlZOTI5fLpcWLFwfVsZcaP5C6du2q2NjYA/YF87Hf60iOcUREhIYNG6Z///vfkoLnb0BlZaWuvfZa/f73v9c111xz0MfExsbq5Zdf9pxl/MYbbwTNz4AxRo8//rjKy8vldDr1zjvvHNC2YP77X1JSotraWnXq1Omg+4Ph2B/s881vf+e9enpAgPjoo4/Mueeea8aPH2/mzZtnjDHmuuuuM+vWrTPGGJORkWEuvPBCc/bZZ5s77rjD1NXVWVlui3rkkUfMkCFDzJQpUzxfb775ZpP2L1myxPP9mTlzZlC1/+mnnzZnn322GT9+vHnttdeMMcZMmTLF7N692xhjzIoVK8zkyZPN+PHjzWOPPWbcbreV5ba4jz/+2Nx+++1NtoXCsR8zZoznrLJDHeP77rvPfPbZZ8YYY3bu3GmuuOIKM3HiRHPNNdeYsrIyy2o/Xnvb/uqrr5oBAwY0+d1/5plnjDFN275q1Spz3nnnmbPPPtv89re/NQ6Hw8ryj9u+x/6NN94wEydONOPGjTN//vOfPY8J1r//+7Z97dq15uKLLz7gMcF07A/1+eaPv/M2Yw4yOAoAAACfCPlhSgAAACsRxgAAACxEGAMAALAQYQwAAMBChDEAAAALEcYA4Ai89957mj9/viTprbfe0rx58yyuCECwCLzldAHAAj/88IN69eolSbrsssssrgZAMCGMAfBL8+bN04IFCxQXF6dhw4Zp2bJlWrJkiZ566imtWrVKLpdL/fv31wMPPKD4+HideeaZOv/887Vy5Url5eVp4sSJuvvuuyVJn3/+uV544QU5nU5FR0frnnvu0dChQ/Xcc8/pxx9/VEFBgfr06aOZM2fqj3/8o4qLi1VYWKgOHTromWee0erVq/X5559r+fLlio6OVklJiUpLS/XHP/5Rmzdv1uzZs1VWViabzaZrrrlG5513nr799ls9/fTT6tSpkzZv3qz6+nr98Y9/1IgRI/T999/riSeekNvtliTdeOONmjBhgpXfbgAWYpgSgN/56quvtHDhQi1YsEALFy5UVVWVpMaAFhYWpoULF+qjjz5SWlqannrqKc/zqqur9eabb+rtt9/WG2+8oR07dmjbtm16+umnNW/ePH3wwQd65JFHdOutt6q6ulqStGvXLr3//vt66qmn9PHHH2vIkCF65513tGzZMkVHR+vDDz/UuHHjdOaZZ+rqq6/W5Zdf7nm/hoYG3XTTTbryyiu1aNEivfTSS/rrX/+qNWvWSJLWrVuna665Rh988IEuuugizZ07V5L03HPP6Te/+Y0WLlyoxx9/XN98842vvrUA/BA9YwD8zpdffqmzzz5biYmJkqTLL79c33zzjb744gtVVFRoxYoVkiSn06mUlBTP88aOHSup8QLPKSkpKi8v19q1a1VQUKCrr77a8zibzabt27dLkoYMGeK5APJVV12l77//Xq+++qq2bdumzZs3a/DgwYesc9u2baqrq9P48eM97zt+/Hh99dVXOuWUU9S+fXv169dPktS/f3+9//77kqSJEydq9uzZ+vzzzzVq1CjdcccdLfFtAxCgCGMA/E54eLj2vVJbWFiYJMntduu+++7T6NGjJUlVVVWqq6vzPC4qKspz22azyRgjt9utkSNH6plnnvHsy8vLU1pamj799NMmF0n/85//rHXr1unCCy/UKaecooaGBh3uinF7hxn3ZYxRQ0ODpMaLre9fjyRNmzZNY8aM0fLly/XVV19p7ty5+uijj5SQkHBE3x8AwYVhSgB+Z/To0Vq6dKkqKiokSQsWLJAknXbaaZo/f77q6+vldrv14IMP6q9//ethX2vEiBFavny5tm7dKqmx123KlClNQtxeX3/9ta666iqdd955SklJ0YoVK+RyuSQ1BsK9IWuvbt26KSIiQkuXLpUk5efn65NPPtGoUaMOW9O0adOUkZGhCy64QI888ogcDofKy8uP4DsDIBjRMwbA74wcOVKXXHKJLr30UkVHR6tXr16KiYnR7373Oz355JM6//zz5XK51K9fP82cOfOwr9WrVy/Nnj1bd9xxh4wxCg8P1wsvvNCkR2yvm2++WXPmzNHzzz+vsLAwnXjiiZ7hzNNPP12PPPJIk8dHRETo+eef16OPPqrnnntOLpdLN998s0aMGKFvv/32kDXdddddevzxx/XMM8/IbrfrlltuUceOHY/hOwUgGNjM4frgAcAC69ev15o1azR9+nRJ0quvvqq1a9c2GWoEgGBBGAPgdyorK3XfffcpKytLNptN7dq10yOPPKL09HSrSwOAFkcYAwAAsBAT+AEAACxEGAMAALAQYQwAAMBChDEAAAALEcYAAAAsRBgDAACw0P8HKEb86Xv8I/IAAAAASUVORK5CYII=\n" + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot = plot_fitness_evolution(evolved_estimator, metric=\"fitness\")\n", + "plt.show()\n" + ], + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n" + } + } + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.6" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/docs/release_notes.rst b/docs/release_notes.rst index fccae5c..1ed4c8a 100644 --- a/docs/release_notes.rst +++ b/docs/release_notes.rst @@ -3,6 +3,30 @@ Release Notes Some notes on new features in various releases + +What's new in 0.7.0dev0 +----------------------- + +This is the current in-development version, these features are not yet +available via PyPI + +^^^^^^^^^ +Features: +^^^^^^^^^ + +* :class:`~sklearn_genetic.GAFeatureSelectionCV` for feature selection along + with any scikit-learn classifier or regressor. It optimizes the cv-score + while minimizing the number of features to select. + This class is compatible with the mlflow and tensorboard integration, + the Callbacks and the ``plot_fitness_evolution`` function. + +^^^^^^^^^^^^ +API Changes: +^^^^^^^^^^^^ + +* The module :mod:`~sklearn_genetic.mlflow` was renamed to :class:`~sklearn_genetic.mlflow_log` + to avoid unexpected errors on name resolutions + What's new in 0.6.1 ------------------- diff --git a/docs/tutorials/basic_usage.rst b/docs/tutorials/basic_usage.rst index ad51370..a6adfbe 100644 --- a/docs/tutorials/basic_usage.rst +++ b/docs/tutorials/basic_usage.rst @@ -6,7 +6,8 @@ How to Use Sklearn-genetic-opt Introduction ------------ -Sklearn-genetic-opt uses evolutionary algorithms to fine-tune scikit-learn machine learning algorithms. +Sklearn-genetic-opt uses evolutionary algorithms to fine-tune scikit-learn machine learning algorithms +and perform feature selection. It is designed to accept a `scikit-learn `__ regression or classification model (or a pipeline containing on of those). @@ -23,8 +24,8 @@ Then by using evolutionary operators as the mating, mutation, selection and eval it generates new candidates looking to improve the cross-validation score in each generation. It'll continue with this process until a number of generations is reached or until a callback criterion is met. -Example -------- +Fine-tuning Example +------------------- First let's import some dataset and other scikit-learn standard modules, we'll use the `digits dataset `__. @@ -165,10 +166,109 @@ sklearn-genetic-opt comes with a plot function to analyze this log: .. image:: ../images/basic_usage_plot_space_4.png -What this plot shows us, is the distributione of the sampled values for each hyperparameter. +What this plot shows us, is the distribution of the sampled values for each hyperparameter. We can see for example in the *'min_weight_fraction_leaf'* that the algorithm mostly sampled values below 0.15. You can also check every single combination of variables and the contour plot that represents the sampled values. + +Feature Selection Example +------------------------- + +For this example, we are going to use the well-known Iris dataset, it's a classification problem with four features. +We are also going to simulate some random noise to represent non-important features: + +.. code:: python3 + + import matplotlib.pyplot as plt + from sklearn_genetic import GAFeatureSelectionCV + from sklearn_genetic.plots import plot_fitness_evolution + from sklearn.model_selection import train_test_split, StratifiedKFold + from sklearn.svm import SVC + from sklearn.datasets import load_iris + from sklearn.metrics import accuracy_score + import numpy as np + + data = load_iris() + X, y = data["data"], data["target"] + + noise = np.random.uniform(0, 10, size=(X.shape[0], 10)) + + X = np.hstack((X, noise)) + + X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=0) + +This should give us 10 extra noisy features with our train and test set. + +Now we can create the GAFeatureSelectionCV object, it's very similar to the GASearchCV and they share +most of the parameters, the main difference is GAFeatureSelectionCV doesn't run hyperparameters optimization +thus the param_grid parameter it's not available, and the estimator should be defined with its hyperparameters. + +The way the feature selection is performed is by creating models with a subsample of features +and evaluate its cv-score, the way the subsets are created is by using the available evolutionary algorithms. +It also tries to minimize the number of selected features, so it's a multi-objective optimization. + +Let's create the feature selection object, the estimator we're going to use is a SVM: + +.. code:: python3 + + clf = SVC(gamma='auto') + + evolved_estimator = GAFeatureSelectionCV( + estimator=clf, + cv=3, + scoring="accuracy", + population_size=30, + generations=20, + n_jobs=-1, + verbose=True, + keep_top_k=2, + elitism=True, + ) + +We are ready to run the optimization routine: + +.. code:: python3 + + # Train and select the features + evolved_estimator.fit(X_train, y_train) + +During the training, the same log format is displayed as before: + +.. image:: ../images/basic_usage_train_log_5.png + +After fitting the model, we have some extra methods to use the model right away. It will use by default the best set of +features it found, remember as the algorithm used only a subset, you have to select them from the +``X_test array``, this is done like this: + +.. code:: python3 + + features = evolved_estimator.best_features_ + + # Predict only with the subset of selected features + y_predict_ga = evolved_estimator.predict(X_test[:, features]) + accuracy = accuracy_score(y_test, y_predict_ga) + +.. image:: ../images/basic_usage_accuracy_6.png + +In this case, we got an accuracy score in the test set of 0.98. + +Notice that the ``best_features_`` is a vector of bool values, each +position represents the index of the feature (column) and the value indicates +if that features was selected (True) or not (False) by the algorithm. +In this example, the algorithm, discarded all the noisy random variables we created +and selected the original variables. + +We can also plot the fitness evolution: + +.. code:: python3 + + from sklearn_genetic.plots import plot_fitness_evolution + plot_fitness_evolution(evolved_estimator) + plt.show() + +.. image:: ../images/basic_usage_fitness_plot_7.png + This concludes our introduction to the basic sklearn-genetic-opt usage. -Further tutorials will cover the GASearchCV parameters, callbacks, -different optimization algorithms and more advanced use cases. \ No newline at end of file +Further tutorials will cover the GASearchCV and GAFeatureSelectionCV parameters, callbacks, +different optimization algorithms and more advanced use cases. + diff --git a/sklearn_genetic/_version.py b/sklearn_genetic/_version.py index 43c4ab0..8531016 100644 --- a/sklearn_genetic/_version.py +++ b/sklearn_genetic/_version.py @@ -1 +1 @@ -__version__ = "0.6.1" +__version__ = "0.7.0dev0" diff --git a/sklearn_genetic/plots.py b/sklearn_genetic/plots.py index 1b47113..ba4b4fa 100644 --- a/sklearn_genetic/plots.py +++ b/sklearn_genetic/plots.py @@ -15,6 +15,7 @@ from .utils import logbook_to_pandas from .parameters import Metrics from .space import Categorical +from .genetic_search import GAFeatureSelectionCV """ This module contains some useful function to explore the results of the optimization routines @@ -75,6 +76,10 @@ def plot_search_space(estimator, height=2, s=25, features: list = None): Pair plot of the used hyperparameters during the search """ + + if isinstance(estimator, GAFeatureSelectionCV): + raise TypeError("Estimator must be a GASearchCV instance, not a GAFeatureSelectionCV instance") + sns.set_style("white") df = logbook_to_pandas(estimator.logbook) @@ -131,6 +136,9 @@ def plot_parallel_coordinates(estimator, features: list = None): """ + if isinstance(estimator, GAFeatureSelectionCV): + raise TypeError("Estimator must be a GASearchCV instance, not a GAFeatureSelectionCV instance") + df = logbook_to_pandas(estimator.logbook) param_grid = estimator.space.param_grid score = df["score"] diff --git a/sklearn_genetic/tests/test_plots.py b/sklearn_genetic/tests/test_plots.py index 1399c1c..7fe8af6 100644 --- a/sklearn_genetic/tests/test_plots.py +++ b/sklearn_genetic/tests/test_plots.py @@ -3,11 +3,10 @@ from sklearn.model_selection import train_test_split from sklearn.tree import DecisionTreeRegressor -from .. import GASearchCV +from .. import GASearchCV, GAFeatureSelectionCV from ..plots import plot_fitness_evolution, plot_search_space, plot_parallel_coordinates from ..space import Integer, Categorical, Continuous - data = load_boston() y = data["target"] @@ -49,9 +48,9 @@ def test_plot_evolution(): plot = plot_fitness_evolution(evolved_estimator, metric="accuracy") assert ( - str(excinfo.value) - == "metric must be one of ['fitness', 'fitness_std', 'fitness_max', 'fitness_min'], " - "but got accuracy instead" + str(excinfo.value) + == "metric must be one of ['fitness', 'fitness_std', 'fitness_max', 'fitness_min'], " + "but got accuracy instead" ) @@ -68,3 +67,35 @@ def test_plot_parallel(): plot = plot_parallel_coordinates( evolved_estimator, features=["ccp_alpha", "criterion"] ) + + +def test_wrong_estimator_space(): + estimator = GAFeatureSelectionCV( + clf, + cv=3, + scoring="accuracy", + population_size=6 + ) + with pytest.raises(Exception) as excinfo: + plot = plot_search_space(estimator) + + assert ( + str(excinfo.value) + == "Estimator must be a GASearchCV instance, not a GAFeatureSelectionCV instance" + ) + + +def test_wrong_estimator_parallel(): + estimator = GAFeatureSelectionCV( + clf, + cv=3, + scoring="accuracy", + population_size=6 + ) + with pytest.raises(Exception) as excinfo: + plot = plot_parallel_coordinates(estimator) + + assert ( + str(excinfo.value) + == "Estimator must be a GASearchCV instance, not a GAFeatureSelectionCV instance" + )