kouprianov: (Default)
Created a repo containing data, scripts, and visualisations for COVID-2019 epidemics in Russia.

https://github.com/alexei-kouprianov/COVID.2019.ru
kouprianov: (Default)

Вообще, такая задача встречается крайне редко, потому что гистограммы печатаются отлично и без того, при помощи специальной функции hist(). Более того, если зачем-то нужно именно напечатать ее при помощи plot(), то можно записать гистограмму в объект, а потом напечатать объект при помощи plot():

hist.x <- hist(x)
plot(hist.x)

Однако мне пришлось решить не совсем тривиальную задачу. Надо было напечатать в черно-белом варианте две просвечивающие сквозь друг друга гистограммы, назовем их A и B, с доволно узкими бинами. Будь бины широкими, разнонаправленная штриховка «читалась» бы легко, и то в глазах бы рябило, но с узкими все выглядело совсем плохо, хотя, конечно, при большом желании, читалось.

Мне же надо было сделать так, чтобы даже те, кто не имеет большого желания, поняли, что тут надо увидеть. Тогда я подумал, что было бы неплохо сделать одну из гистограмм (B) черной, оставив другую (A) заштрихованной, однако оставалась одна проблема: с определенного момента столбики B оказывались систематически выше, чем столбики A, в результате чего столбики A были бы совершенно не видны.

Тогда я подумал, что можно напечатать B поверх A, а после этого напечатать поверх них еще одну гистограмму, C, со штриховкой белого цвета, тогда будет казаться, что A просвечивает сквозь B тонкими белыми линиями.

Оставалось решить только одну проблему: A и B генерировались стандартной функцией hist(), а откуда брать C, было ясно только в общих чертах. Теретически, надо было собрать объект «гистограмма» при помощи веревочной петли и палки, а потом подсунуть его функции plot() для печати. По сути, гистограмма -- это определенной формы объект класса list, в котором в виде числовых векторов хранятся данные о границах (breaks) и центрах (mids) бинов, их высотах (counts) и кое-какая еще информация, уже не так нужная для того конкретного рисунка, который я собирался напечатать, так что задача не представлялась неразрешимой. Постепенно, после нескольких проб и ошибок, это смутное понимание оформилось в скрипт (имена объектов изменены):

# Недолго думая я использовал первую попытку печати гистограмм, 
# чтобы создать объекты hist.A и hist.B:
hist.A <- hist(A$x, xlim=c(0,50), breaks=-.5:100.5, angle=45, density=22)
hist.B <- hist(B$x, breaks=-.5:152.5, angle=-45, density=22, add=TRUE)

counts <- NULL

# Мне надо было нарисовать увеличенно только часть гистограммы, 
# поэтому я взял по 50 бинов от каждой (понятно, что можно было
# взять обе целиком, ту, в которой бинов было меньше, дополнить 
# нулями в counts).

for(i in 1:50){
   if(hist.A$counts[i] < hist.B$counts[i]){
      counts <- c(counts, hist.A$counts[i])}
   else{
      counts <- c(counts, hist.B$counts[i])}
   }
}

breaks <- -.5:50.5
mids <- 0:50
equidist <- TRUE

# Теперь собираем гистограмму:

hist.C <- list(
breaks,
counts,
mids,
equidist
)

# Добавляем имена элементов объекта:

names(hist.C) <- c(
"breaks",
"counts",
"mids",
"equidist"
)

# Добавляем специфическое имя класса ("histogram"):

attributes(hist.C$class) <- "histogram"

Оставалось только напечатать все это.

hist(A$x, xlim=c(0,30), breaks=-.5:100.5, angle=45, density=22, main="", xlab="Legend for x-axis")
hist(B$x, breaks=-.5:152.5, col=1, add=TRUE)
plot(hist.C, col="white", density=22, add=TRUE)

Там еще легенду пришлось вручную напечатать, но это такие танцы были с rect() и text(), что лучше о них не рассказывать.

kouprianov: (Default)

There are several characters that should be avoided within data fields in .csv and .tdv like files handled by R's read.table() with as many default settings untouched as it is only possible.

#
"
'

The former gives a false impression of a comment, the two latter may be mistaken for data field borders.

Substitute:

" with ”
' with ’
kouprianov: (Default)
Designed a script to process the transcripts of the video records we prepare within the framework of a project on Polling Stations Ethnography. Draws nice pics.

Написал скрипт для обработки дневников видеонаблюдения, создаваемых в рамках проекта по этнографии избирательных участков. Пока он просто натренирован быстро рисовать картинки по динамике явки, но картинки красивые.

https://github.com/alexei-kouprianov/Polling-station-Ethnography
kouprianov: (Default)

Долгие годы не решался сделать это (процедура пугала заковыристостью, альтернатива в виде растрового изображения нужного размера казалась вполне достойной, но тут вопрос принципа -- можно или нет), и вот -- наконец. Начертание основного кириллического шрифта ("CM Sans Cyrillic") страшно, как смерть (надо будет поглядеть, не появилось ли удачных замен), но в генерируемых R PDF, все же, можно использовать кириллицу.

install.packages('extrafont') # Needed only once
library(extrafont) # Needed every session
font_install('fontcm') # Needed only once (installs fontcm fonts)

font_import() # Needed after any new fonts had been installed with font_install() 
loadfonts() # Needed after font_import()

fonts() # Preview font families
fonttable() # Preview all fonts

pdf("plot_cm.pdf", family="CM Sans Cyrillic", encoding="KOI8-R", width=5, height=5)

plot(c(1,5), c(1,5), main="Сделано с CM fonts") 
text(x=3, y=3, cex=1.5, 
  expression(italic(sum(frac(1, n*'!'), n==0, infinity) == 
             lim(bgroup('(', 1 + frac(1, n), ')')^n, n %->% infinity))))

dev.off()

embed_fonts("plot_cm.pdf", outfile="plot_cm_embed.pdf") # embed fonts, create a new and better file

Т. е., коротко говоря, после того, как все в первый раз поставили, в каждой новой сессии это будет выглядеть так:

library(extrafont) # Needed every session

pdf("plot_cm.pdf", family="CM Sans Cyrillic", encoding="KOI8-R", width=5, height=5)

plot(c(1,5), c(1,5), main="Сделано с CM fonts") 
text(x=3, y=3, cex=1.5, 
  expression(italic(sum(frac(1, n*'!'), n==0, infinity) == 
             lim(bgroup('(', 1 + frac(1, n), ')')^n, n %->% infinity))))

dev.off()

embed_fonts("plot_cm.pdf", outfile="plot_cm_embed.pdf") # embed fonts, create a new and better file
Важно! Без embed_fonts() работать не будет. Обратите внимание, что embed_fonts() создает новый файл, в котором и находится итоговая иллюстрация с интегрированными шрифтами.

При написании этой памятки использовал следующие материалы:

kouprianov: (Default)
https://www.digitalocean.com/community/tutorials/how-to-install-r-on-ubuntu-18-04-quickstart
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E298A3A825C0D65DFD57CBB651716619E084DAB9
sudo add-apt-repository 'deb https://cloud.r-project.org/bin/linux/ubuntu bionic-cran35/'
sudo apt update
sudo apt install r-base

Было : R version 3.4.4 (2018-03-15) -- "Someone to Lean On"
Стало : R version 3.5.2 (2018-12-20) -- "Eggshell Igloo"
kouprianov: (Default)
Одна из удобных интегральных метрик количества подтасовок. Когда большие количества малограмотных людей начинают неумело выдумывать цифры из головы, у них постепенно начинают накапливаться излишки красивых цифр (обычно, нулей и пятерок). В результате, частоты последних цифр начинают значительно отклоняться от теоретически ожидаемой (0.1). Эти отклонения можно затем оценить при помощи метода хи-квадрат (он работает с квадратами отклонений от теоретически ожидаемых абсолютных частот). Можно сравнить по этому показателю президентские кампании разных лет. Сделал таблицу (число степеней свободы везде 9, писать не стал) и нарисовал картинку. Общий вывод печален. Несмотря на значительные успехи по ряду направлений, мы не приблизились даже к далеко не безупречным результатам 2000 г., что уж там говорить о каком-то идеальном мире, в котором царствуют стохастические процессы, и люди не ходят голосовать строем.

BALL.VALID.num.last

NB! Нет, это был не ggplot2.

