From fdfb807430b87a83feaa4b9948f518f0e1d1d664 Mon Sep 17 00:00:00 2001 From: s452662 Date: Sat, 27 Jan 2024 22:31:51 +0100 Subject: [PATCH] added new fuzzy logic methods --- data_filters.py | 53 +----------- fuzzy.py | 222 ++++++++++++++++++++++++++++++++++++++++++++++++ main.py | 1 + rules.py | 115 ------------------------- 4 files changed, 226 insertions(+), 165 deletions(-) create mode 100644 fuzzy.py diff --git a/data_filters.py b/data_filters.py index 51e903d..fcd4af1 100644 --- a/data_filters.py +++ b/data_filters.py @@ -1,7 +1,6 @@ import pandas as pd -from simpful import * +from fuzzy import * -FS = FuzzySystem() def generateTrainingData(dataframe): columns = ['season','date','home_team','away_team','result_full','home_passes','away_passes', 'home_possession','away_possession','home_shots','away_shots'] @@ -17,55 +16,7 @@ def generateFuzzyLogicData(dataframe): 'c_home_diff_season', 'c_away_diff_season'] return dataframe[columns] -def calculateFuzzyAggression(yellow_cards, red_cards): - FS.set_crisp_output_value("low", 0.0) - FS.set_crisp_output_value("average", 0.5) - FS.set_crisp_output_value("high", 1.0) - Yellow_cards1 = TriangleFuzzySet(0, 2, 3, term="low") - Yellow_cards2 = TriangleFuzzySet(2, 3, 4, term="average") - Yellow_cards3 = TriangleFuzzySet(3, 4, 4, term="high") - - FS.add_linguistic_variable("yellow_cards", LinguisticVariable([Yellow_cards1, Yellow_cards2, Yellow_cards3], universe_of_discourse=[0, 10])) - - Red_cards1 = TriangleFuzzySet(0, 0, 1, term="low") - Red_cards2 = TriangleFuzzySet(0, 1, 2, term="average") - Red_cards3 = TriangleFuzzySet(1, 2, 2, term="high") - - FS.add_linguistic_variable("red_cards", LinguisticVariable([Red_cards1, Red_cards2, Red_cards3], universe_of_discourse=[0, 4])) - - # Pass_domination1 = TriangleFuzzySet(2,2,6, term="low") - # Pass_domination2 = TriangleFuzzySet(3,5,7, term="average") - # Pass_domination3 = TriangleFuzzySet(4,8,8, term="high") - - # FS.add_linguistic_variable("passes_domination", LinguisticVariable([Pass_domination1, Pass_domination2, Pass_domination3], universe_of_discourse=[0,10])) - - FS.add_rules([ - - "IF (yellow_cards IS low) AND (red_cards IS low) THEN (aggression IS low)", - - "IF (yellow_cards IS high) AND (red_cards IS high) THEN (aggression IS high)", - - "IF (yellow_cards IS average) AND (red_cards IS average) THEN (aggression IS average)", - - "IF (yellow_cards IS low) AND (red_cards IS high) THEN (aggression IS high)", - - "IF (yellow_cards IS high ) AND (red_cards IS low) THEN (aggression IS high)", - - "IF (yellow_cards IS average) AND (red_cards IS high) THEN (aggression IS high)", - - "IF (yellow_cards IS high) AND (red_cards IS average) THEN (aggression IS high)", - - "IF (yellow_cards IS low) AND (red_cards IS average) THEN (aggression IS low)", - - "IF (yellow_cards IS average) AND (red_cards IS low) THEN (aggression IS average)" - ]) - - FS.set_variable("yellow_cards", yellow_cards) - FS.set_variable("red_cards", red_cards) - - aggression = FS.inference() - return aggression def last5Matches(season, teamA, data, df): # Wybierz rekordy dla danej pary drużyn i sezonu subset = df[((df['season'] == season) & ((df['home_team'] == teamA) | (df['away_team'] == teamA)))] @@ -166,3 +117,5 @@ def calculateGoalDifference(matches, team): else: goal_diff = goal_diff + (y-x) return goal_diff + + diff --git a/fuzzy.py b/fuzzy.py new file mode 100644 index 0000000..5106996 --- /dev/null +++ b/fuzzy.py @@ -0,0 +1,222 @@ +from simpful import * +from data_filters import * +import pandas as pd + +FS = FuzzySystem() + +# Dominacja OK +# Jakość strzałów - Witek +# Agresesywnosc (zolte + czerwone kartki) - Wojtek +# odbiory i wslizgi (xDef) - Michał, ekspert od xDef +# statystyki z calego sezonu - Wojtek OK +# 5 ostatnich spotkan miedzy druzynami - Witek +def categorize_fuzzy_passes(passes,possession): + + + FS.set_crisp_output_value("low", 0.0) + FS.set_crisp_output_value("average", 0.5) + FS.set_crisp_output_value("high", 1.0) + + Pass1 = TriangleFuzzySet(300,300,500, term="low") + Pass2 = TriangleFuzzySet(300,450,600, term="average") + Pass3 = TriangleFuzzySet(400,600,600, term="high") + + FS.add_linguistic_variable("passes", LinguisticVariable([Pass1, Pass2, Pass3], universe_of_discourse=[0,1000])) + + Poss1 = TriangleFuzzySet(30,30,45, term="low") + Poss2 = TriangleFuzzySet(40,50,60, term="average") + Poss3 = TriangleFuzzySet(55,70,70, term="high") + + FS.add_linguistic_variable("possession", LinguisticVariable([Poss1, Poss2, Poss3], universe_of_discourse=[0,100])) + + + #Pass_domination1 = TriangleFuzzySet(2,2,6, term="low") + #Pass_domination2 = TriangleFuzzySet(3,5,7, term="average") + #Pass_domination3 = TriangleFuzzySet(4,8,8, term="high") + + #FS.add_linguistic_variable("passes_domination", LinguisticVariable([Pass_domination1, Pass_domination2, Pass_domination3], universe_of_discourse=[0,10])) + + + FS.add_rules([ + + "IF (passes IS low) AND (possession IS low) THEN (pass_domination IS low)", + + "IF (passes IS high) AND (possession IS high) THEN (pass_domination IS high)", + + "IF (passes IS average) AND (possession IS average) THEN (pass_domination IS average)", + + "IF (passes IS low) AND (possession IS high) THEN (pass_domination IS average)", + + "IF (passes IS high ) AND (possession IS low) THEN (pass_domination IS average)", + + "IF (passes IS average) AND (possession IS high) THEN (pass_domination IS high)", + + "IF (passes IS high) AND (possession IS average) THEN (pass_domination IS high)", + + "IF (passes IS low) AND (possession IS average) THEN (pass_domination IS low)", + + "IF (passes IS average) AND (possession IS low) THEN (pass_domination IS average)" + ]) + + FS.set_variable("passes", passes) + + FS.set_variable("possession", possession) + + pass_domination = FS.inference() + + return pass_domination + + +def categorize_fuzzy_defence(tackles,clearances): + + + FS.set_crisp_output_value("low", 0.0) + FS.set_crisp_output_value("average", 0.5) + FS.set_crisp_output_value("high", 1.0) + + Tackle1 = TriangleFuzzySet(12,12,20, term="low") + Tackle2 = TriangleFuzzySet(12,18,24, term="average") + Tackle3 = TriangleFuzzySet(16,24,24, term="high") + + FS.add_linguistic_variable("tackles", LinguisticVariable([Tackle1, Tackle2, Tackle3], universe_of_discourse=[0,100])) + + Clear1 = TriangleFuzzySet(12,12,30, term="low") + Clear2 = TriangleFuzzySet(12,27,42, term="average") + Clear3 = TriangleFuzzySet(24,42,42, term="high") + + FS.add_linguistic_variable("clearances", LinguisticVariable([Clear1, Clear2, Clear3], universe_of_discourse=[0,100])) + + FS.add_rules([ + + "IF (tackles IS low) AND (clearances IS low) THEN (defence_actions IS low)", + + "IF (tackles IS high) AND (clearances IS high) THEN (defence_actions IS high)", + + "IF (tackles IS average) AND (clearances IS average) THEN (defence_actions IS average)", + + "IF (tackles IS low) AND (clearances IS high) THEN (defence_actions IS average)", + + "IF (tackles IS high ) AND (clearances IS low) THEN (defence_actions IS average)", + + "IF (tackles IS average) AND (clearances IS high) THEN (defence_actions IS high)", + + "IF (tackles IS high) AND (clearances IS average) THEN (defence_actions IS high)", + + "IF (tackles IS low) AND (clearances IS average) THEN (defence_actions IS low)", + + "IF (tackles IS average) AND (clearances IS low) THEN (defence_actions IS average)" + ]) + + FS.set_variable("tackles", tackles) + + FS.set_variable("clearances", clearances) + + defence_actions = FS.inference() + + return defence_actions + +def categorize_fuzzy_shots(shots_overall, shots_on_target): + + FS.set_crisp_output_value("low", 0.0) + FS.set_crisp_output_value("average", 0.5) + FS.set_crisp_output_value("high", 1.0) + + Shot_ov1 = TriangleFuzzySet(0,0,6, term="low") #pozmieniać przedziały (nakładają się) + Shot_ov2 = TriangleFuzzySet(5,10,15, term="average") + Shot_ov3 = TriangleFuzzySet(14,25,25, term="high") + + FS.add_linguistic_variable("shots_overall", LinguisticVariable([Shot_ov1, Shot_ov2, Shot_ov3], universe_of_discourse=[0,35])) + + Shot_ont1 = TriangleFuzzySet(0,0,3, term="low") + Shot_ont2 = TriangleFuzzySet(2,4,6, term="average") + Shot_ont3 = TriangleFuzzySet(5,10,10, term="high") + + FS.add_linguistic_variable("shots_on_target", LinguisticVariable([Shot_ont1, Shot_ont2, Shot_ont3], universe_of_discourse=[0,15])) + + + #Qual_of_shots1 = TriangleFuzzySet(0,0,0.3, term="low") + #Qual_of_shots2 = TriangleFuzzySet(0.2,0.5,0.8, term="medium") + #Qual_of_shots3 = TriangleFuzzySet(0.7,1,1, term="high") + + #FS.add_linguistic_variable("expected_goals", LinguisticVariable([Qual_of_shots1, Qual_of_shots2, Qual_of_shots3], universe_of_discourse=[0,1])) + + + FS.add_rules([ + + "IF (shots_overall IS low) AND (shots_on_target IS low) THEN (quality_of_shots IS low)", + + "IF (shots_overall IS high) AND (shots_on_target IS high) THEN (quality_of_shots IS high)", + + "IF (shots_overall IS average) AND (shots_on_target IS average) THEN (quality_of_shots IS average)", + + "IF (shots_overall IS low) AND (shots_on_target IS high) THEN (quality_of_shots IS high)", + + "IF (shots_overall IS high ) AND (shots_on_target IS low) THEN (quality_of_shots IS low)", + + "IF (shots_overall IS average) AND (shots_on_target IS high) THEN (quality_of_shots IS high)", + + "IF (shots_overall IS high) AND (shots_on_target IS average) THEN (quality_of_shots IS average)", + + "IF (shots_overall IS low) AND (shots_on_target IS average) THEN (quality_of_shots IS average)", + + "IF (shots_overall IS average) AND (shots_on_target IS low) THEN (quality_of_shots IS low)" + + ]) + + FS.set_variable("shots_overall", shots_overall) + + FS.set_variable("shots_on_target", shots_on_target) + + quality_of_shots = FS.inference() + + return quality_of_shots + +def calculateFuzzyAggression(yellow_cards, red_cards): + FS.set_crisp_output_value("low", 0.0) + FS.set_crisp_output_value("average", 0.5) + FS.set_crisp_output_value("high", 1.0) + + Yellow_cards1 = TriangleFuzzySet(0, 2, 3, term="low") + Yellow_cards2 = TriangleFuzzySet(2, 3, 4, term="average") + Yellow_cards3 = TriangleFuzzySet(3, 4, 4, term="high") + + FS.add_linguistic_variable("yellow_cards", LinguisticVariable([Yellow_cards1, Yellow_cards2, Yellow_cards3], universe_of_discourse=[0, 10])) + + Red_cards1 = TriangleFuzzySet(0, 0, 1, term="low") + Red_cards2 = TriangleFuzzySet(0, 1, 2, term="average") + Red_cards3 = TriangleFuzzySet(1, 2, 2, term="high") + + FS.add_linguistic_variable("red_cards", LinguisticVariable([Red_cards1, Red_cards2, Red_cards3], universe_of_discourse=[0, 4])) + + # Pass_domination1 = TriangleFuzzySet(2,2,6, term="low") + # Pass_domination2 = TriangleFuzzySet(3,5,7, term="average") + # Pass_domination3 = TriangleFuzzySet(4,8,8, term="high") + + # FS.add_linguistic_variable("passes_domination", LinguisticVariable([Pass_domination1, Pass_domination2, Pass_domination3], universe_of_discourse=[0,10])) + + FS.add_rules([ + + "IF (yellow_cards IS low) AND (red_cards IS low) THEN (aggression IS low)", + + "IF (yellow_cards IS high) AND (red_cards IS high) THEN (aggression IS high)", + + "IF (yellow_cards IS average) AND (red_cards IS average) THEN (aggression IS average)", + + "IF (yellow_cards IS low) AND (red_cards IS high) THEN (aggression IS high)", + + "IF (yellow_cards IS high ) AND (red_cards IS low) THEN (aggression IS high)", + + "IF (yellow_cards IS average) AND (red_cards IS high) THEN (aggression IS high)", + + "IF (yellow_cards IS high) AND (red_cards IS average) THEN (aggression IS high)", + + "IF (yellow_cards IS low) AND (red_cards IS average) THEN (aggression IS low)", + + "IF (yellow_cards IS average) AND (red_cards IS low) THEN (aggression IS average)" + ]) + + FS.set_variable("yellow_cards", yellow_cards) + FS.set_variable("red_cards", red_cards) + + aggression = FS.inference() + return aggression \ No newline at end of file diff --git a/main.py b/main.py index 1e1ab2c..72befe3 100644 --- a/main.py +++ b/main.py @@ -2,6 +2,7 @@ import pandas as pd from simpful import * from rules import * from data_filters import * +from fuzzy import * from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score diff --git a/rules.py b/rules.py index 8ae0c0a..9112662 100644 --- a/rules.py +++ b/rules.py @@ -1,121 +1,6 @@ -import simpful from data_filters import * import pandas as pd -FS = FuzzySystem() - -# Dominacja OK -# Jakość strzałów - Witek -# Agresesywnosc (zolte + czerwone kartki) - Wojtek -# odbiory i wslizgi (xDef) - Michał, ekspert od xDef -# statystyki z calego sezonu - Wojtek OK -# 5 ostatnich spotkan miedzy druzynami - Witek -def categorize_fuzzy_passes(passes,possession): - - - FS.set_crisp_output_value("low", 0.0) - FS.set_crisp_output_value("average", 0.5) - FS.set_crisp_output_value("high", 1.0) - - Pass1 = TriangleFuzzySet(300,300,500, term="low") - Pass2 = TriangleFuzzySet(300,450,600, term="average") - Pass3 = TriangleFuzzySet(400,600,600, term="high") - - FS.add_linguistic_variable("passes", LinguisticVariable([Pass1, Pass2, Pass3], universe_of_discourse=[0,1000])) - - Poss1 = TriangleFuzzySet(30,30,45, term="low") - Poss2 = TriangleFuzzySet(40,50,60, term="average") - Poss3 = TriangleFuzzySet(55,70,70, term="high") - - FS.add_linguistic_variable("possession", LinguisticVariable([Poss1, Poss2, Poss3], universe_of_discourse=[0,100])) - - - #Pass_domination1 = TriangleFuzzySet(2,2,6, term="low") - #Pass_domination2 = TriangleFuzzySet(3,5,7, term="average") - #Pass_domination3 = TriangleFuzzySet(4,8,8, term="high") - - #FS.add_linguistic_variable("passes_domination", LinguisticVariable([Pass_domination1, Pass_domination2, Pass_domination3], universe_of_discourse=[0,10])) - - - FS.add_rules([ - - "IF (passes IS low) AND (possession IS low) THEN (pass_domination IS low)", - - "IF (passes IS high) AND (possession IS high) THEN (pass_domination IS high)", - - "IF (passes IS average) AND (possession IS average) THEN (pass_domination IS average)", - - "IF (passes IS low) AND (possession IS high) THEN (pass_domination IS average)", - - "IF (passes IS high ) AND (possession IS low) THEN (pass_domination IS average)", - - "IF (passes IS average) AND (possession IS high) THEN (pass_domination IS high)", - - "IF (passes IS high) AND (possession IS average) THEN (pass_domination IS high)", - - "IF (passes IS low) AND (possession IS average) THEN (pass_domination IS low)", - - "IF (passes IS average) AND (possession IS low) THEN (pass_domination IS average)" - ]) - - FS.set_variable("passes", passes) - - FS.set_variable("possession", possession) - - pass_domination = FS.inference() - - return pass_domination - -def categorize_fuzzy_shots(shots_overall, shots_on_target): - - FS.set_crisp_output_value("low", 0.0) - FS.set_crisp_output_value("average", 0.5) - FS.set_crisp_output_value("high", 1.0) - - Shot_ov1 = TriangleFuzzySet(0,0,5, term="low") #pozmieniać przedziały (nakładają się) - Shot_ov2 = TriangleFuzzySet(5,10,15, term="medium") - Shot_ov3 = TriangleFuzzySet(15,25,25, term="high") - - FS.add_linguistic_variable("shots_overall", LinguisticVariable([Shot_ov1, Shot_ov2, Shot_ov3], universe_of_discourse=[0,35])) - - Shot_ont1 = TriangleFuzzySet(0,0,2, term="low") - Shot_ont2 = TriangleFuzzySet(2,4,6, term="medium") - Shot_ont3 = TriangleFuzzySet(6,10,10, term="high") - - FS.add_linguistic_variable("shots_on_target", LinguisticVariable([Shot_ont1, Shot_ont2, Shot_ont3], universe_of_discourse=[0,15])) - - - #Qual_of_shots1 = TriangleFuzzySet(0,0,0.3, term="low") - #Qual_of_shots2 = TriangleFuzzySet(0.2,0.5,0.8, term="medium") - #Qual_of_shots3 = TriangleFuzzySet(0.7,1,1, term="high") - - #FS.add_linguistic_variable("expected_goals", LinguisticVariable([Qual_of_shots1, Qual_of_shots2, Qual_of_shots3], universe_of_discourse=[0,1])) - - - FS.add_rules([ - - "IF (shots_overall IS low) AND (shots_on_target IS low) THEN (quality_of_shots IS low)", - - "IF (shots_overall IS high) AND (shots_on_target IS high) THEN (quality_of_shots IS high)", - - "IF (shots_overall IS average) AND (shots_on_target IS average) THEN (quality_of_shots IS average)", - - "IF (shots_overall IS low) AND (shots_on_target IS high) THEN (quality_of_shots IS high)", - - "IF (shots_overall IS high ) AND (shots_on_target IS low) THEN (quality_of_shots IS low)", - - "IF (shots_overall IS average) AND (shots_on_target IS high) THEN (quality_of_shots IS high)", - - "IF (shots_overall IS high) AND (shots_on_target IS average) THEN (quality_of_shots IS average)", - - "IF (shots_overall IS low) AND (shots_on_target IS average) THEN (quality_of_shots IS average)", - - "IF (shots_overall IS average) AND (shots_on_target IS low) THEN (quality_of_shots IS low)" - - ]) - - - def categorize_shots(shots): if shots >= 12: