{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'C': 5.0, 'A': 7.75, 'D': 7.5, 'B': 2.25}\n" ] } ], "source": [ "from collections import namedtuple\n", "import numpy.matlib as mat\n", "import numpy as np\n", "from numpy.linalg import inv\n", "\n", "Match = namedtuple(\"Match\", [\"teams\", \"score\"])\n", "\n", "def CalcOpr(matches):\n", " \"\"\"\n", " Given a list of matches, to least squares OPR calculation\n", " \"\"\"\n", " num_matches = len(matches) # rows\n", " teams = list(set().union(*[match.teams for match in matches]))\n", " num_teams = len(teams)\n", " \n", " alliances = mat.zeros((num_matches, num_teams))\n", " scores = mat.zeros((num_matches, 1))\n", " \n", " for idx, match in enumerate(matches):\n", " scores[idx, 0] = match.score\n", " for team in match.teams:\n", " alliances[idx, teams.index(team)] = 1\n", " \n", " least_squares_approx = np.dot(\n", " inv(np.dot(np.transpose(alliances), alliances)),\n", " np.dot(np.transpose(alliances), scores))\n", " \n", " oprs = {}\n", " for idx, team in enumerate(teams):\n", " oprs[team] = least_squares_approx[idx, 0] \n", " return oprs\n", "\n", "print(CalcOpr([\n", " Match(teams=['A', 'B'], score=10),\n", " Match(teams=['A', 'C'], score=13),\n", " Match(teams=['B', 'C'], score=7),\n", " Match(teams=['A', 'D'], score=15),\n", " Match(teams=['B', 'D'], score=10),\n", " ]))" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'android': {'latest_app_version': 4020399, 'min_app_version': 4000299},\n", " 'contbuild_enabled': True,\n", " 'current_season': 2018,\n", " 'down_events': [],\n", " 'ios': {'latest_app_version': -1, 'min_app_version': -1},\n", " 'is_datafeed_down': False,\n", " 'json': {'android': {'latest_app_version': 4020399,\n", " 'min_app_version': 4000299},\n", " 'contbuild_enabled': True,\n", " 'current_season': 2018,\n", " 'down_events': [],\n", " 'ios': {'latest_app_version': -1, 'min_app_version': -1},\n", " 'is_datafeed_down': False,\n", " 'max_season': 2018,\n", " 'web': {'commit_time': '2018-02-08 16:24:47 -0500',\n", " 'current_commit': '0818a656fa52a99bd0af8943e91bf6107a80314d',\n", " 'deploy_time': 'Thu Feb 8 21:39:42 UTC 2018',\n", " 'travis_job': '339186456'}},\n", " 'max_season': 2018,\n", " 'web': {'commit_time': '2018-02-08 16:24:47 -0500',\n", " 'current_commit': '0818a656fa52a99bd0af8943e91bf6107a80314d',\n", " 'deploy_time': 'Thu Feb 8 21:39:42 UTC 2018',\n", " 'travis_job': '339186456'}}\n" ] } ], "source": [ "import tbapy\n", "from pprint import pprint\n", "\n", "api_key = \"6qOZ9uAEsb4CDrOBNG6ZnIdi9cWBaZ6DHnCSato97Qfo7bBeUwT9NfFt4Gi5sHFN\"\n", "\n", "tba = tbapy.TBA(api_key)\n", "pprint(tba.status())" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false, "scrolled": false }, "outputs": [], "source": [ "matches = tba.event_matches('2017roe')" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[('frc973', 177.56919288327308),\n", " ('frc115', 157.0259913331104),\n", " ('frc1011', 149.76450747382796),\n", " ('frc4265', 146.76438484413518),\n", " ('frc365', 143.49460917929289),\n", " ('frc2928', 135.80511381914454),\n", " ('frc624', 134.76677882359436),\n", " ('frc2403', 134.32245109158637),\n", " ('frc1574', 129.37613398098358),\n", " ('frc1414', 127.96800663206291),\n", " ('frc2642', 127.18581346587769),\n", " ('frc3824', 126.96309325527552),\n", " ('frc1339', 125.96798422065352),\n", " ('frc4590', 125.26308475200871),\n", " ('frc1002', 124.21225689931802),\n", " ('frc3316', 122.8078910824091),\n", " ('frc5970', 122.50535563795168),\n", " ('frc6325', 119.78641397302121),\n", " ('frc418', 116.62106655170464),\n", " ('frc1477', 114.77491503934719),\n", " ('frc8', 114.29890025268725),\n", " ('frc5803', 113.73483804756773),\n", " ('frc6705', 111.58307204661132),\n", " ('frc4561', 111.00355528639119),\n", " ('frc2468', 110.41012216879824),\n", " ('frc5026', 110.04546378593928),\n", " ('frc5614', 107.61788458386509),\n", " ('frc3402', 107.4626066948726),\n", " ('frc2655', 104.24531198243945),\n", " ('frc3158', 101.14330694999202),\n", " ('frc488', 98.055462452244143),\n", " ('frc4592', 98.052651237205325),\n", " ('frc435', 96.464573727156278),\n", " ('frc3834', 91.570774782459154),\n", " ('frc441', 91.149404570612035),\n", " ('frc3140', 90.638557116564982),\n", " ('frc5816', 89.708856584075434),\n", " ('frc4219', 89.586753586033979),\n", " ('frc2485', 88.505690883901565),\n", " ('frc585', 88.25561566820447),\n", " ('frc3229', 86.158182066996943),\n", " ('frc6304', 85.649736210525333),\n", " ('frc3653', 85.284652499378396),\n", " ('frc175', 85.116732278878715),\n", " ('frc6508', 84.873574464768041),\n", " ('frc4276', 81.574812779764528),\n", " ('frc5499', 81.076671646279891),\n", " ('frc2478', 80.843731553943798),\n", " ('frc5515', 80.505727211308368),\n", " ('frc3826', 78.089578436795648),\n", " ('frc2881', 76.769491169265663),\n", " ('frc955', 75.507539471727597),\n", " ('frc2183', 70.635782080362318),\n", " ('frc6361', 70.17568719278286),\n", " ('frc1482', 69.055515009333917),\n", " ('frc6560', 68.823962846736208),\n", " ('frc3991', 67.737826004420583),\n", " ('frc4371', 67.365329372744242),\n", " ('frc6388', 66.306467100842639),\n", " ('frc4060', 65.914273669761229),\n", " ('frc4191', 62.865270011745224),\n", " ('frc4723', 56.810485185257662),\n", " ('frc5472', 54.510742035159979),\n", " ('frc6144', 36.696388177764277),\n", " ('frc2905', 26.417361845177616),\n", " ('frc6409', 8.2241314774465888)]\n" ] } ], "source": [ "match_outcomes = []\n", "for match in matches:\n", " match_outcomes.append(\n", " Match(teams=match['alliances']['blue']['team_keys'],\n", " score=match['alliances']['blue']['score'])\n", " )\n", " match_outcomes.append(\n", " Match(teams=match['alliances']['red']['team_keys'],\n", " score=match['alliances']['red']['score'])\n", " )\n", "score_oprs = sorted(CalcOpr(match_outcomes).items(), key=lambda x: -x[1])\n", "pprint(score_oprs)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false, "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'frc1002': 0.011495807536502572,\n", " 'frc1011': -0.23843650566297964,\n", " 'frc115': -0.012713387884420797,\n", " 'frc1339': 0.049583694803860427,\n", " 'frc1414': -0.025609512663978932,\n", " 'frc1477': 0.022485935872360904,\n", " 'frc1482': 0.024757792159351494,\n", " 'frc1574': 0.66808268010260641,\n", " 'frc175': 0.014010517155780116,\n", " 'frc2183': 0.014016941366526755,\n", " 'frc2403': 0.080360541678350023,\n", " 'frc2468': 0.054313747859282599,\n", " 'frc2478': 0.056793675027969996,\n", " 'frc2485': -0.11004523242061667,\n", " 'frc2642': -0.0093209117666008812,\n", " 'frc2655': 0.026158138151728107,\n", " 'frc2881': 0.12976928277693456,\n", " 'frc2905': -0.0054328961126955868,\n", " 'frc2928': -0.14365141927979586,\n", " 'frc3140': 0.034966321717088245,\n", " 'frc3158': -0.0083270752513364132,\n", " 'frc3229': -0.052914169109274517,\n", " 'frc3316': 0.022681055565912493,\n", " 'frc3402': -0.036669808722433681,\n", " 'frc365': -0.033387969672823169,\n", " 'frc3653': 0.014729368563237756,\n", " 'frc3824': 0.080450382242200247,\n", " 'frc3826': 0.019110268657443839,\n", " 'frc3834': -0.038611090946230317,\n", " 'frc3991': 0.0069417322847042124,\n", " 'frc4060': 0.031568346005882965,\n", " 'frc418': -0.17836616410749317,\n", " 'frc4191': -0.027664312060668557,\n", " 'frc4219': 0.018668059497609552,\n", " 'frc4265': -0.039762814142503211,\n", " 'frc4276': -0.011733796335331451,\n", " 'frc435': 0.021490162884872023,\n", " 'frc4371': 0.0013029801530613384,\n", " 'frc441': -0.017291511574850489,\n", " 'frc4561': 0.039187096494449604,\n", " 'frc4590': -0.0047923055382814448,\n", " 'frc4592': -0.0099013917493386283,\n", " 'frc4723': 0.027083177527512065,\n", " 'frc488': 0.30838132037945404,\n", " 'frc5026': -0.020690991999509637,\n", " 'frc5472': 0.070349291821964782,\n", " 'frc5499': 0.019626942011950511,\n", " 'frc5515': 0.063851785439747955,\n", " 'frc5614': -0.024521676323755421,\n", " 'frc5803': -0.015295375370894511,\n", " 'frc5816': 0.016515716145632582,\n", " 'frc585': 0.0023789472066973009,\n", " 'frc5970': -0.0044706821988662231,\n", " 'frc6144': 0.050254228103232886,\n", " 'frc624': -0.081349484164234639,\n", " 'frc6304': 0.033648856674681996,\n", " 'frc6325': -0.034250313916356766,\n", " 'frc6361': 0.045042709293893271,\n", " 'frc6388': -0.021082445337662147,\n", " 'frc6409': 0.045497807930851217,\n", " 'frc6508': 0.074536576581233485,\n", " 'frc6560': -0.080212765492548535,\n", " 'frc6705': -0.056760688554744892,\n", " 'frc8': 0.013041665258332877,\n", " 'frc955': 0.05983277602696755,\n", " 'frc973': 0.69379487994753519}\n" ] } ], "source": [ "match_outcomes = []\n", "for match in matches:\n", " match_outcomes.append(\n", " Match(teams=match['alliances']['blue']['team_keys'],\n", " score=match['score_breakdown']['blue']['kPaRankingPointAchieved'])\n", " )\n", " match_outcomes.append(\n", " Match(teams=match['alliances']['red']['team_keys'],\n", " score=match['score_breakdown']['red']['kPaRankingPointAchieved'])\n", " )\n", "kpa_oprs = CalcOpr(match_outcomes)\n", "pprint(kpa_oprs)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True positives 17\n", "True negatives 229\n", "False positives 3\n", "False negatives 3\n", "Correctness 0.9761904761904762\n" ] } ], "source": [ "true_positives = 0\n", "true_negatives = 0\n", "false_positives = 0\n", "false_negatives = 0\n", "\n", "for match in matches:\n", " for alliance in ['red', 'blue']:\n", " result = match['score_breakdown'][alliance]['kPaRankingPointAchieved']\n", " prediction = sum(\n", " kpa_oprs[team] for team in match['alliances'][alliance]['team_keys']\n", " ) > 0.5\n", " if result and prediction:\n", " true_positives += 1\n", " elif result and not prediction:\n", " false_negatives += 1\n", " elif not result and prediction:\n", " false_positives += 1\n", " elif not result and not prediction:\n", " true_negatives += 1\n", "\n", "print(\"True positives\", true_positives)\n", "print(\"True negatives\", true_negatives)\n", "print(\"False positives\", false_positives)\n", "print(\"False negatives\", false_negatives)\n", "print(\"Correctness\", (true_positives + true_negatives) / (true_positives + true_negatives + false_positives + false_negatives + 0.0))" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'frc1002': 0.17727192353651036,\n", " 'frc1011': 0.23646020615753144,\n", " 'frc115': 0.27027459301427076,\n", " 'frc1339': 0.27767467034227666,\n", " 'frc1414': 0.097528516725300579,\n", " 'frc1477': 0.24271506617743271,\n", " 'frc1482': -0.20183290190431527,\n", " 'frc1574': -0.062725432249641944,\n", " 'frc175': 0.066614006692210043,\n", " 'frc2183': 0.17779147326885175,\n", " 'frc2403': 0.26038237793502095,\n", " 'frc2468': 0.077335124862353138,\n", " 'frc2478': 0.11611763401010168,\n", " 'frc2485': 0.22766288292212927,\n", " 'frc2642': 0.44131736419305789,\n", " 'frc2655': 0.078615164315436414,\n", " 'frc2881': 0.026395389715158406,\n", " 'frc2905': -0.15742362551120212,\n", " 'frc2928': 0.19144017072648187,\n", " 'frc3140': 0.050819349427158898,\n", " 'frc3158': 0.099557651860255836,\n", " 'frc3229': 0.30137859678360285,\n", " 'frc3316': -0.017803621940292693,\n", " 'frc3402': 0.23407474552151586,\n", " 'frc365': 0.027014917937426858,\n", " 'frc3653': 0.055081036501289343,\n", " 'frc3824': 0.034654129291765062,\n", " 'frc3826': 0.1618711950878218,\n", " 'frc3834': -0.10927154609293535,\n", " 'frc3991': 0.20426591613959094,\n", " 'frc4060': -0.041813912600997927,\n", " 'frc418': -0.18067404916238411,\n", " 'frc4191': -0.16868864593985589,\n", " 'frc4219': 0.0035790511659747511,\n", " 'frc4265': 0.080896946538550563,\n", " 'frc4276': 0.13708185480133839,\n", " 'frc435': 0.16573089995659673,\n", " 'frc4371': 0.080681643521142932,\n", " 'frc441': -0.077337956468450111,\n", " 'frc4561': 0.06389536845233032,\n", " 'frc4590': -0.049808506391208721,\n", " 'frc4592': 0.10461776563177416,\n", " 'frc4723': 0.086487057324865432,\n", " 'frc488': 0.012815142631013174,\n", " 'frc5026': -0.039661993822559902,\n", " 'frc5472': -0.19424322205436845,\n", " 'frc5499': 0.19376531412413966,\n", " 'frc5515': 0.064064234500017039,\n", " 'frc5614': 0.08808190904164967,\n", " 'frc5803': 0.057311874395802438,\n", " 'frc5816': 0.069464650468857733,\n", " 'frc585': 0.035569288619228395,\n", " 'frc5970': 0.44357144135582388,\n", " 'frc6144': 0.0079100008274700304,\n", " 'frc624': 0.35576013463202721,\n", " 'frc6304': -0.10973657565707473,\n", " 'frc6325': 0.26476227726013973,\n", " 'frc6361': 0.13208922601294448,\n", " 'frc6388': -0.15295108609704131,\n", " 'frc6409': -0.10431659019076206,\n", " 'frc6508': 0.086131409830338679,\n", " 'frc6560': 0.074907461418003418,\n", " 'frc6705': 0.22003298058691301,\n", " 'frc8': 0.247847970810986,\n", " 'frc955': -0.010061945508252013,\n", " 'frc973': -0.076970861048886952}\n" ] } ], "source": [ "match_outcomes = []\n", "for match in matches:\n", " match_outcomes.append(\n", " Match(teams=match['alliances']['blue']['team_keys'],\n", " score=match['score_breakdown']['blue']['rotorRankingPointAchieved'])\n", " )\n", " match_outcomes.append(\n", " Match(teams=match['alliances']['red']['team_keys'],\n", " score=match['score_breakdown']['red']['rotorRankingPointAchieved'])\n", " )\n", "rotor_oprs = CalcOpr(match_outcomes)\n", "pprint(rotor_oprs)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True positives 27\n", "True negatives 177\n", "False positives 9\n", "False negatives 39\n", "Correctness 0.8095238095238095\n" ] } ], "source": [ "true_positives = 0\n", "true_negatives = 0\n", "false_positives = 0\n", "false_negatives = 0\n", "\n", "for match in matches:\n", " for alliance in ['red', 'blue']:\n", " result = match['score_breakdown'][alliance]['rotorRankingPointAchieved']\n", " prediction = sum(\n", " rotor_oprs[team] for team in match['alliances'][alliance]['team_keys']\n", " ) > 0.5\n", " if result and prediction:\n", " true_positives += 1\n", " elif result and not prediction:\n", " false_negatives += 1\n", " elif not result and prediction:\n", " false_positives += 1\n", " elif not result and not prediction:\n", " true_negatives += 1\n", "\n", "print(\"True positives\", true_positives)\n", "print(\"True negatives\", true_negatives)\n", "print(\"False positives\", false_positives)\n", "print(\"False negatives\", false_negatives)\n", "print(\"Correctness\", (true_positives + true_negatives) / (true_positives + true_negatives + false_positives + false_negatives + 0.0))" ] } ], "metadata": { "kernelspec": { "display_name": "py35native", "language": "python", "name": "py35native" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.5.2" } }, "nbformat": 4, "nbformat_minor": 1 }