ГодNX2p-value
20009130617.962p = 0.03562
20049577747.292p = 3.463 x 10-7
20089661296.036p < 2.2 x 10-16
20129541442.484p = 2.68 x 10-6
20189769435.029p = 5.89 x 10-5
kouprianov: (Default)
Здесь будет несколько картинок, в которые пока вдумчиво вглядываюсь. Основаны они на простых соображениях. Явка в каждом регионе должна как-то варьировать по участкам. Эта вариация может быть оценена.

Например, можно посмотреть на разброс дисперсий или интерквартильных расстояний. Они могут варьировать в определенных пределах, однако понятно, что полностью контролируемые фальсификаторами регионы будут характеризоваться уменьшением дисперсии (потому что все все рисуют, как сказано), а не полностью контролируемые -- увеличением дисперсии (потому что кто-то рисует, а кто-то -- нет). Кроме того, в некоторых регионах рост дисперсии явки по участкам может быть связан не с фальсификациями, а с обилием корабельных участков с их стопроцентными явками. Нарисовал в связи с этим две серии картинок: интерквартильное расстояние (как робастная мера вариабельности) / количество участков и стандартное отклонение (как величина, связанная с дисперсией) / количество участков. Стабильно относительно «честные» регионы (Алтайский край, Архангельская, Владимирская, Ивановская, Костромская, Магаданская, Мурманская, обл., Ненецкий АО, респ. Карелия и Хакасия, Сахалинская Свердловская и Ярославская обл.) имеют средственные или высокие значения показателей вариабельности. Заведомо подозрительные регионы -- заниженные. Интересно смотреть, как картинка скачком меняется от 2000 г. к 2004-му.

Кроме того, нарисовал наконец диаграмму в осях явка по региону / nonparametric skew (скошенность распределения). Получилось интересно. Стабильно относительно «честные» регионы почти все держатся плотной группой в области невысоких явок и положительной асимметрии. Самые подозрительные -- летают по диаграмме, и, в основном, характеризуются высокими явками и отрицательными значениями непараметрического коэфф. асимметрии. И здесь, понятное дело, картинка меняется от 2000 г. к 2004-му скачком.

Вместе с тем, по этим и иным диаграммам видно, что и в 2000 г. у нас все было уже местами не вполне благополучно.

Начну с конца. Вот явка по региону / nonparametric skew (среднее - медиана)/(стандартное отклонение):

sduv.turn.mean_nps.2000

Остальные -- под cut... )

Еще вывел таблицу регионов с отрицательной асимметрией (обратите внимание на скачок между 2000 и 2004 г., нормализацию в 2012 и новое ухудшение в 2018 г.):

под cut, естественно... )
kouprianov: (Default)
По следам записей о МК-симуляции распределения явки (см. [1] и [2]) по предложению [Андрея Мятлева] попробовал, основываясь на тех же принципах, провести симуляцию более сложного распределения -- численности голосующих по бинам явки, что позволило бы получить минимальные оценки фальсификаций на выборах. Результаты таковы.

Если сложить пики, выступающие за три стандартных отклонения от среднего по МК-симуляции, то на них приходится 780142.7 (780143) голоса, или ~ 1% поданных голосов. Это в несколько раз больше, чем могло бы, все же, находиться в этой области (приблизительно 0.135%). Т.о., по грубым прикидкам, заведомо нарисованными можно считать 674823 голоса из 780143.

За пределами двух стандартных отклонений от среднего находится 1089752, за полутора межквартильными интервалами от медианного значения -- 1098447 голосов, все это -- порядка 1.5% голосовавших.

Следует учесть, что этот метод -- крайне «щадящий» по отношению к фальсификаторам и дает нам абсолютный минимум общих приписок численности проголосовавших, так как исходит из предположения о том, что все наблюдавшиеся на участках значения явки -- «настоящие». С другой стороны, к нему, конечно, не подкопаешься, потому что, даже приняв это допущение, мы все равно получаем крайне маловероятные выбросы на целых и круглых процентных значениях в правом плече распределения.

На графике сплошная черная линия -- исходные данные, толстая красная линия -- среднее арифметическое по 100 итерациям Монте-Карло симуляции (на 1000 итераций ушло бы часов восемь, но результат отличался бы не сильно), серая затененная область между двумя тонкими красными линиями -- среднее плюс-минус три стандартных отклонения.

