Last active
January 18, 2019 00:47
-
-
Save kliph/2906141e4a0949d8f696b32fcbe2bea7 to your computer and use it in GitHub Desktop.
Predict Soccer win streaks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
*#* | |
*~* | |
.bundle |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
soccer-predict |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2.6.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
source 'https://rubygems.org' | |
gem 'nokogiri' | |
gem 'pry' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
GEM | |
remote: https://rubygems.org/ | |
specs: | |
coderay (1.1.2) | |
method_source (0.9.2) | |
mini_portile2 (2.3.0) | |
nokogiri (1.8.2) | |
mini_portile2 (~> 2.3.0) | |
pry (0.12.2) | |
coderay (~> 1.1.0) | |
method_source (~> 0.9.0) | |
PLATFORMS | |
ruby | |
DEPENDENCIES | |
nokogiri | |
pry | |
BUNDLED WITH | |
1.17.3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'open-uri' | |
require 'nokogiri' | |
# previous_picks = ["Chelsea", 'Tottenham'] | |
# Usage: | |
# load 'predict.rb' | |
# p = Predict.new(previous_picks) | |
# start = Time.now; p.realize_streaks!; Time.now - start | |
# p.scored_streaks | |
class Predict | |
attr_accessor :teams, :matches, :upcoming_probabilities, :streaks, :scored_streaks, :previous_picks | |
def initialize(previous_picks = []) | |
@previous_picks = previous_picks | |
@matches = matches_node_set.map do |e| | |
{ | |
first_team_name(e) => first_team_prob(e), | |
second_team_name(e) => second_team_prob(e) | |
} | |
end | |
@teams = matches_node_set.map { |e| [e['data-team1'], e['data-team2']] }.flatten.uniq - @previous_picks | |
@upcoming_probabilities = roi.map { |idx| next_n_matches.map { |ary| ary[idx] }.reduce({}, :merge) } | |
@streaks = [] | |
@scored_streaks = [] | |
@prediction_weights = prediction_weights | |
@evaluated_streaks = {} | |
end | |
def n | |
7 | |
end | |
def evaluate_streaks!(streak) | |
score = 0 | |
evaluated_streak = streak.each_with_index.map do |team, idx| | |
team_score = score_team(team, idx) | |
score += team_score | |
{team => team_score} | |
end | |
@evaluated_streaks[score] = evaluated_streak | |
end | |
def realize_streaks! | |
puts "Evaluating possible streaks..." | |
@teams.permutation(n) { |streak| evaluate_streaks!(streak) } | |
puts "Determining top 10 streaks..." | |
top_scores = @evaluated_streaks.keys.sort{|a, b| b <=> a}.take(10) | |
@scored_streaks = top_scores.map{|k| [k, @evaluated_streaks[k]]} | |
end | |
def score_team(team, idx) | |
score = @upcoming_probabilities[idx][team] | |
score * @prediction_weights[idx] | |
end | |
def roi | |
(0...n) | |
end | |
def prediction_weights | |
[1.5, 1.2, 1.2, 1, 1, 1, 1] | |
end | |
def next_n_matches | |
@teams.map do |team| | |
@matches.partition { |h| h.keys.include? team }.first[roi] | |
end | |
end | |
def percent_to_float(s) | |
s.sub('%', '').to_f / 100 | |
end | |
def first_team_name(match_node) | |
match_node.css('tr.match-top').css('td.team')[0]['data-str'] | |
end | |
def first_team_prob(match_node) | |
percent_to_float(match_node.css('tr.match-top').css('td.prob')[0].children.text) | |
end | |
def second_team_name(match_node) | |
match_node.css('tr.match-bottom').css('td.team')[0]['data-str'] | |
end | |
def second_team_prob(match_node) | |
percent_to_float(match_node.css('tr.match-bottom').css('td.prob')[0].children.text) | |
end | |
def matches_node_set | |
upcoming_games.css('.match-container') | |
end | |
def url | |
'https://projects.fivethirtyeight.com/soccer-predictions/premier-league/' | |
end | |
def doc | |
Nokogiri::HTML(open(url)) | |
end | |
def upcoming_games | |
doc.css('.games-container.upcoming') | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment