<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="/assets/xslt/atom.xslt" ?>
<?xml-stylesheet type="text/css" href="/assets/css/atom.css" ?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<id>http://datacuber.github.io/</id>
	<title>datacubeR</title>
	<updated>2023-08-01T02:10:47+00:00</updated>

	<subtitle>Espero pueda ser un lugar donde juntos aprendamos Machine&amp;nbsp;Learning</subtitle>

	
		
		<author>
			
				<name>Alfonso</name>
			
			
			
		</author>
	

	<link href="http://datacuber.github.io/atom.xml" rel="self" type="application/rss+xml" />
	<link href="http://datacuber.github.io/" rel="alternate" type="text/html" />

	<generator uri="http://jekyllrb.com" version="3.9.3">Jekyll</generator>

	
		<entry>
			<id>http://datacuber.github.io/corne/</id>
			<title>6 meses usando un Corne</title>
			<link href="http://datacuber.github.io/corne/" rel="alternate" type="text/html" title="6 meses usando un Corne" />
			<updated>2023-08-01T00:00:00+00:00</updated>

			
			<summary>Mi viaje para comenzar a comenzar más rápido y sin dolor.</summary>
			<content type="html" xml:base="http://datacuber.github.io/corne/">&lt;p&gt;&lt;img src=&quot;/images/corne/corne.png&quot; alt=&quot;picture of me&quot; class=&quot;left show-for-large-up hide-for-print&quot; width=&quot;500&quot; /&gt; 
&lt;img src=&quot;/images/corne/corne.png&quot; alt=&quot;picture of me&quot; class=&quot;center hide-for-large-up&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Soy un fanático de la productividad. Siento que como Científico de Datos tenemos que ser sumamente eficientes, y utilizar todos los recursos posibles que nos den comodidad y rápidez. Sí, también es verdad que soy un hacker frustrado (básicamente porque siento que soy muy poco informático)&lt;!--more--&gt;, pero por lo mismo, hace unos años es que estoy invirtiendo mucho tiempo en ser mejor computín. Y entre aprender mucho más de todo lo que no sé de informática, también dedico mucho tiempo a escribir rápido en el teclado. De hecho practico regularmente en plataformas como &lt;a href=&quot;monkeytype.com&quot;&gt;MonkeyType&lt;/a&gt; y estoy rondando los 80-100 wpm (palabras por minutos en inglés: words per minute). El tema es que un poco inspirado por &lt;a href=&quot;https://www.youtube.com/@HolaMundoDev&quot;&gt;Hola Mundo&lt;/a&gt;, pero por sobre todo por &lt;a href=&quot;https://www.youtube.com/@chrisatmachine&quot;&gt;chris@machine&lt;/a&gt; y &lt;a href=&quot;https://www.youtube.com/@ThePrimeagen&quot;&gt;ThePrimeagen&lt;/a&gt; es que siento que uno tiene que trabajar primordialmente con el teclado. Esto por dos cosas:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Cambié mi mouse vertical, porque en verdad me estaba dando tendinitis por un movimiento muy antinatural que estaba haciendo al bajar. Ahora uso uno de trackball, pero igual uno pierde tiempo moviendo la mano al mouse, aunque no quiera notarlo.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Cambié mi teclado y aprendí a hacer touch typing para escribir más rápido, sin mirar el teclado y con todos los dedos. Realmente he notado una mejora muy notoria en esto y si bien es un cambio a mediano-largo plazo, el forzarme a escribir sin mirar y con la técnica correcta me ha dado muchos beneficios.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Un tercer punto y que es algo completamente nuevo, es que decidí cambiarme a Neovim. Esto porque creo que es la única manera de dejar de utilizar el mouse, y poder depender sólo del teclado. Lamentablemente este cambio ha sido el más costoso, en términos de curva de aprendizaje y de configurar el &lt;q&gt;maldito editor&lt;/q&gt;. No creo que sea algo para todos, definitivamente no lo es. Pero me siento orgulloso de haberme atrevido y demasiado satisfecho con mi entorno de programación.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
  &lt;p&gt;Más acerca de cómo ha sido el cambio a Neovim pronto!!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ahí es cuando entra el Corne. No quería el Corne la verdad. Porque se está volviendo &lt;q&gt;too mainstream&lt;/q&gt; y como que piensan que es el único teclado que hay. Yo en verdad quería el &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Sofle&lt;/code&gt; (pero sólo por ser rebelde), porque ví a este &lt;a href=&quot;https://www.youtube.com/watch?v=sDf0YJcL1-A&amp;amp;t=269s&quot;&gt;tipo&lt;/a&gt; decir que el Corne era demasiado difícil de aprender porque tenía muy pocas teclas (Spoiler, cuesta unas dos semanas, pero no es tan difícil como dice).&lt;/p&gt;

&lt;p&gt;Pero cuando ví que Zone Keyboards tenía esta versión con &lt;a href=&quot;https://zonekeyboards.cl/keyboards/corne-cherry-v3-wood-case&quot;&gt;carcasa de madera&lt;/a&gt;, la verdad es que no me pude resistir. Aunque yo lo pillé en oferta a un precio muchísimo menor que el que indican ahora.&lt;/p&gt;

&lt;p&gt;Cuando compré el teclado tenía la intención trabajar un poco con VIM, pero sin VIM. Porque, como he dicho varias veces, no había encontrado una buena solución para el REPL en Python, y porque realmente no me gustaba tener que presionar la &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;i&lt;/code&gt; cada vez que quiero comenzar a escribir. Hoy la historia es distinta y todas mis molestias eran sólo un tema de costumbre.&lt;/p&gt;

&lt;div class=&quot;alert-box warning radius &quot;&gt;&lt;p&gt;Es verdad, se pueden usar los key bindings de VIM en VSCode, pero ¿qué pasa con el resto?&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Yo tenía anteriormente el &lt;a href=&quot;https://es.aliexpress.com/item/1005001906178386.html?pdp_npi=2%40dis%21CLP%21CLP%20155%2C656%21CLP%20139%2C750%21%21%21%21%21%402101d1b616795227315617531e4b7a%2112000024053865288%21btf&amp;amp;_t=pvid%3A58e3e668-a724-42bc-9c51-beab28d788bf&amp;amp;afTraceInfo=1005001906178386__pc__pcBridgePPC__xxxxxx__1679522731&amp;amp;spm=a2g0o.ppclist.product.mainProduct&amp;amp;gatewayAdapt=glo2esp&quot;&gt;GK68XS&lt;/a&gt; que es un buen teclado, me gustaba harto, pero con varias limitaciones que probablemente a nadie le afectan excepto a mí. Primero lo bueno:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Compacto, 65% con teclas dedicadas a los números. Lejos lo que más me ha costado acostumbrarme en el Corne.&lt;/li&gt;
  &lt;li&gt;Bluetooth.&lt;/li&gt;
  &lt;li&gt;Switches Cherry MX Rojos (de excelente calidad).&lt;/li&gt;
  &lt;li&gt;Programable.&lt;/li&gt;
  &lt;li&gt;Macros.&lt;/li&gt;
  &lt;li&gt;Tiene triple barra espaciadora que permitía usar teclas modificadores con los pulgares.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ahora los contra:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Cherry MX Rojos. Son demasiado sensibles, probablemente los Café serían mejor, con mis switches actuales me equivocó infinitamente menos debido a que requieren más intencionalidad al tipear. Escribo menos sin querer queriendo.&lt;/li&gt;
  &lt;li&gt;Staggered. Si se fijan tiene las columnas como en pendiente negativa, lo cuál si haces touch typing, implicará una rotación de la muñeca izquierda horrible. ¡Y duele!&lt;/li&gt;
  &lt;li&gt;Flechas a la derecha, lo cual implica un retraso horrible cada vez que quieres usarlas. Además de perder la posición de home row (Tener tus dedos descansando en &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;A&lt;/code&gt;, &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;S&lt;/code&gt;, &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;D&lt;/code&gt;, &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;F&lt;/code&gt; y &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;J&lt;/code&gt;, &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;K&lt;/code&gt;, &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;L&lt;/code&gt;, &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;;&lt;/code&gt;).&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-text highlighter-rouge&quot;&gt;FN&lt;/code&gt; no modificable. Fijo y a la derecha, lo cuál no me gustaba.&lt;/li&gt;
  &lt;li&gt;Sólo una función por tecla.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;alert-box success radius &quot;&gt;&lt;p&gt;No es terrible, de verdad que no. Ese teclado ahora es de mi hermano y está feliz usándolo.&lt;/p&gt;
&lt;/div&gt;

&lt;blockquote&gt;
  &lt;p&gt;¿Entonces qué tiene de distinto cualquier teclado mecánico basado en QMK (ojo, cualquiera sirve, no sólo el Corne)?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Yo creo que es la &lt;em&gt;programabilidad&lt;/em&gt; (ni siquiera sé si eso es una palabra). Pero me refiero a que realmente se puede definir todo. Ahora, ¿es perfecto? No, no lo es. Y si uno quiere realmente el teclado perfecto hay que invertir mucho más dinero (principalmente en hardware, los pro-micro que son los controladores que tengo no tienen tanta capacidad, pero cumplen). Al menos a mí me gusta.&lt;/p&gt;

&lt;h3 id=&quot;lo-bueno&quot;&gt;Lo bueno&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Que es separado&lt;/strong&gt;, lo cual permite que la espalda se relaje mucho más. Esto es verdad. Estar con los brazos hacia adentro genera tensión en los trapecios. Tener los brazos a la altura del hombro realmente ayuda.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Columnar:&lt;/strong&gt; Las teclas están en columnas, por ejemplo, la &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;a&lt;/code&gt; está inmediatamente abajo de la &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;q&lt;/code&gt; y no abajo a la derecha. Ya tengo absolutamente cero dolor de muñecas, incluso usando una distribución tan nefasta como QWERTY. Y esto no me tomó tanto tiempo en acostumbrarme como decían.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Cada tecla puede tener demasiadas funcionalidades&lt;/strong&gt; al mismo tiempo (lo cual es casi agobiante).&lt;/li&gt;
  &lt;li&gt;Tiene &lt;strong&gt;pantallitas leds&lt;/strong&gt; con indicadores y buenas luces RGB de fondo (aunque yo las tengo apagadas la mayor parte del tiempo).&lt;/li&gt;
  &lt;li&gt;Las &lt;strong&gt;teclas de Pulgar&lt;/strong&gt; son lo máximo. Y realmente permiten que uno no tenga que abandonar la posición de home row nunca. Además tienes 6 por lo tanto es harta funcionalidad extra.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;lo-malo&quot;&gt;Lo malo&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Es cableado.&lt;/strong&gt; Hay versiones inalámbricas, pero son DIY y no sé soldar.&lt;/li&gt;
  &lt;li&gt;Tiene una &lt;strong&gt;pequeña latencia&lt;/strong&gt;. Probablemente imperceptible para muchos, pero yo la siento cuando estamos cerca de los 80-90 wpm (&lt;strong&gt;Update:&lt;/strong&gt; Es posible que esto sea sólo una percepción mía. He probado con el terminal Kitty que es mucho más fluido y una mejor calidad de cable y ya casi no siento desfase).&lt;/li&gt;
  &lt;li&gt;Los &lt;strong&gt;switches Gateron café&lt;/strong&gt; son increíbles, pero un poco toscos. Siento que hay que lubricarlos, aunque me da una lata inmensa hacerlo. Pero a pesar de so, realmente me permite escribir equivocándome muy poco.&lt;/li&gt;
  &lt;li&gt;El sonido no es tan agradable como pensé que sería. No me molesta, pero me gustaba mucho más el de mi teclado anterior. He visto algunos hacks, pero me da lata desarmar el teclado para ponerle goma eva adentro.&lt;/li&gt;
  &lt;li&gt;Algunas &lt;strong&gt;funcionalidades súper cool lo hacen un teclado lento&lt;/strong&gt;. Afortunadamente yo encontré mi configuración ideal sin tener que usar cosas como los combos, o los tap dance, que realmente traban el teclado (de manera más perceptible).&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Me es casi imposible teclear en un teclado Staggered nuevamente&lt;/strong&gt;. No porque se me haya olvidado, sino porque no le achunto a las teclas. Cuando tengo que usar un teclado que no es el mío, tengo que recurrir al clásico escribir sólo con los índices y mirando, pero puede que sea yo el ñurdo.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;alert-box info radius &quot;&gt;&lt;p&gt;Los combos se utilizan normalmente para hacer lo que se llama los Home Row Modifiers. Por ejemplo si presionas la &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;a&lt;/code&gt; es una &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;a&lt;/code&gt;, pero si la mantienes es un &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Alt&lt;/code&gt;. Era excelente la idea, pero presionar significa que el teclado literalmente tiene que esperar 200ms para detectar si es un tap o un hold y escribiendo rápido eso se nota.&lt;/p&gt;
&lt;/div&gt;

&lt;div class=&quot;alert-box info radius &quot;&gt;&lt;p&gt;Lo mismo los tap dance. Esto es cuando presionas una tecla hace algo, pero si lo presionas dos rápido hace otra cosa. Como yo uso principalmente una distribución en inglés, quería que un doble tap de la &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;n&lt;/code&gt; sea una &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;ñ&lt;/code&gt;. Pero nuevamente el delay para detectar si es un tap o un doble tap.&lt;/p&gt;
&lt;/div&gt;

&lt;h2 id=&quot;personalización&quot;&gt;Personalización&lt;/h2&gt;

&lt;p&gt;Bueno una de las gracias es que era completamente personalizado. Y la verdad es que yo elegí desde el color de los keycaps, hasta los simbolitos:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/corne/corne.jpeg&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;En el Mayus, está básicamente mi logo, que cree hace ya varios años increíblemente con una librería en R que se llamaba algo como Hex, o algo así.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Ctrl&lt;/code&gt; y &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Alt&lt;/code&gt; son los símbolos de Mac, que encuentro harto más bonitos que simplemente colocarle el nombre.&lt;/li&gt;
  &lt;li&gt;Abajo tengo el logo de Zone Keyboards, un poco para agradecer y hacer propaganda al teclado, que está bonito. Y tengo el logo de &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;PopOS&lt;/code&gt;, mi Sistema Operativo.&lt;/li&gt;
  &lt;li&gt;A la derecha tengo la patita de la Kira, mi perrita y las otras son teclas estándar.&lt;/li&gt;
  &lt;li&gt;A la derecha decidí colocar las flechas estilo VIM. Esto porque llevo mucho tiempo intentando aprendérmelas, y creo que por fín puedo decir que me acostumbré, en especial la flecha izquierda es como difícil acordarse.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bueno, a lo que nos interesa, ¿cómo lo tengo configurado?. Esto fue realmente una lata y estuve como 3+ semanas moviéndolo todo el día, todos los días. Pero realmente siento que mi distribución está como quiero. Tengo en total 4 capas las cuales voy a describir a continuación.&lt;/p&gt;

&lt;h1 id=&quot;capa-principal&quot;&gt;Capa Principal&lt;/h1&gt;

&lt;p&gt;La capa principal la verdad es que es muy estándar. Es una distribución QWERTY con varias moficicaciones. Por un tema de orden me referiré a esta capa como referencia para que se entienda la posición de otras funcionalidades. Además me referiré a las teclas de Pulgar como &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;LT(idx)&lt;/code&gt; y &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;RT(idx)&lt;/code&gt; donde &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;idx=1,2,3&lt;/code&gt; siendo el &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;1&lt;/code&gt; la tecla más interior y &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;3&lt;/code&gt; la más exterior de cada mano (L: Izquierda, R: Derecha).&lt;/p&gt;

&lt;p&gt;La filosofía detrás es poder tener todos mis Mods (&lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Ctrl&lt;/code&gt;, &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Shift&lt;/code&gt; y &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Alt&lt;/code&gt;) en mi mano izquierda, cosa de combinar atajos con el uso del Mouse en caso de ser necesario. Además la posición debe ser lo más ergonómica posible.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/corne/main.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;La tecla &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;' &quot;&lt;/code&gt; sirve como mi &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;´&lt;/code&gt;. Esto porque utilizo una distribución llamada US International Keyboard with dead keys. Normalmente si yo quiero el &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;'&lt;/code&gt; necesito presionar la tecla dos veces, lo cual encuentro lento, por lo que lo remapee como &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;RAlt + '&lt;/code&gt; lo que entrega directamente el &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;´&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;No uso la tecla &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;/ ?&lt;/code&gt; y en vez de eso la cambio por &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;- _&lt;/code&gt;, ya que el guión bajo se utiliza muchísimo más al momento de programar y quiero tenerla muy a la mano.&lt;/li&gt;
  &lt;li&gt;Una cosa que a mucho les parece extraño es que uso el espacio en &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;RT(2)&lt;/code&gt; y no en &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;RT(1)&lt;/code&gt;. No sé, lo encuentro una posición mucho más natural y que mantiene mi mano más relajada. Se lo copié a un chico indio de Youtube que no recuerdo su nombre como para darle el crédito.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-text highlighter-rouge&quot;&gt;RT(3)&lt;/code&gt; tiene doble funcionalidad. Un tap es &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Enter&lt;/code&gt; y un hold es la tecla &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Super&lt;/code&gt;, &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;GUI&lt;/code&gt; o &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Windows&lt;/code&gt;. En el caso de Pop esto permite lanzar el Launcher. Como dije, esto es una funcionalidad que da cierto Lag (debo esperar 1 segundo para activarlo), pero dado que el Hold lo utilizo en contadas ocasiones no me afecta como sí lo haría en una letra o un símbolo.&lt;/li&gt;
  &lt;li&gt;La tecla &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Esc&lt;/code&gt; la hago como un doble Tap sobre el &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;CAPS LOCK&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Todos mis modificadores son &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;One Shot Keys&lt;/code&gt;. Es decir si hago tap deja el modificador presionado hasta la siguiente tecla. Por lo tanto, si quiero hacer Copy hago &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Ctrl C&lt;/code&gt; secuencial, y no &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Ctrl + C&lt;/code&gt; (dejándo ambos presionados), lo cual es particularmente útil para escribir mayúsculas rápidas y no escribir dos mayúsculas por error. Lo bueno de estas teclas es que si por costumbre las dejo en Hold igual funciona. Tener como One Shots me permite usar acordes por ejemplo &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Ctrl K A&lt;/code&gt; es un acorde de Jupyter Notebook que me permite seleccionar todo lo que esté entre paréntesis. O &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Ctrl R K&lt;/code&gt; lo uso para reiniciar kernel y &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Ctrl R A&lt;/code&gt; para correr todo (Run All). Súper útil.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Una cosa bien chora que tengo configurado es que doble &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Shift&lt;/code&gt; es &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Caps Word&lt;/code&gt;. Esta funcionalidad permite colocar en mayúsculas y transformar &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;-&lt;/code&gt; en &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;_&lt;/code&gt; hasta que presione un espacio. Lo cual permite por ejemplo crear constantes sin tener que activar y desactivar el &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;CAPS LOCK&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;Además todas mis capas OSL son &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;One Shot Layers&lt;/code&gt;. Si la presiono una vez cambia a la capa indicada sólo para la siguiente tecla, si la dejo presionada quedo en esa capa hasta que suelte el OSL. Por ejemplo si quiero eliminar sólo un caracter hago &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;OSL(0) Del&lt;/code&gt; y si quiero borrar tres hago &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;OSL(0) + (Del Del Del)&lt;/code&gt;. Ahora si quiero quedarme en esa capa hago un doble tap a &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;OSL(0)&lt;/code&gt; o cualquier otra capa y me quedo ahí hasta desactivarla (con la misma tecla que la activé). Esto lo uso normalmente con la capa de navegación o la numérica cuando tengo que sólo recorrer un archivo o cuando tengo que escribir sólo operaciones aritméticas respectivamente (obviamente cuando no estoy en Neovim).&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;alert-box tip radius &quot;&gt;&lt;p&gt;Otra ventaja de usar One Shot Layers es que me permite combinaciones muy rápidas sin equivocarme, como se garantiza que la siguiente tecla será modificado por el modificador o la capa, cualquier desincronización en mis dedos se perdona.&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Quizás la funcionalidad más potente del teclado es la &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Leader Key&lt;/code&gt;. la cual se ubica donde en RT(1) de la capa 2. La &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Leader Key&lt;/code&gt; me permite generar comandos con ciertas combinaciones de teclas de hasta 5 teclas. Esta es la parte que quizás más modifico del teclado, ya que a medida que voy encontrando cosas interesantes las agrego. Para usar las combinaciones debo presionar RT(1) 2 veces y luego puedo hacer la combinación que me interesa.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-text highlighter-rouge&quot;&gt;t&lt;/code&gt; me abre/cierra el terminal de VSCode.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-text highlighter-rouge&quot;&gt;p&lt;/code&gt; me permite abrir el explorador de VSCode y navegarlo con flechas.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-text highlighter-rouge&quot;&gt;py&lt;/code&gt; me permite abrir un &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;ipython&lt;/code&gt; y ejecutar inmediatemente &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;%load_ext autoreload&lt;/code&gt; y &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;%autoreload 2&lt;/code&gt; para inmediatemente reconocer nuevos módulos.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-text highlighter-rouge&quot;&gt;pd&lt;/code&gt; me escribe &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;import pandas as pd&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-text highlighter-rouge&quot;&gt;np&lt;/code&gt; me escribe &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;import numpy as np&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-text highlighter-rouge&quot;&gt;plt&lt;/code&gt; me escribe &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;import matplotlib.pyplot as plt&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-text highlighter-rouge&quot;&gt;dd&lt;/code&gt; Selecciona todo y copia.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;alert-box alert radius &quot;&gt;&lt;p&gt;Y tengo algunas combinaciones secretas con claves y cosas que me da lata recordar, pero que no compartiré acá 🤗.&lt;/p&gt;
&lt;/div&gt;

&lt;h1 id=&quot;capa-de-navegación-capa-0&quot;&gt;Capa de Navegación (Capa 0)&lt;/h1&gt;

&lt;p&gt;Esta es la capa que utilizo para moverme. La activo con &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;OSL(0)&lt;/code&gt;. Está inspirada en las teclas de navegación de VIM y algunas cosillas extras. Esta es probablemente la capa que más utilizo. Incluso más que las letras (Esto porque uso Vimium para navegar en Chrome, es decir, puedo usar atajos de VIM para moverme en el navegador).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/corne/capa_0.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Esta capa la activo con la tecla que normalmente uno tiene el &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;CAPS LOCK&lt;/code&gt;. Un tap me permite que la siguiente tecla pertenezca a esta capa, por ejemplo &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;OSL(0) L&lt;/code&gt;, es equivalente a la flecha a la derecha, para salir de paréntesis, comillas, etc. (En VSCode puedo usar directamente &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Tab&lt;/code&gt; gracias a la extensión TabOut, pero en otros ambientes no puedo). Si hago doble tap bloqueo esta capa para quedarme navegando sin tener que dejar presionado &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;OSL(0)&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Donde normalmente va la &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;y&lt;/code&gt; y la &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;o&lt;/code&gt; tengo &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Home&lt;/code&gt; y &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;End&lt;/code&gt; respectivamente. Son teclas que uso muchísimo para moverme rápido en una línea. La &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;u&lt;/code&gt; y la &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;i&lt;/code&gt; son el &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;PageDown&lt;/code&gt; y &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;PageUp&lt;/code&gt; respectivamente.&lt;/li&gt;
  &lt;li&gt;Lo que más ocupo es dejar presionado &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Shift&lt;/code&gt; más las flechas que sería equivalente al visual mode de VIM y si presiono &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Control&lt;/code&gt; y hacia los lados salto por palabras palabras, mientras que hacia arriba/abajo hago scroll. Me permite moverme sin casi necesitar el mouse. Esto lo hago sólo cuando no tengo disponible los atajos de VIM, por ejemplo, en el navegador, o en Github.&lt;/li&gt;
  &lt;li&gt;Acá la tecla &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;- _&lt;/code&gt; está mapeado a &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;?&lt;/code&gt; . Y además &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;' &quot;&lt;/code&gt; está realmente mapeado a &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;'&lt;/code&gt; (la comilla simple).&lt;/li&gt;
  &lt;li&gt;Las teclas &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;n&lt;/code&gt; y &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;m&lt;/code&gt; me sirven como &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;*&lt;/code&gt; y &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;/&lt;/code&gt; respectivamente.&lt;/li&gt;
  &lt;li&gt;Finalmente &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;RT(1)&lt;/code&gt; sirve como mi &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Delete&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Además en mi mano izquierda tengo controles de mis servicios multimedia: La &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;f&lt;/code&gt; es para Play/Pause. La &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;s&lt;/code&gt; para retroceder y la &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;d&lt;/code&gt; para adelantar. Además el equivalente a la &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;r&lt;/code&gt; es para subir volumen y la &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;v&lt;/code&gt; para bajar volumen.&lt;/li&gt;
  &lt;li&gt;La tecla equivalente a la &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;g&lt;/code&gt; la tengo mapeada a un espacio, en caso que tenga la mano derecha en el Mouse y rápidamente necesite agregar un espacio.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;capa-numérica-capa-1&quot;&gt;Capa Numérica (Capa 1)&lt;/h1&gt;

&lt;p&gt;Esta es por lejos la capa que más me ha costado usar. Acá utilizo &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;OSL(1)&lt;/code&gt; como tap para colocar un sólo número, y dejo presionado en el caso de algún número de más de un caracter. Luego de mucho probar varias estrategias me quedé con una configuración en dos filas: del &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;1&lt;/code&gt; al &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;5&lt;/code&gt; y del &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;6&lt;/code&gt; al &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;0&lt;/code&gt;. Al principio me costó mucho esto, pero fue la única manera de dejar de presionado &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;LT(1)&lt;/code&gt; mientras usaba dedos de otra mano, que al menos a mí me alivió mucho el dolor que tenía.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;La filosofía acá fue: “Si es que tengo que dejar una tecla presionada para hacer una combinación, que presione con una y genere la combinación con la otra”.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;img src=&quot;/images/corne/capa_1.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Además la tecla &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;n&lt;/code&gt; me sirve como mi &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;ñ&lt;/code&gt;. El botón de tildes, acá me sirve como mi comilla simple. Y acá sí utilizo la tecla al lado del &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;.&lt;/code&gt; como mi &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;?&lt;/code&gt;. Si bien estas teclas están repetidas, la mayoría de las veces las uso desde esta capa.&lt;/p&gt;

&lt;h1 id=&quot;capa-de-símbolos-capa-2&quot;&gt;Capa de Símbolos (Capa 2)&lt;/h1&gt;

&lt;p&gt;Esta capa está exclusivamente dedicada a todos los símbolos.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/corne/capa_2.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Mi tecla &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;h&lt;/code&gt; corresponde a &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;=&lt;/code&gt; y mi tecla &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;j&lt;/code&gt; corresponde a el símbolo &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;+&lt;/code&gt;. Son los únicos en mi mano derecha, porque no tenía más espacio y por alguna razón me acomoda presionar &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;RT(1)&lt;/code&gt; y estas teclas.&lt;/li&gt;
  &lt;li&gt;En la parte izquierda, la fila superior son todos los símbolos asociados a números hasta el 5, excepto el &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;@&lt;/code&gt; que cambie por &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;&quot;&lt;/code&gt;. Estuve un tiempo obligado a usar un teclado en español y me gustó mucho la posición de las comillas ahí, por lo que las dejé. El resto normalmente lo tengo en otro lugar.&lt;/li&gt;
  &lt;li&gt;El Home Row izquierdo es la apertura de paréntesis &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;(&lt;/code&gt;, &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;[&lt;/code&gt; &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;&amp;amp;&lt;/code&gt;, &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;{&lt;/code&gt; y &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;\&lt;/code&gt; respectivamente. Esto porque &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;{&lt;/code&gt; se utiliza como desplazamiento en VIM y me acomodó mucho tenerlo directamente bajo mi índice.&lt;/li&gt;
  &lt;li&gt;En la fila inferior están sus opuestos: &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;]&lt;/code&gt;, &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;]&lt;/code&gt; &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;|&lt;/code&gt;, &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;}&lt;/code&gt; y &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;@&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;En las teclas &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;LT(2)&lt;/code&gt; y &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;LT(1)&lt;/code&gt; están los símbolos de &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;`&lt;/code&gt; y &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;~&lt;/code&gt; respectivamente.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Más simbología que eso creo que no tengo ni necesito.&lt;/p&gt;

&lt;h1 id=&quot;capa-de-configuración&quot;&gt;Capa de Configuración&lt;/h1&gt;

&lt;p&gt;Solía tener una capa de configuración, que si ven algún tutorial todos suelen ponerla en una capa presionando &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;LT(1)&lt;/code&gt; y &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;RT(1)&lt;/code&gt;. Yo la verdad, encontré que no me aportaba y rara vez la ocupaba. Por lo tanto, decidí dejar de agregarla, lo cual genera un teclado con menos memoria ocupada y más rapidito.&lt;br /&gt;
Además, como se puede ver, no tengo teclas de función. No las ocupo. Y en verdad no las he echado de menos. Eventualmente si las necesito las iré agregando.&lt;/p&gt;

&lt;div class=&quot;alert-box success radius &quot;&gt;&lt;p&gt;Debo decir que en verdad llegar a esta configuración me costó bastante y está inspirada en miles de configuraciones que ví. Si bien existen configuraciones numéricas que todavía me trabo, me siento súper cómodo como está. Lo mismo con los símbolos, es algo que ya tengo sumamente integrado y que hago rápido en forma de acorde. Por ejemplo &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;RT(1) A&lt;/code&gt; permite abrir paréntesis rápidamente y no es necesario que deje nada presionado&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Espero que mi configuración les pueda servir de inspiración para la suya (si es que tienen) o que les anime a probar algo parecido. Lo bueno es que no hay nadie mejor que yo para escribir en mi teclado. Lo malo, nadie más puede usarlo. Pero bueno, no es mi intención que alguien más lo use.&lt;/p&gt;

&lt;p&gt;Nos vemos a la otra.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/contact/&quot;&gt;&lt;strong&gt;Alfonso&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
</content>

			
				<category term="other" />
			
			
				<category term="tutorial" />
			

			<published>2023-08-01T00:00:00+00:00</published>
		</entry>
	
		<entry>
			<id>http://datacuber.github.io/vscode/</id>
			<title>Mis Extensiones para Trabajar en VSCode</title>
			<link href="http://datacuber.github.io/vscode/" rel="alternate" type="text/html" title="Mis Extensiones para Trabajar en VSCode" />
			<updated>2023-03-22T00:00:00+00:00</updated>

			
			<summary>Por qué prefiero VScode por sobre otros entornos.</summary>
			<content type="html" xml:base="http://datacuber.github.io/vscode/">&lt;p&gt;&lt;img src=&quot;/images/vscode/vscode.png&quot; alt=&quot;picture of me&quot; class=&quot;left show-for-large-up hide-for-print&quot; width=&quot;500&quot; /&gt;
&lt;img src=&quot;/images/vscode/vscode.png&quot; alt=&quot;picture of me&quot; class=&quot;center hide-for-large-up&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Trabajando como Científico de Datos, o de cualquier programador en general, pasas gran parte de tu día en frente de algún editor de código o un IDE. Si bien yo realmente creo que no está totalmente definido cuál es el mejor ambiente para trabajar, a mí me gusta la versatilidad que ofrece VSCode.  &lt;!--more--&gt;.&lt;/p&gt;

&lt;p&gt;En el mundo de los datos uno trabaja en varios frentes: Desde exploración o diseño de prototipos en Notebooks, hasta diseño de pipelines automatizados utilizando Scripts, y desplegando sistemas en Cloud o tecnologías asociadas como Docker. En general uno tiene que manejar muchas tecnologías en distintos entornos. Y a pesar de que me gustan las tecnologías especialistas, tener un entorno multifacético como VSCode me gusta mucho, en especial porque es un todo en uno: Python Scripts, Jupyter Notebooks, terminal además de permitir conectarme a entornos remotos como contendores de Docker o mi servidor utilizando SSH. Todo en un sólo lugar.&lt;/p&gt;

&lt;div class=&quot;alert-box warning radius &quot;&gt;&lt;p&gt;La intención de este artículo no es juzgar qué es mejor y donde trabajar. Yo tengo mi opinión y me gusta trabajar en VSCode. Básicamente quiero compartir y documentar para mi &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;yo del futuro&lt;/code&gt; cuál es mi configuración elegida.&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Lo bueno de VScode es que es completamente personalizable, pero me pasa que siempre que veo videos/artículos que abordan las mejores extensiones están enfocadas en un público más de desarrollo Web, o en otros lenguajes de programación más que en Python en el contexto de Ciencia de Datos. La idea de este artículo es mostrar extensiones conocidas y otras bien &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;under&lt;/code&gt; que me han permitido aumentar la productividad (uno de mis sueños que es no depender tanto del mouse, ni tampoco de Vim/NeoVim que no me terminan de convencer) o sencillamente que tu ambiente de trabajo se vea más bonito.&lt;/p&gt;

&lt;div class=&quot;alert-box info radius &quot;&gt;&lt;p&gt;Como editor de Texto en verdad creo que &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Vim/NeoVim&lt;/code&gt; es lo mejor que hay por velocidad, atajos, funcionalidades, y otras capacidades como IDE. Donde no me termina de convencer es como un entorno de ejecución en tiempo real de Python (tipo REPL). A diferencia del desarrollo de software uno necesita ir ejecutando trozos de código en memoria rápidamente y la verdad es que no he encontrado algo que me termine de gustar en &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;VIM&lt;/code&gt;. El &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Jupyter Notebook&lt;/code&gt; es lo mejor (o menos malo) que he encontrado, pero tiene muchos otros problemas. Para mí la mejor solución la tenía Atom con Hydrogen, pero sabrán que Microsoft decidió darlo de baja y eliminarlo (igual tenía algunas pifias de performance, se volvía muy lento con archivos con muchas líneas de código, pero la idea de tener un Script con el output inmediatemente al lado es para mí lo mejor que hay. VSCode ofrece el Python Interactive Window pero no anda ni cerca de lo útil que era Hydrogen, de hecho funciona muy mal). Me encantaría que algo así saliera en VSCode pero al parecer es medio imposible por la forma en la que VSCode funciona.&lt;/p&gt;
&lt;/div&gt;

&lt;h2 id=&quot;python&quot;&gt;Python&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/images/vscode/python.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;700&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Obvio, esta es probablemente la primera extensión a instalar para poder ejecutar código en Python. No mucho que decir, permite ejecutar Python en VSCode, permite la interactive Window, que es para ejecutar código en vivo tipo REPL pero en Python Script, además de habilitar los Jupyter Notebooks (antes eran extensiones separadas pero ahora viven todo bajo la extensión de Python). Actualmente esta extensión igual instala extensiones amigas como Jupyter Cell Tags, Jupyter Keymap, etc. Pero son extensiones que trabajan &lt;q&gt;behind the scenes&lt;/q&gt;.&lt;/p&gt;

&lt;p&gt;La extensión además permite refactoring (aunque no funciona mucho), e incorpora Pylance como Language Server para dar sugerencias de código, y isort como una herramienta para ordenar imports. Además tiene incorporación con formatters (yo uso Black) y linter (la verdad es que odio los linters por la cantidad de suciedad que agrega a mi pantalla, pero normalmente trabajo con flake8 pero ahora estoy probando Ruff).&lt;/p&gt;

&lt;p&gt;Una de las cosas que más me gusta es que por fín integraron la posibilidad de modificar Tags para poder usar librerías súper interesantes como Papermill.&lt;/p&gt;

&lt;div class=&quot;alert-box tip radius &quot;&gt;&lt;p&gt;Entiendo que aún existe gente que usa R, y la verdad es que si bien VSCode tiene una extensión para trabajar con R, creo que RStudio funciona mucho mejor. Si les interesa hablar de la pelea R vs Python, lo dejamos para otra ocasión.&lt;/p&gt;
&lt;/div&gt;

&lt;h1 id=&quot;extensiones-de-estética&quot;&gt;Extensiones de estética&lt;/h1&gt;

&lt;p&gt;Probablemente muchos pueden pensar que no son necesarias pero de verdad hacen que nuestro ambiente de trabajo sea más ameno. Al menos el hightlighting creo que ayuda mucho a leer mejor el código y poner atención a distintas partes del código. El resto me hace más feliz!! Pero igual ayuda.&lt;/p&gt;

&lt;h2 id=&quot;one-dark-pro&quot;&gt;One Dark Pro&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/images/vscode/one_dark.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;

&lt;p&gt;No mucho que decir acá más que es mi tema favorito (que de hecho proviene de Atom). Para mí es bien importante que el código sea muy multicolor, y que permita diferenciar cada parte del código. He probado muchos temas y este por lejos es el mejor, tiene colores predefinidos para:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Palabras Claves&lt;/li&gt;
  &lt;li&gt;Funciones&lt;/li&gt;
  &lt;li&gt;Clases&lt;/li&gt;
  &lt;li&gt;Métodos&lt;/li&gt;
  &lt;li&gt;Atributos&lt;/li&gt;
  &lt;li&gt;Strings&lt;/li&gt;
  &lt;li&gt;Números&lt;/li&gt;
  &lt;li&gt;Booleanos&lt;/li&gt;
  &lt;li&gt;Signos&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Una imagen de cómo se ve código Python con casi todo lo que mencioné se puede ver acá:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/vscode/sneak_peak.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;700&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;material-icon&quot;&gt;Material Icon&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/images/vscode/material_icon.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Esta es una extensión muy sencilla que coloca íconos a las carpetas y los íconos de manera muy bonito para reconocerlos mejor. Utiliza el nombre o la extensión para asignar íconos que facilitan encontrar archivos y diferencias carpetas importantes de otras no tan importantes.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/vscode/icon.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;300&quot; /&gt;&lt;/p&gt;

&lt;div class=&quot;alert-box info radius &quot;&gt;&lt;p&gt;Una cosa que me gusta bastante de VSCode es que marca qué archivos no están siendo trackeados por Git, cuáles son nuevos, cuáles son partes de &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;.gitignore&lt;/code&gt;, etc. Si bien no es ninguna extensión adicional lo que permite esto, Material Icon si agrega esos colores dorado, verde, o gris para denotar distintos estados de un archivo en Git.&lt;/p&gt;
&lt;/div&gt;

&lt;h2 id=&quot;indent-rainbow&quot;&gt;indent-rainbow&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/images/vscode/indent-rainbow.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Es una extensión muy pequeñita que permite marcar la indentación con colores para asegurarse que estén alineados. Si está incorrectamente alineado aparecerá en rojo, sino irán marcando por colores los distintos niveles.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/vscode/indent.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;better-comments&quot;&gt;Better Comments&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/images/vscode/better_comments.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Esta extensión permite destacar ciertos comentarios. En general lo he encontrado bien útil para poder tener mensajes a los que tengo que estar atento en el futuro o para que mis compañeros vean mis mensajes. Básicamente, tiene varios tipos de mensajes que se destacarán dependiendo del símbolo con el que partan:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/vscode/comments.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;300&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Si bien se sugieren esos comentarios, la verdad es que uno puede usar el color para lo que uno quiera.&lt;/p&gt;

&lt;h2 id=&quot;rainbow-csv&quot;&gt;Rainbow CSV&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/images/vscode/rainbow_csv.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Esta es otra pequeña extensión muy livianita, que permite colorear un CSV para poder tener una mejor lectura del archivo raw. Es la extensión más común, y si bien hay otras extensiones que permiten ver los CSV cómo Spreadsheets, a mí me gusta esta, porque de nuevo, me gusta el editor bien multicolor.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/vscode/csv.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;700&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;autocompletado&quot;&gt;Autocompletado&lt;/h1&gt;

&lt;p&gt;Son extensiones que ayudan a autocompletar código o escribir código de manera más rápida y oprimiendo menos teclas.&lt;/p&gt;

&lt;h2 id=&quot;github-copilot&quot;&gt;Github Copilot&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/images/vscode/copilot.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;

&lt;p&gt;La verdad es que cada vez lo ocupo menos. Si bien es un gusto que me complete mucho código, rara vez me da la respuesta absolutamente correcta, lo que significa que tengo que terminar editando la sugerencia. Lo mejor que tiene es sugerir variables de manera correcta o librerías que necesito importar, pero normalmente editar para mí es más lento que escribir todo. Una de las razones por las que he dejado de usarlo es porque hago clases donde la mayor parte del tiempo hago código en vivo, y no es ninguna gracia que te sugieran largas líneas de código.&lt;/p&gt;

&lt;p&gt;Sirve, vale la pena (yo lo tengo gratis por ser estudiante), pero no es la gran maravilla. Podría vivir sin él y prefiero algo como Intellicode que permita autocompletar más rápido y entender mejor lo que estoy haciendo.&lt;/p&gt;

&lt;h2 id=&quot;intellicode&quot;&gt;Intellicode&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/images/vscode/intellicode.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Esta extensión ha terminado siendo mucho más útil. Intellicode es bien interesante, ya que permite mejorar las capacidades de Pylance para dar mejores sugerencias. No sé si habrán dado cuenta de que muchas veces las sugerencias son bien malas. Uno siempre importa csv y al colocar &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;pd.read_&lt;/code&gt; se sugiere &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;.read_clipboard()&lt;/code&gt; porque alfabéticamente va primero. Al habilitar Intellicode, el motor de sugerencias va aprendiendo para entregar mejores sugerencias de acuerdo a tu código y a tus prácticas de escritura. Verás que mejores sugerencias se ven con una estrella:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/vscode/sugerencia.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;300&quot; /&gt;&lt;/p&gt;

&lt;div class=&quot;alert-box info radius &quot;&gt;&lt;p&gt;Solía haber una extensión llamada Kite que era muy similar y que la verdad funcionaba sumamente bien hasta que comenzar a cobrar por todas las cosas buenas que tenían. Lamentablemente quebró y encontré esta que ha suplido bastante bien mis necesidades.&lt;/p&gt;
&lt;/div&gt;

&lt;h2 id=&quot;path-intellisense&quot;&gt;Path Intellisense&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/images/vscode/path_intellisense.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Esta extensión permite el autocompletado de los paths/rutas reconociendo que archivos están disponibles a medida que uno construye la ruta. Sumamente útil, en especial para los que tenemos mala memoria recordando donde guardamos nuestra info. Creo que lo único que no me gusta es que exige para disparar las sugerencias (al menos inicialmente) el partir el path con &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;./&lt;/code&gt;. A parte de eso, muy buena extensión.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/vscode/path.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;python-type-hint&quot;&gt;Python Type Hint&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/images/vscode/type_hint.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Como el nombre lo dice, sugiere autocompletado para cuando quieres utilizar Type Hints.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/vscode/hint.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;300&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;superpoderes&quot;&gt;Superpoderes&lt;/h1&gt;

&lt;p&gt;Extensiones que permiten que haga cosas de manera más rápido o eficiente normalmente utilizando sólo el teclado.&lt;/p&gt;

&lt;h2 id=&quot;autodocstring&quot;&gt;Autodocstring&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/images/vscode/autodocstring.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Es otra pequeña extensión que entrega el template de un Docstring. Para los que no sepan, un Docstring es una documentación propia de una función en Python. Lo bueno de esto es que no sólo entrega una pauta de referencia de cómo rellenarla sino que además VSCode la renderiza de manera muy bonita cuando se hace hover sobre la función con el mouse.&lt;/p&gt;

&lt;p&gt;Es importante recalcar que VSCode soporta muchos formatos de docstring, pero yo ocupo estilo &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Numpy&lt;/code&gt;, el cuál se puede configurar en &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Settings &amp;gt; AutoDocstring:Docstring Format&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;La extensión automáticamente identificará los parámetros de entrada y si es que existe un &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;return&lt;/code&gt; y mostrará placeholders para reemplazar el tipo de dato y una descripción de cada elemento.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/vscode/docstring.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;400&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;quick-and-simple-text-selection&quot;&gt;Quick and Simple Text Selection&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/images/vscode/quick_simple.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Probablemente la mejor extensión para los que nos gusta usar el teclado y sumamente desconocida (pueden ver el número de descargas). Tiene atajos de teclados que permiten seleccionar todo lo que se encuentre entre cualquier tipo de paréntesis o comillas. Además tiene otra funcionalidad que permite cambiar el tipo de comillas inmediatamente.&lt;/p&gt;

&lt;p&gt;En mi caso lo tengo configurado como acorde, es decir, presionados como secuencia, no al mismo tiempo, esto gracias a mi Corne:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Ctrl k ;&lt;/code&gt;  seleccionará todo lo que está dentro de cualquier tipo de comillas.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Ctrl k a&lt;/code&gt; seleccionará entre paréntesis, &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Ctrl k s&lt;/code&gt; entre corchetes y &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Ctrl k d&lt;/code&gt; entre llaves. La elección de esto tiene que ver con cómo hago los distintos de paréntesis en mi teclado.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Ctrl k :&lt;/code&gt; irá rotando entre “”, ‘’ y ``. Súper útil.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;advanced-new-file&quot;&gt;Advanced New File&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/images/vscode/advanced_new_file.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Es una extensión que sólo permite crear un archivo nuevo. La gran gracia es que puedo especificar su ruta completa y creará carpetas intermedias que se requieran para su creación en el caso que no existan. Me gusta principalmente porque permite agregar un atajo de teclado para hacerlo más rápido.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/vscode/new_file.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;tabout&quot;&gt;TabOut&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/images/vscode/tabout.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Probablemente la extensión más simple pero más útil del mundo. Una de las ventajas que tiene VSCode es el auto-cerrado de paréntesis y comillas, que es genial para que nunca olvides cerrarlos. El problema que trae eso es que luego tienes que usar la flecha a la derecha ➡️ para salir del paréntesis o cierre de comillas. Esto es particularmente un problema porque la flecha a la derecha suele estar lejos en los teclados convencionales y eso significa perder la posición de home row si haces touch typing (que es una demora innecesaria). Esta extensión tiene el único objetivo de usar la tecla Tab para salir de un cierre de paréntesis o comillas. Demasiado simple, pero no les puedo explicar lo productivo que es.&lt;/p&gt;

&lt;h2 id=&quot;python-postfix-completion&quot;&gt;Python postfix completion&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/images/vscode/postfix.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Todavía no me termino de acostumbrar a esta extensión, pero tiene varias cosas muy interesantes. Por ejemplo: Si tengo un objeto en Python llamado &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;item&lt;/code&gt; y hago &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;item.len&lt;/code&gt; se transforma automáticamente en &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;len(item)&lt;/code&gt;. Esto siempre pasa, no te das cuenta que es una lista y no tiene &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;.shape&lt;/code&gt; y tienes que devolverte a hacer el &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;len()&lt;/code&gt;. Tiene varios atajos más para return, for loops, if statements, y funciones de conversión como &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;int()&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;python-indent&quot;&gt;Python Indent&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/images/vscode/python_indent.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Por alguna razón VSCode al presionar Enter dentro de alguna estructura de datos o alguna sintaxis que requiera indentación, no mantiene la indentación. Esta extensión asegura que si se mantenga. Simple! Por ejemplo si escribo un &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;else:&lt;/code&gt; y presiono Enter automáticamente la siguiente línea está indentada.&lt;/p&gt;

&lt;h1 id=&quot;misceláneo&quot;&gt;Misceláneo&lt;/h1&gt;

&lt;p&gt;Todas las extensiones que no supe como clasificar.&lt;/p&gt;

&lt;h2 id=&quot;git-graph&quot;&gt;Git Graph&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/images/vscode/git_graph.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Otra extensión muy pequeñita. Muchos recomiendan el uso de Git Lens (pero realmente no entiendo para qué sirve). Esto lo único que hace, pero lo hace muy bien, es mostrar de manera mucho más bonito un &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;git log&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/vscode/graph.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;300&quot; /&gt;&lt;/p&gt;

&lt;p&gt;La extensión muestra todas las ramas, como interactúan entre ellas y cada uno de los commits. Simple y bonito!!&lt;/p&gt;

&lt;h2 id=&quot;markdown-all-in-one&quot;&gt;Markdown All in One&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/images/vscode/markdown.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Como el sitio lo llevo principalmente en Markdown, uso esta extensión para habilitar atajos como &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Ctrl + B&lt;/code&gt; para Negrita o &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Ctrl + I&lt;/code&gt; para Cursiva, además de funcionalidades para trabajar mejor en Markdown como previsualizar o evitar el autocompletado innecesario.&lt;/p&gt;

&lt;h2 id=&quot;remote-ssh&quot;&gt;Remote SSH&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/images/vscode/ssh.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;

&lt;p&gt;La mejor extensión que existe para conectarte de manera remota a un servidor. La verdad es que por ahora ser cliente Movistar me dio un pequeño problema porque no tenía autorización al puerto 22 que es el puerto por defecto para usar SSH, pero aparte de eso, requiere cero configuración y me permite conectarme de manera remota a mi servidor JARVIS.&lt;/p&gt;

&lt;h2 id=&quot;project-manager&quot;&gt;Project Manager&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/images/vscode/project_manager.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Creo que todavía no le termino de sacar el beneficio a esta extensión, pero básicamente, en vez de tener que abrir cada carpeta de proyecto, o navegar por el terminal dependiendo de donde quieres trabajar te coloca una pestaña en la que tienes todos tus proyectos. Por lo que basta con abrir VSCode donde sea y ahí tienes todo. No me termino de acostumbrar porque tengo la costumbre de entrar siempre por terminal. Pero es una excelente extensión.&lt;/p&gt;

&lt;h2 id=&quot;dvc&quot;&gt;DVC&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/images/vscode/dvc.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Esta es una extensión para poder generar experimentos en DVC, muy similar a lo que sería Tensorboard. Probablemente muy útil (no la he usado mucho aún), pero requiere de un tutorial por sí sola.&lt;/p&gt;

&lt;div class=&quot;alert-box tip radius &quot;&gt;&lt;p&gt;La verdad es que tengo más extensiones instaladas, pero que en verdad no les he encontrado el uso. Una de ellas es &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Bookmarks&lt;/code&gt;, nunca la he usado. Hay otras que me parecen bien interesantes como &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Docker&lt;/code&gt; o &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Dev Containers&lt;/code&gt;, pero me gusta mucho el uso del terminal, por lo que casi siempre termino interactuando mediante él.&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Otra cosa que para mí es sumamente importante es el terminal. Si bien no es una extensión adicional, sí utilizo mucho el terminal integrado para no tener que abrir ventanas adicionales.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/vscode/terminal.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; width=&quot;900&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Mi terminal utiliza &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Oh my ZSH&lt;/code&gt; con &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Powerlevek10k&lt;/code&gt;. Esto me permite tener mucha información en la línea del terminal como:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;La ruta actual en la que estoy parado.&lt;/li&gt;
  &lt;li&gt;La rama de Git además archivos en stage, si commits esperando push o incluso un stash. Además me indica estados como rebase y el estado del rebase en caso de conflictos.&lt;/li&gt;
  &lt;li&gt;El ambiente de Python en el que estoy actualmente.&lt;/li&gt;
  &lt;li&gt;Hora.&lt;/li&gt;
  &lt;li&gt;Me indica si el estado del comando fue exitoso o no.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Y tiene autocompletado, syntax highlightning entre otros. Vale mucho la pena.&lt;/p&gt;

&lt;p&gt;Ahora, para que todo esto valga la pena tiene que ir de la mano con la configuración de VSCode, y por sobre todo los atajos de teclados. Yo diría que utilizo la mayoría de atajos por defecto, pero tengo algunos customizados que hacen mi vida más sencilla (en combinación con la disposición de algunas teclas en mi teclado como &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Ctrl&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Pero lo dejamos para la otra,&lt;/p&gt;

&lt;p&gt;Espero que les haya gustado y les sirva para armar un ambiente más ameno y cambiarse a VSCode.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/contact/&quot;&gt;&lt;strong&gt;Alfonso&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
</content>

			
				<category term="other" />
			
			
				<category term="tutorial" />
			

			<published>2023-03-22T00:00:00+00:00</published>
		</entry>
	
		<entry>
			<id>http://datacuber.github.io/msds/</id>
			<title>¿Dónde Aprender Ciencia de Datos?</title>
			<link href="http://datacuber.github.io/msds/" rel="alternate" type="text/html" title="¿Dónde Aprender Ciencia de Datos?" />
			<updated>2023-02-20T00:00:00+00:00</updated>

			
			<summary>¿Vale la pena tomar un Master para capacitarse en Ciencia de Datos?</summary>
			<content type="html" xml:base="http://datacuber.github.io/msds/">&lt;p&gt;&lt;img src=&quot;/images/msds/graduado.jpg&quot; alt=&quot;picture of me&quot; class=&quot;left show-for-large-up hide-for-print&quot; width=&quot;300&quot; /&gt;
&lt;img src=&quot;/images/msds/graduado.jpg&quot; alt=&quot;picture of me&quot; class=&quot;center hide-for-large-up&quot; width=&quot;250&quot; /&gt;&lt;/p&gt;

&lt;p&gt;¿Por qué siquiera molestarse en volver a la Universidad si hay tantos cursos por ahí que me permiten aprender lo mismo o más sin tener que pasar por el estrés de la Universidad? Eso es lo que debería haber pensado antes de entrar a &lt;!--more--&gt; la UAI. 
Acabo de terminar mi &lt;del&gt;primer&lt;/del&gt; segundo semestre en el MSDS de la Universidad Adolfo Ibañez, pero ¿Vale la pena el costo? ¿Vale la pena volver a la Universidad para aprender de Ciencia de Datos?&lt;/p&gt;

&lt;p&gt;&lt;q&gt;Actualizado 2023&lt;/q&gt;&lt;/p&gt;

&lt;p&gt;Bueno yo soy de las personas que cree que existen muchos recursos para aprender Ciencia de Datos. Y está lleno, algunos de los que yo he utilizado:&lt;/p&gt;

&lt;div class=&quot;alert-box info radius &quot;&gt;&lt;p&gt;A diferencia de lo que algunas personas muy reputadas en Linkedin puedan pensar yo sí creo que es importante programar de manera excelente. Ya que lo que menos uno puede hacer como Científico de Datos es darse el lujo de desperdiciar recursos por no tener la habilidad suficiente para llevar a cabo una buena implementación.&lt;/p&gt;
&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Google + Stackoverflow (no necesariamente para aprender Ciencia de Datos pero para poder implementar algo)&lt;/li&gt;
  &lt;li&gt;Datacamp&lt;/li&gt;
  &lt;li&gt;Youtube&lt;/li&gt;
  &lt;li&gt;Stanford Artificial Intelligence Professional Program&lt;/li&gt;
  &lt;li&gt;Coursera&lt;/li&gt;
  &lt;li&gt;Udemy&lt;/li&gt;
  &lt;li&gt;Contribuyendo en Open Source&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;En este artículo, me gustaría contarles cuál ha sido mi experiencia con estos cursos, cuáles tengo ahí esperando a tener tiempo libre y si vale la pena hacer lo que estoy haciendo: El&lt;code class=&quot;language-text highlighter-rouge&quot;&gt;MSDS&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;google--stackoverflow&quot;&gt;Google + Stackoverflow&lt;/h2&gt;

&lt;p&gt;Creo que esto es algo transversal para cualquier programador. Siempre que existan dudas de cómo implementar algo lo mejor es Googlear. De hecho, me pasó de que cuando tuve la oportunidad de estar a cargo de un equipo de Data Science para mí es mejor que alguien no sepa, pero sepa Googlear a que &lt;em&gt;“se las sepa todas”&lt;/em&gt;. Rara vez uno conocerá todo lo que necesita para una implementación o para solucionar un error de código. Creo que hoy en día aprender a Googlear y a elegir cuál de todas las respuestas de Stackoverflow es la más apropiada, es un skill que hay que desarrollar. Con una googleada y 2 o 3 links y ya mi problema debería estar solucionado (a menos que sea un problema muy raro y hay que incluso meterse en el Github del autor de la librería).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mi recomendación:&lt;/strong&gt; Es bueno saber googlear, usar palabras claves, comandos de búsqueda específica de Google y ser capaz de rápidamente discernir qué respueta de Stackoverflow es la más apropiada. A eso le sumaría conocer las documentaciones de sus librerías, cuáles son confiables y cuáles no tanto. &lt;strong&gt;Ej:&lt;/strong&gt; Pandas, Scikit-Learn, Pytorch son librerías con excelente documentación y que es muy fácil encontrar algo. Por otro lado, Tensorflow (no me maten), Pytorch Lightning, Statsmodels, son como documentaciones enredadas, difíciles de seguir. No sé si han entrado a la Documentación de SQLAlchemy o Pytest, esas son imposibles. Entonces, si la documentación es buena ir directo ahí, sino, Stackoverflow al rescate.&lt;/p&gt;

&lt;div class=&quot;alert-box warning radius &quot;&gt;&lt;p&gt;Hay otro tipo de documentación que está haciendo bien popular &lt;a href=&quot;https://www.linkedin.com/in/tiangolo/&quot;&gt;Tiangolo&lt;/a&gt; en librerías como SQLModel, Typer o FastAPI que es como un arma de doble filo. Es como en modo historia/tutorial que para aprender la librería está espectacular, pero cuando quieres buscar una funcionalidad específica nunca sabes donde buscar. Pero bueno estamos hablando de otra cosa.&lt;/p&gt;
&lt;/div&gt;

&lt;h2 id=&quot;datacamp&quot;&gt;Datacamp&lt;/h2&gt;

&lt;p&gt;Creo que he tomado suficientes cursos como para hablar con propiedad: tengo 37 Cursos en Python más el Track de Machine Learning Scientist y ML Fundamentals además de 18 en R. No les voy a mentir, no es un curso que sea increíblemente difícil y en el que vayan a volverse expertos, pero quita el miedo, y les ayuda a soltar la mano para &lt;em&gt;codear&lt;/em&gt; rápido. Yo aprendí Python en Datacamp, venía de sólo saber R, y aprendí Pandas, Scikit-Learn y Python Base a un nivel bastante decente. Eso junto con empezar a implementar cosas fue lo que más confianza me dió en Python.&lt;/p&gt;

&lt;p&gt;Ahora, hay cursos muy buenos como los de Pandas y Scikit-Learn (no todos, pero la mayoría), pero encontré particularmente malos los de Matplotlib y Seaborn, más que ayudarme a entender la librería me ayudaron a confundirme más. Además, tomé por ahí un curso de GIT y de UNIX que fueron bastante buenos para perder el miedo a estas tecnologías.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mi Recomendación:&lt;/strong&gt; Creo que este tipo de cursos sólo vale la pena para gente que no conoce una tecnología y quieres perderle el miedo. Si bien yo pagué dos veces la suscripción anual a Datacamp, no creo que lo volvería a hacer. Si te quieres iniciar en R o Python (creo que ahora también tiene SQL y Tableau) vale completamente la pena. Si tú intención es especializarte, entonces te vas a aburrir.&lt;/p&gt;

&lt;h2 id=&quot;youtube&quot;&gt;Youtube&lt;/h2&gt;

&lt;p&gt;Para mí es casi mi fuente primaria de sabiduría. Obviamente hay de todo y hay que saber filtrar. No tengo las respuestas de todo y probablemente va a depender mucho de cuáles son tus intereses para aprender. Yo puedo compartir los youtubers que más sigo para algunos de mis temas:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Probabilidad y Estadística y Teoría en General: &lt;a href=&quot;https://www.youtube.com/c/joshstarmer&quot;&gt;Statsquest&lt;/a&gt;, por lejos lo mejor. A algunos les pueden molestar sus canciones, pero vale la pena aguantárselas porque el contenido es muy bueno. Y uno que encontré para algebra lineal que es espectacular &lt;a href=&quot;https://www.youtube.com/c/3blue1brown&quot;&gt;3Blue1Brown&lt;/a&gt; recomendado por mi amigo &lt;a href=&quot;https://www.linkedin.com/in/alex-%C3%A1lvarez-l%C3%B3pez-a561ba164/&quot;&gt;Álex Álvarez&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;Python Misceláneo: &lt;a href=&quot;https://www.youtube.com/c/PythonEngineer&quot;&gt;Python Engineer&lt;/a&gt;, &lt;a href=&quot;https://www.youtube.com/c/sentdex&quot;&gt;Sentdex&lt;/a&gt;(aunque no me gusta mucho en aspectos más teóricos, es medio chamuyento).&lt;/li&gt;
  &lt;li&gt;Deep Learning en Español: &lt;a href=&quot;https://www.youtube.com/c/sensio-ia&quot;&gt;Sensio&lt;/a&gt;, lo mejor que hay en español.&lt;/li&gt;
  &lt;li&gt;Machine Learning y Deep Learning: &lt;a href=&quot;https://www.youtube.com/c/AbhishekThakurAbhi&quot;&gt;Abishek Thakur&lt;/a&gt;, súper buen contenido del primer Cuádruple Kaggle GrandMaster.&lt;/li&gt;
  &lt;li&gt;Otros canales buenos:
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/@ArjanCodes&quot;&gt;ArjanCodes&lt;/a&gt; es un canal misceláneo de muchas cosas pero todas en Python. He aprendido muy buenas prácticas de diseño de software viendo este canal. Y el tipo explica muy bien.&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/@HuggingFace&quot;&gt;HuggingFace&lt;/a&gt; es una joyita bien escondida.&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/c/TheAIEpiphany&quot;&gt;AI Epiphany&lt;/a&gt;, es un canal mucho más avanzado de Aleksa Gordic, un cabro que hoy está trabajando en DeepMind. Creo que tanto su canal como su Github tiene mucha info de lo último en Deep Learning.&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/c/AladdinPersson&quot;&gt;Aladdin Persson&lt;/a&gt;, es un canal súper denso igual, casi siempre son implementaciones de Papers.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Cursos de Deep Learning: Canales de Stanford principalmente.
    &lt;ul&gt;
      &lt;li&gt;CS229 &lt;a href=&quot;https://www.youtube.com/watch?v=jGwO_UgTS7I&amp;amp;list=PLoROMvodv4rMiGQp3WXShtMGgzqpfVfbU&quot;&gt;2018&lt;/a&gt; y &lt;a href=&quot;https://www.youtube.com/watch?v=KzH1ovd4Ots&amp;amp;list=PL4YhK0pT0ZhVf4nIsEjcRT5K47K7WH76P&quot;&gt;2019&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=rmVRLeJRkl4&amp;amp;list=PLoROMvodv4rOSH4v6133s9LFPRHjEmbmJ&quot;&gt;CS224N&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=rha64cQRLs8&amp;amp;list=PLoROMvodv4rPt5D0zs3YhbWSZA8Q_DyiJ&quot;&gt;CS224U&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=JAB_plj2rbA&amp;amp;list=PLoROMvodv4rPLKxIpqhjhPgdQy7imNkDn&quot;&gt;CS224W&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/channel/UCpvn0ycxIA6Uf8W00OX3frQ&quot;&gt;Uva Deep Learning&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/playlist?list=PLoROMvodv4rNiJRchCzutFw5ItR_Z27CM&quot;&gt;Transformers United&lt;/a&gt; (no lo he visto aún)&lt;/li&gt;
      &lt;li&gt;HuggingFace Course: Acá tienen varias opciones. Yo estoy en este momento tomando el de NLP, pero no me había percatado del beneficio de este curso en partícular porque se explica demasiado bien el por qué funcionan los transformers.
        &lt;ul&gt;
          &lt;li&gt;&lt;a href=&quot;https://huggingface.co/course/chapter1/1&quot;&gt;Curso Transformers&lt;/a&gt;.&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;https://huggingface.co/deep-rl-course/unit0/introduction&quot;&gt;Curso Reinforcement Learning&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;https://github.com/huggingface/diffusion-models-class&quot;&gt;Diffusion Models&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;etc.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Mi Recomendación:&lt;/strong&gt; Suelo utilizar Youtube para contenido más denso, que no siempre entiendo de un paper o un libro, por lo que prefiero que alguien me lo explique. Para dudas de programación, normalmente googleo.&lt;/p&gt;

&lt;h2 id=&quot;artificial-intelligence-professional-program&quot;&gt;Artificial Intelligence Professional Program&lt;/h2&gt;

&lt;p&gt;Este es el programa que estoy a punto de terminar en la Universidad de Stanford. Básicamente te entregan un pool de cursos y tú debes tomar 3. Yo tomé &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;XCS229&lt;/code&gt; que es el curso de Machine Learning de Andrew Ng, &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;XCS224W&lt;/code&gt; que es el curso de Jure Leskovec de Redes Neuronales de Grafos y &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;XCS224N&lt;/code&gt; que es el de Chris Manning de NLP y Transformers.&lt;/p&gt;

&lt;p&gt;Estos son por lejos los mejores cursos que he tomado. He aprendido muchísimo tanto teóricamente, como en implementaciones prácticas. Son cursos basados en los cursos dictados en postgrado en Stanford, con las mismas tareas que se dan en el Campus. Son cursos densos, teóricamente muy profundos, y las tareas son muy difíciles, normalmente tienen parte teórica para probar la matemática detrás e implementaciones en Python (ML implementa en Numpy desde cero y en DL con Pytorch).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mi Recomendación:&lt;/strong&gt; Este tipo de cursos se toman sólo si te gusta sufrir. Me tomó cerca de 2 años tomar los 3 cursos, toman un trimestre cada uno, y además son muy caros: &lt;del&gt;US$1595&lt;/del&gt; US$1700 y ojo que si no estudias te los puedes echar. Hay alta tasa de deserción y no se devuelve el dinero. Lo que sí, quedas certificado por la Universidad de Stanford y recibes Certificados y un registro de la Universidad.&lt;/p&gt;

&lt;h2 id=&quot;coursera-y-udemy&quot;&gt;Coursera y Udemy&lt;/h2&gt;

&lt;p&gt;Este es el cementerio de cursos más grandes que tengo, en especial de Udemy. En Udemy, hay harto curso malo, y que luego de un par de videos te das cuenta que no vas a aprender nada nuevo. Yo tomé unos de Pytorch que me gustaron y unos de una librería llamada Feature Engine, aunque aún me queda uno esperando de MLOps dado por la misma autora. En Coursera, dado que son más caros, tengo muchos ahí que tomé completos, pero sin las tareas. Los mejores cursos a tomar en Coursera son definitivamente cualquiera de &lt;em&gt;Deep Learning AI&lt;/em&gt; y uno que se llama &lt;em&gt;How to Win a Kaggle Competition&lt;/em&gt;, que hoy es muy dificil de encontrar porque es dada por una Universidad Rusa y debido a la guerra no está disponible para nuevos estudiantes. &lt;em&gt;How to Win a Kaggle Competition&lt;/em&gt; tiene todos los trucos habidos y por haber de ML clásico: EDA, Preprocesamiento, Tuning de Hiperparámetros, un detalle de todos los modelos más comunes, Data Leakage, Cross Validation, Ensambles.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mi recomendación:&lt;/strong&gt; En Coursera, tomar los de Deep Learning AI. Son muchísimos, pero valen la pena aunque sean en Tensorflow (El de GANs es en Pytorch). Y no sé, en mi opinión son cursos difíciles y caros, entonces si hay algo que realmente quieres aprender dale, porque son en general de muy buen nivel. Respecto a Udemy, no sé, tomarlos bajo tu propio riesgo, es muy alta la chance de salir decepcionado.&lt;/p&gt;

&lt;h2 id=&quot;contribuyendo-en-open-source-nuevo&quot;&gt;Contribuyendo en Open Source (Nuevo)&lt;/h2&gt;

&lt;p&gt;Esto es algo nuevo para mí. Y tengo que agradecer a &lt;a href=&quot;https://www.linkedin.com/in/soledad-galli/&quot;&gt;Sole Galli&lt;/a&gt; por animarme a hacerlo. Ella es la mantenedora de Feature Engine y me animo a solucionar un bug que encontré en la librería el año pasado. Fue genial porque es super presente en las revisiones y en las sugerencias de donde hacer las correcciones. Sigo contribuyendo regularmente a la librería y creo que el mayor aprendizaje es en buenas prácticas de programación y uso de Git.&lt;/p&gt;

&lt;h2 id=&quot;y-el-msds&quot;&gt;¿Y el MSDS?&lt;/h2&gt;

&lt;p&gt;Bueno el Master of Science in Data Science (MSDS, igual es como malo el nombre), es un Magister Académico, es decir, está enfocado en quedarse idealmente investigando y/o eventualmente tomar el Doctorado en Data Science. ¿Por qué lo tomé? No voy a mentir, por el cartón. Yo soy solo egresado de Ingeniería Civil (y tengo mi licenciatura en Ciencias de la Ingeniería), pero es algo que siempre me sacan en cara. Aún así, Jooycar confió en mí y me dio la oportunidad de ser Head de Data Science y creo no haberles fallado. Pero en general el cartón pesa. Ahora, yo tuve que entrevistar varios tipos con Magister y no les encontré nada especial. Es más, incluso algunos sabían menos que un Data Scientist con un par de años de experiencia.&lt;/p&gt;

&lt;p&gt;La siguiente pregunta es: ¿Por qué en la UAI? Bueno, ví varias opciones, y Magister en Data Science propiamente tal sólo encontré la UAI y la Universidad de Chile. Y la UAI me becó, por eso en la UAI. No creo que haya una gran diferencia entre ambas universidades. La otra opción que tenía era tomar un Msc. en Informática y armar mi malla con ramos en Ciencia de Datos. Pero la UAI me becó y aquí estamos.&lt;/p&gt;

&lt;p&gt;La decisión fue tomada en conciencia de que probablemente no aprendería nada nuevo. Esto, luego de ver un video de &lt;a href=&quot;https://www.linkedin.com/in/mark-tenenholtz-173a3a122/&quot;&gt;Mark Tennenholtz&lt;/a&gt; (Kaggle Master) que está haciendo su Master en Georgia Tech y dijo estar aprendiendo incluso menos cosas de las que ha aprendido en Kaggle. Bajo eso, dije bueno: &lt;q&gt;No pierdo nada en intentar estando becado&lt;/q&gt; y &lt;del&gt;me he sorprendido para bien, he aprendido más de lo que esperaba,&lt;/del&gt; me encantó. La verdad es que terminé aprendiendo demasiado de cosas que jamás pensé que fueran tan útiles. Acá dejo un detalle de todos los ramos que tomé, sin pelos en la lengua.&lt;/p&gt;

&lt;h3 id=&quot;primer-semestre&quot;&gt;Primer Semestre&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Análisis Geoespacial&lt;/strong&gt; (Prof. Moreno Bevilacqua): Creo que fue el ramo que más me gustó del primer semestre. Es básicamente estadística avanzada enfocado en Campos Aleatorios. No sé si alguna vez utilice esto, pero la cantidad de estadística multivariada que aprendí es impagable. Este tipo de análisis permite ajustar modelos en el espacio y espacio-tiempo para luego generar predicciones (Kriging). El ramo lamentablemente se hace en R, pero utilizamos la librería que creó el profe además de implementaciones hechas de manera manual. Súper buena mezcla entre teoría dura y código.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Current Trends in Data Genomics&lt;/strong&gt; (Prof. Álvaro Cortés): Este es quizás el ramo más interesante. A mí no me mató principalmente porque no me gusta la Biología, pero básicamente nos enseñaron lo último en análisis genético tanto de ADN como de ARN. Además lo interesante es que el profe nos hizo clases desde Bélgica (KU Leuven) y nos dió acceso a un Supercomputador (HPC Cluster), lo cuál fue una tremenda experiencia (trabajamos con Clusters con hasta 384 Nodos). Es sumamente interesante saber cómo se pueden detectar mutaciones, cánceres, variantes genéticas, etc. Es una clase de harta teoría, nos hicieron leer varios papers, pero quizás lo mejor fue que justo en la mitad del curso se liberó el artículo indicando que finalmente se pudo secuenciar el Genoma Humano completo, lo cual fue entretenido, porque gracias al curso pudimos entender el alcance de este trabajo. Finalmente (y eso que el curso no me mató), el trabajo final consistió (en mi caso) en investigar acerca de un Modelo de Red Neuronal de Grafos para el proceso &lt;em&gt;de novo assembly&lt;/em&gt;, para poder generar Genomas de especies en las que no se tiene referencia. Realmente fue un joya tener un curso así aunque es difícil que alguna vez lo llegue a aplicar.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Percepción Remota&lt;/strong&gt; (Prof. Javier Lopatín): Otro ramo que me gustó, y el tema en el que estoy haciendo mi tesis. Al principio el nombre no parecía muy atractivo, pero terminó siendo súper interesante. Principalmente la percepción remota se encarga de utilizar imágenes que pueden ser satélitales, de drones, de aviones y un largo etc. para poder detectar cosas. Esto lo encontré súper interesante, porque el ramo es en Python, es sumamente aplicado, y además pudimos utilizar librerías de manipulación de imágenes para calcular muchas cosas: pendientes, sombras, altitud. Aprendimos librerías súper cool como rasterio, xarray, geopandas y es un tema súper interesante (por eso mi tema de investigación), entre otras cosas, por el cambio climático. El ramo enseña todo lo teórico en cuánto a qué información se puede extraer de imágenes hiperespectrales (o sea tienen más canales que el RGB) y métodos de Machine Learning en Clasificación, Regresión y Series de Tiempo (aunque es sólo una pincelada). &lt;strong&gt;SPOILER&lt;/strong&gt;: Estoy trabajando en el uso de Deep Learning para Anomalías en Series de Tiempo de Imágenes, súper choro.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Tópicos en Data Management y Data Analytics&lt;/strong&gt; (Nombre fancy para Bases de Datos) (Prof. Miguel Romero): Este pensé que sería el ramo más aburrido de la vida pero terminó siendo súper interesante. Aprendimos SQL (y sí, aprendí cosas nuevas de SQL que no sabía, como consultas recurrentes, índices, y uno que otro truquito de queries), aprendí Mongo (yo igual había usado mongo, pero siento que el curso enseña varias cosas bastante avanzadas que no sabía) y lo que más me gustó fue Neo4j. Neo4j es una base de datos de Grafos, que realmente cambió mi manera de ver la organización de la data. Sirve tanto para data estructurada como no estructurada y es poderoso y rápido, y además permite aplicar proyecciones y algoritmos como PageRank. Definitivamente voy a estar subiendo un tutorial de Mongo y Neo4j. Si bien no esperaba mucho de este curso, que de paso es obligatorio, terminé aprendiendo muchísimo.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Técnicas Estocásticas y Estadísticas en Data Science&lt;/strong&gt; (nombre fancy para estadística básica) (Prof. Leopoldo Bertossi): Quizás el ramo más decepcionante, y no creo que sea por la materia sino por el Profe. Realmente la pasamos mal en este ramo, es estadística básica, y realmente aprendí conceptos muchos más robustos en estadística, variable aleatoria discreta sobre todo, redes de Bayes, algo de Markov, y un poquito de teoría de Información, pero no volvería a tomar este ramo con el mismo profe. Explica bien, pero nunca entendimos lo que preguntaba en las evaluaciones, y lo pasamos mal, era bien pesote. Lo voy a dejar ahí. Lamentablemente es un ramo obligatorio y que no vale la pena, ya que aprendí mucha más estadística en Análisis Geoespacial.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;segundo-semestre&quot;&gt;Segundo Semestre&lt;/h3&gt;

&lt;p&gt;Durante el segundo semestre tomé los siguientes ramos:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Álgebra Lineal y Optimización para Data Science (Prof. Miguel Romero)&lt;/strong&gt;: Este fue el curso cortacabezas, bien denso teoricamente pero probablemente el mejor curso que he tomado de teoría asociada a Data Science. El curso es una joya, especialmente porque está dividido en dos partes: Algebra Lineal, creo que en el Algebra Lineal de pregrado rara vez se aborda el entendimiento de Operaciones Matriciales como Transformaciones Lineales que llevan de una dimensión a otra (que es la base del funcionamiento de las redes neuronales). El curso no sólo cubre en detalle toda la parte matricial incluyendo interpretabilidad de operaciones, calculo diferencial y optimización de funciones matriciales, pero también toca en detalles algoritmos basados en operaciones tipo Valores Propios como son PageRank, PCA y SVD. Y una segunda parte de Optimización que cubre desde Optimización Convexa hasta Optimización No Convexa, incluyendo algoritmos como SGD, Momentum, Nesterov, Adagrad, Adadelta, RMSProp y Adam. El curso es muy bueno pero difícil. Las pruebas son de corte más teórica, incluyendo algunas demostraciones no tan complejas, pero que hay que pensarlas igual, y las tareas son más de código implementando todo en Numpy. Muy buen curso.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Métodos de Aprendizaje de Máquina en Data Science (Prof. Raimundo Sanchez)&lt;/strong&gt;: Este fue un ramo obligatorio (y el que pasé con la peor nota 😂) y la verdad no me gustó mucho. Siento que no es un curso en el que se enseñe modelamiento (para ser justos hubo otra sección donde se entró en más detalle) pero no se entró en el detalle que esperaba (como sí se hizo en Algebra Lineal). El profe muy simpático, pero hubo tres cosas que me molestaron particularmente: Una que el curso se hizo en R y &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;tidymodels&lt;/code&gt; (luego de usar Scikit-Learn se nota que R es realmente malo para Machine Learning. La documentación es pésima, los errores son muy confusos y no hay mucha ayuda en StackOverflow, además de que la librería es muy lenta. De hecho fue tanto así que para la última tarea se permitió el uso de Python porque la última entrega requería del uso de un dataset de 1M de registros y &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;tidymodels&lt;/code&gt; sencillamente no daba a basto. Segundo, realmente como un curso de post-grado era absolutamente necesario entrar en los detalles más mínimos y descomponer las ecuaciones detrás de cada modelo. Humildemente creo que la documentación de Scikit-Learn es más profunda que la clase. Finalmente, me pareció que las pruebas eran muy de opinión, muy subjetivas, casi apreciativas, y no creo que sea la mejor forma de evaluar este tipo de curso. En general, no me gustó mucho el curso, pero bueno, no me fue tan bien y puede sonar a picado 😇.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Seminario de Tesis (Prof. Tamara Fernández)&lt;/strong&gt;: Este curso fue un desperdicio. Pero espero se entienda bien. No porque el curso fuera malo, sino que porque desaprovechamos una profesora de talla mundial en un curso Online. Creo que ella intentó hacer lo mejor que pudo enfocándose en cosas que son sumamente útiles para la investigación: Aprender a buscar papers, crear documentos académicos, utilizar Latex, y algunas herramientas de mucha utilidad para alguien que quiere investigar. Lamentablemente en mi opinión perdimos demasiado tiempo en comandos básicos de Latex, que son googleables, y no tuvimos la oportunidad de aprovechar a la profe. Digo esto porque la actividad final del ramo fue diseñar un póster del trabajo de tesis, que a mí en particular me sirvió mucho para poder ordenar mis ideas y encaminar sumamente bien mi tesis (que va avanzando bastante bien), pero también tuvimos la oportunidad al finalizar la sesión de quedarnos conversando con ella y aprender muchísimo sobre su experiencia estudiando en Oxford, su trabajo con su supervisor &lt;a href=&quot;https://www.stats.ox.ac.uk/~teh/&quot;&gt;Yee Whye Teh&lt;/a&gt;, Research Scientist en DeepMind, y obviamente aprendiendo a sobrevivir un doctorado. Realmente hubiera sido genial poder tener muchas más conversaciones con ella.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;alert-box tip radius &quot;&gt;&lt;p&gt;En mi opinión este es uno de los fuertes de la UAI. Viniendo de Universidades como la USM donde al menos en mi tiempo costaba muchísimo que un profesor te diera bola. Tener conversaciones donde los profes no te hagan sentir como “idiota”, y en verdad te animen y aconsejen sobre tu futuro es algo invaluable.&lt;/p&gt;
&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Neural Networks (Prof. Daniel Furtado)&lt;/strong&gt;: No me gustó en general el ramo. No aprendí nada nuevo porque en mi opinión el curso estaba muy desactualizado, aunque siendo súper sincero a muchos les sirvió bastante. Los puntos bajos para mí es que tocamos cosas como la historia de la IA o arquitecturas que ya nadie usa y que no existe forma de implementarlas de lo añejas que están y lo que todo queríamos que era algo como Transformers, RF o Stable Diffusion eran temas que el profe ni siquiera conocía. Ahora las tareas fueron bien entretenidas, pero dependía mucho de el esfuerzo que uno quisiera poner. Debido a que yo quería sacarle el máximo provecho al curso implementé en Pytorch un MLP, un RBF-NN, una ResNet, una EfficientNet. Pero una tarea que era implementar una GAN se eliminó (y menos mal, porque teníamos muy poco tiempo para todo eso). No recomendaría el curso, y no me gustó. Probablemente la gran decepción del semestre.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Grafos en Ciencia de Datos (Prof. Miguel Romero)&lt;/strong&gt;: Otro curso excelente, que es una de las grandes joyas del programa. El profe es un crack, y este es el tema que más domina. El curso es interesante no sólo porque toca temas relacionados a Grafos, pero también porque introduce mucho background de Informática que uno como Data Scientist debería tener: Escritura de Algoritmos, Complejidad Algorítmica (Notación Big O, Notación NP, etc.), estructura de datos, y por supuesto su aplicación en Grafos. Cosas muy útiles como Breadth First Search, Depth First Search, fueron explicados en detalles e implementados por nosotros en código además de algoritmos para caminos mínimos, minimum spanning trees, clustering, comunidades, cliques, coloreo, homomorfismos, etc. Además pudimos tener una visión general de cómo se implementan algoritmos de Machine Learning en Grafos, como PageRank, PageRank con Teleportación, DeepWalk, Node2vec, Node Embeddings, y entender el detalle la diferencia con las Redes Neuronales de Grafos. En particular agradezco mucho el uso de Pytorch Geometric y el poder entender muy en detalle el funcionamiento interno. Creo que este es el curso en el que más cosas nuevas (y útiles) aprendí.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;alert-box warning radius &quot;&gt;&lt;p&gt;Muchas personas se quejaron porque el profe Romero es un poco bajo perfil. Lo consideran fome y aburrido para sus clases, pero yo lo siento como en el mismo tono de Andrew Ng, que parece que tiene sueño, su tono es medio plano, pero dejando eso de lado y enfocando en su contenido son demasiado buenos. Sus slides son demasiado ordenadas y el orden en el que va pasando el contenido hace que realmente uno disfrute mucho sus ramos. Para mi gusto (y esto es muy personal) fue el mejor profesor del programa.&lt;/p&gt;
&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Modelos Lineales (Prof. Moreno Bevilacqua)&lt;/strong&gt;: Este fue un ramo que me gustó mucho también. Fue un ramo bien teórico y el Profesor Bevilacqua se caracteriza por ser un profesor de mucha pizarra y de mucha demostración. Siempre es bueno tener en cuenta técnicas de demostración, los supuestos al momento de generar modelos lineales, y técnicas de optimización como el Maximum Likelihood Estimation (MLE). El ramo si bien es en R, se usa muy poca librería, porque el profe le gusta implementar todo desde cero, que es un approach que me gusta, porque desmenuzar el código me ayuda a entender de mejor manera cómo funciona el algoritmo por detrás. Una de las cosas que más agradecí es entender en detalle el problema de la multicolinealidad (acá influyó bastante entender el problema de cuadrados mínimos desde el Algebra Lineal) y al menos el Profesor Bevilacqua, piensa que variables multicolineales o con un grado de multicolinealidad no es de gran gravedad, lo cual fue algo que me sorprendió bastante. Otro de los mitos que rompió fue el tema de la significancia de las variables. He estado en varios cursos, en los que se enseña como método de selección de variables el deshechar las variables no significativas por p-value, algo que siempre me llamó la atención porque nunca he visto un algoritmo que mejores su performance predictiva por eliminar variables no significativas.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
  &lt;p&gt;Bueno, ¿vale la pena? Depende.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;En mi caso, estaba buscando aplicaciones en Ciencias de Datos que no sean típicos modelos de fuga, de propensión y que el único objetivo que tienen es que empresas ganen más plata. Por otro lado, como mi rollo es el Deep Learning, he tenido la oportunidad de aprender varias cosas fuera de lo común, acabo de implementar un algoritmo de Anomaly Detection llamado &lt;a href=&quot;/deepant/&quot;&gt;DeepAnT&lt;/a&gt; y voy a estar implementando varios más, algunos que no tengo idea cómo. Si te gusta implementar cosas raras, que tienen un valor, pero no necesariamente en lo económico para una empresa (en mi caso queremos encontrar anomalías en el uso de terrenos como bosques &lt;del&gt;, humedales y turberas&lt;/del&gt; con imágenes satelitales), entonces vale completamente la pena. Si quieres sólo estar más preparado para hacer la pega de siempre (lo cual no es malo), quizás es mejor un programa Profesional.&lt;/p&gt;

&lt;p&gt;Sólo a modo de ejemplo, el Magister Profesional de la UAI (puede ser cualquier otro, nada en particular con este), probablemente te enseñará elementos más aplicados, con menos teoría. Perfeccionarte en R y Python, cómo hacer buenas visualizaciones, uno que otro modelo por ahí, y un largo etc.&lt;/p&gt;

&lt;p&gt;En el MSDS, no teníamos tiempo de aprender a programar, el que sabía bien, y sino, doble pega (aunque se ofrece un bootcamp de nivelación en caso de necesitarlo). En mi caso, me ayudó mucho tener experiencia en Python y R, hizo que los ramos se me hicieran menos pesados. Pero aún así en especial en las últimas 3 semanas fue caótico, mucho que estudiar, muchas tareas, presentaciones, informes, posters, y entregas teóricas (todo en Latex, aunque no es obligación) y código. Lo pasé mal, así que hay que tener ojo también con cuanta carga quieres tener. Yo partí tomando el Master y mi pega (que siendo bien organizado es posible, al menos en mi opinión), luego me echaron, pero el segundo semestre tuve proyectos freelance, competencia, clases, bootcamps y sobreviví.&lt;/p&gt;

&lt;p&gt;Espero que para los que están buscando algún programa les sirva. Traté de ser lo más imparcial posible. Y si me preguntan si recomendaría el MSDS yo diría que sí, me gustó. Aprendí cosas que no están en Youtube, o que cuesta mucho encontrar, y que rara vez tendrás la oportunidad de verlas en empresas tradicionales. Me gustó tanto que decidí seguir adelante y comienzo mi PhD en Ciencias de Datos en Marzo, aunque todavía estoy en el proceso de cerrar mi tesis de Magister que tiene fecha para Mayo.&lt;/p&gt;

&lt;p&gt;Nos vemos y espero que sea de utilidad.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/contact/&quot;&gt;&lt;strong&gt;Alfonso&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
</content>

			
				<category term="ds" />
			
			
				<category term="tutorial" />
			

			<published>2023-02-20T00:00:00+00:00</published>
		</entry>
	
		<entry>
			<id>http://datacuber.github.io/project-pt3/</id>
			<title>¿Hagamos un Proyecto desde cero? Parte 3</title>
			<link href="http://datacuber.github.io/project-pt3/" rel="alternate" type="text/html" title="¿Hagamos un Proyecto desde cero? Parte 3" />
			<updated>2022-10-10T00:00:00+00:00</updated>

			
			<summary></summary>
			<content type="html" xml:base="http://datacuber.github.io/project-pt3/">&lt;p&gt;&lt;img src=&quot;/images/rul/lags.png&quot; alt=&quot;picture of me&quot; class=&quot;left show-for-large-up hide-for-print&quot; width=&quot;250&quot; /&gt;
&lt;img src=&quot;/images/rul/lags.png&quot; alt=&quot;picture of me&quot; class=&quot;center hide-for-large-up&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Esta es la tercera patita de cómo hacer un proyecto desde cero. Puedes ver &lt;a href=&quot;/project-pt1/&quot;&gt;la parte 1 acá&lt;/a&gt; y &lt;a href=&quot;/project-pt2/&quot;&gt;la parte 2 acá&lt;/a&gt;. La idea es que, como ya implementamos un modelo baseline y un clipping, ahora podamos ir implementando elementos que permitan poder mejorar el puntaje obtenido. &lt;!--more--&gt;.&lt;/p&gt;

&lt;p&gt;Si es que hiciste la tarea, habrás notado que algo raro pasa. En la vida real nosotros no podemos ver nuestro Test Set, eso irá ocurriendo a medida de que el Motor vaya funcionando. Por lo tanto, nosotros deberíamos confiar que nuestro esquema de validación es suficientemente robusto para decirnos que el modelo va a generalizar como corresponde en Test-Time. Pero acá no ocurre.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/rul/resultados_pt2.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Los resultados que debieron haber obtenido muestran que el mejor puntaje de Validación se obtiene con Clipping de 150 pero no es el que generaliza mejor en Test. En test nuestro modelo actúa mejor con Clipping de 120. Lo que acaba de pasar es algo muy dificil de detectar (no sabría como hacerlo en tiempo real), nuestro modelo no está generalizando de manera apropiada. Y esto puede ser por varias razones:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Nuestro esquema de Validación no es confiable.&lt;/li&gt;
  &lt;li&gt;Tenemos algún error en nuestro código.&lt;/li&gt;
  &lt;li&gt;No estamos capturando apropiadamente el error.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;alert-box tip radius &quot;&gt;&lt;p&gt;Detectar este tipo de Problemas es quizás de las Skills más complicadas de desarrollar, y para los que dicen que la Modelación Competitiva (Kaggle principalmente) no sirve, déjenme decirles que esto es precisamente la skill principal a desarrollar en competencias. Poder descubrir a ciegas si el modelo está generalizando de manera apropiada o no.&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Me gustaría pensar que este problema se da por lo siguiente:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/rul/F_vs_t_1.png&quot; alt=&quot;&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Nuestro modelo tiene predicciones bajo cero para RUL reales muy pequeños. Lo cual no refleja la realidad. Debemos pensar que el objetivo final del modelo es poder predecir de manera anticipada que nuestro motor fallará. Por lo tanto, no nos interesan valores negativos diciéndonos que la falla ya ocurrió. Para corregir realizaremos un Post-Procesamiento. Es decir, evitaremos que nuestro modelo prediga RUL menores a uno, de esa manera cuando hayan predicciones con 1 indicará que el motor está pronto a fallar. Quiero pensar que esto solucionará nuestro problema 😕.&lt;/p&gt;

&lt;p&gt;Adicionalmente, intetaremos otro approach. Debido a la naturaleza temporal del problema generaremos variables que nos permitan modelar el problema en el tiempo. Para ello generaremos lags, variables con un desfase en el tiempo. Para ello trataremos de descubrir cuál es el mejor set de lags, dejando en este caso un RUL_CLIP fijo de 125.&lt;/p&gt;

&lt;p&gt;Vamos a implementar esos cambios.&lt;/p&gt;

&lt;h2 id=&quot;archivo-de-configuración-paramsyaml&quot;&gt;Archivo de Configuración params.yaml&lt;/h2&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;random_seed&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;42&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;train_name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;train_FD001.txt&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;test_name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;test_FD001.txt&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;rul_name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;RUL_FD001.txt&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;featurize&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;index_names&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;unit_nr&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;time_cycles&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;setting_names&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;setting_1&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;setting_2&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;setting_3&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;sensor_names&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;s_1&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_2&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_3&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_4&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_5&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_6&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_7&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_8&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_9&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_10&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_11&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_12&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_13&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;s_14&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_15&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_16&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_17&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_18&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_19&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_20&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_21&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;to_keep&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;s_2&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_3&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_4&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_6&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_7&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_8&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_9&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_11&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_12&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_13&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_14&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_15&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_17&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;s_20&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_21&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;lags&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;4&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;5&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;10&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;20&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;30&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;model_name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;model.joblib&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;n_split&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;5&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;rul_clip&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;125&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;pred_clip&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;standardize&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;En este nuevo archivo de configuración tenemos lo siguiente:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;En la etapa featurize mantenemos el parámetro &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;to_keep&lt;/code&gt;, que nos perrmitirá determinar con qué sensores queremos quedarnos.&lt;/li&gt;
  &lt;li&gt;Además agregamos los posibles lags que nos gustaría calcular. (La razón en utilizar - como separador es que cuando probamos listas como hiperparámetros DVC al sobreescribir el óptimo lo deja en ese formato).&lt;/li&gt;
  &lt;li&gt;En la etapa agregamos dos parámetros nuevos: &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;standardize&lt;/code&gt; que permitirá activar o no el StandardScaler, que es buena práctica para modelos lineales y que no veníamos realizando. Además fijamos el &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;rul_clip&lt;/code&gt; a 125 y el &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;pred_clip&lt;/code&gt; a 1.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;featurize&quot;&gt;Featurize&lt;/h2&gt;

&lt;p&gt;En esta etapa utilizaremos ahora la función &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;create_features()&lt;/code&gt; cambiará de la siguiente forma:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;create_features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df_train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df_test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    
    &lt;span class=&quot;n&quot;&gt;to_keep&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'to_keep'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;lag_features&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lag&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'lags'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]:&lt;/span&gt;
        
        &lt;span class=&quot;n&quot;&gt;cols&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;col&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'_lag_&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lag&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;col&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to_keep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;lag_features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;extend&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cols&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;df_train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cols&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df_train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;groupby&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'unit_nr'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_keep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shift&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;df_test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cols&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df_test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;groupby&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'unit_nr'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_keep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shift&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;n&quot;&gt;df_train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dropna&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inplace&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;df_test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dropna&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inplace&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;c1&quot;&gt;# selecting last instance to predict
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;df_test&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df_test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;groupby&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'unit_nr'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df_train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_keep&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lag_features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df_test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_keep&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lag_features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df_train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rul&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Esta función aceptará un set de train y test y creará los lags sólo para los sensores que vamos a dejar (los que entregan info de acuerdo a &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;to_keep&lt;/code&gt;). Luego debido a la naturaleza del lag, quedarán observaciones con nulos, los cual simplemente los eliminaremos. También eliminaremos etiquetas, por lo que devolveremos el Train set y el Test set con las nuevas variables y las etiquetas de entrenamiento que sobrevivan a la eliminación de nulos.&lt;/p&gt;

&lt;p&gt;La definición de features se ve mucho más sencilla ahora:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;df_train&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;add_rul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df_train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;train_features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test_features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train_labels&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;create_features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df_train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                                                &lt;span class=&quot;n&quot;&gt;df_test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                                                &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Notar que los set ingresados a &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;create_features()&lt;/code&gt; son el train luego de crear el RUL y el test sin agrupar.&lt;/p&gt;

&lt;h2 id=&quot;train&quot;&gt;Train&lt;/h2&gt;

&lt;p&gt;Cuando entrenamos nuestro modelo ahora tendremos los siguientes cambios:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'standardize'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Pipeline&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'scaler'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;StandardScaler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()),&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'model'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LinearRegression&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())])&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LinearRegression&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;#======================================================
# Validation Metrics
#======================================================
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;folds&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;KFold&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n_splits&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'n_split'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; 
                &lt;span class=&quot;n&quot;&gt;shuffle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                &lt;span class=&quot;n&quot;&gt;random_state&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RANDOM_SEED&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;mae&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zeros&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'n_split'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;rmse&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zeros&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'n_split'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;r2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zeros&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'n_split'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fold_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train_idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val_idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;folds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;X&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train_features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train_labels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Training Fold: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fold_&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;n&quot;&gt;X_train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;X_val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train_features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train_idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train_features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val_idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;y_train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y_val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train_labels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train_idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train_labels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val_idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    
    &lt;span class=&quot;c1&quot;&gt;# Training Clipping
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;X_train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y_train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;clip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;upper&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'rul_clip'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
    
    &lt;span class=&quot;c1&quot;&gt;# Adding Prediction Clipping (Numpy)
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;val_preds&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;predict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;X_val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;clip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;min&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'pred_clip'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;val_mae&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mean_absolute_error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y_val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val_preds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;val_rmse&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mean_squared_error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y_val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val_preds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;squared&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;val_r2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r2_score&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y_val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val_preds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;n&quot;&gt;mae&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fold_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val_mae&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;rmse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fold_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val_rmse&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;r2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fold_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val_r2&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Validation MAE for Fold &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fold_&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val_mae&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Validation RMSE for Fold &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fold_&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val_rmse&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Validation R2 for Fold &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fold_&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val_r2&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Agregaremos la opción de un Pipeline de Estandarización y además al momento de Predecir aplicaremos Clipping mínimo (para evitar los RUL negativos).&lt;/p&gt;

&lt;div class=&quot;alert-box info radius &quot;&gt;&lt;p&gt;El resultado de la predicción es un Numpy Array y el clipping en Numpy utiliza min, max en vez de lower, upper. Fue un dolor de cabeza inicialmente, porque no entendía por qué me arrojaba error.&lt;/p&gt;
&lt;/div&gt;

&lt;h2 id=&quot;evaluate&quot;&gt;Evaluate&lt;/h2&gt;

&lt;p&gt;En el caso de nuestro Evaluate, también debemos aplicar clipping.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;joblib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MODELS_PATH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'model.joblib'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Adding Prediction Clipping (Numpy)
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y_pred&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;predict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;X_test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;clip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;min&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'pred_clip'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;proceso-de-experimentación&quot;&gt;Proceso de Experimentación&lt;/h2&gt;

&lt;p&gt;DVC es sumamente inteligente, y podemos utilizarlo para hacer nuestra búsqueda de Hiperparámetros. DVC automáticamente detecta qué etapas se deben reejecutar y cuáles se pueden reutilizar dependiendo de nuestras dependencias definidas en &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;dvc.yaml&lt;/code&gt; (ejecutando &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;dvc_config.sh&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Para definir nuestra búsqueda de Hiperparámetros utilizarmos &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;exp_config.sh&lt;/code&gt; para probar con distintos lags.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;dvc exp run &lt;span class=&quot;nt&quot;&gt;-S&lt;/span&gt; featurize.lags&lt;span class=&quot;o&quot;&gt;=[&lt;/span&gt;1,2,3,4,5]
dvc exp run &lt;span class=&quot;nt&quot;&gt;-S&lt;/span&gt; featurize.lags&lt;span class=&quot;o&quot;&gt;=[&lt;/span&gt;1,2,3,4,5,6,7,8,9]
dvc exp run &lt;span class=&quot;nt&quot;&gt;-S&lt;/span&gt; featurize.lags&lt;span class=&quot;o&quot;&gt;=[&lt;/span&gt;1,2,3,4,5,10,20,30]
dvc exp run &lt;span class=&quot;nt&quot;&gt;-S&lt;/span&gt; featurize.lags&lt;span class=&quot;o&quot;&gt;=[&lt;/span&gt;1,2,3,4,5,10,20]
dvc exp run &lt;span class=&quot;nt&quot;&gt;-S&lt;/span&gt; featurize.lags&lt;span class=&quot;o&quot;&gt;=[&lt;/span&gt;1,3,6,9,12,15]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Estudiaremos el efecto de los distintos niveles de Lag:&lt;/p&gt;

&lt;center&gt;
&lt;a href=&quot;https://colab.research.google.com/github/datacubeR/cmapps/blob/time-series/LR_timeseries.ipynb&quot;&gt;&lt;img src=&quot;https://colab.research.google.com/assets/colab-badge.svg&quot; /&gt;&lt;/a&gt;
&lt;/center&gt;

&lt;div class=&quot;alert-box success radius &quot;&gt;&lt;p&gt;Ahora les toca poder ejecutar todo este proceso en Colab. ¿Mejoramos nuestros resultados? ¿Fue posible solucionar el problema de Generalización? ¿Y si quiero probar otro modelo? Cambia el tipo de Modelo a un Random Forest o a un XGBoost y cuéntame cómo te dan los resultados.&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Habiendo entendido esta parte la verdad es que podrías utilizar cualquier modelo de Machine Learning Shallow (los clásicos, RF, XGB, LGBM, Catboost, incluso un Multilayer Perceptron) y no habrían grandes cambios. Variables extras pueden ir en featurize y el resto del Pipeline sigue igual.&lt;/p&gt;

&lt;p&gt;Por eso es tan importante la parte de programación en Ciencia de Datos. Mucho del gran esfuerzo se hace al principio en el cual tenemos que dedicar mucho tiempo a un Pipeline robusto que nos permita experimentar de manera rápida y sencilla.&lt;/p&gt;

&lt;p&gt;Consejo/Opinión muy personal:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Utiliza Jupyter Notebooks cuanto quieras para explorar, visualizar, incluso cómo instrucciones de Reproducibilidad como estoy utilizandolo yo ahora.&lt;/li&gt;
  &lt;li&gt;Vamos de a poco dejando de usar los Jupyter Notebooks. Lamentablemente este tipo de estructura para el core del código te fuerza a hacer códigos eternos y poco modulares. Uno se olvida de utilizar abstreaer en Clases o Funciones y copia y pega a veces incluso ejecutando en órdenes diferentes.&lt;/li&gt;
  &lt;li&gt;Utiliza alguna herramienta de Automatización de Pipelines, yo uso DVC, pero está MAKE (que estoy empezando a revisar y posiblemente se vuelva un tutorial luego), Airflow (también viene luego), y un largo etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;¿Y habrá parte 4?&lt;/p&gt;

&lt;!-- 
Esta es la parte final del tutorial. Espero que hayan podido aprender con esto algunos de los inconvenientes del modelamiento.
Pueden ver que utilizando sólo una Regresión Lineal fue posible solucionar bastante bien nuestro problema. Obviamente esto puede extenderse a mucho más utilizando XGBoost, LightGBM o Catboost. --&gt;

&lt;p&gt;&lt;a href=&quot;/contact/&quot;&gt;&lt;strong&gt;Alfonso&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

</content>

			
				<category term="ml" />
			
			
				<category term="sklearn" />
			
				<category term="tutorial" />
			
				<category term="ML" />
			
				<category term="dl" />
			

			<published>2022-10-10T00:00:00+00:00</published>
		</entry>
	
		<entry>
			<id>http://datacuber.github.io/project-pt2/</id>
			<title>¿Hagamos un Proyecto desde cero? Parte 2</title>
			<link href="http://datacuber.github.io/project-pt2/" rel="alternate" type="text/html" title="¿Hagamos un Proyecto desde cero? Parte 2" />
			<updated>2022-09-05T00:00:00+00:00</updated>

			
			<summary></summary>
			<content type="html" xml:base="http://datacuber.github.io/project-pt2/">&lt;p&gt;&lt;img src=&quot;/images/rul/rul.png&quot; alt=&quot;picture of me&quot; class=&quot;left show-for-large-up hide-for-print&quot; width=&quot;250&quot; /&gt;
&lt;img src=&quot;/images/rul/rul.png&quot; alt=&quot;picture of me&quot; class=&quot;center hide-for-large-up&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;

&lt;p&gt;En este artículo estaremos continuando el proyecto que comenzamos la semana pasada. Si es que te perdiste el inicio del proyecto puedes revisar la primera parte &lt;!--more--&gt; &lt;a href=&quot;/project-pt1/&quot;&gt;acá&lt;/a&gt;. La idea es que este proyecto sea interactivo y puedas ir siguiendo las distintas etapas, pero por sobre todo reproduciendo el código y analizándolo.&lt;/p&gt;

&lt;p&gt;Si seguiste la parte uno sabrás que implementamos un modelo baseline muy sencillo. Si entrenaste el modelo y visto sus resultados notarás que el modelo que hicimos no anda muy bien, y sería bueno probar nuevas estrategias para mejorar su performance. Mucho del trabajo duro de programación ya lo hicimos en la parte 1 por lo que ahora nos enfocaremos en las mejoras.&lt;/p&gt;

&lt;p&gt;De acuerdo a nuestro Análisis Exploratorio vimos que existen sensores que no están aportando información. Por lo tanto, una primera cosa a probar sería eliminar de nuestras features aquellos sensores que no aportan información. Por otro lado, debido a que estamos utilizando una regresión lineal, podríamos crear interaciones entre variables para ver qué tal le va.&lt;/p&gt;

&lt;p&gt;Finalmente si analizamos nuestro True vs Fitted Curve de la parte pasada podemos ver lo siguiente:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/rul/F_vs_t_1.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;A partir de esto podemos concluimos lo siguiente:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Parece ser que a medida que el RUL aumenta nuestros errores se hacen más grandes. Eso normalmente es esperable ya que que no hay evidencia para decir que el motor fallará cuando falta demasiado tiempo para su falla. Debido a la naturaleza del problema a nosotros nos interesa entender cuando queda poco tiempo para la falla y enfocarnos ahí. Una técnica utilizada para resolver este problea es usar un clipping. Es decir, yo permito un RUL máximo, todo lo que supere ese RUL máximo lo acoto a dicho nivel.
&lt;!-- * Pero otra cosa que se puede ver es que el modelo genera predicciones negativas. Lo cual no está bien. El modelo debería siempre ser capaz de predecir un número positivo. Y es más, nunca debería decirme que hoy falló. De ser ese el caso, no me permite tomar medidas para prevenirlo. Por eso aplicaremos un clipping inferior para evitar dicho comportamiento. El primer paso es un preprocesamiento, antes de entrenar. El segundo paso es un postprocesamiento, después de predecir. --&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Implementemos esos cambios y tratemos de buscar el valor de RUL más apropiado.&lt;/p&gt;

&lt;h2 id=&quot;archivo-de-configuración-paramsyaml&quot;&gt;Archivo de Configuración params.yaml&lt;/h2&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;random_seed&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;42&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;train_name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;train_FD001.txt&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;test_name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;test_FD001.txt&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;rul_name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;RUL_FD001.txt&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;featurize&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;index_names&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;unit_nr&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;time_cycles&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;setting_names&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;setting_1&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;setting_2&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;setting_3&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;sensor_names&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;s_1&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_2&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_3&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_4&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_5&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_6&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_7&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_8&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_9&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_10&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_11&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_12&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_13&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;s_14&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_15&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_16&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_17&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_18&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_19&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_20&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_21&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;to_keep&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;s_2&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_3&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_4&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_6&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_7&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_8&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_9&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_11&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_12&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_13&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_14&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_15&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_17&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;s_20&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;s_21&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;train&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;model_name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;model.joblib&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;n_split&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;5&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;rul_clip&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;50&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;En este nuevo archivo de configuración tenemos lo siguiente:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;En la etapa featurize agregamos el parámetro &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;to_keep&lt;/code&gt;, que nos perrmitirá determinar con qué sensores queremos quedarnos. Es decir, no consideramos los que no aportan información. La razón por la que hacemos eso es porque &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;sensor_names&lt;/code&gt; tiene otra función que es darle el nombre a las variables a importar.&lt;/li&gt;
  &lt;li&gt;En la etapa train usaremos un clip de 50 inicialmente. Pero la idea es que implementemos una búsqueda de algún valor más óptimo.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;featurize&quot;&gt;Featurize&lt;/h2&gt;

&lt;p&gt;En esta etapa utilizaremos ahora la función &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;create_features()&lt;/code&gt; que nos permitirá crear las interacciones con Scikit-Learn.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;create_features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df_train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df_test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;pf&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PolynomialFeatures&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;interaction_only&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;n&quot;&gt;df_train&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DataFrame&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fit_transform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df_train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;columns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_feature_names_out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;df_test&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DataFrame&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fit_transform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df_test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;columns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_feature_names_out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df_train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df_test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Esta función aceptará un set de train y test y creará las interacciones correspondientes entre ellas.&lt;/p&gt;

&lt;div class=&quot;alert-box info radius &quot;&gt;&lt;p&gt;Normalmente suelo usar la librería &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Feature Engine&lt;/code&gt; para hacer las transformaciones. Resulta que &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Feature Engine&lt;/code&gt; tenía un bug con el uso de &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;PolynomialFeatures&lt;/code&gt;. Gracias a Soledad Galli (autora de &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Feature Engine&lt;/code&gt;) que me animó a solucionar el bug que reporté. Mi Pull Request ya es parte de la rama main de la librería y en el próximo release habrá código contribuido por mí, lo que me pone muy contento.&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;/images/rul/PR.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Finalmente en la etapa de definición de features se verá así:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;to_keep&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'to_keep'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;df_train&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;add_rul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df_train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;train_features&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df_train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_keep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;test_features&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df_test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;groupby&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'unit_nr'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_keep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;train_features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test_features&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;create_features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train_features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test_features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Notar que los set ingresados a &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;create_features()&lt;/code&gt; son el train luego de crear el RUL y el test, luego de ser agrupado para obtener el último ciclo. La razón de esto se explicó en la &lt;a href=&quot;/project-pt1/&quot;&gt;la parte 1&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;train&quot;&gt;Train&lt;/h2&gt;

&lt;p&gt;Cuando entrenamos nuestro modelo ahora lo haremos con el RUL clippeado. Por lo tanto, el KFold CV cambia de la siguiente forma:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fold_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train_idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val_idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;folds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;X&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train_features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train_labels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Training Fold: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fold_&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;n&quot;&gt;X_train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;X_val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train_features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train_idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train_features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val_idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;y_train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y_val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train_labels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train_idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train_labels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val_idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    
    &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;X_train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y_train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;clip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;upper&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'rul_clip'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;val_preds&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;predict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;X_val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;val_mae&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mean_absolute_error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y_val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val_preds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;val_rmse&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mean_squared_error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y_val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val_preds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;squared&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;val_r2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r2_score&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y_val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val_preds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;n&quot;&gt;mae&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fold_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val_mae&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;rmse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fold_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val_rmse&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;r2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fold_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val_r2&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Validation MAE for Fold &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fold_&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val_mae&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Validation RMSE for Fold &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fold_&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val_rmse&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Validation R2 for Fold &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fold_&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val_r2&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Notar que al momento del fit, ahora &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;y_train&lt;/code&gt; irá con el clip indicado en mis parámetros.&lt;/p&gt;

&lt;h2 id=&quot;evaluate&quot;&gt;Evaluate&lt;/h2&gt;

&lt;p&gt;En el caso de nuestro Evaluate, no tendremos ningún cambio, ya que realizaremos el mismo proceso.&lt;/p&gt;

&lt;h2 id=&quot;proceso-de-experimentación&quot;&gt;Proceso de Experimentación&lt;/h2&gt;

&lt;p&gt;DVC es sumamente inteligente, y podemos utilizarlo para hacer nuestra búsqueda de Hiperparámetros. DVC automáticamente detecta qué etapas se deben reejecutar y cuáles se pueden reutilizar dependiendo de nuestras dependencias definidas en &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;dvc.yaml&lt;/code&gt; (ejecutando &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;dvc_config.sh&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Para definir nuestra búsqueda de Hiperparámetros utilizarmos &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;exp_config.sh&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;dvc exp run &lt;span class=&quot;nt&quot;&gt;-S&lt;/span&gt; train.rul_clip&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;150
dvc exp run &lt;span class=&quot;nt&quot;&gt;-S&lt;/span&gt; train.rul_clip&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;130
dvc exp run &lt;span class=&quot;nt&quot;&gt;-S&lt;/span&gt; train.rul_clip&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;125
dvc exp run &lt;span class=&quot;nt&quot;&gt;-S&lt;/span&gt; train.rul_clip&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;120
dvc exp run &lt;span class=&quot;nt&quot;&gt;-S&lt;/span&gt; train.rul_clip&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;90
dvc exp run &lt;span class=&quot;nt&quot;&gt;-S&lt;/span&gt; train.rul_clip&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;70
dvc exp run &lt;span class=&quot;nt&quot;&gt;-S&lt;/span&gt; train.rul_clip&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;50
dvc exp run &lt;span class=&quot;nt&quot;&gt;-S&lt;/span&gt; train.rul_clip&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;30
dvc exp run &lt;span class=&quot;nt&quot;&gt;-S&lt;/span&gt; train.rul_clip&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;10
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Si quieres entender el efecto de probar distintos valores de clipping te invito a seguir el experimento en el siguiente Colab:&lt;/p&gt;

&lt;center&gt;
&lt;a href=&quot;https://colab.research.google.com/github/datacubeR/cmapps/blob/LR-v2/LR_v2.ipynb&quot;&gt;&lt;img src=&quot;https://colab.research.google.com/assets/colab-badge.svg&quot; /&gt;&lt;/a&gt;
&lt;/center&gt;

&lt;div class=&quot;alert-box success radius &quot;&gt;&lt;p&gt;Ahora les toca poder ejecutar todo este proceso en Colab. ¿Con cuántas features se entrenó el modelo?¿Sirvió de algo lo que implementamos? ¿Cuál es el mejor valor de Clipping? ¿Ves algún problema con las predicciones?&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Esto fue todo por esta semana, espero que vayan siguiendo y los espero para revisar los resultados en la parte 3.&lt;/p&gt;

&lt;p&gt;Nos vemos,&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/contact/&quot;&gt;&lt;strong&gt;Alfonso&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

</content>

			
				<category term="ml" />
			
			
				<category term="sklearn" />
			
				<category term="tutorial" />
			
				<category term="ML" />
			
				<category term="dl" />
			

			<published>2022-09-05T00:00:00+00:00</published>
		</entry>
	
		<entry>
			<id>http://datacuber.github.io/project-pt1/</id>
			<title>¿Hagamos un Proyecto desde cero? Parte 1</title>
			<link href="http://datacuber.github.io/project-pt1/" rel="alternate" type="text/html" title="¿Hagamos un Proyecto desde cero? Parte 1" />
			<updated>2022-08-30T00:00:00+00:00</updated>

			
			<summary></summary>
			<content type="html" xml:base="http://datacuber.github.io/project-pt1/">&lt;p&gt;&lt;img src=&quot;/images/rul/front.jpg&quot; alt=&quot;picture of me&quot; class=&quot;left show-for-large-up hide-for-print&quot; width=&quot;250&quot; /&gt;
&lt;img src=&quot;/images/rul/front.jpg&quot; alt=&quot;picture of me&quot; class=&quot;center hide-for-large-up&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Hace tiempo que me interesaba poder mostrar cómo realizar un proyecto desde cero (Al menos simular cómo hacerlo). Para ello me gustaría mostrar alguna de los problemas que me ha tocado resolver. Hoy día vamos a tratar de predecir el RUL. &lt;!--more--&gt; El &lt;mark&gt;RUL&lt;/mark&gt; o &lt;em&gt;Remaining Useful Life&lt;/em&gt; es un problema típico en Mecánica en el que se quiere al menos intentar predecir cuánto falta para que una maquinaria falle. Este es un problema sumamente difícil, porque para poder construir el modelo necesitamos construir data, y necesitamos hacer que maquinas fallen lo cual es caro. Si no tenemos maquinas que fallan, este modelo no funciona, porque necesitamos entender qué pasa justo el tiempo antes que la maquina falle. Lamentablemente, empresas hoy en día quieren que se haga magia adivinando cuando sus maquinas fallan, y peor aún, existen consultoras que prometen resolver este problema sin siquiera tener datos al respecto. Esto porque nadie está dispuesto a que sus maquinas fallen en favor de la ciencia.&lt;/p&gt;

&lt;p&gt;Hoy día vamos a ver varios métodos tratando de ver cómo resolver este problema y por qué funciona. Para ello utilizaremos el dataset benchmark stándard que se utiliza para probar metodologías: El NASA CMAPPS. Este dataset contiene funcionamiento simulado de motores de aviones, que representan la realidad bastante bien.&lt;/p&gt;

&lt;p&gt;Intetaremos por nuestra parte tratar de simular cómo se resuelve un proyecto de Data Science en la realidad, sólo que un poco más acotado.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;No quiero que se aburran con tanto código.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;análisis-exploratorio-eda&quot;&gt;Análisis Exploratorio (EDA)&lt;/h2&gt;

&lt;p&gt;Normalmente para realizar el análisis exploratorio utilizo un Notebook para poder ir mirando mis datos y dejar comentarios en el mismo lugar. El código completo del EDA está en el siguiente Colab.&lt;/p&gt;

&lt;center&gt;
&lt;a href=&quot;https://colab.research.google.com/github/datacubeR/cmapps/blob/master/EDA.ipynb&quot;&gt;&lt;img src=&quot;https://colab.research.google.com/assets/colab-badge.svg&quot; /&gt;&lt;/a&gt;
&lt;/center&gt;

&lt;h3 id=&quot;datos-de-entrenamiento&quot;&gt;Datos de Entrenamiento&lt;/h3&gt;

&lt;p&gt;En este caso particular, la data se encuentra en formato txt separado por espacios, y no tiene bien definidos los nombres. Por lo que se ingresarán todos de la siguiente forma:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;index_names&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'unit_nr'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'time_cycles'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;setting_names&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'setting_1'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'setting_2'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'setting_3'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sensor_names&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'s_{}'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;22&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt; 
&lt;span class=&quot;n&quot;&gt;col_names&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index_names&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setting_names&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sensor_names&lt;/span&gt;


&lt;span class=&quot;n&quot;&gt;df_train&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_csv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'../assets/CMAPSSData/train_FD001.txt'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sep&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'\s+'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;header&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;names&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;col_names&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;df_train&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;table-overflow&quot;&gt;
&lt;style scoped=&quot;&quot;&gt;
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
&lt;/style&gt;
&lt;table border=&quot;1&quot; class=&quot;dataframe&quot;&gt;
  &lt;thead&gt;
    &lt;tr style=&quot;text-align: right;&quot;&gt;
      &lt;th&gt;&lt;/th&gt;
      &lt;th&gt;unit_nr&lt;/th&gt;
      &lt;th&gt;time_cycles&lt;/th&gt;
      &lt;th&gt;setting_1&lt;/th&gt;
      &lt;th&gt;setting_2&lt;/th&gt;
      &lt;th&gt;setting_3&lt;/th&gt;
      &lt;th&gt;s_1&lt;/th&gt;
      &lt;th&gt;s_2&lt;/th&gt;
      &lt;th&gt;s_3&lt;/th&gt;
      &lt;th&gt;s_4&lt;/th&gt;
      &lt;th&gt;s_5&lt;/th&gt;
      &lt;th&gt;...&lt;/th&gt;
      &lt;th&gt;s_12&lt;/th&gt;
      &lt;th&gt;s_13&lt;/th&gt;
      &lt;th&gt;s_14&lt;/th&gt;
      &lt;th&gt;s_15&lt;/th&gt;
      &lt;th&gt;s_16&lt;/th&gt;
      &lt;th&gt;s_17&lt;/th&gt;
      &lt;th&gt;s_18&lt;/th&gt;
      &lt;th&gt;s_19&lt;/th&gt;
      &lt;th&gt;s_20&lt;/th&gt;
      &lt;th&gt;s_21&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;th&gt;0&lt;/th&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;-0.0007&lt;/td&gt;
      &lt;td&gt;-0.0004&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;518.67&lt;/td&gt;
      &lt;td&gt;641.82&lt;/td&gt;
      &lt;td&gt;1589.70&lt;/td&gt;
      &lt;td&gt;1400.60&lt;/td&gt;
      &lt;td&gt;14.62&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;521.66&lt;/td&gt;
      &lt;td&gt;2388.02&lt;/td&gt;
      &lt;td&gt;8138.62&lt;/td&gt;
      &lt;td&gt;8.4195&lt;/td&gt;
      &lt;td&gt;0.03&lt;/td&gt;
      &lt;td&gt;392&lt;/td&gt;
      &lt;td&gt;2388&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;39.06&lt;/td&gt;
      &lt;td&gt;23.4190&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;1&lt;/th&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;2&lt;/td&gt;
      &lt;td&gt;0.0019&lt;/td&gt;
      &lt;td&gt;-0.0003&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;518.67&lt;/td&gt;
      &lt;td&gt;642.15&lt;/td&gt;
      &lt;td&gt;1591.82&lt;/td&gt;
      &lt;td&gt;1403.14&lt;/td&gt;
      &lt;td&gt;14.62&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;522.28&lt;/td&gt;
      &lt;td&gt;2388.07&lt;/td&gt;
      &lt;td&gt;8131.49&lt;/td&gt;
      &lt;td&gt;8.4318&lt;/td&gt;
      &lt;td&gt;0.03&lt;/td&gt;
      &lt;td&gt;392&lt;/td&gt;
      &lt;td&gt;2388&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;39.00&lt;/td&gt;
      &lt;td&gt;23.4236&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;2&lt;/th&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;3&lt;/td&gt;
      &lt;td&gt;-0.0043&lt;/td&gt;
      &lt;td&gt;0.0003&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;518.67&lt;/td&gt;
      &lt;td&gt;642.35&lt;/td&gt;
      &lt;td&gt;1587.99&lt;/td&gt;
      &lt;td&gt;1404.20&lt;/td&gt;
      &lt;td&gt;14.62&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;522.42&lt;/td&gt;
      &lt;td&gt;2388.03&lt;/td&gt;
      &lt;td&gt;8133.23&lt;/td&gt;
      &lt;td&gt;8.4178&lt;/td&gt;
      &lt;td&gt;0.03&lt;/td&gt;
      &lt;td&gt;390&lt;/td&gt;
      &lt;td&gt;2388&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;38.95&lt;/td&gt;
      &lt;td&gt;23.3442&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;3&lt;/th&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;4&lt;/td&gt;
      &lt;td&gt;0.0007&lt;/td&gt;
      &lt;td&gt;0.0000&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;518.67&lt;/td&gt;
      &lt;td&gt;642.35&lt;/td&gt;
      &lt;td&gt;1582.79&lt;/td&gt;
      &lt;td&gt;1401.87&lt;/td&gt;
      &lt;td&gt;14.62&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;522.86&lt;/td&gt;
      &lt;td&gt;2388.08&lt;/td&gt;
      &lt;td&gt;8133.83&lt;/td&gt;
      &lt;td&gt;8.3682&lt;/td&gt;
      &lt;td&gt;0.03&lt;/td&gt;
      &lt;td&gt;392&lt;/td&gt;
      &lt;td&gt;2388&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;38.88&lt;/td&gt;
      &lt;td&gt;23.3739&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;4&lt;/th&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;5&lt;/td&gt;
      &lt;td&gt;-0.0019&lt;/td&gt;
      &lt;td&gt;-0.0002&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;518.67&lt;/td&gt;
      &lt;td&gt;642.37&lt;/td&gt;
      &lt;td&gt;1582.85&lt;/td&gt;
      &lt;td&gt;1406.22&lt;/td&gt;
      &lt;td&gt;14.62&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;522.19&lt;/td&gt;
      &lt;td&gt;2388.04&lt;/td&gt;
      &lt;td&gt;8133.80&lt;/td&gt;
      &lt;td&gt;8.4294&lt;/td&gt;
      &lt;td&gt;0.03&lt;/td&gt;
      &lt;td&gt;393&lt;/td&gt;
      &lt;td&gt;2388&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;38.90&lt;/td&gt;
      &lt;td&gt;23.4044&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;...&lt;/th&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;   
      &lt;td&gt;...&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;20626&lt;/th&gt;
      &lt;td&gt;100&lt;/td&gt;
      &lt;td&gt;196&lt;/td&gt;
      &lt;td&gt;-0.0004&lt;/td&gt;
      &lt;td&gt;-0.0003&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;518.67&lt;/td&gt;
      &lt;td&gt;643.49&lt;/td&gt;
      &lt;td&gt;1597.98&lt;/td&gt;
      &lt;td&gt;1428.63&lt;/td&gt;
      &lt;td&gt;14.62&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;519.49&lt;/td&gt;
      &lt;td&gt;2388.26&lt;/td&gt;
      &lt;td&gt;8137.60&lt;/td&gt;
      &lt;td&gt;8.4956&lt;/td&gt;
      &lt;td&gt;0.03&lt;/td&gt;
      &lt;td&gt;397&lt;/td&gt;
      &lt;td&gt;2388&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;38.49&lt;/td&gt;
      &lt;td&gt;22.9735&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;20627&lt;/th&gt;
      &lt;td&gt;100&lt;/td&gt;
      &lt;td&gt;197&lt;/td&gt;
      &lt;td&gt;-0.0016&lt;/td&gt;
      &lt;td&gt;-0.0005&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;518.67&lt;/td&gt;
      &lt;td&gt;643.54&lt;/td&gt;
      &lt;td&gt;1604.50&lt;/td&gt;
      &lt;td&gt;1433.58&lt;/td&gt;
      &lt;td&gt;14.62&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;519.68&lt;/td&gt;
      &lt;td&gt;2388.22&lt;/td&gt;
      &lt;td&gt;8136.50&lt;/td&gt;
      &lt;td&gt;8.5139&lt;/td&gt;
      &lt;td&gt;0.03&lt;/td&gt;
      &lt;td&gt;395&lt;/td&gt;
      &lt;td&gt;2388&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;38.30&lt;/td&gt;
      &lt;td&gt;23.1594&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;20628&lt;/th&gt;
      &lt;td&gt;100&lt;/td&gt;
      &lt;td&gt;198&lt;/td&gt;
      &lt;td&gt;0.0004&lt;/td&gt;
      &lt;td&gt;0.0000&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;518.67&lt;/td&gt;
      &lt;td&gt;643.42&lt;/td&gt;
      &lt;td&gt;1602.46&lt;/td&gt;
      &lt;td&gt;1428.18&lt;/td&gt;
      &lt;td&gt;14.62&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;520.01&lt;/td&gt;
      &lt;td&gt;2388.24&lt;/td&gt;
      &lt;td&gt;8141.05&lt;/td&gt;
      &lt;td&gt;8.5646&lt;/td&gt;
      &lt;td&gt;0.03&lt;/td&gt;
      &lt;td&gt;398&lt;/td&gt;
      &lt;td&gt;2388&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;38.44&lt;/td&gt;
      &lt;td&gt;22.9333&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;20629&lt;/th&gt;
      &lt;td&gt;100&lt;/td&gt;
      &lt;td&gt;199&lt;/td&gt;
      &lt;td&gt;-0.0011&lt;/td&gt;
      &lt;td&gt;0.0003&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;518.67&lt;/td&gt;
      &lt;td&gt;643.23&lt;/td&gt;
      &lt;td&gt;1605.26&lt;/td&gt;
      &lt;td&gt;1426.53&lt;/td&gt;
      &lt;td&gt;14.62&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;519.67&lt;/td&gt;
      &lt;td&gt;2388.23&lt;/td&gt;
      &lt;td&gt;8139.29&lt;/td&gt;
      &lt;td&gt;8.5389&lt;/td&gt;
      &lt;td&gt;0.03&lt;/td&gt;
      &lt;td&gt;395&lt;/td&gt;
      &lt;td&gt;2388&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;38.29&lt;/td&gt;
      &lt;td&gt;23.0640&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;20630&lt;/th&gt;
      &lt;td&gt;100&lt;/td&gt;
      &lt;td&gt;200&lt;/td&gt;
      &lt;td&gt;-0.0032&lt;/td&gt;
      &lt;td&gt;-0.0005&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;518.67&lt;/td&gt;
      &lt;td&gt;643.85&lt;/td&gt;
      &lt;td&gt;1600.38&lt;/td&gt;
      &lt;td&gt;1432.14&lt;/td&gt;
      &lt;td&gt;14.62&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;519.30&lt;/td&gt;
      &lt;td&gt;2388.26&lt;/td&gt;    
      &lt;td&gt;8137.33&lt;/td&gt;
      &lt;td&gt;8.5036&lt;/td&gt;
      &lt;td&gt;0.03&lt;/td&gt;
      &lt;td&gt;396&lt;/td&gt;
      &lt;td&gt;2388&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;38.37&lt;/td&gt;
      &lt;td&gt;23.0522&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;20631 rows × 26 columns&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Como se puede ver el dataset tiene 26 columnas, las cuales corresponden a lo siguiente:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;unit_nr: Es el identificador del Motor. Hay 100 motores diferentes, desde su instalación hasta su falla.&lt;/li&gt;
  &lt;li&gt;time_cycles: Es la unidad de tiempo. Cada Cycle es una medición hasta que muere en el último time_cycle.&lt;/li&gt;
  &lt;li&gt;setting_1 y setting_2 corresponden a mediciones que fijan configuración del motor.&lt;/li&gt;
  &lt;li&gt;s_1 a s_21 son mediciones hechas a distintos sensores del motor para detectar la posible falla.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Acá se pueden ver algunos de los elementos que son medidos en el motor (Pero para mí es chino).
&lt;img src=&quot;/images/rul/diagram.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Este dataset no contiene un vector objetivo (algo que ocurre la mayor cantidad del tiempo en la realidad). Por lo tanto vamos a contar la cantidad de ciclos que quedan hasta la falla (RUL). Sabiendo que el último ciclo de cada motor tiene un RUL cero. Creamos el RUL con la siguiente función.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;add_rul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;max_cycles&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;groupby&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'unit_nr'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;as_index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time_cycles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;columns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'time_cycles'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'max_cycles'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;merge&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max_cycles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;on&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'unit_nr'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;how&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'left'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;assign&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rul&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max_cycles&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time_cycles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;drop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;columns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'max_cycles'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Al chequear la distribución del Máximo RUL por motor se tiene lo siguiente:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/rul/output_7_1.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;Número de Ciclos de Vida Promedio 205.31
STD Ciclos de Vida 46.34
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Luego una buena idea es chequear si los sensores utilizados en el proceso son capaces de detectar algo cuando efectivamente el motor va a fallar. Acá algunos ejemplos:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/rul/output_9_1.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; /&gt;
&lt;img src=&quot;/images/rul/output_9_5.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; /&gt;
&lt;img src=&quot;/images/rul/output_9_13.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; /&gt;
&lt;img src=&quot;/images/rul/output_9_19.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Podemos ver que el sensor 2 tiene un aumento de su valor cuando un motor se acerca al fin de la vida útil.&lt;/li&gt;
  &lt;li&gt;El sensor 6 por otro lado es dificil de interpretar pero pareciera tener un fuerte peak antes de morir.&lt;/li&gt;
  &lt;li&gt;El sensor 14 tiene un comportamiento más disperso, algunos motores decrecen mientras que otros se incrementan, incluso algunos se mantienen.&lt;/li&gt;
  &lt;li&gt;El sensor 19 tiene una fuerte baja en el último cuarto de su vida útil.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Si chequean el notebook verán que algunos sensores como el 1, 5, 10, 16, 18 y 19 no aportan información.&lt;/p&gt;

&lt;h2 id=&quot;datos-de-validación&quot;&gt;Datos de Validación&lt;/h2&gt;

&lt;p&gt;En este caso, la data de validación viene en dos archivos: El primero, un Test set muy similar al de entrenamiento con 100 motores y sus variables predictoras. Y un segundo archivo el cual contiene el valor real del RUL para el último ciclo de vida en el Test set. Cabe destacar que ha diferencia del train set, el test set contiene un número de ciclos que no necesariamente representa la vida completa del motor. Y ahí radica la tarea, generar una buena estimación del RUL para la última medición a los sensores. El formato de estos datos es similar al de entrenamiento y se puede importar así:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;df_test&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_csv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'../assets/CMAPSSData/test_FD001.txt'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sep&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'\s+'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;header&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;names&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;col_names&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;rul&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_csv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'../assets/CMAPSSData/RUL_FD001.txt'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sep&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'\s+'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;header&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;names&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'RUL'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Por lo tanto, en el caso que queramos predecir utilizando el test set en modelos Shallow de Machine Learning (no Deep Learning) predeciremos en este set:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;df_test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;groupby&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'unit_nr'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;as_index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;table-overflow&quot;&gt;
&lt;style scoped=&quot;&quot;&gt;
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
&lt;/style&gt;
&lt;table border=&quot;1&quot; class=&quot;dataframe&quot;&gt;
  &lt;thead&gt;
    &lt;tr style=&quot;text-align: right;&quot;&gt;
      &lt;th&gt;&lt;/th&gt;
      &lt;th&gt;unit_nr&lt;/th&gt;
      &lt;th&gt;time_cycles&lt;/th&gt;
      &lt;th&gt;setting_1&lt;/th&gt;
      &lt;th&gt;setting_2&lt;/th&gt;
      &lt;th&gt;setting_3&lt;/th&gt;
      &lt;th&gt;s_1&lt;/th&gt;
      &lt;th&gt;s_2&lt;/th&gt;
      &lt;th&gt;s_3&lt;/th&gt;
      &lt;th&gt;s_4&lt;/th&gt;
      &lt;th&gt;s_5&lt;/th&gt;
      &lt;th&gt;...&lt;/th&gt;
      &lt;th&gt;s_12&lt;/th&gt;
      &lt;th&gt;s_13&lt;/th&gt;
      &lt;th&gt;s_14&lt;/th&gt;
      &lt;th&gt;s_15&lt;/th&gt;
      &lt;th&gt;s_16&lt;/th&gt;
      &lt;th&gt;s_17&lt;/th&gt;
      &lt;th&gt;s_18&lt;/th&gt;
      &lt;th&gt;s_19&lt;/th&gt;
      &lt;th&gt;s_20&lt;/th&gt;
      &lt;th&gt;s_21&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;th&gt;0&lt;/th&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;31&lt;/td&gt;
      &lt;td&gt;-0.0006&lt;/td&gt;
      &lt;td&gt;0.0004&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;518.67&lt;/td&gt;
      &lt;td&gt;642.58&lt;/td&gt;
      &lt;td&gt;1581.22&lt;/td&gt;
      &lt;td&gt;1398.91&lt;/td&gt;
      &lt;td&gt;14.62&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;521.79&lt;/td&gt;
      &lt;td&gt;2388.06&lt;/td&gt;
      &lt;td&gt;8130.11&lt;/td&gt;
      &lt;td&gt;8.4024&lt;/td&gt;
      &lt;td&gt;0.03&lt;/td&gt;
      &lt;td&gt;393&lt;/td&gt;
      &lt;td&gt;2388&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;38.81&lt;/td&gt;
      &lt;td&gt;23.3552&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;1&lt;/th&gt;
      &lt;td&gt;2&lt;/td&gt;
      &lt;td&gt;49&lt;/td&gt;
      &lt;td&gt;0.0018&lt;/td&gt;
      &lt;td&gt;-0.0001&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;518.67&lt;/td&gt;
      &lt;td&gt;642.55&lt;/td&gt;
      &lt;td&gt;1586.59&lt;/td&gt;
      &lt;td&gt;1410.83&lt;/td&gt;
      &lt;td&gt;14.62&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;521.74&lt;/td&gt;
      &lt;td&gt;2388.09&lt;/td&gt;
      &lt;td&gt;8126.90&lt;/td&gt;
      &lt;td&gt;8.4505&lt;/td&gt;
      &lt;td&gt;0.03&lt;/td&gt;
      &lt;td&gt;391&lt;/td&gt;
      &lt;td&gt;2388&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;38.81&lt;/td&gt;
      &lt;td&gt;23.2618&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;2&lt;/th&gt;
      &lt;td&gt;3&lt;/td&gt;
      &lt;td&gt;126&lt;/td&gt;
      &lt;td&gt;-0.0016&lt;/td&gt;
      &lt;td&gt;0.0004&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;518.67&lt;/td&gt;
      &lt;td&gt;642.88&lt;/td&gt;
      &lt;td&gt;1589.75&lt;/td&gt;
      &lt;td&gt;1418.89&lt;/td&gt;
      &lt;td&gt;14.62&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;520.83&lt;/td&gt;
      &lt;td&gt;2388.14&lt;/td&gt;
      &lt;td&gt;8131.46&lt;/td&gt;
      &lt;td&gt;8.4119&lt;/td&gt;
      &lt;td&gt;0.03&lt;/td&gt;
      &lt;td&gt;395&lt;/td&gt;
      &lt;td&gt;2388&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;38.93&lt;/td&gt;
      &lt;td&gt;23.2740&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;3&lt;/th&gt;
      &lt;td&gt;4&lt;/td&gt;
      &lt;td&gt;106&lt;/td&gt;
      &lt;td&gt;0.0012&lt;/td&gt;
      &lt;td&gt;0.0004&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;518.67&lt;/td&gt;
      &lt;td&gt;642.78&lt;/td&gt;
      &lt;td&gt;1594.53&lt;/td&gt;
      &lt;td&gt;1406.88&lt;/td&gt;
      &lt;td&gt;14.62&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;521.88&lt;/td&gt;
      &lt;td&gt;2388.11&lt;/td&gt;
      &lt;td&gt;8133.64&lt;/td&gt;
      &lt;td&gt;8.4634&lt;/td&gt;
      &lt;td&gt;0.03&lt;/td&gt;
      &lt;td&gt;395&lt;/td&gt;
      &lt;td&gt;2388&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;38.58&lt;/td&gt;
      &lt;td&gt;23.2581&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;4&lt;/th&gt;
      &lt;td&gt;5&lt;/td&gt;
      &lt;td&gt;98&lt;/td&gt;
      &lt;td&gt;-0.0013&lt;/td&gt;
      &lt;td&gt;-0.0004&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;518.67&lt;/td&gt;
      &lt;td&gt;642.27&lt;/td&gt;
      &lt;td&gt;1589.94&lt;/td&gt;
      &lt;td&gt;1419.36&lt;/td&gt;
      &lt;td&gt;14.62&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;521.00&lt;/td&gt;
      &lt;td&gt;2388.15&lt;/td&gt;
      &lt;td&gt;8125.74&lt;/td&gt;
      &lt;td&gt;8.4362&lt;/td&gt;
      &lt;td&gt;0.03&lt;/td&gt;
      &lt;td&gt;394&lt;/td&gt;
      &lt;td&gt;2388&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;38.75&lt;/td&gt;
      &lt;td&gt;23.4117&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;...&lt;/th&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;95&lt;/th&gt;
      &lt;td&gt;96&lt;/td&gt;
      &lt;td&gt;97&lt;/td&gt;
      &lt;td&gt;-0.0006&lt;/td&gt;
      &lt;td&gt;0.0003&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;518.67&lt;/td&gt;
      &lt;td&gt;642.30&lt;/td&gt;
      &lt;td&gt;1590.88&lt;/td&gt;
      &lt;td&gt;1397.94&lt;/td&gt;
      &lt;td&gt;14.62&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;522.30&lt;/td&gt;
      &lt;td&gt;2388.01&lt;/td&gt;
      &lt;td&gt;8148.24&lt;/td&gt;
      &lt;td&gt;8.4110&lt;/td&gt;
      &lt;td&gt;0.03&lt;/td&gt;
      &lt;td&gt;391&lt;/td&gt;
      &lt;td&gt;2388&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;38.96&lt;/td&gt;
      &lt;td&gt;23.4606&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;96&lt;/th&gt;
      &lt;td&gt;97&lt;/td&gt;
      &lt;td&gt;134&lt;/td&gt;
      &lt;td&gt;0.0013&lt;/td&gt;
      &lt;td&gt;-0.0001&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;518.67&lt;/td&gt;
      &lt;td&gt;642.59&lt;/td&gt;
      &lt;td&gt;1582.96&lt;/td&gt;
      &lt;td&gt;1410.92&lt;/td&gt;
      &lt;td&gt;14.62&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;521.58&lt;/td&gt;
      &lt;td&gt;2388.06&lt;/td&gt;
      &lt;td&gt;8155.48&lt;/td&gt;
      &lt;td&gt;8.4500&lt;/td&gt;
      &lt;td&gt;0.03&lt;/td&gt;
      &lt;td&gt;395&lt;/td&gt;
      &lt;td&gt;2388&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;38.61&lt;/td&gt;
      &lt;td&gt;23.2953&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;97&lt;/th&gt;
      &lt;td&gt;98&lt;/td&gt;
      &lt;td&gt;121&lt;/td&gt;
      &lt;td&gt;0.0017&lt;/td&gt;
      &lt;td&gt;0.0001&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;518.67&lt;/td&gt;
      &lt;td&gt;642.68&lt;/td&gt;
      &lt;td&gt;1599.51&lt;/td&gt;
      &lt;td&gt;1415.47&lt;/td&gt;
      &lt;td&gt;14.62&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;521.53&lt;/td&gt;
      &lt;td&gt;2388.09&lt;/td&gt;
      &lt;td&gt;8146.39&lt;/td&gt;
      &lt;td&gt;8.4235&lt;/td&gt;
      &lt;td&gt;0.03&lt;/td&gt;
      &lt;td&gt;394&lt;/td&gt;
      &lt;td&gt;2388&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;38.76&lt;/td&gt;
      &lt;td&gt;23.3608&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;98&lt;/th&gt;
      &lt;td&gt;99&lt;/td&gt;
      &lt;td&gt;97&lt;/td&gt;
      &lt;td&gt;0.0047&lt;/td&gt;
      &lt;td&gt;-0.0000&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;518.67&lt;/td&gt;
      &lt;td&gt;642.00&lt;/td&gt;
      &lt;td&gt;1585.03&lt;/td&gt;
      &lt;td&gt;1397.98&lt;/td&gt;
      &lt;td&gt;14.62&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;521.82&lt;/td&gt;
      &lt;td&gt;2388.02&lt;/td&gt;
      &lt;td&gt;8150.38&lt;/td&gt;
      &lt;td&gt;8.4003&lt;/td&gt;
      &lt;td&gt;0.03&lt;/td&gt;
      &lt;td&gt;391&lt;/td&gt;
      &lt;td&gt;2388&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;38.95&lt;/td&gt;
      &lt;td&gt;23.3595&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;99&lt;/th&gt;
      &lt;td&gt;100&lt;/td&gt;
      &lt;td&gt;198&lt;/td&gt;
      &lt;td&gt;0.0013&lt;/td&gt;
      &lt;td&gt;0.0003&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;518.67&lt;/td&gt;
      &lt;td&gt;642.95&lt;/td&gt;
      &lt;td&gt;1601.62&lt;/td&gt;
      &lt;td&gt;1424.99&lt;/td&gt;
      &lt;td&gt;14.62&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;521.07&lt;/td&gt;
      &lt;td&gt;2388.05&lt;/td&gt;
      &lt;td&gt;8214.64&lt;/td&gt;
      &lt;td&gt;8.4903&lt;/td&gt;
      &lt;td&gt;0.03&lt;/td&gt;
      &lt;td&gt;396&lt;/td&gt;
      &lt;td&gt;2388&lt;/td&gt;
      &lt;td&gt;100.0&lt;/td&gt;
      &lt;td&gt;38.70&lt;/td&gt;
      &lt;td&gt;23.1855&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;100 rows × 26 columns&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;
Lo cuál nos regresa 100 registros, el último para cada motor.&lt;/p&gt;

&lt;h1 id=&quot;modelamiento&quot;&gt;Modelamiento&lt;/h1&gt;

&lt;p&gt;Todo el proceso de modelamiento será utilizando las tecnologías que me gustan, es decir, &lt;mark&gt;DVC&lt;/mark&gt;, &lt;mark&gt;Scikit-Learn&lt;/mark&gt; y &lt;mark&gt;Pytorch Lightning&lt;/mark&gt; cuando corresponda. Además el código será en formato Script. Voy a entrar en detalle de ciertas partes del código. Para todo lo demás incluiré al final un Colab con los pasos para analizar los resultados finales. También disponibilizaré los Scripts utilizados para que puedan analizarlos.&lt;/p&gt;

&lt;div class=&quot;alert-box warning radius &quot;&gt;&lt;p&gt;El Colab añadido tiene sólo comandos que capaces de reproducir el código. Mayoritariamente serán comandos de DVC. Cada uno de estos comandos irán llamando a los distintos Python Scripts según correspondan. Si realmente te interesa empezar a embarrarte las manos con códigos deberás investigar dichos Scripts.&lt;/p&gt;
&lt;/div&gt;

&lt;h2 id=&quot;modelo-baseline-la-querida-regresión-lineal&quot;&gt;Modelo Baseline: La querida Regresión Lineal&lt;/h2&gt;

&lt;p&gt;Lo primero a definir es la configuración que utilizaremos:&lt;/p&gt;

&lt;div title=&quot;config.py&quot; class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pathlib&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Path&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;yaml&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'params.yaml'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;yaml&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;safe_load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;RANDOM_SEED&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'base'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'random_seed'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ASSETS_PATH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'assets'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;DATA_PATH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ASSETS_PATH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'CMAPSSData'&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;TRAIN_FILE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;DATA_PATH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'import'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'train_name'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;TEST_FILE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DATA_PATH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'import'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'test_name'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;RUL_FILE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DATA_PATH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'import'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'rul_name'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;FEATURES_PATH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ASSETS_PATH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'features'&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;MODELS_PATH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ASSETS_PATH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'models'&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;METRICS_PATH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ASSETS_PATH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'train_metrics.json'&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;VAL_METRICS_PATH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ASSETS_PATH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'val_metrics.json'&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;TEST_METRICS_PATH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ASSETS_PATH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'test_metrics.json'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Con esto definimos parámetros de reproducibilidad, nuestros Paths de Input de Datos, y carpetas intermedias para almacenar features, modelos y métricas.
Todos los parámetros utilizados acá son definidos en mi &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;params.yaml&lt;/code&gt; el cual pueden ver en Colab.&lt;/p&gt;

&lt;h3 id=&quot;1era-etapa-featurize&quot;&gt;1era Etapa: Featurize&lt;/h3&gt;

&lt;div title=&quot;01-featurize.py&quot; class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pandas&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;config&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Config&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;yaml&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;utils&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;add_rul&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'params.yaml'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;yaml&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;safe_load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'featurize'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;#======================================================
# importing files
#======================================================
&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FEATURES_PATH&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mkdir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parents&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;exist_ok&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;col_names&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'index_names'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'setting_names'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'sensor_names'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;df_train&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_csv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TRAIN_FILE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sep&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'\s+'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;header&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;names&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;col_names&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;df_test&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_csv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TEST_FILE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sep&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'\s+'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;header&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;names&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;col_names&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;rul_test&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_csv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RUL_FILE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sep&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'\s+'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;header&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;names&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'rul'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;


&lt;span class=&quot;c1&quot;&gt;#======================================================
# defining features
#======================================================
&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;df_train&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;add_rul&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df_train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;train_features&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df_train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'sensor_names'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;train_labels&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df_train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rul&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;test_features&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df_test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;groupby&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'unit_nr'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'sensor_names'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;test_labels&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rul_test&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;#======================================================
# Export Files
#======================================================
&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;train_features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_csv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FEATURES_PATH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'train_features.csv'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;train_labels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_csv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FEATURES_PATH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'train_labels.csv'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;test_features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_csv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FEATURES_PATH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'test_features.csv'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;test_labels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_csv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FEATURES_PATH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'test_labels.csv'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;La etapa featurize básicamente crea la carpeta features, la cual guardará las features que eventualmente se creen.&lt;/li&gt;
  &lt;li&gt;Importa train, test y rul y realiza lo siguiente:
    &lt;ul&gt;
      &lt;li&gt;Define variables a utilizar de acuerdo al parámetro &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;sensor_names&lt;/code&gt;. O sea se están utilizando sólo variables del Sensor 1 al 21, sin importar si éste aporta o no información.&lt;/li&gt;
      &lt;li&gt;Agrega el RUL para el set de entrenamiento.&lt;/li&gt;
      &lt;li&gt;Calcula las features de test (como se mostró en el Notebook).&lt;/li&gt;
      &lt;li&gt;Guarda por separados train y test features además de train y test labels.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;2da-etapa-train&quot;&gt;2da Etapa: Train&lt;/h3&gt;

&lt;div title=&quot;02-train.py&quot; class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;config&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Config&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pandas&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;joblib&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sklearn.linear_model&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LinearRegression&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sklearn.model_selection&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;KFold&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sklearn.metrics&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mean_squared_error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mean_absolute_error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r2_score&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;numpy&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;json&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;yaml&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;logging&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;log&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getLogger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Training&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MODELS_PATH&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mkdir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parents&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;exist_ok&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'params.yaml'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;yaml&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;safe_load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'train'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;train_features&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_csv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FEATURES_PATH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'train_features.csv'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;train_labels&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_csv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FEATURES_PATH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'train_labels.csv'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train_features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train_labels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LinearRegression&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;#======================================================
# Validation Metrics
#======================================================
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;folds&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;KFold&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n_splits&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'n_split'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; 
                &lt;span class=&quot;n&quot;&gt;shuffle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                &lt;span class=&quot;n&quot;&gt;random_state&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RANDOM_SEED&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;mae&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zeros&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;rmse&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zeros&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;r2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zeros&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fold_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train_idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val_idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;enumerate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;folds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;X&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train_features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train_labels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Training Fold: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fold_&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;n&quot;&gt;X_train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;X_val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train_features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train_idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train_features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val_idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;y_train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y_val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train_labels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train_idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train_labels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val_idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    
    &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;X_train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y_train&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;val_preds&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;predict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;X_val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;val_mae&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mean_absolute_error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y_val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val_preds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;val_rmse&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mean_squared_error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y_val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val_preds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;squared&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;val_r2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r2_score&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y_val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val_preds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;n&quot;&gt;mae&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fold_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val_mae&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;rmse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fold_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val_rmse&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;r2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fold_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val_r2&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Validation MAE for Fold &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fold_&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val_mae&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Validation RMSE for Fold &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fold_&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val_rmse&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Validation R2 for Fold &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fold_&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val_r2&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;val_metrics&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;validation&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val_mae&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mae&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mean&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; 
                                    &lt;span class=&quot;n&quot;&gt;val_rmse&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rmse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mean&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; 
                                    &lt;span class=&quot;n&quot;&gt;val_r2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mean&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Saving Validation Metrics'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;VAL_METRICS_PATH&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'w'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;outfile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dump&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val_metrics&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;outfile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;#======================================================
# Retrain Model
#======================================================
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'Model Retraining'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train_features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train_labels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;joblib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dump&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MODELS_PATH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'model_name'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Esta segunda etapa realiza lo siguiente:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Crear el directorio de Modelos.&lt;/li&gt;
  &lt;li&gt;Cargar features y Labels de Entrenamiento.&lt;/li&gt;
  &lt;li&gt;Instanciar el Modelo, en este caso una Regresión Lineal.&lt;/li&gt;
  &lt;li&gt;Instanciar un proceso de KFold.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;alert-box alert radius &quot;&gt;&lt;p&gt;Es importante que hay formas muchas más sencillas de hacer un KFold. Entre ellas está utilizar &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;cross_val_score()&lt;/code&gt;, &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;cross_validate()&lt;/code&gt;, o el mismo &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;GridSearchCV&lt;/code&gt;. Estoy acostumbrándome más a esta forma ya que si bien es más verbosa es muchísimo más flexible para formas de modelación más raras.&lt;/p&gt;
&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Entrenar el Modelo en esquema de Validación y calcular R², RMSE y MAE de Validación.&lt;/li&gt;
  &lt;li&gt;Se reentrena el modelo en toda la data y se guarda el modelo como &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;.joblib&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;3era-etapa-evaluate&quot;&gt;3era Etapa: Evaluate&lt;/h3&gt;

&lt;div title=&quot;03-evaluate.py&quot; class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;json&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;joblib&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sklearn.metrics&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mean_absolute_error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mean_squared_error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r2_score&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pandas&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;utils&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;plot_oof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;plot_importance&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;config&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Config&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IMAGE_PATH&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mkdir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parents&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;exist_ok&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;X_test&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_csv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FEATURES_PATH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'test_features.csv'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;y_test&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_csv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FEATURES_PATH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'test_labels.csv'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;joblib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MODELS_PATH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'model.joblib'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;y_pred&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;predict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;X_test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;#======================================================
# Metrics
#======================================================
&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;test_metrics&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;test&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;test_mae&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mean_absolute_error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y_test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y_pred&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                                &lt;span class=&quot;n&quot;&gt;test_rmse&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mean_squared_error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y_test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y_pred&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;squared&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                                &lt;span class=&quot;n&quot;&gt;test_r2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r2_score&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y_test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y_pred&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TEST_METRICS_PATH&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'w'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;outfile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dump&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;test_metrics&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;outfile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    
&lt;span class=&quot;c1&quot;&gt;#======================================================
# Other Evaluation Curves
#======================================================
&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;plot_oof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y_test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y_pred&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IMAGE_PATH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'F_vs_t.png'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;plot_importance&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;X_test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;columns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IMAGE_PATH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'Feature_Importance.png'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Esta etapa final es más cortita, por lo que sólo realizaremos lo siguiente:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Se crea la carpeta de Imágenes para guardar las Curvas de Interés.&lt;/li&gt;
  &lt;li&gt;Se carga la data de test.&lt;/li&gt;
  &lt;li&gt;Se carga el modelo entrenado.&lt;/li&gt;
  &lt;li&gt;Se calculan las mismas métricas pero ahora para validación.&lt;/li&gt;
  &lt;li&gt;Se calculan una curva OOF para chequear qué partes son las que más falla el modelo.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Si quieres correr todo este proceso puedes usar este Google Colab.&lt;/p&gt;

&lt;center&gt;
&lt;a href=&quot;https://colab.research.google.com/github/datacubeR/cmapps/blob/master/LR_Baseline.ipynb&quot;&gt;&lt;img src=&quot;https://colab.research.google.com/assets/colab-badge.svg&quot; /&gt;&lt;/a&gt;
&lt;/center&gt;

&lt;h2 id=&quot;siguientes-pasos&quot;&gt;Siguientes Pasos&lt;/h2&gt;

&lt;p&gt;Está claro que este no puede ser nuestro modelo final.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;No hemos limpiado variables que no aportan.&lt;/li&gt;
  &lt;li&gt;No hemos creado variables nuevas.&lt;/li&gt;
  &lt;li&gt;No hemos probado otros approaches.&lt;/li&gt;
  &lt;li&gt;No hemos probado otros modelos.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;En la parte 2 iremos agregando algunas de estas mejoras.&lt;/p&gt;

&lt;div class=&quot;alert-box success radius &quot;&gt;&lt;p&gt;Entonces, la idea ahora es desafiarlos. ¿Qué tal nos dio el modelo? ¿Es bueno o es malo? ¿Se puede determinar algún grado de sobreajuste? Ojalá puedas ir comentando lo que pudiste revisar y vamos a ir dejando desafio mayores en cada parte.&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Si les gustó la modalidad, y aprendieron algo nuevo, por fa denme una estrellita en el &lt;a href=&quot;https://github.com/datacubeR/cmapps&quot;&gt;Repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Hasta la otra!!&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/contact/&quot;&gt;&lt;strong&gt;Alfonso&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
</content>

			
				<category term="ml" />
			
			
				<category term="sklearn" />
			
				<category term="tutorial" />
			
				<category term="ML" />
			
				<category term="dl" />
			

			<published>2022-08-30T00:00:00+00:00</published>
		</entry>
	
		<entry>
			<id>http://datacuber.github.io/deepant/</id>
			<title>Implementando DeepAnt</title>
			<link href="http://datacuber.github.io/deepant/" rel="alternate" type="text/html" title="Implementando DeepAnt" />
			<updated>2022-08-08T00:00:00+00:00</updated>

			
			<summary></summary>
			<content type="html" xml:base="http://datacuber.github.io/deepant/">&lt;p&gt;&lt;img src=&quot;/images/deepant/anomaly.png&quot; alt=&quot;picture of me&quot; class=&quot;left show-for-large-up hide-for-print&quot; width=&quot;250&quot; /&gt;
&lt;img src=&quot;/images/deepant/anomaly.png&quot; alt=&quot;picture of me&quot; class=&quot;center hide-for-large-up&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Bueno, como les comenté en los post anteriores, mi tema de investigación está siendo el uso de Anomalías en Series de Tiempo &lt;strong&gt;util&lt;/strong&gt;izando Deep Learning. Por lo que comencé por implementar mi primer Paper y publicándolo en &lt;a href=&quot;https://paperswithcode.com/paper/deepant-a-deep-learning-approach-for&quot;&gt;Papers with Code&lt;/a&gt; &lt;!--more--&gt; por lo que les agradecería encarecidamente que si aprendieron algo nuevo me dieran una estrellita en el &lt;a href=&quot;https://github.com/datacubeR/DeepAnt&quot;&gt;Github&lt;/a&gt; para que gane popularidad.&lt;/p&gt;

&lt;p&gt;Además, creo que gran parte del valor de un tutorial es que puedan reproducirlo, por lo que de ahora en adelante podrán reproducirlo sin casi nada de configuración en Google Colab. Sólo clickeen en &lt;strong&gt;Open in Colab&lt;/strong&gt; e instalen las dependencias. Perdón que el Notebook esté en Inglés pero lo estoy usando como parte de la publicación en Papers with Code. Prometo que otros estarán en español.&lt;/p&gt;

&lt;p&gt;El código completo lo encontrarán en el Notebook, por lo que sólo incluiré el código más interesante a explicar.&lt;/p&gt;

&lt;center&gt;
&lt;a href=&quot;https://colab.research.google.com/github/datacubeR/DeepAnt/blob/master/DeepAnt.ipynb&quot;&gt;&lt;img src=&quot;https://colab.research.google.com/assets/colab-badge.svg&quot; /&gt;&lt;/a&gt;
&lt;/center&gt;

&lt;h2 id=&quot;deepant&quot;&gt;DeepAnt&lt;/h2&gt;

&lt;p&gt;Bueno DeepAnt es un algoritmo de Detección de Anomalías en series de tiempo. Su principal usi es detectar comportamiento anormal de una medición en el tiempo de manera no supervisada, es decir, no tenemos etiquetas para validar qué partes de las series de tiempo son anómalas o no. Esto es particularmente importante debido a que las anomalías son raras, no tenemos cómo saber a priori cómo son y cómo se ven. Algunas de las principales aplicaciones de la Detección de Anomalías son Detección de Fraude, comportamientos inusuales, etc.&lt;/p&gt;

&lt;p&gt;En este caso lo que haremos es reproducir el algoritmo en uno de los dataset de prueba utilizados en el paper. Este dataset chequea el tiempo de demora en tráfico en Minnesota, y la tarea es detectar cuáles de esos tiempos son son correctos.&lt;/p&gt;

&lt;p&gt;Para ello DeepAnt propone una arquitectura utilizando Redes Convolucionales de 1 dimensión para análisis de secuencias. Lo más común para resolver este tipo de problemas es utilizar redes recurrentes pero en este caso, las redes convolucionales funcionan bastante bien.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/deepant/DeepAnt.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Obviamente lo común es pensar que las Redes Convolucionales se utilizan sólo en Imágenes, pero una Red Convolucional de 1D es como una imagen pero sin alto, solo con ancho.&lt;/p&gt;

&lt;p&gt;Investigando y adentrándome más en el tema se definen 3 tipos de algoritmos para la detección de Anomalías: Forecast Based, Reconstruction Based y mixtos. DeepAnt es ForecastBased, lo que quiere decir que va a intentar predecir uno más a puntos con la hipótesis que valores anómalos serán más dificiles de predecir. Luego las predicciones pasarán por una métrica de error, este caso Norma L2, Los puntos con más error serán considerados anomalías.&lt;/p&gt;

&lt;p&gt;Si quieres conocer cómo funciona uno Reconstruction Based, puedes ir &lt;a href=&quot;/lstm-ae/&quot;&gt;acá&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;La métrica L2 se define como:&lt;/p&gt;

\[L2 = ||y_{pred}-y||_2 = \sqrt{(y_{pred}-y)^2}\]

&lt;h1 id=&quot;data&quot;&gt;Data&lt;/h1&gt;

&lt;p&gt;Al revisar nuestra data nos encontramos con esto:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_csv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'data/TravelTime_451.csv'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index_col&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'timestamp'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parse_dates&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'timestamp'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;plot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;figsize&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'Travel Time'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;legend&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;img src=&quot;/images/deepant/data.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Se puede ver claramente que la data tiene unos peaks que podrían ser eventualmente inusuales.&lt;/p&gt;

&lt;p&gt;Para el entrenamiento del modelo el Paper propone crear minisecuencias, supongamos que tenemos una series de Tiempo TS de 5 Puntos:&lt;/p&gt;

\[TS = \{x_1, x_2, x_3, x_4, x_5\}\]

&lt;p&gt;Por ejemplo, las secuencias $S_i$ de largo 2 serían así:&lt;/p&gt;

\[S_i = \{x_{i-2}, x_{i-1}\} \rightarrow x_i\]

&lt;p&gt;Es decir, el punto $x_i$ se trataría de predecir con los dos puntos inmediatamente anteriores.&lt;/p&gt;

&lt;p&gt;Esto podemos implementarlo en Pytorch de la siguiente manera:&lt;/p&gt;

&lt;div title=&quot;Pytorch Dataset&quot; class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TrafficDataset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Dataset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seq_len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq_len&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seq_len&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sequence&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;timestamp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;create_sequence&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seq_len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;create_sequence&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seq_len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;sc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MinMaxScaler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_numpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fit_transform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_numpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reshape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        
        &lt;span class=&quot;n&quot;&gt;sequence&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;label&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;timestamp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seq_len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;sequence&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq_len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq_len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;timestamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq_len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
            
            
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sequence&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;timestamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__len__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq_len&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__getitem__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;torch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tensor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sequence&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;torch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;permute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
                &lt;span class=&quot;n&quot;&gt;torch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tensor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;torch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;El método &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;create_sequence()&lt;/code&gt; creará la secuencia escalada en el rango [0.1]. Hacer este preprocesamiento genera más estabilidad en el entrenamiento. Además se crea la etiqueta a utilizar dependiendo del &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;SEQ_LEN&lt;/code&gt; dado. Además guardaremos el timestamp asociado a la etiqueta para poder identificar dónde ocurren las anomalías. El resto corresponde a la estructura de Pytorch Dataset para incluirlo posteriormente en los DataLoaders.&lt;/p&gt;

&lt;p&gt;Luego, viene el &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;DataModule&lt;/code&gt;. Este permitirá indicar el proceso de entrenamiento:&lt;/p&gt;

&lt;div title=&quot;DataModule&quot; class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DataModule&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LightningDataModule&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seq_len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq_len&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seq_len&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stage&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dataset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TrafficDataset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq_len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;train_dataloader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DataLoader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dataset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batch_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num_workers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pin_memory&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shuffle&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;predict_dataloader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DataLoader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dataset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batch_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num_workers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pin_memory&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shuffle&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;En este caso sólo tenemos dos DataLoaders idénticos excepto por el batch size: 32 para entrenar con shuffle, y 1 para predecir. Sólo por un tema de organizar las predicciones de manera más fácil (y sin shuffle).&lt;/p&gt;

&lt;p&gt;Luego la Arquitectura de &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;DeepAnt&lt;/code&gt;:&lt;/p&gt;

&lt;div title=&quot;Arquitectura DeepAnt&quot; class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DeepAnt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seq_len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p_w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;convblock1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Sequential&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Conv1d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;in_channels&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out_channels&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kernel_size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'valid'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ReLU&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inplace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MaxPool1d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kernel_size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;convblock2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Sequential&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Conv1d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;in_channels&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;out_channels&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kernel_size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'valid'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ReLU&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inplace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MaxPool1d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kernel_size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flatten&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Flatten&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;denseblock&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Sequential&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Linear&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;#nn.Linear(96, 40), # for SEQL_LEN = 20
&lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ReLU&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inplace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Dropout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Linear&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p_w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;forward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;convblock1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;convblock2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flatten&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;denseblock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Como se puede ver se compone de 3 Bloques + la salida:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;2 Bloques Convolucionales de 32 Filtros con una Capa Convolucional 1D Relu y MaxPool1D. El Kernel Convolucional es 3x3, mientras que el Pooling es 2x2.&lt;/li&gt;
  &lt;li&gt;Una capa flatten para conectar con la Capa Densa.&lt;/li&gt;
  &lt;li&gt;Una capa Hidden de 40 Neuronas más Relu y Dropout de 25%.&lt;/li&gt;
  &lt;li&gt;Finalmente la capa de Predicción con salida p_w. El paper indica que de predecir anomalías puntuales se usa p_w = 1, que es el caso implementado. En caso de predecir secuencias se puede usar p_w, con el correspondiente ajuste a la creación de secuencias.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finalmente el LightningModule:&lt;/p&gt;

&lt;div title=&quot;LighningModule&quot; class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AnomalyDetector&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LightningModule&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;criterion&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;L1Loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;forward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;training_step&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batch_idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;y_pred&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;criterion&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y_pred&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'train_loss'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prog_bar&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;predict_step&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batch_idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;y_pred&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y_pred&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;torch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;linalg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;norm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y_pred&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;configure_optimizers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;torch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;optim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Adam&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parameters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1e-5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;De acuerdo al Paper se entrena el modelo con MAE Loss (L1Loss en Pytorch) durante 30 epochs. Para la predicción, no nos interesa la predicción propiamente tal, sino que la Norma L2 (&lt;code class=&quot;language-text highlighter-rouge&quot;&gt;torch.linalg.norm(y_pred-y)&lt;/code&gt;), aunque también retorno la predicción en caso de necesitarla.&lt;/p&gt;

&lt;h2 id=&quot;análisis-de-los-resultados&quot;&gt;Análisis de los Resultados&lt;/h2&gt;

&lt;p&gt;Al momento de inferencia se grafica la distribución de Errores por Norma L2 y el error para cada punto predicho. Por inspección visual se decide que todos los puntos con error mayor a 0.5 se consideran anomalías:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/deepant/loss.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; /&gt;
&lt;img src=&quot;/images/deepant/thresh.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;Anomalies Detected: 
2015-07-29 06:49:00    0.759585
2015-07-31 10:29:00    0.504894
2015-07-31 10:39:00    0.533254
2015-07-31 10:59:00    0.509283
2015-07-31 11:09:00    0.731919
2015-07-31 11:29:00    0.665691
2015-07-31 11:39:00    0.734755
2015-07-31 11:59:00    0.815328
2015-07-31 12:09:00    0.890414
2015-07-31 12:29:00    0.904424
2015-07-31 12:33:00    0.965008
2015-08-07 06:09:00    0.947923
2015-08-11 12:07:00    0.524375
dtype: float32
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Luego si marcamos los puntos encontrados en la serie de tiempo original obtenemos lo siguiente:
&lt;img src=&quot;/images/deepant/anomalies_detected.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Bueno, no tenemos información sobre etiquetas existentes como para poder medir la performance del modelo. Esto debido a la naturaleza no supervisada del modelo. Lo que sí se indica en distintos blog post de este dataset es que existe una anomalía confirmada el día &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;2015-08-11 12:07:00&lt;/code&gt;. La cuál es difícil de detectar porque no es la más prominente de las existentes.&lt;/p&gt;

&lt;p&gt;En este caso DeepAnt es capaz de encontrarla de manera exitosa junto con otras más.&lt;/p&gt;

&lt;h2 id=&quot;conclusiones&quot;&gt;Conclusiones&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Es posible ver que DeepAnt funciona bastante bien. Es una arquitectura relativamente sencilla de realizar y su tiempo de entrenamiento e inferencia son bien bajos lo cual lo hace un modelo que puede ser de fácil implementación en producción.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;Ventajas: El uso de Redes Convolucionales 1D, ya que son mucho más fáciles de entrenar que una RNN, LSTM o GRU. Su procedimiento es estándar y fácilmente explicable.&lt;/li&gt;
  &lt;li&gt;Desventajas: Debido a la naturaleza secuencial, no es posible detectar anomalías en los primeros &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;SEQ_LEN&lt;/code&gt; puntos, ya que no hay data previa para el Forecast necesario.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bueno, espero que este tipo de modelos sean útiles tanto para eventualmente implementarlos como para aprender del funcionamiento del Deep Learning en Detección de Anomalías.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Y ahora a jugar con el modelo, no hay excusa. &lt;strong&gt;El código está para llegar y ejecutar en Colab!!!&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href=&quot;/contact/&quot;&gt;&lt;strong&gt;Alfonso&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
</content>

			
				<category term="pp" />
			
			
				<category term="pytorch" />
			
				<category term="tutorial" />
			
				<category term="dl" />
			

			<published>2022-08-08T00:00:00+00:00</published>
		</entry>
	
		<entry>
			<id>http://datacuber.github.io/ds-lib/</id>
			<title>¿Qué debo aprender para ser Data Scientist?</title>
			<link href="http://datacuber.github.io/ds-lib/" rel="alternate" type="text/html" title="¿Qué debo aprender para ser Data Scientist?" />
			<updated>2022-08-01T00:00:00+00:00</updated>

			
			<summary></summary>
			<content type="html" xml:base="http://datacuber.github.io/ds-lib/">&lt;p&gt;&lt;img src=&quot;/images/libraries/librerías.png&quot; alt=&quot;picture of me&quot; class=&quot;left show-for-large-up hide-for-print&quot; width=&quot;300&quot; /&gt;
&lt;img src=&quot;/images/libraries/librerías.png&quot; alt=&quot;picture of me&quot; class=&quot;center hide-for-large-up&quot; width=&quot;250&quot; /&gt;&lt;/p&gt;

&lt;p&gt;La ciencia de datos es una de las disciplinas más de moda hoy en día. Y cómo que por alguna razón todos quieren ser parte de ello. Sin duda en el mediano/largo plazo probablemente todas las disciplinas tendrán una componente de datos y la verdad es que vale la pena aprender a lidiar con ellos.&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;Hoy en día la decisión es simple, trabajar con R o con Python, pero el tema es que Python tiene 150.000+ librerías y R tiene otras tantas, por lo que a veces es abrumante pensar, tengo que aprender todo? Ojo, eso sin contar otro tipo de tecnologías de Visualización, ETL y un largo etc. Por donde empiezo, tengo un montón de opciones y no me gustaría perder el tiempo en cosas que no valen la pena.&lt;/p&gt;

&lt;p&gt;Además, en plataformas como Linkedin siempre hay gente en cuyo título dice Data Science | Machine Learning | Analytics Expert y un largo etc. y que probablemente en su vida ha programado y comparten publicaciones como esta:&lt;/p&gt;

&lt;h1 class=&quot;no_toc&quot; id=&quot;tldr&quot;&gt;&lt;abbr title=&quot;Too Long; Didn't Read&quot;&gt;TL;DR&lt;/abbr&gt;&lt;/h1&gt;

&lt;h2 class=&quot;no_toc&quot; id=&quot;top-10-librerías-de-python&quot;&gt;TOP 10 LIBRERÍAS DE PYTHON&lt;/h2&gt;

&lt;p&gt;Esta es una lista que encontré por ahí:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Pandas.&lt;/li&gt;
  &lt;li&gt;NLTK.&lt;/li&gt;
  &lt;li&gt;Plotly.&lt;/li&gt;
  &lt;li&gt;Scikit-learn.&lt;/li&gt;
  &lt;li&gt;Category-encoders (era tremenda librería pero está sin mantenimiento actualmente)&lt;/li&gt;
  &lt;li&gt;Imbalance Learning. (Esta no es ni siquiera una librería en Python, se llama Imbalanced-Learn)&lt;/li&gt;
  &lt;li&gt;XGBoost.&lt;/li&gt;
  &lt;li&gt;Keras / Tensorflow.&lt;/li&gt;
  &lt;li&gt;Theano. (Nadie usa esto ya)&lt;/li&gt;
  &lt;li&gt;Beautiful Soup.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Colocan una foto llena de logos, y un listado con nombres casi aleatorios:&lt;br /&gt;
&lt;img src=&quot;/images/libraries/ble.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;A veces te indican qué librerías sí o sí tienes que saber, y nunca las has escuchado:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/libraries/libraries_1.jpg&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;A veces tienen hasta errores burdos:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/libraries/libraries_2.jpg&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Y uno se pregunta ¿Con qué parto?. Y la verdad es que si bien son librerías que pueden ser útiles, hay que ver si realmente son aplicables al trabajo que haces y si vale el esfuerzo de aprenderlo.&lt;/p&gt;

&lt;h2 class=&quot;no_toc&quot; id=&quot;un-alto-antes-de-continuar&quot;&gt;Un Alto antes de Continuar&lt;/h2&gt;

&lt;p&gt;La ciencia de datos es una disciplina enorme. Y hay que darla paso a paso, o no vamos a lograr nada y vamos a vivir estresados de tantas cosas que no sabemos usar y que tenemos que aprender. No digo que mi caso sea el perfecto, para nada, pero yo partí así:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Business Analyst&lt;/strong&gt; (Una especie de Data Analyst, pero enfocado en dar valor al negocio 🤭 ja ja): En mis primeros 2 años, lo que más hacía era responder preguntas con datos. El resultado, una query en SQL, la mayor parte del tiempo con una tabla exportada en Excel. Aprendí mucho SQL porque las Bases de Datos que usábamos eran gigantes y muy complejas. Responder una pregunta de negocio podía tomar 6 o 7 subqueries, con muchos joins en cada una de ellas. Luego tuve la oportunidad de crear algoritmos sencillos para aplicar lógicas de negocios, a esto le llamábamos Calculation Engines (Motores de cálculo). Y es básicamente aplicar lógicas de negocio complejas en los datos para chequear qué clientes cumplían o no regulaciones bancarias. Luego muté nuevamente a algo más BI, y me tocaba hacer dashboards en Tableau todo el día, todos los días. La data que el dashboard necesita no se ordena sola, por lo que aparte de hacer gráficos que digan algo, había que hacer mucho SQL de fondo. No fue hasta como mi tercer año de Analista que comencé a hacer una Regresión o un SVM loco por ahí. Todo esto en R.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Data Scientist&lt;/strong&gt;: Luego de como 4 años logre un puesto de Data Scientist. Ya llevaba como 1 año haciendo modelos a escondidas, porque no era mi rol. Y acá me cambié a Python definitivamente. Tuve que aprender mucho pandas, Scikit-Learn (y los 3 grandes XGBoost, LightGBM y CatBoost) y modelar mucho. Pero con muchos errores teóricos de fondo, y ahí decidí que era importante entender el transfondo teórico. En ese tiempo leía mucho blog y veía mucho video (aún lo hago, pero ahí partí). Quizás desde el 2021 que ya me metí de lleno en el Deep Learning y acá estamos.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
  &lt;p&gt;Todo tiene que ser progresivo. El &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Deep Learning&lt;/code&gt; es sólo una extensión del &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Machine Learning&lt;/code&gt;, en vez de hacer feature selection/engineering, acá hay que hacer “Architecture Engineering”, tratando de encontrar la arquitectura más apropiada a un problema. Por otra parte el &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Machine Learning&lt;/code&gt; es una extensión del &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Análisis&lt;/code&gt;. En vez de que tenga que analizar la data manualmente, el modelo aprende los insights por mí y a escala, pero hay que entregar data estructurada. Y el &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Análisis&lt;/code&gt; es sólo una extensión de la &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Manipulación de Datos&lt;/code&gt;. Sólo se puede entender la data una vez que la tengo ordenadita. Entonces, hay que partir de a poco, y no saltarse pasos.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div id=&quot;toc&quot; class=&quot;panel radius&quot;&gt;
  &lt;h2 class=&quot;no_toc&quot; id=&quot;tabla-de-contenidos&quot;&gt;Tabla de Contenidos&lt;/h2&gt;
&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#la-idea&quot; id=&quot;markdown-toc-la-idea&quot;&gt;La idea&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#manipulación-de-datos&quot; id=&quot;markdown-toc-manipulación-de-datos&quot;&gt;Manipulación de Datos&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#bases-de-datos&quot; id=&quot;markdown-toc-bases-de-datos&quot;&gt;Bases de Datos&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#visualizaciones&quot; id=&quot;markdown-toc-visualizaciones&quot;&gt;Visualizaciones&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#otras-herramientas-bi&quot; id=&quot;markdown-toc-otras-herramientas-bi&quot;&gt;Otras herramientas BI&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#machine-learning&quot; id=&quot;markdown-toc-machine-learning&quot;&gt;Machine Learning&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#deep-learning&quot; id=&quot;markdown-toc-deep-learning&quot;&gt;Deep Learning&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#misceláneo&quot; id=&quot;markdown-toc-misceláneo&quot;&gt;Misceláneo&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#librerías-estándar-que-deberías-usarconocer&quot; id=&quot;markdown-toc-librerías-estándar-que-deberías-usarconocer&quot;&gt;Librerías estándar que deberías usar/conocer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;

&lt;h1 id=&quot;la-idea&quot;&gt;La idea&lt;/h1&gt;

&lt;p&gt;Trabajando como Data Scientist creo que he usado 100+ librerías y otras tecnologías, por lo que quiero hablar de cada una de ellas y dar mi opinión si vale la pena aprenderla o no. Quiero decir que en verdad llevo más tiempo usando R (cerca de 5 años) que Python (3 años), por lo que voy a tratar de dar mi opinión de ambos.&lt;/p&gt;

&lt;p&gt;La idea nace porque siempre me pongo a rabiar cuando &lt;q&gt;gente experta&lt;/q&gt; publica algo copiado de plataformas como Coding Dojo, Datacamp, etc. con información incompleta y recomendando librerías que nunca han usado (y hoy yo también voy a hacer eso 🤭😅). Entonces decidí que quiero hacer un compendio de las tecnologías más famosas que hay relacionadas a la ciencia de datos.&lt;/p&gt;

&lt;p&gt;El compendio incluirá lo siguiente:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Todas las librerías/tecnologías que he utilizado previamente.&lt;/li&gt;
  &lt;li&gt;Sólo en ocasiones excepcionales listaré librerías que no he utilizado cuando ocurra algunos de los siguientes casos:
    &lt;ul&gt;
      &lt;li&gt;Están en mi lista de estar próximo a usarla y si bien no tengo proyectos con ellas ya me he adentrado en su documentación.&lt;/li&gt;
      &lt;li&gt;Son demasiado famosas para dejarlas fuera.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Principalmente mencionaré librerías de Python, porque es el estado del arte en Ciencia de Datos y algunas librerías de mi tiempo usando R.&lt;/p&gt;

&lt;p&gt;Además me dí la lata de recorrer los 5000 paquetes más descargados en PyPI para recomendar librerías de Python, por lo que en el caso de que corresponda indicaré el Ranking y el número de descargas al 01-07-2022. Debo advertir que puedo estar un poco desactualizado en R porque dejé de usarlo definitivamente desde fines del 2019. Además cuando corresponda voy a mencionar otras tecnologías fuera de R o Python que quizás vale la pena conocer cuando se trabaja en ciertas áreas de la Ciencia de Datos.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Librerías de Python incluirán Ranking en PyPI (Rk) y número de descargas (ND).&lt;/li&gt;
  &lt;li&gt;Librerías de R irán acompañadas de un indicador (R).&lt;/li&gt;
  &lt;li&gt;Otras Técnologías que no son librerías ni de R ni de Python llevarán una (O) de Otras.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Voy además dividirlas en Prioridades:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;1: Definitivamente debes aprenderlas y empezar a utilizarlas ya. En el caso de R debes aprenderla ya, pero sólo si usas R.&lt;/li&gt;
  &lt;li&gt;2: Dependiendo del caso (si trabajas con tecnologías anexas) podría ser una buena opción.&lt;/li&gt;
  &lt;li&gt;0: No pierdas tu tiempo en aprenderlas. No porque sea mala, sino que la vas a necesitar de manera muy esporádica, por lo que hay que saber qué puede hacer, para qué sirve y puede que en algún momento de la vida una que otra función sea útil.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finalmente, dividiré todas las recomendaciones en las siguientes categorías:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Manipulación de Datos,&lt;/li&gt;
  &lt;li&gt;Bases de Datos,&lt;/li&gt;
  &lt;li&gt;Machine Learning,&lt;/li&gt;
  &lt;li&gt;Deep Learning,&lt;/li&gt;
  &lt;li&gt;Misceláneo.&lt;/li&gt;
  &lt;li&gt;Librerías Estándar&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;alert-box todo radius &quot;&gt;&lt;p&gt;Esta lista no es exhaustiva y si alguien quiere contribuir ayudando a reclasificar esto estoy abierto a sugerencias y colaboraciones.&lt;/p&gt;
&lt;/div&gt;

&lt;blockquote&gt;
  &lt;p&gt;Disclaimer: Todas las librerías que mencionaré son excelente en lo que hacen. Si recomiendo no aprenderlas no es porque sean malas (a menos que lo diga), es sólo que muy rara vez necesitarás utilizarlas debido a que son demasiado específicas y no vale la pena enfocarse en ellas. Basta con leer la documentación un rato antes de utilizarla y saber que existe.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Finalmente el objetivo final de este compendio es que los nuevos Data Scientists (y también los más experimentados) puedan tener una opinión de qué librerías existen y cuáles sí o sí deberían dominar.&lt;/p&gt;

&lt;h1 id=&quot;manipulación-de-datos&quot;&gt;Manipulación de Datos&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;SQL&lt;/strong&gt; ((O), Pr: 1): Si bien esta no es una librería de Python/R, esto es por lejos lo primero que todo Data Scientist debe saber. No es necesario ser un ultra experto en este tema pero sí al menos debes dominar los siguientes aspectos:&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;SELECT/FROM&lt;/li&gt;
  &lt;li&gt;JOINS: Entender las principales diferencias entre LEFT, RIGHT, INNER, SELF JOINS.&lt;/li&gt;
  &lt;li&gt;WHERE, GROUP BY, HAVING.&lt;/li&gt;
  &lt;li&gt;ORDER BY&lt;/li&gt;
  &lt;li&gt;MIN,MAX, AVG, etc.&lt;/li&gt;
  &lt;li&gt;CREATE (volatile, temporary) TABLE, INSERT INTO, WITH (Esto es bien difuso ya que depende del motor).&lt;/li&gt;
  &lt;li&gt;Entender al menos los motores más populares que son por lejos MySQL y Postgresql.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Es muy triste ver gente que se hace llamar Data Scientist y no sabe hacer una query. Sin datos, no hay Científico de Datos, por lo que sí o sí dale a esto primero que cualquier otra cosa!!&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Pandas&lt;/strong&gt; (Rk: 31, ND: 86M+, Pr: 1): Esta es por lejos la librería más utilizada en Ciencia de Datos y para mi gusto la más completa. No está en el primer lugar porque realmente creo que es más importante saber SQL primero ya que es mucho más simple. Básicamente Pandas es un SQL con Esteroides, muchísimo más poderosa y que bajo ningún motivo puede ser reemplazada por SQL. Pero tiene tantos comandos que al principio uno podría no saber cómo empezar. Su API es tan buena que existen muchos mirrors, como Dask, koalas, o cuDF, que siguen la misma convención sólo que el backend hace algo distinto (Básicamente aprendiendo pandas se pueden aprender varias librerías a la vez). Mi recomendación es aprender cómo reproducir todo lo aprendido en SQL y luego aprender funciones para resolver problemas específicos. ¿Cómo aprender? Lo mejor es a través del &lt;a href=&quot;https://pandas.pydata.org/docs/user_guide/index.html&quot;&gt;User Guide&lt;/a&gt; en su propia documentación.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Numpy&lt;/strong&gt; (Rk: 15, ND: 110M+, Pr: 0): Numpy es una librería de computación científica, esto quiere decir, computar/calcular implementaciones matemáticas/estadísticas desde test de hipótesis, Transformadas de Fourier, y un largo etc. Normalmente se recomienda aprender antes o junto a Pandas, pero realmente creo que (prepárense) &lt;mark&gt;no vale la pena aprenderla inicialmente&lt;/mark&gt;. Hace unos años era necesario aprender numpy para complementar pandas, ya que habían muchas cosas que no estaban disponibles en pandas pero sí en Numpy, pero si es que no vas a hacer implementaciones directamente de Algebra Lineal, no va a ser necesario usarla. Obviamente cuando uno es avanzado se dará cuenta que es bueno entender conceptos de Numpy como la vectorización. Mi recomendación es aprender &lt;strong&gt;sólo funciones que no están en pandas&lt;/strong&gt; a medida que las vayas necesitando.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A varios les puede llamar la atención que tiene más descargas que Pandas, pero la explicación es sencilla. Muchas librerías tiene como dependencia Numpy, Scikit-Learn, Matplotlib, pandas, y un largo etc, que hace obligatorio siempre tenerla instalada.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Scipy&lt;/strong&gt; (Rk: 65, ND: 42M+, Pr: 0): Este es un pedacito de Numpy aún más específico. Definitivamente &lt;mark&gt;no vale la pena aprenderlo&lt;/mark&gt;, y sólo se necesitarán funciones muy específicas. En mi caso sólo la he usado para utilizar matrices sparse cuando queremos disminuir el tamaño de matrices con demasiados ceros y cuando enseñé probabilidad, porque tiene todas las distribuciones de probabilidad (incluso si son muy raras) con sus respectivas funciones para muestreos, pmf, pdf y cdf.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;dplyr&lt;/strong&gt; ((R), Pr: 1): Diría que es la versión en R de pandas, pero es un poco más limitado. No porque no tenga las capacidades para hacer lo que pandas hace sino porque el ecosistema de R está disperso en más paquetes. Para emular pandas en R se tiene que usar casi todo el tidyverse: &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;dplyr&lt;/code&gt;, &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;tidyr&lt;/code&gt;, &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;lubridate&lt;/code&gt; y &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;hms&lt;/code&gt; (para fechas), &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;forecats&lt;/code&gt; (para variables categóricas), &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;purrr&lt;/code&gt; (para loops eficientes), &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;readr&lt;/code&gt; + &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;vroom&lt;/code&gt; para io, &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;stringr&lt;/code&gt; y &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;stringi&lt;/code&gt; para lidiar con strings. Creo que el uso del pipe (%&amp;gt;%) hace que el código en R sea más expresivo que en pandas y realmente vale la pena aprender este ecosistema si trabajas en R ya que es mucho más amigable que la sintaxis de R puro.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Dask&lt;/strong&gt; (Rk: 390, ND: 5.6M+, Pr: 0): Corresponde al motor que provee paralelismo para Pandas. La librería es excelente pero bajo ningún motivo vale la pena invertir tiempo acá, porque básicamente es la misma interfaz de pandas. Basta con hacer &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;import dask.dataframe as dd&lt;/code&gt; y anteponer &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;dd&lt;/code&gt; en vez de &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;pd&lt;/code&gt; y listo. No he tenido que usar nunca esta librería pero es demasiado famosa para no mencionarla.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;data.table&lt;/strong&gt; (R principalmente pero creo que también está en Python, Pr: 0): Este es un tema polémico porque hace mucho tiempo había una discusión entre el creador de esta librería y la gente de RStudio. Básicamente &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;data.table&lt;/code&gt; es la librería más rápida para manejo de datos en R pero su sintaxis no es muy amigable. Afortunadamente Hadley Wickham creo &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;dtplyr&lt;/code&gt; que permite usar data.table como el backend de dplyr, por lo que diría que si bien esta librería es extremadamente poderosa no vale la pena aprenderla si sabes &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;dplyr&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;cudf&lt;/strong&gt; (Rk: NA, ND: NA, Pr: 0): &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;cuDF&lt;/code&gt; es una librería que es parte de RAPIDS, un set de paquetes en Python desarrollado por NVIDIA que permiten ejecutar todo en GPU. Este es el mirror de Pandas, básicamente la misma sintaxis que pandas pero que en el backend se ejecuta en GPU. &lt;mark&gt;No vale la pena apenderla, ya que es igual a pandas&lt;/mark&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;cupy&lt;/strong&gt; (Rk: NA, ND: NA, Pr: 0): Es el Mirror en este caso de Numpy. Si sabes &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;numpy&lt;/code&gt; entonces sabes &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;cupy&lt;/code&gt;, no debería estar dentro de tus prioridades como Data Scientist. Pero en el caso de querer lanzar tus procesos a la GPU es excelente.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;alert-box alert radius &quot;&gt;&lt;p&gt;Estas librerías no deberían ser la mejor opción para trabajar con grandes volumentes de datos. Esto porque normalmente la GPU tiene menos RAM, a menos que tengas varias GPU o una RTX3090. La mayoría del tiempo utilizar pandas va a ser más que suficiente.&lt;/p&gt;
&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;pyspark&lt;/strong&gt; (Rk: 127, ND: 23.9M+, Pr: 0): Este es la librería por excelencia para trabajar con Big Data. &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;pyspark&lt;/code&gt; es el cliente de Python para el Spark de Scala. Lo bueno de esta librería es que te da la opción de usar una API muy similar al Spark en Scala o incluso una que utiliza comandos tipo SQL. Esta va a ser la mejor opción para cuando tengas que trabajar con Big Data y computación distribuida en un Cluster, pero &lt;mark&gt;NO VALE LA PENA APRENDERLO&lt;/mark&gt;. Principalmente porque la interfaz de SQL te servirá la mayor cantidad del tiempo para llevar a cabo ETLs y en caso de procesamiento más rebuscado &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;koalas&lt;/code&gt; es un mirror de pandas para ejecutar Spark.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;findspark&lt;/strong&gt; (Rk: 729, ND: 2.4M+, Pr: 0): Tan enredada es la instalación de Spark que se creó una librería para tener el path de instalación y poder levantar un Cluster local. Sólo sirve para eso.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;koalas&lt;/strong&gt; (Rk: 1047, ND: 1.4M+, Pr: 0): Si tienes que usar Spark yo creo que es mejor &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;koalas&lt;/code&gt;, que tiene la sintaxis de pandas que uno ya sabe. No es necesario aprender nada nuevo.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;sparklyr&lt;/strong&gt; ((R), Pr: 2): La única vez que tuve que trabajar con data en Spark fue en Python y usé koalas. Pero vale la pena mencionar esta librería porque básicamente permite ejecutar Spark usando sintaxis de &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;dplyr&lt;/code&gt;. Si es que llegaras a necesitar Spark, mi recomendación sería hazlo en otro lenguaje (principalmente por los problemas de memory leakage de R) pero si necesitas hacerlo en R, esta es la mejor opción.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;NetworkX&lt;/strong&gt; (Rk: 147, ND: 20M+, Pr: 2): Es una librería de manipulación de datos, pero en forma de grafos. No la he usado más que para calcular métricas de centralidad (closeness, betweeness, degree, etc). Pero es probable que comience a utilizarla más.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Microsoft Excel&lt;/strong&gt; ((O), Pr: 1): Excel &lt;strong&gt;nunca&lt;/strong&gt; debería ser una opción para trabajar con Datos, pero sí o sí tienes que saber usarlo porque lamentablemente los archivos &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;.xlsx&lt;/code&gt; son todavía un formato extremadamente popular. &lt;mark&gt;NUNCA&lt;/mark&gt; deberías utilizar Excel si no es sólo para entregar resultados. Si tú eres de los que aún dice que hay cosas que son más sencillas en Excel que en Pandas o SQL, es que no sabes utilizar bien esas tecnologías aún.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;bases-de-datos&quot;&gt;Bases de Datos&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;sqlalchemy&lt;/strong&gt; (Rk: 49, ND: 49M+, Pr: 1): Esta es por lejos una de las mejores librerías que se han creado en Python. Básicamente permite utilizar cualquier Base de Dato SQL con una interfaz común. Debo decir que si bien esta es una librería extremadamente poderosa y que vale completamente la pena aprender, la documentación está pensada para gente bien “computín” y no es tan amigable. Mi recomendación para aprenderla es mediante videos tutoriales. Ahora en Ciencia de Datos la vas a ocupar sí o sí si eres Data Engineer para poder modelar Bases de Datos o hacer consultas. Como Data Scientist normalmente sólo la usarás como forma de conexión con Pandas mediante &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;create_engine&lt;/code&gt; y &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;.to_sql()&lt;/code&gt; para extraer datos.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;sqlmodel&lt;/strong&gt; (Rk: 4085, ND: 90K, Pr: 2): Esta es una librería creada hace muy poco por el gran &lt;a href=&quot;https://www.linkedin.com/in/tiangolo/?originalSubdomain=de&quot;&gt;Sebastián Ramírez&lt;/a&gt; (Tiangolo). No he utilizado esta librería pero sí sé que está construida sobre sqlalchemy. &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;sqlmodel&lt;/code&gt; es a &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;sqlalchemy&lt;/code&gt; lo que &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;FastAPI&lt;/code&gt; es a &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Flask&lt;/code&gt;. Por lo tanto, es muy posible que en el tiempo esta librería venga a reemplazar a SQLAlchemy principalmente porque Tiangolo dedica mucho tiempo a la buena documentación y casos de usos, cosa que SQLAlchemy no tiene tan bien hecho en mi opinión.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;DBI&lt;/strong&gt; ((R), Pr: 1): DBI viene a ser una interfaz común para poder consultar datos. Creo que podría considerarse el símil de sqlalchemy, pero no sé si tiene tantas funcionalidades. Al menos esta siempre fue mi opción para conectarme a DBs en R, pero nunca me tocó modelar una base de datos como sí tuve que hacerlo en Python. DBI tiene conexión con casi todos los motores de SQL o usando conexión &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;odbc&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;PyMongo&lt;/strong&gt; (Rk: 185, ND: 16.8M+, Pr: 2): Esta es la interfaz para utilizar MongoDB desde Python. MongoDB es probblemente la base de datos no relacional más famosa. Sólo vale la pena si es que te toca trabajar con MongoDB pero lo bueno es que su uso es sumamente intuitivo. Utiliza la misma sintaxis que MongoDB pero en vez de usar el formato BSON (que es como un tipo de JSON), lo hace en los diccionarios de Python. Y por cierto, hacer queries en MongoDB es básicamente SQL con otra sintaxis y permitiendo data no estructurada como output, por lo que aprenderla es bastante sencillo.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;elasticsearch-dsl&lt;/strong&gt; (Rk: 732, ND: 2.4M+, Pr: 2): Este no es la librería más popular para conectarse a ElasticSearch, que es un motor de base de datos basado en documentos que es extremadamente rápida. La sintaxis en ElasticSearch es horrible, y yo reconozco que no tengo idea como extraer datos usando ElasticSearch puro. El tema es que elasticsearch-dsl es tan intuitivo que pude generar procesos de ETL en ElasticSearch utilizando esta librería, ya que su API es como estilo dplyr (aunque es una librería de Python), lo que le permite ser muy expresiva y fácil de crear, leer y entender. Si alguna vez tienes que trabajar con ElasticSearch, usa esta librería ya que es muchísimo más sencilla.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;psycopg2&lt;/strong&gt; (Rk: 194 y 99, ND: 31M + 15M, Pr: 0): El Ranking de esta librería es un poco extraño, la razón es porque si utilizas Windows descargas psycopg2, pero si tienes Mac o Linux descargas psycopg2-binary, por lo que en estricto rigor esta librería es la suma de ambos. Este es el cliente de Postgresql en Python, un motor de base de datos extremadamente popular y poderoso. Es una interfaz muy parecida a DBI en R. Es un cliente lowlevel y bien rápido para poder interactuar con DBs Postgres. Yo la he utilizado como motor tanto para DBs Postgres Puras o para Datawarehouse como Redshift que están basadas en Postgres. Además se puede conectar con &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;sqlalchemy&lt;/code&gt;, por lo que diría que no es necesario aprender mucho su sintaxis porque saber &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;sqlalchemy&lt;/code&gt; ya hace la pega.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;pyodbc&lt;/strong&gt; (Rk: 161, ND: 19M, Pr: 0): Es una librería que nos permite hacer conexiones ODBC. Esta librería la usé únicamente en Windows para conectarme con Teradata que es un motor de Base de Datos que suele ser utilizado en entornos de alta seguridad como Bancos o Retail (mi recomendación: no usen Teradata, funciona bien, es rápido y todo pero su documentación al no ser código abierto es pésima, por lo que cosas fáciles se pueden hacer pero encontrar cómo hacer algo fuera de la común es casi imposible. Se los dice alguien que lo usó por 5 años). Normalmente se utiliza una línea para conectarse y es compatible con &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;sqlalchemy&lt;/code&gt;, por lo que no es necesario aprender mucho.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Neo4J&lt;/strong&gt; ((O), Pr: 2): Debo decir que este tipo de bases de Grafo cambió demasiado mi manera de ver el almacenamiento de datos. Creo, luego de pelear con hartos motores de datos no estructurado que, este es la manera más sencilla de interactuar con datos NoSQL. Entre sus grandes pro está el hecho de que su sintaxis es muy fácil de aprender (parecida a SQL, pero no igual), es rápido, y no requiere joins.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;rasterio&lt;/strong&gt; (Rk: 1454, ND: 749K+, Pr: 0): Esta es una librería para trabajar con rasters. Rasters son las típicas imágenes donde cada píxel está representado como un valor en una matriz/tensor. En el caso de rasterio, tiene más utility functions para trabajar con imágenes satélitales pero en general se utiliza como complemento a otras librerías. Normalmente se utiliza una que otra función.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Xarray&lt;/strong&gt; (Rk: 1454, ND: 749K+, Pr: 0): No sé si saben pero antiguamente pandas (que deriva de PAnel DAta ), tenía data panel, que es son varias realizaciones en el tiempo de un DataFrame, o sea un Pandas de 3 dimensiones. Bueno eso hace un tiempo se quitó de pandas y si querías más de 3 dimensiones necesitabas Numpy. Bueno Xarray permite la data panel, 3 Dimensiones, pero con nombre del nombres de array. Es una extensión que permite por ejemplo trabajar mejor con Imágenes Multiespectrales (ya que queda capa tiene un significado: RGB, Infrarrojo Cercano, Infrarrojo Lejano, etc.) y normalmente se combinan para poder crear índices y falsos colores para destacar ciertos aspectos de la imágen. Es una librería súper específica, por lo que sólo será útil cuando necesites trabajar con este tipo de datos.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Geopandas&lt;/strong&gt; (Rk: 733, ND: 2.4M+, Pr: 2): Esta es una extensión de Pandas, que incluye dos cosas interesantes a mi gusto, el incorportar shapes: Puntos, Polígonos, etc. Y el hecho de tener joins espaciales. De esta manera puedes combinar datasets si es que comparten mismo espacio, por ejemplo: Tienes puntos (coordenadas) de casas en un csv y tienes polígonos de regiones en otro csv. Al hacer join espacial, unirá los registros de casas que están dentro del polígono región igual que un join. El tema es que hay varios tipos de join espaciales: dentro, que colinden, que se intersecten, etc. Excelente librería, y no muy dificil de aprender.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Scikit-Image&lt;/strong&gt; (Rk: 325, ND: 8.6M+, Pr: 0): Esta es una librería de manipulación de Imágenes, muy parecida a OpenCV. Yo la usé una sola vez para intentar reconstruir una foto que rompí por error. Bien intuitiva tiene muchas built-in functions para manipular imágenes.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Spacy&lt;/strong&gt; (Rk: 475, ND: 5.1M+, Pr: 0): Esta es una tremenda librería para lidiar con texto libre. Tiene modelos pre-entrenados muy buenos en muchos idiomas para llegar y utilizar. Yo la usé una sóla vez porque en Cenco teníamos info sucia de muchas empresas (y querían sacar promociones en la tarjeta, o algo así): “Hipermercados Lider”, “Supermercado Lider”, “Falabella” , “Tiendas Falabella”. Entonces hicimos un Name Entity Recognition para encontrar nombres de potenciales Comercios donde compraba la gente para poder ofrecer descuentos al sacar la tarjeta Cencosud. Por ejemplo, ellos tenían descuentos en Cine, y nadie y usaba la tarjeta para ir al cine. Pero sí la usaban para Uber, entonces querían cambiar la estrategia a ofrecer no sé 10 lucas en Uber o algo así. Aprendí lo que necesitaba en una tarde porque su documentación es excelente.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;DBeaver&lt;/strong&gt; ((O), Pr: 2): Esta es un cliente de bases Open Source gratis (aunque también tiene una versión pagada). Básicamente es un software que puedes descargar que te permite conectarte a cualquier Base de Datos SQL y muchos otros. Entre los motores disponibles están: Postgresql, MySQL, Hive, ElasticSearch, Redshift, Snowflake y Neo4J entre otros. Además, en la versión paga te permite conectarte a MongoDB. Es rápido, tiene posibilidad de tener los modelos ER de cada Esquema además de varios atajos de teclado. Muy buena opción para conectarse con distintos motores.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;visualizaciones&quot;&gt;Visualizaciones&lt;/h1&gt;

&lt;p&gt;Esta es probablemente mi parte más débil principalmente porque es un área que no me gusta. Aún así he usado varias librerías, las cuales voy a mencionar ahora.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Seaborn&lt;/strong&gt; (Rk: 310, ND: 9M+, Pr: 1): Probablemente no esperaban que esta fuera mi primera opción. La razón por la que la menciono en primer lugar es porque es una librería con funcionalidades restringidas pero que hace la pega muy bien. Tiene la mayoría de gráficos prehechos y permite sin mucho código hacer gráficos muy bonitos y muy expresivos. Mi recomendación es sólo aprender &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;sns.catplot()&lt;/code&gt; que permite graficar gráficos de variables categóricas o combinación categórica numérica (conteos, barplots, boxplot y amigos, etc.), &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;sns.relplot()&lt;/code&gt; que permite generar gráficos para variables sólo númericas (scatter, lineplots) y &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;sns.displot()&lt;/code&gt; que grafica básicamente histogramas. Estas 3 funciones tienen interfaz comunes con built-in facet y varias manera de agrupación (columnas, filas, colores, estilos, etc.). Una de las cosas que más me entusiasma es que Seaborn comenzó a desarrollar una interfaz muy similar a &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;ggplot2&lt;/code&gt; de R lo cual la haría extremadamente flexible y fácil de usar. Definitivamente vale la pena aprenderla.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Matplotlib&lt;/strong&gt; (Rk: 110, ND: 26.9M+, Pr: 1): Yo creo que el ranking es un poco mentiroso, principalmente porque matplolib es dependencia de casi todas las librerías de gráficos, por lo que siempre la vas a necesitar. Lamentablemente hay que aprenderla. Y digo lamentable, porque a pesar de ser muy poderosa, considero que la documentación es como engorrosa y tiene una sintaxis muy verbosa. Además &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;seaborn&lt;/code&gt; está construida sobre &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;matplotlib&lt;/code&gt;, por lo que en casos de querer cambiar elementos del layout en &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;seaborn&lt;/code&gt; se debe hacer mediante comandos &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;matplotlib&lt;/code&gt;. Mi recomendación es aprenderla con ejemplos y algún cursito corto en Datacamp, porque es realmente difícil de aprender (no por su sintaxis sino que porque tiene muchas maneras distintas de hacer lo mismo y que a veces aplican y otras veces no). Igual me he dado cuenta que la termino usando más que Seaborn.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;ggplot2&lt;/strong&gt; ((R), Pr: 1): Para muchos es la mejor librería de visualizaciones que existe. Y quizás tienen razón. &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;ggplot2&lt;/code&gt; es un remake de ggplot (que fue un fracaso) y que está basado en el grammar of graphics que es un concepto en el cual las partes del gráfico se construye en capas (la figura; ejes; elementos como puntos, líneas, boxplots; cálculos como regresiones lineales, promedios, intervalos de confianza; etc.) Además como que por defecto la paleta de colores y los ejes son bien bonitos. Yo considero que no es tan fácil de aprenderla pero es la mejor sintaxis para graficar.
Existen algunas librerías/addins en RStudio como &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;esquisse&lt;/code&gt; que permiten crear ggplots (te entrega el código incluso) con una interfaz tipo Tableau. Muy recomendada si trabajas en R y/o en Python. Además tiene un enorme ecosistema de librerías complementarias para poder graficar casi cualquier cosa.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;plotnine&lt;/strong&gt; (Rk: 2473, ND: 232K+, Pr: 0): Es la versión en Python de ggplot2. Creo que es un tremendo esfuerzo y casi todas las funcionalidades están implementadas pero no funciona tan bien como ggplot2 (su ranking lo indica). El problema es que ggplot2 tiene muchos paquetes que lo complementan. Uno de los más poderosos es &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;patchwork&lt;/code&gt; que es una interfaz para crear gráficos sobre gráficos de manera muy sencilla. Este es precisamente uno de las grandes problemáticas de plotnine, si se quieren crear layouts un poco más complejos comenzamos nuevamente a depender de &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;matplotlib&lt;/code&gt; lo que evita una sintaxis única. Gracias a ver visto un EDA por &lt;a href=&quot;https://www.linkedin.com/in/martin-henze/&quot;&gt;Martin Henze&lt;/a&gt; utilizando ggplot comencé a usar esta librería pensando que podría lograr los mismos resultados, pero lamentablemente ggplot es &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;muy superior&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;alert-box info radius &quot;&gt;&lt;p&gt;En mi opinión el 90% del tiempo utilizar gráficos estáticos será más que suficiente tanto para compartirlos en un PPT o para hacer EDAs. En caso de crear alguna aplicación interactiva entonces gráficos dinámicos e interactivos como los que hacen las siguientes librerías son una buena opción.&lt;/p&gt;
&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;plotly&lt;/strong&gt; (Rk: 359, ND: 7.5M+, Pr: 0): Plotly es una librería basada en D3, que a su vez es una librería de Javascript que se hizo muy popular gracias a su capacidad de desarrollar gráficos interactivos muy bonitos. Hoy tiene APIs en casi todos los lenguajes más populares. Para mí gusto es una librería que sólo vale la pena aprender si es que estás completamente dedicado a las visualizaciones. Si bien es una librería poderosa es muy verbosa. Afortundamente paquetes como &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;plotly-express&lt;/code&gt; han aparecido para abstraer la verbosidad y crear versiones de gráficos comúnmente usados en pocas líneas.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;plotly-express&lt;/strong&gt; (Rk: 2936, ND: 181K+, Pr: 2): Es la versión menos verbosa de plotly, si bien es un pelín menos poderosa debido a que es más simple, la mayor parte del tiempo será maś que suficiente. No entiendo por qué no es tan popular aún.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;altair&lt;/strong&gt; (Rk: 360, ND: 7.4M+, Pr: 0): Es otra librería muy parecida a Seaborn en términos de sintaxis pero con la interactividad de plotly. Yo la utilicé sólo una vez creando una app en Streamlit. La razón: no quería usar plotly (en ese tiempo no conocía plotly express) y quedaban los gráficos más bonitos que en matplotlib y seaborn que eran estáticos. No vale la pena aprenderla y rara vez la verán por ahí.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;bokeh&lt;/strong&gt; (Rk: 674, ND: 1.8M+, Pr: 0): Es otra librería proveniente de Javascript que puede ser usadas desde R o Python. La verdad es que no la he usado, pero pueden ser alternativas para plotly ya que también son interactivas basadas en HTML pero con una sintaxis más simple. Nuevamente las recomiendo sólo en caso de dedicarse el BI o al Data Storytelling donde vale la pena invertir en visualizaciones llamativas.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;otras-herramientas-bi&quot;&gt;Otras herramientas BI&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Tableau&lt;/strong&gt; ((O), Pr: 2): En el caso de trabajar en Business Intelligence donde el foco es más mostrar herramientas interactivas que puedan manipular la data con algunos clicks, aparecen herramientas que no están basadas en código. Tableau es una muy buena alternativa. Es rápido, fácil de crear Dashboard con gráficos que sirven como filtros y pueden interactuar entre ellos. El problema, es que su costo es prohibitivo, su licencia es extremadamente cara y hoy existen otras herramientas más baratas que hacen lo mismo.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;PowerBI&lt;/strong&gt; ((O), Pr: 2): Es el Tableau de Microsoft. Es una buena alternativa con costos de licencias bastante más bajo. Sigue la misma idea de Tableau de usar cajitas tipo Pivot Tables para crear gráficos. Igual de eficiente que Tableau pero mucho más barato.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Qliksense&lt;/strong&gt; ((O), Pr: 2): No recuerdo quien creó esto, pero es otra versión. Funciona exactamente igual que los otros dos. Tienen las mismas funcionalidades. Ninguna ventaja ni desventaja con los otros.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;alert-box tip radius &quot;&gt;&lt;p&gt;¿Cuál elegir? Da lo mismo, es lo que tu empresa esté dispuesta a pagar.&lt;/p&gt;
&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Shiny&lt;/strong&gt; ((R), Pr: 1): Podríamos decir que es la versión en R de estos productos. La diferencia es que es gratis, y es basado completamente en código. Permite crear todo tipo de Dashboards interactivos mezclando cualquier otra librería de R (aunque también se podría agregar Python mediante &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;reticulate&lt;/code&gt;) tanto para manipular datos como para visualizar. Es extremadamente poderosa y flexible y hay varias empresas que crean sus portales utilizando Shiny. El problema es que no es tan fácil de hostear. En mi tiempo sólo RStudio ofrecía servicios para hostear ShinyApps (algunos gratis y otros de pago). Lo bueno es que se comenzó a crear todo un ecosistema en torno a &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Shiny&lt;/code&gt;, el cual tiene temas (basados en Bootstrap, material y otros frameworks de HTML, CSS y Javascript). Además, hay una librería llamada &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;golem&lt;/code&gt;, que permite modularizar grandes aplicaciones e incluso se permiten ingresar elementos nativos en HTML, CSS o Javascript. Vale completamente la pena aprenderlo &lt;mark&gt;si es que&lt;/mark&gt; te dedicas al BI en R y tienes tiempo de crear todo desde cero. Va a ser más flexible que Tableau, PowerBI o Qliksense, pero hay que crear todo.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;streamlit&lt;/strong&gt; (Rk: 1361, ND: 853K+, Pr: 1): Similar a Shiny pero en Python. En mi opinión es mucho más sencillo de utilizar, pero mucho más simplista. Tiene lo justo y necesario para hacer funcionar una excelente aplicación demo. Lo bueno es que Streamlit fue comprado por HuggingFace por lo que se ha estado llevando sus funcionalidades para que sea el front-end de modelos de Machine Learning. Una ventaja de streamlit es que es fácilmente hosteable en cualquier servidor con Python (que son casi todos), en Heroku, en un servicio provisto por la misma gente de Streamlit o en Huggingface Spaces, siendo estos últimos totalmente gratis. En el caso de querer hacer una demo, se puede crear algo de gran calidad y complejidad en no más de una hora. Su sintaxis es muy sencilla y se puede aprender en unas horas.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Dash&lt;/strong&gt; (Rk: 1380, ND: 830K+, Pr: 0): Este es casi idéntico a Shiny (pero también en Python). Yo lo usé sólo una vez en un proyecto, y no nos gustó porque era muy complicado de setear. Básicamente crear el CSS que dejara los distintos divs en orden fue un martirio por lo que siempre nos quedaba la aplicación descuadrada. No vale la pena, ya que streamlit simplificó esto infinitamente.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Gradio&lt;/strong&gt; (Rk: 3187, ND: 148K+, Pr: 2): Es una interfaz aún más simple que Streamlit, pero con muchas menos funcionalidades. Esta librería sí que se creó con el sólo propósito de ser un IO para modelos de Machine Learning. A diferencia de Streamlit que puedes crear Dashboards, sitios webs, agregar gadgets, Gradio sólo le interesa crear gadgets de input/output para un modelo a modo de demo. Yo lo probé rápidamente y lo encontré muy fácil. Decidí aprenderlo luego de ver una demo de un Pipeline de Transformers por Omar Sanseviero, donde construyó un front-end con modelos de Generación de Texto y Machine Translation en 10 mins. Puedes ver su presentación &lt;a href=&quot;https://www.youtube.com/watch?v=Mg7YeWBUKbM&quot;&gt;acá&lt;/a&gt;. Vale mencionar que también fue adquirido por HuggingFace por lo que puedes hostearlo facilmente en servidores Python, Heroku o Spaces. La gran ventaja de Gradio es que permite hostear de manera gratuita desde cualquier computador por dos días. Una vez se acabe puedes volver a levantar el servicio, el cual permite el frontend y una API en FastAPI creada automáticamente.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Django&lt;/strong&gt; (Rk: 357, ND: 7.5M+, Pr: 0): No lo he usado. Pero es por lejos la librería más poderosa de desarrollo Web. Acá ya no hablamos sólo de una interfaz de Dashboards sino que un software completo. Es tanto así que existen Ingenieros de Software especializados sólamente en el Ecosistema Django. Por nada del mundo como Data Scientist debieras tener que llegar a usar una librería tan poderosa como esta. Pero si te interesa crear una aplicación a nivel profesional con procesos de datos o Modelos de Machine Learning por abajo, esta podría ser una opción. Algunas aplicaciones creadas en Django son Instagram, Spotify, Youtube, Dropbox, entre otras.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Flask&lt;/strong&gt; (Rk: 88, ND: 35.9M+, Pr: 0): Tampoco lo he usado, pero tengo entendido que es un Django pequeñito, que además tiene otras funcionalidades como crear APIs. Es aún extremadamente popular en entornos de desarrollo web, pero en mi opinión está poco a poco cayendo en desuso, principalmente debido a que FastAPI está ganando mucho protagonismo en cuánto a APIs se refiere y es una opción mucho más sencilla de aprender.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;machine-learning&quot;&gt;Machine Learning&lt;/h1&gt;

&lt;p&gt;Esta es por lejos mi sección favorita, por lo que puede que me extienda un poco más de que el resto.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Scikit-Learn&lt;/strong&gt; (Rk: 94, ND: 32.6M+, Pr: 1): Es la librería por excelencia para crear modelos de Machine Learning. La sintaxis de su API está tan bien diseñada que una manera de reconocer que otras librerías de Machine Learning son confiables es si es que siguen su API. Básicamente &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;scikit-learn&lt;/code&gt; es super reconocida por sus modelos como Clase y su estandar &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;fit-transform-predict&lt;/code&gt;, además de casi 15 años de vida. Si quieres hacer modelos de Machine Learning sí o sí tienes que partir por acá por varias razones: (1) Su documentación es excelente, incluso puedes aprender la teoría detras de cada modelo leyendo su &lt;a href=&quot;https://scikit-learn.org/stable/user_guide.html&quot;&gt;User Guide&lt;/a&gt; (toda persona que se dedique al ML debería leer la documentación completa de Sklearn una vez al año 🤪). Además contiene sólo modelos ML que están en el estado del arte. De hecho para que un modelo se implemente en Scikit Learn tiene que cumplir &lt;a href=&quot;https://scikit-learn.org/stable/faq.html&quot;&gt;requisitos&lt;/a&gt; muy estrictos. Andreas Mueller, mantenedor de Scikit-Learn tiene un curso disponible de manera gratuita &lt;a href=&quot;https://www.youtube.com/watch?v=d79mzijMAw0&amp;amp;list=PL_pVmAaAnxIRnSw6wiCpSvshFyCREZmlM&quot;&gt;acá&lt;/a&gt;. Este es por lejos una de las mejores inversiones que uno hará como Data Scientist, ya que aprendiendo a utilizar esta librería podrás utilizar millones de otras basadas en la misma API. &lt;a href=&quot;/titanic/&quot;&gt;Acá&lt;/a&gt;un ejemplo de modelamiento en Scikit-Learn.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;tidymodels&lt;/strong&gt; (R, Pr: 2): Yo solía ser un fan de esta compilación de librerías. Creo que Max Kuhn es un tremendo desarrollador y lo respeto profundamente, pero creo que parsnip trató de llevar el modelamiento en R a un estado incluso más flexible que &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;scikit-learn&lt;/code&gt; pero no les funcionó. Lamentablemente el Machine Learning en R está disgregado en muchas librerías todas con APIs diferentes, por lo que este esfuerzo de unificar todo es increíble. Lamentablemente el memory leakage que sufre R y el tremendo trabajo de los mantenedores de &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;scikit-learn&lt;/code&gt; hacen que un esfuerzo como este nunca logre la popularidad que tiene Python en este rubro. Tidymodels está basado en 3 paquetes principalmente: &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;recipes&lt;/code&gt;, para el preprocesamiento, que a mi gusto tiene una API muy similar a los Pipelines de Scikit, &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;parsnip&lt;/code&gt;, que es la unificación de todos los modelos de ML implementados en R y &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;yardstick&lt;/code&gt; que contiene todas las métricas de evaluación. Si te dedicas a hacer modelos pequeñitos de prueba, sin mucho intensidad de cómputo es una opción, en cualquier otro caso vale más cambiarse a &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;scikit-learn&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;caret&lt;/strong&gt; (R, Pr: 2): Este es el predecesor de &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;tidymodels&lt;/code&gt;. A pesar de ser una librería que se le quitó mantenimiento hace un tiempo sigue disfruntando de mucha popularidad ya que tiene más de 200 modelos implementados. El propósito de Caret es el mismo de tidymodels sólo que su API no era compatible con el tidyverse por lo que decidieron seguir el esfuerzo de tidymodels. Este proyecto contaba con todo integrado, preprocesamiento, entrenamiento, postprocesamiento, esquemas de validación, métricas de evaluación, incluso ensambles. Por alguna razón lamentablemente decidieron cortarlo.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;pycaret&lt;/strong&gt; (Rk: 1940, ND: 432K+, Pr: 2): Este es un proyecto en Python que nace de la base de Caret y que se ha hecho extremadamente popular. En mi opinión sólo vale la pena aprenderlo si es que no te gusta codear. Las ventajas es que permite hacer mucho en pocas líneas de código y es compatible con muchas librerías externas como XGBoost, LightGBM, etc. Además cuando uno no es experto en tareas menos habituales como Anomaly Detection o Series de Tiempo permite seguir el mismo esquema de código. Lo que me gusta del creador de esta librería es que él deja muy en claro que su objetivo que es que los Citizen Data Scientist pueden tener modelos de alta calidad a la mano. Creo que están haciendo un tremendo trabajo y he visto muchos Notebooks en Kaggle que lo usan y obtienen muy buenos resultados.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Feature Engine&lt;/strong&gt; (Rk: 3096, ND: 99K+, Pr: 1): Para mí esta es una librería de primerísima calidad. Tiene muy buen mantenimiento y tiene muchísimos mejores preprocesamiento que Scikit-Learn y además implementados en DataFrames. Contiene muchos de los excelentes encoders que tenía Category Encoders y además un Wrapper que permite convertir los preprocesadores de Scikit para que devuelvan pandas DataFrames en vez de Numpy Arrays. Espero que gane más popularidad, yo al menos la uso mucho.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;category-encoders&lt;/strong&gt; (Rk: 814, ND: 2M+, Pr: 0): Esta solía ser mi librería de encoders por defecto, pero dejó de mantenerse porque los mantenedores se cansaron. En su momento fue muy buena y todavía tiene mucha popularidad. Particularmente encontré un par de issues que reporté pero se demoraron casi un año en corregirlo. Una pena.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;statsmodels&lt;/strong&gt; (Rk: 294, ND: 9.6M+, Pr: 2): Si trabajas en Estadística en Python esta es la librería. Yo no soy muy fan de los modelos estadísticos, pero igualmente creo que es una librería interesante, porque también contiene muchas herramientas para trabajar con series de tiempo. En caso de necesitar mucho poder estadístico, creo que R es mucho más potente acá.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;XGBoost&lt;/strong&gt; (Rk: 320, ND: 8.8M+, Pr: 1): Uno de los problemas que Scikit-Learn solía tener es que no tenía una buena implementación de algoritmos de Gradient Boosting (hoy tiene una buena implementación de HistGradientBoosting similar a LightGBM) y XGBoost quizás es la implementación más famosa que hay. Desde el 2014 viene dominando por lejos el modelamiento en data tabular y definitivamente es un algoritmo que hay que dominar. Si bien es cierto su performance es superior, llegar a esa performance es difícil de lograr, ya que hay que hacer un buen afinamiento de Hiperpárámetros. Definitivamente un algoritmo que hay que aprender.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;LightGBM&lt;/strong&gt; (Rk: 393, ND: 6.5M+, Pr: 1): Me llama la atención que tenga menos descargas. Porque LightGBM para mí supera a XGBoost, por poco pero lo supera. En general para todas las competencias en la que he estado y modelos en producción que he dejado siempre obtengo mejor performance con LightGBM. Esta es una implementación liberada por Microsoft en 2016, y en mi opinión es bastante más rápido que XGBoost y menos complicado de afinar Hiperparámetros. El problema es la instalación, las docs de instalación son malitas, y la versión con GPU es bien enredada de instalar. Definitivamente, hay que tenerlo en el arsenal.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;CatBoost&lt;/strong&gt; (Rk: 747, ND: 2.3M+, Pr: 1): Otro Gradient Boosting que está muy de moda. En mi opinión es el algoritmo más fácil de afinar. Casi no hay que mover los Hiperparámetros para obtener muy buenos resultados. Es fácil de instalar, pero en velocidad es similar a XGBoost. Creo que el único problema que le he visto es que cuando guardas el modelo es muy pesado. Por ejemplo, una vez entrené los 3 Boosting (típico en Kaggle) y no sé, XGBoost y LightGBM pesaban del orden de megas mientras que CatBoost pesaba 11 GB, no sé si habré hecho algo mal, pero encontré que era muy pesado. El otro contra (no tan contra), es que siempre queda fuera de los frameworks, y la API es un poquito diferente a Scikit. (XGBoost y LightGBM tienen versiones con API de Scikit). Definitivamente hay que aprenderlo.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;alert-box info radius &quot;&gt;&lt;p&gt;Lo bueno de los 3 grandes Boosting es que todos tienen Early Stopping y permiten el uso de un set de Validación mietras se entrena, igual que los algoritmos de Deep Learning.&lt;/p&gt;
&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;DeepChecks&lt;/strong&gt; (Rk: NA, ND: NA, Pr: 2): Yo no lo he usado aún en mis pegas, pero he hecho pruebas y revisado a fondo la documentación y creo que es una excelente librería para estudios previos de la data (chequear potenciales drifts y el potencial poder de generalización de un modelo) y para monitoreo. Permite realizar distintas validaciones para entre tu set de entrenamiento y tu data real, o test set para chequear que el modelo funciones bien en el tiempo.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Mapie&lt;/strong&gt; (Rk: NA, ND: NA, Pr: 2): Excelente librería para aplicar Conformal Prediction, es decir, se pueden generar predicciones con intervalos de confianza en Regresión y Clasificación probabilística para modelos de clasificación. Lo bueno es que es solo un wrapper y es Scikit-Learn compatible. Tuve la oportunidad de estudiar la documentación a fondo y es realmente la manera de generar modelos robustos en especial cuando hay mucha incertidumbre.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;mlxtend&lt;/strong&gt; (Rk: 1024, ND: 1.4M+, Pr: 2): Tremenda librería creada por Sebastian Raschka, profesor de Wisconsin Madison y parte de Lightning AI. Es un complemento a Scikit-Learn y tiene varios elementos que permiten extender las capacidad de Scikit. En particular rescato las herramientas para ensambles tipo Stacking. Muy necesaria si quieres competir, y si quieres un modelo ensamblado.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;pyGAM&lt;/strong&gt; (Rk: 2237, ND: 325K+, Pr: 0): Es una librería que hace modelos GAM (Generalized Additive Models). Estos modelos son famosos por ser la mejor mezcla entre buena predicción y buena explicabilidad. Quizás el modelo GAM más conocido es &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;prophet&lt;/code&gt; de Meta. En general esta librería no me gustó, y si es que realmente quieres meterte en este tipo de modelos mejor utilizar &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;mgcv&lt;/code&gt; en R que es años luz más maduro. No creo que valga la pena aprenderlo.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;CuML&lt;/strong&gt; (Rk: NA, ND: NA, Pr: 0): Esta es una librería que está aún en desarrollo por parte de NVIDIA, pero es la parte de ML de cuDF y cuPY. Es un mirror de Scikit-Learn, pero que corre en GPU. En especial algoritmos como Random Forest y SVM pueden verse muy beneficiados. No creo que valga la pena aprenderlo, porque es lo mismo que Scikit-Learn.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Imbalanced-Learn&lt;/strong&gt; (Rk: 650, ND: 3M+, Pr: 0): Es la librería por excelencia para desbalance de clases. Lo bueno es que incluye técnicas de undersampling, oversampling, SMOTE y algoritmos propios que funcionan con desbalance como RUSBoost y BalancedRandomForest. Debo confesar que casi nunca obtengo mejores modelos utilizando estas estrategias, y no me ha tocado usarlo aún, pero normalmente utilizando el parámetro sample_weigths de cualquier modelo de Scikit-learn podría funcionar mejor.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Shap&lt;/strong&gt; (Rk: 530, ND: 4.1M+, Pr: 1): Es hoy quizás la librería más poderosa para dar explicabilidad. Existen varios spin-offs enfocados en problemas específicos pero creo que es algo que todos deberíamos dominar porque al negocio siempre le interesa entender por qué un modelo predice lo que predice.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;ELI5&lt;/strong&gt; (Rk: 1022, ND: 1.4M+, Pr: 2): Otra opción para la explicabilidad de modelos. No lo he usado pero solía ser la librería por defecto antes que apareciera el boom de los shap values.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Implicit&lt;/strong&gt; (Rk: 2761, ND: 207K+, Pr: 2): Librería de Factorization Machines para modelos de recomendación Implicita. Esta la usé una vez para una prueba de Concepto en Cencosud. Fácil de usar, buenos tutoriales, me gustó. No tengo más que decir, porque fue “el uso” que le dí.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Surprise&lt;/strong&gt; (Scikit-Surprise) (Rk: 2860, ND: 195K+, Pr: 2): No alcancé a usarla, porque en la misma Prueba de Concepto anterior me dí cuenta que teníamos un recomendador implícito y Surprise es para modelos explícitos. Para tenerlo en cuenta.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;LightFM&lt;/strong&gt; (Rk: 1920, ND: 441K+, Pr: 2): Esta fue la librería que terminé utilizando, debido a su rápidez. Recuerdo que en ese momento no pude sacarle todo el potencial porque funciona mejor en entornos Unix y obvio, nos obligaban a usar Windows. También para tenerla en cuenta.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;H2O&lt;/strong&gt; (Rk: 1954, ND: 428K+, Pr: 2, (R)): Es una librería que está tanto en Python como en R que por detrás corre una JVM. Es la librería en CPU más rápida que he visto. Yo sólo la ví en curso en R con Erin Ledell. Es buena para hacer cosas rápido. Además posee AutoML y Stacking, para los que les guste algo rápido con poquito código.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Prophet&lt;/strong&gt; (Rk: 1367, ND: 848K+, Pr: 2): Hace poco hubo un escándolo porque la empresa Zillow hizo un uso indiscriminado de Prophet entrenando modelos sin entender y eso le significó un impacto muy negativo (pueden leer más al respeco &lt;a href=&quot;https://towardsdatascience.com/in-defense-of-zillows-besieged-data-scientists-e4c4f1cece3c&quot;&gt;acá&lt;/a&gt;). Pero si se le da un uso correcto, creo que es una tremenda librería. Es fácil de usar y tienen muchas ventajas. Konrad Banachewicz está haciendo un curso de series de tiempo en el canal de &lt;a href=&quot;https://www.youtube.com/channel/UCBPRJjIWfyNG4X-CRbnv78A&quot;&gt;Abishek Thakur&lt;/a&gt; y habló sobre este modelo, y la verdad lo encontré muy interesante. Úselo con precaución y bajo su propio riesgo.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Neuralprophet&lt;/strong&gt; (Rk: 4635, ND: 68K+, Pr: 2): Spin-off de Prophet pero utilizando algoritmos de Redes Neuronales. Mismo cuidado que con prophet.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Sktime&lt;/strong&gt; (Rk: 2739, ND: 211K+, Pr: 2): Es una extensión de Scikit-Learn para modelos aplicados a Series de Tiempo. Tiene algoritmos propios para clasificación (de series de tiempos, o sea clasificar un secuencia), regresión, forecast (no es lo mismo que regresión), anomaly detection y tiene varios CV propios de series de tiempo. Yo no la usé propiamente tal, pero aprendí mucho leyendo su documentación, en especial para entender la diferencia entre forecast y regresión. Además posee un transformer que permite convertir modelos de forecasting en Regresión. Muy buena librería si trabajas con series de tiempo.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Skforecast&lt;/strong&gt; (Rk: NA, ND: NA, Pr: 2): Muy similar a sktime pero creada por Joaquin Amat, un data scientist español. Creo que siempre el trabajo en español tiene que ser destacado.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;TSFresh&lt;/strong&gt; (Rk: 1888, ND: 456K+, Pr: 2): Yo utilicé esta librería como herramienta de feature extraction para series de tiempo. Posee una función &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;extract_features&lt;/code&gt; que permite crear muchísimas features para series de tiempo. Muy buena librería.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Lifetimes&lt;/strong&gt; (Rk: 1473, ND: 731K+, Pr: 2): Librería especializada en Survival Models. Los modelos de sobrevivencia son modelos que buscan estimar el tiempo a un evento. Lo utilicé en la competencia de Mercado Libre, pero no me dió muy bueno así que seguí por otro lado. Es bueno tenerlo como alternativa para tipos de modelación no tan comunes.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Boruta-Shap&lt;/strong&gt; (Rk: NA, ND: NA, Pr: 0): Es una librería muy pequeñita que permite utilizar el algoritmo Boruta más Shap Values para Feature Selection. Por defecto utiliza un Random Forest para escoger las variables más importantes, pero yo lo utilicé con XGBoost y LightGBM en GPU y funciona bastante bien.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;LOFO&lt;/strong&gt; (Rk: NA, ND: NA, Pr: 0): Es otra librería de Feature Selection. En este caso la ventaja que ofrece sobre Boruta Shap es que se realiza una selección utilizando un modelo específico pero en un esquema de Cross Validation. Esta la utilicé en una competencia que tenía muchas variables anónimas, y funcionó bastante bien.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Optuna&lt;/strong&gt; (Rk: 613, ND: 3.2M+, Pr: 1): Es probablemente la mejor librería de optimización que hay hoy. Originalmente permite resolución de algoritmos de Optimización (min, max, minmax). Pero su gran fortaleza es que permite la implementación de algoritmos Bayesianos de búsqueda compatibles con modelos de Machine Learning y Deep Learning (agregando Pruning, que permite terminar la búsqueda en espacios poco prometedores). Es obligación aprender a utilizarla, 100-200 iteraciones de Optuna es equivalente a una búsqueda gigantesca en GridSearch o RandomSearch.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Scikit-Optimize&lt;/strong&gt; (Rk: 613, ND: 3.2M+, Pr: 0): No lo he usado, pero es competidor directo de Optuna. No sé mucho más pero creo que era necesario mencionarlo.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Hyperopt&lt;/strong&gt; (Rk: 809, ND: 3.2M+, Pr: 0): Idem al anterior.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Scikit-plot&lt;/strong&gt; (Rk: 1756, ND: 520K+, Pr: 0): Es en estricto rigor una librería de visualizaciones, pero sólo tiene visualizaciones asociadas a Machine Learning. Es muy sencillo de usar y con un comando permite graficar matrices de confusión, curvas ROC, curvas Precision-Recall, Curvas de Aprendizaje, Silhouette, Curvas de Calibración, etc. Yo comencé utilizandola porque antes los Plot de Scikit-Learn quedaban muy feos. Esto está muy mejorado actualmente y recomendaría utilizar este tipo de librerías sólo para curvas muy específicas.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Yellowbrick&lt;/strong&gt; (Rk: 1659, ND: 578K+, Pr: 0): Para mí, hace y tiene exactamente lo mismo que Scikit-Plot. No recuerdo por qué comencé a usar Scikit-Plot por sobre esta.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;deep-learning&quot;&gt;Deep Learning&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Pytorch&lt;/strong&gt; (Rk: NA, ND: NA, Pr: 1): Es el framework de Deep Learning de Meta. Quizás esto es sorpresivo. Pero la razón por la que Pytorch no está en el Ranking es porque se recomienda su instalación via Conda. Para mí (y esto es muy sesgado), es la mejor librería de Deep Learning. Y la razón es porque te permite entender el funcionamiento de una red neuronal de mejor manera que con otros frameworks. El contra de Pytorch es que necesitas mucho código para entrenar principalmente, pero permite entender muy bien cuando hay que setear los gradientes a cero, en qué parte se evalúa la loss function, cuando haces backpropagation y actualizas los pesos. Además como te fuerza a utilizar clases permite mejorar tu programación orientada a objetos y su gran fuerte es la documentación, muy buena en términos de uso, pero también de teoría. Otro aspecto espectacular de Pytorch es que permite el desarrollo de spin-offs que mencionaré más tarde. ¿Es Pytorch perfecto? la verdad es que no. Como dije antes, es muy verboso y entrenar en Aceleradores es engorroso. Hay que estar consciente en todo momento de si tu tensor vive en CPU o GPU, hay que moverlo manualmente. No, es un cacho. Aún así, creo que es necesario hacer al menos un par de modelos en Pytorch Nativo, acá un &lt;a href=&quot;/pytorch-native/&quot;&gt;ejemplo&lt;/a&gt;. Si quieres iniciarte en Pytorch, lo mejor es partir por el 60 minutes &lt;a href=&quot;https://pytorch.org/tutorials/beginner/deep_learning_60min_blitz.html&quot;&gt;Blitz&lt;/a&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Pytorch-Lightning&lt;/strong&gt; (Rk: 692, ND: 2.7M+, Pr: 1): Pero afortunadamente existe Pytorch Lightning que soluciona todos los inconvenientes de Pytorch Nativo. Permite organizar mucho del excesivo código de Pytorch y tiene una API que permite escalar a GPUs, TPUs, IPUs y HPUs sin casi ningún cambio. Además permite la portabilidad del código, haciendo que un mismo módulo sea muy fácil de reutilizar casi sin latencia. Creo que definitivamente Lightning es la razón por la que me enamoré de Pytorch. Dentro de los mejores lugares para entender bien el funcionamiento de Pytorch Lightning está este el &lt;a href=&quot;https://pytorch-lightning.readthedocs.io/en/latest/expertise_levels.html&quot;&gt;level up&lt;/a&gt; y una serie de &lt;a href=&quot;https://pytorch-lightning.readthedocs.io/en/latest/notebooks/course_UvA-DL/01-introduction-to-pytorch.html&quot;&gt;tutoriales&lt;/a&gt; de la Universidad de Amsterdam y &lt;a href=&quot;https://pytorch-lightning.readthedocs.io/en/latest/tutorials.html&quot;&gt;otros más&lt;/a&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Tensorflow&lt;/strong&gt; (Rk: 181, ND: 17.2M+, Pr: 0): Es el primer framework de Deep Learning liberado por Google en el 2015. Esto no es sesgo. No conozco a nadie que haga sus modelos utilizando Tensorflow. Inicialmente el hecho de tener ejecución estática, hacía que fuera muy difícil programar en él, además de que se sentía como programar en otro lenguaje distinto de Python. La versión dos permite ejecución dinámica, para debuggear en tiempo real, pero siento que ya quedó muy por detrás de Pytorch. Ahora, ¿por qué tiene tantas descargas? Porque se necesita el backend para programar en Keras que sí es la manera en que todo el mundo usa Tensorflow.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Keras&lt;/strong&gt; (Rk: 292, ND: 17.2M+, Pr: 1): Para los que no les gusta complicarse con Pytorch pero igualmente quieren utilizar Redes Neuronales, Keras es la solución. Es por lejos la API más famosa, y más sencilla de aprender. Es un poco más lento que Tensorflow puro pero se encuentran muchos tutoriales de cómo implementar modelos sencillos. Yo comencé a aprender redes neuronales en Keras pero me fui desalentando porque no me gustó la documentación, la encontré muy engorrosa, y además porque empecé a confundirme. Hay como 3 formas distintas de implementar modelos, hoy algunas muy parecidos a Pytorch utilizando clases. No hay mejor o peor entre Keras o Pytorch, pero Pytorch está ganando mucha popularidad, mientras Tensorflow la pierde. Acá tengo un pequeño &lt;a href=&quot;/keras/&quot;&gt;ejemplo&lt;/a&gt; de cómo utilizar Keras.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Jax&lt;/strong&gt; (Rk: 1546, ND: 662K+, Pr: 0): No la he usado, y no está en mi agenda aprenderlo, pero puede que gane mucha popularidad. Corresponde a otro framework desarrollado por Google y fue adoptado por DeepMind, por lo que quizás debido al tremendo desarrollo que ellos hacen comience a hacerse famoso.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Pytorch-Geometric&lt;/strong&gt; (Rk: 4190, ND: 86K+, Pr: 2): Es una extensión de Pytorch para trabajar con Redes de Grafos (Geometric Deep Learning). Yo lo encontré difícil de aprender, pero no por el framework sino que las redes de Grafos son más enredadas. Para tenerlo en cuenta. Tiene muy buena &lt;a href=&quot;https://pytorch-geometric.readthedocs.io/en/latest/&quot;&gt;documentación&lt;/a&gt;, por lo que pueden comenzar el aprendizaje por ahí.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Pytorch-Forecasting&lt;/strong&gt; (Rk: 4346, ND: 78K+, Pr: 2): Es un spin-off de Pytorch para Forecast utilizando Redes Neuronales. Lo interesantees que tiene varios algoritmos famosos implementados como N-Beats, DeepAR y Temporal Fusion Transformer. Además tiene Dataloaders que están diseñados para tipos de predicción propios de series de tiempo. Yo no la utilicé pero sí estudié bastante sus docs para ver si podía utilizarla.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Pycox&lt;/strong&gt; (Rk: NA, ND: NA, Pr: 2): Spin-Off de Pytorch para el uso de Modelos Survival en Deep Learning. Tampoco alcancé a utilizarla, pero también para tenerla en el arsenal si usamos este tipo de modelos.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;torchvision&lt;/strong&gt; (Rk: 518, ND: 4.3M+, Pr: 0): Es una librería auxiliar a Pytorch para Visión que provee de datasets, Data Augmentation y algunos modelos preentrenados. Particularmente creo que hoy no vale la pena. Existen otras librerías más potentes que esta y se demora mucho en incluir cosas nuevas. No vale la pena a mi gusto.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Albumentations&lt;/strong&gt; (Rk: 2391, ND: 283K+, Pr: 1): Es por lejos la mejor librería de Data Augmentation en Imágenes. No sólo es rápida sino que permite augmentation de Imágenes y Masks. No es muy dificil de aprender y es compatible tanto con Pytorch como con Tensorflow/Keras. Muy buena librería.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Kornia&lt;/strong&gt; (Rk: 1918, ND: 441K+, Pr: 2): Si bien Albumentations funciona sumamente rápido, funciona en CPU. Kornia es un Albumentation en GPU, lo cual permitiría, es especial en multiple GPU, tener una que se dedique al preprocesamiento. No la he usado, pero está ganando mucha popularidad.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;OpenCV&lt;/strong&gt; (Rk: 466, ND: 5.2M+, Pr: 0): Si bien es una librería agnóstica de Visión, posee algunos modelitos internos que funcionan súper bien de manera rápida para tareas de detección de objetos, segmentación, etc. con los que fácil y rápidamente puedes impresionar. Yo la uso principalmente junto con Albumentations y es espectacular.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Timm&lt;/strong&gt; (Rk: 837, ND: 1.9M+, Pr: 0): Si te dedicas a la Visión Computacional tienes que conocer esta librería, debe tener un par de comandos y su principal función es descargar modelos pre-entrenados. Principalmente sus modelos son compatibles con Pytorch pero creo que ya se pueden utilizar en Tensorflow/Keras también. Lo mejor de esta librería es que en quizás un par de semanas de salido una arquitectura estado del arte (SOTA Model) ya va a estar disponible acá. Puedes encontrar desde MobileNet o ResNets, hasta ViT, ConvNext, EfficientNets, y un largo etc. Otra buena noticia es que Timm se asoció con HuggingFace por lo que muy probablemente será aún más rápido ver avances en arquitecturas ultra modernas.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Transformers&lt;/strong&gt; (Rk: 403, ND: 6.3M+, Pr: 1): Es quizás por lejos la librería que más rápido ha crecido en el último tiempo y es mantenida por HuggingFace. Inicialmente estaba enfocada en proveer modelos preentrenados y tokenizers de modelos de NLP. Hoy tiene modelos, de Visión, Audio, y dicen que vienen de Grafos. Yo no la he usado mucho, porque no estoy muy metido en el área de NLP, pero hay que conocerla. Con un par de líneas puedes hacer un tremendo transformer estado del arte. Aprovecho de destacar el trabajo que hace la Universidad de Chile que tiene un Bert preentrenado en español disponible para uso libre, el &lt;a href=&quot;https://github.com/dccuchile/beto&quot;&gt;Beto&lt;/a&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;torchinfo&lt;/strong&gt; (torch-summary) (Rk: 4030, ND: 93K+, Pr: 0): Es una librería pequeñita que con una función &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;summary&lt;/code&gt; permite ver un detalle de la red neuronal: capas, parámetros, tamaño, peso, idéntico a como lo permite Keras. Es una función literalmente.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;torchmetrics&lt;/strong&gt; (Rk: 705, ND: 2.6M+, Pr: 0): Es una excelente librería con métricas de evaluación para Deep Learning. ¿Por qué no usar las típicas de Scikit-Learn? Primero, esta tiene muchas más métricas específicas para NLP, Object Detection y un largo etc. Además estas métricas se pueden ejecutar en GPU o Clusters, dependiendo de la paralelización o distribución, lo cuál las hacen mucho más rápidas.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;misceláneo&quot;&gt;Misceláneo&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;VSCode&lt;/strong&gt; ((O), Pr: 1): Para mí, el mejor IDE para programar hoy en día, aunque es agnóstico, puedes programar casi lo que quieras acá. Principalmente porque es liviano, evita muchas complejidades para trabajar en ambientes aislados (conda o venv). Lo bueno es que es totalmente personalizable, tiene extensiones para todo. De hecho este blog es escrito en Markdown utilizando distintas extensiones que me facilitan la escritura. Otro aspecto para los más computines es que puede utilizar keycodes populares como Vim, Emacs o Sublime para usar sólo el teclado. En particular VSCode tiene muy buen soporte para Python permitiendo el uso de Notebooks, Scripts o una Consola Interactiva. Además es posible utilizar terminal (aunque increíblemente no funciona tan bien en Windows, por eso Linux for the “Win”), tiene soporte de GIT, debugger y un largo etc. Vale la pena, toma un tiempo aprenderlo pero no se van a arrepentir.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;RStudio&lt;/strong&gt; ((O), (R) Pr: 1): Hay que decir que este es por lejos el IDE más optimizado para R. Permite instalar librerías directo de CRAN, tiene visualizador de Datasets, un sector de Plots, Documentación incluida, Explorador de Archivos y Terminal. Además tiene integración con GIT y librerías como blogdown (para hacer tu sitio web en R, mi antiguo sitio fue hecho ahí), bookdown (mi tesis de pregrado la escribí ahí), etc.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Spyder&lt;/strong&gt; ((O), (R) Pr: 2): Este es como una réplica de Rstudio pero para Python. Inicialmente cuando me moví de Python comencé a utilizarlo, y es bien completo, permite Scripts, tiene extensiones para Notebooks, tiene explorador de variables. A mí particularmente me molestaban dos cosas, que se demora en iniciar, y que nunca pude encontrar una paleta de colores para el highlighting. Es una buena opción para programar en un ambiente que está diseñado para ciencia de datos.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Pycharm&lt;/strong&gt; ((O), (R) Pr: 0): También lo utilicé con licencia completa y debo decir que si bien es un IDE enfocado exclusivamente en Python me cargó. Siento que no está pensado para Ciencia de Datos. Es muy pesado, se demora mucho en partir, su configuración inicial es terrible y al menos a mí siempre se me quedó pegado. Jetbrains (los creadores de esto) creo que se dieron cuenta que no era lo mejor y crearon un IDE enfocado en Ciecia de datos (&lt;a href=&quot;https://www.jetbrains.com/es-es/dataspell/&quot;&gt;DataSpell&lt;/a&gt;), pero la verdad no lo he probado. Es tan completo que llega ser abrumante, y nunca pude aprender todo lo que podía eventualmente servirme. Para mí, no vale mucho la pena.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Atom&lt;/strong&gt; ((O), (R) Pr: 0): Para mí era lejos el mejor IDE para programar, creado por Github. Tiene extensiones, muy buenos atajos de teclado, era rápido, liviano y tenía una extensión llamada Hydrogen que permitía tener los resultados de tu código directamente en el Script de manera muy intuititva y cómoda. ¿Por qué dejé de usarlo? Siento que dejaron de darle tanto soporte luego que Github fue adquirido por Microsoft y favorecieron más VSCode. Además luego de usarlo por un rato, comandos simples como &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;df.shape&lt;/code&gt; tomaba 40-50 segundos, lo cual era inaceptable. Créanme que volvería mil veces a utilizarlo si viera que hay soporte y mantenimiento continuo. Una lástima.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;GIT/Github&lt;/strong&gt; ((O), Pr: 1): Me cuesta creer que aún existen muchos “Data Algo” que no usan GIT. Esto debería ser obligación y requisito siempre. Afortunadamente me tocó trabajar en un equipo con muy buenas prácticas de desarrollo donde entendí la importancia de llevar control de versiones siempre. GIT no es difícil, pero es importante entender conceptos de Commits, push, trabajo en ramas. Adicionalmente llevarlo con Github (u otras variantes como GitLab o BitBucket) y entender conceptos como Pull Request, levantar Issues, Revisiones de códigos, approvals, etc. Si no usas GIT/Github, no te sientas mal. Hay empresas gigantes que no lo usan, pero aprenderlo y fomentar su uso te lleva fácilmente a un nivel más alto de calidad. Si quieres aprenderlo tengo una serie de tutoriales que parten &lt;a href=&quot;/github/&quot;&gt;acá&lt;/a&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Docker&lt;/strong&gt; ((O), Pr: 1): Hoy por hoy es imprescindible mover a producción todo en Docker. No soy para nada experto en el tema pero puedo crear un contenedor, conectarlo con el mundo real y eventualmente hostearlo en alguna parte. Es por lejos la mejor manera de asegurar reproducibilidad en cualquier ambiente (Unix, Max o incluso Windows con WSL2). Hay que aprenderlo sí o sí.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Bash&lt;/strong&gt; ((O), Pr: 1): Creo que es sumamente importante conocer un poquito de Bash, en especial para automatizar procesos. Bash es el lenguaje de tu computador y te permite interactuar con él. Algunas cosas interesantes que puedes hacer: Agendar trabajos periódicos de manera automática, mandar correos cuando termine un proceso largo, apagar el computador luego de entrenar un modelo por la noche. No es dificil de aprender, y la mayoría de las veces vas a googlear en Stackoverflow para salir del paso.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Wandb&lt;/strong&gt; (Rk: 791, ND: 2.1M+, Pr: 2): Este es un logger, que si bien permite llevar registro de modelos de ML y DL, funciona mejor en Deep Learning. Fácil de usar, muy linda interfaz y permite llevar registro de Arquitectura, Hiperparámetros, Curvas de Aprendizaje, ejemplos de Inferencia, almacenar tablas y gráficas, etc. Además contiene un sistema de Búsqueda de Hiperparámetros distribuido usando Hyperband, es decir, se puede entrenar el mismo modelo en distintas máquinas sin interferir entre ellos y sin repetir búsqueda, Weights &amp;amp; Biases lleva el control.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;MLFlow&lt;/strong&gt; (Rk: 260, ND: 11.1M+, Pr: 2): La verdad es que MLFlow es igual o mejor que Weights &amp;amp; Biases, pero a mí no me gustó. Encuentro que su documentación es engorrosa y su API no es tan intuitiva. Hace lo mismo además de poder llevar proyectos y un Model Registry para llevar control de versiones del entrenamiento de tu modelo. Si les interesa aprenderlo, tengo un tutorial &lt;a href=&quot;/mlflow/&quot;&gt;acá&lt;/a&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;FastAPI&lt;/strong&gt; (Rk: 377, ND: 6.8M+, Pr: 1): Es quizás una de las librerías más rápidas en Python y es muy fácil de usar. Primero, está hecha por un Colombiano (Tiangolo), es de excelentísima cálidad, muy buena documentación, muchas funcionalidades, y requiere de poquito código, ¿qué más se puede pedir?. Definitivamente si quieres distribuir lo que sea, data, un modelo de ML, FastAPI es la mejor opción. Es tanto la popularidad que varias librerías utilizan esta librería under the hood.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Airflow&lt;/strong&gt; (Rk: 375, ND: 6.8M+, Pr: 1): Yo creo que a menos que seas Analista de Datos, es una herramienta que hay que aprender. Airflow es un orquestador creado por Airbnb, que permite ejecutar y agendar Scripts para ser ejecutados de manera local o remota. Lo bueno de Airflow es que servicios como AWS, o Astronomer permiten ejecutarlos en entornos autoescalables en Kubernetes, lo cual quita una capa de complejidad, en especial a los que no sabemos cómo demonios funciona Kubernetes (un orquestador de contenedores). Airflow se hizo famoso como un orquestador de ETLs, que es compatible con casi todo. Yo lo he usado con: AWS, Spark, AWS Glue, ElasticSearch, MongoDB, SQLAlchemy, Redshift, Postgres. Es tan potente que incluso permite entrenar modelos de ML localmente o en entornos como Amazon SageMaker (aunque no es la opción óptima para ML), de hecho Airbnb creó BigHead para eso, que no ha sido liberado al público. Creo que su único contra es que un poco verboso, y tiene harto código boilerplate. Pero su funcionamiento es impecable.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Metaflow&lt;/strong&gt; (Rk: NA, ND: NA, Pr: 2): Otro orquestador, pero creado por Netflix, pero que está enfocado en llevar modelos de ML a producción. Las ventajas, mucho menos boilerplate que Airflow, no tienes los típicos problemas de Xcoms en Airflow, puede ejecutarse local o en AWS mediante AWS Batch, EC2 y Step Functions. Permite automatizar todo el proceso de entrenamiento creando de ser necesarios ambientes anacondas independientes para cumplir con requerimientos de versiones específicas. No alcancé a utilizarlo, pero me tocó leerme toda la documentación para impulsar su uso.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Kedro&lt;/strong&gt; (Rk: 2066, ND: 378K+, Pr: 0): Otro orquestador, pero desarrollado por QuantumBlack. Es bien poderoso, en el sentido que permite crear Pipelines de carga de datos, y de entrenamiento de modelos, pero no logré encontrar tantas opciones de escalabilidad. Si bien permite por ejemplo conexión con Sagemaker en AWS, no tiene las opciones más avanzadas de escalamiento vertical y horizontal que tiene Airflow y Metaflow. Además lo encontré en su momento un poco verboso, y sus Docs tenían errores, que hizo que me costará mucho entenderlo.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;DVC&lt;/strong&gt; (Rk: 1700, ND: 551K+, Pr: 1): Para mí es el orquestador más liviano, con menos Boilerplate y más sencillo de utilizar, pero tiene una cierta inclinación al entrenamiento de modelos. DVC es más que un orquestador, permite llevar registro de versiones de tu data, los cuales normalmente no es posible llevar en GIT; organizar Pipelines, llevar registro de Hiperparámetros, guardar métricas de performance, etc. Me gustó mucho más que Airflow, pero para una orquestación local, aunque podría escalar. Puedes aprender de él en este &lt;a href=&quot;/dvc/&quot;&gt;tutorial&lt;/a&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Great-Expectations&lt;/strong&gt; (Rk: 429, ND: 5.9M+, Pr: 1): Es un validador de datos. No les puedo explicar lo necesario que es empezar a incluir elementos como estos en nuestros Pipelines de datos. Todas las empresas tienen datos, pero pocas empresas con calidad suficiente para llegar y utilizar. Great Expectations es como una librería de Tests asociados a si los datos cumplen: rangos, tipos, cantidad, distribución y un largo etc. En caso de no cumplir levanta la alerta dando en detalle qué registros no cumplen con el estándar solicitado. Además es compatible con Airflow, por lo que uno puede usar como Gate de Ejecución si tu data cumple o no los requerimientos de modo de no cargar datos sucios en tus fuentes principales de almacenamiento. Muy buena librería.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Pytest&lt;/strong&gt; (Rk: 72, ND: 39.4M+, Pr: 1): Librería de Unit Test, algo que los Data Scientist rara vez hacemos. Es muy buena librería, fácil de usar, aunque es media rara la Documentación, pero nada que un buen tutorial de Youtube no pueda enseñar. Todos los pipelines de datos, deberían considerar Unit Tests.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Hydra&lt;/strong&gt; (Rk: 1507, ND: 698K+, Pr: 1): Para mí el mejor CLI para modelos de Machine Learning, nacida en el equipo de Research de Facebook, ahora Meta. No sólo permite crear comandos personalizados para ejecutar Scripts desde el terminal sino que también permite crear configuraciones muy complejas tanto para modelos de ML como para Pipelines en general. Para los que siguen el Blog saben que es de mis favoritas, y pueden ver &lt;a href=&quot;/hydra/&quot;&gt;ejemplos&lt;/a&gt; acá. Muy buena librería, aunque no es tan famosa aún.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;CML&lt;/strong&gt; (Rk: NA, ND: NA, Pr: 0): Es una librería para automatizar procesos con Github Actions. Si les interesa ver en acción pueden chequear &lt;a href=&quot;/cml/&quot;&gt;acá&lt;/a&gt;. No vale la pena aprenderla, son sólo un par de comandos y ya.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;BentoML&lt;/strong&gt; (Rk: NA, ND: NA, Pr: 0): Esta es una librería que permite automatizar el Deployment de Modelos de Machine Learning. No la he usado pero he leído mucho su documentación, porque en estricto rigor permite crear de manera muy sencilla un Docker con tu modelo que esté listo para entregar al equipo de desarrollo. También crea una API Rest automáticamente. Definitivamente voy a estar metiéndome más en el tema.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;MLEM&lt;/strong&gt; (Rk: NA, ND: NA, Pr: 0): Esta es una librería que me ofrecí a probarla en Beta. Hace lo mismo que Bento, pero permite rápidamente deploy en Cloud (AWS, Azure y GCP y Heroku), para cualquier tipo de modelo, y crea el Docker automáticamente. Cuando la ví me pareció demasiado mágica y está recién partiendo. Lo bueno es que incluye un curso que se puede tomar de manera gratuita &lt;a href=&quot;https://learn.iterative.ai/&quot;&gt;acá&lt;/a&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Typer&lt;/strong&gt; (Rk: 349, ND: 7.8M+, Pr: 2): Creada también por Tiangolo, es un CLI mucho más poderoso que Hydra pero con un enfoque general. Su API es muy parecida a FastAPI, muy sencilla y potente. Yo la probé antes de conocer Hydra, pero igual creo que vale mucho la pena.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;BeautifulSoup4&lt;/strong&gt; (Rk: 63, ND: 42M+, Pr: 2): Es una herramienta de Scrapping para poder tomar data de páginas web. Súper potente, ya que tiene mucho del trabajo que uno normal necesita hacer automatizado. Su documentación es buena y es fácil de aprender. Si quieres saber cómo usarla tengo un tutorial &lt;a href=&quot;/dtc/&quot;&gt;acá&lt;/a&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Boto3&lt;/strong&gt; (Rk: 1, ND: 392M+, Pr: 0): Es impresionante la cantidad de descargas de Boto3. Lamentablemente sólo será útil si utilizas AWS. Yo la he usado principalmente para interactuar con S3. Además si instalas &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;s3fs&lt;/code&gt; y &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;fsspec&lt;/code&gt; es posible utilizar pd.read_* y .to_* de pandas utilizando un URI de S3 directamente, por ejemplo: &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;pd.read_csv('S3://bucket/folder/file.ext')&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Joblib&lt;/strong&gt; (Rk: 126, ND: 24M+, Pr: 0): Yo lo uso principalmente para serializar modelos entrenados de Scikit-Learn y similares de acuerdo a &lt;a href=&quot;https://scikit-learn.org/stable/model_persistence.html&quot;&gt;esto&lt;/a&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Pickle&lt;/strong&gt; (Rk: NA, ND: NA, Pr: 0): Dejé de usarlo, porque Scikit-Learn favorece guardarlo en formato joblib.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Faker&lt;/strong&gt; (Rk: 454, ND: 5.4M+, Pr: 0): Yo sólo lo utilicé para una prueba de técnica para un candidato. Quería poner la misma data que utilizabamos pero sin entregar información confidencial. Faker permite emular info de manera muy real, creando de todo. En ese momento, cree: Nombres, Apellidos, Direcciones, Teléfonos, Patentes de Auto, Empresas, y un largo etc. Es sumamente bueno cuando se quiere generar un producto en el cual la data no está lista. Súper útil, pero no lo vas a usar siempre.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;pyyaml&lt;/strong&gt; (Rk: 11, ND: 142M+, Pr: 0): No vale la pena aprender más que una función para importar un yaml, esto permitirá manipular tu &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;yaml file&lt;/code&gt; como diccionario de Python. De esta manera toda tu configuración vive en un archivo yaml, y no ensucia tus Scripts.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;pdbpp&lt;/strong&gt; (Rk: 2999, ND: 173K+, Pr: 2): Es un debugger en terminal. Personalmente no me gusta el debugger de VSCode, por eso uso este. Tiene atajos de teclado y es bastante rápido. Lo recomiendo, aunque no es necesario que lo sepan utilizar.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;holidays&lt;/strong&gt; (Rk: 526, ND: 4.2M+, Pr: 0): Es una librería pequeñita pero muy poderosa (se ve en su ND). Tiene todos los feriados, de todos los países de todos los años. Sólo indicas país, periodo y ya. Yo la utilice para crear features en un &lt;a href=&quot;/kaggle-tps/&quot;&gt;Tabular Playground de Kaggle&lt;/a&gt;. Muy útil en series de tiempo, pero tiene un método y ya.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Python-Box&lt;/strong&gt; (Rk: 1038, ND: 1.4M+, Pr: 0): Es súper útil, solo envuelves un diccionario con &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Box()&lt;/code&gt; y puedes llamar tu diccionario como &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;dict.key&lt;/code&gt; en vez de &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;dict['key']&lt;/code&gt;. Ahorras varios caractéres.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;beepr&lt;/strong&gt; ((R), Pr: 0): Esta es una librería inútil, pero que me encantaba. Podías agregar sonidos cuando tu código fallaba o terminaba correctamente (típico sonido de Mario al pasar el nível), lo cual sacó más de una carcajada en el equipo.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;chime&lt;/strong&gt; (Rk: NA, ND: NA, Pr: 0): Sería como el equivalente en Python de Beepr. Hay otra librería más que ocupé que no recuerdo el nombre pero no funcionó tan bien.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Rich&lt;/strong&gt; (Rk: 290, ND: 9.8M+ Pr: 2): Esta es una librería muy poderosa para agregar color a tu terminal. Tiene muchas funcionalidades, barras de progreso, outputs de colores, quizás la mejor es que es posible que los errores en Python se rendericen más bonitos, para por lo menos frustrarse menor cuando algo falla. Creo que igual vale la pena invertir en una mejor experiencia de usuario cuando crees productos CLI, por lo que vale la pena aprenderla en ese caso.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;tqdm&lt;/strong&gt; (Rk: 77, ND: 38M+ Pr: 0): Tiene dos funciones interesantes, &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;tqdm&lt;/code&gt; para envolver un For Loop y tener barra de progreso. Y otra para llamada &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;progress_apply&lt;/code&gt; que permite barra para el apply de pandas. No te demoras nada en dominarla.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;librerías-estándar-que-deberías-usarconocer&quot;&gt;Librerías estándar que deberías usar/conocer&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Logging&lt;/strong&gt; (Rk: NA, ND: NA Pr: 1): Si vas a automatizar algo en Python, sea cual sea su uso, debes loggear todo. Logging permite generar archivos &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;.log&lt;/code&gt; que permitirán analizar a posteriori si un Script terminó con éxito o no. Súper útil, fácil de aprender, tiene sólo un par de comandos para indicar éxito, info, warning, errores. Puedes combinar con chime y con Rich para tener un producto multicolor y sonoro. Hace más agradable la pega.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;requests&lt;/strong&gt; (Rk: 5, ND: 194M+ Pr: 0): Sirve para conectarse a una API o en combinación con BeautifulSoup para obtener el HTML de un sitio WEB. Yo la he utilizado sólo para eso y no cuesta nada aprender a utilizarla, aunque quizás si debas entender el output que normalmente es un string con HTML o string con arreglos de diccionarios anidados si proviene de una API.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;glob&lt;/strong&gt; (Rk: NA, ND: NA Pr: 0): Permite revisar directorios utilizando sólo el comando &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;glob&lt;/code&gt; y un path con expresiones regulares simples. Súper útil, por ejemplo, cuando tienes que importar muchos archivos en un sólo pandas DataFrame.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;json&lt;/strong&gt; (Rk: NA, ND: NA Pr: 0): Yo lo he usado para convertir el output de requests en diccionarios y para guardar outputs como json. Sólo eso!&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;pathlib&lt;/strong&gt; (Rk: NA, ND: NA Pr: 2): Esta es una librería bien interesante para poder automatizar la creación de directorios y llevar tus Path de manera más sencilla. Puedes manipular Path combinandolos, creando Paths más sencillos y crear o eliminar carpetas dentro de ellos. Es fácil de utilizar y tengo ejemplos de ello en mis tutoriales de &lt;a href=&quot;/dvc/&quot;&gt;DVC&lt;/a&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;getpass&lt;/strong&gt; (Rk: NA, ND: NA Pr: 0): Esta librería tiene una función llamada &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;getpass&lt;/code&gt;, que funciona como un Text Input pero con los caractéres ocultos. Útil para ingresar data que no quieres que se vea, pero no la encripta ojo.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 class=&quot;no_toc&quot; id=&quot;uff&quot;&gt;Uff&lt;/h2&gt;

&lt;p&gt;Y con esto terminamos. Debo decir que este es al artículo que más trabajo me ha dado. Y demoré cerca de dos meses en escribirlo. Voy a tratar de ir llenando esto con el tiempo a medida que vaya probando más cosas. Algunas de las tecnologías que se me quedaron en el tintero porque no cumplen los requisitos exigidos arriba:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Varios servicios AWS
    &lt;ul&gt;
      &lt;li&gt;Sagemaker&lt;/li&gt;
      &lt;li&gt;AWS Lambda&lt;/li&gt;
      &lt;li&gt;API Gateway&lt;/li&gt;
      &lt;li&gt;Step Functions&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://pregex.readthedocs.io/en/latest/&quot;&gt;PRegex&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://dagshub.com/&quot;&gt;Dagshub&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://python-poetry.org/&quot;&gt;poetry&lt;/a&gt;. Por alguna razón me da terror instalarla, aunque he leído bastante de ella.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://pypi.org/project/fancyimpute/&quot;&gt;fancyimpute&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://stanfordmlgroup.github.io/projects/ngboost/&quot;&gt;NGBoost&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://scikit-lego.readthedocs.io/en/latest/&quot;&gt;SKLego&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/dreamquark-ai/tabnet&quot;&gt;tabnet&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://umap-learn.readthedocs.io/en/latest/&quot;&gt;UMAP&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/qubvel/segmentation_models.pytorch&quot;&gt;Segmentation Models&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.nannyml.com/&quot;&gt;NannyML&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.dgl.ai/&quot;&gt;DGL&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://biopython.org/&quot;&gt;BioPython&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Ecosistema Pytorch :
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://pytorch.org/text/stable/index.html&quot;&gt;torchtext&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://pytorch.org/audio/stable/index.html&quot;&gt;torchaudio&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://torchgeo.readthedocs.io/en/stable/&quot;&gt;torchgeo&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://github.com/benedekrozemberczki/pytorch_geometric_temporal&quot;&gt;Pytorch Geometric Temporal&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://pytorch.org/torchrec/&quot;&gt;torchrec&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://pytorchvideo.org/&quot;&gt;Pytorch Video&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Espero que esto sea de utilidad para tenerlo como referencia a la hora de enfrentar distintos problemas en Ciencia de Datos.&lt;/p&gt;

&lt;p&gt;Nos vemos,&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/contact/&quot;&gt;&lt;strong&gt;Alfonso&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
</content>

			
				<category term="ds" />
			
			
				<category term="python" />
			
				<category term="tutorial" />
			

			<published>2022-08-01T00:00:00+00:00</published>
		</entry>
	
		<entry>
			<id>http://datacuber.github.io/recsys/</id>
			<title>¿Cómo funciona un Sistema Recomendador?</title>
			<link href="http://datacuber.github.io/recsys/" rel="alternate" type="text/html" title="¿Cómo funciona un Sistema Recomendador?" />
			<updated>2022-04-25T00:00:00+00:00</updated>

			
			<summary>Neural Collaborative Filtering (NCF) en Pytorch</summary>
			<content type="html" xml:base="http://datacuber.github.io/recsys/">&lt;p&gt;&lt;img src=&quot;/images/recsys/front.png&quot; alt=&quot;picture of me&quot; class=&quot;left show-for-large-up hide-for-print&quot; width=&quot;250&quot; /&gt;
&lt;img src=&quot;/images/recsys/front.png&quot; alt=&quot;picture of me&quot; class=&quot;center hide-for-large-up&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Los sistemas de Recomendación están en todas partes. Abrimos Netflix, Amazon, Spotify, sin ir más lejos el mismo Mercado Libre, y todos siempre tienen algo que ofrecernos. Los sistemas de recomendación son otro tipo de modelos de modelos de Machine Learning, y son el eje principal en las grandes de Silicon Valley. &lt;!--more--&gt; Pero, conversando con &lt;a href=&quot;https://www.linkedin.com/in/gustavo-prudencio-cerfogli/&quot;&gt;Gustavo Prudencio&lt;/a&gt; de Cornershop, ambos estuvimos de acuerdo en que no son para nada Modelos Populares. Es más, particularmente en Chile, creo que es de los modelos más raros de ver. Probablemente Cornershop sea de los pioneros en esto (aunque no me quiso dar detalles de qué tienen actualmente implementado 😆).&lt;/p&gt;

&lt;p&gt;En fin, no soy experto en modelos de recomendación. Pero por ahí en el 2019 me tocó armar un piloto en Cencosud Scotiabank utilizando filtrado colaborativo con librerías como implicit, surprise y lightfm pero nunca llegué a entenderlo a profundidad. Este fin de semana decidí aprender en más profundidad de esto e implementar un modelo de Recomendación en Pytorch (así como si tuviera tiempo de sobra, el cual no tengo).&lt;/p&gt;

&lt;h2 id=&quot;modelo-de-recomendación&quot;&gt;Modelo de Recomendación&lt;/h2&gt;

&lt;p&gt;Entender el problema de recomendación es muy sencillo, hay dos tipos de recomendadores, los que usan rating explícito y rating implícito.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Rating Explícito&lt;/strong&gt;: Es cuando un usuario de manera explícita califica un producto: Notas, estrellas, lo que sea. El tema con este tipo de data es que es rara porque normalmente no es obligatorio calificar un producto.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Rating Implícito&lt;/strong&gt;: Es cuando la calificación del producto se da de manera implícita. Normalmente se puede dar como: compra o no compra un producto, ve o no ve un video, escucha o no una canción, etc.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;El objetivo del modelo de Recomendación determinar qué producto sería bueno mostrarle al usuario. Para ello existen distintos approaches. El más común hoy el día es el filtrado colaborativo. Es una técnica que consiste en que se recomendarán productos que usuarios parecidos a ti hayan visto. Por lo tanto, no influye solo lo que tú has visto, sino que también lo que gente con gustos similares a los tuyos han visto.&lt;/p&gt;

&lt;p&gt;Mi interés es poder implementar un modelo de Deep Learning que tenga esto en cosideración, por lo tanto, decidí utilizar el siguiente &lt;a href=&quot;https://arxiv.org/abs/1708.05031&quot;&gt;paper&lt;/a&gt; implementando un Neural Collaborative Filtering:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/recsys/ncf.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Este modelo está basado en Embeddings, que es una especie de Encoding en el cual se representa un espacio de alta dimensionalidad en un espacio de menor dimensionalidad en el cual la distancia de las representaciones pueden tener una cierta interpretación. Esto es particularmente importante porque normalmente los sistemas recomendadores están implementados cuando hay muchos usuarios y muchos productos.&lt;/p&gt;

&lt;p&gt;Para el caso que quiero mostrar voy a utilizar un dataset llamado &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;MovieLens 25M&lt;/code&gt;, el cual se puede descargar de &lt;a href=&quot;https://grouplens.org/datasets/movielens/25m/&quot;&gt;acá&lt;/a&gt;. La razón por la que escogí este dataset es porque contiene una lista de usuarios y películas calificadas por usuarios hasta el 2019, que incluye muchas películas actuales (aunque pre-pandemia). El problema del dataset es que contiene 25 millones de ratings, 62423 películas y 162541 usuarios.&lt;/p&gt;

&lt;div class=&quot;alert-box alert radius &quot;&gt;&lt;p&gt;No voy a utilizar el dataset completo porque no quiero ensuciar las recomendaciones con películas antiguas, pero de igual manera quiero como desafío personal trabajar con una gran cantidad de datos. Es en este tipo de problemas cuando realmente es necesario tener buenas skills de programación para poder lidiar con alta cantidad de datos.&lt;/p&gt;
&lt;/div&gt;

&lt;div class=&quot;alert-box info radius &quot;&gt;&lt;p&gt;Esto no es Big Data, es harta data pero para que se vea el poder del Stack de Data Science no vamos a usar nada extraño, sólo Pandas, Scipy y Numpy.&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Entonces para poder entender qué hace el modelo encontré el siguiente ejemplo:
Supongamos que Bob no es muy fan de las peliculas de Romance, pero sí de ls películas de Acción, mientras que Joe, le gustan ambas. Podemos dependiendo del id de usuario y de las id de las películas vistas transformarlo en lo siguiente:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/recsys/embeddings.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Luego su representación en el plano bidimensional Action x Romance nos permite identificar qué tan parecidos o distintos son Bob y Joe. Esto permitirá al modelo aprender las relaciones que existen entre usuarios al momento de poder recomendar.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/recsys/distance.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Teniendo estas ideas básicas del funcionamiento de un recomendador vamos a la implementación:&lt;/p&gt;

&lt;h2 id=&quot;entendiendo-los-datos&quot;&gt;Entendiendo los datos&lt;/h2&gt;

&lt;h3 id=&quot;películas&quot;&gt;Películas&lt;/h3&gt;

&lt;div title=&quot;Importación Librerías.&quot; class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pandas&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;numpy&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;movies&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_csv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'ml-25m/movies.csv'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;movies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;(62423, 3)

Index(['movieId', 'title', 'genres'], dtype='object')
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;El set de películas contiene sólo el Id de Película, el título y los géneros asociados a cada película. La verdad es que el formato no es mi favorito, por lo que decidí limpiar un poco la data para por ejemplo poder obtener el año de cada película. Además como dijimos anteriormente, no queremos recomendar películas viejas por lo que decidí mantener sólo las películas de 2010 en adelante.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;year&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2010&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;movies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'year'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;movies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;extract&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'\((\d{4})\)'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;astype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;float&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;movie_id_removed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;movies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'year &amp;lt; @year'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;movieId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tolist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;movies&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;movies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'year &amp;gt;= @year'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;movies&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;table-overflow&quot;&gt;
&lt;style scoped=&quot;&quot;&gt;
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
&lt;/style&gt;
&lt;table border=&quot;1&quot; class=&quot;dataframe&quot;&gt;
  &lt;thead&gt;
    &lt;tr style=&quot;text-align: right;&quot;&gt;
      &lt;th&gt;&lt;/th&gt;
      &lt;th&gt;movieId&lt;/th&gt;
      &lt;th&gt;title&lt;/th&gt;
      &lt;th&gt;genres&lt;/th&gt;
      &lt;th&gt;year&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;th&gt;14156&lt;/th&gt;
      &lt;td&gt;73268&lt;/td&gt;
      &lt;td&gt;Daybreakers (2010)&lt;/td&gt;
      &lt;td&gt;Action|Drama|Horror|Thriller&lt;/td&gt;
      &lt;td&gt;2010.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;14161&lt;/th&gt;
      &lt;td&gt;73319&lt;/td&gt;
      &lt;td&gt;Leap Year (2010)&lt;/td&gt;
      &lt;td&gt;Comedy|Romance&lt;/td&gt;
      &lt;td&gt;2010.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;14162&lt;/th&gt;
      &lt;td&gt;73321&lt;/td&gt;
      &lt;td&gt;Book of Eli, The (2010)&lt;/td&gt;
      &lt;td&gt;Action|Adventure|Drama&lt;/td&gt;
      &lt;td&gt;2010.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;14222&lt;/th&gt;
      &lt;td&gt;73744&lt;/td&gt;
      &lt;td&gt;If You Love (Jos rakastat) (2010)&lt;/td&gt;
      &lt;td&gt;Drama|Musical|Romance&lt;/td&gt;
      &lt;td&gt;2010.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;14256&lt;/th&gt;
      &lt;td&gt;73929&lt;/td&gt;
      &lt;td&gt;Legion (2010)&lt;/td&gt;
      &lt;td&gt;Action|Fantasy|Horror|Thriller&lt;/td&gt;
      &lt;td&gt;2010.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;...&lt;/th&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;62412&lt;/th&gt;
      &lt;td&gt;209143&lt;/td&gt;
      &lt;td&gt;The Painting (2019)&lt;/td&gt;
      &lt;td&gt;Animation|Documentary&lt;/td&gt;
      &lt;td&gt;2019.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;62413&lt;/th&gt;
      &lt;td&gt;209145&lt;/td&gt;
      &lt;td&gt;Liberté (2019)&lt;/td&gt;
      &lt;td&gt;Drama&lt;/td&gt;
      &lt;td&gt;2019.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;62415&lt;/th&gt;
      &lt;td&gt;209151&lt;/td&gt;
      &lt;td&gt;Mao Zedong 1949 (2019)&lt;/td&gt;
      &lt;td&gt;(no genres listed)&lt;/td&gt;
      &lt;td&gt;2019.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;62418&lt;/th&gt;
      &lt;td&gt;209157&lt;/td&gt;
      &lt;td&gt;We (2018)&lt;/td&gt;
      &lt;td&gt;Drama&lt;/td&gt;
      &lt;td&gt;2018.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;62420&lt;/th&gt;
      &lt;td&gt;209163&lt;/td&gt;
      &lt;td&gt;Bad Poems (2018)&lt;/td&gt;
      &lt;td&gt;Comedy|Drama&lt;/td&gt;
      &lt;td&gt;2018.0&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;20489 rows × 4 columns&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Esto nos dejó con 20489 películas pero que no deja de ser un número considerable.&lt;/p&gt;

&lt;p&gt;Además es importante guardar los id de las películas removidas que fueron 41524. Estas tienen que retirarse también de los reviews de los usuarios.&lt;/p&gt;
&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;movie_id_removed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;41524
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Finalmente, creé un mapping entre el movieId y el nombre de la película. Esto será de gran utilidad al final del procedimiento, para poder identificar los movieId recomendado para ver si es que hacen sentido.&lt;/p&gt;

&lt;div title=&quot;Mapeo de Películas.&quot; class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;movies_mapping&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;movies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'movieId'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'title'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'movieId'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'title'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;calificaciones&quot;&gt;Calificaciones&lt;/h1&gt;

&lt;p&gt;Por otro lado, tenemos el dataset de Ratings, el cual contiene los 25 millones de datos. Estos contienen los distintos usuarios con las películas vistas y sus reviews. Además incluye un &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;timestamp&lt;/code&gt; para poder por ejemplo, tener información de cuando vió la película, en caso de que el orden también tenga relevancia para la recomendación.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;ratings&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_csv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'ml-25m/ratings.csv'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parse_dates&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'timestamp'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ratings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;columns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ratings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ratings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;userId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nunique&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;Index(['userId', 'movieId', 'rating', 'timestamp'], dtype='object')
(25000095, 4)

162541
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Entonces, dentro del procesamiento de los datos tenemos que primero eliminar todas las películas anteriores a 2010 (por eso guardamos los movieId de las películas). Además modificaremos el rating a 1. Esto convertirá nuestro problema en un recomendador implícito. Es decir, el 1 significará que el usuario interactuó con la película, es decir, la vio. Esto es importante para el algoritmo de recomendación ya que entonces tendremos que modelar nuestro problema como un problema de clasificación.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;ratings&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ratings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'movieId not in @movie_id_removed'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ratings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'rating'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ratings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'timestamp'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_datetime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ratings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'timestamp'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;unit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'s'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ratings&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;table-overflow&quot;&gt;
&lt;style scoped=&quot;&quot;&gt;
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
&lt;/style&gt;
&lt;table border=&quot;1&quot; class=&quot;dataframe&quot;&gt;
  &lt;thead&gt;
    &lt;tr style=&quot;text-align: right;&quot;&gt;
      &lt;th&gt;&lt;/th&gt;
      &lt;th&gt;userId&lt;/th&gt;
      &lt;th&gt;movieId&lt;/th&gt;
      &lt;th&gt;rating&lt;/th&gt;
      &lt;th&gt;timestamp&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;th&gt;712&lt;/th&gt;
      &lt;td&gt;3&lt;/td&gt;
      &lt;td&gt;73268&lt;/td&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;2015-08-13 14:11:38&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;713&lt;/th&gt;
      &lt;td&gt;3&lt;/td&gt;
      &lt;td&gt;73321&lt;/td&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;2015-08-13 13:52:05&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;715&lt;/th&gt;
      &lt;td&gt;3&lt;/td&gt;
      &lt;td&gt;74458&lt;/td&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;2017-04-21 14:39:18&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;716&lt;/th&gt;
      &lt;td&gt;3&lt;/td&gt;
      &lt;td&gt;74789&lt;/td&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;2019-08-18 00:59:42&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;717&lt;/th&gt;
      &lt;td&gt;3&lt;/td&gt;
      &lt;td&gt;76077&lt;/td&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;2017-01-18 16:15:09&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;...&lt;/th&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;24999773&lt;/th&gt;
      &lt;td&gt;162538&lt;/td&gt;
      &lt;td&gt;111617&lt;/td&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;2015-08-05 14:15:09&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;24999774&lt;/th&gt;
      &lt;td&gt;162538&lt;/td&gt;
      &lt;td&gt;112138&lt;/td&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;2015-08-05 14:14:35&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;24999775&lt;/th&gt;
      &lt;td&gt;162538&lt;/td&gt;
      &lt;td&gt;112556&lt;/td&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;2015-08-05 14:25:33&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;24999776&lt;/th&gt;
      &lt;td&gt;162538&lt;/td&gt;
      &lt;td&gt;116797&lt;/td&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;2015-08-05 13:25:21&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;24999777&lt;/th&gt;
      &lt;td&gt;162538&lt;/td&gt;
      &lt;td&gt;126548&lt;/td&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;2015-08-05 14:24:57&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;2711937 rows × 4 columns&lt;/p&gt;
&lt;/div&gt;

&lt;div class=&quot;alert-box tip radius &quot;&gt;&lt;p&gt;Este es quizás uno de los proyectos que más he disfrutado haciendo, y la razón principal es porque el Proceso de un Motor de Recomendación es bastante más complejo que sólo entrenar el modelo. La data tiene que ser manipulada de muchas maneras distintas (incluyendo sus complejidades por el tamaño, así que veamos cómo me las ingenié)&lt;/p&gt;
&lt;/div&gt;

&lt;h3 id=&quot;label-encoder&quot;&gt;Label Encoder&lt;/h3&gt;

&lt;p&gt;Debido a los recortes que hicimos en la data, nuetros Id, tanto de Usuarios como de películas no tienen porque ser consecutivos. Esto nos pueden traer algún problema para el algoritmo ya que el id va a representar una distancia en nuestro espacio de embeddings y no queremos que esto se vea alterado. Para ello entonces utilizaremos el &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;LabelEncoder&lt;/code&gt; para crear un mapeo entre los ids reales y un id correlativo.&lt;/p&gt;

&lt;div class=&quot;alert-box info radius &quot;&gt;&lt;p&gt;Esto es básicamente lo mismo que hicimos con el mapeo de películas, pero eventualmente al momento de produccionalizar esto tendremos que tener acceso rápido a nuestros mapeos, por lo que el &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;LabelEncoder&lt;/code&gt; permite una fácil serialización de ellos, ya que las clases quedarán como listas.&lt;/p&gt;
&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sklearn.preprocessing&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LabelEncoder&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;user_encoder&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LabelEncoder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;movie_encoder&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LabelEncoder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ratings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'userId'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_encoder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fit_transform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ratings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;userId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ratings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'movieId'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;movie_encoder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fit_transform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ratings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;movieId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;primer-tropezón&quot;&gt;Primer Tropezón&lt;/h3&gt;

&lt;p&gt;Dado que este es un recomendador implícito, va a ser modelado como un problema de clasificación binaria. Por lo que tenemos muchas películas que el usuario ha visto, pero no tenemos las que no ha visto. Para que el modelo pueda aprender bien leí que una buena idea es poder entregar casos negativos, es decir, películas que no ha visto. Y un buen ratio era 4:1, es decir 4 películas no vistas por cada película vista.&lt;/p&gt;

&lt;p&gt;Mi primer approach fue este:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;create_negative_movies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;userid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'userId'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;movieid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'movieId'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;neg_examples&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;unique_movies&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;movieid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
    
    &lt;span class=&quot;n&quot;&gt;movies&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;uids&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;userid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unique&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;u&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uids&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;movies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;extend&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;choice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unique_movies&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;movieid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;userid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;neg_examples&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uids&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;movies&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;/images/recsys/mala_imp.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Intenté una implementación, que de partida estaba mala, pero que demoró 20 minutos en ejecutarse. 
Básicamente el código hace lo siguiente:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Para cada usuario en la lista de usuarios.&lt;/li&gt;
  &lt;li&gt;Calculo la diferencia entre todos los ids de películas y las que ha visto un usuario.&lt;/li&gt;
  &lt;li&gt;A partir de las películas no vistas saco un random de 4 ejemplos.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Este approach está incorrecto porque generé sólo 4 ejemplos por usuario, unos 400K registros extras y demoró demasiado debido a los muchos usuarios, y debido a que filtrar un dataset tan grande tantas veces lo hace muy lento.&lt;/p&gt;

&lt;h3 id=&quot;la-solución&quot;&gt;La solución&lt;/h3&gt;

&lt;p&gt;Si han estudiado el mecanismo de atención de los transformers, notarán que básicamente se basan en un one-hot encoder para utilizarla como una matriz de filtrado (si quieren estudiar esto en detalle pueden leerlo &lt;a href=&quot;https://e2eml.school/transformers.html#one_hot&quot;&gt;acá&lt;/a&gt;). Con esto podríamos crear una matriz cuyas filas sean los ids de los usuarios y las columnas los ids de las películas. Esto se conoce como una &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;user-item matrix&lt;/code&gt; y basta con hacerla así:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;user_item_matrix&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ratings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pivot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'userId'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;columns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'movieId'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;values&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'rating'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fillna&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;El problema es que esta matriz es gigantesca y me dio el clásico error &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Unable to allocate 1010. MiB for an array with shape...&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Entonces, aquí es donde hay que ponerse creativo. Básicamente la &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;user-item matrix&lt;/code&gt; es una matriz rala (escasa, esparsa, llena de ceros, no sé cuál es la terminología correcta, sparse matrix en inglés…). Y &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;scipy&lt;/code&gt; tiene matrices especiales para eso. &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;csr_matrix&lt;/code&gt; sólo almacena los índices de los valores distintos de cero. Este tipo de matriz es extremadamente eficiente para sumas y productos matriciales, los cuales no vamos a usar, pero sí queremos beneficiarnos de la eficiencia.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;scipy.sparse&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;csr_matrix&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;create_matrix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_col&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item_col&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rating_col&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user_col&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item_col&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user_col&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item_col&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;astype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'category'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user_col&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;codes&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;cols&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item_col&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;codes&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;rating&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rating_col&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;user_item_matrix&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;csr_matrix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rating&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cols&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_item_matrix&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;user_item_matrix&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;create_matrix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ratings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'userId'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'movieId'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'rating'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Encontré una implementación que básicamente toma los índices de usuarios y películas y en la cordenada (userId, movieId) rellena el 1 o cero si es que dicho usuario vio o no la película. Crear esto toma exactamente nada:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/recsys/uim.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Antes eso sí de generar las clases negativas decidí generar el split de la data. Esto con el fin de poder evaluar el comportamiento del modelo:&lt;/p&gt;

&lt;div class=&quot;alert-box tip radius &quot;&gt;&lt;p&gt;La verdad es que en mi proceso real hice el split antes, pero luego me di cuenta que era mejor crear la &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;user-item matrix&lt;/code&gt; primero. Esto porque si creaba este procedimiento después tendría que crear dos &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;user-item matrix&lt;/code&gt;, una para el train_set y otra para el test_set. El gran problema de esto, es que los índices en test son películas que no están en train, por lo que iba a tener problemas para identificar el id correcto ya que el &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;test_set&lt;/code&gt; iba a tener dimensiones distintas y el id 0 de test no iba a corresponder a la película con id cero, si no a la primera película del &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;test_set&lt;/code&gt; que podría ser una película arbitraria. Esto me forzaría a hacer otro mapeo, el cual no quise hacer. Todo ese problema me lo evité haciendo el split después.&lt;/p&gt;
&lt;/div&gt;

&lt;h3 id=&quot;train-test-split&quot;&gt;Train-Test Split&lt;/h3&gt;

&lt;p&gt;Para poder generar el split sin generar leakage se recomendaba utilizar el siguiente procedimiento:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;ratings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'test'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ratings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;groupby&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'userId'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'timestamp'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rank&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'first'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ascending&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;train_ratings&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ratings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'test != 1'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;drop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;columns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'test'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'timestamp'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;test_ratings&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ratings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'test == 1'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;drop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;columns&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'test'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'timestamp'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Básicamente estamos aprendiendo de todas las películas excepto la última que cada usuario vió. La última película estará en el &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;test_set&lt;/code&gt;, por lo que esperamos que nuestro recomendador efectivamente pueda recomendar la última película que vió.&lt;/p&gt;

&lt;h2 id=&quot;generación-de-películas-no-vistas&quot;&gt;Generación de Películas no vistas&lt;/h2&gt;

&lt;p&gt;Ahora generé otra implementación utilizando la &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;user-item matrix&lt;/code&gt;. Debido a la fea sintáxis de &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;numpy&lt;/code&gt;, el resultado dejaba muchas funciones anidadas, por lo que decidí escribirlo estilo &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Pytorch&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;create_negative_df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user_ids&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;neg_examples&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    
    &lt;span class=&quot;n&quot;&gt;movies_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arange&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user_item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;negative_movies&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;examples&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user_ids&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)):&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;interacted&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nonzero&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;~&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;movies_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;interacted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argwhere&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;squeeze&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;neg_examples&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;interacted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;neg_examples&lt;/span&gt;
        
        &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;choice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;negative_movies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;extend&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;examples&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        
    &lt;span class=&quot;n&quot;&gt;negative_movies_df&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DataFrame&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;userId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user_ids&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;examples&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;movieId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;negative_movies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;rating&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zeros&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;negative_movies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
                        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;negative_movies_df&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Esta función:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Toma los ids de películas y para cada id de usuario detecta las películas con que interactuó.&lt;/li&gt;
  &lt;li&gt;Genera un mask de películas no vistas, es decir, donde la user-item matrix no es uno.&lt;/li&gt;
  &lt;li&gt;Calcula qué indices son las películas no vistas.&lt;/li&gt;
  &lt;li&gt;Saca una muestra de toda las películas no vistas igual a &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;neg_examples&lt;/code&gt; en el caso de test y de &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;neg_examples&lt;/code&gt; por el número de películas vistas en otro caso.&lt;/li&gt;
  &lt;li&gt;Finalmente combina todo eso en un DataFrame (con una lógica bien enredada que no sé muy bien como explicar así que pueden deducirlo del código).&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
  &lt;p&gt;Esta función la implementé solito (sin StackOverflow).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Esta función entonces sacará 4 ejemplos no vistos por cada película vista por un usuario en train. En el caso de test es un poco distinto, dado que cada usuario tiene sólo una película vista, sacaremos 99 casos no vistos (aleatorios). Luego la predicción del modelo será las 10 recomendaciones de los 100 casos, donde una de ellas ha sido vista por el usuario. Esperamos que en las 10 recomendaciones se encuentre la película que efectivamente vio.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/recsys/split.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Como pueden ver esta implementación es muy rápida y eficiente y los resultados son 10 millones de registros para el train y 6 para el test.&lt;/p&gt;

&lt;p&gt;Finalmente se combinan los casos vistos y no vistos obteniendo 12 millones para el &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;train set&lt;/code&gt; y 6 millones para el &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;test set&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;full_training_df&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train_ratings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train_negative_movies_df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;full_test_df&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test_ratings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;test_negative_movies_df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;full_training_df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full_test_df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;((12797849, 3), (6078000, 3))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;neural-collaborative-filtering&quot;&gt;Neural Collaborative Filtering&lt;/h1&gt;

&lt;p&gt;Como siempre el modelo lo crearemos utilizando Pytorch Lightning. Justo actualicé Pytorch Lightning a la versión 1.6.1 el cuál trajo varios cambios en la API por lo que aprovecharé de mencionar dichos cambios:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;torch&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;torch.nn&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pytorch_lightning&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pl&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pytorch_lightning.callbacks&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ModelCheckpoint&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;pl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seed_everything&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;workers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;Global seed set to 42
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Primero que todo fijamos la semilla para la reproducibilidad. Además, encontré que utilizando &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;workers=True&lt;/code&gt; se garantiza la reproducibilidad en los DataLoaders, que a veces no eran tan fáciles de reproducir debido a la carga de la data en GPU.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;torch.utils.data&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Dataset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DataLoader&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MovieData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Dataset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;movies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ratings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;users&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;users&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;movies&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;movies&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ratings&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ratings&lt;/span&gt;
        
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__len__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ratings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__getitem__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    
        &lt;span class=&quot;n&quot;&gt;users&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;movies&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;movies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ratings&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ratings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;users&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;torch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tensor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;torch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;movies&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;torch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tensor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;movies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;torch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;long&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;ratings&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;torch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tensor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ratings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;torch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Creamos nuestro Pytorch &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;Dataset&lt;/code&gt;, que básicamente tomará los usuarios, películas y ratings y los transformará en tensores.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MovieDataModule&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LightningDataModule&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train_df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test_df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batch_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;512&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train_df&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;train_df&lt;/span&gt; 
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;test_df&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test_df&lt;/span&gt; 
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;batch_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batch_size&lt;/span&gt;
        
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stage&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train_data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MovieData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train_df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;userId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train_df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;movieId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train_df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rating&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;test_data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MovieData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;test_df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;userId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;test_df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;movieId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;test_df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rating&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;train_dataloader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DataLoader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batch_size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;batch_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shuffle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pin_memory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num_workers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;test_dataloader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DataLoader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;test_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batch_size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;batch_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shuffle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pin_memory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num_workers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;En este caso el &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;LightningDataModule&lt;/code&gt; tomará los set de train y test los transformará en tensores y los cargará en GPU con los DataLoader. Si se fijan el &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;batch_size&lt;/code&gt; lo dejé en 512 porque es mucha data y batch size pequeños demoraban demasiado. El tema de usar batch_size alto es que hizo explotar mis DataLoaders muchas veces, y la razón de eso es porque tenía mi &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;num_workers&lt;/code&gt; en 12 (que son todos mis core en mi laptop). Luego de mucho batallar, encontré que era mejor decisión bajar esto y dejar algunos libres. Hay que recordar que la función del DataLoader es cargar la data al modelo y en este caso hacer el traspaso a la GPU, pero este proceso se realiza en CPU, por lo que es bueno dejar unos cores para que el compu pueda sobrevivir el proceso de entrenamiento.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NCF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dim_users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dim_movies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n_out&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user_embedding&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Embedding&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dim_users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;movie_embedding&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Embedding&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dim_movies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;encoder&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Sequential&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                            &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Linear&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                            &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ReLU&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inplace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                            &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Linear&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                            &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ReLU&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inplace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                            &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Linear&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n_out&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;forward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;movies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;user_emb&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user_embedding&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;movie_emb&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;movie_embedding&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;movies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        
        &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;torch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user_emb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;movie_emb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dim&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;encoder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;El modelo de Neural Collaborative Filtering es una red neuronal que toma como entrada los usuarios y películas y devuelve un rating. En este caso el modelo es una red neuronal que parte con un embedding tanto para users como movies de 8 dimensiones, que se concatenan para entrar en un encoder compuesto por una capa de 64 dimensiones, una capa de 32 dimensiones y una capa de 1 dimension (el rating). (Pueden creer que el parrafo anterior lo escribió Github Copilot, es espectacular). Como es un modelo de clasificación, este debería terminar con una sigmoide, pero se recomienda no hacerlo y utilizar una Loss Function de &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;BCEWithLogitsLoss&lt;/code&gt;, que es una Binary CrossEntropy más la sigmoide que provee mejor estabilidad numérica.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;RecSys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LightningModule&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;criterion&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BCEWithLogitsLoss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;forward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;movies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;movies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
        
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;training_step&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batch_idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;movies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ratings&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'users'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'movies'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'ratings'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;preds&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;movies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# print('preds:',  preds.shape)
&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;# print('ratings: ', ratings.shape)
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;criterion&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;preds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ratings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'train_loss'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;prog_bar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'loss'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;configure_optimizers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;torch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;optim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Adam&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parameters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1e-3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;El &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;LightningModule&lt;/code&gt; no tiene nada especial. Sólo mencionar que en este caso nuestra red neuronal recibe de cada batch los usuarios por un lado y las películas por otro. Esto es importante porque usuarios y películas tienen embeddings diferentes por lo que deben entrar al modelo por separado ya que los embeddings del modelo no van en serie sino en paralelo.&lt;/p&gt;

&lt;p&gt;Finalmente para el entrenamiento instanciamos el modelo:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NCF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dim_users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dim_movies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;dm&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MovieDataModule&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;full_training_df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full_test_df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batch_size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;512&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;recommender&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RecSys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Definimos el Callback:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;mc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ModelCheckpoint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;dirpath&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'checkpoints'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;#filename = 'best-checkpoint',
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;save_last&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;save_top_k&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;verbose&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;monitor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'train_loss'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
    &lt;span class=&quot;n&quot;&gt;mode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'min'&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;mc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CHECKPOINT_NAME_LAST&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'best-checkpoint-latest'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Un detalle acá es que aprendí que cambiando la variable &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;CHECKPOINT_NAME_LAST&lt;/code&gt; se puede tener el mejor checkpoint con un nombre fijo. De esta manera podemos automatizar el rescate del mejor estado del modelo ya que siempre tendrá el mismo nombre y no un &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;-v1&lt;/code&gt;, &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;-v2&lt;/code&gt;, &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;-v3&lt;/code&gt;, etc.&lt;/p&gt;

&lt;p&gt;Definimos el Trainer:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;trainer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Trainer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max_epochs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;accelerator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;gpu&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;devices&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                    &lt;span class=&quot;n&quot;&gt;callbacks&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; 
                    &lt;span class=&quot;n&quot;&gt;progress_bar_refresh_rate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                    &lt;span class=&quot;c1&quot;&gt;# fast_dev_run=True,
&lt;/span&gt;                    &lt;span class=&quot;c1&quot;&gt;#overfit_batches=1
&lt;/span&gt;                    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;trainer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;recommender&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Acá es importante destacar que hay cambios, ahora para ejecutar en gpu no utilizamos &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;gpus=1&lt;/code&gt; sino que definimos el &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;accelerator&lt;/code&gt; que puede ser gpu, tpu, ipu, etc. Y definimos el &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;devices&lt;/code&gt; que es el número de GPUs que queremos utilizar.
Pueden ver comentado dos comandos que uso para debuggear que la red funcione correctamente antes de dejarla harto rato corriendo:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-text highlighter-rouge&quot;&gt;fast_dev_run=True&lt;/code&gt; ejecuta una epoch de prueba para chequear por ejemplo que las dimensiones de los tensores funcionen bien.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-text highlighter-rouge&quot;&gt;overfit_batches=1&lt;/code&gt; sobreajusta una batch por cada epoch. Si el overfit funciona es que el modelo efectivamente tiene la posibilidad de aprender. Con esto se puede chequear que el modelo no diverge.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Normalmente ejecuto esto antes de dejar la red corriendo y luego de una larga epoch de entrenamiento darme cuenta que falló.&lt;/p&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;GPU available: True, used: True
TPU available: False, using: 0 TPU cores
IPU available: False, using: 0 IPUs
HPU available: False, using: 0 HPUs

LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]

  | Name      | Type              | Params
------------------------------------------------
0 | model     | NCF               | 653 K 
1 | criterion | BCEWithLogitsLoss | 0     
------------------------------------------------
653 K     Trainable params
0         Non-trainable params
653 K     Total params
2.612     Total estimated model params size (MB)



Training: 0it [00:00, ?it/s]


Epoch 0, global step 24996: 'train_loss' reached 0.08028 (best 0.08028), saving model to '/home/alfonso/Documents/kaggle/recom/checkpoints/epoch=0-step=24996.ckpt' as top 1
Epoch 1, global step 49992: 'train_loss' was not in top 1
Epoch 2, global step 74988: 'train_loss' reached 0.07823 (best 0.07823), saving model to '/home/alfonso/Documents/kaggle/recom/checkpoints/epoch=2-step=74988.ckpt' as top 1
Epoch 3, global step 99984: 'train_loss' reached 0.06737 (best 0.06737), saving model to '/home/alfonso/Documents/kaggle/recom/checkpoints/epoch=3-step=99984.ckpt' as top 1
Epoch 4, global step 124980: 'train_loss' reached 0.06487 (best 0.06487), saving model to '/home/alfonso/Documents/kaggle/recom/checkpoints/epoch=4-step=124980.ckpt' as top 1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;evaluación-del-modelo&quot;&gt;Evaluación del Modelo&lt;/h3&gt;

&lt;p&gt;Otro cambio, esta vez en Pytorch 1.11, es la introducción de un decorador de inferencia. Hacer esto es equivalente al &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;with torch.no_grad()&lt;/code&gt;.
Básicamente vaciaremos nuestro dataloader al modelo, aplicaremos la sigmoide que no colocamos en nuestro modelo e increiblemente descargando las predicciones a la CPU funcionó más rápido que la GPU (esto porque evita el overhead de subir los datos a la GPU para poder predecir).&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;torch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inference_mode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;predict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;eval&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;preds&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;test_dataloader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
        
        &lt;span class=&quot;n&quot;&gt;pred&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;torch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sigmoid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'users'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'movies'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;preds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;extend&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pred&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cpu&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;detach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;numpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
        
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;preds&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Luego convertimos todo en un Numpy Array para poder incluirlo en nuestro &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;full_test_df&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;predictions&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;predict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;recommender&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;predictions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;full_test_df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'preds'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;predictions&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;full_test_df&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;(6078000, 1)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div&gt;
&lt;style scoped=&quot;&quot;&gt;
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
&lt;/style&gt;
&lt;table border=&quot;1&quot; class=&quot;dataframe&quot;&gt;
  &lt;thead&gt;
    &lt;tr style=&quot;text-align: right;&quot;&gt;
      &lt;th&gt;&lt;/th&gt;
      &lt;th&gt;userId&lt;/th&gt;
      &lt;th&gt;movieId&lt;/th&gt;
      &lt;th&gt;rating&lt;/th&gt;
      &lt;th&gt;preds&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;th&gt;734&lt;/th&gt;
      &lt;td&gt;0&lt;/td&gt;
      &lt;td&gt;230&lt;/td&gt;
      &lt;td&gt;1.0&lt;/td&gt;
      &lt;td&gt;0.987030&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;1066&lt;/th&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;929&lt;/td&gt;
      &lt;td&gt;1.0&lt;/td&gt;
      &lt;td&gt;0.749257&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;2855&lt;/th&gt;
      &lt;td&gt;2&lt;/td&gt;
      &lt;td&gt;465&lt;/td&gt;
      &lt;td&gt;1.0&lt;/td&gt;
      &lt;td&gt;0.911151&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;2889&lt;/th&gt;
      &lt;td&gt;3&lt;/td&gt;
      &lt;td&gt;2505&lt;/td&gt;
      &lt;td&gt;1.0&lt;/td&gt;
      &lt;td&gt;0.973490&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;3015&lt;/th&gt;
      &lt;td&gt;4&lt;/td&gt;
      &lt;td&gt;9907&lt;/td&gt;
      &lt;td&gt;1.0&lt;/td&gt;
      &lt;td&gt;0.959640&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;...&lt;/th&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
      &lt;td&gt;...&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;6017215&lt;/th&gt;
      &lt;td&gt;60779&lt;/td&gt;
      &lt;td&gt;2442&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
      &lt;td&gt;0.006992&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;6017216&lt;/th&gt;
      &lt;td&gt;60779&lt;/td&gt;
      &lt;td&gt;10800&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
      &lt;td&gt;0.003167&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;6017217&lt;/th&gt;
      &lt;td&gt;60779&lt;/td&gt;
      &lt;td&gt;17767&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
      &lt;td&gt;0.000137&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;6017218&lt;/th&gt;
      &lt;td&gt;60779&lt;/td&gt;
      &lt;td&gt;7073&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
      &lt;td&gt;0.000070&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;6017219&lt;/th&gt;
      &lt;td&gt;60779&lt;/td&gt;
      &lt;td&gt;2124&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
      &lt;td&gt;0.000730&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;6078000 rows × 4 columns&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Para evaluar el modelo utilizaremos la métrica HitRatio@10. Esto quiere decir que si dentro de las 10 mejores predicciones por usuario, el usuario tiene la película vista entonces eso es un éxito.&lt;/p&gt;

&lt;div title=&quot;Cálculo 10 mejores predicciones por usuario&quot; class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;recomendations&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;full_test_df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sort_values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'userId'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'preds'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ascending&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;groupby&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'userId'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;En uno de los artículos que ví como referencia encontré la siguiente implementación:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# User-item pairs for testing
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;test_user_item_set&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;test_ratings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'userId'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test_ratings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'movieId'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Dict of all items that are interacted with by each user
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user_interacted_items&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ratings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;groupby&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'userId'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'movieId'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;hits&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test_user_item_set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;interacted_items&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_interacted_items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;not_interacted_items&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;all_movieIds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;interacted_items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;selected_not_interacted&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;choice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;not_interacted_items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;99&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;test_items&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;selected_not_interacted&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    
    &lt;span class=&quot;n&quot;&gt;predicted_labels&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;squeeze&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;torch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tensor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
                                        &lt;span class=&quot;n&quot;&gt;torch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tensor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;test_items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;detach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;numpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
    
    &lt;span class=&quot;n&quot;&gt;top10_items&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;test_items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argsort&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;predicted_labels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[::&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tolist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()]&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;top10_items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;hits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;hits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;The Hit Ratio @ 10 is {:.2f}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;average&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Sólo al verla me dio dolor de estomago, porque no la entiendo. Una manera mucho más sencilla es esta:&lt;/p&gt;

&lt;p&gt;Sabemos que sólo hay un 1 en cada usuario, por lo tanto &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;recomendations.rating.sum()&lt;/code&gt; nos dirá cuantas películas efectivamente vistas por nuestro usuario están en las 10 mejores recomendaciones. Si eso lo dividimos por el número de usuarios entonces tenemos el HitRatio@10&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;recomendations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rating&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;recomendations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;userId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nunique&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;0.9457880881869036
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;cómo-utilizamos-el-modelo&quot;&gt;¿Cómo Utilizamos el Modelo?&lt;/h2&gt;

&lt;p&gt;Bueno para poder operacionalizar el modelo entonces tenemos que llevar a nuestros Ids originales:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;back_to_normal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_encoder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;movie_encoder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;movies_mapping&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    
    &lt;span class=&quot;n&quot;&gt;idx_movies&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;movieId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tolist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;idx_users&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;userId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tolist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DataFrame&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;userId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_encoder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;classes_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;idx_users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;movieId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Series&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;movie_encoder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;classes_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;idx_movies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]).&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;movies_mapping&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;rating&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rating&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tolist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;vistos&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;back_to_normal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;train_ratings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_encoder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;movie_encoder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;movies_mapping&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;visto&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;(2651157, 3)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;recomendar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;back_to_normal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;recomendations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_encoder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;movie_encoder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;movies_mapping&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;recomendar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;(607800, 3)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-text highlighter-rouge&quot;&gt;visto&lt;/code&gt; corresponderá a las películas ya vistas por nuestro usuario, y &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;recomendar&lt;/code&gt; a las 10 mejores recomendaciones. Ojo que agregamos el movies_mapping del principio para poder tener el nombre de la película y no sólo el Id.&lt;/p&gt;

&lt;p&gt;Revisemos entonces algunas recomendaciones:&lt;/p&gt;

&lt;div class=&quot;alert-box warning radius &quot;&gt;&lt;p&gt;Al revisar los resultados me dí cuenta que sé muy poco de películas (a excepción de las películas de Marvel) pido perdón de antemano si mi análisis es un poco pobre, pero no soy muy cinéfilo XD.&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Por ejemplo, el usuario 4 parece que le gustan las películas de acción y ciencia ficción. Correctamente predijimos John Carter, que es la película que vio y además dado que ha visto varias películas del MCU se le recomienda ver Thor 2 (que es muy mala película, pero bueno, nada que hacer).&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visto&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'userId == @user'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'movieId'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;recomendar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'userId == @user'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;193                                Shutter Island (2010)
194    Percy Jackson &amp;amp; the Olympians: The Lightning T...
195                      How to Train Your Dragon (2010)
196                           Clash of the Titans (2010)
197                                    Iron Man 2 (2010)
                             ...                        
303             Spider-Man: Into the Spider-Verse (2018)
304             John Wick: Chapter 3 – Parabellum (2019)
305                    Pokémon: Detective Pikachu (2019)
306                               Ford v. Ferrari (2019)
307         Fast &amp;amp; Furious Presents: Hobbs &amp;amp; Shaw (2019)
Name: movieId, Length: 115, dtype: object
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div&gt;
&lt;style scoped=&quot;&quot;&gt;
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
&lt;/style&gt;
&lt;table border=&quot;1&quot; class=&quot;dataframe&quot;&gt;
  &lt;thead&gt;
    &lt;tr style=&quot;text-align: right;&quot;&gt;
      &lt;th&gt;&lt;/th&gt;
      &lt;th&gt;userId&lt;/th&gt;
      &lt;th&gt;movieId&lt;/th&gt;
      &lt;th&gt;rating&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;th&gt;10&lt;/th&gt;
      &lt;td&gt;4&lt;/td&gt;
      &lt;td&gt;Thor: The Dark World (2013)&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;11&lt;/th&gt;
      &lt;td&gt;4&lt;/td&gt;
      &lt;td&gt;Margin Call (2011)&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;12&lt;/th&gt;
      &lt;td&gt;4&lt;/td&gt;
      &lt;td&gt;Kubo and the Two Strings (2016)&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;13&lt;/th&gt;
      &lt;td&gt;4&lt;/td&gt;
      &lt;td&gt;John Carter (2012)&lt;/td&gt;
      &lt;td&gt;1.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;14&lt;/th&gt;
      &lt;td&gt;4&lt;/td&gt;
      &lt;td&gt;Autómata (Automata) (2014)&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;15&lt;/th&gt;
      &lt;td&gt;4&lt;/td&gt;
      &lt;td&gt;You Were Never Really Here (2017)&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;16&lt;/th&gt;
      &lt;td&gt;4&lt;/td&gt;
      &lt;td&gt;Aloha (2015)&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;17&lt;/th&gt;
      &lt;td&gt;4&lt;/td&gt;
      &lt;td&gt;Thanks for Sharing (2012)&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;18&lt;/th&gt;
      &lt;td&gt;4&lt;/td&gt;
      &lt;td&gt;Eva (2011)&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;19&lt;/th&gt;
      &lt;td&gt;4&lt;/td&gt;
      &lt;td&gt;Magic Mike XXL (2015)&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;El usuario 6225 parece que le gustan las películas de Romance, Miedo y Suspenso, y se recomienda correctamente Midnight in Paris que no tengo idea de qué trata pero podemos ver otras recomendaciones como Saw (Miedo), Friends with Benefits o Aladdin que serán medio Romance/Fantasía supongo.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6265&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visto&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'userId == @user'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'movieId'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;recomendar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'userId == @user'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;100326    Cabin in the Woods, The (2012)
100327                Snowpiercer (2013)
100328                  Gone Girl (2014)
100329         The Imitation Game (2014)
Name: movieId, dtype: object
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div&gt;
&lt;style scoped=&quot;&quot;&gt;
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
&lt;/style&gt;
&lt;table border=&quot;1&quot; class=&quot;dataframe&quot;&gt;
  &lt;thead&gt;
    &lt;tr style=&quot;text-align: right;&quot;&gt;
      &lt;th&gt;&lt;/th&gt;
      &lt;th&gt;userId&lt;/th&gt;
      &lt;th&gt;movieId&lt;/th&gt;
      &lt;th&gt;rating&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;th&gt;22630&lt;/th&gt;
      &lt;td&gt;6265&lt;/td&gt;
      &lt;td&gt;Midnight in Paris (2011)&lt;/td&gt;
      &lt;td&gt;1.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;22631&lt;/th&gt;
      &lt;td&gt;6265&lt;/td&gt;
      &lt;td&gt;Friends with Benefits (2011)&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;22632&lt;/th&gt;
      &lt;td&gt;6265&lt;/td&gt;
      &lt;td&gt;Saw VII 3D - The Final Chapter (2010)&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;22633&lt;/th&gt;
      &lt;td&gt;6265&lt;/td&gt;
      &lt;td&gt;Searching (2018)&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;22634&lt;/th&gt;
      &lt;td&gt;6265&lt;/td&gt;
      &lt;td&gt;Aladdin (2019)&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;22635&lt;/th&gt;
      &lt;td&gt;6265&lt;/td&gt;
      &lt;td&gt;The Dark Tower (2017)&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;22636&lt;/th&gt;
      &lt;td&gt;6265&lt;/td&gt;
      &lt;td&gt;The BFG (2016)&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;22637&lt;/th&gt;
      &lt;td&gt;6265&lt;/td&gt;
      &lt;td&gt;ARQ (2016)&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;22638&lt;/th&gt;
      &lt;td&gt;6265&lt;/td&gt;
      &lt;td&gt;A Wrinkle in Time (2018)&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;22639&lt;/th&gt;
      &lt;td&gt;6265&lt;/td&gt;
      &lt;td&gt;Magic of Belle Isle, The (2012)&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;El usuario 63 es como mi esposa, le gustan las películas livianitas, de monitos o para reirse, Tangled, Inside Out o Pitch Perfect sólo pueden recomendar algo como The Twilight Saga: Eclipse.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;63&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visto&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'userId == @user'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'movieId'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;recomendar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'userId == @user'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;623                              Easy A (2010)
624                             Tangled (2010)
625                         Bridesmaids (2011)
626                     Horrible Bosses (2011)
627                Crazy, Stupid, Love. (2011)
628                      21 Jump Street (2012)
629                       Pitch Perfect (2012)
630    Perks of Being a Wallflower, The (2012)
631                   Great Gatsby, The (2013)
632                      Now You See Me (2013)
633                   We're the Millers (2013)
634                          About Time (2013)
635            Wolf of Wall Street, The (2013)
636                           Gone Girl (2014)
637                          Inside Out (2015)
638                                Room (2015)
639                               Moana (2016)
640                                Coco (2017)
Name: movieId, dtype: object
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div&gt;
&lt;style scoped=&quot;&quot;&gt;
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
&lt;/style&gt;
&lt;table border=&quot;1&quot; class=&quot;dataframe&quot;&gt;
  &lt;thead&gt;
    &lt;tr style=&quot;text-align: right;&quot;&gt;
      &lt;th&gt;&lt;/th&gt;
      &lt;th&gt;userId&lt;/th&gt;
      &lt;th&gt;movieId&lt;/th&gt;
      &lt;th&gt;rating&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;th&gt;200&lt;/th&gt;
      &lt;td&gt;63&lt;/td&gt;
      &lt;td&gt;Spotlight (2015)&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;201&lt;/th&gt;
      &lt;td&gt;63&lt;/td&gt;
      &lt;td&gt;Twilight Saga: Eclipse, The (2010)&lt;/td&gt;
      &lt;td&gt;1.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;202&lt;/th&gt;
      &lt;td&gt;63&lt;/td&gt;
      &lt;td&gt;Sorcerer's Apprentice, The (2010)&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;203&lt;/th&gt;
      &lt;td&gt;63&lt;/td&gt;
      &lt;td&gt;Melancholia (2011)&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;204&lt;/th&gt;
      &lt;td&gt;63&lt;/td&gt;
      &lt;td&gt;Oz the Great and Powerful (2013)&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;205&lt;/th&gt;
      &lt;td&gt;63&lt;/td&gt;
      &lt;td&gt;Venom (2018)&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;206&lt;/th&gt;
      &lt;td&gt;63&lt;/td&gt;
      &lt;td&gt;Selma (2014)&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;207&lt;/th&gt;
      &lt;td&gt;63&lt;/td&gt;
      &lt;td&gt;Burlesque (2010)&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;208&lt;/th&gt;
      &lt;td&gt;63&lt;/td&gt;
      &lt;td&gt;Silent Hill: Revelation 3D (2012)&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;209&lt;/th&gt;
      &lt;td&gt;63&lt;/td&gt;
      &lt;td&gt;Double, The (2011)&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;El usuario 162532 es de los míos, harta película de Acción, del MCU y como de Niños (Despicable Me) y se recomienda Guardians of the Galaxy (muy buena película) y Spy Kids que es de Acción e Infantil que también es rebuena.&lt;/p&gt;
&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;162532&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;visto&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'userId == @user'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'movieId'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;recomendar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'userId == @user'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;2650878                      How to Train Your Dragon (2010)
2650879                                      Kick-Ass (2010)
2650880                    Exit Through the Gift Shop (2010)
2650881                                    Iron Man 2 (2010)
2650882                                 Despicable Me (2010)
2650883                                     Inception (2010)
2650884                   Scott Pilgrim vs. the World (2010)
2650885                           Social Network, The (2010)
2650886                                        Easy A (2010)
2650887    Harry Potter and the Deathly Hallows: Part 1 (...
2650888                            King's Speech, The (2010)
2650889                                   Source Code (2011)
2650890                                          Thor (2011)
2650891                            X-Men: First Class (2011)
2650892    Harry Potter and the Deathly Hallows: Part 2 (...
2650893            Captain America: The First Avenger (2011)
2650894                                 Avengers, The (2012)
2650895                                          Hugo (2011)
2650896                              The Hunger Games (2012)
2650897                        Dark Knight Rises, The (2012)
2650898            Sherlock Holmes: A Game of Shadows (2011)
2650899                                  Intouchables (2011)
2650900                                        Looper (2012)
2650901                                          Argo (2012)
2650902                       Silver Linings Playbook (2012)
2650903            Hobbit: An Unexpected Journey, The (2012)
2650904                                    Iron Man 3 (2013)
Name: movieId, dtype: object
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div&gt;
&lt;style scoped=&quot;&quot;&gt;
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
&lt;/style&gt;
&lt;table border=&quot;1&quot; class=&quot;dataframe&quot;&gt;
  &lt;thead&gt;
    &lt;tr style=&quot;text-align: right;&quot;&gt;
      &lt;th&gt;&lt;/th&gt;
      &lt;th&gt;userId&lt;/th&gt;
      &lt;th&gt;movieId&lt;/th&gt;
      &lt;th&gt;rating&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;th&gt;607750&lt;/th&gt;
      &lt;td&gt;162532&lt;/td&gt;
      &lt;td&gt;Guardians of the Galaxy (2014)&lt;/td&gt;
      &lt;td&gt;1.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;607751&lt;/th&gt;
      &lt;td&gt;162532&lt;/td&gt;
      &lt;td&gt;Only the Brave (2017)&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;607752&lt;/th&gt;
      &lt;td&gt;162532&lt;/td&gt;
      &lt;td&gt;Immigrant, The (2013)&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;607753&lt;/th&gt;
      &lt;td&gt;162532&lt;/td&gt;
      &lt;td&gt;Diary of a Wimpy Kid: Rodrick Rules (2011)&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;607754&lt;/th&gt;
      &lt;td&gt;162532&lt;/td&gt;
      &lt;td&gt;Spy Kids: All the Time in the World in 4D (2011)&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;607755&lt;/th&gt;
      &lt;td&gt;162532&lt;/td&gt;
      &lt;td&gt;The Belko Experiment (2017)&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;607756&lt;/th&gt;
      &lt;td&gt;162532&lt;/td&gt;
      &lt;td&gt;All the Way (2016)&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;607757&lt;/th&gt;
      &lt;td&gt;162532&lt;/td&gt;
      &lt;td&gt;Come Together (2016)&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;607758&lt;/th&gt;
      &lt;td&gt;162532&lt;/td&gt;
      &lt;td&gt;Batman: Gotham by Gaslight (2018)&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;607759&lt;/th&gt;
      &lt;td&gt;162532&lt;/td&gt;
      &lt;td&gt;Kizumonogatari Part 1: Tekketsu (2016)&lt;/td&gt;
      &lt;td&gt;0.0&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;

&lt;h2 id=&quot;conclusiones&quot;&gt;Conclusiones&lt;/h2&gt;

&lt;p&gt;Creo que el Modelo funciona sumamente bien. Cabe destacar que estamos haciendo el trabajo bien dificil porque en estricto rigor nosotros deberíamos predecir el Rating de todas las películas del catálogo y entregar las 10 mejores, y estamos haciendo un random de 99 películas que puede que no tengan nada que ver con el usuario y aún así el modelo es capaz de ordenar las predicciones de buena manera.&lt;/p&gt;

&lt;p&gt;Es interesante que gran parte del modelo de Recomendación tiene que ver con el manejo de la data y cómo vamos a operacionalizarlo. No es llegar y hacer un predict sino que es necesario pensar en una estrategia para poder mostrar esto.&lt;/p&gt;

&lt;p&gt;Una de las ventajas de este tipo de modelo es que podemos tener todas las predicciones hechas por ejemplo en la noche y luego operacionalizarlas en nuestro front-end. Esto es beneficioso también en el sentido que una inferencia en tiempo real para semejante cantidad de datos es difícil.&lt;/p&gt;

&lt;p&gt;Una desventaja de este tipo de modelos es que sólo pueden entregar recomendaciones a los usuarios que ya han visto películas y que ya se encuentran en la user-item matrix. Esto es lo que se conoce como el cold-start problem. No sé muy bien como se soluciona pero en la forma en la que se planteó esta solución no es posible decir me gusta A, B, C, entonces, ¿qué me recomiendas? Deben existir otro tipo de modelos que sí pueden lidiar con esto, pero que no manejo.&lt;/p&gt;

&lt;p&gt;Eso es todo por esta semana, espero les haya gustado y gracias Gustavo, aprendí harto de Sistemas Recomendadores (aunque me sacó canas verdes) durante este fin de semana.&lt;/p&gt;

&lt;p&gt;Hasta la otra,&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/contact/&quot;&gt;&lt;strong&gt;Alfonso&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
</content>

			
				<category term="pp" />
			
			
				<category term="pytorch" />
			
				<category term="tutorial" />
			
				<category term="dl" />
			

			<published>2022-04-25T00:00:00+00:00</published>
		</entry>
	
		<entry>
			<id>http://datacuber.github.io/cml/</id>
			<title>Github para Data Science Pt. 3</title>
			<link href="http://datacuber.github.io/cml/" rel="alternate" type="text/html" title="Github para Data Science Pt. 3" />
			<updated>2022-04-11T00:00:00+00:00</updated>

			
			<summary>CI/CD en Machine Learning</summary>
			<content type="html" xml:base="http://datacuber.github.io/cml/">&lt;p&gt;&lt;img src=&quot;/images/cml/cml.png&quot; alt=&quot;picture of me&quot; class=&quot;left show-for-large-up hide-for-print&quot; width=&quot;250&quot; /&gt;
&lt;img src=&quot;/images/cml/cml.png&quot; alt=&quot;picture of me&quot; class=&quot;center hide-for-large-up&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Siguiendo un poco con la racha de tutoriales dedicado al uso de Github, hoy quiero hablar de un tercer punto que creo que es importante que es la automatización al momento de productivizar. Yo soy Data Scientist, pero me gustaría mucho en el futuro cercano trabajar como Machine Learning Engineer y creo que una de las cosas más importantes de aprender en el desarrollo de software es CI/CD.&lt;!--more--&gt;&lt;/p&gt;

&lt;h2 id=&quot;cicd&quot;&gt;CI/CD&lt;/h2&gt;

&lt;p&gt;Corresponde a la sigla para &lt;em&gt;Continuous Integration / Continuous Delivery&lt;/em&gt; y en el desarrollo de software se usa para automatizar tareas que siempre deben de ejecutarse para asegurar que el producto a productivizar es infalible, ojalá libre de errores y que pasa todos los test de calidad que el mismo proyecto se ha impuesto. Normalmente el Proceso de CI/CD incluirá procesos de Unit Testing, Deploy, Dockerización y un largo etc.&lt;/p&gt;

&lt;p&gt;Cuando pensamos en el desarrollo de Machine Learning es un poco distinto. Hoy no quiero hablar de cómo hacer el deploy y el proceso de MLOps que uno debería seguir, sino más bien de cómo poder automatizar el proceso de Experimentación y que pueda ser revisado de manera más amena.&lt;/p&gt;

&lt;p&gt;Pongo el siguiente caso (porque lo he vivido):&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Tengo un proyecto.&lt;/li&gt;
  &lt;li&gt;Tengo un Product Owner, que normalmente no entiende nada de código (esto me parece que no debiera ser así y deberían empezar a interiorizarse más en el tema. Siempre se habla de que el DS tiene que entender del negocio para poder explicar a los stakeholders, pero el negocio nunca hace un esfuerzo por entender lo técnico, en fin, pelea para otro día).&lt;/li&gt;
  &lt;li&gt;El Product Owner quiere entender si tenemos alguna mejora, es decir, si el modelo está mejorando o no.&lt;/li&gt;
  &lt;li&gt;Cita a una Reunión en la que hay mostrarle el &lt;em&gt;Jupyter Notebook&lt;/em&gt; y llegamos a las métricas finales.&lt;/li&gt;
  &lt;li&gt;Finalmente el interés del PO es: &lt;em&gt;¿Mejoramos el Accuracy/Recall/Valor para el negocio/etc. o no?&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Y la reunión termina con un &lt;em&gt;¿y probaste X, probaste Y o probaste Z? ¿Mejora o no?&lt;/em&gt; Y uno rápidamente tiene que ponerse a corregir el notebook en vivo o citar a otra reunión para volver a tener la misma conversación y mostrar los nuevos resultados.&lt;/p&gt;

&lt;p&gt;Bueno, creo que todo este proceso tedioso podría hacerse de manera asíncrona, sin perder tiempo en reuniones y tener la discusión en un Pull Request (que creo que es algo que un PO debería poder saber qué es, cómo hacerlo y cómo interactuar con él).&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://iterative.ai/&quot;&gt;iterative.ai&lt;/a&gt; desarrolló una herramienta llamada &lt;a href=&quot;https://cml.dev/&quot;&gt;CML&lt;/a&gt; una herramienta para Continuous Machine Learning.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Si bien creo que es una herramienta bastante básica y en pleno desarrollo, creo que aporta con varios elementos que nos permiten solucionar el problema que expongo anteriormente. Es fácil de usar y cumple su objetivo que es lo más importante de todo que es generar reportes, en medio del Pull Request para mostrar en simple los avances del código del modelo.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;CML funciona con Github Actions. Github Actions es la herramienta que Github provee para hacer CI/CD. Github Actions básicamente crea una maquina virtual (VM) de manera automatizada donde se ejecutarán los comandos que uno le indique. Estos comandos pueden ejecutarse cada vez que se hace un commit, push, PR, etc. Dentro de esa VM nosotros ejecutaremos CML, el cual nos permitirá crear dicho reporte con lo que nosotros indiquemos.&lt;/p&gt;

&lt;div class=&quot;alert-box todo radius &quot;&gt;&lt;p&gt;Creo que CML se puede utilizar para bastantes cosas más, pero aún estoy aprendiendo y haciendo pruebas de en qué flujos podría ser una alternativa.&lt;/p&gt;
&lt;/div&gt;

&lt;div class=&quot;alert-box info radius &quot;&gt;&lt;p&gt;CML es compatible también con Gitlab CI, y tiene una imagen Docker prefabricada, por lo que en caso de tener Circle CI, Travis CI, Jenkins o cualquier otra alternativa de CI/CD también debería ser posible utilizarlo.&lt;/p&gt;
&lt;/div&gt;

&lt;h2 id=&quot;github-actions&quot;&gt;Github Actions&lt;/h2&gt;

&lt;p&gt;Bueno Github Actions está disponible en cualquier repositorio de Github. Basicamente una Action es un Script que permite crear un ambiente virtual en el que podemos tener cosas pre-instaladas, o podemos cargar una imagen Docker. Todo usuario de Github tiene gratis varios minutos al mes de Github Actions, luego de esa cuota se empieza a cobrar para tener acceso a minutos adicionales. Si les interesa pueden ver los precios &lt;a href=&quot;https://github.com/pricing&quot;&gt;acá&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;alert-box tip radius &quot;&gt;&lt;p&gt;Acabo de volverme Github Pro y eso aumenta la cuota de minutos mensuales de 2000 a 3000, que creo que para un usuario normal es suficiente. En el caso de empresas es recomendable que tenga un plan.&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Entonces para utilizar Github Actions basta con que tu repo contenga una carpeta llamada &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;.github/workflows&lt;/code&gt;. Dentro de esta carpeta crearemos un archivo yaml, el cual puede tener cualquier nombre.&lt;/p&gt;

&lt;p&gt;Para mostrar esto con ejemplos concretos utilizaremos el Repo utilizado en el tutorial de &lt;a href=&quot;https://github.com/datacubeR/dvc_tutorial&quot;&gt;DVC&lt;/a&gt;. Además para seguir un correcto uso de GIT crearé una Rama llamada &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;CML&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git checkout &lt;span class=&quot;nt&quot;&gt;-b&lt;/span&gt; CML
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Dentro de esta rama crearé el siguiente archivo ´cml.yaml´:&lt;/p&gt;

&lt;div title=&quot;Archivo cml.yaml para lanzar Github Actions.&quot; class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;train-my-model&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;jobs&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;train-model&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;runs-on&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;steps&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;actions/checkout@v2&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;iterative/setup-cml@v1&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;actions/setup-python@v2&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;python-version&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;3.x'&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Train model&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;repo_token&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;$&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;|&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;pip3 install -r requirements.txt&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;dvc repro&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;# Create CML report&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;echo &quot;## Metrics&quot; &amp;gt;&amp;gt; report.md&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;dvc metrics show --show-md &amp;gt;&amp;gt; report.md&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;cml publish conf_mat.png --md &amp;gt;&amp;gt; report.md&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;cml send-comment report.md&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Este archivo puede verse muy complejo de entender, pero paso a explicar parte por parte en detalle:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;name&lt;/strong&gt;: No es nada más que el nombre que yo le doy a mi proceso, no afecta a mi proceso de CI/CD.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;on&lt;/strong&gt;: Esto indica cuando se va a ejecutar la Action. En este caso esto se va a ejecutar siempre y cuando haga un push. Pero existen distintas opciones que se pueden ver &lt;a href=&quot;https://docs.github.com/es/actions/using-workflows/workflow-syntax-for-github-actions&quot;&gt;acá&lt;/a&gt;. Github actions es tán flexible que se pueden ejecutar en distintos eventos, en ramas específicas, etc.&lt;/li&gt;
  &lt;li&gt;Luego jobs especificará qué hará el proceso:
    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;runs-on&lt;/strong&gt;: Indica en qué ambiente correrá. En este caso se indica una maquina virtual con ubuntu-latest. Lo más común es usar ubuntu ya que es lo más barato y fácil, otras opciones incluyen Windows y MacOs que son más caras. En mi opinión Ubuntu es suficiente a menos que tengas dependencia de OS, por ejemplo, si estás desarrollando un app para Mac y tiene que probarse en dicho OS.&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;steps&lt;/strong&gt;: Indica qué se va a instalar en la VM. Hay que entender la VM es una maquina creada de cero, no tiene nada.&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;uses&lt;/strong&gt;: Son las Actions predefinidas que se van a cargar, esto normalmente sirven como preparación del ambiente:
        &lt;ul&gt;
          &lt;li&gt;&lt;strong&gt;actions/checkout@v2&lt;/strong&gt;: Esto lo que hace es cargar toda la Info del commit para que esté disponible en la maquina. Si no hacemos esto, nuestros scripts no pueden ser vistos por la VM.&lt;/li&gt;
          &lt;li&gt;&lt;strong&gt;iterative/setup-cml@v1&lt;/strong&gt;: Esta instala CML, y está indicado en la Documentación de CML como una línea obligatoria.&lt;/li&gt;
          &lt;li&gt;&lt;strong&gt;actions/setup-python@v2&lt;/strong&gt;: Instala Python. Tengo dudas si este paso es realmente necesario porque en la Doc dice que la Action de CML ya tiene Python incluido, pero igual en su ejemplo usan este paso.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;name&lt;/strong&gt;: Este otro name ahora indica el nombre de una etapa. Uno eventualmente puede dividir su Action en varias etapas.&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;env&lt;/strong&gt;: Declara variables de entorno.
        &lt;ul&gt;
          &lt;li&gt;&lt;strong&gt;repo_token&lt;/strong&gt;: $ Esta es una variable de entorno propia del Repo de Github. La razón de agregarla es que para que CML pueda comentar dentro del PR que vamos a generar.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;run&lt;/strong&gt;: Finalmente este comando permite ejecutar cualquier tipo de comando válido en la VM.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;modificaciones-en-esta-rama&quot;&gt;Modificaciones en esta Rama&lt;/h2&gt;

&lt;p&gt;Aparte de que nuestra rama agrega &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;cml.yaml&lt;/code&gt; para configurar Github Actions, hicimos las siguientes modificaciones:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Creamos un archivo &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;requirements.txt&lt;/code&gt; para definir las dependencias de nuestro proyecto. Esto es importante ya que, como dijimos anteriormente, nuestra VM de Github Actions no tiene nada instalado.&lt;/li&gt;
&lt;/ul&gt;

&lt;div title=&quot;requirements.txt&quot; class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;gdown
pandas
dvc
scikit-learn
matplotlib
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Modificamos nuestro script &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;src/04-evaluate_model.py&lt;/code&gt; de la siguiente forma:&lt;/li&gt;
&lt;/ul&gt;

&lt;div title=&quot;src/04-evaluate_model.py&quot; class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;json&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;joblib&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pandas&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sklearn.metrics&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;accuracy_score&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;recall_score&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ConfusionMatrixDisplay&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;matplotlib.pyplot&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;plt&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;config&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Config&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;X_test&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_csv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FEATURES_PATH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'test_features.csv'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;y_test&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_csv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;FEATURES_PATH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'test_labels.csv'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;joblib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MODELS_PATH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'model.joblib'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;y_pred&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;predict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;X_test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;output&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test_accuracy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;accuracy_score&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y_test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y_pred&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;test_recall&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;recall_score&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y_test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y_pred&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;average&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'macro'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;METRICS_PATH&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'w'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;outfile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dump&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;outfile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;ConfusionMatrixDisplay&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;from_predictions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y_test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y_pred&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;plt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Confusion Matrix for NBA Positions.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;plt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xlabel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Posiciones Predichas&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;plt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ylabel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Posiciones Reales&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;plt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;savefig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'conf_mat.png'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Básicamente sólo importamos matplotlib y agregamos una Matriz de Confusión la cual guardamos como &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;conf_mat.png&lt;/code&gt;. Ojo, Scikit-Learn cambió su API gráfica de curvas desde la versión 1.0. Personalmente me gustó mucho la nueva API, ya que permite crear curvas &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;from_prediction&lt;/code&gt;, &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;from_model&lt;/code&gt; y como clase. Para entender más como funciona la nueva interfaz pueden ir &lt;a href=&quot;https://scikit-learn.org/stable/visualizations.html&quot;&gt;acá&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Entonces teniendo estos cambios nuestro &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;run&lt;/code&gt;, que quizas es la única parte que nos corresponde modificar al momento de setear Github Actions, queda así:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Instalamos las dependencias de nuestro proyecto con &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;pip install -r requirements.txt&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Luego hacemos &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;dvc repro&lt;/code&gt; para ejecutar nuestro experimento.&lt;/li&gt;
  &lt;li&gt;Luego tenemos los siguientes comandos:
    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;echo “## Metrics” » report.md&lt;/strong&gt;: Esto escribe Metrics como Título dos y lo guarda en un archivo llamado report.md&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;dvc metrics show –show-md » report.md&lt;/strong&gt;: Esto toma las métricas de nuestro modelo las convierte en formato markdown y le hace un append al mismo archivo report.md.&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;cml publish conf_mat.png –md » report.md&lt;/strong&gt;: &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;cml publish&lt;/code&gt; corresponde a uno de los comandos de CML, tomará en este caso el archivo &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;.png&lt;/code&gt; y lo inserta en el archivo report.md. Publish se utiliza sólo con imágenes.&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-text highlighter-rouge&quot;&gt;cml send-comment report.md&lt;/code&gt; tomará nuestro archivo y lo publica como un comentario en nuestro Pull Request.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Al hacer los cambios mandamos todo a Github:&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git add &lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git commit &lt;span class=&quot;nt&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Adding CI/CD'&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git push &lt;span class=&quot;nt&quot;&gt;--set-upstream&lt;/span&gt; origin CML
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Al ejecutar esto, creamos el Pull Request. Si ahora vamos a Github en la pestaña Actions veremos algo así:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/cml/action.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;En este caso el workflow posee el Mensaje del Commit, la Rama y un color que puede ser Rojo si falla, Amarillo cuando se está ejecutando y verde cuando se ejecutó sin problemas.&lt;/p&gt;

&lt;p&gt;Al clickear en el Workflow encuentran esto:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/cml/action_2.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;En este caso vemos, el nombre de la etapa Train Model se transforma en &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;train-model&lt;/code&gt; y nos dice que el proceso fue exitoso y duró 1m 45s. Esto es importante porque acá Github va llevando registro de nuestra cuota mensual. Si clickeamos nuevamente en &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;train-model&lt;/code&gt; vemos lo siguiente:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/cml/action_3.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Acá podemos ver un desglose de todo. Podemos notar que nuestro proceso de entrenamiento es el que más tiempo toma con 1m 6s debido a la instalación de las librerías más la ejecución de nuestro Pipeline. Luego lo que más demora es la instalación de CML con 25s. Ante la duda de si utilizar o no la Action con Python es indistinto ya que tomó 0 segundos.&lt;/p&gt;

&lt;p&gt;Finalmente si volvemos al Pull Request veremos el resultado:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/cml/resultado_CML.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Podemos ver las métricas obtenidas en nuestro tutorial anterior. Y además tenemos una Matriz de Confusión, la cual podría ser útil para nuestro PO para poder evaluar si el nuevo modelo cumple con sus expectativas o no. Obviamente, esto es un ejemplo, y dependiendo del proyecto podremos definir cuales son las gráficas y métricas de interés para medir si nuestro proyecto está avanzando o no. En el caso de que este modelo cumpla con las expectativas podemos hacer el merge con Master para pasarlo como nuestro modelo actual.&lt;/p&gt;

&lt;div class=&quot;alert-box info radius &quot;&gt;&lt;p&gt;Como justo terminó la temporada regular de la NBA podríamos desviarnos un poquito a analizar los resultados del modelo. No tiene que ver con el tutorial pero es importante entender para qué serviría colocar una gráfica así en el Pull Request.&lt;/p&gt;

&lt;p&gt;Dijimos que la intención del modelo es poder entender de acuerdo a las estadísticas del jugador, cuál podría ser una posición adecuada. Si miramos nuestras métricas, son pésimas, pero ¿quiere decir que nuestro modelo es realmente inservible?&lt;/p&gt;

&lt;p&gt;Si analizamos la Matriz de Confusión que está hecha para el Test Set, podemos notar que nuestro modelo tiene grandes problemas para diferenciar, por ejemplo, un Centro (C) de un Power Forward (PF). Y tiene razón, hoy en día el Centro (C) es una pieza fundamental en el ataque no sólo como el reboteador del equipo y quien hace las pantallas, sino como anotador y pasador (algunos hasta anotando triples). En mi opinión, Anthony Davis (PF), Giannis Antetokounmpo (PF), Nikola Jokic (C) y Joel Embid (C) son el mismo monstruo. Tipos gigantes y atléticos (Jokic un poco menos) pero extremadamente completos, que sólo juegan en esas posiciones por su altura y poder, pero podrían jugar en cualquier posición. Se entiende que en la NBA actual el modelo tenga problemas diferenciando dichas posiciones.&lt;/p&gt;

&lt;p&gt;Por otro lado, se ve una tremenda confusión entre los PF, SG y PG. Y en mi opinión la NBA actual ya no sigue para nada dichas posiciones. Los Point Guards (PG) solían ser tipos pequeñitos muy hábiles que destacaban por su habilidad para pasar (recordar John Stockton, Tony Parker, Steve Nash, Jason Kidd). Hoy son el show de cada partido: Steph Curry, Ja Morant, Chris Paul, Kyrie Irving. Si bien algunos siguen el esterotipo, podrían perfectamente jugar de SG o SF por su habilidad anotadora si tuvieran mayor corpulencia. Por el otro lado, los SG eran los anotadores con buen dominio de balón y los SF eran Anotdores, robustos que no tenían tanta habilidad en el dribble pero hoy: Lebron James (SF), Kevin Durant (SF), Kawhi Leonard (SF), James Harden (SG), Donovan Mitchell (SG) o Devin Booker (SG), son jugadores prácticamente intercambiables. Son tan completos que la única razón por la que no juegan de PF o C es su altura o robustez, pero en muchas ocasiones durante partidos se les ve ejerciendo el rol de armador (PG).&lt;/p&gt;

&lt;p&gt;Con esto no quiero defender al modelo, efectivamente sus métricas están mal, pero analizando una simple Matriz de Confusión más un poquito de Conocimiento del Juego se pueden obtener muy buenos insights para mejorar el modelo (y obtener valor). Por ejemplo, incluir altura y peso para definir de mejor manera las posiciones dentro de la cancha, ya que diría que hoy ya no es un tema de habilidad, sino más bien de corpulencia.&lt;/p&gt;
&lt;/div&gt;

&lt;div class=&quot;alert-box alert radius &quot;&gt;&lt;p&gt;Setear un Action la primera vez no es fácil, de hecho pueden ir a mi &lt;a href=&quot;https://github.com/datacubeR/dvc_tutorial/actions&quot;&gt;tab&lt;/a&gt; de Actions para ver todas los workflows fallidos que tuve antes de encontrar la combinación correcta. Lo bueno es que una vez que la configuración está correctamente hecha no hay que preocuparse más&lt;/p&gt;
&lt;/div&gt;

&lt;h2 id=&quot;cómo-combinar-cml-con-la-interfaz-de-experimentación&quot;&gt;¿Cómo Combinar CML con la Interfaz de Experimentación?&lt;/h2&gt;

&lt;p&gt;Uno de los flujos que consideré que podía ser bueno utilizar CML es para experimentar. Lamentablemente me encontré con un muro. Mi idea era utilizar el Workflow para ejecutar todas los experimentos y generar un reporte de todo lo obtenido con el fin de que todo se hiciera en la maquina virtual y no en mi maquina, cosa que yo pudiera seguir trabajando.&lt;/p&gt;

&lt;div class=&quot;alert-box info radius &quot;&gt;&lt;p&gt;Github Actions permite utilizar self-hosted servers, es decir podríamos correr estos procesos en un servidor propio o incluso en máquinas Cloud (esto queda para una futura iteración)&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Lamentablemente, &lt;del&gt;CML no está pensado para experimentar y luego de muchas pruebas fallidas intentando correr experimentos me di cuenta de que no se podía. Aún así llegué al siguiente flujo el cual se puede ver en mi rama rama-experimental.&lt;/del&gt; la Documentación de DVC y CML no estaba preparada para esto. Intentando muchas pruebas no encontré solución, por lo que decidí abrir un issue en el repo de DVC que pueden ver &lt;a href=&quot;https://github.com/iterative/dvc/issues/7547&quot;&gt;acá&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;alert-box alert radius &quot;&gt;&lt;p&gt;La verdad es que tenía pensado sacar este tutorial la semana anterior, pero al encontrarme con esto decidí que no era buena idea. De hecho en un momento hasta pensé que no valía la pena aprender CML. Pero gracias a la ayuda de los mantenedores logramos sacar el tutorial adelante.&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Por lo tanto, para poder generar una interfaz remota de experimentación crearemos una nueva rama:&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git checkout &lt;span class=&quot;nt&quot;&gt;-b&lt;/span&gt; rama-experimental
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;En esta rama considero los mismos cambios de la Rama CML pero agrego los siguientes:&lt;/p&gt;

&lt;p&gt;Cree el archivo &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;exp_file.sh&lt;/code&gt; en el cual setié experimentos:&lt;/p&gt;

&lt;div title=&quot;exp_file.sh&quot; class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;dvc exp run &lt;span class=&quot;nt&quot;&gt;--queue&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-S&lt;/span&gt; train.C&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;5
dvc exp run &lt;span class=&quot;nt&quot;&gt;--queue&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-S&lt;/span&gt; train.C&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;30
dvc exp run &lt;span class=&quot;nt&quot;&gt;--queue&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-S&lt;/span&gt; train.C&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;60
dvc exp run &lt;span class=&quot;nt&quot;&gt;--queue&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-S&lt;/span&gt; train.C&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;120

dvc exp run &lt;span class=&quot;nt&quot;&gt;--run-all&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Como se puede ver, generé 4 experimentos en el cual pruebo los valores C=5,30,60,120. El flag &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;--queue&lt;/code&gt; permite generar una cola de experimentos los cuales se correrán con &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;dvc exp run --run-all&lt;/code&gt; lo cual puede ser súper útil para dejar ejecutando e irse a descansar.&lt;/p&gt;

&lt;p&gt;Luego para poder hacer correr la interfaz de experimentación en Github Actions tuve que modificar el cml.yaml de la siguiente manera:&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;experiments&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;jobs&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;train-model&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;runs-on&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;steps&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;actions/checkout@v3&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; 
          &lt;span class=&quot;na&quot;&gt;fetch-depth&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;fregante/setup-git-user@v1&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;iterative/setup-cml@v1&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;iterative/setup-dvc@v1&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;actions/setup-python@v2&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;python-version&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;3.x'&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Experiment&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;repo_token&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;$&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;|&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;pip3 install -r requirements.txt&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;bash exp_file.sh&lt;/span&gt;

          &lt;span class=&quot;s&quot;&gt;echo &quot;## Resultados del Experimento&quot; &amp;gt;&amp;gt; report.md&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;dvc exp show --only-changed --drop 'assets|src' --no-pager --md &amp;gt;&amp;gt; report.md&lt;/span&gt;

          &lt;span class=&quot;s&quot;&gt;cml send-comment report.md&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;De acuerdo a los comentarios en el issue, &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;dvc exp run&lt;/code&gt; requiere la historia de GIT completa y no sólo un shallow-clone. Por defecto &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;actions/checkout@v3&lt;/code&gt; hace un checkout sólo del commit actual, lo que no es suficiente. Agregando el &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;fetch-depth: 0&lt;/code&gt; tenemos la historia completa que permite a DVC funcionar correctamente.&lt;/p&gt;

&lt;div class=&quot;alert-box info radius &quot;&gt;&lt;p&gt;Durante esta semana salió &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;actions/checkout@v3&lt;/code&gt; que tiene unas mejoras de performance respecto &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;actions/checkout@v2&lt;/code&gt;. Yo probé todos los workflows probando ambas y cualquiera que quieras utilizar funciona bien siempre y cuando se agregue el &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;fetch_depth: 0&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Al intentar esto, me dí cuenta de que DVC necesita conectarse con tu cuenta de GIT. Y lamentablemente dentro de la maquina virtual DVC no tiene tus credenciales de GIT. Para solucionar esto, encontré otra action que lo hace, con lo que basta agregar la línea &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;uses: fregante/setup-git-user@v1&lt;/code&gt; y asunto solucionado.&lt;/p&gt;

&lt;p&gt;Finalmente indagando dentro de la documentación de DVC encontré que desarrollaron un Action para instalar DVC de manera más rápida que el &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;pip install&lt;/code&gt;. Aplicamos dicho paso utilizando la línea &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;uses: iterative/setup-dvc@v1&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;alert-box warning radius &quot;&gt;&lt;p&gt;Aún así tuve que dejar DVC como dependencia ya que &lt;code class=&quot;language-text highlighter-rouge&quot;&gt;pip install dvc&lt;/code&gt; instala el paquete yaml, el cual es dependencia para usar parámetros. Lo dejé mencionado en el issue y espero pronto se solucione eso.&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Subiendo los cambios a Github y siguiendo el mismo procedimiento anterior obtuve lo siguiente en mi Pull Request:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/cml/exp_cml.png&quot; alt=&quot;picture of me&quot; class=&quot;center&quot; /&gt;&lt;/p&gt;

&lt;div class=&quot;alert-box success radius &quot;&gt;&lt;p&gt;Creo que este puede ser un buen flujo para poder dejar documentado cuales fueron los avances que he ido teniendo junto con visualizaciones y métricas que me interesan para poder medir el impacto del modelo. En el caso de que algún set de hiperparámetros me guste los dejo fijos en el siguiente commit y ejecuto dvc repro para generar el primer reporte que mostramos en el tutorial.&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Investigando para solucionar el flujo de experimentación me encontré que Github Actions es una herramienta muy poderosa. Hay muchas ideas que encontré para poder dejar un flujo automatizado completamente en la interfaz de Github por lo que a medida que vaya implementando más cosas las iré compartiendo. CML por su parte nos ayudará a generar el reporte y agregar nuestras imágenes de manera sencilla como comentario.&lt;/p&gt;

&lt;p&gt;Como siempre, pueden ir a mi Github y en especial a este &lt;a href=&quot;https://github.com/datacubeR/dvc_tutorial&quot;&gt;Repo&lt;/a&gt;. En este caso dejé todas las ramas y los Pull Requests para que puedan seguir todo el flujo que seguí al construir este tutorial. También decidí no eliminar todos los intentos fallidos de Actions por lo que pueden ir revisando lo que les interese.&lt;/p&gt;

&lt;p&gt;Espero que este tutorial les haya gustado y nos vemos a la próxima.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;/contact/&quot;&gt;&lt;strong&gt;Alfonso&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
</content>

			
				<category term="ml" />
			
			
				<category term="python" />
			
				<category term="tutorial" />
			
				<category term="ML" />
			

			<published>2022-04-11T00:00:00+00:00</published>
		</entry>
	
</feed>