diff --git a/Lab2/README.md b/Lab2/README.md new file mode 100755 index 0000000..dbf1ec2 --- /dev/null +++ b/Lab2/README.md @@ -0,0 +1,13 @@ +# Laboratorio: clasificación tabular con MLP + +El laboratorio está en español y distingue claramente los materiales públicos de los privados. + +- datos_publicos contiene el único conjunto de entrenamiento que se entrega: 1,000 ejemplos, 750 de clase 0 y 250 de clase 1. +- notebooks/laboratorio_estudiante.ipynb es la versión para completar. +- notebooks/laboratorio_resuelto.ipynb es la referencia para docencia. +- notebooks/inferencia_configurable.ipynb reconstruye un modelo desde un diccionario que indica arquitectura y origen de pesos. +- instructor_privado contiene el test final balanceado, los pesos de referencia y la evaluación. No se distribuye. + +Ejecute python3 generar_datos.py para generar los CSV con la ecuación analítica, el término de error y una semilla fija. El código sólo necesita Python 3, NumPy y Matplotlib. + +La entrega del estudiante debe incluir código, una tabla de búsqueda de hiperparámetros, curvas de entrenamiento y desarrollo, métricas, la justificación del umbral y predicciones sobre el CSV que indique el instructor. El test privado nunca se usa para ajustar hiperparámetros ni umbral. diff --git a/Lab2/datos_publicos/README.md b/Lab2/datos_publicos/README.md new file mode 100755 index 0000000..79b59fd --- /dev/null +++ b/Lab2/datos_publicos/README.md @@ -0,0 +1,3 @@ +# Datos públicos + +El archivo train_1000_desbalanceado.csv contiene 1,000 ejemplos: 750 de la clase 0 y 250 de la clase 1. Las entradas son x1, x2, x3 y x4; etiqueta es el objetivo. diff --git a/Lab2/datos_publicos/ejemplo_entrada_inferencia.csv b/Lab2/datos_publicos/ejemplo_entrada_inferencia.csv new file mode 100755 index 0000000..41f43d0 --- /dev/null +++ b/Lab2/datos_publicos/ejemplo_entrada_inferencia.csv @@ -0,0 +1,13 @@ +id,x1,x2,x3,x4 +ejemplo_0001,2.16279541,-0.15620382,1.52249089,1.65824076 +ejemplo_0002,-0.33252016,-1.51252489,-0.74678853,2.48168432 +ejemplo_0003,-0.67816516,-1.48254252,1.32306735,0.53641452 +ejemplo_0004,-0.81252663,-0.39666178,0.80564212,-2.38488356 +ejemplo_0005,1.11282146,0.39086547,1.85731970,-0.78875571 +ejemplo_0006,-0.85655470,1.90412707,1.44050521,0.88793538 +ejemplo_0007,-1.64834898,-0.63973431,-0.30206628,1.31444933 +ejemplo_0008,-1.57711791,1.50301207,1.67408804,1.89669274 +ejemplo_0009,-1.30573622,-1.21531243,1.38645484,1.79280184 +ejemplo_0010,-1.47446448,1.32280710,-2.49155307,2.21472376 +ejemplo_0011,-2.45185030,-1.18520910,2.03686553,-2.34874399 +ejemplo_0012,-2.49821307,0.66322044,-2.46049594,-0.55338346 diff --git a/Lab2/datos_publicos/ejemplo_entrada_inferencia_predicciones.csv b/Lab2/datos_publicos/ejemplo_entrada_inferencia_predicciones.csv new file mode 100644 index 0000000..f36c260 --- /dev/null +++ b/Lab2/datos_publicos/ejemplo_entrada_inferencia_predicciones.csv @@ -0,0 +1,13 @@ +id,probabilidad_clase_1,prediccion,umbral +ejemplo_0001,0.00557925,0,0.315 +ejemplo_0002,0.00026550,0,0.315 +ejemplo_0003,0.00176073,0,0.315 +ejemplo_0004,0.00001668,0,0.315 +ejemplo_0005,0.00000370,0,0.315 +ejemplo_0006,0.02924983,0,0.315 +ejemplo_0007,0.00000050,0,0.315 +ejemplo_0008,0.00000003,0,0.315 +ejemplo_0009,0.00000023,0,0.315 +ejemplo_0010,0.00183952,0,0.315 +ejemplo_0011,0.01807133,0,0.315 +ejemplo_0012,0.92466868,1,0.315 diff --git a/Lab2/datos_publicos/train_1000_desbalanceado.csv b/Lab2/datos_publicos/train_1000_desbalanceado.csv new file mode 100755 index 0000000..cbbfc82 --- /dev/null +++ b/Lab2/datos_publicos/train_1000_desbalanceado.csv @@ -0,0 +1,1001 @@ +id,x1,x2,x3,x4,etiqueta +train_0001,2.16279541,-0.15620382,1.52249089,1.65824076,0 +train_0002,-0.33252016,-1.51252489,-0.74678853,2.48168432,0 +train_0003,-0.67816516,-1.48254252,1.32306735,0.53641452,0 +train_0004,-0.81252663,-0.39666178,0.80564212,-2.38488356,0 +train_0005,1.11282146,0.39086547,1.85731970,-0.78875571,0 +train_0006,-0.85655470,1.90412707,1.44050521,0.88793538,0 +train_0007,-1.64834898,-0.63973431,-0.30206628,1.31444933,0 +train_0008,-1.57711791,1.50301207,1.67408804,1.89669274,0 +train_0009,-1.30573622,-1.21531243,1.38645484,1.79280184,0 +train_0010,-1.47446448,1.32280710,-2.49155307,2.21472376,0 +train_0011,-2.45185030,-1.18520910,2.03686553,-2.34874399,0 +train_0012,-2.49821307,0.66322044,-2.46049594,-0.55338346,1 +train_0013,-0.88358646,0.91351560,-0.06673720,-1.64364405,0 +train_0014,-0.64059191,0.14550446,-1.62485776,-0.89009585,0 +train_0015,-1.09622705,-0.78107207,-2.11398042,0.06056275,1 +train_0016,-0.25925568,0.25417709,2.26587892,-0.28030647,0 +train_0017,-0.94922447,0.27434703,1.37110082,2.41378585,0 +train_0018,-0.69472817,-1.80115091,2.30722545,-1.66950606,0 +train_0019,-1.10217774,1.30546599,-1.32263718,1.18058746,0 +train_0020,-2.42001610,0.90776990,1.97611803,-1.12057565,0 +train_0021,-0.55760692,0.02433288,1.88075451,1.23888381,0 +train_0022,-2.36650664,0.29177474,-2.03566915,0.83529703,0 +train_0023,-1.16030112,2.35272013,1.85048423,-2.39359342,0 +train_0024,-1.54974770,-1.74153417,-0.49195136,2.34023173,0 +train_0025,-0.89430305,0.22997824,-1.68348309,-2.32397946,0 +train_0026,1.76117924,-2.04981800,-1.56669378,2.39146284,1 +train_0027,1.63784087,1.66183862,-0.80118350,1.97130806,1 +train_0028,-1.98784724,0.30179279,1.28698380,1.31959978,0 +train_0029,1.71330120,-1.38238474,-0.11461516,0.64559081,1 +train_0030,-1.96932529,-0.18146652,1.22210138,0.13231640,0 +train_0031,-0.38799403,-1.61313356,1.64070487,0.29221800,0 +train_0032,-1.53332057,1.36544685,2.44154224,1.40729969,0 +train_0033,1.09356821,2.01489111,-1.60428492,0.91565239,1 +train_0034,-2.10983531,-0.42849395,-0.02475064,2.31958206,0 +train_0035,-1.85310783,-1.92476316,-0.40492012,1.27013349,0 +train_0036,-2.33320377,1.29108820,1.26594732,-1.01719543,0 +train_0037,1.53557620,1.32430834,-1.44530632,-1.24305657,1 +train_0038,-1.13034248,0.27379409,-1.58202581,1.47810840,0 +train_0039,2.15576170,1.70849399,-1.76277030,-1.60016826,1 +train_0040,-2.43740756,0.50121109,2.16727277,0.20864760,0 +train_0041,1.92930468,-2.49318797,-1.16568780,0.44779762,1 +train_0042,1.34208667,2.33912241,-0.62550687,1.21117900,1 +train_0043,1.39852679,-0.39124836,-0.86162481,-2.23618900,0 +train_0044,-0.95213532,-1.79198963,1.61349428,0.95844519,0 +train_0045,2.41764410,-1.30452448,1.75149237,-1.19104943,0 +train_0046,0.65328406,0.39423014,-1.68765374,-2.23741565,0 +train_0047,-0.46630968,-1.41047154,0.51089793,-1.09363070,0 +train_0048,0.27587146,-1.66928878,-1.42338939,1.16288053,1 +train_0049,-1.45526286,2.36262394,0.91104183,1.15108116,0 +train_0050,-2.37091909,-0.69740484,-0.44619774,-2.29475983,1 +train_0051,-1.23345473,-1.08413166,1.00964480,0.57585438,0 +train_0052,-0.61579945,0.73899713,2.29368300,-0.74633575,0 +train_0053,-1.82706780,-0.01052779,0.96102722,-1.45192526,0 +train_0054,-0.10616564,-1.75105383,2.12084031,0.83395557,0 +train_0055,-2.42778050,-2.34774525,-1.65305949,-0.89197694,1 +train_0056,-0.50213560,0.36251903,0.34676158,-0.84925448,0 +train_0057,-0.24868406,1.48538162,-1.84535861,-0.88045448,1 +train_0058,-1.76796608,0.39314428,-1.01030093,0.64612008,0 +train_0059,0.33323459,-0.28083842,-0.66853793,-2.37724780,0 +train_0060,2.31018679,-1.21109626,1.79002977,1.57943887,0 +train_0061,0.12066954,-2.22048976,1.65913345,-0.51830906,1 +train_0062,1.49194601,0.41049389,2.15231060,-2.18078926,0 +train_0063,2.03576870,0.39491156,-0.17067018,0.18176131,0 +train_0064,-1.43752957,-0.40733568,2.27328541,1.49191875,0 +train_0065,0.27987297,1.88740943,2.48632820,2.38349212,0 +train_0066,0.00462479,1.43456423,1.30729977,0.69039867,0 +train_0067,2.14568426,1.13555966,-0.77554324,2.49866221,1 +train_0068,-0.53432760,0.77096579,0.91851723,-0.11141784,0 +train_0069,-1.96633971,1.81311771,1.36074472,1.00474222,0 +train_0070,-1.47920489,-1.99911385,2.12062858,0.36074018,0 +train_0071,1.56097971,0.60904420,1.09689243,-1.76892131,0 +train_0072,-1.94413175,0.14899231,1.99906955,-1.45149112,0 +train_0073,-1.83222461,-1.17423382,2.19511549,-0.73628337,0 +train_0074,1.87699671,0.23227531,1.86518503,-1.36478356,0 +train_0075,-1.33389378,-1.26483554,-2.14890490,-2.49403161,1 +train_0076,-0.98823799,-0.91857277,2.38780652,-1.04181980,0 +train_0077,0.81879841,-0.84117596,1.97194183,-0.17439644,0 +train_0078,0.95150500,-2.47626164,-1.30294205,1.99814352,1 +train_0079,-1.57512491,1.18043284,-1.07002105,0.25403784,1 +train_0080,0.46247409,-0.17220197,2.39917388,1.63581193,0 +train_0081,-0.49229075,-1.87882207,1.81219623,-0.65116698,0 +train_0082,-0.61975579,-1.35995253,-1.61015321,-2.07616459,1 +train_0083,-2.10608404,1.44480245,0.83271501,1.58704050,0 +train_0084,-2.41383403,0.82218470,-0.31597598,2.10725302,0 +train_0085,-1.04559962,0.84795493,-0.52473783,0.18355251,0 +train_0086,-1.48537297,-1.31838151,2.42766883,-0.57733545,0 +train_0087,2.08351905,0.48441585,0.73533813,1.78322425,1 +train_0088,1.01765469,-1.35881081,-0.77894896,-2.21307269,0 +train_0089,1.15831361,1.30971219,1.54917868,-1.90388386,0 +train_0090,-1.52728688,2.38647149,0.58365023,-2.27506630,1 +train_0091,0.21825519,-2.19344089,-1.10030441,-0.86666483,1 +train_0092,1.36908864,0.10499475,-1.67497467,-2.17692034,0 +train_0093,-0.36502287,-0.17777985,-2.35797565,0.86172844,1 +train_0094,1.41388158,-0.71548973,-1.57988838,1.32095225,1 +train_0095,0.90495666,-0.05562823,2.00099742,1.91400163,0 +train_0096,-1.64315676,-1.20429523,1.88119773,-0.24857395,0 +train_0097,-2.12528159,1.81921364,-0.21180842,1.66490837,0 +train_0098,-0.09546248,-1.38867540,2.46872699,0.17907918,0 +train_0099,-2.49967676,0.90482163,1.25622885,-0.79655291,0 +train_0100,1.63451928,0.61072035,0.43843599,-1.32963059,0 +train_0101,-1.69575607,-0.59856700,-2.14058522,1.30387188,0 +train_0102,-1.64396050,-1.32959954,1.31264022,1.62846279,0 +train_0103,0.15413998,1.33803016,-0.32515817,1.40141279,1 +train_0104,0.42991743,-1.09600057,-1.27625697,-1.69523983,1 +train_0105,-1.80857670,0.88734429,2.03912419,1.29203920,0 +train_0106,-0.16213846,1.59887213,-1.18630107,-2.27793743,1 +train_0107,1.20794963,-0.99643552,2.41870297,1.37733317,0 +train_0108,-0.28239782,0.58369987,1.98237272,0.98867650,0 +train_0109,1.13125743,2.05490460,2.01868990,-1.56729640,0 +train_0110,0.50662556,1.15191605,0.73609995,-1.33954429,0 +train_0111,0.35863050,-1.45065063,0.13697106,-1.74384545,0 +train_0112,-0.04633369,0.56101028,1.02048544,1.81932854,0 +train_0113,-2.29550841,-1.61694930,2.42671917,1.32997298,0 +train_0114,0.91234532,1.46033949,2.27549987,1.90577959,0 +train_0115,1.49942296,-0.26690403,-0.54689537,-0.81239283,1 +train_0116,-0.89058177,1.92885030,-0.85890221,2.22901584,0 +train_0117,1.26479440,2.48490511,2.03276306,-1.10405374,1 +train_0118,1.84443691,1.76888489,1.01997916,-0.06094755,1 +train_0119,-0.48524519,0.32094588,-0.90092288,0.33918802,0 +train_0120,-0.97970950,-1.03186982,-0.41875468,0.13912105,0 +train_0121,-0.33224212,-0.70700782,1.03241885,-1.19562364,0 +train_0122,2.18134681,-0.12424104,0.33184605,1.36135056,1 +train_0123,0.16160494,1.80153086,-0.35777315,-2.30285838,1 +train_0124,-1.26720445,0.79666423,-0.72158440,0.06246998,0 +train_0125,-1.49981742,-1.18805446,-1.75615841,-1.04138506,1 +train_0126,-2.17326657,0.32900906,-1.28768354,1.36042825,0 +train_0127,-1.31127001,0.43556859,1.28376409,0.92625340,0 +train_0128,1.07938682,-1.69813813,2.19360026,-0.09182371,0 +train_0129,1.40211963,-0.56891965,-0.85605860,-1.27351647,0 +train_0130,-0.46856322,-0.79231951,1.95193248,-0.25396588,0 +train_0131,0.28506430,1.49727602,1.68823957,-1.62860430,0 +train_0132,0.83446847,0.37676453,-1.76199302,0.73529653,1 +train_0133,-1.12250912,-1.23954069,2.32243912,-0.43668349,0 +train_0134,-1.59120266,-2.00666959,0.88633822,-2.19487605,1 +train_0135,-1.73169950,-0.40963740,1.19381217,2.13365624,0 +train_0136,-2.38570249,1.28615177,-2.03924805,1.17678052,0 +train_0137,-1.50544190,0.51057619,0.98816091,0.79845714,0 +train_0138,0.53852937,0.41856542,-0.05817180,2.12706586,0 +train_0139,-1.63779488,0.81075397,-2.09989275,1.26704473,0 +train_0140,-1.75119388,-0.90297579,0.95330615,1.42708073,0 +train_0141,-1.01608628,0.89063921,0.01800578,0.47500144,0 +train_0142,-0.61348375,0.57221700,0.97536031,2.09796246,0 +train_0143,-0.04563711,-0.51040579,-1.18259070,2.12415044,0 +train_0144,-1.72200165,2.27126061,1.30459929,2.07079815,0 +train_0145,0.10591781,1.01219148,-1.00514078,-2.33527864,0 +train_0146,2.17032346,-0.97253800,-0.20158582,-2.21432563,0 +train_0147,-1.52956996,1.60382840,-1.33571678,-1.53452479,1 +train_0148,-0.93706361,-0.84724405,2.21410470,2.34691075,0 +train_0149,-2.05844137,1.15675431,0.40095898,-0.06264745,0 +train_0150,-0.73712156,1.54318723,1.43733598,-0.63990024,0 +train_0151,-2.09270008,-0.60694744,1.04312553,-2.17001768,0 +train_0152,-1.18032309,-0.28536360,1.74505902,2.02626735,0 +train_0153,1.67362459,-0.46276118,1.71166316,-2.23432261,0 +train_0154,-2.12821922,-1.55817334,0.71130104,2.21232264,0 +train_0155,-0.61827777,-0.90193441,2.17845335,-2.16621370,0 +train_0156,-1.16875567,-0.11301430,1.62264985,0.58403648,0 +train_0157,1.19455025,0.14117570,0.64299306,1.00262230,0 +train_0158,-1.07202208,0.09853503,-1.27607263,-1.50320876,0 +train_0159,-1.23789519,-1.74691798,0.19607039,-2.44723885,1 +train_0160,-2.35869757,-0.29799552,-1.31015891,2.05031227,0 +train_0161,1.57113531,0.40398120,2.43374337,1.40280366,0 +train_0162,1.58189924,0.09205521,0.25325389,-0.67028253,0 +train_0163,-1.68245115,0.98900007,-0.27110330,-2.45942646,0 +train_0164,-2.08670304,-2.31679626,1.77837830,-0.48906460,1 +train_0165,-1.03330182,2.32728109,1.93737764,-1.24936294,1 +train_0166,-0.68779300,0.20503789,2.36272716,1.13694410,0 +train_0167,-0.78576104,1.78401412,2.36184117,1.23484884,0 +train_0168,-0.00181742,1.83659083,0.92215166,2.09114453,0 +train_0169,-2.08411675,-0.81853847,-0.93127854,0.23886263,0 +train_0170,1.06503587,0.83806178,-0.79687869,-0.15815506,1 +train_0171,1.65345331,-2.08556260,0.01537436,-1.32971521,1 +train_0172,-2.13527253,1.57765402,-2.30873936,0.56445536,1 +train_0173,0.51357875,1.79447645,0.23274352,-1.61973678,1 +train_0174,2.16700683,1.81007834,0.74187202,-1.98218004,0 +train_0175,2.45956691,-1.07732165,2.39989291,0.08987124,0 +train_0176,-0.01189212,-1.12863839,0.38311305,-0.37102393,0 +train_0177,-2.04651714,-0.06736011,1.50121027,-0.28278319,0 +train_0178,0.53493423,-0.50048550,-1.68464534,1.11513160,1 +train_0179,-2.23761918,1.10473005,1.79692719,0.40667787,0 +train_0180,-1.05839647,-0.66323180,1.66606117,-0.51844848,0 +train_0181,-0.47682915,-0.63288111,0.97252289,2.38020432,0 +train_0182,-1.80558385,1.37910589,0.66078303,0.06242206,0 +train_0183,0.08492868,-0.34735051,-0.31939908,-0.71272702,0 +train_0184,-0.93510646,1.83602145,1.75247764,0.37285671,0 +train_0185,2.48993743,0.78799099,-1.30175267,-1.31137552,0 +train_0186,-0.36693248,-0.23353304,1.85523977,-2.41864845,0 +train_0187,1.63610063,0.32146078,-0.30814452,-0.00755891,1 +train_0188,-1.46392814,2.32077963,-1.46240151,-2.37804198,1 +train_0189,2.00436737,0.19634743,-0.36524914,-2.17920083,0 +train_0190,-1.34219211,0.60742617,0.57023048,0.33360865,0 +train_0191,-0.05436589,-0.66078366,0.00477131,-0.17651406,1 +train_0192,0.07349601,-0.48007629,2.07621635,1.06150346,0 +train_0193,-1.58255400,1.19850218,1.65400228,-0.06811082,0 +train_0194,-0.54266670,1.17174933,0.53792996,1.69797589,0 +train_0195,2.12221519,-2.03921730,2.27035809,-1.17895160,0 +train_0196,2.26868919,0.46161360,1.17247918,1.95045206,0 +train_0197,2.10888196,0.42533246,2.25044231,1.83532718,0 +train_0198,-1.99308708,-0.80383270,-1.14192951,0.60737391,0 +train_0199,-1.18821798,2.15120718,-2.02978626,2.24247408,1 +train_0200,1.18009108,0.69194487,1.73434019,-0.74814169,0 +train_0201,1.89613151,-0.76643175,1.81316309,2.22012558,0 +train_0202,-0.03042107,0.14856337,1.56878030,2.11039443,0 +train_0203,1.10171843,-0.32888164,1.68575537,0.48655900,0 +train_0204,-0.11193640,1.37655346,1.21057201,-1.00817706,0 +train_0205,2.44474611,-1.28363339,-2.42706780,0.30588657,1 +train_0206,-2.28362133,1.49915076,1.76758800,-1.16733604,0 +train_0207,-2.38574700,-1.27907640,-1.59187459,2.26711563,0 +train_0208,-2.42792884,-1.32011619,-0.31853090,2.00936971,0 +train_0209,-2.47888076,2.02534829,2.08979586,0.77941703,0 +train_0210,1.99092238,0.77468520,2.36954206,-0.22248165,0 +train_0211,1.96683059,1.80214599,-2.34267718,-1.33920080,1 +train_0212,-1.24302920,1.10265633,1.78368194,-1.64513176,0 +train_0213,1.46254125,-0.02185201,0.61433763,1.51939233,0 +train_0214,-1.78179924,-0.16554270,1.48926450,-0.23900312,0 +train_0215,0.65949028,-0.96717919,2.38090009,1.26025921,0 +train_0216,-0.65520733,0.04244594,-1.26967110,1.80363415,0 +train_0217,-1.66386834,0.06566584,-2.47760184,1.01750741,0 +train_0218,0.86626316,-1.51410885,1.82341193,-1.90543874,0 +train_0219,-0.88122293,-1.82213662,1.42265405,-0.66184419,0 +train_0220,1.91358208,0.59112647,-0.77444657,-1.28336808,0 +train_0221,-1.77778423,-1.08202174,-2.44481323,1.73377397,0 +train_0222,2.26276487,1.18586467,-0.22735327,-2.25999882,0 +train_0223,-0.06623984,0.07817819,-1.92632293,-0.50962279,1 +train_0224,1.29815529,1.27050612,-1.88219823,-2.47739623,0 +train_0225,-1.06026401,0.48762427,-0.90319319,-1.92598644,0 +train_0226,0.35583214,1.58824901,1.80582479,-2.11420850,0 +train_0227,-1.57758328,-1.00830274,2.08819648,-2.48932110,0 +train_0228,-0.39126098,-0.20074007,-0.29805582,0.34436167,0 +train_0229,0.60607077,-0.32508281,0.50132036,-1.70775322,0 +train_0230,-0.77304568,1.87149705,-1.85562744,-2.47520173,1 +train_0231,2.05838886,1.59428397,-1.11393394,0.25632386,1 +train_0232,-0.16942613,0.41533334,-1.52414730,-1.20527907,1 +train_0233,1.47005025,0.37435551,0.00501088,0.88765971,1 +train_0234,-1.87334443,-0.70865188,-0.66393465,-1.36510726,0 +train_0235,-0.80557018,-0.54850495,-1.72275772,2.41196402,0 +train_0236,-1.84143709,-0.70820719,-0.07915985,-0.67842198,0 +train_0237,0.40942193,1.42402891,-2.01427737,0.12108984,1 +train_0238,-1.36391967,0.54054898,1.61340719,2.19845980,0 +train_0239,-0.36901447,0.09663461,-2.34290206,1.44972571,0 +train_0240,0.40712693,0.03232250,2.34754308,-0.96987317,0 +train_0241,1.95232115,0.73668069,-1.22939806,-1.16450651,0 +train_0242,1.33407873,-1.36433707,2.46184917,1.43350722,1 +train_0243,1.35259961,-2.14715495,1.43672802,-2.20339926,1 +train_0244,0.90090411,-1.91102797,-1.75685435,-0.18378930,1 +train_0245,-0.98807419,-1.23927494,-0.04434402,-2.49085971,0 +train_0246,-0.48147006,1.46348541,0.75116951,-0.77440483,0 +train_0247,0.66075258,1.04696795,-2.21144958,0.83434717,1 +train_0248,0.25434666,2.29458875,0.47830503,-0.42942869,1 +train_0249,-1.72275934,2.47500678,1.04468894,2.19571103,0 +train_0250,0.72650540,-0.33806915,2.19550585,1.64266820,0 +train_0251,-1.08352060,-0.97034356,-0.16234822,-2.06620000,0 +train_0252,1.26522509,-2.42003383,0.33959864,-2.12438162,1 +train_0253,-1.56006594,2.39228005,-0.39807946,2.21166648,0 +train_0254,1.78142984,1.35945802,-0.29435756,-1.11267706,1 +train_0255,-2.45639506,-2.25316967,2.21466759,-1.95281209,1 +train_0256,-0.01642131,0.79288695,-0.44482228,-1.15213186,0 +train_0257,0.93927867,0.12776911,0.53930241,-1.70547752,0 +train_0258,1.82841449,-1.07982826,-2.27024520,0.43440319,1 +train_0259,1.17710081,0.93783359,2.31437043,0.16893628,0 +train_0260,0.66270405,2.00878640,2.33553150,-2.41063472,0 +train_0261,-2.38050738,-2.47836564,2.07365323,1.77237005,0 +train_0262,-2.49508660,0.70532839,0.38256261,2.08255634,0 +train_0263,2.20324257,-0.67130229,0.09336696,1.77131547,1 +train_0264,-1.20241151,-1.82480102,2.00499713,-0.08059697,0 +train_0265,0.32829132,-0.23893084,-0.36102954,-0.92196103,0 +train_0266,-2.37832113,0.95715935,-1.88877731,-0.32933451,1 +train_0267,-1.08623372,-2.15546048,1.48026598,-2.27667706,0 +train_0268,1.97610340,-0.23670339,-0.26084988,0.08496545,0 +train_0269,0.30971325,-1.49044095,1.65827589,-0.25323915,0 +train_0270,-1.17182809,-1.43324912,0.44826245,1.49232532,0 +train_0271,-1.66576049,-0.29562088,1.36615117,1.66219945,0 +train_0272,-1.63972912,1.82250609,0.49101069,-1.39167111,1 +train_0273,2.43967851,0.65113956,-0.61476329,-0.86308021,0 +train_0274,1.60404954,-0.89323583,0.07350349,-2.06850802,0 +train_0275,0.72692332,-1.82108602,1.23283031,-1.99854210,0 +train_0276,-0.23289712,-0.68234204,0.35185904,0.01161703,0 +train_0277,-0.75009939,-2.41780658,-1.09045460,0.01665153,1 +train_0278,0.69711104,1.35585221,2.27361882,-2.38552844,0 +train_0279,-1.56850135,1.10194406,-0.45031624,0.85301833,0 +train_0280,1.66791351,-1.54143052,-1.34646066,0.59534508,1 +train_0281,-0.45416517,0.58328573,2.31786205,-2.22652992,0 +train_0282,0.27691221,0.35068018,-0.91533261,-0.72365066,0 +train_0283,2.46247149,-0.59862805,2.21205877,-1.58131678,0 +train_0284,-1.75890138,2.34057252,0.97247011,-1.83328846,1 +train_0285,1.45239731,1.87482661,0.99973036,0.47047886,1 +train_0286,0.16095526,1.01095919,0.96756006,1.13160546,0 +train_0287,-1.14186403,-0.73810886,-0.20262738,0.27863819,0 +train_0288,2.29180064,-1.38139570,-0.81290687,-1.90172195,0 +train_0289,-1.07589321,1.48726803,0.79461948,-1.57376472,0 +train_0290,1.18941987,-2.12990850,0.78569504,1.20522126,1 +train_0291,-0.39273023,-0.74167651,-2.17625359,-1.18967898,1 +train_0292,1.85852817,0.33125281,0.05341249,0.23917384,1 +train_0293,-1.15990210,1.02529932,0.93604876,2.37201322,0 +train_0294,0.99331661,0.39480505,2.24027190,1.04952925,0 +train_0295,1.64504418,-0.14501558,-0.45087361,-1.20133088,0 +train_0296,-0.13995445,-0.82420045,0.66140869,0.90724377,0 +train_0297,-0.58884338,-0.42156624,2.10262427,-2.17648042,0 +train_0298,-0.96377933,1.32839522,-2.08705261,1.57584743,0 +train_0299,2.46284824,1.12677836,2.15099494,2.44947988,0 +train_0300,-1.61548536,-0.22972962,0.61897906,-0.74772111,0 +train_0301,-2.25355892,-2.47970593,-2.20212385,1.39831308,1 +train_0302,1.92263884,-0.52831005,-1.14431719,-0.06697605,1 +train_0303,0.78328613,-0.43922734,-1.44685656,-2.49422161,0 +train_0304,-1.07863938,0.80992684,1.17711536,0.26433252,0 +train_0305,0.02910360,-1.96616022,2.02412152,-0.34322930,0 +train_0306,-0.47687431,1.69931061,-1.87067628,1.94960121,1 +train_0307,-2.16091372,-2.09638341,-1.62492754,1.18718890,1 +train_0308,1.16283209,-1.20415185,-0.62001343,-1.83297887,0 +train_0309,-1.00173291,-1.39828786,-0.48218269,0.22394820,0 +train_0310,-0.54271450,1.79514332,1.16904929,-1.72799466,0 +train_0311,-1.75430716,-1.23087056,-0.68440414,1.69354648,0 +train_0312,0.56476455,1.25538765,-0.79150770,-0.86851802,1 +train_0313,-1.54372673,-0.83970038,1.69987371,-0.53672349,0 +train_0314,-0.96423976,2.19898616,1.67604706,-1.41367567,0 +train_0315,-1.23900265,-0.17114292,-2.19752182,-1.12046997,0 +train_0316,1.96773411,-0.89345311,-0.05218582,-1.70500279,0 +train_0317,0.34738898,1.22160711,0.15703535,-2.39091179,0 +train_0318,2.46285707,0.65039255,1.96860513,1.63251516,0 +train_0319,-0.66762614,-0.07112589,1.16872190,-0.31737808,0 +train_0320,-0.34954159,0.65661593,1.83254795,2.46952763,0 +train_0321,-0.95695083,2.06803747,2.44021166,-2.29486144,0 +train_0322,2.00245140,-0.92725940,-2.41153562,-1.60664142,0 +train_0323,0.61962863,-0.99409535,-1.03569882,-1.13268457,1 +train_0324,-0.49858789,-1.50115147,-1.99565526,-2.05339221,1 +train_0325,-2.06022887,0.28402697,-0.09468210,1.19085032,0 +train_0326,-1.48497308,0.66179734,-0.30387158,-1.82809007,0 +train_0327,2.02420373,-1.45812676,-0.52892873,2.43103152,1 +train_0328,-2.44056282,1.34786718,0.73061474,0.22141269,0 +train_0329,1.60423528,1.92352385,1.50405636,-1.85844273,0 +train_0330,-0.01788627,0.41305508,-2.46466527,-0.35696713,1 +train_0331,-1.00861563,1.88501752,1.49392206,0.26991410,0 +train_0332,-0.31598347,2.49453352,1.92319262,-0.87261794,1 +train_0333,1.08945282,1.40540439,-2.19536793,2.20370036,1 +train_0334,-2.42862177,2.02504273,-2.24091193,-1.49220759,1 +train_0335,-0.26355979,1.78068689,1.04821396,1.76108691,0 +train_0336,-0.37111181,1.86397156,-0.44672285,-0.03385866,1 +train_0337,-0.76619951,-1.39907104,-0.33718664,1.09298566,0 +train_0338,-1.21365164,1.35222521,0.04513587,2.41149833,0 +train_0339,-1.52927147,-0.61250204,-0.59537860,2.04993756,0 +train_0340,-2.11445427,2.14153444,2.35210346,-2.32059077,1 +train_0341,-1.63911175,1.34696541,-0.07053504,-2.47807594,0 +train_0342,0.64871731,-0.69224960,2.40127058,-1.87368799,0 +train_0343,0.51565407,0.84587048,2.04361747,1.24553010,0 +train_0344,0.23576185,-1.40560646,-2.34784138,1.95558092,1 +train_0345,0.70310462,-1.36911008,1.97931195,-1.79580259,0 +train_0346,2.49338034,0.60040788,1.80132871,-2.32046247,0 +train_0347,-1.16233549,0.43539596,-0.25783672,2.05642705,0 +train_0348,0.04143439,0.33825809,-1.41079091,0.75924644,0 +train_0349,-1.92274186,-0.57439073,-2.43858760,2.15994985,0 +train_0350,0.60168913,-0.96235146,1.15380641,-0.84172915,0 +train_0351,0.21666256,0.67747678,-0.00251158,-2.47101224,0 +train_0352,1.27400706,1.26750876,-2.28086204,-0.62024166,1 +train_0353,1.45734633,-1.06464948,0.80110723,-0.87294454,0 +train_0354,-0.79133784,-0.04473705,-1.75879356,0.53789483,0 +train_0355,0.20924140,1.41957382,1.33524938,-0.86992082,0 +train_0356,-1.75565887,1.26994938,2.02363377,-0.85399351,0 +train_0357,-1.77830134,-0.42740894,-1.07444729,-0.21030895,0 +train_0358,2.08107725,2.01268044,2.12102459,-2.17358630,0 +train_0359,-1.89593826,0.59489009,-2.33631286,1.24488262,0 +train_0360,-1.46690439,0.07645479,2.15929493,1.55466661,0 +train_0361,0.04272210,0.26594792,-0.49298025,-1.96157003,0 +train_0362,1.83919616,-1.59095895,2.47447238,-1.08226398,0 +train_0363,0.60412821,-1.05519742,1.98678203,2.12054289,0 +train_0364,-1.48323930,1.61067767,-0.22582778,1.09645480,0 +train_0365,-2.17855994,-0.75995636,1.77973674,1.60154063,0 +train_0366,-1.18859138,0.19636992,-1.86927843,1.35262137,0 +train_0367,2.12945707,-2.14969209,-0.76155333,-1.81336333,1 +train_0368,1.74149040,-0.81669583,1.83221015,-1.74171240,0 +train_0369,1.62081335,-1.49302681,-1.23883948,-2.22264820,0 +train_0370,0.28049323,1.64683450,-1.60450461,-0.32924126,1 +train_0371,2.05481822,2.09917309,2.12894653,-1.78215033,0 +train_0372,0.44332498,0.47620343,2.07269187,-1.03748614,0 +train_0373,-2.18452006,-1.04176192,0.17929385,1.01874918,0 +train_0374,-1.26552564,1.20785344,1.86306866,0.85685161,0 +train_0375,-1.03769744,1.97655352,0.24365522,-2.38367989,1 +train_0376,-0.47192384,0.68121278,-0.76261742,2.17445344,0 +train_0377,-0.43073148,-0.08715927,-1.97533788,1.41267402,0 +train_0378,1.53725130,2.43788055,-0.75840040,-1.62635562,1 +train_0379,-1.70470041,-0.44243025,-1.90400483,2.26555538,0 +train_0380,2.05463480,1.45065768,-2.29484902,-0.19425700,1 +train_0381,-2.40725923,-0.96486647,2.09427149,-0.71975027,0 +train_0382,1.46708284,1.07261259,1.47606030,-2.36906532,0 +train_0383,-2.19094645,-1.49478913,2.23415988,-1.31185049,0 +train_0384,2.28548075,1.10423896,2.38247873,-1.76236661,0 +train_0385,1.26761701,-1.28497856,-1.02121681,0.21364332,1 +train_0386,1.23094548,1.05228603,-0.44808736,-2.40672982,0 +train_0387,0.90270700,2.23189698,-1.60697248,-1.55772730,1 +train_0388,-2.22706408,-0.85041051,1.50801039,1.15812865,0 +train_0389,0.33865251,0.67466082,-1.03588146,-0.98418466,0 +train_0390,2.12157434,0.73481030,0.03437085,-0.57821987,0 +train_0391,1.34237607,-1.40913274,0.57435771,0.35967462,1 +train_0392,-1.42337566,-0.45468234,-1.66041375,-1.86809481,0 +train_0393,-0.70011761,-2.33979304,-0.74422196,0.32229459,1 +train_0394,-2.17767058,-1.29104020,-1.26116771,2.04013680,0 +train_0395,1.12530649,-0.78876219,1.83687090,-0.41826982,0 +train_0396,1.96373531,-1.25013217,1.02893627,-0.58264427,1 +train_0397,-2.36961216,1.10185143,1.92792687,-1.93491070,0 +train_0398,-0.14620445,1.29429440,-0.65938994,-2.34405182,0 +train_0399,-0.78416438,-1.55633920,1.28115800,-0.93231464,0 +train_0400,-1.20304816,-0.45832774,1.95461070,-0.87575264,0 +train_0401,0.38002394,0.56778212,-0.32916220,2.13723525,0 +train_0402,0.89988240,0.50236014,-1.54356171,-2.02905461,1 +train_0403,0.34671974,0.88270646,-0.85806199,-1.74644896,0 +train_0404,1.82056082,-0.21663787,-0.20282352,-0.01904764,0 +train_0405,1.48002670,1.11909094,2.32897670,1.45186633,0 +train_0406,1.64138139,1.84501668,-1.73818122,2.49772232,1 +train_0407,0.35282480,-0.33487995,1.78796574,-1.90124249,0 +train_0408,0.87408659,2.13509772,2.40516635,-1.43685296,0 +train_0409,-1.72905256,-0.34073212,1.70032989,1.66444009,0 +train_0410,1.78345246,-1.64231983,-0.42928533,0.84739866,1 +train_0411,-1.03004009,1.44426751,-1.75627407,2.12577793,0 +train_0412,0.43657774,2.07949549,-0.69957479,0.99738718,1 +train_0413,1.42850579,0.80703687,0.97260921,1.37897410,0 +train_0414,1.03565770,1.56012899,0.52985925,-2.29872617,0 +train_0415,2.47799270,-2.20857854,1.20546820,-1.34989448,1 +train_0416,-2.36535872,-1.04720384,1.97072751,1.71687098,0 +train_0417,1.06049253,-0.91395353,2.16228304,-0.48885562,0 +train_0418,2.49791568,1.08374814,2.44109696,0.86821362,0 +train_0419,-0.17076998,1.20882405,-0.32137854,-2.48823217,0 +train_0420,2.23928489,-1.10958990,2.03258591,0.19264122,0 +train_0421,-0.17573093,-0.78549396,2.30449619,-0.31383303,0 +train_0422,0.97488370,1.29933565,0.73287670,1.81085257,1 +train_0423,-1.52656550,-0.73180039,-0.38886994,2.20369561,0 +train_0424,2.35624917,-1.94739318,2.03330035,0.52452867,1 +train_0425,-1.68649283,-1.22491748,1.29300518,2.44299105,0 +train_0426,-2.09437376,0.15914155,1.38863168,2.22665561,0 +train_0427,2.11119011,0.95184440,1.45801777,2.44861155,0 +train_0428,-0.66157929,2.47034928,0.92066589,0.63208225,1 +train_0429,1.31312460,-2.25573427,0.11758624,-1.04127782,1 +train_0430,1.36614066,-2.25555657,-1.45345651,-2.13429897,1 +train_0431,-1.89088782,2.15057948,-2.19356723,-1.31298123,1 +train_0432,-0.09406738,-0.92888050,2.15988231,-2.23154450,0 +train_0433,-2.29429810,1.94660267,2.10371968,1.77463421,0 +train_0434,-1.14133763,1.70949540,0.26848394,0.88681065,0 +train_0435,1.61163881,0.40949901,0.24960154,-0.15204330,0 +train_0436,-0.20766085,1.05956628,-0.61892451,-0.43801161,0 +train_0437,-0.74657049,-1.76453576,-0.25427131,-1.86107863,0 +train_0438,1.31670367,0.99592704,1.95615315,-1.87535918,0 +train_0439,-0.91040692,-1.87233034,2.11812085,-0.93779406,0 +train_0440,-2.35721902,-0.81642807,0.73588536,-1.10377546,1 +train_0441,-0.74451575,0.74139119,2.11295421,2.21482270,0 +train_0442,-2.41184663,-2.00822578,2.24968056,0.99034912,0 +train_0443,0.21556563,-1.40307250,2.19870139,-2.22946454,0 +train_0444,-1.69924450,-1.51397148,0.30218445,-1.87625498,0 +train_0445,-1.17917149,-1.86112897,0.01967041,1.36356454,0 +train_0446,1.20558809,-1.26537580,1.60936741,-2.04319277,0 +train_0447,-0.72060570,-1.60674073,-1.12953369,2.04864115,0 +train_0448,2.49915245,-1.24015363,0.62638078,-0.12468226,0 +train_0449,0.21109370,0.39721740,2.18165787,-0.55599837,0 +train_0450,-0.73228483,0.71909577,-2.08029900,-0.98110869,0 +train_0451,2.07020005,-1.66755240,1.06578369,1.09146769,1 +train_0452,-0.49791171,-1.52539257,-1.32936653,0.01862580,1 +train_0453,-2.11160143,0.51779899,0.97224680,-2.10283211,0 +train_0454,1.87831959,2.11535315,-1.38080271,1.66917196,1 +train_0455,-0.73297938,0.94334879,0.23621095,1.44464877,0 +train_0456,-1.99434961,-0.30583170,0.26407371,-0.98448385,0 +train_0457,-2.49021828,-1.85302522,1.21206828,1.93425040,0 +train_0458,1.42029066,-1.94505828,1.97899584,-0.47147894,1 +train_0459,-2.01111758,-0.39919894,1.29255926,-0.54476010,0 +train_0460,-0.33907679,0.73261681,-1.27378297,-2.40980828,0 +train_0461,0.24469283,-1.69282878,2.08812617,1.78972924,0 +train_0462,1.91481440,0.13927033,1.89247186,-2.32425196,0 +train_0463,-1.97113236,-0.09797337,2.28365517,1.49636921,0 +train_0464,1.58094694,2.41711050,-2.17356042,2.46297709,1 +train_0465,-0.60913785,-0.20283158,-0.62923758,0.49033958,0 +train_0466,-1.66830368,-0.05936522,-1.14962631,1.35568116,0 +train_0467,0.77379287,0.21304091,2.23758492,1.02975998,0 +train_0468,-2.24998572,-1.95193430,-2.13970255,0.40733188,1 +train_0469,-0.53682511,-0.09780924,1.97016297,-0.66735645,0 +train_0470,-2.07618282,-0.73774030,0.62728306,-0.19103549,0 +train_0471,-1.42629386,0.62637902,1.81887902,-0.91727311,0 +train_0472,-1.23056945,2.17034552,-0.23427094,1.94116117,0 +train_0473,-0.73221924,1.99559627,1.59838920,1.90215047,0 +train_0474,2.07103747,0.42467170,2.06551817,2.35844989,0 +train_0475,-0.74924233,1.78139906,1.14877982,-1.23435825,0 +train_0476,-2.19209028,0.91756063,2.25554148,0.44960293,0 +train_0477,-2.31504444,-0.39859773,-0.08741846,-0.29643820,0 +train_0478,-1.00222798,1.23029847,2.31825237,-2.38592487,0 +train_0479,-2.19532606,2.42101106,-0.65033065,0.91490069,1 +train_0480,1.04713483,-0.11667997,0.01925571,2.35947824,0 +train_0481,-2.40243424,-0.07021963,2.06300388,-0.73423150,0 +train_0482,-0.85026222,0.07740415,-1.82849853,-0.37603489,0 +train_0483,-1.78641861,1.51583820,1.81802526,-1.16350402,0 +train_0484,-0.91261303,-1.27019153,2.30474958,2.21639399,0 +train_0485,-1.54533858,-1.81361365,0.10701389,1.88805318,0 +train_0486,2.23853210,0.23478808,-2.40913119,1.21069440,1 +train_0487,-1.15892377,1.47719029,1.15228764,0.74438452,0 +train_0488,-2.45184997,-0.59406174,1.56834978,0.54157951,0 +train_0489,-1.09503925,-0.22933046,1.79270804,0.19289327,0 +train_0490,0.75169431,0.64024481,-1.98338929,-2.27454746,0 +train_0491,-1.16118182,1.81223729,-1.81634314,2.44847064,0 +train_0492,-0.61445070,1.20424359,0.59704474,0.39140152,0 +train_0493,1.20823901,-0.42092820,0.53220310,-0.06643644,0 +train_0494,0.82669163,1.29028647,1.89665461,-0.77707516,0 +train_0495,-0.61796455,-2.12693280,1.89612180,-1.80300443,0 +train_0496,-2.25213035,1.17802103,0.23929742,1.21518545,0 +train_0497,-1.13043852,-1.55873465,-1.92588954,1.13209018,1 +train_0498,0.34259782,-0.35031092,-0.24624592,-0.24029391,1 +train_0499,-0.83483667,1.74162196,1.11121553,1.76370744,0 +train_0500,-1.68283938,-2.48628131,-1.50913449,1.22383678,1 +train_0501,1.13053857,-0.54731314,2.07160106,1.41443951,0 +train_0502,0.01264088,0.72145235,0.15622881,2.10510194,0 +train_0503,0.65749077,-0.36741684,1.81793451,1.34418121,0 +train_0504,0.94979599,0.92270330,-0.47344690,1.06621611,1 +train_0505,-1.49959362,-1.76811831,0.39398909,0.58571877,0 +train_0506,1.20873613,1.88967483,-1.92672335,-1.88094734,1 +train_0507,2.21600016,-1.02489546,0.54198069,-2.12151281,0 +train_0508,0.14827686,-1.69839346,-0.40347242,-0.01671881,1 +train_0509,-1.44750952,-0.94058074,0.62723996,-2.35216820,0 +train_0510,0.89114270,-0.24732341,-1.85984569,0.47438886,1 +train_0511,-0.51883681,1.16456220,-0.93739315,-0.12052825,0 +train_0512,2.12392806,0.71735907,2.48006650,2.18609184,0 +train_0513,-0.25615482,1.48703864,1.43649819,1.35546344,0 +train_0514,0.90492725,-1.66220655,-2.09369674,-0.55561256,1 +train_0515,0.02250029,-0.72263455,-1.52465290,-0.81334931,1 +train_0516,2.17413471,0.65333548,-2.24710303,-1.04091585,0 +train_0517,1.52688873,-0.96910464,1.20358632,1.92429088,0 +train_0518,0.13389203,0.77795854,-0.60666894,1.37344217,0 +train_0519,2.24826069,1.08928330,0.63874165,-0.35919160,0 +train_0520,-0.44643268,-0.69405190,1.48629870,-1.35139984,0 +train_0521,-2.15515497,-1.24197341,1.67354266,-1.71347780,0 +train_0522,0.94904483,-0.33367133,2.17075440,0.10302650,0 +train_0523,0.93408461,1.65231303,2.10055856,1.94576922,0 +train_0524,-0.48283698,-2.14502906,1.26855067,1.22224942,1 +train_0525,-0.63912061,-0.00044307,-1.88603320,-0.57439686,1 +train_0526,-1.23981395,-0.88518310,0.09661426,-0.76192349,0 +train_0527,-2.03178315,1.12918322,-0.31434036,2.33448377,0 +train_0528,1.66069269,0.30660060,0.85347946,1.59759636,0 +train_0529,0.74811104,-1.32294649,1.89735524,-1.80180896,0 +train_0530,-0.11557993,-0.30541100,1.31165236,1.96977107,0 +train_0531,-0.62934337,1.46334077,0.12110530,-2.02413514,0 +train_0532,-1.77413092,0.57230894,-0.13204048,-1.37204085,0 +train_0533,0.30624519,-1.81708723,-0.07534676,-0.38322161,1 +train_0534,-1.24710503,0.21587720,1.07952035,0.82144014,0 +train_0535,0.20931097,0.86896867,1.92575774,0.70584494,0 +train_0536,-1.11304439,1.78595053,0.22868244,1.87353041,0 +train_0537,-1.20522506,-1.56771722,0.04200381,2.37153129,0 +train_0538,1.27051384,0.34836959,1.64513394,-0.23882139,0 +train_0539,-1.41979559,0.57861568,-1.93222039,-2.42136852,0 +train_0540,-1.23267616,-0.56159825,1.30099218,1.03333756,0 +train_0541,1.52863790,-2.11869834,-2.12471276,2.46276345,1 +train_0542,-0.88188415,2.34949408,-0.93631125,-1.92813289,1 +train_0543,-2.05405724,0.53736877,0.69484127,0.71656371,0 +train_0544,1.89126258,-0.27182019,0.38988508,2.42356804,0 +train_0545,1.20236028,-1.29016944,0.39233843,0.15121841,1 +train_0546,-0.99868935,-1.79259009,0.91434222,-2.05240302,0 +train_0547,-0.93994095,0.09331251,-1.83157049,0.83929888,0 +train_0548,-0.78058868,1.55183505,-0.92399996,-2.02152216,0 +train_0549,1.94700577,-0.67524218,0.83428066,0.80116760,0 +train_0550,-0.97220161,1.41173153,-1.67408816,1.70074399,0 +train_0551,-1.85118780,-1.36378305,1.52027432,0.00107055,0 +train_0552,-0.49769899,1.63299601,0.20736330,1.42740956,0 +train_0553,0.11792527,1.21521247,0.91047989,-0.01129249,0 +train_0554,1.90756136,0.41899797,1.75842074,-1.34070979,0 +train_0555,-2.38840865,-0.53598032,2.31180983,-0.51376262,0 +train_0556,-1.21420802,0.02825206,-1.17944557,2.28448323,0 +train_0557,0.08586311,-1.24029697,1.52492615,-1.03786878,0 +train_0558,1.94274196,0.88813715,0.73735545,-0.66323850,0 +train_0559,2.42964543,0.16248874,-1.13655564,-0.99036975,0 +train_0560,1.75208708,-1.52719196,-1.46001058,2.22575558,1 +train_0561,1.91975554,0.30526540,1.31099340,-2.23608992,0 +train_0562,-2.36419185,1.53071096,-1.32620974,1.86924667,0 +train_0563,0.10377518,0.36187385,1.30040330,-2.20298534,0 +train_0564,0.34232018,1.06296123,1.98303943,1.59988173,0 +train_0565,0.14271143,0.09504545,-2.10073715,-2.35443834,0 +train_0566,-0.90443228,2.02315447,2.47645314,-2.33097334,0 +train_0567,-2.47320703,-0.34981246,1.90554473,-0.63904761,0 +train_0568,-1.37493062,1.72066974,0.57633008,0.77719141,0 +train_0569,2.20203576,0.55379996,0.31392922,-1.57377518,0 +train_0570,-1.85947555,-0.56612719,0.33071751,-0.96875175,0 +train_0571,0.37187548,1.26138407,1.16976370,1.72457529,0 +train_0572,-0.02655695,1.19337880,0.40852588,-1.79500785,0 +train_0573,-0.37825027,-1.48361157,-2.23695039,-0.44777311,1 +train_0574,2.36846611,2.03654474,-1.61170317,1.41092207,1 +train_0575,1.03464182,-0.75298132,1.59066498,0.59594249,0 +train_0576,-0.85930070,0.06718911,0.75645413,-2.08091804,0 +train_0577,-1.36888097,-0.31698054,-1.42221286,2.12577966,0 +train_0578,0.38341920,-0.67378612,1.72039864,-1.74217687,0 +train_0579,1.64060722,0.47340892,-1.64913126,-1.82073565,0 +train_0580,0.55178598,0.96295125,1.13396531,-1.40788084,0 +train_0581,0.97709453,-0.25968104,0.62585547,-1.60901117,0 +train_0582,-0.33831643,1.60989245,1.34273074,0.79035021,0 +train_0583,0.43622329,-0.17431385,2.34936161,0.57004951,0 +train_0584,1.16353233,2.15113745,-1.25456865,-1.59826718,1 +train_0585,-0.50385217,0.85188164,0.00660441,-0.43408544,0 +train_0586,-0.59266662,-2.07782724,2.08384574,-0.23865526,0 +train_0587,-1.63827679,0.74306214,1.38134540,-1.91140750,0 +train_0588,-1.23775946,-0.27870340,-0.16873727,-1.76964404,0 +train_0589,-0.89292824,0.69191277,0.47363162,-1.22543610,0 +train_0590,0.72173695,2.39920551,-2.23084687,2.13902498,1 +train_0591,0.13994433,-1.91169278,-0.16709454,2.26666733,1 +train_0592,-1.12386857,-0.64490255,2.32464136,1.14809003,0 +train_0593,-0.00832461,1.89729795,-0.68781246,-1.40613655,1 +train_0594,-1.95346225,0.91211765,-0.15826629,-0.48681104,0 +train_0595,-1.21186588,-1.66716044,2.32568329,1.07439129,0 +train_0596,2.00997683,-1.43239818,1.06280197,-0.03269827,1 +train_0597,1.23541148,-1.99661673,1.15462147,1.66613772,1 +train_0598,-0.96730155,1.12872226,-0.67339803,2.15477503,0 +train_0599,-1.80897036,-0.94003521,-0.53782533,0.48113722,0 +train_0600,-1.61549641,-1.99824133,0.19950654,-0.19340093,1 +train_0601,-0.60818773,-1.00490523,-0.65588929,1.42075219,0 +train_0602,-1.99501571,-1.06190455,-0.33954945,0.88962572,0 +train_0603,0.82838039,1.10861359,0.87731861,-1.82220543,0 +train_0604,-1.50746429,1.46326040,1.04213497,-1.95690334,0 +train_0605,-1.94084468,2.12566660,1.87147642,-1.72615446,1 +train_0606,1.13374991,2.44472367,1.27072587,-1.68315108,1 +train_0607,0.32550069,0.61781974,-1.90270906,-0.62967403,1 +train_0608,-0.76734867,0.35738539,-0.48853235,1.28843479,0 +train_0609,-2.03732293,0.21243384,0.42389885,1.92851296,0 +train_0610,-2.44590305,-2.12907589,-0.65450053,1.31915189,1 +train_0611,-0.60954897,-0.42864157,-2.18048777,-1.48321942,0 +train_0612,-1.65233141,2.14454041,1.72376714,-2.46636892,0 +train_0613,-1.47395432,-2.07011735,-0.57281543,0.07178769,1 +train_0614,-0.74205985,0.24372593,-0.16869177,-2.29650136,0 +train_0615,2.09806247,0.17899810,1.45888260,-2.09124100,0 +train_0616,0.11847926,0.39820612,0.05342771,1.03164895,0 +train_0617,2.03769331,2.39735131,-1.42703997,-1.08887745,1 +train_0618,1.88206639,-2.04706336,-2.04106991,-2.35418075,1 +train_0619,1.51810721,0.68429355,-0.59902822,-1.38548762,0 +train_0620,-0.95623698,1.10346340,-2.08155469,0.94424954,1 +train_0621,0.40074716,1.44869551,1.90340405,1.29617259,0 +train_0622,1.44145756,0.56137222,-0.90914434,-1.97067423,0 +train_0623,-1.96119438,1.88887886,-1.20172573,-1.78726723,1 +train_0624,2.36277806,-1.26903348,0.79772939,0.81525727,1 +train_0625,1.25022880,0.21131848,2.29134072,0.47482097,0 +train_0626,1.02767445,-2.28096292,-0.98890935,0.47916009,1 +train_0627,2.32694972,0.47820173,1.02606091,1.02849660,0 +train_0628,1.07476939,-0.60282934,1.85260612,-0.49686582,0 +train_0629,-0.88379791,-2.06025350,-0.95172305,-2.15921817,1 +train_0630,-0.86079863,-0.94846803,2.09796370,-1.58003319,0 +train_0631,-0.44580546,0.66266575,2.06651882,-0.11252398,0 +train_0632,0.57753559,0.07303963,0.58389750,-2.26886051,0 +train_0633,0.23436504,-0.89759905,-1.57743512,-2.22376105,0 +train_0634,-0.29413683,-2.28647923,-0.14916905,-0.56157720,1 +train_0635,-1.86614683,1.95080717,-1.44675794,-2.11465476,1 +train_0636,1.76023832,-0.33236554,-1.12632736,2.14615191,1 +train_0637,-1.07566876,1.03113918,1.68690501,-1.65924906,0 +train_0638,-0.39431565,-1.71773327,0.79339395,2.06853475,0 +train_0639,2.29840674,-0.18049744,-2.45855052,-1.19405011,0 +train_0640,-0.82676763,-1.62524537,2.47810552,-1.85780982,0 +train_0641,0.28362963,0.35540334,2.06790906,-0.86793055,0 +train_0642,-0.05127597,0.33104371,-0.75250636,1.75262762,0 +train_0643,2.46847376,-0.32836305,-2.46206279,2.45914886,1 +train_0644,-1.15737990,-1.27253457,1.84162444,-1.36189637,0 +train_0645,-0.58012793,-0.76061450,1.14738993,1.04604484,0 +train_0646,0.74730187,-1.60206703,-1.00512743,-0.67986258,1 +train_0647,-0.91613821,-1.75407522,1.57495219,-1.02328266,0 +train_0648,-1.53539657,-0.01305114,-0.21973640,-0.72458637,0 +train_0649,-2.47478180,-0.99869165,-0.15974844,1.83783387,0 +train_0650,-2.10948598,-1.06991795,0.32570831,2.19739963,0 +train_0651,1.82405575,-1.94663240,-2.19735584,-1.08865391,1 +train_0652,-0.60870877,0.33175908,2.12602592,1.43755568,0 +train_0653,0.20807075,1.29464605,0.76865184,2.08044338,0 +train_0654,2.08007934,1.17295330,2.45771219,0.38848013,0 +train_0655,1.84229994,0.58803895,-0.48735137,-0.56374163,0 +train_0656,0.71649586,1.23469624,-0.79735461,-2.31508920,0 +train_0657,-2.22795423,1.32150031,0.32226238,-0.97445811,1 +train_0658,-1.15790086,1.13763585,0.50707473,1.17890934,0 +train_0659,-0.18192545,-0.15225341,-0.96237012,-1.80855199,0 +train_0660,-0.45461223,-0.43547752,2.15215547,2.16046810,0 +train_0661,2.11700602,1.62017633,0.96825546,-0.43643374,1 +train_0662,0.78194013,1.89635556,2.39749641,-0.90013764,0 +train_0663,-0.71870510,-0.26621757,0.02639712,-1.32647978,0 +train_0664,-2.43022543,0.48486055,-0.23209930,2.00159155,0 +train_0665,-0.11793164,-0.66285330,0.35608958,-1.89867474,0 +train_0666,1.42362258,2.23575819,-1.20153689,-0.95868697,1 +train_0667,0.91094154,1.50568820,1.69399703,0.58071492,1 +train_0668,-1.10733117,1.35212244,1.76585891,0.00060946,0 +train_0669,-0.33856335,-1.27514649,0.62553541,2.34424554,0 +train_0670,-2.02726131,-0.81122435,-1.60418508,0.11238077,0 +train_0671,0.33941176,-1.77025468,0.15999911,-1.59772369,1 +train_0672,-0.76715492,1.15653383,1.91425787,1.30551575,0 +train_0673,1.58124292,-0.99926958,-1.48424216,-2.44775697,0 +train_0674,1.97508224,1.83567341,0.37128491,-1.05663940,0 +train_0675,1.55218752,0.39745387,0.57663202,2.18557746,1 +train_0676,0.91557714,0.98430790,2.19477947,-2.27590752,0 +train_0677,-0.17731435,1.13723926,1.98031853,-1.69321714,0 +train_0678,-0.83025875,2.10026391,1.08537138,1.99271867,0 +train_0679,0.70482016,-0.04054209,1.21410488,0.14269286,0 +train_0680,-2.37492526,-1.02964200,2.04432808,-0.62870021,0 +train_0681,0.69916797,0.46939369,-1.25788851,-1.29180265,0 +train_0682,-0.03712750,2.02736008,2.30592489,1.90462096,0 +train_0683,1.70184788,-0.24967211,2.09230591,1.09357665,0 +train_0684,1.52815655,1.50616553,-0.81600488,-2.34914844,0 +train_0685,2.39994541,0.51246732,1.32391279,1.40364624,0 +train_0686,0.01071575,-0.23382157,2.37499843,0.96319736,0 +train_0687,-0.32276906,-1.77197541,-0.14402488,1.41462307,0 +train_0688,2.13342600,0.04218496,1.25670125,1.17329030,0 +train_0689,-2.01327380,1.48475323,0.63610135,0.30139659,0 +train_0690,-0.69573603,2.21031993,-0.23145075,0.04856352,1 +train_0691,-1.71309479,2.01510463,0.46917594,2.44132943,0 +train_0692,0.74500070,-0.41033517,1.68099512,2.22382901,0 +train_0693,-0.84753167,0.17342047,-1.39351995,0.92448158,0 +train_0694,-0.29963592,-0.44678129,0.27280597,1.10580997,0 +train_0695,2.03720987,-1.46395216,0.83788233,-2.32272239,0 +train_0696,1.55925374,-0.38471504,0.47646759,-0.95971491,1 +train_0697,-0.93782428,-1.89971399,-2.42667360,0.34481766,1 +train_0698,-0.18505998,-0.07412389,1.75254349,-1.73135755,0 +train_0699,-2.12072771,0.26434330,1.32854645,0.94541735,0 +train_0700,-1.76433125,-1.04773464,1.40461304,0.73682052,0 +train_0701,-1.38966674,-0.62582337,0.18285446,-1.71782913,0 +train_0702,0.88274134,1.12698024,1.87537439,2.37830500,0 +train_0703,0.28931694,-1.24017753,2.48968060,-1.57834445,0 +train_0704,2.49986092,-0.47300931,-1.92206288,0.22726440,0 +train_0705,-1.03065938,0.27077639,0.08563225,0.70266078,0 +train_0706,0.17861147,-0.53829520,2.21244230,2.42828934,0 +train_0707,-0.64339026,1.65576479,1.60101147,2.07710390,0 +train_0708,2.18845840,0.47535412,-1.16900296,-1.68152137,0 +train_0709,-0.12240395,0.42279627,-2.16540098,-0.36001770,1 +train_0710,-1.65788625,1.96715156,2.10440075,1.13119128,0 +train_0711,1.50100543,0.21283377,0.72594063,-0.56417359,0 +train_0712,-2.22700035,-0.93321620,1.06003507,-2.39114569,0 +train_0713,-1.70231686,1.59967359,1.11963015,-0.74855809,1 +train_0714,0.86032510,1.09414550,1.26420675,-0.40000550,0 +train_0715,-2.48606484,-1.76756527,2.09368102,-0.26747397,0 +train_0716,1.08876646,0.48554744,0.18783786,1.89548875,1 +train_0717,-1.41836289,0.08156735,-2.22661334,1.84863735,0 +train_0718,-0.57479056,0.82126795,-1.78716339,1.85640513,0 +train_0719,1.88763887,0.35101805,1.48641965,1.60499586,0 +train_0720,1.21176555,-0.07293916,2.46517077,-0.36802910,0 +train_0721,-1.50004505,-1.53616727,1.60129358,0.53437694,0 +train_0722,0.25867011,-1.26585928,1.75220669,-1.93525557,0 +train_0723,-0.57998386,0.13623960,-0.22229018,0.17176841,0 +train_0724,-0.40059307,0.20880188,1.37074173,-1.09165738,0 +train_0725,-0.47054189,0.59807114,0.38005142,-0.19515261,0 +train_0726,-1.47708519,1.25615354,0.48396439,-0.54646755,0 +train_0727,2.23929189,-1.81371468,-0.00368361,-2.46187680,0 +train_0728,0.26696047,2.13828320,0.88352553,1.45247755,1 +train_0729,-1.19715982,-0.17606090,-1.79987176,-0.77181588,0 +train_0730,0.29701850,0.88378858,1.11658687,-2.22985505,0 +train_0731,-0.82831514,0.93618436,0.89403817,-1.51860203,0 +train_0732,-1.73484391,-1.35085284,-1.64754538,0.69521558,1 +train_0733,-2.07762817,0.64030659,1.33441111,1.76700483,0 +train_0734,0.75651996,0.83404696,-0.64108525,-1.70890773,0 +train_0735,-1.76504860,-1.85778331,-0.76639303,0.84893126,0 +train_0736,0.18664837,1.04206050,0.25760874,-1.42341468,0 +train_0737,-0.44558510,-1.72490998,1.67631412,0.74470173,0 +train_0738,-1.45579354,-0.43969235,-2.06820498,1.90380543,0 +train_0739,2.02608901,1.49652306,2.17045956,-0.70866678,0 +train_0740,-0.32156966,1.87724911,0.76786694,1.88293503,1 +train_0741,-1.51627616,2.16770985,2.17475769,-1.40590656,1 +train_0742,-1.39474080,1.25282131,0.81308575,2.22686007,0 +train_0743,1.93469352,1.54530966,0.54729768,2.33766893,1 +train_0744,-2.31686939,1.43564801,1.75779728,-2.10154585,0 +train_0745,2.10351262,2.15764647,2.32392585,1.86161005,1 +train_0746,-0.13999258,-0.48329104,-1.70768352,2.12912113,0 +train_0747,2.05681108,0.03391128,-0.10428678,2.40326546,0 +train_0748,-2.03081965,-0.97494804,1.31948553,-0.47246024,0 +train_0749,0.15907534,1.94964034,1.72557292,-1.01391329,0 +train_0750,-0.30780446,-1.93822400,0.57104890,-1.85285312,0 +train_0751,0.39403223,-1.18197963,1.83821412,1.33112263,0 +train_0752,-0.46396110,-0.83512830,-1.40599827,0.58375418,0 +train_0753,2.29805534,1.11380461,-0.96388414,-1.69995527,0 +train_0754,1.87755152,-0.86487694,-1.20584417,-2.33708425,0 +train_0755,1.67434439,1.49204905,-1.51220607,0.60847687,1 +train_0756,0.14239729,0.54686895,1.62349957,-0.15275225,0 +train_0757,1.26850855,1.99162303,-1.30496893,0.78388401,1 +train_0758,1.52723302,-0.59017574,-1.89393581,0.87888436,1 +train_0759,1.86014730,-1.22113983,-2.01382675,-1.11462137,1 +train_0760,0.00346972,1.41455756,2.02739484,2.03376359,0 +train_0761,1.80470313,2.04451324,1.79127490,0.52612335,1 +train_0762,1.25484937,-0.10767560,2.32984035,-0.07512666,0 +train_0763,2.04001469,1.84647103,1.75846453,-0.08126486,1 +train_0764,-0.52329634,-0.55705938,2.04900309,0.91895748,0 +train_0765,-0.13908760,0.83893627,0.70421227,1.91658349,0 +train_0766,-1.07101458,0.81733978,1.95033086,-0.10331917,0 +train_0767,-0.38335954,-1.63259369,-1.18570602,1.39608445,1 +train_0768,0.44393236,0.83386238,-1.45566520,-1.53375041,0 +train_0769,-0.66609926,1.58924817,0.05274197,-1.62990405,1 +train_0770,-2.30976422,-0.84720676,2.00602339,1.42978050,0 +train_0771,-2.18802935,-1.27534500,1.14359231,-0.69772317,0 +train_0772,1.95323692,-1.36787000,1.01416033,-0.54757482,0 +train_0773,1.38596309,2.31782894,-0.77582071,-1.98026129,1 +train_0774,-0.14215490,-0.02336217,0.67841388,-0.67736350,0 +train_0775,0.74009859,0.53523635,-2.12042578,0.41568335,1 +train_0776,2.42501963,2.38744690,1.74123755,-2.39163599,0 +train_0777,0.61652328,-1.96334695,2.06374705,0.13619603,1 +train_0778,-0.38290443,-1.61245819,-0.41667059,2.27293395,0 +train_0779,0.85446537,0.40867037,1.54584547,1.62905086,0 +train_0780,0.42075006,1.90101636,-1.75468896,-2.11003424,1 +train_0781,1.14409864,2.09829900,-1.21710179,0.90388632,1 +train_0782,0.57605480,1.96821321,1.45321653,-0.81509755,1 +train_0783,0.87855364,0.51320778,1.58281026,2.44837833,0 +train_0784,-1.98380545,-0.24971401,1.03202680,1.89453540,0 +train_0785,-0.44129353,-1.21265580,0.03793766,-0.85249766,0 +train_0786,2.10509254,-0.44362741,-2.24003470,-1.99381777,0 +train_0787,0.86665334,-1.79923709,-1.61107720,-1.01429092,1 +train_0788,-1.59854709,-0.20268684,-0.77874876,2.30963818,0 +train_0789,-0.70344772,1.23155843,-0.35119188,2.46544357,0 +train_0790,-0.03074980,0.22700938,-1.49216303,0.72062012,0 +train_0791,2.35336904,-2.25477139,1.45510290,1.02139101,1 +train_0792,-1.29976705,-0.91307756,-1.55733316,-1.43762561,1 +train_0793,2.11945468,-1.91965072,1.50817445,-2.02167251,0 +train_0794,0.53128748,-0.51332626,1.60463048,1.60565554,0 +train_0795,-1.84616038,1.80915289,1.89034252,1.44156082,0 +train_0796,-1.91182012,1.93825730,0.86653584,-0.57106088,1 +train_0797,0.18081058,1.30672954,-0.90275792,2.44760470,0 +train_0798,1.84597953,-1.99806367,1.14945606,0.98968850,1 +train_0799,-1.99194424,-1.06267434,-1.64064033,1.79978703,0 +train_0800,-0.49541901,-1.53573571,0.37175583,-1.15316191,0 +train_0801,-1.65170176,-2.06721386,1.74655161,1.51899929,0 +train_0802,-0.54971111,-1.60416888,0.96502169,0.45814332,0 +train_0803,2.13808906,-1.98981032,1.71740150,2.33306645,1 +train_0804,0.20174085,0.38295644,-1.58441317,-0.06543373,1 +train_0805,-0.28209133,-1.88182352,1.52958671,-2.03842563,0 +train_0806,1.75789153,0.29125211,2.16640411,-1.13488972,0 +train_0807,1.57498611,1.58435131,2.43061241,-1.16799182,0 +train_0808,0.05814629,1.26642729,0.55667406,1.98278786,0 +train_0809,-2.00875234,-0.93276012,-1.30263496,-2.19064672,1 +train_0810,-2.38326438,-1.53656875,-0.30861993,-1.52234849,1 +train_0811,1.46333521,-1.00447695,2.29221756,-2.19736708,0 +train_0812,0.43921146,0.36954808,2.34309211,0.71415868,0 +train_0813,-0.59961885,2.18717172,0.27256262,-0.22969359,1 +train_0814,-1.09489067,1.76472002,0.68232054,1.48322060,0 +train_0815,1.35848030,0.18314279,-0.25759978,1.31598967,1 +train_0816,2.33345951,0.45386849,0.88973590,2.30140261,0 +train_0817,-2.14188050,1.72772218,0.57344189,2.08595501,0 +train_0818,0.31484571,0.47496936,0.93570237,-1.78062407,0 +train_0819,-0.34268222,-0.44591330,2.40546253,-1.07460333,0 +train_0820,2.41478428,1.15771267,1.99708434,-2.18061037,0 +train_0821,0.96973613,-0.47192580,2.45232035,2.02446985,0 +train_0822,-0.64592920,1.13659892,1.23544752,-1.51053029,0 +train_0823,-1.27621028,1.64709551,-0.53544644,-1.50549614,1 +train_0824,1.14705046,1.65274077,-0.84206594,-0.58145507,1 +train_0825,2.48956455,-0.48239371,-0.94216118,-1.86533915,0 +train_0826,-1.45628664,0.90891201,1.72493103,-0.68266113,0 +train_0827,-1.35859933,-0.45398162,-1.02915370,1.79454181,0 +train_0828,1.69063229,1.29647362,0.78811567,0.76614738,1 +train_0829,2.31964955,-1.15220263,-1.54912461,-1.38767257,0 +train_0830,1.17089872,-0.29146103,2.27536441,-2.46264302,0 +train_0831,1.13562457,-2.01979391,-1.21332675,1.89719795,1 +train_0832,-0.29403050,-0.54589487,0.74072856,-2.16550442,0 +train_0833,-0.00583708,1.25973382,2.28330164,-2.41169823,0 +train_0834,-1.11802556,1.18146169,0.99022314,-0.71871481,0 +train_0835,2.03684360,-0.68057132,1.80563460,0.88610666,0 +train_0836,-1.45735918,-0.86760036,-2.23571642,1.67883996,0 +train_0837,-1.82328123,-1.82028969,-0.87738497,1.98972653,0 +train_0838,-2.33935365,0.04773069,2.24442084,1.92810481,0 +train_0839,-0.70642475,0.02973485,-1.49443482,2.34268149,0 +train_0840,1.25503495,1.31602602,1.33595020,-0.15290785,1 +train_0841,0.81376000,1.24537690,-1.93143071,-2.48992921,0 +train_0842,0.21631992,-0.05270860,-0.02287855,-0.65278640,0 +train_0843,0.56096896,-2.36479812,0.96486109,-2.23065297,1 +train_0844,-1.57606710,1.64068327,2.14068505,1.33274721,0 +train_0845,-0.31142177,1.41007751,2.49571954,1.55411650,0 +train_0846,-1.77876802,-1.05683043,-0.09428489,-1.43031394,0 +train_0847,-1.38212873,1.10631366,1.25994195,-2.15208128,0 +train_0848,-1.22369434,0.92529952,-1.32254822,0.76754777,0 +train_0849,-2.32585097,0.57533471,1.07013147,-1.01920005,0 +train_0850,0.19672796,0.79206933,-1.05626875,2.03511388,0 +train_0851,-1.05072263,-0.13301003,1.90854140,1.98331152,0 +train_0852,-1.45107745,0.42317286,1.98858470,0.82160115,0 +train_0853,1.00204775,0.49113382,0.09804284,-1.39180701,0 +train_0854,2.42848277,0.34202675,0.20290352,-1.74357951,0 +train_0855,-1.40310355,-2.34951530,0.21427066,0.57324367,1 +train_0856,0.21300668,0.49873156,1.97539863,1.41018728,0 +train_0857,1.60675234,-1.36387286,-1.44681700,0.40628571,1 +train_0858,-0.27274886,1.32386963,0.08888895,2.26839452,0 +train_0859,2.34510583,-0.17326622,2.38397302,2.03750779,0 +train_0860,-2.09560769,0.79043377,1.38319772,0.37671039,0 +train_0861,-1.17208859,-0.25774055,-1.75496716,2.25754787,0 +train_0862,-1.28665678,1.95852242,1.75679358,1.63756385,0 +train_0863,-0.24198348,1.16676523,2.34685171,-0.94908400,0 +train_0864,-2.03190818,0.20396019,1.98762904,2.37162249,0 +train_0865,2.30549823,-1.79712758,-0.99094128,1.84543480,1 +train_0866,-0.27219353,1.67439209,0.51528452,-1.41389805,0 +train_0867,0.32365873,-0.18423646,2.20036252,-0.20382947,0 +train_0868,-1.34407000,-0.54883981,-1.94457380,1.82602151,0 +train_0869,0.19474045,-0.51387280,-0.60830026,-1.11708839,0 +train_0870,-0.72645980,-1.54723900,-1.36248047,1.08700335,0 +train_0871,-2.08842511,-0.65230323,1.06006857,0.02819709,0 +train_0872,-1.28474867,-0.60475688,1.33462762,-0.90382716,0 +train_0873,-1.17710857,-0.06065744,-0.78599282,-1.12374645,0 +train_0874,1.96444075,1.11770444,0.81611772,-0.27913370,1 +train_0875,-1.17030911,2.43323855,-1.44794898,1.72857710,1 +train_0876,1.89763282,2.34759136,-0.37485369,-1.78758730,1 +train_0877,-0.84147599,-0.37770960,0.93468205,-2.02804732,0 +train_0878,-1.16011318,1.08327619,1.87934087,-2.39686631,0 +train_0879,-1.50814973,-2.21558832,0.50290510,-0.93633514,1 +train_0880,-2.27311687,-0.31304314,2.36703701,-0.63717742,0 +train_0881,-0.76541585,0.58043897,2.03013715,0.06875773,0 +train_0882,-0.73153697,0.45062814,-0.43484860,2.11737320,0 +train_0883,1.40455552,-1.35840927,-0.24205204,-2.18427889,0 +train_0884,-0.25917283,-1.36439557,0.70640996,-0.73469486,0 +train_0885,2.25299878,-0.46991126,-0.62538244,-1.92442923,0 +train_0886,-0.97860410,-1.74182907,1.91387894,1.23727340,0 +train_0887,-1.28064570,-0.57695840,-0.24830678,1.13927054,0 +train_0888,1.35029160,-1.21301168,-2.46759962,-0.63475204,1 +train_0889,2.26327289,0.42982009,-0.20247013,1.61138686,1 +train_0890,-1.47794389,-0.04299202,-0.49965759,0.87887788,0 +train_0891,-2.11310896,1.79568621,0.05517766,-1.96159291,1 +train_0892,1.04123508,0.50503667,-1.85847861,-0.83853539,1 +train_0893,0.20535908,1.06550443,0.36308159,-0.44614344,0 +train_0894,0.92390503,-1.61816907,1.44834214,-0.37921633,0 +train_0895,-0.15029524,1.90213351,-0.48378874,0.45221880,1 +train_0896,1.01897693,0.30979930,1.78502446,1.69020949,0 +train_0897,-1.50854501,0.82569494,2.27217237,-2.44235283,0 +train_0898,1.49378330,-0.96150166,0.64840584,2.49447560,1 +train_0899,1.87928713,-0.31198949,0.10338707,-1.59122652,0 +train_0900,0.54683825,-0.59818012,-0.67686770,0.27567728,0 +train_0901,-2.42426996,2.40684614,-1.69997393,-0.70388951,1 +train_0902,1.92241338,1.00481522,-1.77180243,-1.92220374,0 +train_0903,-1.60421608,-0.61525057,1.21886120,1.90496266,0 +train_0904,1.73765402,2.25069381,1.56556237,-2.03058655,0 +train_0905,0.40196387,0.65885552,-0.49341606,-0.55957453,1 +train_0906,-0.92971629,-1.19235918,1.62028701,-0.38537080,0 +train_0907,0.45163309,0.35064465,-0.03020385,1.05814043,0 +train_0908,1.61592504,-1.45848869,-0.32125826,1.86008542,1 +train_0909,0.81454681,-0.06209557,1.21372132,-0.09049404,0 +train_0910,0.56407292,0.96415777,-0.32624497,0.65388122,1 +train_0911,-1.66792197,2.24838453,-1.69642395,1.96825590,1 +train_0912,0.16163572,-1.09537263,-1.19497496,-1.90258271,0 +train_0913,-1.21924201,-1.42564473,-1.70772359,0.96057558,0 +train_0914,1.62518688,0.07825237,-2.04399215,0.45697527,1 +train_0915,-1.25148172,-0.04279974,0.47499965,-1.55561831,0 +train_0916,1.05138390,0.42256886,0.47755416,-1.44839284,0 +train_0917,1.67503315,-2.48124113,-0.53663467,-1.48531875,1 +train_0918,-0.53897943,-1.95105891,1.93303199,1.25583044,0 +train_0919,1.11378069,0.19847715,-2.05695540,2.31367407,1 +train_0920,-2.42614916,-2.43838888,1.72518698,-0.78965661,1 +train_0921,1.69518166,-0.43628492,-1.80697313,-1.83596305,0 +train_0922,0.06166523,-0.48881284,1.98554546,0.35188765,0 +train_0923,-1.51209485,-0.45612166,2.43964599,0.14220387,0 +train_0924,-1.32071316,-1.32221332,-0.17992424,1.32533869,0 +train_0925,2.28019820,-1.92065000,-1.35151492,0.62608842,1 +train_0926,-1.12910116,0.66776325,1.30403220,1.06027970,0 +train_0927,-0.55029101,-2.11209466,2.48616823,0.25094972,0 +train_0928,-1.28785764,-0.61874877,-0.17617437,-0.33451288,0 +train_0929,2.48484499,-0.02782143,-1.46667498,-1.23200041,0 +train_0930,1.71071488,0.43185303,0.23961626,-1.91021913,0 +train_0931,-0.76901271,-1.23680480,0.20468847,1.43659199,0 +train_0932,1.51711218,0.25603758,1.37361150,-0.83858722,0 +train_0933,-1.11790498,0.72379511,1.50159336,-1.65003433,0 +train_0934,-0.90456919,-1.71825920,0.68082565,0.56108794,0 +train_0935,0.47451731,2.26594675,-0.62256778,-1.67401335,1 +train_0936,1.81687848,-0.58747763,-1.30089910,-2.10544462,0 +train_0937,1.33815839,-0.34319485,1.31008614,-0.12547341,0 +train_0938,2.23937483,-2.23460617,-0.55379994,1.75444003,1 +train_0939,-1.50460455,2.15499926,0.95441901,2.26083335,0 +train_0940,-1.73847477,0.36161426,-2.28317180,1.26169125,0 +train_0941,-0.48642510,-2.14632011,-1.61026462,0.64178958,1 +train_0942,-0.62436016,-2.42858959,0.44148523,1.30459114,1 +train_0943,-0.50142421,0.24076476,-0.63929111,2.14048871,0 +train_0944,-0.72662284,1.48010118,0.49627567,-1.25197948,0 +train_0945,-0.62730693,-1.95027371,2.38564798,0.50700070,0 +train_0946,-1.82974720,0.60826966,1.38979385,0.78159891,0 +train_0947,0.46760710,-0.49488716,1.49125010,-0.97847912,0 +train_0948,0.07510129,1.05391847,0.36407866,-2.48575137,0 +train_0949,-2.22811980,1.57400079,0.41215217,2.29482781,0 +train_0950,-1.37721858,-2.00801102,-1.09747680,-1.09141286,1 +train_0951,1.71017633,-0.66259974,1.28437931,-0.29548988,0 +train_0952,-0.32805977,-0.17796978,1.93036065,0.99053591,0 +train_0953,-1.89417717,0.53995562,2.47684822,-0.64312253,0 +train_0954,-0.34012266,-1.35753346,0.89808686,-2.44138027,0 +train_0955,-1.40232567,-0.92309339,1.55701863,-1.26518772,0 +train_0956,0.25520922,-1.89028066,1.57716615,2.44832293,0 +train_0957,1.06824389,-0.94925084,2.36906638,0.03933833,0 +train_0958,-2.31880825,-0.41177786,-1.60379694,2.01255966,0 +train_0959,-0.75771362,0.10778463,2.47259218,-0.62632341,0 +train_0960,-0.92892819,-1.31638873,-1.48165665,1.48804143,0 +train_0961,-0.11178245,-1.10001449,-1.66407392,1.86066804,0 +train_0962,-0.57587173,0.81513325,2.33720024,-0.34269658,0 +train_0963,-0.56609079,0.53126603,-0.86729581,1.72911129,0 +train_0964,0.53549370,-1.27783195,-2.49968309,-0.08255794,1 +train_0965,0.39351772,-0.57335266,-0.24001906,-0.64016572,1 +train_0966,1.58152133,1.28320395,-1.62428340,-1.84915474,0 +train_0967,0.77354126,0.02815355,-0.51504454,2.22077484,0 +train_0968,2.01147873,1.15101644,0.09431044,-1.04414380,0 +train_0969,2.11598619,1.53820709,0.98672997,-1.26775014,0 +train_0970,-0.54878386,-0.10553641,-1.24840279,0.26239613,0 +train_0971,0.38997001,-1.29106068,-0.49344061,2.34289078,0 +train_0972,0.99691964,-1.49551159,1.90522454,-0.32831165,0 +train_0973,0.18088914,-1.52419974,0.10027428,-2.49061917,0 +train_0974,2.21027446,-1.08092918,0.25244126,-2.38853978,0 +train_0975,1.26672836,0.45547773,1.56691049,1.31516129,0 +train_0976,1.00469274,1.97764304,0.15187662,-1.86452732,1 +train_0977,0.83566639,1.03132410,2.28424205,-2.00453653,0 +train_0978,-0.06325355,0.93132552,-0.63170863,0.55635850,0 +train_0979,-1.66106352,1.60931843,1.61325835,1.24710307,0 +train_0980,-0.58173144,2.40442655,1.49764523,1.21619963,1 +train_0981,0.31956389,1.56251513,-1.33448959,2.24532506,0 +train_0982,-0.45877541,-0.14704730,-0.45699009,-0.90047778,0 +train_0983,-1.44391910,0.58614275,-1.24951966,2.03310704,0 +train_0984,1.64224828,0.53770441,-0.20737344,-1.34011520,0 +train_0985,2.21524098,-1.66916567,0.35116584,0.74280600,1 +train_0986,-0.95866819,1.73255910,-2.26148354,-0.31952917,1 +train_0987,-2.29560935,-0.90203527,2.26336733,-0.57386768,0 +train_0988,-0.89745987,-1.29085310,-0.28186214,0.82186597,0 +train_0989,-2.14121170,-2.08107654,-0.69733788,-2.36366536,1 +train_0990,-1.52190215,0.52131097,1.27704438,1.34088665,0 +train_0991,-1.95741275,-2.19411279,-1.87804580,-1.39587579,1 +train_0992,1.36739808,0.69827409,2.07113931,-1.50857801,0 +train_0993,-1.73288553,1.07471206,0.26806354,-0.82024106,0 +train_0994,-0.55211987,-0.31936131,-1.96646207,1.44061236,0 +train_0995,-2.42483691,0.74435575,2.12751699,0.83714047,0 +train_0996,-0.43043466,-1.24748515,-0.94775360,-1.94737635,0 +train_0997,1.64195261,-1.22110751,2.30106368,1.62206863,0 +train_0998,-1.93384417,-0.54440408,2.24002129,1.08509235,0 +train_0999,1.11876022,1.17264887,1.01849562,-1.13105358,0 +train_1000,-0.78850586,-1.39683225,-2.31394731,2.02073576,0 diff --git a/Lab2/entrega/curva_umbral.png b/Lab2/entrega/curva_umbral.png new file mode 100644 index 0000000..12da04e Binary files /dev/null and b/Lab2/entrega/curva_umbral.png differ diff --git a/Lab2/entrega/curvas_entrenamiento.png b/Lab2/entrega/curvas_entrenamiento.png new file mode 100644 index 0000000..6a19c26 Binary files /dev/null and b/Lab2/entrega/curvas_entrenamiento.png differ diff --git a/Lab2/entrega/modelo_elegido.npz b/Lab2/entrega/modelo_elegido.npz new file mode 100644 index 0000000..8c4552e Binary files /dev/null and b/Lab2/entrega/modelo_elegido.npz differ diff --git a/Lab2/entrega_solucion/modelo_elegido.npz b/Lab2/entrega_solucion/modelo_elegido.npz new file mode 100755 index 0000000..4845995 Binary files /dev/null and b/Lab2/entrega_solucion/modelo_elegido.npz differ diff --git a/Lab2/generar_datos.py b/Lab2/generar_datos.py new file mode 100755 index 0000000..b499187 --- /dev/null +++ b/Lab2/generar_datos.py @@ -0,0 +1,54 @@ +"""Genera los datos públicos y privados del laboratorio de forma reproducible.""" +from __future__ import annotations +import csv +from pathlib import Path +import numpy as np + +SEMILLA = 20260815 +COLUMNAS = ("id", "x1", "x2", "x3", "x4", "etiqueta") + +def ecuacion_analitica(x, error): + x1, x2, x3, x4 = x.T + puntuacion = np.sin(1.25*x1) + 0.72*x2**2 - 0.78*x3 + 0.42*x1*x4 - 0.28*x4**2 + error + return (puntuacion > 0.82).astype(np.int64) + +def muestra_por_clase(rng, negativos, positivos): + pendientes = {0: negativos, 1: positivos} + xs, ys = [], [] + while any(pendientes.values()): + x = rng.uniform(-2.5, 2.5, size=(600, 4)) + y = ecuacion_analitica(x, rng.normal(0.0, 0.48, size=600)) + for clase in (0, 1): + indice = np.flatnonzero(y == clase)[:pendientes[clase]] + if len(indice): + xs.append(x[indice]); ys.append(y[indice]); pendientes[clase] -= len(indice) + x, y = np.concatenate(xs), np.concatenate(ys) + orden = rng.permutation(len(y)) + return x[orden], y[orden] + +def guardar(ruta, x, y, prefijo): + ruta.parent.mkdir(parents=True, exist_ok=True) + with ruta.open("w", encoding="utf-8", newline="") as archivo: + escritor = csv.writer(archivo); escritor.writerow(COLUMNAS) + for n, (fila, etiqueta) in enumerate(zip(x, y), 1): + escritor.writerow([f"{prefijo}_{n:04d}", *[f"{z:.8f}" for z in fila], int(etiqueta)]) + +def main(): + raiz = Path(__file__).resolve().parent + rng = np.random.default_rng(SEMILLA) + x, y = muestra_por_clase(rng, 750, 250) + guardar(raiz/"datos_publicos"/"train_1000_desbalanceado.csv", x, y, "train") + ejemplo = raiz/"datos_publicos"/"ejemplo_entrada_inferencia.csv" + with ejemplo.open("w", encoding="utf-8", newline="") as archivo: + escritor = csv.writer(archivo) + escritor.writerow(("id", "x1", "x2", "x3", "x4")) + for n, fila in enumerate(x[:12], 1): + escritor.writerow([f"ejemplo_{n:04d}", *[f"{z:.8f}" for z in fila]]) + x, y = muestra_por_clase(rng, 100, 100) + guardar(raiz/"instructor_privado"/"test_200_balanceado.csv", x, y, "test") + (raiz/"datos_publicos"/"README.md").write_text("# Datos públicos\n\nEl archivo train_1000_desbalanceado.csv contiene 1,000 ejemplos: 750 de la clase 0 y 250 de la clase 1. Las entradas son x1, x2, x3 y x4; etiqueta es el objetivo.\n", encoding="utf-8") + (raiz/"instructor_privado"/"README.md").write_text("# Material privado del instructor\n\nNo compartir test_200_balanceado.csv. Tiene 200 ejemplos exactamente balanceados, 100 por clase, para la evaluación final.\n", encoding="utf-8") + print("Datos generados: train=1000 (750/250); test privado=200 (100/100).") + +if __name__ == "__main__": + main() diff --git a/Lab2/instructor_privado/README.md b/Lab2/instructor_privado/README.md new file mode 100755 index 0000000..831243b --- /dev/null +++ b/Lab2/instructor_privado/README.md @@ -0,0 +1,3 @@ +# Material privado del instructor + +No compartir test_200_balanceado.csv. Tiene 200 ejemplos exactamente balanceados, 100 por clase, para la evaluación final. diff --git a/Lab2/instructor_privado/artefactos/curvas_solucion.png b/Lab2/instructor_privado/artefactos/curvas_solucion.png new file mode 100755 index 0000000..e581b53 Binary files /dev/null and b/Lab2/instructor_privado/artefactos/curvas_solucion.png differ diff --git a/Lab2/instructor_privado/artefactos/modelo_mejor.npz b/Lab2/instructor_privado/artefactos/modelo_mejor.npz new file mode 100755 index 0000000..5edad68 Binary files /dev/null and b/Lab2/instructor_privado/artefactos/modelo_mejor.npz differ diff --git a/Lab2/instructor_privado/artefactos/resumen_solucion.json b/Lab2/instructor_privado/artefactos/resumen_solucion.json new file mode 100755 index 0000000..1af3a96 --- /dev/null +++ b/Lab2/instructor_privado/artefactos/resumen_solucion.json @@ -0,0 +1,66 @@ +{ + "split": { + "train": 800, + "dev": 200, + "clase_1_train": 200, + "clase_1_dev": 50 + }, + "candidatos": [ + { + "arquitectura": { + "tipo": "mlp", + "entrada": 4, + "ocultas": [ + 32, + 16 + ] + }, + "costo_dev": 41, + "umbral_dev": 0.4049999999999999, + "accuracy_dev": 0.895, + "precision_dev": 0.7377049180327869, + "recall_dev": 0.9, + "f1_dev": 0.8108108108108109 + }, + { + "arquitectura": { + "tipo": "mlp_residual_bn", + "entrada": 4, + "ancho": 32 + }, + "costo_dev": 48, + "umbral_dev": 0.05, + "accuracy_dev": 0.84, + "precision_dev": 0.6216216216216216, + "recall_dev": 0.92, + "f1_dev": 0.7419354838709677 + } + ], + "mejor": { + "arquitectura": { + "tipo": "mlp", + "entrada": 4, + "ocultas": [ + 32, + 16 + ] + }, + "costo_dev": 41, + "umbral_dev": 0.4049999999999999, + "accuracy_dev": 0.895, + "precision_dev": 0.7377049180327869, + "recall_dev": 0.9, + "f1_dev": 0.8108108108108109 + }, + "evaluacion_privada": { + "tp": 85, + "fp": 13, + "fn": 15, + "tn": 87, + "accuracy": 0.86, + "precision": 0.8673469387755102, + "recall": 0.85, + "especificidad": 0.87, + "f1": 0.8585858585858585 + } +} \ No newline at end of file diff --git a/Lab2/instructor_privado/test_200_balanceado.csv b/Lab2/instructor_privado/test_200_balanceado.csv new file mode 100755 index 0000000..1f0f4bc --- /dev/null +++ b/Lab2/instructor_privado/test_200_balanceado.csv @@ -0,0 +1,201 @@ +id,x1,x2,x3,x4,etiqueta +test_0001,-1.45329337,-0.80200976,1.29580787,1.22693757,0 +test_0002,-0.52045331,-0.68697770,-1.40199533,1.54980569,0 +test_0003,-0.09167948,-1.15753259,-1.23926112,-2.05578252,0 +test_0004,-0.95562309,2.23947848,-0.97812000,-0.37391722,1 +test_0005,1.34148897,1.01976166,-1.83249406,1.26312340,1 +test_0006,-0.60382765,-0.42498739,1.22335123,-0.31705208,0 +test_0007,0.18621612,0.41779976,-2.14357433,-2.17898694,1 +test_0008,2.11219013,2.16090114,1.16426707,-1.84287756,0 +test_0009,0.82408644,-2.18348522,1.39197130,-2.01817722,1 +test_0010,-0.68030530,-2.23125657,-2.08941012,1.74167698,1 +test_0011,-2.35824483,-1.28573773,1.29431772,-0.20780914,0 +test_0012,2.11852923,-2.36071958,0.70308976,0.18373273,1 +test_0013,-1.67552723,1.95656447,2.18541988,-1.92263682,0 +test_0014,-0.20424576,2.00422273,2.41835481,0.82287635,0 +test_0015,1.62452182,-2.19005084,0.44618990,0.99007682,1 +test_0016,1.73397093,0.66315434,0.71497331,0.97717974,0 +test_0017,-2.36006033,0.42995369,-2.19505378,-0.31249831,1 +test_0018,1.69117922,-1.88231376,-0.55647826,-2.48874896,1 +test_0019,2.26095193,2.01167391,-1.98860354,-1.30947931,1 +test_0020,-2.08186391,0.80842148,-0.71459713,-1.17981069,1 +test_0021,0.60296969,1.05032325,-1.19790752,-2.24469607,0 +test_0022,0.06976761,-1.26603746,0.97647176,1.16616602,0 +test_0023,-2.16865011,-0.45891806,-1.28671892,0.66225600,0 +test_0024,0.49667051,-1.67151035,-1.03456036,-0.44059422,1 +test_0025,1.03159092,-2.40759248,-1.18394129,-1.25790615,1 +test_0026,1.57952323,-1.07244028,-2.43149390,0.63345346,1 +test_0027,0.13735245,-0.43567881,-0.54721837,-1.70363302,0 +test_0028,-1.90781183,-0.88389181,-0.34347431,1.96026037,0 +test_0029,0.96159706,1.91297323,1.90110582,-1.28053751,1 +test_0030,-2.26873577,1.98767750,-2.23958875,0.64968906,1 +test_0031,-2.00316907,0.71745776,0.86613662,1.76053487,0 +test_0032,-2.45578718,-0.13125501,1.96488336,-1.84651659,0 +test_0033,-0.67572968,-0.06126132,1.42320774,0.02233957,0 +test_0034,1.32482990,2.44076184,0.32482658,1.29013522,1 +test_0035,0.24476376,0.36764926,0.22911212,1.43762596,0 +test_0036,0.54969604,-2.13096766,1.10118906,0.42006305,1 +test_0037,-0.26726884,-1.54382713,-1.44717731,-0.92288292,1 +test_0038,1.40974942,0.58111562,1.00359615,-0.47467149,0 +test_0039,0.24965433,-0.98576518,0.10741817,-2.42164401,0 +test_0040,-2.16194096,-2.07738078,0.36869224,1.89891176,0 +test_0041,-0.06726050,-0.22152113,2.23315436,1.87187572,0 +test_0042,0.45718322,-1.90091108,1.57001435,-1.65792686,0 +test_0043,-2.18459398,1.20082129,-0.77987085,-1.37370548,1 +test_0044,-1.59159843,1.30176166,2.34034269,-2.01184840,0 +test_0045,2.25388348,-1.64404019,-1.91145566,2.42391413,1 +test_0046,2.16611394,-1.48313696,-0.36738261,0.64232959,1 +test_0047,-0.31113493,1.69809874,2.36299659,-0.48603705,0 +test_0048,-1.24941210,-0.28803499,-0.86646972,-0.19631142,0 +test_0049,-1.94501563,-2.41616468,2.07088800,-1.95012774,1 +test_0050,-1.83257121,-0.88768063,-1.98256403,-0.29783165,1 +test_0051,0.16047757,-1.25975942,1.61511934,-0.74494231,0 +test_0052,2.31577261,1.18243490,-1.80013917,1.00554226,1 +test_0053,-1.09179959,-0.36923188,-1.23969889,2.25487871,0 +test_0054,-0.14822303,-0.95022517,-2.36470503,-1.84141731,1 +test_0055,1.77175207,-0.33538042,-2.05550804,-0.01691591,1 +test_0056,0.19813051,2.17931603,2.10657280,-2.14620972,0 +test_0057,-0.39470845,1.16613610,-1.13228061,-0.54310162,1 +test_0058,-0.14970876,0.89414771,0.40800137,1.58418574,0 +test_0059,2.49857886,-0.04437076,0.61949553,-0.03382795,0 +test_0060,0.83732642,-0.48623062,-1.97966632,1.30435953,1 +test_0061,1.55460215,2.32672323,1.74610970,0.74218193,1 +test_0062,1.78819140,0.59594612,0.85060473,-1.91082888,0 +test_0063,-2.14346879,2.47045733,-2.44238526,-1.46627921,1 +test_0064,2.38806503,-1.08699012,1.60109508,-2.40569650,0 +test_0065,0.59316658,-0.16780638,-0.67948597,-1.07304932,0 +test_0066,-2.24844187,0.73646848,-0.75090338,-2.16317527,1 +test_0067,2.03343004,1.96296342,-1.12705154,-0.79836152,1 +test_0068,1.63543612,0.90086255,2.10038823,0.27145194,0 +test_0069,2.30425516,-1.42251118,1.03950495,2.12923819,0 +test_0070,-1.90434601,-0.56559933,-0.68051150,-2.04794981,0 +test_0071,0.16933848,-1.45869995,0.95382899,0.07099242,1 +test_0072,-0.62419535,-1.84917292,-0.13990795,-2.33577645,0 +test_0073,0.92333651,-2.40842454,1.50109107,-1.38579681,1 +test_0074,-1.69447584,0.02847724,0.38192945,-2.11056830,0 +test_0075,0.09334503,0.30772728,-0.03146323,-2.05359311,0 +test_0076,0.01358586,-2.28170631,2.42432526,1.85723762,1 +test_0077,-1.19217760,1.91295366,-0.98624024,-0.70372065,1 +test_0078,0.67059249,0.81869234,-0.09079115,-0.09327915,0 +test_0079,-1.35376536,-0.44382773,-0.94712589,1.78565187,0 +test_0080,-0.60730785,-1.41680375,0.08145395,-1.36936940,0 +test_0081,2.35699375,0.78325978,-1.80833117,0.72802736,1 +test_0082,0.63086133,-1.49935097,-1.70914798,1.44214895,1 +test_0083,-2.42748607,0.85924177,-2.09692344,0.22377841,1 +test_0084,-1.31325624,-1.93071210,-0.09472675,0.68914311,0 +test_0085,1.23908276,0.98596048,2.21314844,0.65154351,1 +test_0086,0.14961595,-0.24398627,-0.45056574,-0.42777022,0 +test_0087,1.25871123,0.60615861,-0.69371829,-0.59495777,0 +test_0088,-0.91227054,0.69118054,2.02635968,1.77828215,0 +test_0089,-0.83869894,0.76593256,-0.49577409,-0.43492475,0 +test_0090,-1.66530589,2.44910222,-1.57113334,0.73054060,1 +test_0091,-1.89585896,2.40074559,0.07165437,-2.24429887,1 +test_0092,-1.74167063,-0.83882977,0.47400933,1.86572658,0 +test_0093,-0.49298474,1.03984063,-1.14411905,0.59369068,0 +test_0094,-1.67642716,-2.10752991,1.89351133,-0.91951711,0 +test_0095,2.11585366,-0.18961527,0.74863511,0.77890455,1 +test_0096,0.29991196,-1.96098617,1.48007879,2.48250993,0 +test_0097,-0.11910194,-0.47242821,-2.24062159,-2.40340404,0 +test_0098,-0.98286999,1.08827497,0.01598984,0.23765656,0 +test_0099,-1.29372176,-0.34978669,-2.29364454,1.49697292,0 +test_0100,-0.90665183,1.13854694,0.47737863,1.50534383,0 +test_0101,1.75271206,-1.98582639,0.59173025,-2.25588044,0 +test_0102,0.91463402,0.49026878,1.62948890,-2.45095511,0 +test_0103,1.69123326,1.41298407,-2.01001064,-2.32060632,0 +test_0104,-1.67766279,-1.43435384,-2.11647264,2.49811505,0 +test_0105,-1.80144033,0.45373587,-2.16173209,-0.67985384,1 +test_0106,0.59391963,-1.99721464,-0.64362664,0.39148548,1 +test_0107,1.07519274,-1.02326075,1.07132256,-1.34998648,0 +test_0108,-1.61872105,-2.43797584,-1.98749349,2.03329457,1 +test_0109,-1.07774354,0.16030905,1.03025212,-0.86615910,0 +test_0110,-2.38347676,0.49667620,0.08810167,-0.34257172,0 +test_0111,-2.07833560,0.80057867,-0.96619428,-1.23069979,1 +test_0112,-1.58705044,-1.06636337,0.35707168,0.97993168,0 +test_0113,0.68680677,-0.43151628,-2.07827137,0.04313296,1 +test_0114,0.86882697,-1.41471475,-0.34521398,-2.23708502,0 +test_0115,-0.92371655,0.72933935,-1.84701534,-1.67426541,1 +test_0116,1.12927661,-2.20661759,-0.80473702,-0.92109921,1 +test_0117,0.75063499,-1.12182696,-1.87815189,-1.30570949,1 +test_0118,-1.54189110,-2.12068811,-0.03445788,2.19694536,0 +test_0119,1.41119451,2.28233921,1.36710184,0.03226869,1 +test_0120,1.12335658,0.92576543,2.20734014,-1.00702253,0 +test_0121,2.36918795,2.02651090,-2.13940262,2.21951023,1 +test_0122,1.24559857,2.21571139,-1.47016421,0.67513295,1 +test_0123,0.78132760,0.83636584,-1.49063294,-1.28601044,1 +test_0124,-0.42653483,-0.20226462,1.33822818,2.21708881,0 +test_0125,2.09229643,0.26185923,1.91241053,0.87587186,0 +test_0126,1.11645014,0.21659179,-1.53846650,-1.02953752,1 +test_0127,1.07644723,0.61617544,1.10957197,2.22305726,0 +test_0128,-0.53472017,1.74743289,0.43954259,0.91183298,1 +test_0129,2.06671301,-1.68453471,-2.49727568,-0.45354613,1 +test_0130,1.30846906,-2.09069057,-0.94337302,-1.38366153,1 +test_0131,-1.18821619,0.77820417,-0.44047102,0.71405693,0 +test_0132,1.00825620,1.37613516,-0.60049548,1.77367282,1 +test_0133,0.99924608,-0.46878608,1.25708870,-1.82238171,0 +test_0134,1.20923187,0.93323130,-1.07566606,-1.22741123,1 +test_0135,0.79048230,-0.58437966,-0.24593741,2.22256008,0 +test_0136,-0.78646328,0.29195737,1.05568528,0.95617044,0 +test_0137,-1.82975876,-1.79373133,0.19964861,0.26557118,1 +test_0138,0.07511816,-0.30160901,-1.70564546,1.27121744,1 +test_0139,1.82232529,0.84608299,1.48812937,0.63265312,0 +test_0140,1.48304154,-0.23175462,0.29458534,1.65723926,0 +test_0141,-1.89720659,1.03235315,-0.92870464,-2.41563946,1 +test_0142,0.70191777,1.57894788,-0.38920993,-1.31113691,1 +test_0143,2.12997911,0.25546600,-2.11885168,0.97053590,1 +test_0144,2.08125423,-1.97791338,-1.95593453,-1.43279258,1 +test_0145,-0.40414829,-0.93995837,2.21613817,-2.14350843,0 +test_0146,1.49730457,0.83614150,1.95774998,-2.04684336,0 +test_0147,0.31599577,-1.93663138,1.57165891,0.51237795,1 +test_0148,-1.12266380,-1.98768988,1.05317509,-0.74157986,0 +test_0149,2.26349408,2.36703096,-1.36109186,-0.83638554,1 +test_0150,-0.30491254,1.32350843,0.29807829,0.61762198,1 +test_0151,-1.46195082,-0.74578199,0.85586293,2.41662407,0 +test_0152,-1.60419411,-0.45724031,0.85807840,1.59964163,0 +test_0153,0.64099480,-0.73794623,-0.49725863,-0.72711901,1 +test_0154,0.74989823,-2.49668144,0.62910560,-0.77756842,1 +test_0155,0.39371566,-1.92057879,-2.19428423,-1.19302672,1 +test_0156,-1.05778903,1.08420919,2.27326487,0.98267644,0 +test_0157,2.40272972,1.57968001,1.23816567,-0.71726643,1 +test_0158,-1.05083206,-1.80725526,-0.35338123,1.71865559,0 +test_0159,-0.76141960,1.87287015,-1.64402836,0.58223314,1 +test_0160,-2.13074779,-0.00527227,-0.61736199,1.17297520,0 +test_0161,1.20382148,-2.18899859,0.17091663,1.91215298,1 +test_0162,0.77711986,0.23372772,-0.05422450,-1.59924184,0 +test_0163,1.50260590,-1.83434449,1.37518338,2.24123250,1 +test_0164,0.25640917,1.13031102,-1.51621878,2.34800905,1 +test_0165,0.27086379,-1.30615157,1.20917386,2.20912214,0 +test_0166,0.05868963,-0.43013314,1.87917447,1.51617368,0 +test_0167,-2.11811078,0.31449053,0.99168714,1.25147560,0 +test_0168,-2.39563199,2.24448153,0.78142293,-1.16573941,1 +test_0169,0.75088988,-0.69924804,-2.46954844,0.74754928,1 +test_0170,2.40373350,-0.06562730,1.71760271,-1.11570584,0 +test_0171,-0.22564064,2.45758864,1.28116831,-0.62193694,1 +test_0172,-2.20774481,1.29075955,-1.18379939,-0.20688917,1 +test_0173,-0.98214541,-1.32743540,-2.29362761,1.57875279,1 +test_0174,0.95545335,-2.22974060,-0.17911193,2.19598009,1 +test_0175,0.88527144,1.16625925,2.09386271,0.18397893,0 +test_0176,-0.52440010,1.11472336,-2.45654324,2.36389928,0 +test_0177,-0.47091838,0.03147500,-1.06883465,-2.23172693,0 +test_0178,-1.44209585,-1.66102789,-1.04403717,0.04743861,1 +test_0179,-0.75338703,-1.66413783,-1.88477911,2.18903776,1 +test_0180,2.10103457,1.07289588,-1.27030198,-0.40487401,1 +test_0181,0.85153441,0.20044776,1.87882761,1.74996884,0 +test_0182,1.75927453,-1.75921244,1.74975537,-0.82601372,1 +test_0183,2.49907267,-2.44099830,-1.21443559,2.05344654,1 +test_0184,1.40000807,2.32155007,2.41148559,1.03830643,1 +test_0185,-1.89305872,-1.04720188,-1.47374211,-0.70848786,1 +test_0186,-2.37957805,-1.78963287,2.27290346,0.88734310,0 +test_0187,-0.78091976,1.02549252,1.76628950,-2.37799837,0 +test_0188,-0.86625762,-0.30128846,-0.89844486,-2.14972633,0 +test_0189,-1.82915165,0.61862172,2.16940618,0.20235168,0 +test_0190,-1.26064826,2.18851343,-0.29151919,-0.06185392,1 +test_0191,-1.85280012,1.44904159,-2.10045311,-0.62109544,1 +test_0192,-1.60477761,-1.74361636,-1.80323793,0.82332343,1 +test_0193,0.42713831,1.06727749,0.37919761,1.44867722,1 +test_0194,-1.32165112,-1.19786516,-1.98078520,-1.33092447,1 +test_0195,0.66067093,-0.59922476,0.22879934,1.94027287,0 +test_0196,0.04861905,0.88783688,0.61098210,-0.92653606,0 +test_0197,1.77209903,0.06586325,0.17907839,1.02733614,1 +test_0198,-0.92283097,-1.48616370,2.14012563,0.18272875,0 +test_0199,0.43965858,2.04316190,-2.22104418,0.74529927,1 +test_0200,1.31857489,-0.44833159,-1.31362535,0.75549619,1 diff --git a/Lab2/lib_modelos.py b/Lab2/lib_modelos.py new file mode 100755 index 0000000..edb6ead --- /dev/null +++ b/Lab2/lib_modelos.py @@ -0,0 +1,121 @@ +"""Implementación didáctica con NumPy de MLP, residual MLP+BN y selección.""" +from __future__ import annotations +import csv, json +from pathlib import Path +import numpy as np + +CARACTERISTICAS = ("x1", "x2", "x3", "x4") + +def cargar_csv(ruta, con_etiqueta=True): + with Path(ruta).open(encoding="utf-8", newline="") as archivo: filas = list(csv.DictReader(archivo)) + x = np.array([[float(f[c]) for c in CARACTERISTICAS] for f in filas]) + ids = [f["id"] for f in filas] + return (x, np.array([int(f["etiqueta"]) for f in filas]), ids) if con_etiqueta else (x, ids) + +def division_estratificada(y, proporcion_dev=0.20, semilla=17): + rng = np.random.default_rng(semilla); train=[]; dev=[] + for c in np.unique(y): + i = rng.permutation(np.flatnonzero(y == c)); n = round(len(i)*proporcion_dev) + dev.extend(i[:n]); train.extend(i[n:]) + return rng.permutation(train), rng.permutation(dev) + +def ajustar_estandarizador(x): + media=x.mean(0); desviacion=x.std(0) + return media, np.where(desviacion < 1e-12, 1.0, desviacion) + +def transformar(x, media, desviacion): return (x-media)/desviacion +def sigmoide(z): return 1/(1+np.exp(-np.clip(z, -40, 40))) + +def metricas(y, p, umbral=.5): + pred=(p>=umbral).astype(int); tp=int(((pred==1)&(y==1)).sum()); fp=int(((pred==1)&(y==0)).sum()) + fn=int(((pred==0)&(y==1)).sum()); tn=int(((pred==0)&(y==0)).sum()) + precision=tp/max(tp+fp,1); recall=tp/max(tp+fn,1); f1=2*precision*recall/max(precision+recall,1e-12) + return dict(tp=tp,fp=fp,fn=fn,tn=tn,accuracy=(tp+tn)/len(y),precision=precision,recall=recall,especificidad=tn/max(tn+fp,1),f1=f1) + +def buscar_umbral(y,p,costo_fn=5,costo_fp=1): + filas=[] + for t in np.linspace(.05,.95,181): + m=metricas(y,p,t); filas.append(dict(umbral=float(t),costo=costo_fn*m["fn"]+costo_fp*m["fp"],**m)) + return min(filas,key=lambda z:(z["costo"],-z["f1"])),filas + +def _bn_adelante(z, entrenando, media, var): + if entrenando: + mu=z.mean(0,keepdims=True); va=z.var(0,keepdims=True); media[:]=.9*media+.1*mu; var[:]=.9*var+.1*va + else: mu,va=media,var + inv=1/np.sqrt(va+1e-5); hat=(z-mu)*inv + return hat,(hat,inv) +def _bn_atras(d,c): + hat,inv=c; n=len(d) + return inv/n*(n*d-d.sum(0,keepdims=True)-hat*(d*hat).sum(0,keepdims=True)) + +class MLP: + arquitectura="mlp" + def __init__(self, entrada=4, ocultas=(32,16), semilla=0): + r=np.random.default_rng(semilla); ds=(entrada,)+tuple(ocultas)+(1,) + self.params={f"{v}{i}": (r.normal(0,np.sqrt(2/ds[i]),(ds[i],ds[i+1])) if v=="W" else np.zeros((1,ds[i+1]))) for i in range(len(ds)-1) for v in ("W","b")} + def forward(self,x,entrenando=True): + a=[x]; z=[]; h=x; n=len(self.params)//2-1 + for i in range(n): z.append(h@self.params[f"W{i}"]+self.params[f"b{i}"]); h=np.maximum(z[-1],0); a.append(h) + return h@self.params[f"W{n}"]+self.params[f"b{n}"],(a,z) + def probabilidad(self,x): return sigmoide(self.forward(x,False)[0]).ravel() + def perdida_y_gradiente(self,x,y,peso_positivo=1): + l,c=self.forward(x); yy=y[:,None]; w=np.where(yy==1,peso_positivo,1); p=sigmoide(l); d=(p-yy)*w/w.sum() + loss=np.sum(w*(np.maximum(l,0)-l*yy+np.log1p(np.exp(-np.abs(l)))))/w.sum(); a,z=c; n=len(self.params)//2-1; g={f"W{n}":a[-1].T@d,f"b{n}":d.sum(0,keepdims=True)}; dh=d@self.params[f"W{n}"].T + for i in range(n-1,-1,-1): + dz=dh*(z[i]>0); g[f"W{i}"]=a[i].T@dz; g[f"b{i}"]=dz.sum(0,keepdims=True); dh=dz@self.params[f"W{i}"].T + return float(loss),g + +class MLPResidualBN: + arquitectura="mlp_residual_bn" + def __init__(self,entrada=4,ancho=32,semilla=0): + r=np.random.default_rng(semilla); ini=lambda a,b:r.normal(0,np.sqrt(2/a),(a,b)) + self.params={"Win":ini(entrada,ancho),"bin":np.zeros((1,ancho)),"W1":ini(ancho,ancho),"b1":np.zeros((1,ancho)),"W2":ini(ancho,ancho),"b2":np.zeros((1,ancho)),"Wout":ini(ancho,1),"bout":np.zeros((1,1))} + self.media={k:np.zeros((1,ancho)) for k in ("in","1","2")}; self.var={k:np.ones((1,ancho)) for k in ("in","1","2")} + def forward(self,x,entrenando=True): + zi=x@self.params["Win"]+self.params["bin"]; ni,ci=_bn_adelante(zi,entrenando,self.media["in"],self.var["in"]); h0=np.maximum(ni,0) + z1=h0@self.params["W1"]+self.params["b1"]; n1,c1=_bn_adelante(z1,entrenando,self.media["1"],self.var["1"]); a1=np.maximum(n1,0) + z2=a1@self.params["W2"]+self.params["b2"]; n2,c2=_bn_adelante(z2,entrenando,self.media["2"],self.var["2"]); suma=h0+n2; h=np.maximum(suma,0) + return h@self.params["Wout"]+self.params["bout"],(x,ni,h0,n1,a1,n2,suma,h,ci,c1,c2) + def probabilidad(self,x): return sigmoide(self.forward(x,False)[0]).ravel() + def perdida_y_gradiente(self,x,y,peso_positivo=1): + l,c=self.forward(x,True); yy=y[:,None]; w=np.where(yy==1,peso_positivo,1); d=(sigmoide(l)-yy)*w/w.sum(); loss=np.sum(w*(np.maximum(l,0)-l*yy+np.log1p(np.exp(-np.abs(l)))))/w.sum() + x,ni,h0,n1,a1,n2,suma,h,ci,c1,c2=c; g={"Wout":h.T@d,"bout":d.sum(0,keepdims=True)}; ds=(d@self.params["Wout"].T)*(suma>0); dh0=ds.copy() + dz2=_bn_atras(ds,c2); g["W2"]=a1.T@dz2; g["b2"]=dz2.sum(0,keepdims=True); dn1=(dz2@self.params["W2"].T)*(n1>0) + dz1=_bn_atras(dn1,c1); g["W1"]=h0.T@dz1; g["b1"]=dz1.sum(0,keepdims=True); dh0+=dz1@self.params["W1"].T + dzi=_bn_atras(dh0*(ni>0),ci); g["Win"]=x.T@dzi; g["bin"]=dzi.sum(0,keepdims=True) + return float(loss),g + +def crear_modelo(a,semilla=0): + if a["tipo"]=="mlp": return MLP(a.get("entrada",4),tuple(a.get("ocultas",[32,16])),semilla) + if a["tipo"]=="mlp_residual_bn": return MLPResidualBN(a.get("entrada",4),a.get("ancho",32),semilla) + raise ValueError("Arquitectura desconocida") + +def entrenar(modelo,x,y,xd,yd,epocas=120,batch_size=64,learning_rate=.002,peso_positivo=None,semilla=0): + peso_positivo=peso_positivo or float((y==0).sum()/max((y==1).sum(),1)); r=np.random.default_rng(semilla); estado={k:[np.zeros_like(v),np.zeros_like(v)] for k,v in modelo.params.items()}; h={k:[] for k in ("loss_train","loss_dev","accuracy_dev","f1_dev")}; paso=0 + for e in range(epocas): + for inicio in r.permutation(np.arange(0,len(y),batch_size)): + ind=np.arange(inicio,min(inicio+batch_size,len(y))); _,g=modelo.perdida_y_gradiente(x[ind],y[ind],peso_positivo); paso+=1 + for k,v in modelo.params.items(): + m,s=estado[k]; m[:]=.9*m+.1*g[k]; s[:]=.999*s+.001*g[k]**2; v[:]-=learning_rate*(m/(1-.9**paso))/(np.sqrt(s/(1-.999**paso))+1e-8) + lt,_=modelo.perdida_y_gradiente(x,y,peso_positivo); ld,_=modelo.perdida_y_gradiente(xd,yd,peso_positivo); met=metricas(yd,modelo.probabilidad(xd)) + h["loss_train"].append(lt);h["loss_dev"].append(ld);h["accuracy_dev"].append(met["accuracy"]);h["f1_dev"].append(met["f1"]) + return h + +def buscar_hiperparametros(configs,x,y,xd,yd,semilla=0): + filas=[] + for i,c in enumerate(configs): + m=crear_modelo(c["arquitectura"],semilla+i); h=entrenar(m,x,y,xd,yd,**c["entrenamiento"],semilla=semilla+i); u,_=buscar_umbral(yd,m.probabilidad(xd),c.get("costo_fn",5),c.get("costo_fp",1)); filas.append(dict(configuracion=c,modelo=m,historia=h,**u)) + return min(filas,key=lambda z:(z["costo"],-z["f1"])),filas + +def guardar_modelo(ruta,modelo,arquitectura,media,desviacion): + ruta=Path(ruta);ruta.parent.mkdir(parents=True,exist_ok=True); d={f"param_{k}":v for k,v in modelo.params.items()};d.update(media=media,desviacion=desviacion,arquitectura_json=np.array(json.dumps(arquitectura))) + if isinstance(modelo,MLPResidualBN): + for k in modelo.media:d[f"media_bn_{k}"]=modelo.media[k];d[f"var_bn_{k}"]=modelo.var[k] + np.savez(ruta,**d) + +def cargar_modelo(ruta,arquitectura): + d=np.load(ruta,allow_pickle=False); m=crear_modelo(arquitectura) + for k in m.params:m.params[k][:]=d[f"param_{k}"] + if isinstance(m,MLPResidualBN): + for k in m.media:m.media[k][:]=d[f"media_bn_{k}"];m.var[k][:]=d[f"var_bn_{k}"] + return m,d["media"],d["desviacion"] diff --git a/Lab2/notebooks/inferencia_configurable.ipynb b/Lab2/notebooks/inferencia_configurable.ipynb new file mode 100755 index 0000000..4a44304 --- /dev/null +++ b/Lab2/notebooks/inferencia_configurable.ipynb @@ -0,0 +1,135 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Inferencia configurable\n", + "\n", + "Este notebook recibe un CSV con las columnas id, x1, x2, x3 y x4. Carga los pesos desde un diccionario que declara explícitamente la ruta y arquitectura, estandariza con los valores guardados y produce un CSV de predicciones.\n", + "\n", + "La ruta configurada por defecto es un artefacto del instructor. Para inferencia de estudiante, cambie ruta_pesos a su propio modelo exportado y mantenga una arquitectura coincidente.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Raíz del laboratorio: /home/aleleba/projects/cursos/Universidad/Procesamiento de Imagenes y Vision por Computadora/Labs/Lab2\n" + ] + } + ], + "source": [ + "from pathlib import Path\n", + "import sys\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "\n", + "candidatos = [Path.cwd().resolve(), Path.cwd().resolve() / 'dist' / 'laboratorio_clasificacion', Path.cwd().resolve().parent]\n", + "RAIZ = next((ruta for ruta in candidatos if (ruta / 'lib_modelos.py').exists()), None)\n", + "if RAIZ is None:\n", + " raise FileNotFoundError('No se encontró la carpeta laboratorio_clasificacion.')\n", + "sys.path.insert(0, str(RAIZ))\n", + "print('Raíz del laboratorio:', RAIZ)\n", + "from lib_modelos import cargar_csv, cargar_modelo, transformar\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "CONFIG_MODELOS = {\n", + " 'referencia_instructor': {\n", + " 'ruta_pesos': RAIZ / 'instructor_privado' / 'artefactos' / 'modelo_mejor.npz',\n", + " 'arquitectura': {'tipo': 'mlp', 'entrada': 4, 'ocultas': [32, 16]},\n", + " 'umbral': 0.405,\n", + " },\n", + " # Modelo propio, exportado en la sección 6 de laboratorio_estudiante.ipynb:\n", + " 'mi_modelo': {\n", + " 'ruta_pesos': RAIZ / 'entrega' / 'modelo_elegido.npz',\n", + " 'arquitectura': {'tipo': 'mlp', 'entrada': 4, 'ocultas': [48, 24]},\n", + " 'umbral': 0.315,\n", + " },\n", + "}\n", + "NOMBRE_MODELO = 'mi_modelo'\n", + "RUTA_ARCHIVO = RAIZ / 'datos_publicos' / 'ejemplo_entrada_inferencia.csv'\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Ejecución\n", + "\n", + "Cambie RUTA_ARCHIVO por el CSV recibido. No incluya la columna etiqueta: inferencia no requiere ni debe leer etiquetas.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Predicciones guardadas en: /home/aleleba/projects/cursos/Universidad/Procesamiento de Imagenes y Vision por Computadora/Labs/Lab2/datos_publicos/ejemplo_entrada_inferencia_predicciones.csv\n", + "Filas procesadas: 12\n" + ] + } + ], + "source": [ + "import csv\n", + "\n", + "config = CONFIG_MODELOS[NOMBRE_MODELO]\n", + "if not config['ruta_pesos'].exists():\n", + " raise FileNotFoundError(f\"No se encontraron los pesos: {config['ruta_pesos']}\")\n", + "if not RUTA_ARCHIVO.exists():\n", + " raise FileNotFoundError('Actualice RUTA_ARCHIVO con el archivo de entrada.')\n", + "\n", + "modelo, media, desviacion = cargar_modelo(config['ruta_pesos'], config['arquitectura'])\n", + "x, ids = cargar_csv(RUTA_ARCHIVO, con_etiqueta=False)\n", + "probabilidades = modelo.probabilidad(transformar(x, media, desviacion))\n", + "predicciones = (probabilidades >= config['umbral']).astype(int)\n", + "\n", + "salida = RUTA_ARCHIVO.with_name(RUTA_ARCHIVO.stem + '_predicciones.csv')\n", + "with salida.open('w', encoding='utf-8', newline='') as archivo:\n", + " escritor = csv.writer(archivo)\n", + " escritor.writerow(['id', 'probabilidad_clase_1', 'prediccion', 'umbral'])\n", + " for ident, p, pred in zip(ids, probabilidades, predicciones):\n", + " escritor.writerow([ident, f'{p:.8f}', int(pred), config['umbral']])\n", + "print('Predicciones guardadas en:', salida)\n", + "print('Filas procesadas:', len(ids))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Verificación de arquitectura\n", + "\n", + "Si se cambia el archivo de pesos, la entrada arquitectura debe coincidir exactamente con el modelo usado al guardarlo: tipo mlp y lista ocultas, o tipo mlp_residual_bn y ancho. El notebook falla de forma visible si las dimensiones son incompatibles.\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "name": "python", + "version": "3.x" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/Lab2/notebooks/laboratorio_estudiante.ipynb b/Lab2/notebooks/laboratorio_estudiante.ipynb new file mode 100755 index 0000000..e01db2f --- /dev/null +++ b/Lab2/notebooks/laboratorio_estudiante.ipynb @@ -0,0 +1,463 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "nm9eJW4JtsGr", + "metadata": { + "id": "nm9eJW4JtsGr" + }, + "source": [ + "# Laboratorio de clasificación tabular\n", + "\n", + "## Propósito\n", + "\n", + "Construya, compare y seleccione clasificadores binarios para un problema no lineal y desbalanceado. El único archivo de datos permitido durante desarrollo es datos_publicos/train_1000_desbalanceado.csv.\n", + "\n", + "El conjunto privado de 200 ejemplos no se entrega al estudiante. No lo use para ajustar la arquitectura, hiperparámetros, normalización ni umbral.\n", + "\n", + "## Reglas de calidad\n", + "\n", + "- Use una división estratificada fija de 800 ejemplos para entrenamiento y 200 para desarrollo.\n", + "- Ajuste cualquier transformación, incluidas media y desviación estándar, únicamente con entrenamiento.\n", + "- El entrenamiento tiene 75% de clase 0 y 25% de clase 1. Justifique cómo manejará el desbalance: peso de clase, métrica de selección y umbral.\n", + "- Compare exactamente estas familias: un MLP convencional y un MLP residual con Batch Normalization.\n", + "- Seleccione configuración y umbral usando exclusivamente desarrollo. Declare explícitamente los costos de falso negativo y falso positivo.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "luvf3DLZtsGs", + "metadata": { + "id": "luvf3DLZtsGs" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Raíz del laboratorio: /home/aleleba/projects/cursos/Universidad/Procesamiento de Imagenes y Vision por Computadora/Labs/Lab2\n" + ] + } + ], + "source": [ + "from pathlib import Path\n", + "import sys\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "\n", + "candidatos = [Path.cwd().resolve(), Path.cwd().resolve() / 'dist' / 'laboratorio_clasificacion', Path.cwd().resolve().parent]\n", + "RAIZ = next((ruta for ruta in candidatos if (ruta / 'lib_modelos.py').exists()), None)\n", + "if RAIZ is None:\n", + " raise FileNotFoundError('No se encontró la carpeta laboratorio_clasificacion.')\n", + "sys.path.insert(0, str(RAIZ))\n", + "print('Raíz del laboratorio:', RAIZ)\n" + ] + }, + { + "cell_type": "markdown", + "id": "EH5B5dnztsGs", + "metadata": { + "id": "EH5B5dnztsGs" + }, + "source": [ + "## 1. Carga, auditoría y división 800/200\n", + "\n", + "Complete la siguiente celda. Verifique los tamaños y las proporciones de clase. La función division_estratificada preserva el 75/25 en ambas particiones.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "4iZH4V99tsGs", + "metadata": { + "id": "4iZH4V99tsGs" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "800 200\n", + "0.25 0.25\n" + ] + } + ], + "source": [ + "from lib_modelos import (\n", + " cargar_csv,\n", + " division_estratificada,\n", + " ajustar_estandarizador,\n", + " transformar,\n", + ")\n", + "\n", + "# Único archivo de datos permitido durante el desarrollo.\n", + "x, y, ids = cargar_csv(RAIZ / 'datos_publicos' / 'train_1000_desbalanceado.csv')\n", + "\n", + "# División estratificada fija: 800 entrenamiento / 200 desarrollo,\n", + "# preservando la proporción 75 % clase 0 / 25 % clase 1 en ambas partes.\n", + "SEMILLA_DIVISION = 31\n", + "indice_train, indice_dev = division_estratificada(y, proporcion_dev=0.20, semilla=SEMILLA_DIVISION)\n", + "\n", + "# La media y la desviación estándar se ajustan SOLO con entrenamiento,\n", + "# para no filtrar información de desarrollo hacia el preprocesamiento.\n", + "media_entrenamiento, desviacion_entrenamiento = ajustar_estandarizador(x[indice_train])\n", + "\n", + "x_train = transformar(x[indice_train], media_entrenamiento, desviacion_entrenamiento)\n", + "x_dev = transformar(x[indice_dev], media_entrenamiento, desviacion_entrenamiento)\n", + "y_train, y_dev = y[indice_train], y[indice_dev]\n", + "\n", + "# Comprobaciones requeridas.\n", + "print(len(y_train), len(y_dev))\n", + "print(y_train.mean(), y_dev.mean())\n" + ] + }, + { + "cell_type": "markdown", + "id": "PIGc4mqFtsGs", + "metadata": { + "id": "PIGc4mqFtsGs" + }, + "source": [ + "## 2. Estrategia ante el desbalance\n", + "\n", + "Responda en esta celda:\n", + "\n", + "1. ¿Por qué accuracy sola no es suficiente?\n", + "2. ¿Qué peso positivo usará y cómo se calcula?\n", + "3. ¿Qué métrica y qué costo operacional usaría para elegir modelo y umbral?\n", + "\n", + "Luego calcule el peso positivo y escriba su valor.\n", + "\n", + "**Respuesta.**\n", + "\n", + "1. Accuracy sola no basta porque el conjunto está desbalanceado (75 % clase 0 / 25 % clase 1): un modelo que siempre prediga la clase 0 obtiene 75 % de accuracy con recall 0, es decir, nunca detecta la clase minoritaria.\n", + "2. Se usa `peso_positivo = negativos_train / positivos_train` (ver celda de código), que multiplica el costo de los errores sobre la clase 1 dentro de la BCE ponderada, compensando la proporción 3:1 de entrenamiento.\n", + "3. La selección de modelo y umbral usa el costo esperado en desarrollo `costo = costo_fn * FN + costo_fp * FP`, con `costo_fn = 5` y `costo_fp = 1` (un falso negativo cuesta cinco veces más que un falso positivo). Se reportan además precision, recall, F1, especificidad y accuracy para ver el desempeño por clase, no solo el global.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "9vNYL7qItsGs", + "metadata": { + "id": "9vNYL7qItsGs" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Peso positivo: 3.0\n" + ] + } + ], + "source": [ + "# El entrenamiento tiene 75 % clase 0 / 25 % clase 1. Para que la pérdida\n", + "# BCE ponderada no ignore la clase minoritaria, el peso positivo se calcula\n", + "# como la razón negativos/positivos en entrenamiento (compensa 3:1).\n", + "peso_positivo = (y_train == 0).sum() / (y_train == 1).sum()\n", + "print('Peso positivo:', peso_positivo)\n" + ] + }, + { + "cell_type": "markdown", + "id": "Zr2LjQa9tsGt", + "metadata": { + "id": "Zr2LjQa9tsGt" + }, + "source": [ + "## 3. Dos arquitecturas\n", + "\n", + "La biblioteca incluye:\n", + "\n", + "- MLP: capas densas ReLU y salida logística.\n", + "- MLP residual con Batch Normalization: proyección de entrada, bloque residual y salida logística.\n", + "\n", + "Defina una configuración inicial para cada familia. Mantenga fija la dimensión de entrada en 4. Utilice por lo menos dos configuraciones para cada caso con 4 o 10 capas. Explore la configuración optima en la seleción de hiperparametros.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "TcI-ymgAtsGt", + "metadata": { + "id": "TcI-ymgAtsGt" + }, + "outputs": [], + "source": [ + "configuraciones = [\n", + " { # MLP angosto y poco profundo: referencia base.\n", + " 'arquitectura': {'tipo': 'mlp', 'entrada': 4, 'ocultas': [24, 16]},\n", + " 'entrenamiento': {'epocas': 100, 'batch_size': 64, 'learning_rate': 0.003},\n", + " 'costo_fn': 5, 'costo_fp': 1,\n", + " },\n", + " { # MLP más ancho: más capacidad, learning rate algo menor.\n", + " 'arquitectura': {'tipo': 'mlp', 'entrada': 4, 'ocultas': [48, 24]},\n", + " 'entrenamiento': {'epocas': 100, 'batch_size': 64, 'learning_rate': 0.002},\n", + " 'costo_fn': 5, 'costo_fp': 1,\n", + " },\n", + " { # Residual + BatchNorm angosto.\n", + " 'arquitectura': {'tipo': 'mlp_residual_bn', 'entrada': 4, 'ancho': 24},\n", + " 'entrenamiento': {'epocas': 100, 'batch_size': 64, 'learning_rate': 0.002},\n", + " 'costo_fn': 5, 'costo_fp': 1,\n", + " },\n", + " { # Residual + BatchNorm más ancho, learning rate menor para más estabilidad.\n", + " 'arquitectura': {'tipo': 'mlp_residual_bn', 'entrada': 4, 'ancho': 40},\n", + " 'entrenamiento': {'epocas': 100, 'batch_size': 64, 'learning_rate': 0.0015},\n", + " 'costo_fn': 5, 'costo_fp': 1,\n", + " },\n", + "]\n" + ] + }, + { + "cell_type": "markdown", + "id": "xmbqjNl5tsGt", + "metadata": { + "id": "xmbqjNl5tsGt" + }, + "source": [ + "## 4. Búsqueda de hiperparámetros\n", + "\n", + "Use buscar_hiperparametros. Pruebe al menos cuatro configuraciones en total: dos MLP y dos residuales. Registre en una tabla arquitectura, ancho/capas, learning rate, épocas, costo en desarrollo, F1, recall, precision y umbral.\n", + "\n", + "No modifique el conjunto de desarrollo después de mirar los resultados; elija una regla de selección antes de comparar.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "eTgo4ia-tsGt", + "metadata": { + "id": "eTgo4ia-tsGt" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "arquitectura capas/ancho lr epocas costo f1 recall precision umbral\n", + "mlp [24, 16] 0.003 100 43 0.715 0.980 0.563 0.050\n", + "mlp [48, 24] 0.002 100 43 0.796 0.900 0.714 0.315\n", + "mlp_residual_bn 24 0.002 100 55 0.686 0.940 0.540 0.060\n", + "mlp_residual_bn 40 0.0015 100 56 0.804 0.820 0.788 0.400\n", + "Configuración seleccionada: {'tipo': 'mlp', 'entrada': 4, 'ocultas': [48, 24]}\n" + ] + } + ], + "source": [ + "from lib_modelos import buscar_hiperparametros\n", + "\n", + "mejor, resultados = buscar_hiperparametros(\n", + " configuraciones, x_train, y_train, x_dev, y_dev, semilla=41,\n", + ")\n", + "\n", + "# Tabla compacta: una fila por configuración probada, ordenadas como se declararon.\n", + "encabezado = (\n", + " f\"{'arquitectura':<16}{'capas/ancho':<14}{'lr':>8}{'epocas':>8}\"\n", + " f\"{'costo':>8}{'f1':>7}{'recall':>8}{'precision':>10}{'umbral':>8}\"\n", + ")\n", + "print(encabezado)\n", + "for fila in resultados:\n", + " arquitectura = fila['configuracion']['arquitectura']\n", + " entrenamiento = fila['configuracion']['entrenamiento']\n", + " capas_o_ancho = arquitectura.get('ocultas', arquitectura.get('ancho'))\n", + " print(\n", + " f\"{arquitectura['tipo']:<16}{str(capas_o_ancho):<14}\"\n", + " f\"{entrenamiento['learning_rate']:>8}{entrenamiento['epocas']:>8}\"\n", + " f\"{fila['costo']:>8}{fila['f1']:>7.3f}{fila['recall']:>8.3f}\"\n", + " f\"{fila['precision']:>10.3f}{fila['umbral']:>8.3f}\"\n", + " )\n", + "print('Configuración seleccionada:', mejor['configuracion']['arquitectura'])\n" + ] + }, + { + "cell_type": "markdown", + "id": "_nMKEVfHtsGt", + "metadata": { + "id": "_nMKEVfHtsGt" + }, + "source": [ + "## 5. Curvas y decisión\n", + "\n", + "Grafique pérdida de train/dev y al menos una métrica de desarrollo. Seleccione el modelo con su criterio declarado. Después genere la curva de costo contra umbral, fije el mejor umbral y reporte la matriz de confusión y las métricas en desarrollo.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "vX0KAMj4tsGt", + "metadata": { + "id": "vX0KAMj4tsGt" + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA04AAAFlCAYAAADcVLhdAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjksIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvJkbTWQAAAAlwSFlzAAAPYQAAD2EBqD+naQAAy29JREFUeJzs3Xd8U+X3wPFPundL6aKltFD2LBQpGxQQ2aAMFVkKTsSviApuUeTnQmQooixxMVUUBBFkyd67rEIp0FIo3bu5vz+eJm1oC21pm1LO+/XKK8nNzb1PiiY5ec5zjk7TNA0hhBBCCCGEEIWyMPcAhBBCCCGEEKKik8BJCCGEEEIIIW5DAichhBBCCCGEuA0JnIQQQgghhBDiNiRwEkIIIYQQQojbkMBJCCGEEEIIIW5DAichhBBCCCGEuA0JnIQQQgghhBDiNiRwEkIUyZYtW5g8eTLx8fHmHooQQgghRLmTwEmICmzkyJEEBgaaexhcuHCB/v374+zsjKur6x0da9OmTeh0OjZt2mTcVtTXef78eXQ6HQsXLryjMQghhLi7FPT+/95776HT6cw3KHHPkcBJVDhnz57lmWeeoVatWtjZ2eHi4kK7du348ssvSU1NNffw7jmZmZkMGTKEkSNH8vLLL5t7OEIIcU9auHAhOp3OeLGzs8PX15fu3bszY8YMEhMTzT1EISo9K3MPQIi8Vq9ezaBBg7C1tWX48OE0btyYjIwMtm3bxquvvsqxY8eYO3euuYd5Tzl27BiPPvooL730Upmd49tvv0Wv15fZ8YUQorKYPHkyNWvWJDMzk6ioKDZt2sT//vc/pk2bxqpVq2jatKm5hyhEpSWBk6gwwsPDefTRRwkICGDjxo1Uq1bN+NgLL7zAmTNnWL16damcKzk5GUdHx1I5VmUXHBxMcHBwkffXNI20tDTs7e2L/Bxra+sSjEwIIe49PXr0oGXLlsb7kyZNYuPGjfTu3Zu+ffty4sSJYr3/lrXCPm9L8lkhhLlJqp6oMD755BOSkpKYN2+eSdBkULt2beOsx63Wuuh0Ot577z3jfUMO9PHjx3n88cepUqUK7du357PPPkOn03HhwoV8x5g0aRI2NjbcuHEDgK1btzJo0CBq1KiBra0t/v7+vPzyy/lSB6Oiohg1ahTVq1fH1taWatWq0a9fP86fP3/b1//bb7/RuHFj7OzsaNy4Mb/++muB++n1eqZPn06jRo2ws7PD29ubZ555xjjWWxk5ciROTk6cO3eO7t274+joiK+vL5MnT0bTtBKdJzAwkN69e7Nu3TpatmyJvb0933zzDQCRkZH0798fR0dHvLy8ePnll0lPTy9wXDevcYqLi2PkyJG4urri5ubGiBEjiIuLy/fcw4cPM3LkSGNqp4+PD08++STXr1+/7d9DCCEqgwceeIC3336bCxcu8MMPPxi3nzx5koEDB+Lu7o6dnR0tW7Zk1apVJs/NzMzk/fffp06dOtjZ2VG1alXat2/P+vXrjfsU9X22sM9buPVnxblz5xg0aBDu7u44ODjQunXrEv9QmpWVxQcffEBQUBC2trYEBgbyxhtvFPjZI0RxyYyTqDD++OMPatWqRdu2bcvk+IMGDaJOnTp89NFHaJpG7969ee2111i6dCmvvvqqyb5Lly7lwQcfpEqVKgAsW7aMlJQUnnvuOapWrcru3buZOXMmkZGRLFu2zPi8Rx55hGPHjvHiiy8SGBjI1atXWb9+PREREbcsfvD333/zyCOP0LBhQ6ZOncr169eNAdjNnnnmGRYuXMioUaMYN24c4eHhzJo1iwMHDvDff//ddvYmOzubhx56iNatW/PJJ5+wdu1a3n33XbKyspg8eXKJzhMWFsZjjz3GM888w5gxY6hXrx6pqal06dKFiIgIxo0bh6+vL4sXL2bjxo23HB+oXyL79evHtm3bePbZZ2nQoAG//vorI0aMyLfv+vXrOXfuHKNGjcLHx8eYznns2DF27twpC4eFEPeEYcOG8cYbb/D3338zZswYjh07Rrt27fDz82PixIk4OjqydOlS+vfvz4oVKxgwYACggp2pU6cyevRoWrVqRUJCAnv37mX//v1069YNKP777M2ftwYFfVZER0fTtm1bUlJSGDduHFWrVmXRokX07duX5cuXG8dZVKNHj2bRokUMHDiQV155hV27djF16lROnDhR6A+SQhSZJkQFEB8frwFav379irR/eHi4BmgLFizI9xigvfvuu8b77777rgZojz32WL5927Rpo4WEhJhs2717twZo33//vXFbSkpKvudOnTpV0+l02oULFzRN07QbN25ogPbpp58W6TXkFRwcrFWrVk2Li4szbvv77781QAsICDBu27p1qwZoP/74o8nz165dW+D2m40YMUIDtBdf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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Umbral elegido: 0.31499999999999995\n", + "Métricas en desarrollo (incluye matriz de confusión tp/fp/fn/tn): {'tp': 45, 'fp': 18, 'fn': 5, 'tn': 132, 'accuracy': 0.885, 'precision': 0.7142857142857143, 'recall': 0.9, 'especificidad': 0.88, 'f1': 0.7964601769911505}\n" + ] + } + ], + "source": [ + "from lib_modelos import buscar_umbral, metricas\n", + "\n", + "historia = mejor['historia']\n", + "epocas_transcurridas = range(1, len(historia['loss_train']) + 1)\n", + "\n", + "figura, ejes = plt.subplots(1, 2, figsize=(10, 3.5))\n", + "ejes[0].plot(epocas_transcurridas, historia['loss_train'], label='train')\n", + "ejes[0].plot(epocas_transcurridas, historia['loss_dev'], label='dev')\n", + "ejes[0].set(xlabel='Época', ylabel='Pérdida BCE ponderada', title='Curvas de pérdida')\n", + "ejes[0].legend()\n", + "ejes[1].plot(epocas_transcurridas, historia['accuracy_dev'], label='accuracy dev')\n", + "ejes[1].plot(epocas_transcurridas, historia['f1_dev'], label='F1 dev')\n", + "ejes[1].set(xlabel='Época', ylabel='Métrica', title='Desarrollo')\n", + "ejes[1].legend()\n", + "plt.show()\n", + "\n", + "# El umbral de \"mejor\" ya minimiza el costo en desarrollo; recalculamos el\n", + "# recorrido completo únicamente para graficar costo vs. umbral.\n", + "probabilidades_dev = mejor['modelo'].probabilidad(x_dev)\n", + "umbral_elegido, recorrido_umbrales = buscar_umbral(y_dev, probabilidades_dev, costo_fn=5, costo_fp=1)\n", + "\n", + "plt.figure(figsize=(6, 3.5))\n", + "plt.plot([f['umbral'] for f in recorrido_umbrales], [f['costo'] for f in recorrido_umbrales])\n", + "plt.axvline(umbral_elegido['umbral'], color='crimson', linestyle='--',\n", + " label=f\"umbral={umbral_elegido['umbral']:.3f}\")\n", + "plt.xlabel('Umbral'); plt.ylabel('Costo esperado en desarrollo'); plt.legend()\n", + "plt.show()\n", + "\n", + "metricas_dev = metricas(y_dev, probabilidades_dev, umbral_elegido['umbral'])\n", + "print('Umbral elegido:', umbral_elegido['umbral'])\n", + "print('Métricas en desarrollo (incluye matriz de confusión tp/fp/fn/tn):', metricas_dev)\n" + ] + }, + { + "cell_type": "markdown", + "id": "justificacionDecisionFinal1", + "metadata": { + "id": "justificacionDecisionFinal1" + }, + "source": [ + "**Justificación de la decisión final.**\n", + "\n", + "Se elige la configuración con menor costo esperado en desarrollo (`costo_fn=5`, `costo_fp=1`); si dos configuraciones quedan con costo igual, se desempata por mayor F1. El umbral se fija con el mismo criterio de costo mínimo, calculado exclusivamente sobre desarrollo, nunca sobre el test privado. Las curvas de pérdida permiten revisar sobreajuste: si `loss_dev` empieza a subir mientras `loss_train` sigue bajando, convendría un checkpoint de una época anterior en vez de la última.\n" + ] + }, + { + "cell_type": "markdown", + "id": "oSs_-a31tsGt", + "metadata": { + "id": "oSs_-a31tsGt" + }, + "source": [ + "## 6. Exportación\n", + "\n", + "Guarde los pesos y el estandarizador del modelo seleccionado. La inferencia debe poder reconstruir la arquitectura desde un diccionario de configuración. Guarde en una carpeta entrega que no sustituya los artefactos del instructor.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "A1BlaJqNtsGt", + "metadata": { + "id": "A1BlaJqNtsGt" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'ruta_pesos': PosixPath('/home/aleleba/projects/cursos/Universidad/Procesamiento de Imagenes y Vision por Computadora/Labs/Lab2/entrega/modelo_elegido.npz'),\n", + " 'arquitectura': {'tipo': 'mlp', 'entrada': 4, 'ocultas': [48, 24]},\n", + " 'umbral': 0.31499999999999995}" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from lib_modelos import guardar_modelo\n", + "\n", + "# Carpeta propia del estudiante: \"entrega\", distinta de \"entrega_solucion\"\n", + "# (que es la referencia del instructor y no debe sobrescribirse).\n", + "ruta_modelo_elegido = RAIZ / 'entrega' / 'modelo_elegido.npz'\n", + "guardar_modelo(\n", + " ruta_modelo_elegido,\n", + " mejor['modelo'],\n", + " mejor['configuracion']['arquitectura'],\n", + " media_entrenamiento,\n", + " desviacion_entrenamiento,\n", + ")\n", + "\n", + "# Este diccionario es el que se copia a inferencia_configurable.ipynb para\n", + "# reconstruir exactamente este modelo (arquitectura, pesos y umbral).\n", + "configuracion_inferencia = {\n", + " 'ruta_pesos': ruta_modelo_elegido,\n", + " 'arquitectura': mejor['configuracion']['arquitectura'],\n", + " 'umbral': umbral_elegido['umbral'],\n", + "}\n", + "configuracion_inferencia\n" + ] + }, + { + "cell_type": "markdown", + "id": "5Ci3fWhHtsGt", + "metadata": { + "id": "5Ci3fWhHtsGt" + }, + "source": [ + "## Entrega\n", + "\n", + "Entregue este notebook completado, su tabla de búsqueda, las curvas, las métricas en desarrollo, la justificación del manejo del desbalance y la configuración exportada. No incluya resultados del test privado.\n" + ] + } + ], + "metadata": { + "colab": { + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "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.10.12" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/Lab2/notebooks/laboratorio_resuelto.ipynb b/Lab2/notebooks/laboratorio_resuelto.ipynb new file mode 100755 index 0000000..6ddf4b5 --- /dev/null +++ b/Lab2/notebooks/laboratorio_resuelto.ipynb @@ -0,0 +1,200 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Laboratorio resuelto: clasificación tabular con MLP\n", + "\n", + "Esta referencia separa 800/200 de forma estratificada, ajusta el estandarizador sólo en entrenamiento, pondera la clase positiva y elige configuración y umbral con desarrollo. El bloque final de evaluación privada es exclusivamente para el instructor.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from pathlib import Path\n", + "import sys\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "\n", + "candidatos = [Path.cwd().resolve(), Path.cwd().resolve() / 'dist' / 'laboratorio_clasificacion', Path.cwd().resolve().parent]\n", + "RAIZ = next((ruta for ruta in candidatos if (ruta / 'lib_modelos.py').exists()), None)\n", + "if RAIZ is None:\n", + " raise FileNotFoundError('No se encontró la carpeta laboratorio_clasificacion.')\n", + "sys.path.insert(0, str(RAIZ))\n", + "print('Raíz del laboratorio:', RAIZ)\n", + "from lib_modelos import (cargar_csv, division_estratificada, ajustar_estandarizador, transformar, buscar_hiperparametros, buscar_umbral, metricas, guardar_modelo)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1. Datos y división\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x, y, ids = cargar_csv(RAIZ / 'datos_publicos' / 'train_1000_desbalanceado.csv')\n", + "indice_train, indice_dev = division_estratificada(y, proporcion_dev=.20, semilla=31)\n", + "media, desviacion = ajustar_estandarizador(x[indice_train])\n", + "x_train = transformar(x[indice_train], media, desviacion)\n", + "x_dev = transformar(x[indice_dev], media, desviacion)\n", + "y_train, y_dev = y[indice_train], y[indice_dev]\n", + "print('Train/dev:', len(y_train), len(y_dev))\n", + "print('Proporción positiva train/dev:', y_train.mean(), y_dev.mean())\n", + "peso_positivo = (y_train == 0).sum() / (y_train == 1).sum()\n", + "print('Peso positivo:', peso_positivo)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2. Decisiones para el desbalance\n", + "\n", + "Se usa una BCE ponderada con peso positivo igual a negativos/positivos. Accuracy no basta: un clasificador que siempre predice cero tendría 75% de accuracy y recall nulo. La selección minimiza costo esperado en desarrollo, con costo de falso negativo 5 y costo de falso positivo 1; se reportan también precision, recall y F1.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "configuraciones = [\n", + " {'arquitectura': {'tipo': 'mlp', 'entrada': 4, 'ocultas': [24, 16]},\n", + " 'entrenamiento': {'epocas': 100, 'batch_size': 64, 'learning_rate': .003}, 'costo_fn': 5, 'costo_fp': 1},\n", + " {'arquitectura': {'tipo': 'mlp', 'entrada': 4, 'ocultas': [48, 24]},\n", + " 'entrenamiento': {'epocas': 100, 'batch_size': 64, 'learning_rate': .002}, 'costo_fn': 5, 'costo_fp': 1},\n", + " {'arquitectura': {'tipo': 'mlp_residual_bn', 'entrada': 4, 'ancho': 24},\n", + " 'entrenamiento': {'epocas': 100, 'batch_size': 64, 'learning_rate': .002}, 'costo_fn': 5, 'costo_fp': 1},\n", + " {'arquitectura': {'tipo': 'mlp_residual_bn', 'entrada': 4, 'ancho': 40},\n", + " 'entrenamiento': {'epocas': 100, 'batch_size': 64, 'learning_rate': .0015}, 'costo_fn': 5, 'costo_fp': 1},\n", + "]\n", + "mejor, resultados = buscar_hiperparametros(configuraciones, x_train, y_train, x_dev, y_dev, semilla=41)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for n, r in enumerate(resultados, 1):\n", + " a = r['configuracion']['arquitectura']\n", + " print(n, a, 'costo=', r['costo'], 'umbral=', round(r['umbral'], 3),\n", + " 'F1=', round(r['f1'], 3), 'recall=', round(r['recall'], 3),\n", + " 'precision=', round(r['precision'], 3))\n", + "print('Selección:', mejor['configuracion']['arquitectura'])\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3. Curvas y umbral\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "historia = mejor['historia']\n", + "epocas = np.arange(1, len(historia['loss_train']) + 1)\n", + "fig, ax = plt.subplots(1, 2, figsize=(11, 3.5))\n", + "ax[0].plot(epocas, historia['loss_train'], label='train')\n", + "ax[0].plot(epocas, historia['loss_dev'], label='dev')\n", + "ax[0].set(xlabel='Época', ylabel='BCE ponderada', title='Pérdida'); ax[0].legend()\n", + "ax[1].plot(epocas, historia['accuracy_dev'], label='accuracy dev')\n", + "ax[1].plot(epocas, historia['f1_dev'], label='F1 dev')\n", + "ax[1].set(xlabel='Época', ylabel='Métrica', title='Desarrollo'); ax[1].legend()\n", + "plt.show()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "prob_dev = mejor['modelo'].probabilidad(x_dev)\n", + "umbral, recorrido = buscar_umbral(y_dev, prob_dev, costo_fn=5, costo_fp=1)\n", + "plt.figure(figsize=(6, 3.5))\n", + "plt.plot([f['umbral'] for f in recorrido], [f['costo'] for f in recorrido])\n", + "plt.axvline(umbral['umbral'], color='crimson', linestyle='--', label=f\"umbral={umbral['umbral']:.3f}\")\n", + "plt.xlabel('Umbral'); plt.ylabel('Costo esperado en desarrollo'); plt.legend(); plt.show()\n", + "print(umbral)\n", + "print(metricas(y_dev, prob_dev, umbral['umbral']))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4. Exportación\n", + "\n", + "La selección se hizo sólo con desarrollo. El siguiente artefacto contiene los pesos, media, desviación y configuración necesaria para reproducir inferencia.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "guardar_modelo(RAIZ / 'entrega_solucion' / 'modelo_elegido.npz', mejor['modelo'],\n", + " mejor['configuracion']['arquitectura'], media, desviacion)\n", + "CONFIGURACION = {\n", + " 'ruta_pesos': str(RAIZ / 'entrega_solucion' / 'modelo_elegido.npz'),\n", + " 'arquitectura': mejor['configuracion']['arquitectura'],\n", + " 'umbral': umbral['umbral'],\n", + "}\n", + "CONFIGURACION\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 5. Evaluación privada — instructor\n", + "\n", + "Ejecute este bloque sólo cuando las decisiones estén cerradas. Nunca se devuelve este CSV al estudiantado.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# BLOQUE DEL INSTRUCTOR\n", + "# x_test, y_test, _ = cargar_csv(RAIZ / 'instructor_privado' / 'test_200_balanceado.csv')\n", + "# prob_test = mejor['modelo'].probabilidad(transformar(x_test, media, desviacion))\n", + "# print(metricas(y_test, prob_test, CONFIGURACION['umbral']))\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "name": "python", + "version": "3.x" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/Lab2/plantilla_reporte_laboratorio.pdf b/Lab2/plantilla_reporte_laboratorio.pdf new file mode 100755 index 0000000..1a84bd1 Binary files /dev/null and b/Lab2/plantilla_reporte_laboratorio.pdf differ diff --git a/Lab2/plantilla_reporte_laboratorio.tex b/Lab2/plantilla_reporte_laboratorio.tex new file mode 100755 index 0000000..bb3c8fd --- /dev/null +++ b/Lab2/plantilla_reporte_laboratorio.tex @@ -0,0 +1,131 @@ +\documentclass[10pt]{article} +\usepackage[margin=1.8cm]{geometry} +\usepackage[utf8]{inputenc} +\usepackage[T1]{fontenc} +\usepackage[spanish]{babel} +\shorthandoff{<>} +\usepackage{amsmath,booktabs,array} +\usepackage{xcolor} +\usepackage{graphicx} +\setlength{\parindent}{0pt} +\newcommand{\campo}[1]{\underline{\hspace{#1}}} +\begin{document} + +\begin{center} +{\LARGE Reporte de laboratorio: clasificación tabular con MLP}\\[0.4em] +Nombre: Alejandro Lembke Barrientos\hfill Fecha: 25 de agosto de 2026\\ +Repositorio o archivo entregado: \texttt{https://gitea.p-lao.com/aleleba/Procesamiento-de-Imagenes-y-Vision-Por-Computadora} +\end{center} + +\textbf{Propósito.} Documentar una comparación reproducible entre un MLP convencional y un MLP residual con Batch Normalization, usando una división estratificada 800/200 y un conjunto de entrenamiento desbalanceado. Los valores de este reporte provienen de la ejecución real de \texttt{notebooks/laboratorio\_estudiante.ipynb}. + +\section*{1. Datos, división y control de fuga} +\small +\begin{tabular}{@{}p{2.4cm}p{5.8cm}p{6.8cm}c@{}} +\toprule +Elemento & Valor & Evidencia o justificación & Estado\\ +\midrule +Archivo público & train\_1000\_desbalanceado.csv & 1,000 ejemplos & Real\\ +División & 800 train / 200 dev & Estratificada, semilla 31 & Real\\ +Clases en train / dev & 600/200 clase 0 y 1 en train; 150/50 en dev & Proporción 75/25 conservada en ambas particiones & Real\\ +Estandarización & Media y desviación de train & Sin usar dev ni test & Real\\ +Test privado & No usado durante selección & Sólo evaluación final (a cargo del instructor) & Real\\ +\bottomrule +\end{tabular} +\normalsize + +\vspace{0.7em} +\textbf{Respuesta.} Describa una fuente posible de fuga de información y cómo la evitó: + +\vspace{0.3em} +La fuente de fuga más directa habría sido ajustar la media y la desviación estándar del estandarizador (\texttt{ajustar\_estandarizador}) usando todo el conjunto de 1,000 ejemplos antes de dividir en train/dev, o recalcularlas después de ver las métricas de desarrollo. Se evitó ajustando el estandarizador exclusivamente con \texttt{x[indice\_train]} (800 ejemplos) y aplicando esa misma transformación a dev y, al final, al artefacto exportado; el umbral y la arquitectura también se eligieron mirando solo el costo en desarrollo, sin usar en ningún momento \texttt{test\_200\_balanceado.csv}. + +\vspace{1.0cm} + +\section*{2. Estrategia ante el desbalance} +\begin{tabular}{@{}p{3.1cm}p{5.4cm}p{5.3cm}@{}} +\toprule +Decisión & Valor elegido & Justificación\\ +\midrule +Pérdida & BCE ponderada; peso positivo = 3.0 & Compensa la relación 600/200 de train.\\ +Selección de modelo & Costo esperado en dev & Falso negativo cuesta 5; falso positivo cuesta 1.\\ +Métricas reportadas & Precision, recall, F1, especificidad y accuracy & Accuracy sola oculta el desempeño de la clase minoritaria.\\ +Umbral & Se elige sólo en dev & Se congela antes del test privado.\\ +\bottomrule +\end{tabular} + +\vspace{0.6em} +\textbf{Respuesta.} Declare los costos y explique por qué el umbral 0.5 puede no ser adecuado: + +\vspace{0.3em} +Se asumió costo de falso negativo = 5 y costo de falso positivo = 1 (dejar pasar un caso positivo real es cinco veces más costoso que una falsa alarma). Con esos costos, el umbral que minimiza el costo esperado en desarrollo resultó ser 0.315, por debajo de 0.5: un umbral de 0.5 favorece la precisión pero deja escapar más falsos negativos, que en este problema son mucho más caros que los falsos positivos adicionales que introduce un umbral más bajo. + +\vspace{0.8cm} + +\section*{3. Búsqueda de hiperparámetros} +\small +\begin{tabular}{@{}lcccccccc@{}} +\toprule +ID & Arquitectura & Capas/ancho & LR & Épocas & Costo dev & F1 dev & Recall dev & Umbral\\ +\midrule +A & MLP & [24,16] & 0.003 & 100 & 43 & 0.715 & 0.980 & 0.050\\ +B & MLP & [48,24] & 0.002 & 100 & 43 & 0.796 & 0.900 & 0.315\\ +C & Residual + BN & 24 & 0.002 & 100 & 55 & 0.686 & 0.940 & 0.060\\ +D & Residual + BN & 40 & 0.0015 & 100 & 56 & 0.804 & 0.820 & 0.400\\ +\bottomrule +\end{tabular} +\normalsize + +\vspace{0.5em} +\textbf{Decisión.} Se elige la configuración de menor costo esperado en desarrollo; A y B empataron en costo (43), por lo que se desempató por mayor F1 en desarrollo, lo que favoreció a B (MLP, capas [48,24], learning rate 0.002, 100 épocas, umbral 0.315). + +\vspace{0.8cm} + +\section*{4. Curvas de entrenamiento y desarrollo} +\begin{center} +\includegraphics[width=\linewidth]{entrega/curvas_entrenamiento.png} +\end{center} + +\textbf{Interpretación.} Indique la época o checkpoint seleccionado y explique si observa sobreajuste, subajuste o estabilidad: + +\vspace{0.3em} +Se entrenaron las 100 épocas completas y se usó el modelo final (época 100). La pérdida de train baja de forma monótona hasta $\approx 0.09$, mientras que la pérdida de dev baja rápido hasta $\approx 0.27$ (época $\approx 20$) y luego se mantiene estable con una leve subida hacia el final ($\approx 0.30$–$0.33$ después de la época 70), señal de un sobreajuste leve. Accuracy y F1 en dev crecen rápido y se estabilizan alrededor de la época 20–30 (accuracy $\approx 0.88$–$0.91$, F1 $\approx 0.78$–$0.82$), con ruido pero sin caída sostenida, por lo que la configuración es razonablemente estable y no sería indispensable un checkpoint anterior. + +\vspace{0.5cm} + +\section*{5. Selección de umbral y reporte de métricas} +\begin{center} +\includegraphics[width=0.7\linewidth]{entrega/curva_umbral.png} +\end{center} + +\begin{center} +\begin{tabular}{@{}lccccc@{}} +\toprule +Conjunto & Accuracy & Precision & Recall & F1 & Especificidad\\ +\midrule +Desarrollo, umbral 0.315 & 0.885 & 0.714 & 0.900 & 0.796 & 0.880\\ +Test privado, umbral congelado & \campo{1cm} & \campo{1cm} & \campo{1cm} & \campo{1cm} & \campo{1cm}\\ +\bottomrule +\end{tabular} +\end{center} +\footnotesize +La fila de test privado se deja en blanco a propósito: \texttt{instructor\_privado/test\_200\_balanceado.csv} nunca se usa ni se lee durante el desarrollo del laboratorio; esa evaluación final es exclusiva del instructor. +\normalsize + +\vspace{0.5em} +\textbf{Matriz de confusión en desarrollo (umbral 0.315).} +\[ +\begin{array}{c|cc} + & \text{Pred. 0} & \text{Pred. 1}\\ \hline +\text{Real 0} & 132 & 18\\ +\text{Real 1} & 5 & 45 +\end{array} +\] + +\section*{6. Conclusión reproducible} +\begin{enumerate} +\item Arquitectura final, pesos y ruta del artefacto: MLP con capas ocultas [48, 24], entrada de dimensión 4; pesos guardados en \texttt{entrega/modelo\_elegido.npz}. +\item Umbral congelado y costos asumidos: umbral 0.315, elegido minimizando el costo esperado en desarrollo con costo de falso negativo = 5 y costo de falso positivo = 1. +\item Cambio que haría antes de desplegar: repetir la búsqueda de hiperparámetros con más de una semilla por configuración para verificar que la elección de arquitectura y umbral no dependa de una sola inicialización, y monitorear en producción la distribución de \texttt{x1..x4} para detectar drift respecto a los datos de entrenamiento. +\end{enumerate} +\end{document} diff --git a/Lab2/resolver_laboratorio.py b/Lab2/resolver_laboratorio.py new file mode 100755 index 0000000..80d1280 --- /dev/null +++ b/Lab2/resolver_laboratorio.py @@ -0,0 +1,61 @@ +"""Ejecuta la solución de referencia y guarda el artefacto para inferencia.""" +from __future__ import annotations +import json +from pathlib import Path +import matplotlib.pyplot as plt +from lib_modelos import ( + ajustar_estandarizador, buscar_hiperparametros, buscar_umbral, cargar_csv, + division_estratificada, guardar_modelo, metricas, transformar, +) + +RAIZ = Path(__file__).resolve().parent + +def fila_publica(resultado): + return { + "arquitectura": resultado["configuracion"]["arquitectura"], + "costo_dev": resultado["costo"], "umbral_dev": resultado["umbral"], + "accuracy_dev": resultado["accuracy"], "precision_dev": resultado["precision"], + "recall_dev": resultado["recall"], "f1_dev": resultado["f1"], + } + +def main(): + x, y, _ = cargar_csv(RAIZ/"datos_publicos"/"train_1000_desbalanceado.csv") + indice_train, indice_dev = division_estratificada(y, .20, semilla=31) + media, desviacion = ajustar_estandarizador(x[indice_train]) + xt = transformar(x[indice_train], media, desviacion) + xd = transformar(x[indice_dev], media, desviacion) + + configuraciones = [ + {"arquitectura": {"tipo": "mlp", "entrada": 4, "ocultas": [32, 16]}, + "entrenamiento": {"epocas": 100, "batch_size": 64, "learning_rate": .003}, + "costo_fn": 5, "costo_fp": 1}, + {"arquitectura": {"tipo": "mlp_residual_bn", "entrada": 4, "ancho": 32}, + "entrenamiento": {"epocas": 100, "batch_size": 64, "learning_rate": .002}, + "costo_fn": 5, "costo_fp": 1}, + ] + mejor, resultados = buscar_hiperparametros(configuraciones, xt, y[indice_train], xd, y[indice_dev], semilla=41) + carpeta = RAIZ/"instructor_privado"/"artefactos" + guardar_modelo(carpeta/"modelo_mejor.npz", mejor["modelo"], mejor["configuracion"]["arquitectura"], media, desviacion) + + xpriv, ypriv, _ = cargar_csv(RAIZ/"instructor_privado"/"test_200_balanceado.csv") + ppriv = mejor["modelo"].probabilidad(transformar(xpriv, media, desviacion)) + mpriv = metricas(ypriv, ppriv, mejor["umbral"]) + resumen = { + "split": {"train": int(len(indice_train)), "dev": int(len(indice_dev)), "clase_1_train": int(y[indice_train].sum()), "clase_1_dev": int(y[indice_dev].sum())}, + "candidatos": [fila_publica(r) for r in resultados], + "mejor": fila_publica(mejor), + "evaluacion_privada": mpriv, + } + (carpeta/"resumen_solucion.json").write_text(json.dumps(resumen, indent=2), encoding="utf-8") + + historia = mejor["historia"]; ejes = range(1, len(historia["loss_train"])+1) + fig, ax = plt.subplots(1, 2, figsize=(10, 3.5)) + ax[0].plot(ejes, historia["loss_train"], label="train"); ax[0].plot(ejes, historia["loss_dev"], label="dev") + ax[0].set(xlabel="Época", ylabel="Pérdida BCE ponderada", title="Curvas de pérdida"); ax[0].legend() + ax[1].plot(ejes, historia["accuracy_dev"], label="Accuracy dev"); ax[1].plot(ejes, historia["f1_dev"], label="F1 dev") + ax[1].set(xlabel="Época", ylabel="Métrica", title="Desarrollo"); ax[1].legend() + fig.tight_layout(); fig.savefig(carpeta/"curvas_solucion.png", dpi=160); plt.close(fig) + print(json.dumps(resumen, indent=2)) + +if __name__ == "__main__": + main() diff --git a/README.md b/README.md index a0709a0..fb7d26b 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ Repositorio con los laboratorios de la asignatura. ## Laboratorios -| # | Laboratorio | Notebook | -|---|---|---| -| 1 | MLPs, verosimilitud, entrenamiento y evaluación | [Lab 1 - MLP](Lab1/lab1_mlp.ipynb) | +| # | Laboratorio | Notebook | Reporte | +|---|---|---|---| +| 1 | MLPs, verosimilitud, entrenamiento y evaluación | [Lab 1 - MLP](Lab1/lab1_mlp.ipynb) | — | +| 2 | Clasificación tabular con MLP (desbalance de clases) | [Lab 2 - Clasificación](Lab2/notebooks/laboratorio_estudiante.ipynb) | [Reporte PDF](Lab2/plantilla_reporte_laboratorio.pdf) |