Skip to content

Instantly share code, notes, and snippets.

@demacdolincoln
Last active September 23, 2018 20:35
Show Gist options
  • Save demacdolincoln/b1ed82d2b5114160df5da01c84f857ba to your computer and use it in GitHub Desktop.
Save demacdolincoln/b1ed82d2b5114160df5da01c84f857ba to your computer and use it in GitHub Desktop.
word2vec
Display the source blob
Display the rendered blob
Raw
{
"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