From 98ae76885f9eb2789976e2f0542b5c11134dac0c Mon Sep 17 00:00:00 2001 From: Oceane <oceane.fourquet@outlook.fr> Date: Tue, 7 Feb 2023 14:06:48 +0100 Subject: [PATCH] Updated version --- .DS_Store | Bin 6148 -> 6148 bytes Module/.DS_Store | Bin 6148 -> 6148 bytes .../cost_matrix_uncertainty.cpython-39.pyc | Bin 3810 -> 4824 bytes .../dynamic_preselection.cpython-39.pyc | Bin 0 -> 10739 bytes ...onic_regression_uncertainty.cpython-39.pyc | Bin 12799 -> 12839 bytes .../optimal_k_aggregations.cpython-39.pyc | Bin 4315 -> 4703 bytes .../__pycache__/preselection.cpython-39.pyc | Bin 2415 -> 2449 bytes .../selection_algorithm.cpython-39.pyc | Bin 5173 -> 5207 bytes .../show_results_4cases.cpython-39.pyc | Bin 8079 -> 10577 bytes Module/__pycache__/stages.cpython-39.pyc | Bin 2390 -> 2902 bytes Module/__pycache__/tools.cpython-39.pyc | Bin 4329 -> 4356 bytes Module/cost_matrix_uncertainty.py | 37 +- Module/dynamic_preselection.py | 491 ++++++++++++++++++ Module/optimal_k_aggregations.py | 2 +- Module/selection_algorithm.py | 6 +- Module/show_results_4cases.py | 33 +- Module/stages.py | 14 +- README.md | 106 +--- 18 files changed, 589 insertions(+), 100 deletions(-) create mode 100644 Module/__pycache__/dynamic_preselection.cpython-39.pyc create mode 100644 Module/dynamic_preselection.py diff --git a/.DS_Store b/.DS_Store index eddf048df7bdf3062d661508dc2c5d7649330bb9..2b9bae89bfec19fb150e5768c13485011dc026c1 100644 GIT binary patch delta 176 zcmZoMXfc=|#>B)qu~2NI-d)DY+$<hSJCX`=GK)(L46ZRUF|)9;v2(C<aC5{4XXKX$ zmn4>y7CTLDX7Tpn<lu}Kkf^RUHZ;^xFg7)-)lsOnG&0apFflf(t>xqpRo1r-iqFo; z&CBm%00Txw2+hC?rD0U}W@*+pOdA{cnKrX?@N)p&vssYiJM(0I5l0S?8lXOw%@HDN Fm;s)1B{l#6 delta 191 zcmZoMXfc=|#>B!ku~2NI-d)DU0xV3ExtTl+jwco5WEPhg7+hy$VrF4wW9Q)D;^5-t ziVe=lFApwBEGaE^N-T;7@d6S{GLj~jGI{%QaB^_Q3y4)$8|x?-n;F&WC{$Y-8R#gO z7@O7Ba&m~P8rpg$<W^Qy*VNWcX8;36MhMNo52az$jLkgEZ<sc-bMSKjowu2h<va6a Sei26wpn4{dn#~a+YnTBSk}6&R diff --git a/Module/.DS_Store b/Module/.DS_Store index 19b82036d32618a951840f33d2c93ee7eff892ee..60012d079a89867047f0d7d9fb7fc36de744b8e2 100755 GIT binary patch delta 121 zcmZoMXfc@J&&a(oU^g=(_hcTHUQKa^6oyKMJcdMuT!u`BWQKT#0)`@nREA<8&H>_N xh7zE7K11GQ0alSoY=V<#vb>Yz$D>G;RhEH)Vcz5#*6_`OY%3Tyvvd6A2LROf9Kiqp delta 53 zcmV-50LuS_FoZCWPXP+CP`d*G3X=>3jg#jD?voP+OaTv*U<MhJu>}*8)&vo=Uk0cF Lk$_IK2MGNS(hw1w diff --git a/Module/__pycache__/cost_matrix_uncertainty.cpython-39.pyc b/Module/__pycache__/cost_matrix_uncertainty.cpython-39.pyc index a217a1b2a57daeee20a7c2f30411d77c5736faac..a39af419af09ac84330c78ad6a8a94e5580258a5 100644 GIT binary patch delta 2621 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 delta 1685 zcmZ8iO>7%Q6yDiC@7ms7|Hg^qCJluaC*-GvO8gX5np7ZA)6%q3YCx9bS-W=a-OcP6 zHE7%v1(Z}GRohWd2+84ABo2rR;?gq`f@`%G5VxMWAtZR?lnA;jfBSyseedm?x8q08 z{eH-<Syo(v>)wggwb|5NyM%7uow=zgD^l6H`~AbI#reyjOTu}-;rGaT&z)cL>%Fe) z(Qy8v8}>Ss|9}?1yP_J%`4i1YaonmkJwK$aI{!OW<iE+&N6P3if(*n0D9e#Nw-6!k zffA`=ZAGEvc!kd@Mg1uF|B(12ZDuqhmL?)C3_2|uDJ_o@1xywGxw4S0r0ae+=ux*y z+<K3ME#Kp>>Ek?7N-Gu3@6l=yq18z5`q=G+l^AiGRhN*8vK9<st)h@>04l6g1LERg zWh4&?hz$@W!<N_VxFX0WCH|v+WO4@Vbrs;>s{n!tKT%dV$`i4Zn|+POwxqsJjkd`U zmYb*`VPzNHl4zVJn6`zs(314w*ZmmN+DR6}5|%!b8}gXcH<&iCSgeWmP~T)`+r}!~ z+OCWw>M+DiW-w(-?Z=rqNYONl(+t*uGronGT$HxtJ*B^yz%gumDzU_pw1xUfW?*wn zVo5BYlBhArvLujOI8JkrS}(wwg2b$99?Bir0clX!liH&V87FXZSH30PFxOYNr3S(l zuo?_X2UeSowTsL?;Ix6$!8UWM`OPOp&i{$}DH>y`_BaHmS$a^y@*aY>f==B+EDilw z=x4xx2uL!+USwHzzgyTDm#(RI5NYh7!34{QxI1XQu_Lvu9fWo0P-<5}5=0Aq^T4nz zZ6kP(^ndEk4eQPw)SZL6^Ekuu`|r<EEdNy5BW$ES2}v^8Zpx4<D^lIi*a&<Xx#h?? zf9^tc`SQ8yrMEAheRF9gGR@$s>-lseaQQdp1j_KA%tcEK@{_?QSzd}y>F)^3D39VL zUX7a?NrTR>#;15HZSvcRW5qErJdmRp^{bs$NF%N8_dNPQhWK9+6Gu;g`_hmDpknsC zx=U!S<vkXYSeD64!neS)$?hg-!~Daq@1(H53;;~8!Xr|M+ufghG4w?6Hia-MoZ4{q z%gT^0lGirK0+`E($++;!ei-RZm%83Zk=zX`>IL8LL~7j+HX;MNZXhJWO)Hn45R{W5 zNNsieI+^El)+CzY%hp07lD!~OyqZVm_-*SMRN&uQ6N-!*{AcSVpRp&=EBsyid6}Hz zpV%Y%i@*|I;$PY?AdNq=XHb=^&KV^0x12Ik__{OhsMln&!}NhpW7NPZ|H2tdXka@n zY*^zDo&5Xy^04P*R#Y}@&9F(L?PZgcg!K?Wq+WA3LZS)%;3bGIRM7)61yDBNl&MkD zx=vO>t?=p8vuK*1Pferi{NvOy<npglSI{i~E4BRk8zM^NE2Bt(R>1CLg$V<|o_qig zXa;UPwI}z*no+);K7MRYh${jP3IdX=A`p5X(*4LL|219Qya(3M0FY1|?h+zxkjuG9 zKj-6K$0ahT<gfrSIFaV{y0B;O30V(n9<GJttni)|7L~TTZe+G7%o=QUNW@V{7KO{{ z!k<7ZAb#Bq#kon&2v^<_C{9gM72pbJ^Lv@26Gae{D5)4||4t%9F*GA?6pXV*@gIm^ Bo5278 diff --git a/Module/__pycache__/dynamic_preselection.cpython-39.pyc b/Module/__pycache__/dynamic_preselection.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6e7a5d749d3ae53b8cb678e579961c50add26f61 GIT binary patch literal 10739 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 AKmY&$ literal 0 HcmV?d00001 diff --git a/Module/__pycache__/monotonic_regression_uncertainty.cpython-39.pyc b/Module/__pycache__/monotonic_regression_uncertainty.cpython-39.pyc index 0c149e50c32e14944c7ad6e4e464d285e645b056..261caf75a92252ad4805cf09d5d7d5d480095b10 100644 GIT binary patch delta 540 zcmXAlO=uHQ6oub;6Psk3X_{&p>rWbpVyn`q1-o+76zW2-2x?HI3^S7w+fJG{6Y1hj zrHr8KTsMkzQ5XJ!pd$)uRn&#lT@i&sSMJ=n5)=e|P4D8|cMj)%i}%mEXB(zr=uAy| zexLR1iSY|%w{+HXgjcFp>rK&UI;F9?)tq%)-z%NIVv3sS7Rsh;IihsN@tQNfH#s33 z&zW&7zgBlAC(N3Niu{&-brg*G%tnYHZu1~vYeCY7WRlxjj)i=TT{;=)Qj>Zg3p#x+ zAv;4Jq-09Qr<ph>Q$bwnfw6ffJEU%FJDF-G8u@mEi@Z$Q+6W7hDp9ZLn0Vf%Xwv9o z;W$?qE^bOga)nd7T{aqX?SzYm3aYX#sGDlL*p~A(xh;gv)%_|h7$>lcUK@{d>##&# zeU>=9DF>9SYc<!V#jZl~xN?jq5TpBDPq9K5(~I~>8|ioWL`&V*@Rf?0d2G;~%u9Ty z^F1y6q#r$N_)9C>R}rThJKo?Fjc4=drD}E-S^AP)!d~)vTPQ{yxo(cZDA!lfP>$yI zm>kQrmcNcibfJF=k<t<R(?5h)G*GDFcGM~?aJ-K)#R|vo=<@zb45Rd6a2f91>Oo*Q enmV*wLn{i0hJm;AqVxctBlAcTI7Z)&4*UmF$f7a; delta 530 zcmXw#OK4L;6o%)_q<P+{Nt-mLwlS@U^+B$Ug1GQqL9l`pgt%}~b0d^A37OmrF6LU~ z3gV`koK1@$_`srqXl7SRQG^z{62VOogn}#4od_z_@fK%s=KMb&-{LG-n<YNUd6ejf zh2qt@*Zc<zjhmO6WzjV2*XoXFIAwFJUUI7Cn%y)f%1vk5R%hvabmlk^ViOBIa6=Y# z!!}4Fsm0R7qhsXCIX5DijAV!#wW$Od^{5+@F&U~5F(G4aNJd=4VlJ0K8L`-QqRDWh z-zTW(m)v4Uh|6`Ow@N^Cd<&CCM*Fqp3>EjJA*t5s--nIHwBJziR7-WYC9N5L3T!2t z$u18pTA^YEpYUVQha3E5T4ePN#DRZfj~?r6s%EW22^YF^p~Jc$G>q@NJFtY_wwv${ zyW($P6<6Z7;3J+-T<4!O(xg5pE@L7-h~E+|*ua^dHhjmP-Vg8_zx1v_5ML#i;R4oE zSxDh*stQT`lX?IHc)za=!z!PSQy5VvGDQZb)!e`&g@^bndpr1CpIaocl|6~8JBNdv z|FM8WxjZc5#oQFktHs<63UAfXT}28%ReN_a0H^Tl-bYY<Ji8B|pziM9!JwsH<PQNX T<7e|3tf@N(9e`2X93A-!;r^RH diff --git a/Module/__pycache__/optimal_k_aggregations.cpython-39.pyc b/Module/__pycache__/optimal_k_aggregations.cpython-39.pyc index 6e6a22c8bb46763329272e0b152ec47e7ee05a9b..278c9521ba1737d10a989dc280157324a77ae69f 100644 GIT binary patch delta 1243 zcmah}&5ImG6t7p^J=4?EJ>P3))|hP8AeoR469sP~*^L*)1VcQ?#<4TiJIv1KR+oZF zwL_T5&I*Br^5C&Y@Zv#`fG5xX2ZD@(|AF99@Zfv1BkCg9P5=76SHF7i)vv1ir*prY z55geu7+$~bo^Sv7O;F(=%m!b-aO=ZRcEjPuRyb@&^6J}B{6SyEt=lq+qkhy@-O;dh zJM7A*ukn4J&8SdzBK7n;`wMHrImkPhvh7mh)m6uL4j&7j_#$UaF##!PYYtNYCb+O3 zGsT6iGgH3Jrf>*~D@&s_g>7~O_kK=XWvBL>B{}8jtZ=40@wAs_L<aM?bC_cu^e5Rl zLxb(P+7(Q&Pxvlxuq3Zpn$vCvX^F4>Jx^rucAs!yDxYFRgXY+dodhS+=T?cAd666F zU=D{&JHqSnBak;#VaC$poSNnbY;u4FMPB%iT@07zj8>BrbU_3S)`6s`%2+I~i&Spv z?C_+NlyzAYdKM<TJ_F%3SXxn4ofpLh)1^Ajrxu1TYE~k(sPro=aTM3iv0nE+ODZdM zCRJ6#0>O;w3YM^^nH?*sC2PqutHNvlS@^3N=*s^UKA}t*g<qA`)jFGVYV#f3gQZkQ zu>a<X36&I%yVN<P|FvUF_WqRv*acC=bKw5HE>!N6K6QsRYvz*o2yU9MJ;`Opgh9=G zAH39Ta!IF5RuIr$$JfGE(O@jI6!r-Mgb*h-3;k}a+M~hvRS6g~8~JaaZ^FXqwFcez z9~184;3Jw@KxnR+-}B=a7S^CUl$SBEuzS%*@$!VrHS(?Sek?bMS~nB_wA~%HdggQg z;u{MKzZUs2j>s({I%7GyAIfLR=ITXxjz(^gXNUdHXp!x;A}L35*-Fz|u13B`q<769 z{+Y}TG~>6-MzDF!^0*Im@T?kmaGJZ^wF=;3q{feZ57xm)n>ckYAEIJu;{oN$6Z~79 zL$h9JzApD@gqA3K2q@>0PxdiilSPs)a-*^84#Iw`cYto3L0~`)$;5nG_yKz6{o*z} zFkcq0KKFzev_A|g*rJaO(`{pWa%O%jR?l>BOwx}*UL&v(7Ca86Ltbb$OV?q?+%26w c`!NMbX}L{6KN<OuAR(9;Q`&OM?oBuIC*WQeUjP6A delta 909 zcmZ8e&rcIU6rMM`-QDi5c3U7V5D_HN#wg0sc)})}j7DOD3c;2wq_j|&-D1Gmps6S% znh@s?aO;7@qapEs(1SM*t_Ls1|H8yKfQrmyzIorwd*6F+=KJWkVW;9aCcz=br>h^| zJ2?sy;w<gg?$m;IGd!r$HENlDy|TE{3c~vQL887@MpX)I3WMf#8G1bWa8Kh>a0UAy zVq;({)uCn5fn5^PP~m8GpiK5)b~@5SHCDSMGQt$seDsUbJRNJk76aG2&;=mK^)A7k zEE!z)iBGoa0xgor<RngWeG$DPi(5;kuj4dcQ6Qle+uY*7DObAcR%D-&PoES<XNTJ; z;)K*!`C+lMuOs)kv`pxtl+7LPqMX{%W|Sx!c~LIR;JL{?nWU4Np;12S;XS_DQ1*ab z*dg34k~kZBe9QE$BH{T0b}kdI7$NcP4qB(ma<J>;v^-NFU3#+2wNIzK-58Ea<Ocfw z_f~6{UyudxGrsc72x;z5R~?9YdG8b{WyNRnDNKsn784Eo!?|~GKh>C9t_MthC9@^m zMR+0&7on6BWoNaIjmQJ}=d2eYQ7YA-)F%>WQ2cVvUt|69W<cK1@CqB2?3QF|rMcK* zH>8<bWvyx@(HnC$##-zs;jC!6XS6cj2iJvgM~1R47*K#7YQi8j5c|PIEP$yLC|egl z-MHA6@|J{uMLS4$#G6cMGEtW6E9?^TL~YbIf)Zti0ULh<9!X2KnxtE+VSTyMoNGKs z8fXXvY|O?sg`52X8{$W{3~f>J#^9y6=MD63qerQjXg6DayIErtDO(V`-XJ^_``$P_ n5MRBa(Z}-m@X2IrNAI>StxXA1gX!X`l^0{Vi>bUZVQ9YrGLX?m diff --git a/Module/__pycache__/preselection.cpython-39.pyc b/Module/__pycache__/preselection.cpython-39.pyc index 335c7d27405aec0aade12dd43f1cd38612ce4370..4d41e46b2dd3c60aedce8685c63e36ef57eb1c95 100644 GIT binary patch delta 127 zcmaDaG*Os0k(ZZ?0SKmcTuchs$m_w#ST#9}QH$HJmbrwvhB<{voMCc1qrHe%p-rJ$ z4O1|KCad2qwvxo6^wg5c_ZX`gqb5f&Non|(B^G5S<|#NQ<|U^V=?A42m*$id#|IRp e7N_Q<CYNO9=fwvkW)@AZVzOrx+q{cuD;oeLhA0LA delta 93 zcmbOz{9cGRk(ZZ?0SG1=MI?o7<n>@=ESnt0sKxG8%Ur@-!#ug0(O$x>(4tVShAEgq wlhyAQS4w7LdR~5UNoMlodyLhL7L%ixq}YN|i%WA#CeLBAXB66ehiNMt0F3S%I{*Lx diff --git a/Module/__pycache__/selection_algorithm.cpython-39.pyc b/Module/__pycache__/selection_algorithm.cpython-39.pyc index 79170c5987605a38fd82c88271acc26b149a7405..a0551de01deefc715028220dfa8fa706bcebaef8 100644 GIT binary patch delta 111 zcmdn0ab1Hak(ZZ?0SLNJhbM33xx?t3s2^IKT2!o`pO#-*R9Kp-?~<Qfnwy$eQmpS^ zmROXTn5W>Jn3tSdq#u-8T$)o-93N1WTAZ4bnp~2ZpBEpHm|3)$lgW&U)yLo8Ic&2F NO9Ve-)a1FsGXPp?CR_jj delta 77 zcmcbvu~ma7k(ZZ?0SG1=MI>$Hxx=VvuOC{RT2!o`pO#-*R9Kp-?~<Qfnwy$eQmh}8 gT3nh_vRRwSjEOb1s3^Z^a~ewoKjW>*`-Nu!0I+fy{{R30 diff --git a/Module/__pycache__/show_results_4cases.cpython-39.pyc b/Module/__pycache__/show_results_4cases.cpython-39.pyc index b60c307a3f8c7658a1ad25c34c2e454dc7179053..2b9b125d99e0defa046427be9eb4e541495beb70 100644 GIT binary patch delta 4151 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 KK4zXb%zpvuuTpgY delta 1683 zcmbu9TTdHD6vuaV*Txs@*ap|eU~Cg(yu^t@M0!o2RTEM|0}ZJvN-qR5Zd1j?>DVSA zSwhw3_S6!MS|y59;kWvwQp8iF-aZ0->`HwoFD+F+L7sa4(?Xpp;U#PDZ_k{aIdk?u zXXfY0FNTA&fq+k=>)h!2+;0bN2fNtH?LDUtM!1K2ud(S6Z{t4hCo9a`c`FZ)72#1H z<h#gf;~^ftrcJkV<CJDSbARI~W0uV8SvO)n9Fdc{CBM>t@uMjMKv-Tj`qO=6o@pU$ zUAxKf)BP&lmG4aXS9(+i%r{xr+MKy;uyMK3(qFPObyjCgvt3-Pu@zH%TQyg^Y?s{< z(|9bV*&cevV;cHYlhmt&+KJEfr5?LywVQXYcG@krUe{HOEsw`Gwmqr3#<Y*`P}H=% z>KSHx<qw|S%qurM1+sT}bJ0P{&oM-i3uN!Oib9lyJnkK6%ZM0xL>zAOTye1?qVjWZ z!QBCGLjL4kmLtC2P!`P`kOI>3iZ8`7@}6&@T^uHl!#)s7Erqb`^WP1HbRSFTK^CE( zPZyWg*8Tg<K`+K11Y8757tl}CfTjRwMhG`yw8_DcwVa1(0sX)pfB^+yAFv<51P%Rn zqPoOodWZqw0D!4C|1ikfi{`VybHMY!3&0^@2p9%l240afS<i%(_)ji@MHf-v2yhe_ z0geH$0sp87YZQ1LFo6@mgxnX7pL!eSH1G~E1-uKqM`(13|4WZo?*lWyEHDRTfHMG> zzs8OysxXzV7hyGtEA`0NY-z0?*)*Q0s$+~57aRH}7D;>pJgTr*gzr&V#TEE=l+|G$ z(vrW3eyB;ohU6RB*jtUx$LZ?0E{KoLSD#AWsU79Dl1g63DA%gZ<&D&yQsc4sD!VS% z{mHdI({7{q#Ol3@xt0MXu&PJ3M|KwYu_a4d#tWY!mJKv5IW?VDrRGefxKI?umuTx$ z&dbC8w0w}AWH)4M@Am`S1GcthlEyWd=-!SNhJ}s!C5@+z`LH)f2Tdl|5$nU7F(3h4 zB3MDuEl=i>6RJ{AlgBYHl*=W@T$n9Ya2{10CjLE9Fi0IRs@_#5YV%`8r?qmnd~t^Q z*Gkojlt1R8JuBq5^zm_vZT+K;`$U=7N=2a~Sf`xNC)h1{E1zOV<Tv@$$q9rq=Vz;D qg&RFo%1Bf!0oQ>W0Ae?(r;<^5cn;008HVWVwMs%3tb{S`oBA6iNkCHo diff --git a/Module/__pycache__/stages.cpython-39.pyc b/Module/__pycache__/stages.cpython-39.pyc index f1b1d8b631f5a1ddbd8bdaa280656de911f2e391..8619cd1ba1731d59207ef468dfe6812fdfd0bbfc 100644 GIT binary patch literal 2902 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 P&m(X~PS6Mfe4qRmyH^3x delta 1449 zcmZuxTaVl{6t<mAZj;O<bJ>}l3M~(%46G2HQmI0eixwVMDivyZfM`*ajWeTkvy;Kj zR+Ks#p`{WpAXed#hlvC~gTK*-Jn=jF#Bo}+%YZF^w$H^r=lC2y9X@qif#X;RS~2_T z*f%d)SMYBaZ+~%Udk#fZPg<vKuY*y&?s{FAjl@0ec|D++)cO&5ecGfp%meDs7R*E1 zrX84fsD2+!yBB}|;@+L&%3*2f2WO$r!<0qEU-);e4c9)K6+YS3?nV48$%>Nn)*8=( zMf7e5nB0(-VH+DTSQplzE-5dXwA+Mn0E6!XWN3p05?CmrAyh$xR_eJ9R3h{eACcV1 zO<@RqPVOTnHK$6Yq$h#bKk-jv&ch_&#WQ92mc^RDt&}j~UgI?Q&Oc$cBs6%&f~;!H z&z50UDM`90K2b+&=?JSqT3zY22mbXjY`6x1@DR5!8^J29U6M3t6BsWY_ybD^&QWgE zXx3<DI3og`<8%Be`W1g;<xPPeD541ufu4{#8Kc}@3$#&1bAd~oJHmO;pcp#&nP8M@ zLZ`|($y=he(W$yIM6(1rj9_n;2qdgcQ#cSaRWwR9Z^PaeZ8)j3rQ7(Ima}PrR$Fu+ z%4-z@tsN<OH+S=1=4{%)vV~h8*?_S3^TF0(8W_?SgOXf6R2Z91))h9@$4K-?;C0P4 zHyx0aCR?zoxpMdIYas7Zqr__nk#UYEC?96MO<$P85=yD$JJ|qMCU`#r`cUi$t0eh& z%M=q#k-TxKTs8(YKwg+70mrP|%y*wl%@xRM>+Y9RQmK@st4fcHC)!8vcovO=#WLkt z95Q%H^!+#p!`qMZ{XNL~dOkSZyS?`~-?OHpVxo`nxVWj`!*21DerN5OFKdIz6!Cgt zx}3)}T85DyFSCd}3=*#gc?UVl<9QrWf0Y7*PbYP<vL0x$9jR)_qvmlE)k(_+lF^q8 z6%v+LTEtk&xTmdHdK|z$36AY3;T4Xd8qPAW_`$dmRgF~;GhV4dvPdg+#Uko8YK=+( z$2<it@l=4BM-C1>2P}(N7Q{<`mGS4r@Slp9?SU2iV*rFT*^7yJt=~~xs16I;#KL`S z5Ervs#gX}FeHG-`8vvD-rGCgCvTKs!N_Z1s+T8Md%U^a~O3ozQkno;_n-c!NU~k+3 z9<P5x+`-mWuxS^w_klPaRodq%J%f-Esb5>B$dy|>vR=nl@u&6K*Ye%!U#hNjc1v!h l_ND7yg~a&av_9}dnJau3z=lumMJMvZGZb4fOhY&J{{d)KOyU3l diff --git a/Module/__pycache__/tools.cpython-39.pyc b/Module/__pycache__/tools.cpython-39.pyc index 03b72c0092087876efdff4564d67f0237de44159..3335ebb09460a99f00dcbc32116d144a20c70a59 100644 GIT binary patch delta 59 zcmaE<*rLRf$ji&c00d`FhbM33(PCr_o@~yjDHW7jT$)o-93N1WTAZ4bnp~2ZpBEpH Nm|0Z3Ii9hL9{>rU6D0ru delta 32 mcmZosda1~h$ji&c00iy4dy+QtXfZNcOg3lK++5Ar$qxX2MF-FT diff --git a/Module/cost_matrix_uncertainty.py b/Module/cost_matrix_uncertainty.py index 9ef4090..a04024b 100755 --- a/Module/cost_matrix_uncertainty.py +++ b/Module/cost_matrix_uncertainty.py @@ -10,7 +10,7 @@ from itertools import chain import copy -import multiprocessing as mp +import multiprocess as mp ### Useful functions for parallele @@ -22,6 +22,23 @@ def vals_mp(pairs, df_2, out, funct): return vals + +def monotonic_model_RE(p, df): + p1, p2, key = p.split('/') + key = int(key) + rev, up = tools.equiv_key_case(key) + tr1 = df[p1].values.tolist() + tr2 = df[p2].values.tolist() + diag = df['target'].values.tolist() + data = [((tr1[n], tr2[n] ), 1, diag[n]) for n in range(len(diag))] + X, m = mru.compute_recursion(data, (rev, up, key)) + reg, bpr, bpb, pr, pb = m[key] + return (reg, p) + + + + + #### ERROR MATRIX ###### @@ -79,6 +96,16 @@ def error_matrix(df_, pairs, nbcpus, funct): del df_2 + vals_re = [(c, df) for c in pairs] + res_re = pool.starmap(monotonic_model_RE, vals_re, max(1,len(vals)//nbcpus)) + + REd = {re[1] : re[0] for re in res_re} + REd['target'] = np.nan + re_s = pd.Series(REd) + re_s.name = 'RE' + + mat_err_re = pd.concat((mat_err,re_s.to_frame().T), axis=0) + unc = {col: mat_err[col].to_list().count(-1) for col in pairs} @@ -86,7 +113,7 @@ def error_matrix(df_, pairs, nbcpus, funct): unc_s = pd.Series(unc) unc_s.name = 'uncertain' - mat_err_unc = pd.concat((mat_err,unc_s.to_frame().T), axis=0) + mat_err_unc = pd.concat((mat_err_re,unc_s.to_frame().T), axis=0) @@ -103,12 +130,12 @@ def error_matrix(df_, pairs, nbcpus, funct): err = {col: mat_err[col].to_list().count(1)/(mat_err[col].to_list().count(1) + mat_err[col].to_list().count(0)) for col in pairs if col not in rem} err['target'] = np.nan err_s = pd.Series(err) - err_s.name = 'error' + err_s.name = 'LOOCV' mat_err_final = pd.concat((mat_err_unc,err_s.to_frame().T), axis=0) - mat_err_final.sort_values(axis = 1, by=['error', 'uncertain'], inplace=True) + mat_err_final.sort_values(axis = 1, by=['LOOCV', 'RE', 'uncertain'], inplace=True) del df return mat_err_final @@ -146,5 +173,5 @@ def error_to_prediction(matrix, df): def cost_classifiers(ndf): cols = list(ndf.columns) cols.remove('target') - cost = {cols[i] : ndf[cols[i]].loc[['error']][0] for i in range(len(cols))} + cost = {cols[i] : ndf[cols[i]].loc[['LOOCV']][0] for i in range(len(cols))} return cost diff --git a/Module/dynamic_preselection.py b/Module/dynamic_preselection.py new file mode 100644 index 0000000..6c71fd6 --- /dev/null +++ b/Module/dynamic_preselection.py @@ -0,0 +1,491 @@ +import pandas as pd +import numpy as np +from random import shuffle +import pandas as pd +from Module import monotonic_regression_uncertainty as mru +from Module import tools +import heapq as hq +from copy import deepcopy + +import multiprocessing as mp + +import time + +def monotonic_model_RE(p, df): + p1, p2, key = p.split('/') + key = int(key) + rev, up = tools.equiv_key_case(key) + tr1 = df[p1].values.tolist() + tr2 = df[p2].values.tolist() + diag = df['target'].values.tolist() + data = [((tr1[n], tr2[n] ), 1, diag[n]) for n in range(len(diag))] + X, m = mru.compute_recursion(data, (rev, up, key)) + reg, bpr, bpb, pr, pb = m[key] + return (reg, p) + + +def H_df(df, cls, nbcpus): + pool = mp.Pool(nbcpus) + vals = [(c, df) for c in cls] + res = pool.starmap(monotonic_model_RE, vals, max(1,len(vals)//nbcpus)) + #f = open('logs_H_df.txt', 'a') + #f.write('H d_f {} \n'.format(res)) + #f.close() + return sorted(res) + + +def monotonic_model_LOOCV(p, df, maxi): + p1, p2, key = p.split('/') + key = int(key) + rev, up = tools.equiv_key_case(key) + tr1 = df[p1].values.tolist() + tr2 = df[p2].values.tolist() + diag = df['target'].values.tolist() + data = [((tr1[n], tr2[n] ), 1, diag[n]) for n in range(len(diag))] + + err = 0 + + + for d in data: + data_bis = deepcopy(data) + data_bis.remove(d) + X, m = mru.compute_recursion(data_bis, (rev, up, key)) + + + target = d[2] + out = d[0] + + reg, bpr, bpb, rps, bps = m[key] + pred = mru.predict_severe(out, bpr, bpb, rev, up) + + err += abs(target-pred) + if err > maxi: + return (maxi+1, p) + + return (err, p) + + +def Q_df(df, cls, nbcpus, maxi): + pool = mp.Pool(nbcpus) + vals = [(c, df, maxi) for c in cls] + return sorted(pool.starmap(monotonic_model_LOOCV, vals, max(1,len(vals)//nbcpus))) + + +def heapify(arr, n, i): + # Find the largest among root, left child and right child + largest = i + l = 2 * i + 1 + r = 2 * i + 2 + + if l < n and arr[i][0] < arr[l][0]: + largest = l + + if r < n and arr[largest][0] < arr[r][0]: + largest = r + + # Swap and continue heapifying if root is not largest + if largest != i: + arr[i], arr[largest] = arr[largest], arr[i] + heapify(arr, n, largest) + + +# Function to insert an element into the tree +def insert(array, newNum): + size = len(array)+1 + if size == 0: + array.append(newNum) + else: + array.append(newNum) + for i in range((size // 2) - 1, -1, -1): + heapify(array, size, i) + + +# Function to delete an element from the tree +def deleteNode(array, num): + size = len(array) + i = 0 + for i in range(0, size): + if num == array[i][0]: + break + + #print('array 1', array) + array[i], array[size - 1] = array[size - 1], array[i] + #print('array 2', array) + array.remove(array[size - 1]) + #print('array 3', array) + + for i in range((len(array) // 2) - 1, -1, -1): + heapify(array, len(array), i) + + +def deleteNodeNum(array, num): + size = len(array) + i = 0 + for i in range(0, size): + if num == array[i][0]: + break + + array[i], array[size - 1] = array[size - 1], array[i] + array.remove(array[size - 1]) + for i in range((len(array) // 2) - 1, -1, -1): + heapify(array, len(array), i) + +def deleteNodeName(array, name): + size = len(array) + i = 0 + for i in range(0, size): + if name == array[i][1]: + break + + array[i], array[size - 1] = array[size - 1], array[i] + array.remove(array[size - 1]) + + for i in range((len(array) // 2) - 1, -1, -1): + heapify(array, len(array), i) + + + +def keepPairs(Q, pair, q): + g1, g2, g3 = pair.split('/') + r1 = lookGene(Q, g1) + r2 = lookGene(Q, g2) + + f1 = True + f2 = True + + pairs = list() + + if r1[0]: + if q >= r1[1][0]: + f1 = False + pairs.append(r1[1]) + + if r2[0]: + if q >= r2[1][0]: + f2 = False + pairs.append(r2[1]) + + if f1 and f2: + return True, pairs + else: + return False, pairs + +def lookGene(Q, gene): + flag = False + pair_with_gene = None + for el in Q: + p1, p2, p3 = el[1].split('/') + if gene == p1 or gene == p2: + flag = True + pair_with_gene = el + break + return flag, pair_with_gene + + +def suppH(H, num): + j = 0 + while H[j][0] < num: + j+=1 + return H[:j] + + + + +def nb_de_genes(G): + s = set() + for k in G.keys(): + s = s.union(G[k]) + return len(s) + + +def H_dict(H): + Hd = dict() + for h in H: + kh = h[0] + if kh not in Hd.keys(): + Hd[kh] = list() + Hd[kh].append(h[1]) + return Hd + + +def Q_dict(Q): + Qd = dict() + G = dict() + for q in Q: + kq = q[0] + g1, g2, g3 = q[1].split('/') + if kq not in Qd.keys(): + Qd[kq] = set() + if kq not in G.keys(): + G[kq] = set() + Qd[kq].add(q[1]) + G[kq].add(g1) + G[kq].add(g2) + + + return Qd, G + +def update_dict(G, G_): + for key in G_.keys(): + if key not in G.keys(): + G[key] = G_[key] + else: + G[key] = G[key].union(G_[key]) + return G + + +def supp_H_above_a(H, a): + S = [k for k in H.keys() if k > a] + for s in S: + del H[s] + return H + +def supp_H_below_a(H, a): + S = [k for k in H.keys() if k <= a] + for s in S: + del H[s] + return H + + +def check_disjoint_pairs(Q, param): + dis_p = list() + genes = list() + + flag = False + for k in sorted(Q.keys()): + pairs = Q[k] + for p in pairs: + g1, g2, g3 = p.split('/') + if g1 not in genes and g2 not in genes: + dis_p.append(p) + genes.append(g1) + genes.append(g2) + if len(dis_p) >= param: + flag = True + break + print('Pairs with {} genes'.format(len(genes))) + return flag + +### Preselection based on the number of genes +def algorithm_1(cls, df, k, nbcpus, logs): + + t0 = time.time() + H = H_df(df, cls, nbcpus) + t1 = time.time() + + f = open(logs, 'a') + f.write('H computed in {} en len(H) = {}\n\n'.format(t1 - t0, len(H))) + f.close() + + + Hd = H_dict(H) + + Q = dict() #For each strat of LOOCV, we have a list of pairs + G = dict() #List of genes in Q + + count = 0 + + + + t2 = time.time() + + + for h_key in sorted(Hd.keys()): + + pairs = Hd[h_key] + Q_ = Q_df(df, pairs, nbcpus, max(Hd.keys())) + Qd, Gd = Q_dict(Q_) + + + G = update_dict(G, Gd) + Q = update_dict(Q, Qd) + + + if nb_de_genes(G) >=k: + break + + + f = open(logs, 'a') + f.write('Old G {}\n\n'.format(G.keys())) + f.close() + + a = max(Q.keys()) + G_ = deepcopy(G) + del G_[a] + while nb_de_genes(G) > k and nb_de_genes(G_) >= k: + G = G_ + del Q[a] + a = max(Q.keys()) + G_ = deepcopy(G) + del G_[a] + + f = open(logs, 'a') + f.write('New G {}\n\n'.format(G.keys())) + f.close() + + + + a = max(Q.keys()) #Highest value of LOOCV in Q + Hd = supp_H_above_a(Hd, a) + Hd = supp_H_below_a(Hd, h_key) + + + t3 = time.time() + f = open(logs, 'a') + f.write('S1 computed in {} and size pairs={}\n\n'.format(t3 - t2, Hd.keys())) + f.close() + f = open(logs, 'a') + f.write('G {}\n\n'.format(G.keys())) + f.close() + + + t4 = time.time() + + + for h_key in sorted(Hd.keys()): + f = open(logs, 'a') + f.write('H_key {}\n\n'.format(h_key)) + f.close() + a = max(Q.keys()) + if h_key <= a: + + pairs = Hd[h_key] + Q_ = Q_df(df, pairs, nbcpus, a) + Qd, Gd = Q_dict(Q_) + + Qd = supp_H_above_a(Qd, a) + + + + Gd = supp_H_above_a(Gd, a) + + + + G = update_dict(G, Gd) + Q = update_dict(Q, Qd) + + f = open(logs, 'a') + f.write('Old G {}\n\n'.format(G.keys())) + f.close() + + G_ = deepcopy(G) + del G_[a] + while nb_de_genes(G) > k and nb_de_genes(G_) >= k: + G = G_ + del Q[a] + a = max(Q.keys()) + G_ = deepcopy(G) + del G_[a] + + f = open(logs, 'a') + f.write('New G {}\n\n'.format(G.keys())) + f.close() + pairs = list() + for key in Q.keys(): + pairs += Q[key] + + + t5 = time.time() + f = open(logs, 'a') + f.write('S2 computed in {} and size pairs={}\n\n'.format(t5 - t4, len(pairs))) + f.close() + + return Q, pairs + + + + +## Preselection based on the number of pairs + +def algorithm_2(cls, df, m, nbcpus, logs): + + t0 = time.process_time() + H = H_df(df, cls, nbcpus) + t1 = time.process_time() + + f = open(logs, 'a') + f.write('H computed in {} en len(H) = {}\n\n'.format(t1 - t0, len(H))) + f.close() + + + Hd = H_dict(H) + + Q = dict() #For each strat of LOOCV, we have a list of pairs + + + count = 0 + + + t2 = time.process_time() + + + for h_key in sorted(Hd.keys()): + + pairs = Hd[h_key] + Q_ = Q_df(df, pairs, nbcpus, max(Hd.keys())) + Qd, Gd = Q_dict(Q_) + + Q = update_dict(Q, Qd) + + + if check_disjoint_pairs(Q, m): + break + + + a = max(Q.keys()) #Highest value of LOOCV in Q + Hd = supp_H_above_a(Hd, a) + Hd = supp_H_below_a(Hd, h_key) + + + t3 = time.process_time() + f = open(logs, 'a') + f.write('S1 computed in {}, H size pairs={}, Q size pairs = {}\n\n'.format(t3 - t2, Hd.keys(), Q.keys())) + f.close() + + t4 = time.process_time() + + for h_key in sorted(Hd.keys()): + a = max(Q.keys()) + if h_key <= a: + + pairs = Hd[h_key] + Q_ = Q_df(df, pairs, nbcpus, a) + Qd, Gd = Q_dict(Q_) + + Qd = supp_H_above_a(Qd, a) + + Q = update_dict(Q, Qd) + + Q_ = deepcopy(Q) + del Q_[a] + + while check_disjoint_pairs(Q_, m): + + Q = Q_ + a = max(Q.keys()) + + Q_ = deepcopy(Q) + del Q_[a] + + pairs = list() + for key in Q.keys(): + pairs += Q[key] + + t5 = time.process_time() + f = open(logs, 'a') + f.write('S2 computed in {} and size pairs={}\n\n'.format(t5 - t4, len(pairs))) + f.close() + + return Q, pairs + + +def all_configurations(df): + transcripts = list(df.columns) + transcripts.remove('target') + + configurations = list() + for i in range(len(transcripts)): + for j in range(i+1, len(transcripts)): + for key in range(1,5): + configurations.append('/'.join([transcripts[i], transcripts[j], str(key)])) + return configurations diff --git a/Module/optimal_k_aggregations.py b/Module/optimal_k_aggregations.py index fe0c450..a0ca582 100755 --- a/Module/optimal_k_aggregations.py +++ b/Module/optimal_k_aggregations.py @@ -66,7 +66,7 @@ def create_and_predict_metamodel(df_, out, pairs, nbcpus, funct): def k_missclassification(df, cls, nbcpus, funct, strat, min_k, max_k, log): print('k misclassification : {}\n'.format(funct)) - k_mis = {k : list() for k in range(3, max_k)} #Store for each value of k, whereas patients were misclassified or not with an ensemble of k classifiers + k_mis = {k : list() for k in range(min_k, max_k)} #Store for each value of k, whereas patients were misclassified or not with an ensemble of k classifiers #pairs_err = {cl : list() for cl in cls} #For each classifiers we are going to store the average misclassification error (computed with LOOCV) made with each patients diff --git a/Module/selection_algorithm.py b/Module/selection_algorithm.py index 8471605..0dce58c 100755 --- a/Module/selection_algorithm.py +++ b/Module/selection_algorithm.py @@ -43,7 +43,7 @@ def filter_pairs_adapt(pairs, cl): def NB(df, ndf_, cost, k, nbcpus, mes = ms.MVE): ndf = copy.deepcopy(ndf_) - ndf.drop(['uncertain', 'error'], inplace=True) + ndf.drop(['uncertain', 'LOOCV'], inplace=True) pairs = sorted(cost.items(), key=lambda t: t[1]) pairs = [pairs[i][0] for i in range(len(pairs))] @@ -73,7 +73,7 @@ def FS(df, ndf_, cost, k, nbcpus, mes = ms.MVE, jump = 30): pool = mp.Pool(nbcpus) ndf = copy.deepcopy(ndf_) - ndf.drop(['uncertain', 'error'], inplace=True) + ndf.drop(['uncertain', 'LOOCV'], inplace=True) temp = min(cost.values()) res = [key for key in cost.keys() if cost[key] == temp] #Many classifiers can have the lowest error @@ -134,7 +134,7 @@ def BS(df, ndf_, cost, k, nbcpus, mes = ms.F2, end = 30): pool = mp.Pool(nbcpus) ndf = copy.deepcopy(ndf_) - ndf.drop(['uncertain', 'error'], inplace=True) + ndf.drop(['uncertain', 'LOOCV'], inplace=True) pairs = sorted(cost.items(), key=lambda t: t[1]) diff --git a/Module/show_results_4cases.py b/Module/show_results_4cases.py index f83fc86..25d9795 100755 --- a/Module/show_results_4cases.py +++ b/Module/show_results_4cases.py @@ -76,13 +76,13 @@ def print_model(data, models, p1, p2, df1, pathname = None, cm=None): for bp in bpb: x, y = bp if key == 1: - ax.add_artist(patches.Rectangle((min_x, min_y), abs(x-min_x), abs(y-min_y), facecolor = 'lightskyblue', zorder = 1)) + ax.add_artist(patches.Rectangle((min_x, min_y), abs(x-min_x), abs(y-min_y), facecolor = 'lightsteelblue', zorder = 1)) elif key == 2: - ax.add_artist(patches.Rectangle((x, min_y), max_x+abs(x), abs(y-min_y), facecolor = 'lightskyblue', zorder = 1)) + ax.add_artist(patches.Rectangle((x, min_y), max_x+abs(x), abs(y-min_y), facecolor = 'lightsteelblue', zorder = 1)) elif key == 3: - ax.add_artist(patches.Rectangle((x, y), max_x+abs(x), max_y+abs(y), facecolor = 'lightskyblue', zorder = 1)) + ax.add_artist(patches.Rectangle((x, y), max_x+abs(x), max_y+abs(y), facecolor = 'lightsteelblue', zorder = 1)) else: - ax.add_artist(patches.Rectangle((min_x, y ), abs(x-min_x), max_y+abs(y), facecolor = 'lightskyblue', zorder = 1)) + ax.add_artist(patches.Rectangle((min_x, y ), abs(x-min_x), max_y+abs(y), facecolor = 'lightsteelblue', zorder = 1)) for bp in bpr: @@ -106,16 +106,18 @@ def print_model(data, models, p1, p2, df1, pathname = None, cm=None): for d in data: if d[2] == 0: - plt.scatter(d[0][0], d[0][1], c = 'blue', marker='.', zorder = 2) + plt.scatter(d[0][0], d[0][1], c = 'royalblue', marker='.', zorder = 2) elif d[2] == 1: - plt.scatter(d[0][0], d[0][1], c = 'red', marker='.', zorder = 2) + plt.scatter(d[0][0], d[0][1], c = 'firebrick', marker='.', zorder = 2) plt.xlabel(g1) plt.ylabel(g2) if cm is not None: pair = '/'.join([p1, p2, str(key)]) - error = cm.at['error', pair] - plt.title('LOOCV Error {}'.format(error)) + error = cm.at['LOOCV', pair] + plt.title('RE = {} & LOOCVE = {}'.format(round(reg_err/len(data),3),round(error,3))) + else: + plt.title('RE = {}'.format(round(reg_err,3))) if pathname is not None: plt.savefig(pathname + g1 + '_' + g2 + '.png') @@ -346,7 +348,6 @@ def print_model_RS(data, models, p1, p2, df1, pathname = None, cm=None): plt.figure(figsize=(3,3)) ax = plt.axes() ax.set_facecolor("lightgray") - plt.title('Ranking Space') plt.xlabel(p1) plt.ylabel(p2) @@ -396,6 +397,10 @@ def print_model_RS(data, models, p1, p2, df1, pathname = None, cm=None): plt.scatter(rxd, ryd, c='red', marker='.', zorder=2) elif d[2] == 0: plt.scatter(rxd, ryd, c='blue', marker='.', zorder=2) + if cm is not None: + pair = '/'.join([p1, p2, str(key)]) + error = cm.at['LOOCV', pair] + plt.title('Ranking Space \n LOOCV Error {}'.format(round(error,3))) plt.show() @@ -496,3 +501,13 @@ def show_results(df, probs_df, pairs, nbcpus, pathname, cm): for r in res: p1, p2, models, data = r print_model(data, models, p1, p2, probs_df, pathname, cm) + +def show_results_RS(df, probs_df, pairs, nbcpus, pathname, cm): + pool = mp.Pool(nbcpus) + vals = [(p, df) for p in pairs] + + res = pool.starmap(cr_models, vals, max(1,len(vals)//nbcpus) ) + + for r in res: + p1, p2, models, data = r + print_model_RS(data, models, p1, p2, probs_df, pathname, cm) diff --git a/Module/stages.py b/Module/stages.py index 24ab16b..1fc8350 100755 --- a/Module/stages.py +++ b/Module/stages.py @@ -5,6 +5,8 @@ from Module import tools from Module import selection_algorithm as sa from Module import preselection as psl +from Module import dynamic_preselection as dpsl + import pandas as pd import matplotlib.pyplot as plt import os @@ -13,13 +15,19 @@ import os from sklearn.metrics import roc_auc_score, confusion_matrix, matthews_corrcoef -def stage0(df, nbcpus, threshold): +def stage0_old(df, nbcpus, threshold): reg = psl.regression_error_matrix(df, nbcpus) if threshold is not None: reg = psl.preselection_reg_err(reg, threshold) return reg +def stage0(df, nbcpus, m, log): + config = dpsl.all_configurations(df) + Q, pairs = dpsl.algorithm_2(config, df, m, nbcpus, log) + return pairs + + def stage_1(df, cls, min_k, max_k, nbcpus, strat, funct, log): @@ -74,9 +82,9 @@ def stage_2(df, cls, k_opt, auc_file, conf_mat_file, nbcpus, funct, strat, logs) labels, probas, uncertain_pts = tools.unclassified_points(y_true, y_proba) return acc, auc, CI, conf_mat -def stage_3(df, cls, k_opt, nbcpus, funct, strat): +def stage_3(df, cls, k_opt, cost_mat, nbcpus, funct, strat): ndf_err = cmu.error_matrix(df, cls, nbcpus,funct) - ndf_err.to_csv('cm_st3.csv') + ndf_err.to_csv(cost_mat) cost = cmu.cost_classifiers(ndf_err) mve, pairs, algo = oka.find_k_metamodel(df, ndf_err, cost, k_opt, nbcpus, strat) return pairs, mve diff --git a/README.md b/README.md index a9e194b..9bc3c91 100644 --- a/README.md +++ b/README.md @@ -1,92 +1,40 @@ -# MEM_Python +# Monotonic Ensemble Models +Author: Océane FOURQUET +This project aims to construct an ensemble model of bidimensional monotonic classifiers[1](https://link.springer.com/article/10.1007/s00453-012-9628-4). In addition to reimplementing an established approach[2](https://academic.oup.com/jid/article/217/11/1690/4911472?login=true) in python, it integrates a preselection of the pairs of features, reducing drastically the running time of the approach. -## Getting started +## Python and librairies versions +- Python 3.9.1 +- Pandas 1.2.3 +- Numpy 1.19.2 +- Matplotlib 3.3.4 -To make it easy for you to get started with GitLab, here's a list of recommended next steps. +## Run the code -Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)! +### Data +Data should be presented in csv format, in the form of samples per row and features per column, with a 'target' column for classes. -## Add your files +### Code +The code is split in 3 stages. Stage 1: determine the optimal number of classifiers to construct the metamodel. Stage 2: compute an estimate of the AUC score of a metamodel constructed with k_opt classifiers. Stage 3: construct the final metamodel from the whole dataset. The three stages are coded in the py file stages.py, available in the Module. -- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files -- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command: +To run the whole project, you can run full\_project.py with as follow: -``` -cd existing_repo -git remote add origin https://gitlab.pasteur.fr/ofourque/mem_python.git -git branch -M main -git push -uf origin main -``` +python3 full\_project.py <dataset> <probeset> <outpath> -## Integrate with your tools +ex : python3 full\_project.py dengue/dengue.csv dengue/probeset_annotations.txt Result/ > log.txt -- [ ] [Set up project integrations](https://gitlab.pasteur.fr/ofourque/mem_python/-/settings/integrations) +To run only one stage, you can use the relevant py file among stage1.py, stage2.py and stage3.py. -## Collaborate with your team +Note that by default, this code uses the 3-classes classification (severe, non severe and uncertain). If you want to compute the metamodel by favoring severe or non severe (2-classes classification), you must change the parameter in the file full\_project.py. -- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/) -- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html) -- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically) -- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/) -- [ ] [Automatically merge when pipeline succeeds](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html) -## Test and Deploy - -Use the built-in continuous integration in GitLab. - -- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html) -- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing(SAST)](https://docs.gitlab.com/ee/user/application_security/sast/) -- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html) -- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/) -- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html) - -*** - -# Editing this README - -When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thank you to [makeareadme.com](https://www.makeareadme.com/) for this template. - -## Suggestions for a good README -Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information. - -## Name -Choose a self-explaining name for your project. - -## Description -Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors. - -## Badges -On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge. - -## Visuals -Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method. - -## Installation -Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection. - -## Usage -Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README. - -## Support -Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc. - -## Roadmap -If you have ideas for releases in the future, it is a good idea to list them in the README. - -## Contributing -State if you are open to contributions and what your requirements are for accepting them. - -For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self. - -You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser. - -## Authors and acknowledgment -Show your appreciation to those who have contributed to the project. - -## License -For open source projects, say how it is licensed. - -## Project status -If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers. +## Files in Module +- cost\_matrix\_uncertainty.py +- measures.py +- monotonic\_regression\_uncertainty.py +- optimal\_k\_aggregations.py +- selection\_algorithm.py +- show\_results.py +- stages.py +- tools.py -- GitLab