Resumen

Cuatro medidas de poder para cada bancada en la LXVI Legislatura: porcentaje nominal de escaños, índice de Shapley-Shubik, índice de Banzhaf y poder empírico derivado de datos reales de votación nominal. Las divergencias entre estas medidas revelan partidos formalmente pequeños pero estratégicamente críticos — o viceversa.

Visualización: Distribución de poder

Compara el poder nominal (escaños) vs. el poder de negociación (Shapley/Banzhaf) por partido.

Abrir gráfico interactivo →

Cuatro medidas de poder

Cada medida captura una dimensión distinta de la influencia legislativa:

ÍndiceBaseQué mide
NominalConteo de escañosRepresentación formal — porcentaje de escaños sobre el total
Shapley-ShubikDistribución de escañosPoder de negociación — contribución marginal promediada en todos los ordenamientos
BanzhafDistribución de escañosPoder de negociación — frecuencia de ser miembro crítico en coaliciones
EmpíricoVotos realesRelevancia real — qué tan frecuente fue decisivo el voto de un partido

La comparación clave es nominal vs. empírico. Un partido con 5% de escaños pero un poder empírico de 20% es un rey Midas: sus votos son desproporcionadamente decisivos. Esto ocurre cuando la coalición dominante necesita frecuentemente a un partido pequeño para cruzar el umbral de mayoría.

Poder Nominal (Conteo de Escaños)

La medida más simple: la participación de cada partido en los escaños de la cámara.

poder_nominal[partido] = escaños_partido / total_escaños

La asignación de escaños maneja la multi-membresía — legisladores que pertenecen a más de un partido a lo largo de su carrera — asignando cada legislador al partido donde emitió más votos. Los empates se resuelven con la start_date más reciente de membresía.

Para la Cámara de Diputados el total es de 500 escaños. Para el Senado de la República, 128. Estos totales se derivan dinámicamente desde la base de datos vía get_total_seats(), sin valores hardcodeados.

Índice de Shapley-Shubik

El índice de Shapley-Shubik mide el poder de negociación de cada partido promediando su contribución marginal en todos los posibles ordenamientos en que podría formarse una coalición.

Concepto

Un partido es un pivote en la posición k de una permutación si la coalición de los primeros k partidos alcanza la mayoría, pero al eliminar ese partido la coalición cae por debajo de la mayoría. El índice es:

SS_i = (permutaciones donde i es pivote) / N!

Algoritmo de Programación Dinámica

El enfoque naive enumera todas las N! permutaciones — inviable para 13 partidos. La implementación usa un algoritmo DP que corre en tiempo O(n²W):

# dp[s][w] = número de subconjuntos de tamaño s con peso total w
#            usando todos los jugadores EXCEPTO player_i
dp = [[0] * (quota) for _ in range(n)]
dp[0][0] = 1

for p in players:
    if p == player_i:
        continue
    w_j = weights[p]
    for s in range(n - 2, -1, -1):
        for w in range(max_w - w_j, -1, -1):
            if dp[s][w]:
                dp[s + 1][w + w_j] += dp[s][w]

# SS_i = Σ dp_i[s][w] * s! * (n-1-s)! / n!
#        para w < quota y w + w_i >= quota

Con 13 partidos y quota ~251 (mayoría simple en una cámara de 500 escaños), esto requiere aproximadamente 330K operaciones por jugador — tractable y exacto (sin muestreo).

:::tip El enfoque DP fue validado contra el método de fuerza bruta O(n!) en 4 datasets con diff = 0.0 en todos los casos. :::

Índice de Banzhaf

El índice de Banzhaf cuenta qué tan frecuente es cada partido un jugador crítico en coaliciones ganadoras. Un jugador es crítico si la coalición gana con él, pero pierde sin él.

Algoritmo

for coalition in todos_subconjuntos(players):
    if peso_coalicion >= quota:       # coalición ganadora
        for player in coalition:
            if peso_coalicion - pesos[player] < quota:
                player es crítico

banzhaf[partido] = conteo_crítico[partido] / total_conteo_crítico

El resultado está normalizado: el puntaje de cada partido es su proporción del total de ocurrencias críticas en todas las coaliciones.

Con 8 partidos en la LXVI Legislatura, esto significa 2⁸ = 256 coaliciones — trivial de enumerar exhaustivamente.

Shapley-Shubik vs. Banzhaf

Ambos miden poder de negociación a partir de escaños, pero difieren en su tratamiento de la formación de coaliciones:

AspectoShapley-ShubikBanzhaf
PromediadoSobre todos los ordenamientos (permutaciones)Sobre todas las coaliciones (subconjuntos)
SimetríaConsidera orden de incorporaciónIgnora el orden
ValoresSiempre suman 1.0Normalizados para sumar 1.0

En la práctica, producen rankings similares pero pueden divergir para partidos de tamaño medio en legislaturas fragmentadas.

Poder Empírico

Los índices nominales asumen disciplina perfecta de partido — cada miembro vota con su bancada. El poder empírico mide lo que realmente ocurre en las votaciones nominales.

Partidos Críticos por Votación

Para cada evento de votación, el módulo identifica qué partidos fueron necesarios para alcanzar el umbral de mayoría:

