Primeira vez aqui? Seja bem vindo e cheque o FAQ!
x

Explorando o artigo Casuality in Political Networks

0 votos
16 visitas
perguntada Nov 3 em Ciência da Computação por Henrique Alves (11 pontos)  
Compartilhe

3 Respostas

0 votos
respondida Nov 3 por Henrique Alves (11 pontos)  

Olá a todos! :)

Vamos fazer uma discussão em sobre o artigo Casuality in Political Networks. Esse é um artigo bastante extenso, então vamos tentar aproveitar o máximo possível. Durante esse exercício estarei disponibilizando os códigos que escrevi, então vamos lá!

Explorando o artigo Casuality in Political Networks, por Henrique Alves de Lima. 04/11/2021

1 - Introdução

Entender a formação de redes de opinião política, as political networks, é algo fundamental para entender a dinâmica das opiniões dentro de um grupo de indivíduos. Essas redes são descritas pelo autor do artigo como úteis para descrever como os indivíduos recebem e interpretam a informação política.

Com o tempo, a forma com que se estuda o comportamento político e a forma com que se consegue a informação sobre a opinião política das pessoa mudou drasticamente, principalmente por conta da internet. O autor fala sobre o cenário em que estudamos pequenas redes de opinião, geralmente compostas de 3 a 6 indivíduos. Esse é um ponto importante para o desenvolvimento posterior de nosso trabalho.

Há porém um fenômeno bem documentado que explica o princípio das formações dessas redes, o chamado fenômeno da homofilia.

2 - Fenômeno da homofilia

O autor do texto escreve:

'Homofilia é um fenômeno bem documentado dentro das relações sociais e representa a tendencia dos indivíduos de formarem laços sociais com outros indivíduos similares'

Essa definição se torna para nós uma espécie de problema e solução, vamos explicar o motivo. Entender como essas redes são formadas adianta a maior parte do trabalho, porém, imagine a quantidade de parâmetros possíveis a serem considerados quando tratamos das características entre dois indivíduos. O artigo trata de uma série dessas possíveis características, por exemplo:

  • Distância geográfica entre os indivíduos;
  • Renda, riqueza;
  • Obesidade;
  • Fumante ou não fumante;
  • Exposição do individuo aos mais diversos tipos de mídia;

A lista dos possíveis atributos é imensa, por isso vamos tentar reproduzir a ideia principal do artigo de uma maneira simples e didática.

3 - Exemplo de Alter e Ego

Vamos pensar no fenômeno da homofilia por um breve exemplo. Vamos supor que exista um indivíduo chamado Ego, que possui a sua rede de amigos, todos eles possuindo uma certa opinião política. Então chega um novo indivíduo nessa rede, chamado Alter. Como alter irá influenciar a opinião política de Ego? Isso depende de uma série de fatores, mas a princípio queremos saber quão semelhantes são Alter e Ego.

O altor propõe um modelo estatístico dado por:

\( Y_{t+1}^{ego} = \alpha + \beta_{1}Y_{t}^{ego}+\beta_{2}Y_{t+1}^{alter}+\beta_{3}Y_{t}^{alter}+\gamma_{ego} \) (1)

Esse termo é bastante interessante e relaciona o nível da opinião de Ego num tempo t+1 em função de sua opinião do tempo t e da opinião de alter nesses mesmo períodos. A proposta do autor do texto em buscar reproduzir a mudança das características dos indivíduos em função das características de seus correlacionados é interessante, contudo, vamos fazer uma pequena modificação.

A minha proposta é que a opinião de Ego varie da seguinte forma:

\( Y_{t+1}^{ego} = \alpha + \beta_{1} Y_{t}^{ego} + \beta_{2} \sum_{i}^{N}\frac{Y_{t+1}^i}{N} \) (2)

Ou seja, queremos que a opinião de Ego varie em função de sua opinião anterior e uma média das opiniões dos indivíduos em sua rede.

E como é essa rede? Vamos considerar que essas redes são compostas pelos 4 indivíduos mais próximos.

A imagem será apresentada aqui.

Chamamos essa abordagem de vizinhança de Von Neumann.

Vamos agora entender um pouco da proposta do algoritmo a ser realizado.

4 - Descrevendo o fenômeno

O artigo nos dá os passos de como faríamos para iniciar essas simulações:

  1. Geramos uma população onde cada indivíduo possui um fator score, que é um número de uma distribuição normal

  2. Se score >= 0, opinião = 1; Caso contrário score = 0

  3. A rede de cada indivíduo vai ser descrita pela sua vizinhança de Von Neumann

  4. Fazemos um número N de simulações, onde N é um número muito grande, em cada simulação fazemos:

  • Escolhemos aleatoriamente um indivíduo e calculamos a variação de sua opinião a partir da equação (2);

  • Após todas as simulações, fazemos a normalização de todos os indivíduos e fazemos novamente: Se score >= 0, opinião = 1; Caso contrário score = 0

Para deixar mais claro, vamos visualizar o algoritmo que foi desenvolvido.

@author: henrique
"""

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import random

Importadas as bibliotecas necessárias, vamos criar as matrizes:

n = 50

score = np.ones((n, n))

option = np.ones((n,n))

for i in range(len(score)):
    for j in range(len(score)):

        score[i][j] = np.random.normal(0,1)
        if score[i][j] >= 0:
            option[i][j] = 1
        else:
            option[i][j] = 0

Vamos analisar os seguintes gráficos para entender melhor a forma dessas matrizes. O primeiro:

A imagem será apresentada aqui.

Essa imagem representa a distribuição dos scores de cada indivíduo em nossa amostra. Como em nosso exemplo o score vai ser uma espécie de resumo da opinião de cada indivíduo, apenas ele vai influenciar na opinião política de cada um. É claro que numa análise mais próxima da realidade, as coisas não são tão binárias assim, mas para nosso exemplo, vamos considerar que os indivíduos sejam separados apenas em Democratas e Republicanos.

Então, se o score for maior que zero dizemos que o indivíduo é um Republicano, caso contrário será um Democrata.

A distribuição ficará da seguinte forma:

A imagem será apresentada aqui.

Percebam que inicialmente estão bem distribuídos os espectros políticos, mas isso mudará em breve.

Antes, vamos resolver um problema inerente das vizinhanças de Von Neumann. Imagine que você escolha o indivíduo (32, 0) ou (12,50) em sua matriz. Eles não possuem vizinhos à esquerda e à direita respectivamente. A solução clássica desse problema se dá em 'espelhar' sua matriz, de forma que se o indivíduo (12,50) não possui um par em (12, 51) escolheremos o ponto (12, 0) da matriz.

O algoritmo que resolve esse problema se dá por:

l = 50
cont = 0
p=0
n=1200000
x = option


sns.heatmap(score)
plt.show()
sns.heatmap(option, linewidths=.5, cmap =  ['red', 'blue'], cbar = False )
plt.show()

for i in range(0,n,1):

    select1=random.randint(0,l-1)
    select2=random.randint(0,l-1)

    select=[select1,select2]

    temp=x[select[0],select[1]]
    #print(select)
    soma=0

    if select[0]==0:
        nu=l-1
        cont+=1
    else:
        nu=select[0]-1


    if select[0]==l-1:
        nd=0
        cont+=1
    else:
        nd=select[0]+1


    if select[1]==0:
        nl=l-1
        cont+=1
    else:
        nl=select[1]-1


    if select[1]==l-1:
        nr=0
        cont+=1
    else:
        nr=select[1]+1

Assim resolvemos esse problema nas vizinhanças e podemos avançar.

Vamos agora fazer as simulações:

    soma=score[nu,select[1]]+score[nd,select[1]]+score[select[0],nr]+score[select[0],nl]
    soma /= 4

    soma *= 0.5

    beta = np.random.random()

    score[select[0],select[1]] = (score[select[0],select[1]]) + soma + random.normalvariate(0, 1)


score -+ np.mean(score)
score /= sum(score)


for i in range(len(score)):
    for j in range(len(score)):
        if score[i][j] >= np.mean(score):
            option[i][j] = 1
        else:
            option[i][j] = 0

Gostaríamos de enfatizar o seguinte pedaço desse trecho:

score[select[0],select[1]] = (score[select[0],select[1]]) + soma + random.normalvariate(0, 1)

Que é exatamente o que foi expresso na equação (2). O resultado após uma série de simulações foi o esperado, a formação de alguns clusters, nas opiniões desse indivíduos.

A imagem será apresentada aqui.

Analisando a imagem acima podemos perceber a formação de aglomerados de indivíduos com scores semelhantes. Como a amostra é sempre normalizada, as escalas estão um pouco diferentes da figura anterior.

E como fica a distribuição das opiniões políticas?

A imagem será apresentada aqui.

Numa outra análise, eu reduzi a influência da vizinhança de Von Neumann na evolução dos scores, o que resultou nas seguintes distribuições:

A imagem será apresentada aqui.

A matriz das opiniões:

A imagem será apresentada aqui.

Pela imagem acima percebemos claramente a formação de um cluster bem definido de Democratas. Em nosso programa, calculamos também a quantidade de Republicanos e Democratas, para termos noção da proporção entre essas opiniões.

if __name__ == '__main__':

    sns.heatmap(score, vmin = score.min(), vmax = score.max())
    plt.show()
    sns.heatmap(option, linewidths=.5, cmap =  ['red', 'blue'], cbar = False )
    plt.show()


    unique, counts = np.unique(option, return_counts=True)
    a = dict(zip(unique, counts))

    print(f'As interações resultaram em {list(a.values())[0]} democratas e {list(a.values())[1]} republicanos.')

Em cada simulação, devido ao fato dos scores iniciais serem números aleatórios, temos distribuições diferentes. Essa situação contudo deve ser atenuada ou excluída em um cenário que os scores são números que representam a realidade de uma amostra.

0 votos
respondida Nov 3 por Henrique Alves (11 pontos)  

Continuação:

0 votos
respondida Nov 3 por Henrique Alves (11 pontos)  
editado Nov 4 por Henrique Alves

O autor do artigo cita um problema muito interessante, que vale a pena descrever e pensar sobre:

Como os dados sobre a opinião política, a rede de influência e outros são adquiridos? O autor expõe que em geral são feitas pesquisas e então obtidas as respostas das pessoas. O problema é a complexidade de se medir o nível de confiança dessas respostas. Imagine também o quão complexo é calcular o nível de influência dessa rede de 'amigos' na opinião de uma pessoa.

O autor utiliza algumas ferramentas, como por exemplo, analisar graficamente os resíduos da equação (1). Como na figura abaixo retirada do artigo:

A imagem será apresentada aqui.

A legenda da imagem diz que a homofilia não afeta o efeito de indução de opinião, isso para a regressão descrita por (1). Há ainda uma série de métricas que podem ser analisadas, mas não serão descritas em nosso trabalho.

5 - Comentários finais e possíveis melhorias

É bastante interessante o fato de que nas simulações feitas no artigo o fenômeno da homofilia influencie tão pouco na dinâmica de opiniões. Acredito que isso se deva ao fato de que outros fatores como a mídia tenham uma alta relevância.

Além disso, para a melhoria de nosso trabalho precisaríamos resolver alguns pontos importantes, como por exemplo descartar a vizinhança de Von Neumann e considerar que essas redes são formadas como o artigo sugere, por uma função da forma:

\( F = \frac{\gamma}{|\theta_{i} - \theta_{j}|} + \alpha \)

Onde \(\theta_{i}\) e \(\theta_{j}\) representam as opiniões de dois indivíduos e \(\alpha\) é uma variável normal aleatória. Quanto mais próximo for esse número, maior o valor de F.

Além disso é importante considerar a distância entre esses indivíduos. Então seria razoável expressarmos nosso sistema não mais por uma simples matriz quadrada e sim por um grafo. Considerando também a possível complexidade desse sistema, seria interessante também usar técnicas de Machine Learning para tratar essa quantidade considerável de variáveis categóricas.

A ideia seria verificar quais variáveis mais influenciam na opinião pessoal de cada indivíduo, e analisar também quais variáveis são mais significativas na mudança de opinião dentro de uma rede.

O código completo usado durante esse trabalho:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Fri Oct 29 11:27:33 2021

@author: Henrique Alves de Lima
"""

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import random

