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:
Arthur Lu 2020-05-20 08:52:38 -05:00 committed by GitHub
parent ae64c7f10e
commit 4f439d6094
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 378 additions and 319 deletions

View File

@ -23,5 +23,5 @@
"mhutchie.git-graph", "mhutchie.git-graph",
"donjayamanne.jupyter", "donjayamanne.jupyter",
], ],
"postCreateCommand": "pip install -r analysis-master/analysis-amd64/requirements.txt" "postCreateCommand": "pip install -r analysis-master/requirements.txt"
} }

2
.gitignore vendored
View File

@ -21,11 +21,13 @@ data-analysis/test.ipynb
data-analysis/visualize_pit.ipynb data-analysis/visualize_pit.ipynb
data-analysis/config/keys.config data-analysis/config/keys.config
analysis-master/analysis/__pycache__/ analysis-master/analysis/__pycache__/
analysis-master/analysis/metrics/__pycache__/
data-analysis/__pycache__/ data-analysis/__pycache__/
analysis-master/analysis.egg-info/ analysis-master/analysis.egg-info/
analysis-master/build/ analysis-master/build/
analysis-master/metrics/ analysis-master/metrics/
data-analysis/config-pop.json data-analysis/config-pop.json
data-analysis/__pycache__/
analysis-master/__pycache__/ analysis-master/__pycache__/
analysis-master/.pytest_cache/ analysis-master/.pytest_cache/
data-analysis/.pytest_cache/ data-analysis/.pytest_cache/

View File

@ -12,6 +12,7 @@ __version__ = "1.2.1.003"
# changelog should be viewed using print(analysis.__changelog__) # changelog should be viewed using print(analysis.__changelog__)
__changelog__ = """changelog: __changelog__ = """changelog:
1.2.1.003: 1.2.1.003:
- changed output of basic_stats and histo_analysis to libraries
- fixed __all__ - fixed __all__
1.2.1.002: 1.2.1.002:
- renamed ArrayTest class to Array - renamed ArrayTest class to Array
@ -360,7 +361,7 @@ def basic_stats(data):
_min = npmin(data_t) _min = npmin(data_t)
_max = npmax(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 # returns z score with inputs of point, mean and standard deviation of spread
@jit(forceobj=True) @jit(forceobj=True)
@ -383,7 +384,7 @@ def z_normalize(array, *args):
# expects 2d array of [x,y] # expects 2d array of [x,y]
def histo_analysis(hist_data): def histo_analysis(hist_data):
if(len(hist_data[0]) > 2): if len(hist_data[0]) > 2:
hist_data = np.array(hist_data) hist_data = np.array(hist_data)
derivative = np.array(len(hist_data) - 1, dtype = float) derivative = np.array(len(hist_data) - 1, dtype = float)
@ -391,7 +392,7 @@ def histo_analysis(hist_data):
derivative = t[1] / t[0] derivative = t[1] / t[0]
np.sort(derivative) 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: else:

View File

@ -1,4 +1,5 @@
from analysis import analysis as an from analysis import analysis as an
from analysis import metrics
def test_(): def test_():
test_data_linear = [1, 3, 6, 7, 9] test_data_linear = [1, 3, 6, 7, 9]
@ -6,12 +7,12 @@ def test_():
y_data_ccd = [1, 5, 7, 8.5, 8.66] 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.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_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_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_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, ["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_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, ["sig"])) == True
assert an.Metric().elo(1500, 1500, [1, 0], 400, 24) == 1512.0 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().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))]

45
data-analysis/config.json Normal file
View 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
}
}
}

View File

@ -1 +0,0 @@
2020ilch

View File

@ -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

View File

@ -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

View File

@ -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}) x=requests.get("https://www.thebluealliance.com/api/v3/event/"+competition+"/matches/simple", headers={"X-TBA-Auth_Key":api_key})
out = [] out = []
for i in x.json(): 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"]}) 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 return out
@ -34,17 +34,6 @@ def get_team_metrics_data(apikey, competition, team_num):
mdata = db.team_metrics mdata = db.team_metrics
return mdata.find_one({"competition" : competition, "team": team_num}) 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): def get_match_data_formatted(apikey, competition):
client = pymongo.MongoClient(apikey) client = pymongo.MongoClient(apikey)
db = client.data_scouting db = client.data_scouting
@ -58,6 +47,19 @@ def get_match_data_formatted(apikey, competition):
pass pass
return out 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): def get_pit_data_formatted(apikey, competition):
client = pymongo.MongoClient(apikey) client = pymongo.MongoClient(apikey)
db = client.data_scouting db = client.data_scouting
@ -71,6 +73,20 @@ def get_pit_data_formatted(apikey, competition):
pass pass
return out 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"): def push_team_tests_data(apikey, competition, team_num, data, dbname = "data_processing", colname = "team_tests"):
client = pymongo.MongoClient(apikey) client = pymongo.MongoClient(apikey)
db = client[dbname] db = client[dbname]
@ -99,4 +115,15 @@ def set_analysis_flags(apikey, flag, data):
client = pymongo.MongoClient(apikey) client = pymongo.MongoClient(apikey)
db = client.data_processing db = client.data_processing
mdata = db.flags mdata = db.flags
return mdata.replace_one({flag:{"$exists":True}}, data, True) 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