# Si aprobada: coalición ganadora = partidos que votaron a_favor
for partido in coalición_ganadora:
    restante = total_a_favor - favor_partido
    if restante < umbral_mayoría:
        partido es "crítico" para esta votación

Un partido es crítico cuando, sin sus votos, el bando ganador habría caído por debajo de la mayoría requerida.

Índice de Poder Empírico

poder_empírico[partido] = veces_crítico[partido] / total_eventos_votación

Esto produce un puntaje de 0.0–1.0 que refleja qué tan frecuente fue decisivo el voto de un partido en el resultado. Un partido que está siempre en la coalición ganadora pero nunca es crítico obtiene un puntaje cercano a 0.0 — sus votos son redundantes.

Mayoría Calificada

El sistema soporta tanto mayoría simple como calificada (2/3). Para votaciones de mayoría calificada:

mayoría_necesaria = ceil(2/3 * total_escaños)  # 334 para Diputados, 86 para Senado

El tipo de requerimiento se lee del campo motion.requirement en la base de datos (mayoria_simple o mayoria_calificada), así que el análisis se adapta automáticamente a las reglas de cada votación.

Soporte Bicameral

Todo el pipeline de análisis de poder soporta ambas cámaras vía el parámetro --camara:

CámaraID de OrganizaciónEscaños--camara
DiputadosO08500diputados
SenadoO09128senado

Los conteos de escaños se derivan dinámicamente desde la base de datos vía get_total_seats(db_path, camara), que consulta los registros reales de membresía en lugar de depender de constantes hardcodeadas. La función get_seat_counts() normaliza los valores mixtos de vote.group (algunos eventos usan nombres de partido como "PT", otros usan IDs de organización como "O02") antes de tomar el conteo máximo de votantes por partido, evitando números inflados por agregación entre legislaturas.

Votaciones Cerradas y Swing Voters

Votaciones Cerradas

Una votación es cerrada cuando el margen entre el bando ganador y perdedor cae por debajo de un umbral configurable:

CLOSE_VOTES_THRESHOLD = 10  # configurable en config.py

votación_cerrada = |a_favor - en_contra| < umbral

Las votaciones cerradas son las más consequentes — son donde los legisladores individuales tienen influencia real. El umbral por defecto es 10 pero puede ajustarse en analysis/config.py.

Swing Voters

Dentro de las votaciones cerradas, el módulo identifica swing voters: legisladores individuales que:

  1. Votaron diferente a la posición mayoritaria de su partido, Y
  2. Podrían haber cambiado el resultado con su voto individual
# Un legislador es swing voter si:
#   - Su partido votó 'favor', pero él votó en contra
#   - Y (a_favor_total - 1) < mayoría → un voto menos cambiaría el resultado

Solo se consideran legisladores en partidos con una posición mayoritaria clara (>50% de asistentes votando en una dirección). Partidos divididos o ausentes se excluyen.

Caso de Estudio: Reforma Judicial

Las votaciones de la reforma judicial (VE04 y VE05) se analizan como un caso especial porque requieren mayoría calificada (2/3):

REFORMA_JUDICIAL_VE_IDS = ["VE04", "VE05"]
mayoría_necesaria = ceil(2/3 * 500) = 334

Por Qué Importa

Bajo mayoría simple (251 escaños), un partido dominante puede aprobar legislación unilateralmente. Bajo mayoría calificada (334 escaños), incluso el partido más grande necesita socios de coalición. Esto cambia completamente el cálculo de poder:

  • Partidos pequeños que tienen cero poder Shapley-Shubik bajo mayoría simple se vuelven críticos bajo 2/3
  • La brecha entre poder nominal y empírico se amplía dramáticamente
  • La estrategia de coalición se vuelve esencial

Desglose por Partido

Para cada votación de la reforma judicial, el análisis produce:

CampoDescripción
Posición del partidofavor, contra, split o ausente
Estatus críticoSi al eliminar los votos de este partido la coalición cae por debajo de 334
Margena_favor_total - mayoría_necesaria

El desglose revela exactamente qué partidos fueron decisivos para la reforma — partidos cuya deserción habría hundido la votación.

Análisis de Disidentes

No todos los legisladores votan con su partido. El análisis de disidentes identifica los 10 legisladores que con mayor frecuencia rompen con la línea de su bancada.

Metodología

TOP_DISSENTERS_GLOBAL = 10  # configurable en config.py

for cada legislador:
    for cada evento_votación:
        if voto del legislador ≠ posición mayoritaria del partido:
            conteo_disidencia += 1

    tasa_disidencia = conteo_disidencia / total_votos
    # Mínimo 10 votos requeridos para inclusión

Resultados

El análisis clasifica legisladores por tasa de disidencia (descendente), luego por conteo bruto de disidencias como desempate:

RankNombrePartidoTasa DisidenciaTotal VotosVotos Disidentes
1…%

Una tasa de disidencia alta puede indicar independencia ideológica, posicionamiento estratégico o votación impulsada por el constituency que diverge de la línea partidista. El cruce con los puntos ideales W-NOMINATE revela si los disidentes se agrupan ideológicamente o votan de forma idiosincrásica.