Nieścisłości za rogi!

czyli

matematyka w służbie demokracji

Autor tekstu: Bart

Jeśli sam tego nie zrobię, to nie będzie dobrze zrobione

Gdybym postępował według tej maksymy, to sam bym sobie szył ciuchy, a to by się dobrze nie skończyło. Kiedy jednak człowiek w czymś tam się cokolwiek orientuje, to dlaczego nie? Obecnie (koniec czerwca 2025) szaleje w Polsce inba związana z zarzutami o sfałszowanie przez PiS wyborów prezydenckich. Kiedy na podstawie zgłoszonych protestów wytypowano 13 komisji, a następnie, po ponownym przeliczeniu głosów, w 11 z nich stwierdzono nieprawidłowości, pojawiły się głosy, że skoro w tych 11 komisjach było średnio po 237 błędnie policzonych głosów, to w skali kraju tych głosów musi być 17 milionów, bo komisji jest ponad 30 tysięcy. Poważnie mówię, takie głosy się pojawiły. Stwierdziłem, że skoro wygląda na to, iż rozumiem statystykę lepiej, niż część posłów, a do tego potrafię programować, to sam się zabiorę za analizę wyborczych danych.

Postanowiłem oszacować, jakie „powinny” być wyniki wyborów, porównać je z faktycznymi wynikami drugiej tury i wyłapać najciekawsze anomalie. Od momentu, kiedy tę decyzję powziąłem, do chwili, gdy się za to zabrałem, pojawiło się już kilka różnych propozycji takich analiz, o których nie będę szczegółowo pisał. Dość, że w tym momencie nadal nie zostały podane szczegóły implementacji i użytych metodologii, padają natomiast mądrze brzmiące pojęcia i terminy mające być może onieśmielić przeciwnika.

Tak, przeciwnika. Metody owe łączy bowiem jedno: każda z nich jest skoncentrowana na szukaniu śladów zbrodni popełnionej przez „tych drugich”. Znalazłem jedną analizę, która podchodzi do tematu bezstronnie i jej też metodę nieco rozwinąłem. Różnica jest taka, że jej autor dzieli wszystkich kandydatów z pierwszej tury na „trzaskowskich” i „nawrockich” i na podstawie oddanych na nich głosów szacuje, ile z tych głosów powinno trafić do którego z dwóch głównych rywali. Ja skorzystałem z opublikowanych przez Ipsos szacunków przepływu głosów, które kształtują się mniej więcej tak, jak w tabelce poniżej (jaki procent wyborców danego kandydata poparł później Trzaskowskiego, a jaki Nawrockiego).

KANDYDATDo TrzaskowskiegoDo Nawrockiego
Artur Bartoszewicz15 %70 %
Magdalena Biejat90 %10 %
Grzegorz Braun10 %90 %
Szymon Hołownia85 %15 %
Marek Jakubiak15 %75 %
Maciej Maciak15 %70 %
Sławomir Mentzen10 %90 %
Joanna Senyszyn85 %5 %
Krzysztof Stanowski20 %20 %
Marek Woch20 %60 %
Adrian Zandberg80 %15 %

Nie każdemu kandydatowi sumuje się to do 100 %, gdyż część ich wyborców deklarowała bojkot drugiej tury. Miałem też zagwozdkę ze śmieszkami od Stanowskiego, więc ostatecznie każdemu z dwóch bossów dałem od niego po 20 %.

Moja metoda jest prosta, choć – mam nadzieję – nie prostacka. Dla każdej komisji brałem głosy każdego z kandydatów z pierwszej tury, mnożyłem je przez odpowiedni czynnik z tabeli i dorzucałem do wyniku Trzaskowskiego oraz Nawrockiego. Na koniec uwzględniałem współczynnik frekwencji (zmiany liczby głosujących) – i szacowany wynik w drugiej turze w każdej komisji gotowy.

Sprawdźmy to!

Najpierw opiszę swoje eksperymenty, a następnie podam namiar na mój programik, abyście mogli się sami pobawić.

