
Evaluar si el reparto de escaños en un sistema electoral es justo o no es una tarea complicada. La justicia electoral es un concepto complejo, en el que se pueden dar diferentes interpretaciones que pueden cambiar según los resultados obtenidos por cada uno de los partidos. Aun así, es posible usar algunas métricas para ayudar a objetivar si el reparto es justo o no. En esta entrada se verán algunas métricas que se pueden utilizar para evaluar la proporcionalidad de un sistema de asignación de escaños de una forma objetiva y comparar el efecto de diferentes reglas.
Tabla de contenidos
Principios para evaluar la proporcionalidad de un sistema de asignación de escaños
A la hora de evaluar la proporcionalidad de un sistema de asignación de escaños se debe tener en cuenta algunos principios como los siguientes:
- Proporcionalidad: La proporcionalidad es un principio clave para evaluar la justicia electoral. Consiste en verificar si los escaños asignados a cada partido se corresponden de manera proporcional a los votos obtenidos en las elecciones. El sistema será más justo cuando el porcentaje de los escaños asignados aproxima a los porcentajes de votos recibidos.
- Desperdicio de votos: El desperdicio de votos ocurre cuando los votos no se traducen en escaños y, por lo tanto, se pierden. Evaluar el desperdicio de votos en un sistema de asignación de escaños puede indicar si la asignación es equitativa. Los sistemas en el que exista menos desperdicio de votos suelen considerarse más justo.
- Representación de minorías: Los sistemas que favorecen la representación de minorías, incluyendo la inclusión de diferentes ideas y perspectivas, se consideran más justo en términos de representatividad. Por lo tanto, evaluar si el sistema electoral permite una adecuada representación de minorías puede ayudar a conocer el grado de justicia de este.
Como en casi cualquier actividad humana, es importante tener en cuenta que no existe un sistema electoral perfecto. Los diferentes sistemas de atribución de escaños tienen sus ventajas e inconvenientes. Los que priman a los partidos más votados, como puede ser el método D’Hondt, reducen la proporcionalidad, pero favorecen la gobernabilidad al producir una menor fragmentación de los escaños. Mientras que los que priman a los partidos minoritarios, como puede ser el método Hare-Niemeyer, aumentan la proporcionalidad, pero complica la gobernabilidad. La elección del sistema electoral dependerá de los valores y objetivos de cada sociedad.
Métricas para evaluar la proporcionalidad de un sistema de asignación de escaños
A la hora de evaluar la proporcionalidad de un sistema de asignación de escaños se pueden emplear diferentes métricas mediante las cuales se puede cuantificar el grado de representatividad y equidad. A continuación, se muestran algunas de las métricas más utilizadas para esta tarea.
Desviación porcentual total (Total Percentage Deviation, TPD)
La desviación porcentual total (TDP) es una métrica que mide la diferencia entre la distribución real de escaños y la distribución proporcional ideal. Se calcula como la suma en valor absoluto de las diferencias entre el porcentaje de escaños obtenidos por un partido y el porcentaje de votos recibidos. Siendo el TDP la suma de las diferencias para todos los partidos. Una TPD más cercana a cero indica una asignación de escaños más proporcional.
La fórmula de esta métrica es TPD = \sum \left| \textrm{Porcentaje de esca~nos del partido} - \textrm{Porcentaje de votos del partido}\right|. Una implementación en Python se puede ver en el siguiente código.
def total_percentage_deviation(votes, seats): """ Calcula la Desviación porcentual total (Total Percentage Deviation - TPD). Parámetros ---------- votes : array-like, shape (num_parties, ) Lista con los votos de cada partido. seats : array-like, shape (num_parties, ) Lista con los escaños de cada partido. Retorna ------- tpd : float Valor de la Desviación porcentual total (TPD). """ num_parties = len(votes) votes_percentage = calculate_percentage(votes) seats_percentage = calculate_percentage(seats) tpd = sum(abs(seats_percentage[i] - votes_percentage[i]) for i in range(num_parties)) return tpd def calculate_percentage(votes): """ Calcula los porcentajes de votos de cada partido. Parámetros ---------- votes : array-like, shape (num_parties, ) Lista con la cantidad de votos o escaños obtenidos por cada partido. Retorna ------- votes_percentage : array-like, shape (num_parties, ) Lista con los porcentajes de votos de cada partido. """ total_votes = sum(votes) votes_percentage = [(votes[i] / total_votes) * 100 for i in range(len(votes))] return votes_percentage
En esta función se debe indicar una lista con el número de votos y otra con el número de escaños. La función calcula primero los porcentajes de votos y escaños para posteriormente calcular la diferencia. Siendo este el valor que devuelve.
En este caso se ha creado la función auxiliar calculate_percentage
con el que se puede obtener el porcentaje de votos o escaños a partir de los valores. Una función que simplifica el uso y la escritura de esta y el resto de las funciones que se van a implementar en esta entrada.
Índice de Loosemore-Hanby (Loosemore-Hanby Index)
El índice de Loosemore-Hanby es una mejora del TDP en el que se tiene en cuenta el número de partidos presentados, midiendo de este modo la eficiencia en la proporcionalidad. Para lo que cuantifica la diferencia promedio entre los porcentajes de votos y escaños de los partidos. Se calcula sumando en valor absoluto de las diferencias entre el porcentaje de escaños obtenidos por un partido y el porcentaje de votos recibidos dividido por el número de partidos. Un índice de Loosemore-Hanby más cercano a cero indica una asignación más eficiente y proporcional.
La fórmula de esta métrica es LH = \sum \left| \frac{\textrm{Porcentaje de esca~nos del partido} - \textrm{Porcentaje de votos del partido}}{\textrm{N\'umero total de partidos}}\right|. Una implementación en Python se puede ver en el siguiente código.
def loosemore_hanby_index(votes, seats): """ Calcula el Índice de Loosemore-Hanby (Loosemore-Hanby Index). Parámetros ---------- votes : array-like, shape (num_parties, ) Lista con los votos de cada partido. seats : array-like, shape (num_parties, ) Lista con los escaños de cada partido. Devuelve: lh_index (float): Valor del Índice de Loosemore-Hanby (LH). """ num_parties = len(votes) votes_percentage = calculate_percentage(votes) seats_percentage = calculate_percentage(seats) lh_index = sum(abs(seats_percentage[i] - votes_percentage[i]) for i in range(num_parties)) / num_parties return lh_index
Esta función es similar a la anterior dividiendo el resultado final por el número total de partidos.
Índice de Gallagher (Gallagher Index)
El índice de Gallagher permite medir la desigualdad en la asignación de escaños. Se calcula sumando las diferencias al cuadrado entre el porcentaje de escaños obtenidos por cada partido y el porcentaje de votos recibidos. La suma total se divide entre dos para obtener el índice. Un índice de Gallagher más alto indica una mayor desigualdad entre los resultados de votación y la asignación de escaños.
La fórmula de esta métrica es GI=\sqrt{\sum \frac{\left(\textrm{Porcentaje de esca~nos del partido} - \textrm{Porcentaje de votos del partido}\right )^2}{2}}. Una implementación en Python se puede ver en el siguiente código.
import math def gallagher_index(votes, seats): """ Calcula el Índice de Gallagher (Gallagher Index). Parámetros ---------- votes : array-like, shape (num_parties, ) Lista con los votos de cada partido. seats : array-like, shape (num_parties, ) Lista con los escaños de cada partido. Retorna ------- gallagher_index : float Valor del Índice de Gallagher. """ num_parties = len(votes) votes_percentage = calculate_percentage(votes) seats_percentage = calculate_percentage(seats) gallagher_index = math.sqrt(0.5 * sum((seats_percentage[i] - votes_percentage[i])**2 for i in range(num_parties))) return gallagher_index
El código es similar a los anteriores, solo que en este caso se calcula la suma de las diferencias al cuadrado en lugar del valor absoluto.
Índice de Loosemore-Hanby normalizado (Normalized Loosemore-Hanby Index)
El índice de Loosemore-Hanby normalizado es similar al índice de Loosemore-Hanby, pero se normaliza dividiendo la diferencia promedio entre los porcentajes de votos y escaños por la diferencia máxima posible. Esto permite comparar la proporcionalidad entre diferentes sistemas electorales.
La fórmula de esta métrica es LH_{norm} = \sum \left| \frac{\textrm{Porcentaje de esca~nos del partido} - \textrm{Porcentaje de votos del partido}}{\max\left ( \left | \textrm{Porcentaje de esca~nos del partido} - \textrm{Porcentaje de votos del partido} \right | \right )}\right|. Una implementación en Python se puede ver en el siguiente código.
def normalized_loosemore_hanby_index(votes, seats): """ Calcula el Índice de Loosemore-Hanby normalizado (Normalized Loosemore-Hanby Index). Parámetros ---------- votes : array-like, shape (num_parties, ) Lista con los votos de cada partido. seats : array-like, shape (num_parties, ) Lista con los escaños de cada partido. Retorna ------- normalized_lh_index : float Valor del Índice de Loosemore-Hanby normalizado. """ num_parties = len(votes) votes_percentage = calculate_percentage(votes) seats_percentage = calculate_percentage(seats) max_difference = max(abs(seats_percentage[i] - votes_percentage[i]) for i in range(num_parties)) normalized_lh_index = sum(abs(seats_percentage[i] - votes_percentage[i]) for i in range(num_parties)) / max_difference return normalized_lh_index
La función es similar a la utilizada para el cálculo del índice de Loosemore-Hanby, pero en lugar de dividir por el número de partidos se divide por la máxima diferencia entre los porcentajes de votos.
Evaluación de los resultados
Las métricas que se han definido en la sección anterior se pueden usar para comparar el reparto de escaños que hacen los métodos D’Hondt, Sainte-Laguë o Hare-Niemeyer en una circunscripción. Para ello se puede recoger el número de votos y atribuir los escaños en base a cada uno de estos métodos y analizar los resultados.
import pandas as pd def evaluate_methods(votes, num_seats): seats_dhondt = dhondt_method(votes, num_seats) seats_sainte = sainte_lague_method(votes, num_seats) seats_hare = hare_niemeyer_method(votes, num_seats) df = pd.DataFrame({"D'Hondt": [total_percentage_deviation(votes, seats_dhondt), loosemore_hanby_index(votes, seats_dhondt), gallagher_index(votes, seats_dhondt), normalized_loosemore_hanby_index(votes, seats_dhondt)], "Sainte-Laguë":[total_percentage_deviation(votes, seats_sainte), loosemore_hanby_index(votes, seats_sainte), gallagher_index(votes, seats_sainte), normalized_loosemore_hanby_index(votes, seats_sainte)], "Hare-Niemeyer": [total_percentage_deviation(votes, seats_hare), loosemore_hanby_index(votes, seats_hare), gallagher_index(votes, seats_hare), normalized_loosemore_hanby_index(votes, seats_hare)]}, index=["Desviación porcentual total", "Índice de Loosemore-Hanby", "Índice de Gallagher", "Índice de Loosemore-Hanby normalizado"]) return df votes = [15000, 12000, 8000, 6000, 2000, 1200] num_seats = 16 evaluate_methods(votes, num_seats)
D'Hondt Sainte-Laguë Hare-Niemeyer Desviación porcentual total 16.628959 11.877828 11.821267 Índice de Loosemore-Hanby 2.771493 1.979638 1.970211 Índice de Gallagher 5.428465 3.823734 3.800551 Índice de Loosemore-Hanby normalizado 3.675000 3.333333 3.344000
Las funciones para realizar la atribución de escaño se han presentado en publicaciones anteriores: método D’Hondt, método Sainte-Laguë y método Hare-Niemeyer. También se pueden ver en el apéndice.
En el ejemplo, lo que se puede ver es como en casi todas las métricas los mejores resultados se obtienen con el método Hare-Niemeyer, seguido del método Sainte-Laguë y finalmente el método D’Hondt. Aunque este es un ejemplo y se debería evaluar en diferentes casos para ver cuál es el método más adecuado.
Conclusiones
En esta entrada se han visto diferentes métricas para analizar la proporcionalidad de un sistema de asignación de escaños. Estas métricas se han utilizado para comparar en un caso particular cuál de los tres métodos más populares (D’Hondt, Sainte-Laguë y Hare-Niemeyer) ofrece mejores resultados concluyendo que, en el caso analizado, el método con mejores métricas es Hare-Niemeyer.
Apéndice
Funciones para la atribución de escaños.
import math def dhondt_method(votes, num_seats): """ Método para aplicar el método D'Hondt y obtener la asignación de escaños. Parámetros ---------- votes : array-like, shape (num_parties, ) Una lista o array con los votos obtenidos por cada partido. num_seats : int Número total de escaños a asignar. Retorna ------- seats : array, shape (num_parties,) Una lista con el número de escaños asignados a cada partido. """ num_parties = len(votes) # Inicializar la asignación de escaños a cero seats = [0] * num_parties # Realizar el proceso de asignación de escaños for _ in range(num_seats): max_index = max(range(num_parties), key=lambda i: votes[i] / (seats[i] + 1)) seats[max_index] += 1 return seats def sainte_lague_method(votes, num_seats): """ Método para aplicar el método Sainte-Laguë y obtener la asignación de escaños. Parámetros ---------- votes : array-like, shape (num_parties, ) Una lista o array con los votos obtenidos por cada partido. num_seats : int Número total de escaños a asignar. Retorna ------- seats : array, shape (num_parties,) Una lista con el número de escaños asignados a cada partido. """ num_parties = len(votes) # Inicializar la asignación de escaños a cero seats = [0] * num_parties # Realizar el proceso de asignación de escaños for _ in range(num_seats): max_index = max(range(num_parties), key=lambda i: votes[i] / (2 * seats[i] + 1)) seats[max_index] += 1 return seats def hare_niemeyer_method(votes, num_seats): """ Método para aplicar el método Hare-Niemeyer y obtener la asignación de escaños. Parámetros ---------- votes : array-like, shape (num_parties, ) Una lista o array con los votos obtenidos por cada partido. num_seats : int Número total de escaños a asignar. Retorna ------- seats : array, shape (num_parties,) Una lista con el número de escaños asignados a cada partido. """ num_parties = len(votes) # Obtención de la quota total_votes = sum(votes) hare_quote = math.floor(total_votes / num_seats) # Inicializar la asignación de escaños a cero seats = [0] * num_parties # Realizar el proceso de asignación de escaños for _ in range(num_seats): max_index = max(range(num_parties), key=lambda i: votes[i] - seats[i] * hare_quote) seats[max_index] += 1 return seats
Imágenes: Unsplash (Arnaud Jaegers)
Deja una respuesta