n = 50

score = np.ones((n, n))

option = np.ones((n,n))

for i in range(len(score)):
    for j in range(len(score)):

        score[i][j] = np.random.normal(0,1)
        if score[i][j] >= 0:
            option[i][j] = 1
        else:
            option[i][j] = 0

l = 50
cont = 0
p=0
n=1200000
x = option


sns.heatmap(score)
plt.show()
sns.heatmap(option, linewidths=.5, cmap =  ['red', 'blue'], cbar = False )
plt.show()

for i in range(0,n,1):

    select1=random.randint(0,l-1)
    select2=random.randint(0,l-1)

    select=[select1,select2]

    temp=x[select[0],select[1]]
    #print(select)
    soma=0

    if select[0]==0:
        nu=l-1
        cont+=1
    else:
        nu=select[0]-1


    if select[0]==l-1:
        nd=0
        cont+=1
    else:
        nd=select[0]+1


    if select[1]==0:
        nl=l-1
        cont+=1
    else:
        nl=select[1]-1


    if select[1]==l-1:
        nr=0
        cont+=1
    else:
        nr=select[1]+1

    soma=score[nu,select[1]]+score[nd,select[1]]+score[select[0],nr]+score[select[0],nl]
    soma /= 4

    soma *= 0.5

    beta = np.random.random()

    score[select[0],select[1]] = (score[select[0],select[1]]) + soma + random.normalvariate(0, 1)


score -+ np.mean(score)
score /= sum(score)


for i in range(len(score)):
    for j in range(len(score)):
        if score[i][j] >= np.mean(score):
            option[i][j] = 1
        else:
            option[i][j] = 0

if __name__ == '__main__':

    sns.heatmap(score, vmin = score.min(), vmax = score.max())
    plt.show()
    sns.heatmap(option, linewidths=.5, cmap =  ['red', 'blue'], cbar = False )
    plt.show()


    unique, counts = np.unique(option, return_counts=True)
    a = dict(zip(unique, counts))

    print(f'As interações resultaram em {list(a.values())[0]} democratas e {list(a.values())[1]} republicanos.')
...