Miałem już informację o 13 „podejrzanych” komisjach, wśród których w 11 przeliczono głosy ponownie. Nie dotarłem do wszystkich szczegółowych informacji. Wiadomo, że w 7 komisjach zwyczajnie zamieniono głosy Nawrockiego z głosami Trzaskowskiego (znam 6 z nich). Ponadto znam też wyniki przeliczenia w 3 innych komisjach. Odpaliłem zatem swoje ustrojstwo na razie z filtrem na stratę Trzaskowskiego, sortując według największych odchyleń (różnic między wynikiem szacowanym moją metodą, a policzonym w drugiej turze). Wśród pierwszych 15 wyników pojawiło się 8 z 9 komisji, co do których wiedziałem, jakie dokładnie wykryto w nich błędy. Co do brakującej, katowickiej komisji, był komunikat, że w jej przypadku zostały nieznacznie zawyżone wyniki obu kandydatów – nic więc dziwnego, że mój program nie punktował jej wysoko.

Pojawiły się natomiast w pierwszej 15-tce również te komisje ze zgłoszonych, co do których nie wiem, jakie dokładnie wykryto w nich błędy, oraz te, w których nie było ponownego liczenia. Słowem – tylko Katowice spośród tych „podejrzanych” wypadły poza pierwsze 15 wyników, jeśli uwzględnić anomalie na niekorzyść Trzaskowskiego.

Dobry wynik!

Wklepałem zatem opcję, która wyświetliła mi szacowane wyniki dokładnie dla tej parszywej komisyjnej trzynastki. Porównałem przewidywania mojego modelu (pogrubione) z przeliczonymi ponownie głosami (w tych przypadkach, w których znałem szczegóły). Mówiąc po ludzku: oto, jak mój model twierdzi, że być powinno (bo dane z komisji go nie przekonują), a jak się okazało, że jest rzeczywiście. Oceńcie trafność sami.

Gmina i numer komisji / rodzaj nieprawidłowościNawrockiTrzaskowski
Kraków 95
zamiana głosów
582 / 5401054 / 1132
Bielsko-Biała 61
minus 160 głosów Trzaskowskiego
817 / 888984 / 931
Mińsk Mazowiecki 13
zamiana głosów
383 / 363575 / 611
Gdańsk 17
zamiana głosów
406 / 346506 / 585
Grudziądz 25
zamiana głosów
342 / 324478 / 504
Bielsko-Biała 30
zamiana głosów
466 / 349478 / 610
Brześć Kujawski 4
zamiana głosów
339 / 331448 / 466
Kamienna Góra 6
minus 90 głosów Trzaskowskiego
286 / 278414 / 428

No i co wy na to? Jedynie w komisji nr 30 w Bielsku – Białej mój program przestrzelił na korzyść Nawrockiego, a w komisji nr 61 w tym samym mieście – nieznacznie na korzyść Trzaskowskiego. Poza tym jego szacunki są zaskakująco zbliżone do wyników uwzględniających błędy popełnione w trakcie liczenia po drugiej turze.

Na drugą nóżkę

Kiedy ten tekst był już niemal „w druku”, wyszły informacje o kolejnych nieścisłościach – tym razem głosów zabrakło Nawrockiemu. Nie omieszkałem i tego wziąć na warsztat. Póki co, mam dane z trzech jedynie komisji. Odpaliłem zatem program tym razem ustawiając go na Nawrockiego jako poszkodowanego. Już się zrazu uśmiechnąłem chełpliwie – Mokotów i Magnuszew na trzeciej i czwartej pozycji! Nie ma jednak Staszowa. Zacząłem zwiększać limit wyświetleń i Staszów odnalazł się w piątej dziesiątce. W tym momencie do mnie dotarło, że wyświetlam komisje, w których mój program oszacował wyniki Nawrockiego lepiej, niż wypadły. Staszów zaś, z błędem polegającym na przydzieleniu Trzaskowskiemu 150 głosów Nawrockiego, ma na tej liście (sortowanej według sumy wartości bezwzględnej rozbieżności) pozycję 43. Dla porządku dodam tylko tabelkę analogiczną jak wyżej, a potem przejdziemy do wniosków końcowych.

Gmina i numer komisji / rodzaj nieprawidłowościNawrockiTrzaskowski
Warszawa Mokotów 113
minus 163 głosy Nawrockiego
406 / 2961470 / 1611
Magnuszew 1
minus 270 głosów Nawrockiego
463 / 468189 / 192
Staszów 4
zamiana głosów
354 / 360211 / 209

Na Mokotowie przestrzeliłem oczekiwania wobec Nawrockiego, ale wyniki w dwóch pozostałych komisjach mój model przewidział niemal idealnie!