View File

@ -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()

View File

@ -3,10 +3,27 @@
# Notes: # Notes:
# setup: # setup:
__version__ = "0.0.5.002" __version__ = "0.0.6.002"
# changelog should be viewed using print(analysis.__changelog__) # changelog should be viewed using print(analysis.__changelog__)
__changelog__ = """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: 0.0.5.002:
- made changes due to refactoring of analysis - made changes due to refactoring of analysis
0.0.5.001: 0.0.5.001:
@ -77,101 +94,92 @@ __author__ = (
) )
__all__ = [ __all__ = [
"main",
"load_config", "load_config",
"simpleloop", "save_config",
"simplestats", "get_previous_time",
"metricsloop" "load_match",
"matchloop",
"load_metric",
"metricloop",
"load_pit",
"pitloop",
"push_match",
"push_metric",
"push_pit",
] ]
# imports: # imports:
from analysis import analysis as an from analysis import analysis as an
import data as d import data as d
import json
import numpy as np import numpy as np
from os import system, name from os import system, name
from pathlib import Path from pathlib import Path
import matplotlib.pyplot as plt
import time import time
import warnings 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): def load_config(file):
config_vector = {} config_vector = {}
file = an.load_csv(file) with open(file) as f:
for line in file: config_vector = json.load(f)
config_vector[line[0]] = line[1:]
return config_vector 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 = {} return_vector = {}
for team in data: for team in data:
@ -179,7 +187,7 @@ def simpleloop(data, tests): # expects 3D array with [Team][Variable][Match]
for variable in data[team]: for variable in data[team]:
test_vector = {} test_vector = {}
variable_data = data[team][variable] variable_data = data[team][variable]
if(variable in tests): if variable in tests:
for test in tests[variable]: for test in tests[variable]:
test_vector[test] = simplestats(variable_data, test) test_vector[test] = simplestats(variable_data, test)
else: else:
@ -187,49 +195,40 @@ def simpleloop(data, tests): # expects 3D array with [Team][Variable][Match]
variable_vector[variable] = test_vector variable_vector[variable] = test_vector
return_vector[team] = variable_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) group = {}
data = data[np.isfinite(data)]
ranges = list(range(len(data)))
if(test == "basic_stats"): for team in match[group_name]:
return an.basic_stats(data)
if(test == "historical_analysis"): db_data = d.get_team_metrics_data(apikey, competition, team)
return an.histo_analysis([ranges, data])
if(test == "regression_linear"): if d.get_team_metrics_data(apikey, competition, team) == None:
return an.regression(ranges, data, ['lin'])
if(test == "regression_logarithmic"): elo = {"score": metrics["elo"]["score"]}
return an.regression(ranges, data, ['log']) 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"): group[team] = {"elo": elo, "gl2": gl2, "ts": ts}
return an.regression(ranges, data, ['exp'])
if(test == "regression_polynomial"): else:
return an.regression(ranges, data, ['ply'])
if(test == "regression_sigmoidal"): metrics = db_data["metrics"]
return an.regression(ranges, data, ['sig'])
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]) elo_N = metrics["elo"]["N"]
elo_K = metrics["elo"]["K"]
def metricsloop(tbakey, apikey, competition, timestamp): # listener based metrics update
elo_N = 400
elo_K = 24
matches = d.pull_new_tba_matches(tbakey, competition, timestamp) 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: for match in matches:
red = load_metrics(apikey, competition, match, "red") red = load_metric(apikey, competition, match, "red", metrics)
blu = load_metrics(apikey, competition, match, "blue") blu = load_metric(apikey, competition, match, "blue", metrics)
elo_red_total = 0 elo_red_total = 0
elo_blu_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)} 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} observations = {"red": 1, "blu": 0}
elif(match["winner"] == "blue"): elif match["winner"] == "blue":
observations = {"red": 0, "blu": 1} 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} 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"] 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.Metrics.elo(blu_elo["score"], red_elo["score"], observations["blu"], elo_N, elo_K) - blu_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_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.Metrics.glicko2(blu_gl2["score"], blu_gl2["rd"], blu_gl2["vol"], [red_gl2["score"]], [red_gl2["rd"]], [observations["blu"], observations["red"]]) 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"]} 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"]} 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(red)
temp_vector.update(blu) 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 = {} def pitloop(apikey, competition, pit, tests):
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):
return_vector = {} return_vector = {}
for team in pit: for team in pit:
for variable in pit[team]: for variable in pit[team]:
if(variable in tests): if variable in tests:
if(not variable in return_vector): if not variable in return_vector:
return_vector[variable] = [] return_vector[variable] = []
return_vector[variable].append(pit[team][variable]) return_vector[variable].append(pit[team][variable])
return return_vector push_pit(apikey, competition, return_vector)
main() def push_match(apikey, competition, results):
""" for team in results:
Metrics Defaults:
elo starting score = 1500 d.push_team_tests_data(apikey, competition, team, results[team])
elo N = 400
elo K = 24
gl2 starting score = 1500 def push_metric(apikey, competition, metric):
gl2 starting rd = 350
gl2 starting vol = 0.06 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
View 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()

View File

@ -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()
# %%