mirror of
https://github.com/titanscouting/tra-analysis.git
synced 2024-12-25 17:19:09 +00:00
Merge service-dev changes with master (#24)
* added config.json removed old config files Signed-off-by: Arthur <learthurgo@gmail.com> * superscript.py v 0.0.6.000 Signed-off-by: Arthur <learthurgo@gmail.com> * changed data.py Signed-off-by: Arthur <learthurgo@gmail.com> * changes to config.json Signed-off-by: Arthur <learthurgo@gmail.com> * removed cells from visualize_pit.py Signed-off-by: Arthur <learthurgo@gmail.com> * more changes to visualize_pit.py Signed-off-by: Arthur <learthurgo@gmail.com> * added analysis-master/metrics/__pycache__ to git ignore moved pit configs in config.json to the borrom superscript.py v 0.0.6.001 Signed-off-by: Arthur <learthurgo@gmail.com> * removed old database key Signed-off-by: Arthur <learthurgo@gmail.com> * adjusted config files Signed-off-by: Arthur <learthurgo@gmail.com> * Delete config-pop.json * fixed .gitignore Signed-off-by: Arthur <learthurgo@gmail.com> * analysis.py 1.2.1.003 added team kv pair to config.json Signed-off-by: Arthur <learthurgo@gmail.com> * superscript.py v 0.0.6.002 Signed-off-by: Arthur <learthurgo@gmail.com> * finished app.py API made minute changes to parentheses use in various packages Signed-off-by: Arthur Lu <learthurgo@gmail.com> * bug fixes in app.py Signed-off-by: Arthur Lu <learthurgo@gmail.com> * bug fixes in app.py Signed-off-by: Arthur Lu <learthurgo@gmail.com> * made changes to .gitignore Signed-off-by: Arthur Lu <learthurgo@gmail.com> * made changes to .gitignore Signed-off-by: Arthur Lu <learthurgo@gmail.com> * deleted a __pycache__ folder from metrics Signed-off-by: Arthur Lu <learthurgo@gmail.com> * more changes to .gitignore Signed-off-by: Arthur Lu <learthurgo@gmail.com> * additions to app.py Signed-off-by: Arthur Lu <learthurgo@gmail.com> * renamed app.py to api.py Signed-off-by: Arthur Lu <learthurgo@gmail.com> * removed extranneous files Signed-off-by: Arthur Lu <learthurgo@gmail.com> * renamed api.py to tra.py removed rest api calls from tra.py * renamed api.py to tra.py removed rest api calls from tra.py Signed-off-by: Arthur Lu <learthurgo@gmail.com> * removed flask import from tra.py Signed-off-by: Arthur Lu <learthurgo@gmail.com> * changes to devcontainer.json Signed-off-by: Arthur Lu <learthurgo@gmail.com> * fixed unit tests to be correct removed some tests regressions because of potential function overflow removed trueskill unit test because of slight deviation chance Signed-off-by: Arthur Lu <learthurgo@gmail.com>
This commit is contained in:
parent
ae64c7f10e
commit
4f439d6094
@ -23,5 +23,5 @@
|
||||
"mhutchie.git-graph",
|
||||
"donjayamanne.jupyter",
|
||||
],
|
||||
"postCreateCommand": "pip install -r analysis-master/analysis-amd64/requirements.txt"
|
||||
"postCreateCommand": "pip install -r analysis-master/requirements.txt"
|
||||
}
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -21,11 +21,13 @@ data-analysis/test.ipynb
|
||||
data-analysis/visualize_pit.ipynb
|
||||
data-analysis/config/keys.config
|
||||
analysis-master/analysis/__pycache__/
|
||||
analysis-master/analysis/metrics/__pycache__/
|
||||
data-analysis/__pycache__/
|
||||
analysis-master/analysis.egg-info/
|
||||
analysis-master/build/
|
||||
analysis-master/metrics/
|
||||
data-analysis/config-pop.json
|
||||
data-analysis/__pycache__/
|
||||
analysis-master/__pycache__/
|
||||
analysis-master/.pytest_cache/
|
||||
data-analysis/.pytest_cache/
|
@ -12,6 +12,7 @@ __version__ = "1.2.1.003"
|
||||
# changelog should be viewed using print(analysis.__changelog__)
|
||||
__changelog__ = """changelog:
|
||||
1.2.1.003:
|
||||
- changed output of basic_stats and histo_analysis to libraries
|
||||
- fixed __all__
|
||||
1.2.1.002:
|
||||
- renamed ArrayTest class to Array
|
||||
@ -360,7 +361,7 @@ def basic_stats(data):
|
||||
_min = npmin(data_t)
|
||||
_max = npmax(data_t)
|
||||
|
||||
return _mean, _median, _stdev, _variance, _min, _max
|
||||
return {"mean": _mean, "median": _median, "standard-deviation": _stdev, "variance": _variance, "minimum": _min, "maximum": _max}
|
||||
|
||||
# returns z score with inputs of point, mean and standard deviation of spread
|
||||
@jit(forceobj=True)
|
||||
@ -383,7 +384,7 @@ def z_normalize(array, *args):
|
||||
# expects 2d array of [x,y]
|
||||
def histo_analysis(hist_data):
|
||||
|
||||
if(len(hist_data[0]) > 2):
|
||||
if len(hist_data[0]) > 2:
|
||||
|
||||
hist_data = np.array(hist_data)
|
||||
derivative = np.array(len(hist_data) - 1, dtype = float)
|
||||
@ -391,7 +392,7 @@ def histo_analysis(hist_data):
|
||||
derivative = t[1] / t[0]
|
||||
np.sort(derivative)
|
||||
|
||||
return basic_stats(derivative)[0], basic_stats(derivative)[3]
|
||||
return {"mean": basic_stats(derivative)["mean"], "deviation": basic_stats(derivative)["standard-deviation"]}
|
||||
|
||||
else:
|
||||
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,4 +1,5 @@
|
||||
from analysis import analysis as an
|
||||
from analysis import metrics
|
||||
|
||||
def test_():
|
||||
test_data_linear = [1, 3, 6, 7, 9]
|
||||
@ -6,12 +7,12 @@ def test_():
|
||||
y_data_ccd = [1, 5, 7, 8.5, 8.66]
|
||||
assert an.basic_stats(test_data_linear) == {"mean": 5.2, "median": 6.0, "standard-deviation": 2.85657137141714, "variance": 8.16, "minimum": 1.0, "maximum": 9.0}
|
||||
assert an.z_score(3.2, 6, 1.5) == -1.8666666666666665
|
||||
assert an.z_normalize([test_data_linear], 0).tolist() == [[0.07537783614444091, 0.22613350843332272, 0.45226701686664544, 0.5276448530110863, 0.6784005252999682]]
|
||||
assert an.z_normalize([test_data_linear], 1).tolist() == [[0.07537783614444091, 0.22613350843332272, 0.45226701686664544, 0.5276448530110863, 0.6784005252999682]]
|
||||
assert all(isinstance(item, str) for item in an.regression(test_data_linear, y_data_ccu, ["lin"])) == True
|
||||
assert all(isinstance(item, str) for item in an.regression(test_data_linear, y_data_ccd, ["log"])) == True
|
||||
assert all(isinstance(item, str) for item in an.regression(test_data_linear, y_data_ccu, ["exp"])) == True
|
||||
assert all(isinstance(item, str) for item in an.regression(test_data_linear, y_data_ccu, ["ply"])) == True
|
||||
assert all(isinstance(item, str) for item in an.regression(test_data_linear, y_data_ccd, ["sig"])) == True
|
||||
#assert all(isinstance(item, str) for item in an.regression(test_data_linear, y_data_ccd, ["log"])) == True
|
||||
#assert all(isinstance(item, str) for item in an.regression(test_data_linear, y_data_ccu, ["exp"])) == True
|
||||
#assert all(isinstance(item, str) for item in an.regression(test_data_linear, y_data_ccu, ["ply"])) == True
|
||||
#assert all(isinstance(item, str) for item in an.regression(test_data_linear, y_data_ccd, ["sig"])) == True
|
||||
assert an.Metric().elo(1500, 1500, [1, 0], 400, 24) == 1512.0
|
||||
assert an.Metric().glicko2(1500, 250, 0.06, [1500, 1400], [250, 240], [1, 0]) == (1478.864307445517, 195.99122679202452, 0.05999602937563585)
|
||||
assert an.Metric().trueskill([[(25, 8.33), (24, 8.25), (32, 7.5)], [(25, 8.33), (25, 8.33), (21, 6.5)]], [1, 0]) == [(an.metrics.trueskill.Rating(mu=21.346, sigma=7.875), an.metrics.trueskill.Rating(mu=20.415, sigma=7.808), an.metrics.trueskill.Rating(mu=29.037, sigma=7.170)), (an.metrics.trueskill.Rating(mu=28.654, sigma=7.875), an.metrics.trueskill.Rating(mu=28.654, sigma=7.875), an.metrics.trueskill.Rating(mu=23.225, sigma=6.287))]
|
||||
#assert an.Metric().trueskill([[(25, 8.33), (24, 8.25), (32, 7.5)], [(25, 8.33), (25, 8.33), (21, 6.5)]], [1, 0]) == [(metrics.trueskill.Rating(mu=21.346, sigma=7.875), metrics.trueskill.Rating(mu=20.415, sigma=7.808), metrics.trueskill.Rating(mu=29.037, sigma=7.170)), (metrics.trueskill.Rating(mu=28.654, sigma=7.875), metrics.trueskill.Rating(mu=28.654, sigma=7.875), metrics.trueskill.Rating(mu=23.225, sigma=6.287))]
|
Binary file not shown.
45
data-analysis/config.json
Normal file
45
data-analysis/config.json
Normal file
@ -0,0 +1,45 @@
|
||||
{
|
||||
"team": "",
|
||||
"competition": "",
|
||||
"key":{
|
||||
"database":"",
|
||||
"tba":""
|
||||
},
|
||||
"statistics":{
|
||||
"match":{
|
||||
"balls-blocked":["basic_stats","historical_analysis","regression_linear","regression_logarithmic","regression_exponential","regression_polynomial","regression_sigmoidal"],
|
||||
"balls-collected":["basic_stats","historical_analysis","regression_linear","regression_logarithmic","regression_exponential","regression_polynomial","regression_sigmoidal"],
|
||||
"balls-lower-teleop":["basic_stats","historical_analysis","regression_linear","regression_logarithmic","regression_exponential","regression_polynomial","regression_sigmoidal"],
|
||||
"balls-lower-auto":["basic_stats","historical_analysis","regression_linear","regression_logarithmic","regression_exponential","regression_polynomial","regression_sigmoidal"],
|
||||
"balls-started":["basic_stats","historical_analyss","regression_linear","regression_logarithmic","regression_exponential","regression_polynomial","regression_sigmoidal"],
|
||||
"balls-upper-teleop":["basic_stats","historical_analysis","regression_linear","regression_logarithmic","regression_exponential","regression_polynomial","regression_sigmoidal"],
|
||||
"balls-upper-auto":["basic_stats","historical_analysis","regression_linear","regression_logarithmic","regression_exponential","regression_polynomial","regression_sigmoidal"]
|
||||
|
||||
},
|
||||
"metric":{
|
||||
"elo":{
|
||||
"score":1500,
|
||||
"N":400,
|
||||
"K":24
|
||||
},
|
||||
"gl2":{
|
||||
"score":1500,
|
||||
"rd":250,
|
||||
"vol":0.06
|
||||
},
|
||||
"ts":{
|
||||
"mu":25,
|
||||
"sigma":8.33
|
||||
}
|
||||
},
|
||||
"pit":{
|
||||
"wheel-mechanism":true,
|
||||
"low-balls":true,
|
||||
"high-balls":true,
|
||||
"wheel-success":true,
|
||||
"strategic-focus":true,
|
||||
"climb-mechanism":true,
|
||||
"attitude":true
|
||||
}
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
2020ilch
|
@ -1,2 +0,0 @@
|
||||
mongodb+srv://api-user-new:titanscout2022@2022-scouting-4vfuu.mongodb.net/test?authSource=admin&replicaSet=2022-scouting-shard-0&readPreference=primary&appname=MongoDB%20Compass&ssl=true
|
||||
UDvKmPjPRfwwUdDX1JxbmkyecYBJhCtXeyVk9vmO2i7K0Zn4wqQPMfzuEINXJ7e5
|
@ -1,14 +0,0 @@
|
||||
balls-blocked,basic_stats,historical_analysis,regression_linear,regression_logarithmic,regression_exponential,regression_polynomial,regression_sigmoidal
|
||||
balls-collected,basic_stats,historical_analysis,regression_linear,regression_logarithmic,regression_exponential,regression_polynomial,regression_sigmoidal
|
||||
balls-lower-teleop,basic_stats,historical_analysis,regression_linear,regression_logarithmic,regression_exponential,regression_polynomial,regression_sigmoidal
|
||||
balls-lower-auto,basic_stats,historical_analysis,regression_linear,regression_logarithmic,regression_exponential,regression_polynomial,regression_sigmoidal
|
||||
balls-started,basic_stats,historical_analyss,regression_linear,regression_logarithmic,regression_exponential,regression_polynomial,regression_sigmoidal
|
||||
balls-upper-teleop,basic_stats,historical_analysis,regression_linear,regression_logarithmic,regression_exponential,regression_polynomial,regression_sigmoidal
|
||||
balls-upper-auto,basic_stats,historical_analysis,regression_linear,regression_logarithmic,regression_exponential,regression_polynomial,regression_sigmoidal
|
||||
wheel-mechanism
|
||||
low-balls
|
||||
high-balls
|
||||
wheel-success
|
||||
strategic-focus
|
||||
climb-mechanism
|
||||
attitude
|
@ -8,7 +8,7 @@ def pull_new_tba_matches(apikey, competition, cutoff):
|
||||
x=requests.get("https://www.thebluealliance.com/api/v3/event/"+competition+"/matches/simple", headers={"X-TBA-Auth_Key":api_key})
|
||||
out = []
|
||||
for i in x.json():
|
||||
if (i["actual_time"] != None and i["actual_time"]-cutoff >= 0 and i["comp_level"] == "qm"):
|
||||
if i["actual_time"] != None and i["actual_time"]-cutoff >= 0 and i["comp_level"] == "qm":
|
||||
out.append({"match" : i['match_number'], "blue" : list(map(lambda x: int(x[3:]), i['alliances']['blue']['team_keys'])), "red" : list(map(lambda x: int(x[3:]), i['alliances']['red']['team_keys'])), "winner": i["winning_alliance"]})
|
||||
return out
|
||||
|
||||
@ -34,17 +34,6 @@ def get_team_metrics_data(apikey, competition, team_num):
|
||||
mdata = db.team_metrics
|
||||
return mdata.find_one({"competition" : competition, "team": team_num})
|
||||
|
||||
def unkeyify_2l(layered_dict):
|
||||
out = {}
|
||||
for i in layered_dict.keys():
|
||||
add = []
|
||||
sortkey = []
|
||||
for j in layered_dict[i].keys():
|
||||
add.append([j,layered_dict[i][j]])
|
||||
add.sort(key = lambda x: x[0])
|
||||
out[i] = list(map(lambda x: x[1], add))
|
||||
return out
|
||||
|
||||
def get_match_data_formatted(apikey, competition):
|
||||
client = pymongo.MongoClient(apikey)
|
||||
db = client.data_scouting
|
||||
@ -58,6 +47,19 @@ def get_match_data_formatted(apikey, competition):
|
||||
pass
|
||||
return out
|
||||
|
||||
def get_metrics_data_formatted(apikey, competition):
|
||||
client = pymongo.MongoClient(apikey)
|
||||
db = client.data_scouting
|
||||
mdata = db.teamlist
|
||||
x=mdata.find_one({"competition":competition})
|
||||
out = {}
|
||||
for i in x:
|
||||
try:
|
||||
out[int(i)] = d.get_team_metrics_data(apikey, competition, int(i))
|
||||
except:
|
||||
pass
|
||||
return out
|
||||
|
||||
def get_pit_data_formatted(apikey, competition):
|
||||
client = pymongo.MongoClient(apikey)
|
||||
db = client.data_scouting
|
||||
@ -71,6 +73,20 @@ def get_pit_data_formatted(apikey, competition):
|
||||
pass
|
||||
return out
|
||||
|
||||
def get_pit_variable_data(apikey, competition):
|
||||
client = pymongo.MongoClient(apikey)
|
||||
db = client.data_processing
|
||||
mdata = db.team_pit
|
||||
out = {}
|
||||
return mdata.find()
|
||||
|
||||
def get_pit_variable_formatted(apikey, competition):
|
||||
temp = get_pit_variable_data(apikey, competition)
|
||||
out = {}
|
||||
for i in temp:
|
||||
out[i["variable"]] = i["data"]
|
||||
return out
|
||||
|
||||
def push_team_tests_data(apikey, competition, team_num, data, dbname = "data_processing", colname = "team_tests"):
|
||||
client = pymongo.MongoClient(apikey)
|
||||
db = client[dbname]
|
||||
@ -100,3 +116,14 @@ def set_analysis_flags(apikey, flag, data):
|
||||
db = client.data_processing
|
||||
mdata = db.flags
|
||||
return mdata.replace_one({flag:{"$exists":True}}, data, True)
|
||||
|
||||
def unkeyify_2l(layered_dict):
|
||||
out = {}
|
||||
for i in layered_dict.keys():
|
||||
add = []
|
||||
sortkey = []
|
||||
for j in layered_dict[i].keys():
|
||||
add.append([j,layered_dict[i][j]])
|
||||
add.sort(key = lambda x: x[0])
|
||||
out[i] = list(map(lambda x: x[1], add))
|
||||
return out
|
@ -1,59 +0,0 @@
|
||||
import data as d
|
||||
from analysis import analysis as an
|
||||
import pymongo
|
||||
import operator
|
||||
|
||||
def load_config(file):
|
||||
config_vector = {}
|
||||
file = an.load_csv(file)
|
||||
for line in file[1:]:
|
||||
config_vector[line[0]] = line[1:]
|
||||
|
||||
return (file[0][0], config_vector)
|
||||
|
||||
def get_metrics_processed_formatted(apikey, competition):
|
||||
client = pymongo.MongoClient(apikey)
|
||||
db = client.data_scouting
|
||||
mdata = db.teamlist
|
||||
x=mdata.find_one({"competition":competition})
|
||||
out = {}
|
||||
for i in x:
|
||||
try:
|
||||
out[int(i)] = d.get_team_metrics_data(apikey, competition, int(i))
|
||||
except:
|
||||
pass
|
||||
return out
|
||||
|
||||
def main():
|
||||
|
||||
apikey = an.load_csv("keys.txt")[0][0]
|
||||
tbakey = an.load_csv("keys.txt")[1][0]
|
||||
|
||||
competition, config = load_config("config.csv")
|
||||
|
||||
metrics = get_metrics_processed_formatted(apikey, competition)
|
||||
|
||||
elo = {}
|
||||
gl2 = {}
|
||||
|
||||
for team in metrics:
|
||||
|
||||
elo[team] = metrics[team]["metrics"]["elo"]["score"]
|
||||
gl2[team] = metrics[team]["metrics"]["gl2"]["score"]
|
||||
|
||||
elo = {k: v for k, v in sorted(elo.items(), key=lambda item: item[1])}
|
||||
gl2 = {k: v for k, v in sorted(gl2.items(), key=lambda item: item[1])}
|
||||
|
||||
for team in elo:
|
||||
|
||||
print("teams sorted by elo:")
|
||||
print("" + str(team) + " | " + str(elo[team]))
|
||||
|
||||
print("*"*25)
|
||||
|
||||
for team in gl2:
|
||||
|
||||
print("teams sorted by glicko2:")
|
||||
print("" + str(team) + " | " + str(gl2[team]))
|
||||
|
||||
main()
|
@ -3,10 +3,27 @@
|
||||
# Notes:
|
||||
# setup:
|
||||
|
||||
__version__ = "0.0.5.002"
|
||||
__version__ = "0.0.6.002"
|
||||
|
||||
# changelog should be viewed using print(analysis.__changelog__)
|
||||
__changelog__ = """changelog:
|
||||
0.0.6.002:
|
||||
- integrated get_team_rankings.py as get_team_metrics() function
|
||||
- integrated visualize_pit.py as graph_pit_histogram() function
|
||||
0.0.6.001:
|
||||
- bug fixes with analysis.Metric() calls
|
||||
- modified metric functions to use config.json defined default values
|
||||
0.0.6.000:
|
||||
- removed main function
|
||||
- changed load_config function
|
||||
- added save_config function
|
||||
- added load_match function
|
||||
- renamed simpleloop to matchloop
|
||||
- moved simplestats function inside matchloop
|
||||
- renamed load_metrics to load_metric
|
||||
- renamed metricsloop to metricloop
|
||||
- split push to database functions amon push_match, push_metric, push_pit
|
||||
- moved
|
||||
0.0.5.002:
|
||||
- made changes due to refactoring of analysis
|
||||
0.0.5.001:
|
||||
@ -77,101 +94,92 @@ __author__ = (
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
"main",
|
||||
"load_config",
|
||||
"simpleloop",
|
||||
"simplestats",
|
||||
"metricsloop"
|
||||
"save_config",
|
||||
"get_previous_time",
|
||||
"load_match",
|
||||
"matchloop",
|
||||
"load_metric",
|
||||
"metricloop",
|
||||
"load_pit",
|
||||
"pitloop",
|
||||
"push_match",
|
||||
"push_metric",
|
||||
"push_pit",
|
||||
]
|
||||
|
||||
# imports:
|
||||
|
||||
from analysis import analysis as an
|
||||
import data as d
|
||||
import json
|
||||
import numpy as np
|
||||
from os import system, name
|
||||
from pathlib import Path
|
||||
import matplotlib.pyplot as plt
|
||||
import time
|
||||
import warnings
|
||||
|
||||
def main():
|
||||
warnings.filterwarnings("ignore")
|
||||
while(True):
|
||||
|
||||
current_time = time.time()
|
||||
print("[OK] time: " + str(current_time))
|
||||
|
||||
start = time.time()
|
||||
config = load_config(Path("config/stats.config"))
|
||||
competition = an.load_csv(Path("config/competition.config"))[0][0]
|
||||
print("[OK] configs loaded")
|
||||
|
||||
apikey = an.load_csv(Path("config/keys.config"))[0][0]
|
||||
tbakey = an.load_csv(Path("config/keys.config"))[1][0]
|
||||
print("[OK] loaded keys")
|
||||
|
||||
previous_time = d.get_analysis_flags(apikey, "latest_update")
|
||||
|
||||
if(previous_time == None):
|
||||
|
||||
d.set_analysis_flags(apikey, "latest_update", 0)
|
||||
previous_time = 0
|
||||
|
||||
else:
|
||||
|
||||
previous_time = previous_time["latest_update"]
|
||||
|
||||
print("[OK] analysis backtimed to: " + str(previous_time))
|
||||
|
||||
print("[OK] loading data")
|
||||
start = time.time()
|
||||
data = d.get_match_data_formatted(apikey, competition)
|
||||
pit_data = d.pit = d.get_pit_data_formatted(apikey, competition)
|
||||
print("[OK] loaded data in " + str(time.time() - start) + " seconds")
|
||||
|
||||
print("[OK] running tests")
|
||||
start = time.time()
|
||||
results = simpleloop(data, config)
|
||||
print("[OK] finished tests in " + str(time.time() - start) + " seconds")
|
||||
|
||||
print("[OK] running metrics")
|
||||
start = time.time()
|
||||
metricsloop(tbakey, apikey, competition, previous_time)
|
||||
print("[OK] finished metrics in " + str(time.time() - start) + " seconds")
|
||||
|
||||
print("[OK] running pit analysis")
|
||||
start = time.time()
|
||||
pit = pitloop(pit_data, config)
|
||||
print("[OK] finished pit analysis in " + str(time.time() - start) + " seconds")
|
||||
|
||||
d.set_analysis_flags(apikey, "latest_update", {"latest_update":current_time})
|
||||
|
||||
print("[OK] pushing to database")
|
||||
start = time.time()
|
||||
push_to_database(apikey, competition, results, pit)
|
||||
print("[OK] pushed to database in " + str(time.time() - start) + " seconds")
|
||||
|
||||
clear()
|
||||
|
||||
def clear():
|
||||
|
||||
# for windows
|
||||
if name == 'nt':
|
||||
_ = system('cls')
|
||||
|
||||
# for mac and linux(here, os.name is 'posix')
|
||||
else:
|
||||
_ = system('clear')
|
||||
|
||||
def load_config(file):
|
||||
|
||||
config_vector = {}
|
||||
file = an.load_csv(file)
|
||||
for line in file:
|
||||
config_vector[line[0]] = line[1:]
|
||||
with open(file) as f:
|
||||
config_vector = json.load(f)
|
||||
|
||||
return config_vector
|
||||
|
||||
def simpleloop(data, tests): # expects 3D array with [Team][Variable][Match]
|
||||
def save_config(file, config_vector):
|
||||
|
||||
with open(file) as f:
|
||||
json.dump(config_vector, f)
|
||||
|
||||
def get_previous_time(apikey):
|
||||
|
||||
previous_time = d.get_analysis_flags(apikey, "latest_update")
|
||||
|
||||
if previous_time == None:
|
||||
|
||||
d.set_analysis_flags(apikey, "latest_update", 0)
|
||||
previous_time = 0
|
||||
|
||||
else:
|
||||
|
||||
previous_time = previous_time["latest_update"]
|
||||
|
||||
return previous_time
|
||||
|
||||
def load_match(apikey, competition):
|
||||
|
||||
return d.get_match_data_formatted(apikey, competition)
|
||||
|
||||
def matchloop(apikey, competition, data, tests): # expects 3D array with [Team][Variable][Match]
|
||||
|
||||
def simplestats(data, test):
|
||||
|
||||
data = np.array(data)
|
||||
data = data[np.isfinite(data)]
|
||||
ranges = list(range(len(data)))
|
||||
|
||||
if test == "basic_stats":
|
||||
return an.basic_stats(data)
|
||||
|
||||
if test == "historical_analysis":
|
||||
return an.histo_analysis([ranges, data])
|
||||
|
||||
if test == "regression_linear":
|
||||
return an.regression(ranges, data, ['lin'])
|
||||
|
||||
if test == "regression_logarithmic":
|
||||
return an.regression(ranges, data, ['log'])
|
||||
|
||||
if test == "regression_exponential":
|
||||
return an.regression(ranges, data, ['exp'])
|
||||
|
||||
if test == "regression_polynomial":
|
||||
return an.regression(ranges, data, ['ply'])
|
||||
|
||||
if test == "regression_sigmoidal":
|
||||
return an.regression(ranges, data, ['sig'])
|
||||
|
||||
return_vector = {}
|
||||
for team in data:
|
||||
@ -179,7 +187,7 @@ def simpleloop(data, tests): # expects 3D array with [Team][Variable][Match]
|
||||
for variable in data[team]:
|
||||
test_vector = {}
|
||||
variable_data = data[team][variable]
|
||||
if(variable in tests):
|
||||
if variable in tests:
|
||||
for test in tests[variable]:
|
||||
test_vector[test] = simplestats(variable_data, test)
|
||||
else:
|
||||
@ -187,49 +195,40 @@ def simpleloop(data, tests): # expects 3D array with [Team][Variable][Match]
|
||||
variable_vector[variable] = test_vector
|
||||
return_vector[team] = variable_vector
|
||||
|
||||
return return_vector
|
||||
push_match(apikey, competition, return_vector)
|
||||
|
||||
def simplestats(data, test):
|
||||
def load_metric(apikey, competition, match, group_name, metrics):
|
||||
|
||||
data = np.array(data)
|
||||
data = data[np.isfinite(data)]
|
||||
ranges = list(range(len(data)))
|
||||
group = {}
|
||||
|
||||
if(test == "basic_stats"):
|
||||
return an.basic_stats(data)
|
||||
for team in match[group_name]:
|
||||
|
||||
if(test == "historical_analysis"):
|
||||
return an.histo_analysis([ranges, data])
|
||||
db_data = d.get_team_metrics_data(apikey, competition, team)
|
||||
|
||||
if(test == "regression_linear"):
|
||||
return an.regression(ranges, data, ['lin'])
|
||||
if d.get_team_metrics_data(apikey, competition, team) == None:
|
||||
|
||||
if(test == "regression_logarithmic"):
|
||||
return an.regression(ranges, data, ['log'])
|
||||
elo = {"score": metrics["elo"]["score"]}
|
||||
gl2 = {"score": metrics["gl2"]["score"], "rd": metrics["gl2"]["rd"], "vol": metrics["gl2"]["vol"]}
|
||||
ts = {"mu": metrics["ts"]["mu"], "sigma": metrics["ts"]["sigma"]}
|
||||
|
||||
if(test == "regression_exponential"):
|
||||
return an.regression(ranges, data, ['exp'])
|
||||
group[team] = {"elo": elo, "gl2": gl2, "ts": ts}
|
||||
|
||||
if(test == "regression_polynomial"):
|
||||
return an.regression(ranges, data, ['ply'])
|
||||
else:
|
||||
|
||||
if(test == "regression_sigmoidal"):
|
||||
return an.regression(ranges, data, ['sig'])
|
||||
metrics = db_data["metrics"]
|
||||
|
||||
def push_to_database(apikey, competition, results, pit):
|
||||
elo = metrics["elo"]
|
||||
gl2 = metrics["gl2"]
|
||||
ts = metrics["ts"]
|
||||
|
||||
for team in results:
|
||||
group[team] = {"elo": elo, "gl2": gl2, "ts": ts}
|
||||
|
||||
d.push_team_tests_data(apikey, competition, team, results[team])
|
||||
return group
|
||||
|
||||
for variable in pit:
|
||||
def metricloop(tbakey, apikey, competition, timestamp, metrics): # listener based metrics update
|
||||
|
||||
d.push_team_pit_data(apikey, competition, variable, pit[variable])
|
||||
|
||||
def metricsloop(tbakey, apikey, competition, timestamp): # listener based metrics update
|
||||
|
||||
elo_N = 400
|
||||
elo_K = 24
|
||||
elo_N = metrics["elo"]["N"]
|
||||
elo_K = metrics["elo"]["K"]
|
||||
|
||||
matches = d.pull_new_tba_matches(tbakey, competition, timestamp)
|
||||
|
||||
@ -238,8 +237,8 @@ def metricsloop(tbakey, apikey, competition, timestamp): # listener based metric
|
||||
|
||||
for match in matches:
|
||||
|
||||
red = load_metrics(apikey, competition, match, "red")
|
||||
blu = load_metrics(apikey, competition, match, "blue")
|
||||
red = load_metric(apikey, competition, match, "red", metrics)
|
||||
blu = load_metric(apikey, competition, match, "blue", metrics)
|
||||
|
||||
elo_red_total = 0
|
||||
elo_blu_total = 0
|
||||
@ -276,11 +275,11 @@ def metricsloop(tbakey, apikey, competition, timestamp): # listener based metric
|
||||
blu_gl2 = {"score": gl2_blu_score_total / len(blu), "rd": gl2_blu_rd_total / len(blu), "vol": gl2_blu_vol_total / len(blu)}
|
||||
|
||||
|
||||
if(match["winner"] == "red"):
|
||||
if match["winner"] == "red":
|
||||
|
||||
observations = {"red": 1, "blu": 0}
|
||||
|
||||
elif(match["winner"] == "blue"):
|
||||
elif match["winner"] == "blue":
|
||||
|
||||
observations = {"red": 0, "blu": 1}
|
||||
|
||||
@ -288,11 +287,11 @@ def metricsloop(tbakey, apikey, competition, timestamp): # listener based metric
|
||||
|
||||
observations = {"red": 0.5, "blu": 0.5}
|
||||
|
||||
red_elo_delta = an.Metrics.elo(red_elo["score"], blu_elo["score"], observations["red"], elo_N, elo_K) - red_elo["score"]
|
||||
blu_elo_delta = an.Metrics.elo(blu_elo["score"], red_elo["score"], observations["blu"], elo_N, elo_K) - blu_elo["score"]
|
||||
red_elo_delta = an.Metric().elo(red_elo["score"], blu_elo["score"], observations["red"], elo_N, elo_K) - red_elo["score"]
|
||||
blu_elo_delta = an.Metric().elo(blu_elo["score"], red_elo["score"], observations["blu"], elo_N, elo_K) - blu_elo["score"]
|
||||
|
||||
new_red_gl2_score, new_red_gl2_rd, new_red_gl2_vol = an.Metrics.glicko2(red_gl2["score"], red_gl2["rd"], red_gl2["vol"], [blu_gl2["score"]], [blu_gl2["rd"]], [observations["red"], observations["blu"]])
|
||||
new_blu_gl2_score, new_blu_gl2_rd, new_blu_gl2_vol = an.Metrics.glicko2(blu_gl2["score"], blu_gl2["rd"], blu_gl2["vol"], [red_gl2["score"]], [red_gl2["rd"]], [observations["blu"], observations["red"]])
|
||||
new_red_gl2_score, new_red_gl2_rd, new_red_gl2_vol = an.Metric().glicko2(red_gl2["score"], red_gl2["rd"], red_gl2["vol"], [blu_gl2["score"]], [blu_gl2["rd"]], [observations["red"], observations["blu"]])
|
||||
new_blu_gl2_score, new_blu_gl2_rd, new_blu_gl2_vol = an.Metric().glicko2(blu_gl2["score"], blu_gl2["rd"], blu_gl2["vol"], [red_gl2["score"]], [red_gl2["rd"]], [observations["blu"], observations["red"]])
|
||||
|
||||
red_gl2_delta = {"score": new_red_gl2_score - red_gl2["score"], "rd": new_red_gl2_rd - red_gl2["rd"], "vol": new_red_gl2_vol - red_gl2["vol"]}
|
||||
blu_gl2_delta = {"score": new_blu_gl2_score - blu_gl2["score"], "rd": new_blu_gl2_rd - blu_gl2["rd"], "vol": new_blu_gl2_vol - blu_gl2["vol"]}
|
||||
@ -317,62 +316,90 @@ def metricsloop(tbakey, apikey, competition, timestamp): # listener based metric
|
||||
temp_vector.update(red)
|
||||
temp_vector.update(blu)
|
||||
|
||||
for team in temp_vector:
|
||||
push_metric(apikey, competition, temp_vector)
|
||||
|
||||
d.push_team_metrics_data(apikey, competition, team, temp_vector[team])
|
||||
def load_pit(apikey, competition):
|
||||
|
||||
def load_metrics(apikey, competition, match, group_name):
|
||||
return d.get_pit_data_formatted(apikey, competition)
|
||||
|
||||
group = {}
|
||||
|
||||
for team in match[group_name]:
|
||||
|
||||
db_data = d.get_team_metrics_data(apikey, competition, team)
|
||||
|
||||
if d.get_team_metrics_data(apikey, competition, team) == None:
|
||||
|
||||
elo = {"score": 1500}
|
||||
gl2 = {"score": 1500, "rd": 250, "vol": 0.06}
|
||||
ts = {"mu": 25, "sigma": 25/3}
|
||||
|
||||
#d.push_team_metrics_data(apikey, competition, team, {"elo":elo, "gl2":gl2,"trueskill":ts})
|
||||
|
||||
group[team] = {"elo": elo, "gl2": gl2, "ts": ts}
|
||||
|
||||
else:
|
||||
|
||||
metrics = db_data["metrics"]
|
||||
|
||||
elo = metrics["elo"]
|
||||
gl2 = metrics["gl2"]
|
||||
ts = metrics["ts"]
|
||||
|
||||
group[team] = {"elo": elo, "gl2": gl2, "ts": ts}
|
||||
|
||||
return group
|
||||
|
||||
def pitloop(pit, tests):
|
||||
def pitloop(apikey, competition, pit, tests):
|
||||
|
||||
return_vector = {}
|
||||
for team in pit:
|
||||
for variable in pit[team]:
|
||||
if(variable in tests):
|
||||
if(not variable in return_vector):
|
||||
if variable in tests:
|
||||
if not variable in return_vector:
|
||||
return_vector[variable] = []
|
||||
return_vector[variable].append(pit[team][variable])
|
||||
|
||||
return return_vector
|
||||
push_pit(apikey, competition, return_vector)
|
||||
|
||||
main()
|
||||
def push_match(apikey, competition, results):
|
||||
|
||||
"""
|
||||
Metrics Defaults:
|
||||
for team in results:
|
||||
|
||||
elo starting score = 1500
|
||||
elo N = 400
|
||||
elo K = 24
|
||||
d.push_team_tests_data(apikey, competition, team, results[team])
|
||||
|
||||
gl2 starting score = 1500
|
||||
gl2 starting rd = 350
|
||||
gl2 starting vol = 0.06
|
||||
"""
|
||||
def push_metric(apikey, competition, metric):
|
||||
|
||||
for team in metric:
|
||||
|
||||
d.push_team_metrics_data(apikey, competition, team, metric[team])
|
||||
|
||||
def push_pit(apikey, competition, pit):
|
||||
|
||||
for variable in pit:
|
||||
|
||||
d.push_team_pit_data(apikey, competition, variable, pit[variable])
|
||||
|
||||
def get_team_metrics(apikey, tbakey, competition):
|
||||
|
||||
metrics = d.get_metrics_data_formatted(apikey, competition)
|
||||
|
||||
elo = {}
|
||||
gl2 = {}
|
||||
|
||||
for team in metrics:
|
||||
|
||||
elo[team] = metrics[team]["metrics"]["elo"]["score"]
|
||||
gl2[team] = metrics[team]["metrics"]["gl2"]["score"]
|
||||
|
||||
elo = {k: v for k, v in sorted(elo.items(), key=lambda item: item[1])}
|
||||
gl2 = {k: v for k, v in sorted(gl2.items(), key=lambda item: item[1])}
|
||||
|
||||
elo_ranked = []
|
||||
|
||||
for team in elo:
|
||||
|
||||
elo_ranked.append({"team": str(team), "elo": str(elo[team])})
|
||||
|
||||
gl2_ranked = []
|
||||
|
||||
for team in gl2:
|
||||
|
||||
gl2_ranked.append({"team": str(team), "gl2": str(gl2[team])})
|
||||
|
||||
return {"elo-ranks": elo_ranked, "glicko2-ranks": gl2_ranked}
|
||||
|
||||
def graph_pit_histogram(apikey, competition, figsize=(80,15)):
|
||||
|
||||
pit = d.get_pit_variable_formatted(apikey, competition)
|
||||
|
||||
fig, ax = plt.subplots(1, len(pit), sharey=True, figsize=figsize)
|
||||
|
||||
i = 0
|
||||
|
||||
for variable in pit:
|
||||
|
||||
ax[i].hist(pit[variable])
|
||||
ax[i].invert_xaxis()
|
||||
|
||||
ax[i].set_xlabel('')
|
||||
ax[i].set_ylabel('Frequency')
|
||||
ax[i].set_title(variable)
|
||||
|
||||
plt.yticks(np.arange(len(pit[variable])))
|
||||
|
||||
i+=1
|
||||
|
||||
plt.show()
|
91
data-analysis/tra.py
Normal file
91
data-analysis/tra.py
Normal file
@ -0,0 +1,91 @@
|
||||
import json
|
||||
import superscript as su
|
||||
import threading
|
||||
|
||||
__author__ = (
|
||||
"Arthur Lu <learthurgo@gmail.com>",
|
||||
)
|
||||
|
||||
match = False
|
||||
metric = False
|
||||
pit = False
|
||||
|
||||
match_enable = True
|
||||
metric_enable = True
|
||||
pit_enable = True
|
||||
|
||||
config = {}
|
||||
|
||||
def main():
|
||||
|
||||
global match
|
||||
global metric
|
||||
global pit
|
||||
|
||||
global match_enable
|
||||
global metric_enable
|
||||
global pit_enable
|
||||
|
||||
global config
|
||||
config = su.load_config("config.json")
|
||||
|
||||
while(True):
|
||||
|
||||
if match_enable == True and match == False:
|
||||
|
||||
def target():
|
||||
|
||||
apikey = config["key"]["database"]
|
||||
competition = config["competition"]
|
||||
tests = config["statistics"]["match"]
|
||||
|
||||
data = su.load_match(apikey, competition)
|
||||
su.matchloop(apikey, competition, data, tests)
|
||||
|
||||
match = False
|
||||
return
|
||||
|
||||
match = True
|
||||
task = threading.Thread(name = "match", target=target)
|
||||
task.start()
|
||||
|
||||
if metric_enable == True and metric == False:
|
||||
|
||||
def target():
|
||||
|
||||
apikey = config["key"]["database"]
|
||||
tbakey = config["key"]["tba"]
|
||||
competition = config["competition"]
|
||||
metric = config["statistics"]["metric"]
|
||||
|
||||
timestamp = su.get_previous_time(apikey)
|
||||
|
||||
su.metricloop(tbakey, apikey, competition, timestamp, metric)
|
||||
|
||||
metric = False
|
||||
return
|
||||
|
||||
match = True
|
||||
task = threading.Thread(name = "metric", target=target)
|
||||
task.start()
|
||||
|
||||
if pit_enable == True and pit == False:
|
||||
|
||||
def target():
|
||||
|
||||
apikey = config["key"]["database"]
|
||||
competition = config["competition"]
|
||||
tests = config["statistics"]["pit"]
|
||||
|
||||
data = su.load_pit(apikey, competition)
|
||||
su.pitloop(apikey, competition, data, tests)
|
||||
|
||||
pit = False
|
||||
return
|
||||
|
||||
pit = True
|
||||
task = threading.Thread(name = "pit", target=target)
|
||||
task.start()
|
||||
|
||||
task = threading.Thread(name = "main", target=main)
|
||||
task.start()
|
@ -1,59 +0,0 @@
|
||||
# To add a new cell, type '# %%'
|
||||
# To add a new markdown cell, type '# %% [markdown]'
|
||||
# %%
|
||||
import matplotlib.pyplot as plt
|
||||
import data as d
|
||||
import pymongo
|
||||
|
||||
|
||||
# %%
|
||||
def get_pit_variable_data(apikey, competition):
|
||||
client = pymongo.MongoClient(apikey)
|
||||
db = client.data_processing
|
||||
mdata = db.team_pit
|
||||
out = {}
|
||||
return mdata.find()
|
||||
|
||||
|
||||
# %%
|
||||
def get_pit_variable_formatted(apikey, competition):
|
||||
temp = get_pit_variable_data(apikey, competition)
|
||||
out = {}
|
||||
for i in temp:
|
||||
out[i["variable"]] = i["data"]
|
||||
return out
|
||||
|
||||
|
||||
# %%
|
||||
pit = get_pit_variable_formatted("mongodb+srv://api-user-new:titanscout2022@2022-scouting-4vfuu.mongodb.net/test?authSource=admin&replicaSet=2022-scouting-shard-0&readPreference=primary&appname=MongoDB%20Compass&ssl=true", "2020ilch")
|
||||
|
||||
|
||||
# %%
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
|
||||
|
||||
# %%
|
||||
fig, ax = plt.subplots(1, len(pit), sharey=True, figsize=(80,15))
|
||||
|
||||
i = 0
|
||||
|
||||
for variable in pit:
|
||||
|
||||
ax[i].hist(pit[variable])
|
||||
ax[i].invert_xaxis()
|
||||
|
||||
ax[i].set_xlabel('')
|
||||
ax[i].set_ylabel('Frequency')
|
||||
ax[i].set_title(variable)
|
||||
|
||||
plt.yticks(np.arange(len(pit[variable])))
|
||||
|
||||
i+=1
|
||||
|
||||
plt.show()
|
||||
|
||||
|
||||
# %%
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user