From 0c9e527174d3acac8308c8dccd40c5c2c4b8f9a0 Mon Sep 17 00:00:00 2001 From: Roope Astala Date: Tue, 8 Jan 2019 12:23:15 -0500 Subject: [PATCH] databricks update --- .../Databricks_AMLSDK_1-4_6.dbc | Bin 45504 -> 45976 bytes how-to-use-azureml/azure-databricks/README.md | 21 +- .../automl/automl-databricks-local-01.ipynb | 88 +-- ...oml-databricks-local-with-deployment.ipynb | 704 ++++++++++++++++++ 4 files changed, 742 insertions(+), 71 deletions(-) create mode 100644 how-to-use-azureml/azure-databricks/automl/automl-databricks-local-with-deployment.ipynb diff --git a/how-to-use-azureml/azure-databricks/Databricks_AMLSDK_1-4_6.dbc b/how-to-use-azureml/azure-databricks/Databricks_AMLSDK_1-4_6.dbc index d4a93019d7f1c3047d88e691e2220b26fb56a8f2..74d805376ac8a418130ca70a8a732888d3f05dcb 100644 GIT binary patch literal 45976 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 literal 45504 zcmV(*K;FMlO9KQH00;;O04KSHO#lD@000000000002=@V07PMQVPbM=V{3C?K}}3k zL`z?HZ*psMXm4;Y{>lIV?Y#?^+qjVi`d7H^lWn!rkO>e3L7zDHI`$;-?mT?PGnw7v z_L1@IW-N({D7oF4o&SET08*sXZO^ov-BE7jnPZD2UIbAestWb^@#MW*HdQ@8d3^H6 zdTQPBFZAU6q+V8+FYL)IKxkTvt%{1b&&TYHF7bT7UiHpr^0vmD6?o?&E!xJm2({X5&Asp`FRBwr)CE zuIGQQnpM5Lfyz@gzg(+JEVj5=T|w*6X+4{%xovhjeHL$js!y>QyB9^4TFZ&gOhI^N zQX;()q@blJZK`CdCA8D5_3CDUy|(%v2? z{TuzIo5~bke5F?SdTzO_mrw+nTu)ap<@5D)dLD1TT0=GXO2d2I1+Er9t*`MTy$Q`N zSKn3mxzjMKv#PzMInN53R|ZSm0ex+U+c=@MD^Dnp4HR!Y`%HDo1N=L z^}b%+b?@or<Zi3gX| z|2ylJ&KUYW85Tiek!4y6#%P|Wv?%%&{9U!e(ILG909-%Yy4#NVsN1=@A7}Iq$oRL{DS!Ix#ha0@rmlGu7IX8cngJfN@qfJh)7in$E*IsIc8|2X zKkXXJa>G(XN|rLhy>dhso)YS_%w}3~=j8oqS8ixGFFof{Fv7e|VZRpzk%g4RF_(EO z1lKa%k9PBMu}ithgRhX2Ndi{`3;tlpRAfgoJ(B5Xkf|*^x87J%WWo~8%96+&2{y}e zQWjI7(#!MY)e8E)d;u)_2fX}?GavvxZ5lU&WxKrHnwhGmseEMuVRVgt zSzm(WRGDub&`g6L;C4;-UQO3qwf<1e0b`zRwfIFWRo~I|YCVUcc9oyOYH$9crj^Cg z=Rtaz{b^a*0Df+HFxV&QQM@=}-)CT7F05gOOCpR1Y|?;&!1$-cn?h>CZK*W9H}>V} z2K%IfCPV?)rzy0rj3lbe9myi-YESV3u&+#abP_H3DpW-vp43Z+DEAevSA(%f3hxhAx5(7pifO7UEfQkc?PZne$!Jc|LS%eJMy2e8TmimjHang?XV&zH25 z0m5K-Fv07|LanZV#xG8uTA1NyZr-e$7a+00Oktsm6DSRpf3`4`!Ln`JP$u+nf8trs@7MuP^*{x2`u;q>|3(Y)EM)3KPAAdT#I2rqTIa6)>uw>Uz?Cd<5y7}f- zAjz|{vq3A+!JUo3{hc=AoxX|oCC8zuSFmf$)aY>Vk&EJpkB5wphb{zqS_0_N446Fw zycv_6l*}6mH65^ZV~;Z|>Afkd{82zjHSUuq%;{$xV<=e zb9PsyW~>$qH@Bny)}UPfYc*SZvIz|CK|alO2JWNXtrV&iO_K2nS7(O=bj^$73BBC-6V+4NESDv!1l z|KqFGY&z@(Mm2RW=I>Fz{y6H^6Z|wlddaFz;&b>wp+I0_lhGQG!OfHK@tXt+fBpTJ zUnZ!}hwnBXOxJ@JloG(0j3wDQ;(Dl}>?{1-N&FU!Z46rhugtY*#)?UW-a-M8W^AlLXFclXkXM@GE zA(*a%t>c@%gRaHCkHL~{+k>}pchbhDaTw-VRK{*CQCyD^4&rizIf6Byx+_$WSeTqp z1Sbb3r9+R8%tv@U9PMeibK3T<+ViK-b4#P$c-vkZ{FZl(qAk|oK)QC8Fp`~^g^vIwb8I=7Q6mEFVe3}sl914NojFgTE;%w=1S$Iv|9!izGH*mG7 zR-7}EmJ}EuURnZ=4JnwQLef0t&g{#e&>cDAmhyMJTyIX7zg^#@9v-_73%9IrNp%Ik z*xb4M2>$kgeRH*5Ra3;OXgQ47v#Wv`m=lj@vw(}Su+<)!of=prwYrMT!o|rWyp88s zeTx8w(8lB{Hqv!+8g_Cro086W_q2m-h39Hf!Gyd6&V{~7EXrAUjoanmRcAMYsdzG& zh0%3`jLVD5d9`wrr!OYosp&hwKp0M4ukgK~_^|dkbUm5YmzU7bs0HzF-Q{|!met?m zng6%ARucj{HDE#D_R?{hru00)f8#&lZ~7+IUoGJaz|K53S4r(r<34N-dBV7zceV#f zZ+s9ZF*1`-56fYv?dI1ho4&o>;^XAUpL(qm)amxl2Z;fSgDwXn3O49C%S|j3IF@dT z#^EXcf}Wru;0u%A;`9uL{VO%HQ-{qeUN_f@92uiZAiz#am}_5{1Si(h?^ zAZN6yVMDlTO|uuR5lLSN??C&Vb;$@m@}+B@ynfj6Jm<;74SRB)besP9X7^s6!wBDm z)zEhwHIdk3`;EFsaoyw526jC5RV!e8xmeEpOzub&J@IYI4P6uOE>&db<&?2-u29*CQj0{13bPA(W-=l^7x8FQFJ?pG& z+z97kyNSi}=bCu=?Hw%)r#2GKQz+kB^+TuIG!ut9WMQ{zg>I6U-`=VOgX=2|zYU-Y z67P9C3FqCLpxo54gb0m+Aw+Cy@v?6NsS#RsP`WuhVk_hAb4~(u3PfXuW{H5wuk!n3Mm)r0mwm#zoQ&8 zkdnfFIYyeDAh%ZG8(<%&Q1G}Ncv+h7-eSw3Ko-$xskJ8g2OHbczvj;6t)f2#h zpI9@^aw{@4&=ZnyQFtP?R3K|f5UkRSirn2_xaz$JHKW3++>%^ohH#THq8+CsD?BZ% zFH0)+7Ot}VmjB>`FL4i1=->yRpyP)Ef(=2bRR^_<3y^D4>%Tg)0)}YA1tZ4~TmHOd z%EM;eAp}s?q;u#TbsFBj=IbS3$Q#6*gTWE_3`ZO}WE=?#_n!whG|wEB){=}WpljzG zkz7e4m6e$;l@d(fA2)grLY66OO(95OvYhbLJEFB<#Fn-wEYmhk_cZZE+~B-qyQ-NE zES_wWd3zf~RI`RRdGDTl2Oj~r3yr2F8}4GJK8)I;=LsGKJxQi&rmafeJ??Pm^}9E( zPa~s#`ex7qlpSElpxrkcOTRy$g-hU7n#aI?4$Ab_fKfmS&$|wXZS`G$>^Tq{jO$<^ zD-%aIgoB1Gw9wP-!aQ)e0&a#`uO%^Mnh|bOPP9pZ&5?x=UgR`0_jh>Cd#6dCXV#~M zB&93S8%qLQxjZAZ%u{WBVQ9AZA$KP3vO<1dU(YuJ^FUAwYMu@)0+%xs-CEFz(iIAq zy(YMS&s)_T|mzl{q! zEb9Y@o!mN+QErH%tN>Uja-uWIiS$;dnN&0{%lpGl?*!@{7habcDROi&R#Kv% z&onhYr*co}su+LFRr`yLSLDGEuqcnt+6PU*hkwK@@`3@K3U56gF?&*igg_`4QiH4^ zy}rK;r zlOTwW&XUHtSrZhs?r-aAiF#kPItvFB0cI;ygj9ZW;#)Og;~(ml>*e67t(L=wtv=)v z`rh`@dcIKR-A2KF7niW3YVVGu7ZV+A{t!=pxaH*9xp$}Mr|Qzd-$1n0N=+w7trKM49cRa0tYDe`=FMNpJ8PUPiIG2L(VGJcaWhp6*)r1!SO4gRlF|i+Hl)I4e4>Nc92bsBi zhIz~9n6=!`oaG*7EC&O6S#gx)j-dBBpl4IT1rx-V1wavqT|}2!5R(A|W2|*t++Wcv z2407ymQ#lt{B8RhjYkH$D-)>!CG5<;E6-`xGP37(>d!X;LVW z$$}bSQ}#TSL1NuiynOx5cV9ei?bp%$YM_IunqV{;jN>{j3pxnlflaWZf0R^npl)S@ znfA5)w{1noFEp#{cKq1aM*TC~@dw(J!`byEJI0(k0?FrSM_5X8Q3xUn54*C=JyBF< z#CWQ;OH*a(9->a~B9t0!OC>d73Vozg&WRM6MtR5PmZpaBJ+&j0jrmUCmESa1$m~y> zgiKWn4;J1#;?7&Y`MahaZR~ezHb%bXu zBP!*N2t&(K0mE;L`$rTJy{&4_wB_EEL^F?(wW%XA%NT+2XK7yKoQeIZd^fz3)p!Kb zj60vWvHK8w6`C~&5zQfa@a8N%ZqElz*N476J5d@gr6WLXKv<<^q+}T-l;(xvKwLtz z`x9<&EGjgJ3MGj8QkBp?)gH|t1ks!-4m>_H<(|f(G`mH(zcN`K-9i4>NbwfkwS)cV zA~uDwP)#Zc6AX4qS)f|J%m~+|&qc`#fRdA+aB={7bgh=Qo0~42D(3|)K~z>ymD{2K zIue`!qnlF&1Pk2t$?ci^$cyYQzHKW1`RrG+V14#0F@6eb@vAQxpv9AX&w1Z^{!fxsZ-1OX_LIR z)n&B_-~48TarrPT-=I_o%hv>gdent^eiS0Ag>ZWhYFO?mNg7!HXgoe#|MSB zt}EbZ!ru0$&h6vXI>soZwSooWNJvn6GzF=oF;HCU;L^HdhnFz2%D z{##bBwdT3bWSSMkYvDTAL+ePMrB-LTb0*z04t93OmKCC;p&`ohHmtq^c@hN1CfVc# zdAY3LSHbOYBae>TYF({OrC`)Icg_YV&@p346D;~dw3!HP!(=3YR&`ej;AI8S|0;x( z!-5g_&?ZnJbiINV2_PL128H0J>lUFO%FmNw`jfuGZlA$bBJMnDjuFXlCxhb8rU0(E zNpIeL(Y|}rJ;bIqlLs*P4&L@dXyRul=U}i<@*@L(#KQfp^SmlG;1S6R$q@?+Ji*I} zE?lX2RvPBb{jsnZoYVV^8ASUL;?G zxPtkq{~v^ir-Sm>oASeky2OZ4h^UvBY7S#*vqskS5~wi5oDR7oP0Tn^`vhL%CaFW< ztQMh#>zySjS@&U;lO3aB{i zgB+ln@==#{6K5Y&cKDlC6&A99&!Y);*g578lcymFaF~c7m2P?)BbOMIq~@xw8&v(G zg!wQskIi6I`J@)r{s2zx^a7H zvuks(Erso1*hmZNp_u@g@kU=YULOo-34SzVK4{STei3wJ+Tr2hd*EJ!AW!9VA6H`)&VObbPd`XEYjm|P^ zohtW6vi#?eOdC;Jcrk(jcL~oqBT_0(ycAA@G^n`Bk=VcZVv8%i6UDIq*>s|;o-CTl zl``)z!sH!@q}o!}&FbwU8@xGf`L5ICfw@xiOBau!(bQmvS34BLCnmFFw)um`on-`aapzBIGzysKS)Y7RZDg9|BzK~4BGt^v z{avNEc&1wk&N^9opoRgm$3WbhJEL1bv3=vbPZH848@YvNJ9lnZxrJKWH`*j&Z6Jo* z2gA_hT>^AeSZs4q!RiNaF4_t`ivNuN+JuAW>n3`8w@>d(3ID4wP+7r_+T?#_5c^DC zDHACx4R8{<%P@3G0T9M=O#pQ$yiUebbMHKkQuemjrAafLT0t1I79f)4z^>>VV{lt^ z7R?;pGaeO9?^Gvuwt1-C3qoJC*!*JtzFOAvn6t1`<-PAtfH(FdSC~bs)j9&}67VD_ z4J$Xqi+~=82Y1>Qb~QUi+ja@`jfqOrx8p~51J2@lGh#rL7@R?AVyrKK z{4+&V3i6ooOyri9ma%(B$dt0TEwNN&J}oG*fL4SnYKbhQCr;5KXVjD?-`6|*?jz_n zJLz5NT$fO=o^38y)hsYgfwh{c)dCjZw9*}8wYb3>n80%}UEL}*ZXdUWs~LXdPv(_f zK<{t|+q2m1ok!;P&0~AJ{NN1j7K6A|I_4^j5@uI+XdnHF;=}a2vC6mWgV9*=G(W1@ zkBGRx<#CpIZ?z%Lqy9#7jk(ja}|#KgPdnO-;j{@dDz#w=`&^axY!&HGZq-@BlH}hXFuqn zOqG%YAC_lM5ME|Ep1?5zTv$o-%&Wqx`$NybD?gPWKbn%*k}3>R;EB$yB8+;MGVX-q z|ESo*FM3Ol-U=wVsYSz=+ZMoRBiO#z_zuSA7wEgj5obofP}#M=&g++{zRr`6RqQ0p ztwBcJ`$szq=a!TDU6)Ajx(SK)EUdk1+8mI+D?3_G9ySI(Ma!Bw`lPO+qNLrPH%sxL z&ki}wQ;#-}%saGxC2CEXTjcY2yHKX;G#MvY)9*Lx543#d)4{IYq)tAQriH7W!!W+PLglXD)PF* zGMn3xW9vD!J345M?lw+k8@<~QFwZ+nHrw-(SQ;=K9fA|!+GbVL1e37NvhA{Z?|?Vl z!QHpP4)Hr2U>KVRpaWjf&7-q2n!ODae(g*Jm~5i+FlrHPjgGc)7=716rgUg^I^Qz1 zYYpszM=`dA5%aMzwS9zfm)S_5t9gCLEH-g04wh%49lZ9&Mz3|$Zniz@!de(um4@Yl zdQ61<=mkDU&uZ1+P=dMZ>I%N!)`YU)da19bZjvS_@{emqc z4<&jy6Ex4hwZAz5qsqN-SzMlVe~7^ zcGBP^sc8bETLVxW4x3Mlqt5l9x46S*^KD^7S`-Blg~u$=f|4>7!0;>1tWp`J{{DH> z(xLfFX{@o9n1Vs8C`*)?hrf7XxywsQ*`9gR*bbi`{d+<%u}$jdXbwDCFQ=nBgJu6J zBrEdr7-jdMN%p&?GVkJ+G*o%dZ@Hx>2hEh+fCXioD>NFobE$d+33= zkjiI-(*p1(Wu?#ebotG8BAb}2YHDE#Bu{|Gn_V`bdpg3TT5ZlTEC!{2{OJO{x&ozF z=&uz^wh2&C%7EpA!Hu3I8>V7&b95Gqb!p6?xp$9~_W_#Tox=}kv8&aV8J&%*m7Br8 z!4awnA(iIFjozOpK>TWT_7k?a)h-V8H8MAS&#zCRm1rY!`sVBn=3b0t5dxu0TmqPB z(T*{0)E}3aoNUnA*|-59orJ((BYL)}axlPF7RSUyM_}6@*fdi)GdY13MKN(=K}sq; z@xr8DSf)*W|2zX}ub8ts$FxU|2nLwR1)j@FQ4-I6p-V3%&(xm4c2|_a2O($^P_KLM zLhPew2vdRONt9o;;eH3K>XmAeXWxAF^2;y2`{Mbyw_$_X4*IxozyWx0RmWIO-mT0P zJe@}MSZIA2T1TeGZSh1M*ab7VYllWIr~s>)fwH8YxnR7` z->K^FLrsS4gn@5()&aoVNJDR1h)7yZ>HuH{Q8yQOjv5rLz(Q?VuVRqO5YHg$Rs&BK zVFgvoH*<5ftmiezQ^|9;aDno=t^)s}+BgC8^-QBy8y&}6rl)BS3shjR+5n{2S20%S zPDIsnM5)f3|1B=E$tD#w9$>zWI%8n460=?+bzpeVHazCA$GSZ{m^U@_lXT}IgJ7B< zVb-hdfewy7+zLJ4p_xD8B5j@8n{^Cl(SD8Af&EZ$Gl!k*Q@9yb9Y@$a!sbWp*QoMZ z7nsIXfq+>UfKB9>80VrWna}k7?bpgdfsAavxSt8UsVJn?TKv!c&Yijfbi~)6#!I&;KIxMB z%NjTAiLa;DEf3}>Bp2l;x0fSZe%xO^$(HBFX%B3<=a?yp%9KcL96Hxi=RL(`cK`jQ z4{zou6H3yQ&>Zs#GRzv9!Y^5{oEJi1K(#&hm*P&gd>GaJ+m`$egjNL;$M~X0TK$ZW zK|-=jaDst+ftIp@NLhG7Rc_MEahYX%@Pd7OQIi)%L9HgbETMgm@!CC;#De&oTTL^Y z?`vtW6N_+jxBwe#FB6X=)r__{#q;F0ym>IYuSgj?QuL9c_l_8xI_^@TNvc_fN~@G; zC1Lj!3dB2`<*K-UEby{FK9nraq;McOnh;zRq(`kXPnc(!)Sl&~+%pz9yPdf&!61{c z=i)nu?H3Qu5|{*78__&4&StMnUpV(}kbWha4`MB(!bGj2F=UWWVj>r`eH~S2LGg11 zYjX70vvKmg4v*@@VdTdUp)=%B_-leWdX~1et86uM&B`q{F&DeOIi111mVPp5InKZWum@eVE&jm3HUB-x zy!94aoZz~eU=)eBo#Wzs<)+i>GAglS-l+yd#U|EGs~PG~;-MaPfMaeVY_(ag9t2DF zpnP9C?_fz9hgby?$u&BQ!(zucz~~S4ws{vbj%`2%^Jz_D_OQ_z8qCLpV3Sr2Kf!{N zWnCj5blL@M4KIgJ#u}D#>oyMLj=_!RZuKZ~Q>05!71EMDI=z^;suE}_v@qVDj?qWE z{%vylUt`m}KRp`s{_mE1ZzeH*%gHr|Grd*zdtwZa}Wn~eW`Y&;Y%?GEKdJfMq_6MR(62A*9j5WaiP53N-4xb<< z;|gI!VBKsQvN4dzuqE6tVryX}xGXN=(?eS~I}_Kv%qOSprkyf))oDGy9L1^;9AlcD zdO3nOnmsukKRi9hX+j?|_n~8X4~FOEr967%A9tMnPc#Z`OvyYk%%V-LP(ub`na~AuKH*Mbnml_;C9q1gZpclqw!ex5p#5vVLJI%vtq!H{MO%*@mEuwR=e)p*QeS2$o4l}r|(1qyIO#nPi@K2gFxZmAXbPgNI zWTt?Q07ng=`QX{7s{cdg z_nc3>Q!8YK-^AKC_o@Bne5bJhNzfLq%dcR&sYnbbutG5#K1uR)9!%y;@L~j(a9Mpw zpnG&tghhunrb@f%PO{uvlZ0$1jx9`a$HTQWu2xs@4&MeULx)m4=xa?>+S9%yp7xEq z^@y22V194MpzFO~2PQu2xebPeRkLZQV}(21kKU4Qwg~A!LYX)?_n}%v>P3nRlahqX zK3T?KH%MN@Y%NVwn=1I9Zpb47%=mwjL*XCuJUePEj{M{P>Cbt|M1l6m!aKr!$>5h| zAlDkJweo42-#-d)*@w`~jANQJL9`Ds^ni6#UUE`s=Yc&fl-0$a{Ns*gaw~y%V)Qs@ zH1mTI^iXwtB-A6J?oFslN$X8Xa+zVeLJZvP%Z#LX%Ct9JGk$+TPxht-Mi$(tv>;jL zFwv=CK(Z_&%z0;7CcJfeKSHHb z=+i9>JB9jv9LLc$h-W(k3NN}bz(9Y`c=7sl5asO@T`2F$1Uo1_jI;CNd8l#SjCTSB z_2v6ebGX#H;xPqNS7wtK>Q5Nmrz^7^x~(t$WgDukE7yf?>r1?BKhE=N8FcbDq3HI6 z_oe%J>xVcH%i>TMb__%_slyA7PFqkMNAQBdpmpl4v7Q(%b3A~~N$IsF)KX=5ZmF^NPnuo!;d3Z#2vnCI zghYwQ0otO2LqW8&C37OzWtr}|Rg`yfiC@;rM&~fp^9CE3@0;%D%Wx2VFtjVv<5Av` zcK45P3nZ8FLJ(G9bVUJTn3R+e^u^35Eej>@AK|v_!{g-ASmrq;x-^>b0)CZ6X^D5H z%r$y+iamWgsr*DjrWJf*RGZ#(QEGAf9*B9kZR3f3U>rXFY}B~99X>lW>s2oJ(R%er z{(Fj`>U}mldr|EKiljpmze$fce4| zo~LELANlhg-^4p8^8YeN;xWYX{~8tEBDr?3|EF{o`}_<_%e`|7eRC}<&`Q$-5h!a3 zrg5gi0hHT&2TuU#>8&(NnmOfx>ox|xv~&rStbkKa3!gHR(<0l`W`^ID`LH#7?6%j= z{_$cSZ6DFH?oN})V6^B$)TwwYm`=Wi_c~7=zX_IkTTkO*GCqHU8G6)ZaLsKW#_RC# zP&Q;qk10}*8}esl7i2>D%#=h>u7Dp;F`T3-NN!x}4X56FcYm1Z)vj5IVd!9+rie2{$S+BBnoz#o6CR%qK0;;jVb>w}HFjgNz@P5Njd zXxy_g5yIFZ+WC6vu23QS?=k914C2x~U)7zV2Nprgp3v^#apz(Zn$`GlhJ!hngPWo} z<|jQO$Y-$hT#JmRImw0ADA6mT8MP!cxfUt)Y0mDgjVo!djnldioTrosmK%`hSw^%K zhESI?&Va|!%2LBZxtp8oZf)=juLsh@5h)(@WIA0Y-Lod0|?9)mGaFwn)y-si9^(ox>S>o*=X4GnBh1BV z+g^)MBN))Z=u;#=8q6HQ_jCOFflbpP*e~i+JaBHB7LxcP)rBmWg*UrD`1a~lMtxT1 zRsgO`0QWS{+E`K=3KzU&*6taLgMTdMCh|{s_VLYnc^3=!gNyOSQP&zm$OUv7A~lB2 zgfEt$!D|4~m|CQ@^M(Ka3X2u3d|R)p;8cMXfD1eru1qp{Gy<9v%T3L(RW;l`uQ11fwXchyzf+!)qAnEfAPz8}f_Nap*Jxv_a}WdX!(OGUVp zIg(*UvP`kU8A%JeN4AmPvc069DP4F{SPD!)ZY)t&mZb2xqlFSWWBbP3zB5KkY?RZc1B&Q0V#> zlvBa6eK0XwV;PPkSQ9>kejbL9ig-J^9>VPyuoqK4S7tp`P;N5?4-ba%fxnK7&k+&# zMnqZ4Qc0E)<3oHTS`rXwQUaojE12h{6!%UKTBd!_a9t{4Y05~dH84JwL;Ho(Bn2?k z(q@$FJ?)6IVmIPh{cgSJBh6mG9gJMtG#4iq^ZT(yn?|-8{bysAiu|alK0?F(XI+}= ztYiw^eM-W$WJIgffnX$rHI7ni_F$I!z}UG3(MM;3z+z>D3$0>mHp*P);s0E#Jp&hI z;v>qE0fY31E*A4sU@}62-{h-E^*!sPG)CMBX_wF?8MPlP*GF;Q%0qH7e}zhsF3CX0 z^hB5mfeeuQ3Q;I#=xq)IdD{Wh+o(-`d@#t7r$@83BXaDG9NyW2G3AKQSwT1#g6LG` zq+n@TI-C0fHvOM);$SLtt(LZ%w@!?5%wWPIAsNM-;*6-w81!qT2tm@P$TaNE^6l3+ znd=zt3L3>4FK(BZs`=#_Bc4=qU*nA#Ech01FxbSS4`dN4L3Q*t!4KG7FK#Zws+mmP zhwy2u_$Uj6Y~8FvIt*+<7)-2QZR+>HiMB<<%dr>>>`=GCvL+zK)yq{}KV5YUivSN+ zZr)ZKFK)1%wjU%YGTU`cYW=_XTH?vm)hXnwJ@3_&c|pyD7R>;rLs6 zp0w@9xlCTe5Uonw{Qcv2v_E^i@b4JdFCP#xMGMGhvN- zU#-*(R?JU#;LP?8^mY42pVHT7n{lLk{M;?3_042ePo6$|@sUxt#1{v3ucLupHK4pI zOztr;PwrqhEi$5u+>qQ@Yf771m+iUR(J{++cDsxDCXxET-;Pnzef1{MH_1!2L_At1 zuddWp&==z^uxRl9uEu7lg|^B^ooxWI3k+GN_{a0>&<0Bp36S!9gBiyg{@;CEAs0 znO_z16T^Je>mhhlm@evXYjnVG?Y=fSrZ6H;fP=QxZ{1~uVUb!a!iZ0*n#1*rF109t z?^zpyIF^Z7lpiOXAe^;n##<}uk(-ls^C=o!GEz#0mhiEtg*>@EUii27e`pJIen@i2E!JK+b`A z&nPh(Q;S&4z05KV5;|qMqly)!zdytcQe&mMNNGxm7dFNGTO|S3J|~&WG}qEu?e`5b zFqXw_rs&^ZryMBs%_syEdlc4k^C(zLW#j*N`KP;7cfS(p9`l$SN%ym2z%pNYcnLh@ z1et?}taCaiOfoGLb3lvtjt^4OUay~Osw_5WL0}|YX@zI1Xcu32r8DWWeGMAeC;Uc3 zc)r%BWfQvs9Z$9blVhnaa)>kUl2B_9NTUtv*eUNXP6p2&U!0uZ8Dt~IA~`)hy_kPG zVo7Xt5LyFe&Bw`U^4l)9MxQ(FH1aw?HrRDnri+;|D7O{Zqq3W#JCQvGH8x>8LV%7< zh3&W<=fJ_CY3S+2#T@NE@%;`$2^la@9x?D=83RA}_`-VlUr~~RBn9%B69lM{5}naP z=hCI#@4>tbayeyAkwis)aZgDU7S3%@JXJb5ZK@W z=btN#$9glK&88P8$%ABAegfPX0%6^ZF|OqbrCZ$os?)DvB%&lIps%bO!&DbnP{gZAu zq1E#P3KD=oN7JL6cF;igtY5RRQlBp?fQ-0$pa0>HukM7wm~{HrM?qbb1}!{@&2tdp zOe%>g02GzTGbdHfwc0~V)%!Jb<(w)oS)R*+h*%QMm?yww(vs(#igM5VS37684>mfa z4bWZ8Z!w4C_?23SYi;0XH=VIZxG`R~Ew%X2rk@>x#e*1AdI6BO3h1QT%!vrUPYtp)PN2Oi7D1>Pa%ppo`LJAimErc{5jX}kH`bR1sgRm@m2*6S(+CRK|C zE}v0^V|>r2u(Z1qmTg2nL)Q13rI=G@#fqJo(~-aRIox z!uTiJl!rAmw(HrV8U6U<#mUx}IC%_Iy4BX%Pd}Y?O?0nuGibCyn)-H{tJ?(&ILe|Mw4om=It-;4o)d5n#YHcf4&va5t?kY)=^ zS<(?hJ@23P_n^_?OpG^4-$q@xgONOF^MXDZG%)tnvH=<$f4ZM$yHXpKEynEKH2){J ziiu|eM%XqD>2`D2&};mFA6}pK4W7O^3tUg|93S-hX1Friu_M275(UuE;P3@E!7AEy zggyl!?ki#qrnJ8ddThFy%5_sI(Zy_z`E3(Tr zSMKp0FM%`Q&VH`D!08No>y}9b-ElN`8c^|*9XTBH-i)>oJKT;L02dBL_*)1M()`8A zHDC}9K8oY5Z~N4Z!_KhN;^Bza$6y_Y&Dh2LEO`|Z?^I!84_BJzR_3(GQ(`ieVfY_O zWM06p)N{%d7gpap9B0Y;;2njvv@{y{xSZx7QnQpO&Vj)zm5@1f$ICr4qkJkFXW){8 zN#4XdfB@^}rotpwks*49Po57S1jXTvg5UG^fLyliONzK=lBM7nCAl=>p-kUu znZ;JidLFd(2M=#lQszoPo|J-A$wk3Pnc9LBDwR@XT+s6V9v`d^H>z2|b!kgdI@TtB zlDYRJbG+o7rMYHiUwGTLfql>#XhoB(yA*}jPIm_?EzUhP)eoDS=Sly219$ByFF@W_ z*>UV_vX!)M6w$>j)|hBAghgcC@$Aga>gCPkQV(yg)Fl@B@f2CL)5oU+gWZiWFTBg? zPhEv=mELI=t^*-)C{DIvJI1%|fd9R37*D`0j4EcegKmbx=lJx1(C=ur`%i&>xP&4- z95mvkUUABqB^gW6Q$-q5YP95)rO(S$0esy*o+HaPh$kq^GeaG5o+`qPDv2yh0N9jS zk*7=vm+gmmVX01XK^O)$5G_+OC6_>~cL1$~e3k zWI2M;AL?_$nODeLA0OTl5fLIMk>T5vy2XA)tDInPmjoU$=oW5+b1c#GpV3VJe z!s8x{w+oDiPdhM<*@1*->D7!&b97mwAHuh44<0{)gW>9P0Ge1N{UJH@8qIG#m6X?UBu!aC>Lo zw?9OjiL;C0z{l6B!kj+KN#E@V(V%s-esW+3@kfK{!`@t?v(}cmJ^mBL%|s>eFWg5G z1@^8pm^tVTNXxWTIa4IfFisroA4F^GfcZ8wT&Z){J$l94OgsTGNW9W(~OukxXxuVkTOQPFCaq=ae zXSHGaLBP8XCV(MEFP^gO@KJbZHQF)v*ow$|`r}Wd_v0UbN?!l?)0?xHy4@yfmB6ha zM}~7w46FoqPP?OtslvKGB5bayATIl;&Y>t%JPTJG0EnWI|n zpkXGgeRO4P*MAiQc=QWA1P#NG^wsLX4NKC3mcj`~GVU;KPXSV^!hm+l2_ec-3wi&v zK&WKNx z^_5#5w(yXZWnNmNNSR`Oc3T2-FELgV6%zOc#S0_uj{^fIugnRrWJYqD0lHWzi7d1w zs???S8P#dJZ)VSQM|#+?6nk*#Vlc|424OB{UJhm(7jyjd6a3kkF>QG*yqH6q4ufK& zwy8~4G%&J(Uw>P>)o8nwGhlXrv`2YRUxa5klFsxenqP#J2CEt^L`G-5gxyn}YE|?-2E zDgR+UkIoMcx9gi%_LC8PhA|rVwVh<2kPCxS*rPzq`hJuYeouAJbd10Ni^(83T0Iaj zfL|lj1#cB6J?ltxXkCAt-+@7)IMZVstP#y>zLDR*8-fZpj52j2v#W6nn^Y-n+E`r9KH{&D ziZBxYMb4DUVUdmcDZ0)@%Jhv^Fs)_04*QaKH9QDZ@-7&^*of%5*obdJKz*;wR4S}G zzU)K!Z8<5EdaRka3@Q2BCU%|FM%p5j8tJ%4rg*?Z^mAcDJgtm%U~dylYGg*^f4M^w z2b2y^@)O6GpC(yynH!}$Nz0MlJHo>TV>SZLyn=85Q?A?d%@nmm!L~v}%&82vg;P_gm zonQ%b8ICl>@V9dkijX2r7(&G}mCCA#2PARlh0-Y#lGdP34oZr>)P=6(RhZHgr6rJ~ zw=VS|_8%$%o0qX+B|+B%l@djD3{eVh#S@d`i-nG)Pyj2Fbh<2*m@*}?LxyAhwDkD{ z&&!%XwvB0Xav^@|0VL?jX>#@{@eIkypJmYupOwJFu2^=48_iFro@`kvANpcVeeXG< z3S0@7+ip6HlnhAE;SK$lxjtJb6Yw9{=?9PpUt04VD*vo@I*Lf>0~(=S zkZRDayHn-@X%TrF>1RTCBQ+m+CARoxwJ~BB;i^Mblr4BV|Jxob<>(9=xAibVfg6#N zOSZDrbxh@SY+Bjp#!;7cBZbC)5mse+tP5J#d40M|qr%ct)vo~^!Q#IG`zd-i0dOE8s>d!abFi`&~6xu?mApQ2me6MuW|vpK%10a z>yMD(B&V3mNU5&t*a;r`3}&R6%(w!eXHtMLWGw2ON1GP62cA zflYzC(s#Ni}JYF66bBqsN>j! z@kIM-`Hf&;^m$kMUFO# zIYq%KMR?dc{z>IikT*}+im3{ks81zJJS?UW;fZAr!-@$=xg0`Hmss;uCo-p!@?9o( z?cPh$pR3=-bDDdZYCBgOmhF150x*NhhRkNyVU$O=FpLdzpIFKj_}s*z^P zp4j{^PO#Y6+X%|lD35lB+-6^Ab^Gq%v1jUK>>k-MMjp9E2B}?rS_ZScd26a|IqUn@ z8=|dURd44u&ziAPgsbmZR{Q8pnPDy+C~)9fLEOLjMD4z@*W9^zD6@%-ujZSu?P`)E z;m0M#v5LR9Ep~F$qhUFa{!+RZ%up-;LnuDcOj^Q7ZH8;FdXq5<-ksi7Qrw6hvJ$Rglnf7Gj4~CfOtg3r- z5MY4d@TmNuna@ju{Au%#6wW`pmMJ-pjD>$X#$%s)e%o6%IEsBjqOqGc@Jm-arM zt6>D|xISE=d3CKgJ^E?e8y~FuOUxHO(4GNgZ~ORuVJMp(*W(Y@Tin>8mC}zz*S84y zd}KF;vrHOi(R;db01`Y4A@IQ%YU)|1_|-dnY-p#zp_5C}siDOjn%7v@;f;ZZb%B!V zLxNWsIIZnS`FKIVX~S|@73y{Xl*E9;cjleo$z;hS9g|E%)}kT_zLO*h?a8UL zoQ95I%EW@E$kR-cGP?E3Wjlpv({r7~qiBCMyvYRE7&8Wtl@;_5xsf)D&XX6j2gjw# z=+`l)B2Lcw$6_RL=6IUKCv0ku`^wKT`^HpyLQ&CdIXYZ#wmIb0TNIbzckH*b*=~k9 z6r${{G}&fO4iHypW^0X>hbFvvxWq7-l|VyMZ82@x)K(6|q)ONLtN!?G;eq&;+(W=zFP`keSsBRvHyO3-(`@j8-84aC?=7|4(av%+~zt%*h+ zIH{$E_8R=|^q;*%(;kRkMwMZS<|@w((&~Yun3PZ!N2KffpQo=VhlimQU_kd4#gji% zmAw%1h@>b&QeU$myQ`%bn=sJ(h3>%#Nf5pDUdUC3f=$1A115->w0I~4kQO#GYE#fY zzo70x8XH|zv5Xt5?01(8HwN3RJk?DoL4yXm0k^Crc(@zj;Iwm0Ml2RI!He2k# zb{A%B(zOV(zPZ|LkF?0l1@^=Z00PJN{XKP zvCvK(1%aK~yPMx4k>BHDlKWCM>ONqd( zcx~FtXTk^zjSp}1`%Wg$pySBrN)JaLm4Ktb)r&RCQFfb0yJsCAlw!Ix?}&(81;LL3 zD;9D39OGqB55KrdVPo1rWS2GbJTb_++kKLH7RycyT{05`y*ejl9W}SgEy%7{nnfv45mNnOF-yd1Gz3$oF5Ot8= z%3rvv?&6xRmrTQ>HrIis)DC!+rY^o~_=3G+Fg5*?>44e#vO!rdUhAtgKBczu(8GT9 z4W>5Hz&o(L#^_J@LiZkskA8>LtxPTUQyMGG29yr#Y8O32WoyLk&%;p_9K*TCwf$!U};Z*2yNMDW~5lR}a_EFswhk!p)c8pkCC znJT>nq;ej45?7+W=$h>oqHF0*DVzfuTQbe!bq-o9WN_($cprl~|H1POpm%ts85N0nv3UN+u+t zMfZYQ%o;ebmNIU}-=NT%Qv%3g{gDE)xoQsk{bdsmTa59NjFI)%PW}D^Mmfb%V^V*t zne!f_OR0siaQiLe)%N7#Sxe`o2Vu)w2w-fRLu_WD+ysdg&u+CyU=luhoPT#+E$f1>H<9veGOdk2RDe;pIb)KJ7)@i>FPPrpytv zk1&Od1fVaCX-ka2TgFj+8~DyMjX72TeSUAkFLZ2mT=2J39$4upq;HM3L9Rbv3$ zhuQq`;D}ooYWODipR5ekO0byGA)TKeySn;a(eAf_k%4{oMVcMUtBZVQn2GD2Ik^*7 zq72ce!QGi4l1gNtarQ&9Y3k`KTrYLh4nzyIZW&k**xo`oGc40OreZNJF8z&9N7)wn zcZ1`ht|7ka22ep9-*--!Tnaw@m+#@M%f}Gv36HF7(k>~0Ednyv6HiRHbMgkO3Fm~Z z{LKpMs%_-Wpr@XZRz+JyJ(UhCY{U1{fuXM_dpr4*5&dP*=*aC5f)+}ma^?HX$y*&0 zD4)GCb#jU32`B|KqZ6o$FjXGXAM;XnOGgb?KjSMKn+4sp%R%@lP<%Sgyz@XSMda9k zw=o^cS8nFiF=N*sOl8j~;vWj0v1*qLDhv`r7EFj4Yk2^GrF%dC`TwV! z$n~oz{x5POJrk{t^wYH7ZCVS#Hm3qeu z@!TI~J$`s+l}g$}iJ2qX3<;8qtFZMFAi(*9bix*5lrg51AKz_!3dL3?FV&ZeW|c{B zF%Yb6_jBL*ZGgA2qoj(9YHHHcq`aw7ViS+YfvjmVlN6o44 z5N(WnSK!l6nbgaX%4JeL<*b9UYTL;RSjyAJ_MLGnVy#^ksXgAja>tg$kXo`+ydQMP z9`mRlY0^BoS~iSiIYnI1+STaNfJkzvWGN9!j+pNBv5k~L8IZdQHVLOT(es>nfq$Q^ z+P0a9f7VQLSXyy<4+FaGf15RaI_Fad@3&c#@oRPCe(^7-aE%EPDHU0n$lLBK#2rL- z#w3>|)#F_y+MH=4CJqX+r36iUmYNiqd8BAF!22ghEEC|t&83t_(GI%n=gSXa3fm5o4%`W+Kk=nsZTr;n{~ z+hCOg)G<>ZVVjMe5|0n4WapEORhh3CvTaskE-5Z?y5oW4P=o7G-VAxg8VM^?G$oXe z+O-AGNsr1WEg5o&)$(SZ-p&9(%^soWOEcu1)lv_o47rSsFAVxa zACHDbx@W5nTZ+ilQlFXMxqk_vIEG2W3Uk9`G2kNagyPz~N&5$rZ{g|i*7O8nO%Lcd zrwO1*!z2JxcM6%}x?nuvguQ#;^nvVtFA&D>hXs>4I$hnFMQXO^43(1)YArzAk6FK- z_xmS(>$Lkf^DeQ??OoTD7op>>$kE>rh$eUB`(Dt0&{|XG{KlxKU{jd*-F04Bw!Pi{F`5 zl}u5dw4NmlTwlmxlG~RX5>4w_Z^`&YDRSjop=ePPSP}GMtqxYnz8^ z`p0WJt53MI-ziwI?eE$hx{&t@YhC0&ocdwQ|c&Px4XkFQR%_}CwgxRuyGB?zE z0c`5{#<`codD<4HF2*RAQ2$B0{DO$xM(z&7y>|V*@m9xFq~vN8`bt3L5V3tyN+=P+ z3^-H6UW_jxH>jV%AgJ6xS5n-2bSe3aurM&pOubkR1IM}hp!#}OJ5v(QCsYh50q%;b zUellKAjSU3eKFLdlD3C%3Nc@I{|nkq=+ zy0^y1TAHzqD7%OrJ%BV*txfv-1PS2nx3TD9>Ijrh%rB z)Wg%0^8g44*97SJ)xDVnII1=&*5nyhH6|q+2bPx+7w7&y{{DVGsDC*M@TnUhn+LQv zgAP6BOId+7g|4M8nf~fr9o@QtJ`&_mTbwck0p2(=d2;zsd9Vp>q*mGSmfK}|gs9>I z4|+X_fYr){-gUBQ&%8{G>nrrDm^oyR8Z1wQ1bUE+4kRj2Y=&5ld+m7A&$E!zcu2QC znf8#nSiw?zQvE`yUPYqiL~}I3+2rWjtZd6+j5Tv=_-M6myqYN>Hdr(lUGiM|naWGc zb)(OD_1M$&a)YH~7B!DAfR#TdPAyHOgPChi#}>2MQ%g}5p2jD4H=PTJHj09kN`7E; znv>(yraif&nC1;4SnUX-wW+n@YHGp*PXU4Pu8pT)PvM`c=?Juyz!3`rD@-jNnOa$# zN+nK*ZkFI&Xd%M(U6n>nA0^Pvbt4~vjgUpCgxe)#YDmFUBY}-mb=LY~{OS;fiZ1I+ zCodnDRSy&7&c8)=6BnOSDV4lm%BJ1SF(>DXly8EG+D=0Aqe;bg)#ccl?EaQIONBQT zsAh6z>Hz6vZEkambD#oniAY9bTgx5n@C>54{#iH;drn+N(B63r z!#I+?M_bI9N05<~GN}_`OKT+@Us6mb!%Vh#@t6i+i8qE+_PnC3#l%6fdR94JjkTT_dT6c1*F=T*p05Z?>1W&be2{WdwHLnljTYe9sP2(uUQ%HSbDwQJHuhP=)Oa9H>#mXNhbQQp_~ zJHa%Jmb##W?I4F_@M?jqz>L$lLWJ}X|% zVA9~J7X|%EisKQVoHN(IoyVWJR4dAmK!)AU%eBi;d3c#={aOXzpvZ{bpk#}xRPIN3 z!uCbJfH>TZgG=-^oy{6E!HlXm_TrQI8 z(Vx5Ge4831xJu_UoOC6&LK6NK5cIy_$1N+GuRhGm^!WA67YXh#rq;Y{T3mtxuvOM+Ot`0Z$haPy-n;AKBq;MDrPivGSB28_)M z*k5L?nW0LCh0cVrX7e&4%k2e0Jrq`>)_ApC_t>CwC^Q1N`#&QCiAFtJM1ap+Y@bu( z)32-^dVAm1hy{L*c&OpUHvzPd_u~OpPb@t4T$aL7Zf8}18)??$*YxmiVGSU%#i<>u z>e%~_Za4xJ)J!7m$b+=2SXsB?u6mTwWyPTWh=jg%l1w4NkMROTrzbF&BUSTkE0mQ4(vfl4!OG)LR)rqe%auEJhVTl$!WDI&Wv#!hZs;Xo+NxQHEDMDGeos ze65IeLAKyqsO>sM&>MysHT?0lECr7;>oVOz5elzlollZG`RkPqaz~5Et=afYtNQR* zO_YPQ^~Y1xu|u+%nC+AY)~CDUgWU$_`FtfDcs{n?X!zCAYw^~Ld*9F}Qi?weGUJ^>ULl~Uk4mm1CUQwh~0dA5Xn=bEFBzHZExm{QwBt(0ZYDAM-=He zFpG$ARteWL!1E*I)V`fLBQ!vETYP?f*d0p>Ks$pzUl+SGLYC+l)XUBh{9l98IA3zx z2&+CWs3q&nQc=jW<7j~vIH!$s$iQ(tB(Cn$fPEZn?2U2DzIop2b`z-Tv6V23OScZt!auF0>OOTL&5-cq2h_9x&Hh8K|;6f;gtlbCHg@sNq5T>(9Fo- zj%oW50_Tl2+1s2AzQ4%n8@Sy-{*qk*TuCef@Hsh&8|f-GNG&ILS=EExb=I=iU?CxY zp^*qQI=Am|@9=by%>cz%%p-9D!Rc zez~q}hrA``Sb#|Ut3ruv`$`~t{p8iq`!X`m_p?=lYzVn_#CFTjyjIAHL1$IWr7-Bf#BMN(^m#q{5qnnn~ArbHC|ZN*KajkXWEu87#553=e-_vZ82nU^t9v;D*{mA$#L>#FE zdA$Q1i!=sG_jvv8BBAS!Ni#1~G45T1SKjW2HP47yUtOfkDOlWIUzyXZt{{d(b!;H^^o_6 zG*;&2n59&tk@!aFth_=a@$V>_`Rs?tjd^!>CvW|9CCJ)A6}i50*vGtE-B2!IKoFh@ zw)bFsUfa3xnsx9#9<1G~)8Rt{TLKJ5Hp&|C+?O8*#Tn^obKm6Hw)X4E_0GqAjz1s%6XofZo^~1{0RVhi0{kyg9{2wz%44M!aB;Sik=Faa@;+-jBLnOI z$?|++oHj=jPx}IsE^El?!oa}t4kLGSjL5n+nvl}2iS4Ew6&@)F2?2Qlnyb5y{Q7P% zeotpMV$ZsCba^%?Be190O8u6$m$o0{lHfWk9~;?!_oE2?HCISo;{zuPTOZuo*A{pN(@{+SZgL6-B=QrYl&AN)j{^SKhc zK)E(v$!&kuy^maD()F-2^=9oLr;Ri_en16dvg%IYe$+i_q`X{Y-f3#oOhp-ECEHng z-)hRRtXpiUKiYiwXEq@DR4e!VLBUr*Q%4rb^kK=y(wkz7hvliC^)aAq#6fO zsXc*_c5BF-8>4-n`4g$qhGnsxmettF`uG5*H}9pTv(i0tuk-0Distdj5?(|PlSm8` zh`zz%k+9a}BC9cb>J8b$=VATUy?Th0fJRAIo4@1tkAZh0>bUZqL`|*JLP=Sd?(|=) z4-@^66U=tsgbLH;?y~fu@bfMoFV$(4NCWQ9_3Eq1cY(EQ2~SUF%85#wUP4jIFKsW3@n&1KI4uI2{=L`=3IR4CZhJZh`q) z#cfybMkWr`^ldLIHE8 z_Ap*gZNl&OTDI#h)29hFJGdOLT#6CFtVFDIN3~2Cj?O}XX3h6e;^yjg8*sXgaog}} zJ$uQ?*3o=9-8GSw@e0I&wcd+X|J?#!!6SB8a|~gB$V;c+G;1a2cNBH3?ZvjCwX$Km z*D_uA7&^^T7rC_IRrXNTeZNuR%a_SA^YFWuU`RWuvC~so>sS9gslo$fxQI*AXiDcJ zH)s*c6E89GP+1R1Sd7PjJ};fj5=9$kRZMDq%2-Rrr6q^l<$k-|PNkB27<6sK>7k&C z^K!BMq+=s9)JU1n7%^sFj)iM<**@xDSfAaz$a=UJL6Gh?s~^-~)O3xU($F=(1vLfM zzxM?^s!Y=!td7)cvF1kiPdoH~+ zG20yovTGS|T&b*Q>bMsi#qAdGUI4?#(F?7~t_o?rWvA1(m^oFio>yFBv8LYPMgs`w zsC96>?w;bvuc{>lA95U>=CjrO8O~Z&Ys?-*Qyh^*7zH6yAY?XxJQU8tmtvA=fgSp^ z(~zLcA0?drM^7S3-0wIk4a`=>93i9^LBFc`@$IXn+HN%Ex!1F*#({XIqwWLzKnxMh zVq6iB2&k*4atxk+c2TH4Rg~1Ku4buIP7R<2Rg)3|6fkdqrFaKYX;}ahsxU>V$La85 z^Y<9Y-2&ia7oTS{8upd{0dyMh%oCUjk$-~_`pt-;>PJ2!m z8q5o_E93aLHSAtw)|2Pel2WY)jO68%zCa}br}M6aGMA_n#y9^z$WV9bu> zFGeig1kpfGg1r|VuFQlRBCSYt8y9kp3FTuUNa?{(E@G0SPcTuqPNpCo6fY7`7=05K zvOr7iy~mSvp4zyU*=074*W>Zs*ORK8(C-J$20 zT4GH}f)ueV3{F6T0DP`dj9)kv54N1n9uWZ5!DeD+HCfs(AQE9n41)pj%@_m0A3>@N z+8axp5&-#H^jm>x6o3ZJ9XJ%9jpFF8kSyA3s(vWM_}y;<@p(To;ZC%Bbb71X$MJI? zrt{JIgIid7{vTF!M>t26V(AXJICYS8vW1W^5+s4yB$_k=@-OZND=Yp5@o~KDfx4*d z=BP}mcs{bxq?}8l$R~nJqmnbntqOPdncG#%>~Uc~&llR!-J_=)Diz&7#;)hww4IJu z;Bcy)xRCEW2n0Fsce~a1Fcg&>YyFVlGv5Qyr;!Q#Mrx{jL2s$lyuHO*=Q?Iw=z~=% zf`*OCF-ggCx+<*XxF<0hHPx74l!J48U)^TIjc%l+Rd&XEeNk@w7}B&Vj=E7Sp_?%J zD@=I9k-De#3j|Q=BF`V7ztt$A=C8i$LXpILvFB0!l zn}XeqW>x)1RFdwQMOcIrb0V{{#>$#m%R5z-*TpL+;By7e8f;5^lFDM&x&C%FmO}r? zrX5=(tn9oclkLvGdX^bko2n?GInz++kAp7=AS+=zN^o&4*TU)*&f6Ox9l}+_DNT*l z3eQo9CqiS~wh%=fneKco7dunhI-YoM-X%Gdi>3Fw_WH+vgjI$!r0Pl_>$F+!dbw#Q z;c6e+ng%|)D<@YLU+fw$1^OJ@)`(QM|McFCC~epSkW&>Gu{Kw8#u#PwrCivwaAh?n z(K>$?CZ}P+rL33KMlFq=%aHX<+e|IH-hi3ZEBy+iTP?4)GqjSurq}5#S??Ab*MKbORfLO1gU9VusGPyp4_!*V{3Db=DXpq0K z0jfwgAYA-{*CR>>ANz<>{c$jc0l}Z2fLVw+|DcIQ;w9w>d16n#Uc&7os!)CInUvSz zF824)!6*4F_u6kyhXbB|9uVD0%UbyC$t<83Cjem$AfHnp%}Uxx*soI9FKeHyvlE2% zAlrII$xodf3LUNKs|##vDOWCZ)y2Thno+@0sk5lgTX0}a31mEh z%XopyvXYeq$e6G&Jb$m2P-?D%>Izlx0AtZHhe-=bbyC2-WIQAR8Gds@m2#lj;^^Br zV}ZK)rwT?!R^dkcpbr=lLRs%bdWu1M`OK!C1nO_ZM92(!P++2p!a!jMVTsiH@O0`0 zpke{sd-RB}u3Ogj#T@d`Yq}Gq+F@r6IWuitz3eMt;++#kPX$|3jl&s>DYqO?xT9z^ zwGAAhqKX03I#=>gIcBILq8Dt&7wpb`rQt7e5M+0Bd`}R}koY2rNu`PM=po^2K<1u( zrD~&zj>rf&d!a&*dD6$B^kGg3mjkHECVjb~5gINtGcqRmEZ4>-ei&e5J>Y^mB~dqj zLnZ@n1^29Wdy)0T+cYV3W_u|Wpqj%fhb$f#M`$t@p%*-ov3aa(y4 zbuB#Zy%l8U(j}W^ML`RsVH7-;Nk16^S5zJ)^!F4={Sw2R(c;94{`8noK;=mN_JiYT z6JG??Z9S%oa3OVwf)$DY3Cv)wBE!V`4UvMFp`79`!SsG*oE=RwLf5${AK4=(ZX;pc zlu+6nXd-2kpYu5Yb=P91|AKCsWBWVRxf>*hwBhat3&9TtWH$$Ejmyk8rvrK!WGy^7 zJeslWVZ|ztN5$T+Am~1aqUOlKD}>=Ir2ib@IS%^7j};e4R0EZg%iO}z_1HxGNt}PP z;786!iEz&sPc;oS$1P@nAx^r_EmW`ngz(hW)ftfNBj30+>G@U{7KekgJ+hs@^Ee=$roEl#{b2e_wogGD-Ic20*EboVjm>|+`Z-EOW6voQY zfVj+NUe|Pb?^D0DWxFTDARHTYU|}QIaF4y-sL%JC zP%cQPq9obZ?}^c?j^pNT--lMsbEc|0py6~%b+7ksUVI-l_vTz~YiRGtR2I;WVpds& zMccW{68CwtFa`KeFdN*81@kX-iNX7P8B^%>GI-o69uU>eQSo>@piBU>(T;&8p}lFw z5=6ww`7*$`rT$%|l02VGuBI1XA#*Oa)ToQ}dYYOw+n^zu*UI}1tM=a6w3~Xli+Aq> z557W`Bbiu_)rr{uLP>F8nnm5L${JgCY#`DPXA@jl^6#w7CI^kLv%?gk$|aqfUAE7%a2ZR4 zs+J6g=4)B%n{Y?e(dL_KqU~@Et{AZzoK=#!OdDK%7V5cq3Jlh*uzFS%x^|w*o2(4< zRV>q>E*KDAa?soZa#y-XYt^0BOu=sLj0E+4YPO>rXiq8aW@Kh}J+*1zYXt_!a)*|i z?dnaA2+CM$bOaw7Cmj|;=^W&TWomK;`syAgamm|Qqg;vM@C?ri$Kdc>EF=?`#n%TD{ptAtL-WLx z9dN+{I@*E&9>Y%Pq$w+q6DUG76;kyJ0`wFr32~aJ^Z)v4p>H2N=J>_Ikg|dnY&jOs zV!L-%o)rByQ6-boOT-d+j1zsd96YXDiwh>Z+7DB2aG1R!S4krz$rm_{_!sV=5)JnV zfNPQ2sC)Zf;@^7`YyptcG5H8JN{#ZbnTa##_*`GdQikN=62H*?ei znKV&efMWFHkNBvJcp*OMzk3R%`&`<-eN|&5j;Yf>ss67Z=G{A{z@26NAlk@KFo6lx z3|L3sV|Zw1D<%{?VtzDfj}1yb1<8O@;6YeC_p8z)oDR+>jV&sME^Bc;aHyHJV|Rd- zSCTCrqGn0m3s7%XI0cqiiWTvmPXpxm#QbF#Vk^frDZKn_Lot09ix#9b)@kL0WkNWaM#` zFp$(003+1n5mAjp(}h1s6_m%>JNfFLBRNP6ks8I5f`Lp$A#1FGk$#`n-70ZPxW$Yj|gI z?E!G7CDE!T&O~ST&bKPYtglmQa58Xv29R9z&1Uv&nK3)^fvD@iClehDY9yxi?Iruu zaRHAZ$UmzjqN9CM5oUxz{0qGY3yFi|G$~2gXA(cd{EdK@m;t*H!T(Y~Lj$BPB-*RD z1(R_9Y3vs#dIdqoyj6aFEg;p?jw6h5)(?J5q7U3bpfCcD$kPQ7Hf%A)h}SJ zR$~w^i80%Au1Y0yst>F@-V~gzY$O-ReaO8mX-!^ZF?mPZ8HFTQg$mHLamKdG$nE5z z-b)>@1diXC)~=qd39mHz4@`=P_P6;t$M0Yt@T6o3132h-LM3E5U|(SKE`11f>g6uK zT*`dxa#jRvfLUOWI%_8OS0;51%Dt7Jd2JWhDtqxf9@J>ID{|52L*9xuAp69&t*juwkx_55>Yumd z@*ki@0UHyPv?Y?P-anO@En!KCYWg(1VHTGDM<(5DqACA1D4i{)aeW!Q7)C^N<+R8m zTes4(H16WqPibi7*fdKHTVBcgDMcF_xK#SI@V6|Wfoq(yJqbGXcu3lBC6BW}gFC zN&EjBCM^ZdyraI8fXA|Qqe*0h1K2kFS?sLQkTRiivoq{!tLyNWT??c6Asv$u6_R4@rpr`$0Ks#l}qZXZTb- z0$=&QHx*2)0b(r-s=ncc@qSog=6AarwwK%SOweB+q`bx7QZj|-ZTLWMY;zvO0TgE8 z;v`w1S^Xy|_AnR9D0hz^wf!m{o+&eIlW@=;xsAO-JT534OhIU920gRs-`s}&^X;rp zZfHhGFWT6@wtepQCj-R&8}=swwya(zABvZk1J6{m-tbZcD4yL8qw%V|4rm?u*O%mc zO_6yRzsG@fW=OXl7I-PSqvLU`f@M8o`)Y8vXBEm;YJV+HE=1|pereLyUz!xOZ`40J z#>{;?U&UxG9j$Sep5_+3>KM?67@ zODySt@^LD~Wpx3;J);>72 z_G4a9RvT@@C`D}*g=j+i6*gLw=-lahijrZMSD7U=$|VKQ99lV_Lzw3}z{{`VwzA{+ z+^^ZFb?j9V6G}qCVu&J6%yvc%8-;TSP{g-v;&W|_trhfVr;Np=Ei7hsUVldig4Jf_ zPHCFGW)kr|e~DJV3J04v144bWW|KXh3yh7{`ElGqskkeDQdjEb?5WUPg+xB3#-Nb{ zr$~{jM(;_Q?llEF#S8xc9 zj^|8Pq3#fPa|vkrG^Toib6HoVL(uqQcNjy}E=P9~DA(u;P8e&h2TdKF%KuC2Q}cVf z7sw4G4TcEl(o`qGF+ez!W#4z-vWaKF!~wJp_o8zhvy-VYxbKAvm!oGL5NtzTq(towwNXYl`ZJqG)wl14x^ZIt~d1KlLseS)L^?2{e)AO1Gr4Enn+HYvdbG7v)u2tl?@O3>4^c7V7ysPFf zJelJS!>G0#W9R0fl^lgR-?-qT!S*fpUot6wq}i(sa#1G{U2+4n7+570=ikadQ{VMN z@CJcw^wy}?hH~pMs6-OYI}wXoCsON8P}^RO8mnV0Er-$8MKYhumwAFMPJ1mIi&$g| z@;5O&UY;ktbwoyc?4Mb}*P=eB&{Hd~6G?34pCmu&bgEHu=%&fnEU2rcfF)-7n5Q)n z>Uet}S!8+a6+?e<^O<+fzq9n1UF(Ta`m$f4{}oGRvFGd~&(2vz#vx z?7scqd$59PUwv`X->UzZz(75E>d1}#acjTrCV4irr~_{B&^~<{>vmX1f`T9uPR|;OTOYe+j35!h+Miph9pNnZ?J&jIkWzwiaxQ_V&buYoCXQ$`HU zqWc@U<7;3dR>r6@OGhsn@(IGY{>r3t?#j`7iw{N@0_>siB-Fv^2k+FCG)dt zvXynu>&k2EjRJ0%c5$g7P(uA+!s zDJ#33BejDwt;!#hYKqeuQN!kk+9j`mPEbHS1ay{8M+gL=++&PX!C(2Jn=$oy%LZT# z=BEc1{6D3gV{m5ewytB_=-4(pwr$(Ct&VLwZ)|pK+vwPK(n)rIYoA@~t95p*b*j#o zzux&{Ja5(fG4JP|_j3)Sun}OPf?#2(5VhztQjF+VZ##4winN!)gK@6#g4~t$-rp+j z1o~^iC&2|$e9lD5ptV>_rLDTjTASUFM)-Cc9!B=q;qv^r zOC1UW=HX^PameQW51o`BF-b&JQ^Y0S3Pmv^UWP?5IW|3-1V`EH3kzA${=1pbv}<|` zdws$TIK)qBAoy}gS1aPYq4xy;ro*hZVB#;DYYCn(jZc5EP_s-P84$R7}t>dy$dK(h41BauXM{59eWM=_?1B7KRA4L*$J z`wu`V(Ey`M-4vu@zeGrQF&cSrpIW3bul zSL1Hx4iKo%ZleLGa8f%`iaYAS;)>m~i7sHKhG!+Z^%xc-;MNxZi%{B<*+?&1sY9&9 zdm9~ERU!Q2sc+Pg>Dne^qz3fs4E%a#n5;!l48N<%u;92c4O>=caU>0cTygLPzTsQtcI57XD& zG-SJToM&V7GWF|Zw>&mOu>~REMe~tG#X_)%-+bVF`57#Pz&}O3p@C*+LCr^}FJfAz zDuI*yH=qr!N0#TjzE2h9^(r0axbc= zW+^Pb@q|^x3N8oQeo{DC9k%ewDq(pV)6Xw-C{nGvdL_jb&89xp9p3)~xc8F!6G{^u1lfu=PH6~?F0-

0)L*hoifUP< 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 diff --git a/how-to-use-azureml/azure-databricks/README.md b/how-to-use-azureml/azure-databricks/README.md index b567a035..2a48316c 100644 --- a/how-to-use-azureml/azure-databricks/README.md +++ b/how-to-use-azureml/azure-databricks/README.md @@ -1,20 +1,21 @@ Azure Databricks is a managed Spark offering on Azure and customers already use it for advanced analytics. It provides a collaborative Notebook based environment with CPU or GPU based compute cluster. -In this section, you will see sample notebooks on how to use Azure Machine Learning SDK with Azure Databricks. You can train a model using Spark MLlib and then deploy the model to ACI/AKS from within Azure Databricks. You can also use Automated ML capability (**public preview**) of Azure ML SDK with Azure Databricks. +In this section, you will find sample notebooks on how to use Azure Machine Learning SDK with Azure Databricks. You can train a model using Spark MLlib and then deploy the model to ACI/AKS from within Azure Databricks. You can also use Automated ML capability (**public preview**) of Azure ML SDK with Azure Databricks. - Customers who use Azure Databricks for advanced analytics can now use the same cluster to run experiments with or without automated machine learning. - You can keep the data within the same cluster. - You can leverage the local worker nodes with autoscale and auto termination capabilities. - You can use multiple cores of your Azure Databricks cluster to perform simultenous training. - You can further tune the model generated by automated machine learning if you chose to. -- Every run (including the best run) is available as a pipeline. +- Every run (including the best run) is available as a pipeline, which you can tune further if needed. - The model trained using Azure Databricks can be registered in Azure ML SDK workspace and then deployed to Azure managed compute (ACI or AKS) using the Azure Machine learning SDK. + **Create Azure Databricks Cluster:** Select New Cluster and fill in following detail: - Cluster name: _yourclustername_ - - Databricks Runtime: Any 4.x runtime. + - Databricks Runtime: Any **non ML** runtime (non ML 4.x, 5.x) - Python version: **3** - Workers: 2 or higher. @@ -46,7 +47,7 @@ It will take few minutes to create the cluster. Please ensure that the cluster s - Click Install Library -- Do not select _Attach automatically to all clusters_. In case you have selected earlier then you can go to your Home folder and deselect it. +- Do not select _Attach automatically to all clusters_. In case you selected this earlier, please go to your Home folder and deselect it. - Select the check box _Attach_ next to your cluster name @@ -54,17 +55,17 @@ It will take few minutes to create the cluster. Please ensure that the cluster s - Ensure that there are no errors until Status changes to _Attached_. It may take a couple of minutes. -**Note** - If you have the old build the please deselect it from cluster’s installed libs > move to trash. Install the new build and restart the cluster. And if still there is an issue then detach and reattach your cluster. +**Note** - If you have an old SDK version, please deselect it from cluster’s installed libs > move to trash. Install the new SDK verdion and restart the cluster. If there is an issue after this, please detach and reattach your cluster. -iPython Notebooks 1-4 have to be run sequentially after making changes based on your subscription. The corresponding DBC archive contains all the notebooks and can be imported into your Databricks workspace. You can the run notebooks after importing [databricks_amlsdk](Databricks_AMLSDK_1-4_6.dbc) instead of downloading individually. +**Single file** - +The following archive contains all the sample notebooks. You can the run notebooks after importing [DBC](Databricks_AMLSDK_1-4_6.dbc) in your Databricks workspace instead of downloading individually. -Notebooks 1-4 are related to Income prediction experiment based on this [dataset](https://archive.ics.uci.edu/ml/datasets/adult) and demonstrate how to data prep, train and operationalize a Spark ML model with Azure ML Python SDK from within Azure Databricks. Notebook 6 is an Automated ML sample notebook. +Notebooks 1-4 have to be run sequentially & are related to Income prediction experiment based on this [dataset](https://archive.ics.uci.edu/ml/datasets/adult) and demonstrate how to data prep, train and operationalize a Spark ML model with Azure ML Python SDK from within Azure Databricks. -For details on SDK concepts, please refer to [notebooks](https://github.com/Azure/MachineLearningNotebooks). +Notebook 6 is an Automated ML sample notebook for Classification. Learn more about [how to use Azure Databricks as a development environment](https://docs.microsoft.com/azure/machine-learning/service/how-to-configure-environment#azure-databricks) for Azure Machine Learning service. -You can also use Azure Databricks as a compute target for [training models with an Azure Machine Learning pipeline](https://docs.microsoft.com/machine-learning/service/how-to-set-up-training-targets#databricks). - +For more on SDK concepts, please refer to [notebooks](https://github.com/Azure/MachineLearningNotebooks). **Please let us know your feedback.** \ No newline at end of file diff --git a/how-to-use-azureml/azure-databricks/automl/automl-databricks-local-01.ipynb b/how-to-use-azureml/azure-databricks/automl/automl-databricks-local-01.ipynb index 597ee240..6a70d000 100644 --- a/how-to-use-azureml/azure-databricks/automl/automl-databricks-local-01.ipynb +++ b/how-to-use-azureml/azure-databricks/automl/automl-databricks-local-01.ipynb @@ -13,45 +13,31 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We support installing AML SDK as library from GUI. When attaching a library follow this https://docs.databricks.com/user-guide/libraries.html and add the below string as your PyPi package. You can select the option to attach the library to all clusters or just one cluster.\n", + "# Automated ML on Azure Databricks\n", "\n", - "**install azureml-sdk with Automated ML**\n", - "* Source: Upload Python Egg or PyPi\n", - "* PyPi Name: `azureml-sdk[automl_databricks]`\n", - "* Select Install Library" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# AutoML : Classification with Local Compute on Azure DataBricks\n", - "\n", - "In this example we use the scikit-learn's [digit dataset](http://scikit-learn.org/stable/datasets/index.html#optical-recognition-of-handwritten-digits-dataset) to showcase how you can use AutoML for a simple classification problem.\n", + "In this example we use the scikit-learn's digit dataset to showcase how you can use AutoML for a simple classification problem.\n", "\n", "In this notebook you will learn how to:\n", "1. Create Azure Machine Learning Workspace object and initialize your notebook directory to easily reload this object from a configuration file.\n", "2. Create an `Experiment` in an existing `Workspace`.\n", - "3. Configure AutoML using `AutoMLConfig`.\n", - "4. Train the model using AzureDataBricks.\n", + "3. Configure Automated ML using `AutoMLConfig`.\n", + "4. Train the model using Azure Databricks.\n", "5. Explore the results.\n", "6. Test the best fitted model.\n", "\n", - "Prerequisites:\n", - "Before running this notebook, please follow the readme for installing necessary libraries to your cluster." + "Before running this notebook, please follow the readme for using Automated ML on Azure Databricks for installing necessary libraries to your cluster." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Register Machine Learning Services Resource Provider\n", - "Microsoft.MachineLearningServices only needs to be registed once in the subscription. To register it:\n", - "Start the Azure portal.\n", - "Select your All services and then Subscription.\n", - "Select the subscription that you want to use.\n", - "Click on Resource providers\n", - "Click the Register link next to Microsoft.MachineLearningServices" + "We support installing AML SDK with Automated ML as library from GUI. When attaching a library follow this link and add the below string as your PyPi package. You can select the option to attach the library to all clusters or just one cluster.\n", + "\n", + "**azureml-sdk with automated ml**\n", + "* Source: Upload Python Egg or PyPi\n", + "* PyPi Name: `azureml-sdk[automl_databricks]`\n", + "* Select Install Library" ] }, { @@ -97,10 +83,10 @@ "metadata": {}, "outputs": [], "source": [ - "subscription_id = \"\"\n", - "resource_group = \"\"\n", - "workspace_name = \"\"\n", - "workspace_region = \"\" #eg. eastus2, westcentralus, westeurope" + "subscription_id = \"\" #you should be owner or contributor\n", + "resource_group = \"\" #you should be owner or contributor\n", + "workspace_name = \"\" #your workspace name\n", + "workspace_region = \"\" #your region" ] }, { @@ -132,8 +118,7 @@ "ws = Workspace.create(name = workspace_name,\n", " subscription_id = subscription_id,\n", " resource_group = resource_group, \n", - " location = workspace_region,\n", - " auth = auth,\n", + " location = workspace_region, \n", " exist_ok=True)\n", "ws.get_details()" ] @@ -143,21 +128,7 @@ "execution_count": null, "metadata": {}, "outputs": [], - "source": [ - "from azureml.core import Workspace\n", - "import azureml.core\n", - "\n", - "# Check core SDK version number\n", - "print(\"SDK version:\", azureml.core.VERSION)\n", - "\n", - "#'''\n", - "ws = Workspace.from_config()\n", - "print('Workspace name: ' + ws.name, \n", - " 'Azure region: ' + ws.location, \n", - " 'Subscription id: ' + ws.subscription_id, \n", - " 'Resource group: ' + ws.resource_group, sep = '\\n')\n", - "#'''" - ] + "source": [] }, { "cell_type": "markdown", @@ -213,7 +184,7 @@ "source": [ "## Create an Experiment\n", "\n", - "As part of the setup you have already created an Azure ML `Workspace` object. For AutoML you will need to create an `Experiment` object, which is a named object in a `Workspace` used to run experiments." + "As part of the setup you have already created an Azure ML `Workspace` object. For Automated ML you will need to create an `Experiment` object, which is a named object in a `Workspace` used to run experiments." ] }, { @@ -239,15 +210,6 @@ "from azureml.train.automl.run import AutoMLRun" ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "ws = Workspace.from_config(auth = auth)" - ] - }, { "cell_type": "code", "execution_count": null, @@ -304,6 +266,9 @@ "metadata": {}, "outputs": [], "source": [ + "#Automated ML requires a dataflow, which is different from dataframe.\n", + "#If your data is in a dataframe, please use read_pandas_dataframe to convert a dataframe to dataflow before usind dprep.\n", + "\n", "import azureml.dataprep as dprep\n", "# You can use `auto_read_file` which intelligently figures out delimiters and datatypes of a file.\n", "# The data referenced here was pulled from `sklearn.datasets.load_digits()`.\n", @@ -375,7 +340,6 @@ " spark_context=sc, #databricks/spark related\n", " X = X_train, \n", " y = y_train,\n", - " enable_cache=False,\n", " path = project_folder)" ] }, @@ -420,7 +384,7 @@ "metadata": {}, "outputs": [], "source": [ - "print(local_run.get_portal_url())" + "displayHTML(\"Your experiment in Azure Portal: {}\".format(local_run.get_portal_url(), local_run.id))" ] }, { @@ -548,7 +512,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "When deploying an automated ML trained model, please specify _pip_packages=['azureml-sdk[automl]']_ in your CondaDependencies." + "When deploying an automated ML trained model, please specify _pippackages=['azureml-sdk[automl]']_ in your CondaDependencies.\n", + "\n", + "Please refer to only the **Deploy** section in this notebook - Deployment of Automated ML trained model" ] }, { @@ -586,8 +552,8 @@ "version": "3.7.0" }, "name": "auto-ml-classification-local-adb", - "notebookId": 3836944406456411 + "notebookId": 817220787969977 }, "nbformat": 4, - "nbformat_minor": 1 + "nbformat_minor": 0 } \ No newline at end of file diff --git a/how-to-use-azureml/azure-databricks/automl/automl-databricks-local-with-deployment.ipynb b/how-to-use-azureml/azure-databricks/automl/automl-databricks-local-with-deployment.ipynb new file mode 100644 index 00000000..154fc235 --- /dev/null +++ b/how-to-use-azureml/azure-databricks/automl/automl-databricks-local-with-deployment.ipynb @@ -0,0 +1,704 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Copyright (c) Microsoft Corporation. All rights reserved.\n", + "\n", + "Licensed under the MIT License." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We support installing AML SDK as library from GUI. When attaching a library follow this https://docs.databricks.com/user-guide/libraries.html and add the below string as your PyPi package. You can select the option to attach the library to all clusters or just one cluster.\n", + "\n", + "**install azureml-sdk with Automated ML**\n", + "* Source: Upload Python Egg or PyPi\n", + "* PyPi Name: `azureml-sdk[automl_databricks]`\n", + "* Select Install Library" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# AutoML : Classification with Local Compute on Azure DataBricks with deployment to ACI\n", + "\n", + "In this example we use the scikit-learn's [digit dataset](http://scikit-learn.org/stable/datasets/index.html#optical-recognition-of-handwritten-digits-dataset) to showcase how you can use AutoML for a simple classification problem.\n", + "\n", + "In this notebook you will learn how to:\n", + "1. Create Azure Machine Learning Workspace object and initialize your notebook directory to easily reload this object from a configuration file.\n", + "2. Create an `Experiment` in an existing `Workspace`.\n", + "3. Configure AutoML using `AutoMLConfig`.\n", + "4. Train the model using AzureDataBricks.\n", + "5. Explore the results.\n", + "6. Register the model.\n", + "7. Deploy the model.\n", + "8. Test the best fitted model.\n", + "\n", + "Prerequisites:\n", + "Before running this notebook, please follow the readme for installing necessary libraries to your cluster." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Register Machine Learning Services Resource Provider\n", + "Microsoft.MachineLearningServices only needs to be registed once in the subscription. To register it:\n", + "Start the Azure portal.\n", + "Select your All services and then Subscription.\n", + "Select the subscription that you want to use.\n", + "Click on Resource providers\n", + "Click the Register link next to Microsoft.MachineLearningServices" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Check the Azure ML Core SDK Version to Validate Your Installation" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import azureml.core\n", + "\n", + "print(\"SDK Version:\", azureml.core.VERSION)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Initialize an Azure ML Workspace\n", + "### What is an Azure ML Workspace and Why Do I Need One?\n", + "\n", + "An Azure ML workspace is an Azure resource that organizes and coordinates the actions of many other Azure resources to assist in executing and sharing machine learning workflows. In particular, an Azure ML workspace coordinates storage, databases, and compute resources providing added functionality for machine learning experimentation, operationalization, and the monitoring of operationalized models.\n", + "\n", + "\n", + "### What do I Need?\n", + "\n", + "To create or access an Azure ML workspace, you will need to import the Azure ML library and specify following information:\n", + "* A name for your workspace. You can choose one.\n", + "* Your subscription id. Use the `id` value from the `az account show` command output above.\n", + "* The resource group name. The resource group organizes Azure resources and provides a default region for the resources in the group. The resource group will be created if it doesn't exist. Resource groups can be created and viewed in the [Azure portal](https://portal.azure.com)\n", + "* Supported regions include `eastus2`, `eastus`,`westcentralus`, `southeastasia`, `westeurope`, `australiaeast`, `westus2`, `southcentralus`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "subscription_id = \"\"\n", + "resource_group = \"\"\n", + "workspace_name = \"\"\n", + "workspace_region = \"\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Creating a Workspace\n", + "If you already have access to an Azure ML workspace you want to use, you can skip this cell. Otherwise, this cell will create an Azure ML workspace for you in the specified subscription, provided you have the correct permissions for the given `subscription_id`.\n", + "\n", + "This will fail when:\n", + "1. The workspace already exists.\n", + "2. You do not have permission to create a workspace in the resource group.\n", + "3. You are not a subscription owner or contributor and no Azure ML workspaces have ever been created in this subscription.\n", + "\n", + "If workspace creation fails for any reason other than already existing, please work with your IT administrator to provide you with the appropriate permissions or to provision the required resources.\n", + "\n", + "**Note:** Creation of a new workspace can take several minutes." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Import the Workspace class and check the Azure ML SDK version.\n", + "from azureml.core import Workspace\n", + "\n", + "ws = Workspace.create(name = workspace_name,\n", + " subscription_id = subscription_id,\n", + " resource_group = resource_group, \n", + " location = workspace_region,\n", + " exist_ok=True)\n", + "ws.get_details()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Configuring Your Local Environment\n", + "You can validate that you have access to the specified workspace and write a configuration file to the default configuration location, `./aml_config/config.json`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from azureml.core import Workspace\n", + "\n", + "ws = Workspace(workspace_name = workspace_name,\n", + " subscription_id = subscription_id,\n", + " resource_group = resource_group)\n", + "\n", + "# Persist the subscription id, resource group name, and workspace name in aml_config/config.json.\n", + "ws.write_config()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Create a Folder to Host Sample Projects\n", + "Finally, create a folder where all the sample projects will be hosted." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "\n", + "sample_projects_folder = './sample_projects'\n", + "\n", + "if not os.path.isdir(sample_projects_folder):\n", + " os.mkdir(sample_projects_folder)\n", + " \n", + "print('Sample projects will be created in {}.'.format(sample_projects_folder))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Create an Experiment\n", + "\n", + "As part of the setup you have already created an Azure ML `Workspace` object. For AutoML you will need to create an `Experiment` object, which is a named object in a `Workspace` used to run experiments." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import logging\n", + "import os\n", + "import random\n", + "import time\n", + "\n", + "from matplotlib import pyplot as plt\n", + "from matplotlib.pyplot import imshow\n", + "import numpy as np\n", + "import pandas as pd\n", + "\n", + "import azureml.core\n", + "from azureml.core.experiment import Experiment\n", + "from azureml.core.workspace import Workspace\n", + "from azureml.train.automl import AutoMLConfig\n", + "from azureml.train.automl.run import AutoMLRun" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Choose a name for the experiment and specify the project folder.\n", + "experiment_name = 'automl-local-classification'\n", + "project_folder = './sample_projects/automl-local-classification'\n", + "\n", + "experiment = Experiment(ws, experiment_name)\n", + "\n", + "output = {}\n", + "output['SDK version'] = azureml.core.VERSION\n", + "output['Subscription ID'] = ws.subscription_id\n", + "output['Workspace Name'] = ws.name\n", + "output['Resource Group'] = ws.resource_group\n", + "output['Location'] = ws.location\n", + "output['Project Directory'] = project_folder\n", + "output['Experiment Name'] = experiment.name\n", + "pd.set_option('display.max_colwidth', -1)\n", + "pd.DataFrame(data = output, index = ['']).T" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Diagnostics\n", + "\n", + "Opt-in diagnostics for better experience, quality, and security of future releases." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from azureml.telemetry import set_diagnostics_collection\n", + "set_diagnostics_collection(send_diagnostics = True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Load Training Data Using DataPrep" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import azureml.dataprep as dprep\n", + "# You can use `auto_read_file` which intelligently figures out delimiters and datatypes of a file.\n", + "# The data referenced here was pulled from `sklearn.datasets.load_digits()`.\n", + "simple_example_data_root = 'https://dprepdata.blob.core.windows.net/automl-notebook-data/'\n", + "X_train = dprep.auto_read_file(simple_example_data_root + 'X.csv').skip(1) # Remove the header row.\n", + "\n", + "# You can also use `read_csv` and `to_*` transformations to read (with overridable delimiter)\n", + "# and convert column types manually.\n", + "# Here we read a comma delimited file and convert all columns to integers.\n", + "y_train = dprep.read_csv(simple_example_data_root + 'y.csv').to_long(dprep.ColumnSelector(term='.*', use_regex = True))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Review the Data Preparation Result\n", + "You can peek the result of a Dataflow at any range using skip(i) and head(j). Doing so evaluates only j records for all the steps in the Dataflow, which makes it fast even against large datasets." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "X_train.skip(1).head(5)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Configure AutoML\n", + "\n", + "Instantiate an `AutoMLConfig` object to specify the settings and data used to run the experiment.\n", + "\n", + "|Property|Description|\n", + "|-|-|\n", + "|**task**|classification or regression|\n", + "|**primary_metric**|This is the metric that you want to optimize. Classification supports the following primary metrics:
accuracy
AUC_weighted
average_precision_score_weighted
norm_macro_recall
precision_score_weighted|\n", + "|**primary_metric**|This is the metric that you want to optimize. Regression supports the following primary metrics:
spearman_correlation
normalized_root_mean_squared_error
r2_score
normalized_mean_absolute_error|\n", + "|**iteration_timeout_minutes**|Time limit in minutes for each iteration.|\n", + "|**iterations**|Number of iterations. In each iteration AutoML trains a specific pipeline with the data.|\n", + "|**n_cross_validations**|Number of cross validation splits.|\n", + "|**spark_context**|Spark Context object. for Databricks, use spark_context=sc|\n", + "|**max_concurrent_iterations**|Maximum number of iterations to execute in parallel. This should be <= number of worker nodes in your Azure Databricks cluster.|\n", + "|**X**|(sparse) array-like, shape = [n_samples, n_features]|\n", + "|**y**|(sparse) array-like, shape = [n_samples, ], [n_samples, n_classes]
Multi-class targets. An indicator matrix turns on multilabel classification. This should be an array of integers.|\n", + "|**path**|Relative path to the project folder. AutoML stores configuration files for the experiment under this folder. You can specify a new empty folder.|\n", + "|**preprocess**|set this to True to enable pre-processing of data eg. string to numeric using one-hot encoding|\n", + "|**exit_score**|Target score for experiment. It is associated with the metric. eg. exit_score=0.995 will exit experiment after that|" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "automl_config = AutoMLConfig(task = 'classification',\n", + " debug_log = 'automl_errors.log',\n", + " primary_metric = 'AUC_weighted',\n", + " iteration_timeout_minutes = 10,\n", + " iterations = 5,\n", + " n_cross_validations = 2,\n", + " max_concurrent_iterations = 4, #change it based on number of worker nodes\n", + " verbosity = logging.INFO,\n", + " spark_context=sc, #databricks/spark related\n", + " X = X_train, \n", + " y = y_train,\n", + " enable_cache=False,\n", + " path = project_folder)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Train the Models\n", + "\n", + "Call the `submit` method on the experiment object and pass the run configuration. Execution of local runs is synchronous. Depending on the data and the number of iterations this can run for a while.\n", + "In this example, we specify `show_output = True` to print currently running iterations to the console." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "local_run = experiment.submit(automl_config, show_output = True) # for higher runs please use show_output=False and use the below" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Explore the Results" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Portal URL for Monitoring Runs\n", + "\n", + "The following will provide a link to the web interface to explore individual run details and status. In the future we might support output displayed in the notebook." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "displayHTML(\"Azure Portal: {}\".format(local_run.get_portal_url(), local_run.id))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The following will show the child runs and waits for the parent run to complete." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Retrieve All Child Runs after the experiment is completed (in portal)\n", + "You can also use SDK methods to fetch all the child runs and see individual metrics that we log." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "children = list(local_run.get_children())\n", + "metricslist = {}\n", + "for run in children:\n", + " properties = run.get_properties()\n", + " metrics = {k: v for k, v in run.get_metrics().items() if isinstance(v, float)} \n", + " metricslist[int(properties['iteration'])] = metrics\n", + "\n", + "rundata = pd.DataFrame(metricslist).sort_index(1)\n", + "rundata" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Retrieve the Best Model after the above run is complete \n", + "\n", + "Below we select the best pipeline from our iterations. The `get_output` method returns the best run and the fitted model. The Model includes the pipeline and any pre-processing. Overloads on `get_output` allow you to retrieve the best run and fitted model for *any* logged metric or for a particular *iteration*." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "best_run, fitted_model = local_run.get_output()\n", + "print(best_run)\n", + "print(fitted_model)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Best Model Based on Any Other Metric after the above run is complete based on the child run\n", + "Show the run and the model that has the smallest `log_loss` value:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "lookup_metric = \"log_loss\"\n", + "best_run, fitted_model = local_run.get_output(metric = lookup_metric)\n", + "print(best_run)\n", + "print(fitted_model)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Register the Fitted Model for Deployment\n", + "If neither metric nor iteration are specified in the register_model call, the iteration with the best primary metric is registered." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "description = 'AutoML Model'\n", + "tags = None\n", + "model = local_run.register_model(description = description, tags = tags)\n", + "local_run.model_id # This will be written to the scoring script file later in the notebook." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Create Scoring Script\n", + "Replace model_id with name of model from output of above register cell" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%%writefile score.py\n", + "import pickle\n", + "import json\n", + "import numpy\n", + "import azureml.train.automl\n", + "from sklearn.externals import joblib\n", + "from azureml.core.model import Model\n", + "\n", + "\n", + "def init():\n", + " global model\n", + " model_path = Model.get_model_path(model_name = '<>') # this name is model.id of model that we want to deploy\n", + " # deserialize the model file back into a sklearn model\n", + " model = joblib.load(model_path)\n", + "\n", + "def run(rawdata):\n", + " try:\n", + " data = json.loads(rawdata)['data']\n", + " data = numpy.array(data)\n", + " result = model.predict(data)\n", + " except Exception as e:\n", + " result = str(e)\n", + " return json.dumps({\"error\": result})\n", + " return json.dumps({\"result\":result.tolist()})" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Create a YAML File for the Environment" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from azureml.core.conda_dependencies import CondaDependencies\n", + "\n", + "myenv = CondaDependencies.create(conda_packages=['numpy','scikit-learn'], pip_packages=['azureml-sdk[automl]'])\n", + "\n", + "conda_env_file_name = 'mydeployenv.yml'\n", + "myenv.save_to_file('.', conda_env_file_name)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Create ACI config" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#deploy to ACI\n", + "from azureml.core.webservice import AciWebservice, Webservice\n", + "\n", + "myaci_config = AciWebservice.deploy_configuration(\n", + " cpu_cores = 2, \n", + " memory_gb = 2, \n", + " tags = {'name':'Databricks Azure ML ACI'}, \n", + " description = 'This is for ADB and AutoML example.')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Deploy the Image as a Web Service on Azure Container Instance\n", + "Replace servicename with any meaningful name of service" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "# this will take 10-15 minutes to finish\n", + "\n", + "service_name = \"<>\"\n", + "runtime = \"spark-py\" \n", + "driver_file = \"score.py\"\n", + "my_conda_file = \"mydeployenv.yml\"\n", + "\n", + "# image creation\n", + "from azureml.core.image import ContainerImage\n", + "myimage_config = ContainerImage.image_configuration(execution_script = driver_file, \n", + " runtime = runtime, \n", + " conda_file = 'mydeployenv.yml')\n", + "\n", + "# Webservice creation\n", + "myservice = Webservice.deploy_from_model(\n", + " workspace=ws, \n", + " name=service_name,\n", + " deployment_config = myaci_config,\n", + " models = [model],\n", + " image_config = myimage_config\n", + " )\n", + "\n", + "myservice.wait_for_deployment(show_output=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#for using the Web HTTP API \n", + "print(myservice.scoring_uri)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Test the Best Fitted Model\n", + "\n", + "#### Load Test Data - you can split the dataset beforehand & pass Train dataset to AutoML and use Test dataset to evaluate the best model." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn import datasets\n", + "digits = datasets.load_digits()\n", + "X_test = digits.data[:10, :]\n", + "y_test = digits.target[:10]\n", + "images = digits.images[:10]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Testing Our Best Fitted Model\n", + "We will try to predict digits and see how our model works. This is just an example to show you." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Randomly select digits and test.\n", + "for index in np.random.choice(len(y_test), 2, replace = False):\n", + " print(index)\n", + " predicted = fitted_model.predict(X_test[index:index + 1])[0]\n", + " label = y_test[index]\n", + " title = \"Label value = %d Predicted value = %d \" % (label, predicted)\n", + " fig = plt.figure(1, figsize = (3,3))\n", + " ax1 = fig.add_axes((0,0,.8,.8))\n", + " ax1.set_title(title)\n", + " plt.imshow(images[index], cmap = plt.cm.gray_r, interpolation = 'nearest')\n", + " display(fig)" + ] + } + ], + "metadata": { + "authors": [ + { + "name": "savitam" + }, + { + "name": "wamartin" + } + ], + "kernelspec": { + "display_name": "Python 3.6", + "language": "python", + "name": "python36" + }, + "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.7.0" + }, + "name": "auto-ml-classification-local-adb", + "notebookId": 3888835968049288 + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file