shpilkin.plot.MC.sim.MEAN-3SD
kouprianov: (Default)
Один умудренный пытом муж изрек по поводу недавних выборов (глядя на график по Петербургу со вторым пиком на 70%): «Обычная мобилизация последнего для, территориальная, профессиональная - а суеты то.... Рекомендую также посмотреть на "двугорбую" Италию на последних парламентских и успокоиться)»

По рекомендации умудренного опытом мужа смотрим на "двугорбую" (мне как-то в данном случае не дается это слово без кавычек) Италию и успокаиваемся...

Я не смог быстро найти данные по избирательным участкам (возможно, они где-то имеются, но я их пока не видел). Италия отдает данные иерархически, по регионам, провинциям и коммунам. Построил более и менее детальные графики (распределения явок по провинциям и по коммунам). При агрегировании по провинциям намечается второй горб (юг Италии [Базиликата, Калабрия, Кампания, Апулия, Сардиния и Сицилия], традиционно отличающийся от севера во многих отношениях, характеризуется более низкой явкой). Региональные отличия хорошо видны на боксплотах и на гистограмме явок по коммунам с разделением на "юг" и "север". Ничего общего с картиной по России, разумеется, нет (у нас межрегиональная изменчивость играет весьма значительную роль, но, в основном, благодаря совершенно противоестественному характеру голосования в целом ряде регионов).

Сайт МВД Италии с данными -- тут: http://elezioni.interno.gov.it/c…/votanti/20180304/votantiCI

Гистограмма явок в провинциях (100 провинций):

hist.TURNOUT.by_Prov

Гистограмма явок в коммунах (7384 коммуны):

hist.TURNOUT.by_Communi

Сравнение явок в регионах (агрегировано по провинциям):

plot.TURNOUT~REGIO.by_Prov

Сравнение явок в регионах (агрегировано по коммунам):

plot.TURNOUT~REGIO.by_Communi

Юг Италии против севера:

hist.TURNOUT.by_Communi.NS

Поскольку в Италии тоже отчитываются (хотя и не без некоторых возможных недоразумений -- есть несколько участков с явкой более 100% [не исключено, что это могут быть спецучастки, поскольку итоговая явка не бывает более 100%]). о промежуточной явке, можно нарисовать еще несколько изумительной красоты картинок. Во-первых, гистограммы явки на 12:00, 19:00, 23:00 и на момент окончания голосования можно совместить на одном графике. Во-вторых, можно посмотреть, как бегут наперегонки юг (Базиликата, Калабрия, Кампания, Апулия, Сардиния и Сицилия) и север Италии (все остальное) в течение дня (юг отстает с самого утра, хотя поначалу никак не выделяется из общего почти идеально симметричного колоколообразного распределения). В конце дня помещаю ранее уже вывешенную картинку с севером и югом, поскольку она логически завершает видеоряд.

Явка во времени:

hist.TURNOUT.by_Communi.TIME

Явка во времени, Юг против Севера: сокрыта под cut'ом... )
kouprianov: (Default)
По следам предыдущей записи. По алгоритму Кобака-Шпилькина-Пшеничникова воспроизведены расчеты по России в целом. Увы, пришлось пока ограничиться 100 итерациями (на 1K ушло бы 7-8 часов, на 10K -- 3-4 дня), но все, что надо -- видно. Например, 70% пик (как и многие в высоком правом плече гистограммы) вываливается за три сигмы (поучительно сравнить его с естественным пиком на 67.7%, который, хоть и торчит, но за коридор вероятных значений, подпрыгивающий вместе с ним, не вылезает). Интересно, что некоторые провалы перед "круглыми" процентами тоже выпадают.

hist.TURNOUT.ru.MEAN-SD.simul

