Last active
September 23, 2018 20:35
-
-
Save demacdolincoln/b1ed82d2b5114160df5da01c84f857ba to your computer and use it in GitHub Desktop.
word2vec
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"nbformat": 4, | |
"nbformat_minor": 0, | |
"metadata": { | |
"colab": { | |
"name": "Copy of Hello, Colaboratory", | |
"version": "0.3.2", | |
"provenance": [], | |
"collapsed_sections": [], | |
"toc_visible": true, | |
"include_colab_link": true | |
}, | |
"kernelspec": { | |
"display_name": "Python 3", | |
"name": "python3" | |
} | |
}, | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "view-in-github", | |
"colab_type": "text" | |
}, | |
"source": [ | |
"[View in Colaboratory](https://colab.research.google.com/gist/demacdolincoln/b1ed82d2b5114160df5da01c84f857ba/copy-of-hello-colaboratory.ipynb)" | |
] | |
}, | |
{ | |
"metadata": { | |
"id": "aP0rQ9Nt5tUr", | |
"colab_type": "text" | |
}, | |
"cell_type": "markdown", | |
"source": [ | |
"# word2vec ~> 2graph\n", | |
"\n", | |
"simples exemplo de como fazer um grafo representando a relação entre palavras num texto\n", | |
"\n", | |
"obs.: recomendo muito o link que me basiei para implementar o algoritmo de vetorização: https://towardsdatascience.com/light-on-math-machine-learning-intuitive-guide-to-understanding-word2vec-e0128a460f0f" | |
] | |
}, | |
{ | |
"metadata": { | |
"id": "h6N-CM956B9p", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"cell_type": "code", | |
"source": [ | |
"# bibliotecas necessárias:\n", | |
"\n", | |
"import re\n", | |
"import numpy as np\n", | |
"import networkx as nx\n", | |
"from networkx.drawing.nx_agraph import graphviz_layout\n", | |
"import matplotlib.pyplot as plt\n", | |
"from matplotlib import cm" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"id": "lFIj58og6Jzx", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"cell_type": "code", | |
"source": [ | |
"# texto\n", | |
"\n", | |
"text = \"Bom, o que vendiam lá era leite com alguma coisa.\" +\\\n", | |
"\" Não tinham licença pra vender bebida,\" +\\\n", | |
"\" mas também ainda não tinha nenhuma lei contra\" +\\\n", | |
"\" prodar algumas das novas véssiches que eles costumavam \" +\\\n", | |
"\"botar no moloco, de modo que a gente podia pitar ele com \" +\\\n", | |
"\"velocete, ou sintemesque, ou drencrom, ou uma ou duas \" +\\\n", | |
"\"outras véssiches que deixavam a gente uns bons e tranqüilos\" +\\\n", | |
"\" quinze minutos horrorshow admirando Bog e Todos os Seus Bem \" +\\\n", | |
"\"Aventurados Anjos e Santos no sapato esquerdo, e com luzes \" +\\\n", | |
"\"pipocando dentro do mosgue. Ou se podia pitar leite com facas\" +\\\n", | |
"\", como a gente costumava dizer, e isso deixava a gente afiado \" +\\\n", | |
"\"e pronto pra uma sujeira de vinte-contra-um,\" +\\\n", | |
"\" e era isso que a gente estava pitando naquela noite\" +\\\n", | |
"\" com que eu estou começando a história.\"" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"id": "djSxxvmL7AUr", | |
"colab_type": "text" | |
}, | |
"cell_type": "markdown", | |
"source": [ | |
"## pré processamento do texo\n", | |
"{limpando ele}" | |
] | |
}, | |
{ | |
"metadata": { | |
"id": "h7yO2AGq7Bug", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"cell_type": "code", | |
"source": [ | |
"# convertendo tudo para minusculo\n", | |
"text = text.lower()\n", | |
"\n", | |
"# removendo pontuação\n", | |
"text = \"\".join(re.findall(\"[\\w* ]\", text))" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"id": "p-h0MefK7tEK", | |
"colab_type": "text" | |
}, | |
"cell_type": "markdown", | |
"source": [ | |
"## criando dicionários\n", | |
"\n", | |
"vamos atribuir um valor para cada palavra para que possamos trabalhar a nível numérico" | |
] | |
}, | |
{ | |
"metadata": { | |
"id": "YCMrG6Rm7jNB", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"cell_type": "code", | |
"source": [ | |
"palavras = list(set(text.split())) # removendo duplicados\n", | |
"\n", | |
"# criando 2 dicionários para facilitar a conversão entre valores\n", | |
"word2idx = {w:i for (i, w) in enumerate(palavras)}\n", | |
"idx2word = {i:w for (i, w) in enumerate(palavras)}" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"id": "8Uudt-Bf83wB", | |
"colab_type": "text" | |
}, | |
"cell_type": "markdown", | |
"source": [ | |
"## encontrando a relação entre as palavras\n", | |
"\n", | |
"basicamente uma lista que relaciona por vez 2 números que indicam palavras vizinhas" | |
] | |
}, | |
{ | |
"metadata": { | |
"id": "Jn1-1xDO8Qij", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"cell_type": "code", | |
"source": [ | |
"# configurações iniciais\n", | |
"\n", | |
"janela = 2 # distância máxima entre vizinhas\n", | |
"\n", | |
"# criando uma lista de números correspondentes a palavras\n", | |
"# sendo que o tamanho mínimo das palavras é de 3 letras\n", | |
"index_text = [word2idx[i] for i in text.split() if len(i) > 2]" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"id": "C3XaMxtY9u3H", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"cell_type": "code", | |
"source": [ | |
"# finalmente o algoritmo:\n", | |
"\n", | |
"idx_pairs = []\n", | |
"\n", | |
"for center_word in range(len(index_text)): # center_word == palavra da vez\n", | |
" for w in range(- janela, janela+1):\n", | |
" context_word = center_word + w # context_word == posição da palavra vizinha no texto\n", | |
" if context_word > 0 and \\\n", | |
" context_word < len(index_text) and \\\n", | |
" context_word != center_word:\n", | |
"\n", | |
" # pegando os ids das palavras e relacionando elas\n", | |
" context_word_idx = index_text[context_word]\n", | |
" center_word_idx = index_text[center_word]\n", | |
" idx_pairs.append((center_word_idx, context_word_idx))\n", | |
"\n", | |
"# convertendo para array do numpy porque sim\n", | |
"idx_pairs = np.array(idx_pairs)" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"id": "BO0VS8zX--mC", | |
"colab_type": "text" | |
}, | |
"cell_type": "markdown", | |
"source": [ | |
"explicando melhor esse `if`\n", | |
"\n", | |
"```python\n", | |
"(1) if context_word > 0 and \\ \n", | |
"(2) context_word < len(index_text) and \\\n", | |
"(3) context_word != center_word: \n", | |
"```\n", | |
"\n", | |
"1. a palavra não pode estar antes do texto\n", | |
"2. a palavra não pode estar depois do texto\n", | |
"3. a palavra vizinha não pode ser a própria palavra da vez\n", | |
"\n", | |
"a gente encontra a posição da vizinha com uma soma, neste caso envolvendo um espaço de -2 a 2, são essas as 3 situações possíveis que não queremos para que as coisas funcionem" | |
] | |
}, | |
{ | |
"metadata": { | |
"id": "WPZhNBPi-ib3", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"cell_type": "code", | |
"source": [ | |
"idx_pairs[:16]" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"id": "dvoOCALo_y0w", | |
"colab_type": "text" | |
}, | |
"cell_type": "markdown", | |
"source": [ | |
"## montando um grafo" | |
] | |
}, | |
{ | |
"metadata": { | |
"id": "_zdosLFc-2vq", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"cell_type": "code", | |
"source": [ | |
"G = nx.Graph()\n", | |
"for node in idx2word:\n", | |
" G.add_node(node, label=idx2word[node])\n", | |
"G.add_edges_from(idx_pairs)" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"id": "WZQDZoVJ__A8", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"cell_type": "code", | |
"source": [ | |
"# vou plotar o tamanho dos nós em relação à centralidade\n", | |
"centrality = nx.betweenness_centrality(G)" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"id": "uNRhFTF0AHYK", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"cell_type": "code", | |
"source": [ | |
"# só quero as 15 palavras mais centrais\n", | |
"\n", | |
"most_central = sorted(\n", | |
" [(i, centrality[i]) for i in centrality],\n", | |
" key=lambda x:x[1], reverse=True\n", | |
" )[:16]\n", | |
"\n", | |
"node_labels = {i[0]:idx2word[i[0]] for i in most_central}" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"id": "_nire8oBIWxH", | |
"colab_type": "code", | |
"colab": { | |
"base_uri": "https://localhost:8080/", | |
"height": 303 | |
}, | |
"outputId": "fe91cb88-9fe4-47e3-c448-71fae2d41360" | |
}, | |
"cell_type": "code", | |
"source": [ | |
"# ranking das 16 palavras mais centrais:\n", | |
"node_labels" | |
], | |
"execution_count": 87, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"data": { | |
"text/plain": [ | |
"{5: 'com',\n", | |
" 6: 'uma',\n", | |
" 15: 'que',\n", | |
" 27: 'véssiches',\n", | |
" 28: 'sapato',\n", | |
" 35: 'quinze',\n", | |
" 39: 'bons',\n", | |
" 43: 'coisa',\n", | |
" 58: 'alguma',\n", | |
" 60: 'não',\n", | |
" 70: 'gente',\n", | |
" 74: 'pra',\n", | |
" 80: 'podia',\n", | |
" 81: 'era',\n", | |
" 83: 'anjos',\n", | |
" 88: 'novas'}" | |
] | |
}, | |
"metadata": { | |
"tags": [] | |
}, | |
"execution_count": 87 | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"id": "fUcywRvMAQds", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"cell_type": "code", | |
"source": [ | |
"fig = plt.figure(dpi=100)\n", | |
"\n", | |
"\n", | |
"pos = nx.kamada_kawai_layout(G)\n", | |
"\n", | |
"\n", | |
"nx.draw(G, pos,\n", | |
" with_labels=False,\n", | |
" alpha=0.4,\n", | |
" node_size=list(map(lambda x: np.arctan(x)*7000, centrality.values())),\n", | |
" node_color=list(centrality.values()),\n", | |
" cmap=cm.nipy_spectral,\n", | |
"# ax=ax,\n", | |
" edge_color='#F000FF'\n", | |
" )\n", | |
"nx.draw_networkx_labels(G,pos, node_labels,font_size=15, font_color='#00F0F0')\n", | |
"\n", | |
"\n", | |
"fig.set_facecolor(\"k\")\n" | |
], | |
"execution_count": 0, | |
"outputs": [] | |
} | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment