<jupyter_start><jupyter_text>Aprende Python analizando partidas de Dota 1. Parte 1/3 Jupyter Notebooks & Google Colab> Una manera  divertida de aprender Python mientras analizamos la informacion de lo replays de Dota 1- toc: true - badges: true- comments: true- author: <NAME>- image: images/dota1.jpg- categories: [Python, Dota, NLP] ![](https://www.dropbox.com/s/8cus7kz860xgpxg/pylogo.png?raw=true "https://github.com/fastai/fastpages")En el mes de febrero, en los días de carnaval en Bolivia tuve la suerte de encontrar entre los archivos de mi computadora las repeticiones de dota 1 que había guardado automáticamente en los años que jugamos dota 1 junto con mis amigos.![](https://www.dropbox.com/s/l9j3gcb59r1twuc/dota1.jpg?raw=true "https://github.com/fastai/fastpages")Lo primero que se me vino a la mente al ver estos archivos fue el data que tenian dentro, en especial de Mensajes de Chats que estaban llenos de insultos en su mayoria de las partidas.Uno de mis intereses es el procesamiento del lenguaje natural o (NLP) en inglés. De esta manera, siento que estos datos pueden usarse para crear algun clasificador de insulto a un nivel básico.Estos mensajes de chat no están etiquetados, por lo que creo que se utilizara algun algoritmo de Machine Learning no supervisado.![](https://www.dropbox.com/s/34zl6k596x4d1ru/Screenshot%20from%202020-03-11%2023-09-51.png?raw=true "https://github.com/fastai/fastpages")**Imagen de un mensaje toxico en medio de una partida de Dota 1**El archivo que contiene los replays pesa aproximadamente ~900 MB. Y puede ser descargado de aca:[Link al archivo.](http://www.mediafire.com/file/4xmjki2xxy3kdgo/replays.zip/file)Como comentario adicional, existe una herramienta de Windows para abrir estos archivos, en general suelen ser utilizados por los moderadores de RGC. ProcedimientoEste post esta dividido en tres partes los cuales serán:* Que son los Jupyter Notebooks y como manejarlos.* Introduccion a Python y como extraer los replays.* Analisis de los mensajes de Chat y el clasificador de Insultos (Machine Learning)No es necesario conocimiento previo a Python.Utilizare  `Jupyter Notebook` para escribir este blog como tambien para trabajar con Python.  1. Que son los Jupyter Notebooks y como manejarlos.Una manera  facil de trabajar con Python es utilizando los Jupyter Notebooks de [Google Colab](https://colab.research.google.com/). ![Imgur](https://upload.wikimedia.org/wikipedia/commons/thumb/3/38/Jupyter_logo.svg/250px-Jupyter_logo.svg.png)Dentro de un [Google Colab](https://colab.research.google.com/) existen *`celdas` donde podemos `escribir código`* o  *`Texto normal` con el formato `Markdown`*.El texto que estoy escribiendo ahora mismo esta siguiendo el formato `Markdown`. Para saber mas que es `Markdown` pueden ver el siguiente [Link](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet).Una caracteristica adicional de las celdas donde se puede `escribir código` es que tambien puedo escribir `comandos mágicos` de Jupyter Notebook que al final vienen siendo comandos de Linux. Comandos magicos:Utilizare los siguientes`comandos mágicos`:**Para descargar un archivo desde internet**```unix!wget ```**Para listar los archivos que tengo en la carpeta donde tengo abierto este notebook.**```unix!ls -lsh```**Para descomprimir un archivo**```unix!unzip   -d .``` **Probando los comandos Mágicos**A continuacion empezare a descargar el archivo, listar la carpeta para ver si lo descargo y luego descomprimirlo.  **Descarga**Para descargar el archivo necesitamos tener el link de descarga. Ir a http://www.mediafire.com/file/4xmjki2xxy3kdgo/replays.zip/file y luego hacer click derecho en `Copy link location` y obtener el link de descarga. Este link le pasamos al comando mágico `!wget`<jupyter_code>!wget http://download1639.mediafire.com/iveo702e3bxg/4xmjki2xxy3kdgo/replays.zip<jupyter_output>--2020-03-05 04:13:40--  http://download1639.mediafire.com/iveo702e3bxg/4xmjki2xxy3kdgo/replays.zip
Resolving download1639.mediafire.com (download1639.mediafire.com)... 172.16.58.3
Connecting to download1639.mediafire.com (download1639.mediafire.com)|172.16.58.3|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 897454746 (856M) [application/zip]
Saving to: ‘replays.zip’

replays.zip         100%[===================>] 855.88M  6.53MB/s    in 2m 12s  

2020-03-05 04:15:52 (6.51 MB/s) - ‘replays.zip’ saved [897454746/897454746]<jupyter_text>**Listar**`ls` se refiere a la "listar" y `-lsh`  son la *vanderas* o parametros que acepta este comando:* `l` listar con detalles* `s` mostrar el tamaño de los archivos.* `h` mostrar los resultados en formato que un humano pueda entenderlo<jupyter_code>%ls -lsh<jupyter_output>total 856M
856M -rw-r--r-- 1 root root 856M Mar  5 04:15 replays.zip
4.0K drwxr-xr-x 1 root root 4.0K Mar  3 18:11 [0m[01;34msample_data[0m/<jupyter_text>Parece que mi archivo fue descargado correctamente. Voy a descomprmirlo **Descomprimir**`-d` se refiere al "destino" donde se va a descomprimir y el punto **.** se refiere a `a esta misma carpeta donde estoy actualmente`<jupyter_code>!unzip replays.zip -d .<jupyter_output>Archive:  replays.zip
   creating: ./replays/
  inflating: ./replays/Multiplayer.tar.gz  
 extracting: ./replays/DotAReplay_2.zip  
 extracting: ./replays/Multiplayer17.zip  
 extracting: ./replays/Multiplayer16.zip<jupyter_text>Si listo la carpeta decomprimida `/replays` voy a ver que tiene dentro.<jupyter_code>!ls  replays/<jupyter_output>DotAReplay_2.zip  Multiplayer16.zip  Multiplayer17.zip	Multiplayer.tar.gz<jupyter_text>Parece que internamente tiene mas archivos comprimidos. Voy a utilaar `-lsh` para ver en mas detalle estoys archivos.<jupyter_code>!ls -lsh replays/<jupyter_output>total 856M
2.7M -rw-r--r-- 1 root root 2.7M May 26  2017 DotAReplay_2.zip
275M -rw-r--r-- 1 root root 275M May 26  2017 Multiplayer16.zip
 70M -rw-r--r-- 1 root root  70M May 26  2017 Multiplayer17.zip
510M -rw-r--r-- 1 root root 510M May 26  2017 Multiplayer.tar.gz<jupyter_text>Parece que tenemos dentro otros archivos `.zip`  y uno `.tar.gz`.Para practicar un poco más vamos a descomprimir el ` Multiplayer16.zip` de 275 MB y el otro `Multiplayer.tar.gz` de 510MB.Para descomprimir el `Multiplayer.tar.gz` utilizaremos en siguiente `comando mágico`.```unix!tar xvzf .tar.gz -C ``` **Descomprimir el `.tar.gz`**Los parametros `xvzf` que toma el comando mágico `!tar` son por:* `x` extraer los archivos.* `v` *verbose* que se refiere a "mostrar cada archivo que se esta extrayendo"* `z` esta es muy importante y dice "descomprimir desde `gzip`"* `f` esto le dice a `tar` " cual es el archivo que vamos a  descomprimir"Hay un parametro opcional que vamos a utilzar `-C`.* `C` , lugar donde quieres que se descomprima.<jupyter_code>#collapse_show
!tar xvzf replays/Multiplayer.tar.gz -C replays/<jupyter_output>Multiplayer/Replay_2013_08_23_1854.w3g
Multiplayer/Replay_2014_01_30_2356.w3g
Multiplayer/Replay_2013_11_23_1851.w3g
Multiplayer/Replay_2015_08_17_1239.w3g
Multiplayer/Replay_2015_06_25_1710.w3g
Multiplayer/Replay_2015_07_25_0029.w3g
Multiplayer/Replay_2015_06_24_2006.w3g
Multiplayer/Replay_2013_09_01_1357.w3g
Multiplayer/Replay_2013_08_18_1432.w3g
Multiplayer/Replay_2015_09_03_2102.w3g
Multiplayer/Replay_2015_06_29_1936.w3g
Multiplayer/Replay_2013_08_13_1957.w3g
Multiplayer/Replay_2013_07_18_1930.w3g
Multiplayer/Replay_2013_09_16_1732.w3g
Multiplayer/Replay_2015_07_26_2248.w3g
Multiplayer/Replay_2015_07_27_2311.w3g
Multiplayer/Replay_2013_07_29_2216.w3g
Multiplayer/Replay_2015_08_31_1400.w3g
Multiplayer/Replay_2015_08_09_1132.w3g
Multiplayer/Replay_2015_07_28_2016.w3g
Multiplayer/Replay_2013_08_30_1049.w3g
Multiplayer/Replay_2015_07_25_1530.w3g
Multiplayer/Replay_2013_10_20_0144.w3g
Multiplayer/Replay_2013_11_06_1800.w3g
Multiplayer/Replay_2013_08_13_1745.w3g
Multiplayer/Replay_2014_1[...]<jupyter_text>Vamos a ver que es lo que se descomprimio.<jupyter_code>%ls replays/
#collapse
%ls replays/Multiplayer<jupyter_output>[0m[01;32mReplay_2013_07_18_1614.w3g[0m*  [01;32mReplay_2013_12_19_2004.w3g[0m*
[01;32mReplay_2013_07_18_1636.w3g[0m*  [01;32mReplay_2013_12_19_2243.w3g[0m*
[01;32mReplay_2013_07_18_1639.w3g[0m*  [01;32mReplay_2013_12_19_2331.w3g[0m*
[01;32mReplay_2013_07_18_1723.w3g[0m*  [01;32mReplay_2013_12_20_0035.w3g[0m*
[01;32mReplay_2013_07_18_1736.w3g[0m*  [01;32mReplay_2013_12_20_2004.w3g[0m*
[01;32mReplay_2013_07_18_1738.w3g[0m*  [01;32mReplay_2013_12_20_2239.w3g[0m*
[01;32mReplay_2013_07_18_1828.w3g[0m*  [01;32mReplay_2013_12_20_2319.w3g[0m*
[01;32mReplay_2013_07_18_1930.w3g[0m*  [01;32mReplay_2013_12_21_0010.w3g[0m*
[01;32mReplay_2013_07_18_1931.w3g[0m*  [01;32mReplay_2013_12_21_0116.w3g[0m*
[01;32mReplay_2013_07_18_1944.w3g[0m*  [01;32mReplay_2013_12_21_1402.w3g[0m*
[01;32mReplay_2013_07_18_2032.w3g[0m*  [01;32mReplay_2013_12_21_1430.w3g[0m*
[01;32mReplay_2013_07_18_2044.w3g[0m*  [01;32mReplay_2013_12_21_1535.w3g[0m*
[01;32mReplay_2013_07_1[...]<jupyter_text>Perfecto, ahora vamos  a extraer el  archivo `replays/Multiplayer16.zip` utilizando el mismo procedimiento anterior para el  `replays.zip`, con la diferencia de que cambios el archivo que queremos descomprimir y donde lo vamos a descomprimir `-d replays/`<jupyter_code>#collapse

!unzip replays/Multiplayer16.zip -d replays/<jupyter_output>Archive:  replays/Multiplayer16.zip
replace replays/Multiplayer/Replay_2013_07_18_1614.w3g? [y]es, [n]o, [A]ll, [N]one, [r]ename: y
 extracting: replays/Multiplayer/Replay_2013_07_18_1614.w3g  
replace replays/Multiplayer/Replay_2013_07_18_1636.w3g? [y]es, [n]o, [A]ll, [N]one, [r]ename: A
  inflating: replays/Multiplayer/Replay_2013_07_18_1636.w3g  
 extracting: replays/Multiplayer/Replay_2013_07_18_1639.w3g  
  inflating: replays/Multiplayer/Replay_2013_07_18_1723.w3g  
  inflating: replays/Multiplayer/Replay_2013_07_18_1736.w3g  
 extracting: replays/Multiplayer/Replay_2013_07_18_1738.w3g  
  inflating: replays/Multiplayer/Replay_2013_07_18_1828.w3g  
  inflating: replays/Multiplayer/Replay_2013_07_18_1930.w3g  
 extracting: replays/Multiplayer/Replay_2013_07_18_1931.w3g  
  inflating: replays/Multiplayer/Replay_2013_07_18_1944.w3g  
  inflating: replays/Multiplayer/Replay_2013_07_18_2032.w3g  
  inflating: replays/Multiplayer/Replay_2013_07_18_2044.w3g  
  inflating: replays/Multipl[...]<jupyter_text>Voy a revisar el peso de la carpeta  `replays/Multiplayer` con el comando```unix!du -lsh replays/Multiplayer```<jupyter_code>!du -lsh replays/Multiplayer<jupyter_output>515M	replays/Multiplayer<jupyter_text>Descomprimiendo el ultimo archivo `Multiplayer17.zip`<jupyter_code>#collapse

!unzip replays/Multiplayer17.zip -d replays/<jupyter_output>Archive:  replays/Multiplayer17.zip
  inflating: replays/Multiplayer/Replay_2014_03_23_1748.w3g  
  inflating: replays/Multiplayer/Replay_2014_03_23_1843.w3g  
  inflating: replays/Multiplayer/Replay_2014_03_23_1934.w3g  
  inflating: replays/Multiplayer/Replay_2014_03_23_2018.w3g  
  inflating: replays/Multiplayer/Replay_2014_03_24_1812.w3g  
  inflating: replays/Multiplayer/Replay_2014_03_24_1904.w3g  
  inflating: replays/Multiplayer/Replay_2014_03_24_1951.w3g  
  inflating: replays/Multiplayer/Replay_2014_03_25_1955.w3g  
  inflating: replays/Multiplayer/Replay_2014_03_25_2044.w3g  
  inflating: replays/Multiplayer/Replay_2014_03_25_2123.w3g  
  inflating: replays/Multiplayer/Replay_2014_03_25_2205.w3g  
  inflating: replays/Multiplayer/Replay_2014_03_31_1721.w3g  
  inflating: replays/Multiplayer/Replay_2014_03_31_1816.w3g  
  inflating: replays/Multiplayer/Replay_2014_03_31_1908.w3g  
  inflating: replays/Multiplayer/Replay_2014_03_31_1951.w3g  
  inflating: replays/Multiplayer/R[...]<jupyter_text>Revisando el tamaño final de la carpeta `replays/Multiplayer`<jupyter_code>!du -lsh replays/Multiplayer<jupyter_output>585M	replays/Multiplayer<jupyter_text>Estos archivos dentro de la carpeta `replays/Multiplayer` seran con los que vamos a trabajar. A continuacion empezamos con Python.  2. Intro a Python y como extraer los replays.![](https://www.dropbox.com/s/8cus7kz860xgpxg/pylogo.png?raw=true "https://github.com/fastai/fastpages")Comenzaremos con Python y tomaremos como ejemplo práctico *leer los archivos dentro de la carpeta `replays/Multiplayer` con Python*Para esto necesitamos entender los conceptos de:* `String`* `Variables` y `print()`* `Paquete de Python`* `import`* `Lista` StringUn `String` es una cadena de texto cualquiera. Estos `Strings` en Python se los crea utilizando el "Double Quote" o "Comillas".¿Donde se los utiliza? Un ejemplo claro de como utilizar un `String` es la ruta o direccion donde estan nuestros archivos y en Python seria algo como ```python"replays/Multiplayer"```De esta manera hemos creado un `String` utilizando las "comillas".Un `String` no nos sirve de mucho. Para que un `String` tenga mas utilizad necesitamos asignar este `String` a una `Variable`. Variables y `print()`Una `Variable` puede tener el valor de nuestro `String`, como dice su nombre, esta  `Variable` puede cambiar o variar su valor. *¿Como  creamos una variable?*Para crear una variable es como en las matematicas, primero escogemos un nombre y luego con el simbolo de igual `=` asigmos un "valor" a esta variable, en nuestro caso le vamos a asignar un `String`.```pythonmi_carpeta_de_replays = "replays/Multiplayer"```De esta manera he utilizado la variable `mi_carpeta_de_replays` para asignarle el valor de un `String` que es `"replays/Multiplayer"`.Noten que he utilado  mas de una palabra para crear el nombrede mi variable.`mi`, `carpeta`, `de`, `replays` unidos por una barra baja `_`.En Python y en general en otros lenguajes se suelen crear nombres de variables con mas de dos palabras para tener bien entendido que es lo que una `variable` representa. En Python se suele unir estas palabras con una `barra baja _`.A continuacion voy a crear una `celda` que corra el codigo de crear esta variable `mi_carpeta_de_replays`.<jupyter_code># Creando una variable que aloje el String de donde esta ubicado mis replays.

mi_carpeta_de_replays = "replays/Multiplayer"<jupyter_output><empty_output><jupyter_text>Funciono, he creado una variable que aloje la ruta de donde estan ubicados mis replays. Pero ahora.***¿como verifico si esta variable funciona?*** `print()`Aqui es donde entra una `funcion propia` de Python llamada `print()`. Lo llamo `funcion` porque representa el concepto de transformacion que tiene una funcion matematica, es decir...`y = f(x)` , `f` seria el `print` , los parentesis `( )`la manera en la que esta funcion acepta paremetros `x`. Y finalmente  `y` es el resultado de la transformacion.***¿Pero donde esta `x` en nuestro caso?***`x` son nuestras `Variables`.***¿Que variables tenemos?***La unica variable que tenemos actualmente es `mi_carpeta_de_replays`, entonces probemos `print()` con esta variable `mi_carpeta_de_replays`.<jupyter_code># Utilizando print()

print(mi_carpeta_de_replays)<jupyter_output>replays/Multiplayer<jupyter_text>Entonces `print(mi_carpeta_de_replays)` hace que te muestre el valor que tiene asignado una variable, en nuestro caso, el dato que tiene asignado `mi_carpeta_de_replays` es `"replays/Multiplayer"` un `String`.En conclucion con `print()` podemos ver que valores tienen asignados nuestras variables.`print()` es `un método` que Python ya trae integrado. Otros lenguajes de programacion tambien tiene su equivalente de `print()`, en `javascript` seria algo como:```javascriptconsole.log()```  Paquete de PythonEl concepto de `paquete de python` puede entenderse como herramientas construidas/programadas por alguien mas para solucionar un problema.Un problema que tenemos ahora mismo es como leer los archivos que hay dentro de la `Variable` `mi_carpeta_de_replays` que representa una carpeta fisica en el disco duro.Para esto utilizaremos el paquete `glob` que resulve este problema de manera muy sencilla. Para utilzar `glob` necesitamos `importarlo` dentro de este Jupyter Notebook y ahi es donde entra el siguiente concepto. `import``import` es una palabra reservada por Python para llamar o cargar paquetes en la memeria del Notebook. Este `import` es una palabra recervada y por tal no debe de utilizarse como nombre de alguna variable por parte de nosotros.La manera en la que `import` funciona es:```pythonimport ```En nuestro caso *el nombre del paquete es glob* y deberia llamarse como ```pythonimport glob```Probemos el `import` en codigo.<jupyter_code># Voy a importar glob dentro del Notebook

import glob<jupyter_output><empty_output><jupyter_text>Parece que funciono, ¿que pasa si hago `print(glob)`?, probemos en una celda de codigo nuevamente.<jupyter_code>print(glob)<jupyter_output><module 'glob' from '/usr/lib/python3.6/glob.py'><jupyter_text>Correctamente `print()` nos dice que este `glob` es un `modulo` y esta ubicado en `'/usr/lib/python3.6/glob.py'` Ahora...***¿Como utilizamos `glob`?.***Para utilizar glob tenemos que entender el concepto de `suma de Strings`, es decir:```python"esto es un String" + " ,Esto es Otro String" = "esto es un String ,Esto es Otro String```dos o mas `Strings` se pueden sumar para crear un único `String`.***Esto es importante para utilizar `glob`?***.Esto lo veremos utilizando `glob` a continacion.<jupyter_code>## Utilizando glob.

# Creando una variable con la suma de Strings que necesito para glob
todo_lo_que_este_dentro_de_la_carpet = mi_carpeta_de_replays + "/*"

# mostrando lo que es el resultado de la operacion de suma de Stirngs.
print(todo_lo_que_este_dentro_de_la_carpet)

# glob hace el trabajo de encontrar "todos" los archivos dentro de la carpeta "todo_lo_que_este_dentro_de_la_carpet"
mis_replays = glob.glob(todo_lo_que_este_dentro_de_la_carpet)

# Mostrar lo que glob encontro.
print(mis_replays)<jupyter_output>replays/Multiplayer/*
['replays/Multiplayer/Replay_2013_12_27_2004.w3g', 'replays/Multiplayer/Replay_2013_12_16_1433.w3g', 'replays/Multiplayer/Replay_2013_08_18_1838.w3g', 'replays/Multiplayer/Replay_2013_08_09_2348.w3g', 'replays/Multiplayer/Replay_2017_01_07_2251.w3g', 'replays/Multiplayer/Replay_2013_08_14_0048.w3g', 'replays/Multiplayer/Replay_2013_11_22_1249.w3g', 'replays/Multiplayer/Replay_2014_06_30_2153.w3g', 'replays/Multiplayer/Replay_2015_07_22_2006.w3g', 'replays/Multiplayer/Replay_2013_08_24_2330.w3g', 'replays/Multiplayer/Replay_2015_06_29_0020.w3g', 'replays/Multiplayer/Replay_2013_08_13_2349.w3g', 'replays/Multiplayer/Replay_2015_08_06_2212.w3g', 'replays/Multiplayer/Replay_2013_11_06_1800.w3g', 'replays/Multiplayer/Replay_2013_12_01_0021.w3g', 'replays/Multiplayer/Replay_2013_12_26_0126.w3g', 'replays/Multiplayer/Replay_2013_08_18_2251.w3g', 'replays/Multiplayer/Replay_2014_03_25_2123.w3g', 'replays/Multiplayer/Replay_2013_10_06_0038.w3g', 'replays/Multiplayer/Replay[...]
{'fraction_non_alphanumeric': 0.09591370423508157, 'fraction_numerical': 0.09182209469153516, 'mean_word_length': 6.067217423957942, 'pattern_counts': {'":': 0, '<': 53, '<?xml version=': 0, '>': 55, 'https://': 12, 'lorem ipsum': 0, 'www.': 6, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '16', 'dir': 'jupyter-structured-clean-dedup', 'id': '504920', 'license': 'Apache-2.0', 'n_tokens_mistral': 8292, 'n_tokens_neox': 7146, 'n_words': 1779, 'path': '_notebooks/2020-03-12-python-1-3.ipynb', 'repo_name': 'stanlee321/stanlee321', 'size': '18838'}