hist.TURNOUT.ru.MEDIAN-IQR.simul
kouprianov: (Default)
Не без любезной помощи Сергея Шпилькина понял, как можно симулировать распределение явок примерно тем методом, который реализован в статье Dmitry Kobak, Sergey Shpilkin, and Maxim S. Pshenichnikov "Integer percentages as electoral falsification fingerprints". The Annals of Applied Statistics. Volume 10, Number 1 (2016), 54-73. [https://arxiv.org/abs/1410.6059]. Должен сказать, что идея гениальна в своей простоте. Т. е., наверное, те, кто этим постоянно занимается, все заранее знали, но мне пришлось изрядно задуматься, чтобы вникнуть в ее логику.

Первая попытка написать скрипт была неудачна (я пошел не тем путем и написал какого-то монстра, который считал часов пять-шесть, после чего умер в борьбе с вектором из 950 млн. значений, который он, похоже, так и не смог соорудить). Вторая была несколько лучше, поскольку навела меня, наконец, на правильную мысль о том, какой должна быть итоговая, третья. С итоговым скриптом поколдую еще немного и выложу на github. UPD: После дальнейшей критики и обсуждений стало ясно, что на подготовительном этапе я зря разбивал участки по бинам. Так возник скрипт версии 2, картинки от которого и будут висеть на видном месте. Картинки от скрипта версии 1.3 убрал под кат.

Второй урок, который я вынес по дороге, состоял в том, что надо отлаживать скрипт на каком-нибудь одном регионе. Вся страна, с ее 97+К участков, [UPD5: для криво написанного скрипта, считающего совершенно не то, что нужно] великовата.

UPD3: скрипт: https://github.com/alexei-kouprianov/Russia-presidental-elections/blob/master/Russia.TURNOUT.MC-simulation.St.Petersburg.r
UPD3: данные: https://github.com/alexei-kouprianov/Russia-presidental-elections/blob/master/spb.q.20180319.txt

UPD6: то же, по всей России: https://kouprianov.dreamwidth.org/355526.html

Это -- подготовительная картинка (UPD4: которая оказалась не нужна, хотя и может быть интересна сама по себе):

plot.VOTERS~TURNOUT.spb

UPD: Это -- две «правильных» результирующих, (важное: пик на 70% вылез-таки из коридора вероятных значений за три СКО):

hist.TURNOUT.spb.MEDIAN-IQR.simul

hist.TURNOUT.spb.MEAN-SD.simul

Бывшие (плохие) картинки от скрипта версии 1.3 -- под кат... )
kouprianov: (Default)
Удалось развести в Петербурге участки с КОИБ/КЭГ и без. КОИБ и КЭГ -- электронные устройства для автоматического учета заполненных избирателями бюллетеней. Данные -- один из массивов по России с сайта ЦИК, архивированный Сергеем Шпилькиным и любезно предоставленный им в общее пользование (данные есть по 2037 из 2052 участков). Результаты экспресс-анализа показывают следующее:

(1) Распределение КОИБ/КЭГ по городу крайне неравномерно. Охвачены Кронштадт, пригороды Юго-Запада, Юго-Запад, Васильевский остров, Охта, Колпино.

(2) При сопоставлении данных по явке видно, что аномальный пик на 70% явки сформирован участками без КОИБ/КЭГ.

(3) При сопоставлении данных по доле голосов за лидера видно, что мода на участках с КОИБ/КЭГ смещена на пару процентов в сторону более высокой поддержки (77-78% против 75-76% на участках без КОИБ/КЭГ).

(4) Если рассматривать долю голосов за лидера не от проголосовавших, а от полной численности избирателей, то на участках с КОИБ/КЭГ и без них моды находятся приблизительно в одном и том же месте, на 46-47%.

Материал «с полей» по вопросу о появлении пика на 70%: http://www.fontanka.ru/2018/03/27/059/

Несколько пояснений:

Высота столбиков приведенных ниже графиков, называемых «гистограммами», показывает, сколько участков попадает в диапазон, границы которого соответствуют границам столбиков. На наших гистограммах ширина диапазона составляет 1%, а границы проведены так, чтобы целое значение процента попадало на середину столбика.

Например, первый диапазон явки -- от 43.5 до 44.5%, середина столбика -- на 44% ровно. В этом диапазоне находится только один участок (без КОИБа) с явкой 43.65%, поэтому столбик такой маленький. Самый высокий голубой столбик, (если не считать столбика в районе 100% явки, где расположены одни только корабли и иные специальные участки) приходится на диапазон 61.5--62.5% (середина столбика на 62% ровно), в него попало 104 участка без КОИБ/КЭГ. Пик в диапазоне 69.5--70.5% (середина на 70% ровно) -- 72 участка без КОИБ/КЭГ. У распределения явки на участках с КОИБ/КЭГ (красные столбики) максимум находится в другом месте, в диапазоне 59.5--60.5% (середина на 60%) -- 45 участков. А вот в диапазонах 61.5--62.5% и 69.5--70.5% их меньше -- 34 и 18 соответственно. Точно так же все устроено на графике, показывающем проценты поддержки лидера.

«Мода» распределения, о которой говорится выше -- это группа самых высоких столбиков (самый «популярный» диапазон значений). В относительно симметричных распределениях другие меры центральности -- хорошо знакомое всем среднее арифметическое и менее широко известная медиана (середина упорядоченного от наименьшего к наибольшему ряда значений исследуемого параметра) -- обычно находятся в пределах модального диапазона значений, в асимметричных -- более или менее смещены влево или вправо. В нашем случае, например, средняя явка по участкам без КОИБ/КЭГ составила 67.36%, а медианная -- 63.80%. По участкам с КОИБ/КЭГ, соответственно, 63.16% и 62.09%. Мы видим, что в обоих случаях среднее арифметическое и медиана находятся довольно близко к модальному диапазону, но чем менее симметрично распределение (а распределение явки на участках без КОИБ/КЭГ менее симметрично из-за аномального пика на 70% и закономерного пика на 100%), тем дальше отстоит среднее арифметическое (медиана более устойчива к выбросам и она ближе к моде, хотя и не всегда совпадает с ней).

Явка = (Действительные бюлл. + Недействительные бюлл.)/(Кол-во избирателей в списке).

Доля голосов за кандидата = (Кол-во бюллетений, поданых за кандидата)/(Действительные бюлл. + Недействительные бюлл.).

Иллюстрации:

(1) Гистограммы явки:

spb_koib.TURNOUT

(2) Гистограммы долей голосов за лидера:

spb_koib.PUTIN.share

(3) Гистограмма долей голосов за лидера от общей списочной численности избирателей на участке:

spb_koib.PUTIN.share.VOTERS

(4) Карта распространения КОИБ/КЭГ (контуры территорий, подведомственных ТИК, любезно предоставлены А.С.Карповым):

map.koib.tik
kouprianov: (Default)
По совету Дмитрия Кобака добавил белого шума в явку (убирает пики на простых кратных отношениях). Пик в районе 70% никуда не ушел (и не должен был, потому что 7/10 -- не самая частая в мире дробь, у не есть достойные конкуренты, но все равно приятно).
spb.hist.TURNOUT.whitenoise
kouprianov: (Default)
The data on the vote for each polling station are accumulated by the Central Electoral Commission and put to a web-site. One of the leading researchers in the field of Russian electoral statistics, Sergei Shpilkin, trained a robot to download these data and shares the data with all data analysts (See https://podmoskovnik.livejournal.com/178700.html ).

The diagnostic plots based on the data for 97674 polling stations reveal a clearly visible pattern of outrageous data forgery. The histograms for voters' turnout and the shares of ballots cast for Vladimir Putin show clear anomalous peaks at "round" percentiles (70%, 75%, 80%, 85%, 90%, and, after 90% with 1% increment). A two-dimensional histogram for the said parameters (the so-called Sobianin-Sukhovolskii plot) reveals vertical "shades" starting from 50% turnout, and becoming more and more visible at 60%, 70%, etc. degrading into a clearly visible grid pattern in the top-right corner of the plot (to reveal the data points overlaps, semi-transparent data points are used, the thicker the overlap, the darker the dot).

Histogram for the shares of ballots cast for Vladimir Putin at each polling station:

ru.hist.PUTIN.share

Histogram for voters' turnout (Y-axis truncated to reveal the shape of the frequency distribution):
ru.hist.TURNOUT.truncated

Original histogram for voters' turnout with 100% bin fully drawn... )

Sobianin-Sukhovoskii plot (X-axis: voters' turnout at a polling station; Y-axis: share of ballots cast for Vladimir Putin at a polling station):
ru.ss.plot

The same, enlarged (1500 х 1500 px)... )
kouprianov: (Default)
UPD/Disclaimer: данные по России в целом собраны с сайта ЦИК и любезно предоставлены для анализа всеми желающими Сергеем Шпилькиным: https://podmoskovnik.livejournal.com/178700.html

Перед выборами выдвигалось несколько гипотез о причинах озабоченности окружения президента вопросами явки. Одна из гипотез состояла в том, что повышенная явка поможет избежать масштабных фальсификаций при подсчете голосов. Должен сказать, что гипотеза эта, в общем, провалилась с треском (в том плане, что организаторам не удалось избежать масштабных фальсификаций, которые были бы незаметны глазу, вооруженному данными, соответствующим программным обеспечением и минимальными познаниями о стохастических процессах). Совокупный объем приписок может быть несколько меньшим, чем в некоторые из предыдущих лет, но первый же взгляд на базовые графики (гистограмма явки на участках, гистограмма долей голосов за лидера на участках, диаграмма Собянина-Суховольского для участков) показывает, что, начиная от явки в 70% и выше грубо нарисованные данные мощным потоком вливаются в «настоящие». Обратите внимания на пики на значениях явки, кратных 5 и 10, а в зоне более 90% -- на каждом процентном пункте. На диаграмме Собянина-Суховольского (по X -- явка на участке, по Y -- доля голосов за лидера), участки с кратными целым процентам значениями образуют хорошо различимый сетчатый паттерн в верхнем правом углу. Чтобы этот паттерн стал заметен, достаточно сделать точки, соответствующие отдельным УИК полупрозрачными, чтобы при совпадении позиций точек становились заметны результаты наложения.

Гистограмма долей голосов за В. В. Путина:

ru.hist.PUTIN.share

Гистограмма явки (увеличено):
ru.hist.TURNOUT.truncated

под катом исходная, до обрезки участков со 100% явкой... )