Ponad podziałami

Odpaliłem na koniec listę anomalii bez podziału na kandydatów. Wśród pierwszych 30 wyników 6 jest na korzyść Nawrockiego, a reszta – na korzyść Trzaskowskiego. Weźmy pierwszy z brzegu – komisja nr 1 w Jastarni. Trzaskowski i Nawrocki w pierwszej turze odpowiednio: 689 i 595 głosów. W drugiej turze – 1956 i 1621. Trzykrotnie większa różnica. Tu jednak mogło faktycznie stać się coś nienormatywnego, bo frekwencja w obu turach to odpowiednio 2023 i 3242 osoby. Bardzo duża różnica!

Trzeci na liście jest Poznań, komisja nr 109. Tu już różnica we frekwencji „bez szaleństw”, 3560 i 3963. Głosy w pierwszej turze na Trzaskowskiego i Nawrockiego: 1256 i 235 W drugiej turze: 3126 (szacowane 2777) i 837 (szacowane 1082).

Wydłużam listę do stu pozycji. Dziewięć z nich jest na niekorzyść Trzaskowskiego. Podsumowuję całość globalnie.

Suma odchyleń globalnie (Trzaskowski): 408118
Suma odchyleń globalnie (Nawrocki): -145833

Zważcie minus przy Nawrockim. Oznacza to, że jeśli mój model dobrze kombinuje (a w starciu z prawdziwymi danymi poradził sobie bardzo dobrze), to przeliczenie wszystkich głosów dorzuciłoby Nawrockiemu jeszcze koło 150 tys., a Trzaskowskiego pozbawiło 400 tys.

Na zakończenie dwie konkluzje. Napisanie programu i analiza wyników badania zajęła mi może ze trzy godziny. Ten wpis piszę już niemal tak samo długo. Nie poświęciłem wiele czasu, program nie jest zaś z gatunku rocket science. Wydaje mi się bardzo mało prawdopodobne, żeby osoby pompujące całą tę aferę nie zadały sobie trudu przeanalizowania wyników w taki sposób, zwłaszcza że pewnie z pomocą Excela poszłoby to jeszcze szybciej. O tym jednak, co w związku z tym sobie jeszcze myślę, będzie osobny artykuł.

Nie da się jednak zaprzeczyć, że „coś nie pykło”. Ziemkiewicz, pytany, dlaczego nie wierzy w zamach smoleński, odrzekł, że z tego samego powodu, dla którego nie wierzy np. w to, iż atak na Pearl Harbor był celowo sprowokowany przez Jankesów, by nakłonić opinię publiczną do wojny z Japonią. Ja zaś jego podejście podzielam. Ten powód to brzytwa Ockhama, która przed teorią spiskową każe stawiać banalny i swojski burdel na kółkach. Żeby daleko nie szukać – to, co teraz piszę, wymyśliłem sobie zaraz po analizie wyników działania programu. Po paru godzinach pisania, znużony, zwyczajnie o tym zapomniałem. No to weźmy taką komisję wyborczą, której członkowie po kilkunastu godzinach pracy mają jeszcze liczyć głosy, pod presją czasu i odpowiedzialności. Koperty są zamieniane, karty wpadają nie tam, gdzie powinny. Coś nie gra systemowo, bo to przecież nie pierwsze wybory z nieprawidłowościami. Mój model ma wątpliwości do do 2-3% głosów w skali kraju. To więcej, niż wyniosła różnica między kandydatami, więc sprawa jest poważna. O koniecznych zmianach po stronie dotyczącej wyborców (mObywatel lub skanowanie kartonikowych dowodów) mówi się nie od dziś. Kwestia liczenia głosów jest chyba jeszcze ważniejsza.

Program napisany w Pythonie jest dostępny do pobrania i przetestowania. Instalacja Pythona nie gryzie, więc nie bawiłem się jakieś pliki wykonywalne. W kodzie zaszyte są współczynniki przepływu elektoratu, którymi można się pobawić. W repozytorium są również niezbędne do działania programu pliki protokoly_po_obwodach_utf8.csv i protokoly_po_obwodach_w_drugiej_turze_utf8.csv (nazwy takie, jak na serwerze gov.pl). Szczegóły dotyczące uruchamiania programu znajdziecie w pliku README.md.

Comments

comments

Autor wpisu: Bart

Naczelny czasu traciciel