-
Notifications
You must be signed in to change notification settings - Fork 1
/
benford.rb
55 lines (49 loc) · 1.5 KB
/
benford.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
require 'amazing_print'
# first digit probabilities
#BENFORD = [0.301, 0.176, 0.125, 0.097, 0.079, 0.067, 0.058, 0.051, 0.046].freeze
# second digit probabilities
BENFORD = [0.1197, 0.1139, 0.1088, 0.1043, 0.1003, 0.0967, 0.0934, 0.0904, 0.0876, 0.0850].freeze
def benford precinct_data
benford_data = {}
precinct_data.each do |precinct, candidate_data|
candidate_data.each do |candidate, vote_data|
vote_data.each do |vote_type, count|
digit = count[1]
next if digit.nil?
benford_data[candidate] ||= {}
benford_data[candidate][vote_type] ||= {
'0' => 0,
'1' => 0,
'2' => 0,
'3' => 0,
'4' => 0,
'5' => 0,
'6' => 0,
'7' => 0,
'8' => 0,
'9' => 0
}
benford_data[candidate][vote_type][digit] += 1
end
end
end
ap benford_data
chi_square_test(benford_data)
end
def chi_square_test(benford_data)
benford_data.each do |candidate, c_data|
c_data.each do |vote_type, v_data|
total_count = v_data.map { |_, count| count }.sum
chi_square_stat = 0
v_data.each_with_index do |(digit, count), i|
expected_count = total_count * BENFORD[i]
chi_square = (count - expected_count) ** 2
chi_square_stat += chi_square / expected_count
end
puts ""
puts "Candidate: #{candidate}"
puts "Vote Type: #{vote_type}"
puts "Chi-squared Test Stat (over 15.51 is red flag): #{chi_square_stat}"
end
end
end