Диаграмма Собянина-Суховольского:
ru.ss.plot

под катом она же, увеличенная (1500 х 1500)... )
kouprianov: (Default)
Вчера в качестве журналиста от «Наблюдателей Петербурга» немного ездил по участкам, смотрел, что происходит, говорил с разными наблюдателями. По просьбе координатора по Пиморскому району стался на подсчет голосов на участке #1843. Отчет о путешествиях и впечатлениях постараюсь сдать в ближайшее время. Сегодня утром скачал данные по Петербургу и нарисовал несколько картинок.

Вот -- гистограмма явки. Что не нравится? Многовершинность, в том числе какой-то странный пик в районе 70%, он еще появится на диаграмме Собянина-Суховольского в виде темной вертикальной полосы.
hist.turnout.raw

Вот -- она же, увеличенная:
hist.turnout.truncated

Вот -- гистограмма долей голосов за В. В. Путина (выглядит прилично):
hist.putin.sh

Вот -- общегородская диаграмма Собянина-Суховольского (смущает темная полоса в районе 70% явки, о которой писал выше):
spb.ss.plot

Вот -- развертка по ТИКам. Не все выглядят хорошо (хотя и намного приличнее того, что бывало ранее), подробее напишу сображения позже (очевидно, впрочем, что все более-менее значительные отклонения от эллиптической формы облака -- плохо):
spb.ss.plot.by_tiks

Вот -- участок, на котором я остался наблюдать за подсчетом голосов. Выглядит пристойно на общем фоне.
spb.ss.plot.tik.reddot.9
kouprianov: (Default)
Вывесил на Academia переработанную версию первой части руководства по R. Дописываю вторую (про картинки), однако, опасаюсь, что на нее уйдет еще не менее нескольких недель (сейчас готова наполовину примерно). Большое спасибо Diliara Valeeva за обсуждение (все, что мог и с чем согласился, постарался изменить / расширить, но что-то просто будет в следующих частях). Эта версия не финальная, но добавлений / изменений к этому разделу будет уже, вероятно, немного.

https://www.academia.edu/35756044/Basics_of_data_analysis_and_graphics_in_R_Part_one_command-line_interface_objects_functions_and_file_management
kouprianov: (Default)

В последние годы в кругах, причастных цифровой гуманиоре, популярны работы Льва Мановича [см. http://manovich.net/ ], придумавшего и пропагандирующего интересные формы работы с большими массивами изображений. Обычно, как я понял, он получает эти массивы по API из Instagram или аналогичных источников, потом создает базы изображений и сопутствующих метаданных и строит умопомрачительной красоты визуализации.

Часто говорят о том, что он работает с изображениями в «нередуцированном» виде. Из чтения его работ я не понял, что имеется в виду под нередуцированным видом, потому что вся умопомрачительная графика строится на том, что из графического файла извлекаются весьма немногие суммарные характеристики (обычно усредненная яркость, контрастность и время создания), после чего вся коллекция располагается в осях этих переменных. Отдельные изображения, в зависимости от размеров графика и количества изображений, могут репрезентировать точки, покрашенные в усредненный по изображению цвет, или уменьшенные / неуменьшенные копии изображений, играющие роль все тех же точек на графике, но краше.

Сам Манович предлагает использовать для работы специально созданный им программный продукт, который состоит из надстройки над Jimage. Немного подумав, я решил, что нет ничего запредельно сложного, в том, чтобы добиться того же иными средствами, не отходя далеко от R (в работе с R я вижу два плюса -- возможность создания скриптов, позволяющих воспроизводить преобразования данных, расчеты и графики, и бесконечный аналитический потенциал). При такой простоте подхода к презентации данных, ключевой вопрос был, как понятно, в том, чтобы как-то получить эти самые данные об изображениях (потому что, получив их, нарисовать типичный график несложно). Я не рассматриваю здесь вопрос о сборе метаданных (авторы, комментарии, геопозиция, количество лайков и т. п.) и получении изображений как таковых. Они лежат в несколько иной плоскости (роботы-фетчеры и API), меня интересуют вопросы об анализу уже наличных коллекций.

Если изображения уже имеются в вашем распоряжении, добыть данные об их параметрах гораздо проще, чем может показаться на первый взгляд. Помимо GUI редакторов для графики, как известно, есть довольно мощные инструменты для работы с графикой из командной строки. Я использую в таких случаях ImageMagick (да нагуглится имя его). В его состав, среди многого прочего, входит утилита identify, которая возвращает от просмотренных ею файлов довольно изрядный список параметров. Если не указано иное, то возвращает она его на стандартное устройство вывода (экран), но можно указать иное и направить весь этот поток текста в файл. Вот несколько сокращенный real-life пример данных по одному из моих файлов (фото, сделанное цифровым фотоаппаратом).

Пример под cut... )

Как нетрудно догадаться, можно заставить собрать эту информацию от всех файлов, находящихся в определенном месте. Для меня это были все подпапки в одной из папок фотоархива. Для этого пришлось написать такой простенький скрипт:

Файл imagedata.sh:

#!/bin/bash
shopt -s globstar
for img in **/*.JPG; do identify "$img" -verbose >> imagedata.raw.txt
done

Скрипт жужжал больше часу, собрал 60+ МБ всей этой словесно-цифирной шелухи из 7+ тыс. файлов (скромно, в общем, но я мало снимаю в последние годы). Пришла пора достать оттуда то, что нужно (умные люди могут делать это на лету, думаю, и я, попыхтев немного с sed, смог бы, но пыхтеть не хотелось и я пошел по пути наименьшего сопротивления, написав [опять-таки, по мнению знатоков, наверняка избыточный] скрипт на perl). Доставать я собирался время создания, параметры каналов RGB (mean и standard deviation) и суммарные характеристики изображения, которые могут сойти за меры общей яркости и общей контрастности Overall / mean и Overall / standard deviation.

скрипт тоже под cut... )

После чего у меня образовался небольшой файлик на 1.2 МБ, который уже можно было загружать в R. После загрузки удалось нарисовать несколько картинок примерно настолько же осмысленных, как и картинки автора идеи. Самая большая возня была, как это ни смешно, с осью времени (я редко работаю со временем в таком формате), но все как-то утряслось. Их можно допиливать и дальше (например, теоретически возможен вариант с использованием сильно уменьшенных изображений в качестве точек на графиках), но это уже не принципиально.

Вот -- коллекция, развернутая в осях: яркость / контрастность:

scatter.man

Вот, в порядке нарастания детализации, временные ленты для яркости...:

band.man.20110701_20171231.mean
band.man.20120715_20120731.mean
band.man.20120726.mean

...и контрастности:

band.man.20110701_20171231.sd
band.man.20120715_20120731.sd
band.man.20120726.sd

March 2025

S M T W T F S
      1
2345678
910 1112131415
16171819202122
23242526272829
3031     

Syndicate

RSS Atom

Page Summary

Style Credit

Expand Cut Tags

No cut tags
Page generated Jul. 10th, 2025 01:16 am
Powered by Dreamwidth Studios