{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Quantifying Home-Country Preference in Figure Skating Scores\n", "\n", "The International Skating Union introduced anonymous judging as part of sweeping reforms following the 2002 Olympics. The ISU voted to reverse that policy before the start of the 2016-17 figure skating season, meaning that it is possible to know the scores provided by each judge. This analysis uses scoring data from every major international competition from October 2016 through December 2017 to quantify judges' home-country preference." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import pandas as pd\n", "from scipy import stats\n", "import matplotlib\n", "%matplotlib inline" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Load Judge and Score Data" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
judge_nameassigned_countryrolesegment_categorypdf_nameprogramcompetitionofficials_table_linkresults_pdf_linkclean_judge_name
0Ms. Chihee RHEEKORJudge No.1Free Dance|Ice Dance4f3031488c_data0405.pdfICE DANCE FREE DANCEGrand Prix Final 2017 Senior and Juniorhttp://www.isuresults.com/results/season1718/g...http://www.isuresults.com/results/season1718/g...Chihee RHEE
1Mr. David MUNOZESPJudge No.2Free Dance|Ice Dance4f3031488c_data0405.pdfICE DANCE FREE DANCEGrand Prix Final 2017 Senior and Juniorhttp://www.isuresults.com/results/season1718/g...http://www.isuresults.com/results/season1718/g...David MUNOZ
2Mr. Feng HUANGCHNJudge No.3Free Dance|Ice Dance4f3031488c_data0405.pdfICE DANCE FREE DANCEGrand Prix Final 2017 Senior and Juniorhttp://www.isuresults.com/results/season1718/g...http://www.isuresults.com/results/season1718/g...Feng HUANG
3Mr. Richard DALLEYUSAJudge No.4Free Dance|Ice Dance4f3031488c_data0405.pdfICE DANCE FREE DANCEGrand Prix Final 2017 Senior and Juniorhttp://www.isuresults.com/results/season1718/g...http://www.isuresults.com/results/season1718/g...Richard DALLEY
4Mr. Walter ZUCCAROITAJudge No.5Free Dance|Ice Dance4f3031488c_data0405.pdfICE DANCE FREE DANCEGrand Prix Final 2017 Senior and Juniorhttp://www.isuresults.com/results/season1718/g...http://www.isuresults.com/results/season1718/g...Walter ZUCCARO
\n", "
" ], "text/plain": [ " judge_name assigned_country role segment_category \\\n", "0 Ms. Chihee RHEE KOR Judge No.1 Free Dance|Ice Dance \n", "1 Mr. David MUNOZ ESP Judge No.2 Free Dance|Ice Dance \n", "2 Mr. Feng HUANG CHN Judge No.3 Free Dance|Ice Dance \n", "3 Mr. Richard DALLEY USA Judge No.4 Free Dance|Ice Dance \n", "4 Mr. Walter ZUCCARO ITA Judge No.5 Free Dance|Ice Dance \n", "\n", " pdf_name program \\\n", "0 4f3031488c_data0405.pdf ICE DANCE FREE DANCE \n", "1 4f3031488c_data0405.pdf ICE DANCE FREE DANCE \n", "2 4f3031488c_data0405.pdf ICE DANCE FREE DANCE \n", "3 4f3031488c_data0405.pdf ICE DANCE FREE DANCE \n", "4 4f3031488c_data0405.pdf ICE DANCE FREE DANCE \n", "\n", " competition \\\n", "0 Grand Prix Final 2017 Senior and Junior \n", "1 Grand Prix Final 2017 Senior and Junior \n", "2 Grand Prix Final 2017 Senior and Junior \n", "3 Grand Prix Final 2017 Senior and Junior \n", "4 Grand Prix Final 2017 Senior and Junior \n", "\n", " officials_table_link \\\n", "0 http://www.isuresults.com/results/season1718/g... \n", "1 http://www.isuresults.com/results/season1718/g... \n", "2 http://www.isuresults.com/results/season1718/g... \n", "3 http://www.isuresults.com/results/season1718/g... \n", "4 http://www.isuresults.com/results/season1718/g... \n", "\n", " results_pdf_link clean_judge_name \n", "0 http://www.isuresults.com/results/season1718/g... Chihee RHEE \n", "1 http://www.isuresults.com/results/season1718/g... David MUNOZ \n", "2 http://www.isuresults.com/results/season1718/g... Feng HUANG \n", "3 http://www.isuresults.com/results/season1718/g... Richard DALLEY \n", "4 http://www.isuresults.com/results/season1718/g... Walter ZUCCARO " ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "all_judges = pd.read_csv(\"../data/processed/judges.csv\")\n", "all_judges.head()" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
clean_judge_namejudge_country
0Adriana DOMANSKASVK
1Adriana ORDEANUROU
2Agita ABELELAT
3Agnieszka SWIDERSKAPOL
4Aigul KUANISHEVAKAZ
\n", "
" ], "text/plain": [ " clean_judge_name judge_country\n", "0 Adriana DOMANSKA SVK\n", "1 Adriana ORDEANU ROU\n", "2 Agita ABELE LAT\n", "3 Agnieszka SWIDERSKA POL\n", "4 Aigul KUANISHEVA KAZ" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "judge_nat = pd.read_csv(\"../data/processed/judge-country.csv\")\n", "judge_nat.head()" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": true }, "outputs": [], "source": [ "judges = pd.merge(\n", " all_judges,\n", " judge_nat,\n", " on=\"clean_judge_name\"\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The ISU's results pages list judge roles with a full description, e.g., **Judge No. 1**. In the protocol PDFs that the ISU releases after each competition, the judge number is reduced to a shorter description, e.g., **J1**. The function below converts the longer description to the shorter description found in the PDF." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def clean_judge_number(role):\n", " return \"J\" + role.strip()[-1]" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": true }, "outputs": [], "source": [ "judges[\"clean_role\"] = judges[\"role\"].apply(clean_judge_number)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "J1 152\n", "J2 152\n", "J3 152\n", "J4 152\n", "J5 152\n", "J6 151\n", "J7 152\n", "J8 152\n", "J9 152\n", "Name: clean_role, dtype: int64" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "judges[\"clean_role\"].value_counts().sort_index()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Load scoring data\n", "\n", "See this repository's `README.md` file for more details about the source and structure of the scoring data." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1,726 performances\n", "23,932 aspects\n", "214,531 scores\n" ] } ], "source": [ "performances = pd.read_csv(\"../data/raw/performances.csv\")\n", "print(\"{:,} performances\".format(len(performances)))\n", "\n", "aspects = pd.read_csv(\"../data/raw/judged-aspects.csv\")\n", "print(\"{:,} aspects\".format(len(aspects)))\n", "\n", "scores = pd.read_csv(\"../data/raw/judge-scores.csv\")\n", "print(\"{:,} scores\".format(len(scores)))" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
performance_idcompetitionprogramnamenationrankstarting_numbertotal_segment_scoretotal_element_scoretotal_component_scoretotal_deductions
06e4bd41ac5Grand Prix Final 2017 Senior and JuniorICE DANCE FREE DANCEAnna CAPPELLINI / Luca LANOTTEITA51110.9956.0154.980.0
1562c01c5a6Grand Prix Final 2017 Senior and JuniorICE DANCE FREE DANCEMadison HUBBELL / Zachary DONOHUEUSA42112.5957.4255.170.0
22de894c029Grand Prix Final 2017 Senior and JuniorICE DANCE FREE DANCEMadison CHOCK / Evan BATESUSA33112.7957.2555.540.0
306e4b8b67eGrand Prix Final 2017 Senior and JuniorICE DANCE FREE DANCEMaia SHIBUTANI / Alex SHIBUTANIUSA64109.9154.1555.760.0
472e3228debGrand Prix Final 2017 Senior and JuniorICE DANCE FREE DANCETessa VIRTUE / Scott MOIRCAN25118.3359.6658.670.0
\n", "
" ], "text/plain": [ " performance_id competition \\\n", "0 6e4bd41ac5 Grand Prix Final 2017 Senior and Junior \n", "1 562c01c5a6 Grand Prix Final 2017 Senior and Junior \n", "2 2de894c029 Grand Prix Final 2017 Senior and Junior \n", "3 06e4b8b67e Grand Prix Final 2017 Senior and Junior \n", "4 72e3228deb Grand Prix Final 2017 Senior and Junior \n", "\n", " program name nation rank \\\n", "0 ICE DANCE FREE DANCE Anna CAPPELLINI / Luca LANOTTE ITA 5 \n", "1 ICE DANCE FREE DANCE Madison HUBBELL / Zachary DONOHUE USA 4 \n", "2 ICE DANCE FREE DANCE Madison CHOCK / Evan BATES USA 3 \n", "3 ICE DANCE FREE DANCE Maia SHIBUTANI / Alex SHIBUTANI USA 6 \n", "4 ICE DANCE FREE DANCE Tessa VIRTUE / Scott MOIR CAN 2 \n", "\n", " starting_number total_segment_score total_element_score \\\n", "0 1 110.99 56.01 \n", "1 2 112.59 57.42 \n", "2 3 112.79 57.25 \n", "3 4 109.91 54.15 \n", "4 5 118.33 59.66 \n", "\n", " total_component_score total_deductions \n", "0 54.98 0.0 \n", "1 55.17 0.0 \n", "2 55.54 0.0 \n", "3 55.76 0.0 \n", "4 58.67 0.0 " ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "performances.head()" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
aspect_idperformance_idsectionaspect_numaspect_descinfo_flagcredit_flagbase_valuefactorgoerefscores_of_panel
000034b9414b639d77459componentsNaNTransitionsNaNNaNNaN0.8NaNNaN9.07
10004dd08d69589bb2ebfcomponentsNaNTransitionsNaNNaNNaN0.8NaNNaN6.64
2000b8b507071d2b1b597componentsNaNPerformanceNaNNaNNaN1.0NaNNaN7.68
3000cec97c941a2345881componentsNaNTransitionsNaNNaNNaN0.8NaNNaN4.71
4000df5399ab017147b2felements1.03Tw2NaNNaN5.8NaN-0.2NaN5.60
\n", "
" ], "text/plain": [ " aspect_id performance_id section aspect_num aspect_desc info_flag \\\n", "0 00034b9414 b639d77459 components NaN Transitions NaN \n", "1 0004dd08d6 9589bb2ebf components NaN Transitions NaN \n", "2 000b8b5070 71d2b1b597 components NaN Performance NaN \n", "3 000cec97c9 41a2345881 components NaN Transitions NaN \n", "4 000df5399a b017147b2f elements 1.0 3Tw2 NaN \n", "\n", " credit_flag base_value factor goe ref scores_of_panel \n", "0 NaN NaN 0.8 NaN NaN 9.07 \n", "1 NaN NaN 0.8 NaN NaN 6.64 \n", "2 NaN NaN 1.0 NaN NaN 7.68 \n", "3 NaN NaN 0.8 NaN NaN 4.71 \n", "4 NaN 5.8 NaN -0.2 NaN 5.60 " ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "aspects.head()" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
aspect_idjudgescore
000034b9414J19.00
100034b9414J29.00
200034b9414J38.75
300034b9414J49.25
400034b9414J59.00
\n", "
" ], "text/plain": [ " aspect_id judge score\n", "0 00034b9414 J1 9.00\n", "1 00034b9414 J2 9.00\n", "2 00034b9414 J3 8.75\n", "3 00034b9414 J4 9.25\n", "4 00034b9414 J5 9.00" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "scores.head()" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
aspect_idjudgejudge_goe
0000df5399aJ1-0.7
1000df5399aJ2-0.7
2000df5399aJ3-0.7
3000df5399aJ40.0
4000df5399aJ5-0.7
\n", "
" ], "text/plain": [ " aspect_id judge judge_goe\n", "0 000df5399a J1 -0.7\n", "1 000df5399a J2 -0.7\n", "2 000df5399a J3 -0.7\n", "3 000df5399a J4 0.0\n", "4 000df5399a J5 -0.7" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "judge_goe = pd.read_csv(\"../data/processed/judge-goe.csv\")\n", "judge_goe.head()" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": true }, "outputs": [], "source": [ "scores_with_context = scores.pipe(\n", " pd.merge,\n", " aspects,\n", " on = \"aspect_id\",\n", " how = \"left\"\n", ").pipe(\n", " pd.merge,\n", " performances,\n", " on = \"performance_id\",\n", " how = \"left\"\n", ").pipe(\n", " pd.merge,\n", " judge_goe,\n", " on = [ \"aspect_id\", \"judge\" ],\n", " how = \"left\"\n", ").assign(\n", " is_junior = lambda x: x[\"program\"].str.contains(\"JUNIOR\"),\n", " program_type = lambda x: x[\"program\"]\\\n", " .apply(lambda x: \"short\" if \"SHORT\" in x else \"free\")\n", ")" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": true }, "outputs": [], "source": [ "assert len(scores) == len(scores_with_context)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here, we remove junior programs from the data, so that we're only analyzing senior performances. (There are both junior and senior programs at the Grand Prix Finals.)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1632" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "senior_scores = scores_with_context[\n", " scores_with_context[\"is_junior\"] == False\n", "].copy()\n", "\n", "senior_scores[\"performance_id\"].nunique()" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
214526214527214528214529214530
aspect_idfff81cacfbfff81cacfbfff81cacfbfff81cacfbfff81cacfb
judgeJ5J6J7J8J9
score11222
performance_idba47e4e8f3ba47e4e8f3ba47e4e8f3ba47e4e8f3ba47e4e8f3
sectionelementselementselementselementselements
aspect_num22222
aspect_desc1MB4+kpYYY1MB4+kpYYY1MB4+kpYYY1MB4+kpYYY1MB4+kpYYY
info_flagNaNNaNNaNNaNNaN
credit_flagNaNNaNNaNNaNNaN
base_value55555
factorNaNNaNNaNNaNNaN
goe1.111.111.111.111.11
refNaNNaNNaNNaNNaN
scores_of_panel6.116.116.116.116.11
competitionISU GP Rostelecom Cup 2016ISU GP Rostelecom Cup 2016ISU GP Rostelecom Cup 2016ISU GP Rostelecom Cup 2016ISU GP Rostelecom Cup 2016
programICE DANCE SHORT DANCEICE DANCE SHORT DANCEICE DANCE SHORT DANCEICE DANCE SHORT DANCEICE DANCE SHORT DANCE
nameMadison CHOCK / Evan BATESMadison CHOCK / Evan BATESMadison CHOCK / Evan BATESMadison CHOCK / Evan BATESMadison CHOCK / Evan BATES
nationUSAUSAUSAUSAUSA
rank11111
starting_number66666
total_segment_score75.0475.0475.0475.0475.04
total_element_score38.3538.3538.3538.3538.35
total_component_score36.6936.6936.6936.6936.69
total_deductions00000
judge_goe0.60.61.21.21.2
is_juniorFalseFalseFalseFalseFalse
program_typeshortshortshortshortshort
\n", "
" ], "text/plain": [ " 214526 214527 \\\n", "aspect_id fff81cacfb fff81cacfb \n", "judge J5 J6 \n", "score 1 1 \n", "performance_id ba47e4e8f3 ba47e4e8f3 \n", "section elements elements \n", "aspect_num 2 2 \n", "aspect_desc 1MB4+kpYYY 1MB4+kpYYY \n", "info_flag NaN NaN \n", "credit_flag NaN NaN \n", "base_value 5 5 \n", "factor NaN NaN \n", "goe 1.11 1.11 \n", "ref NaN NaN \n", "scores_of_panel 6.11 6.11 \n", "competition ISU GP Rostelecom Cup 2016 ISU GP Rostelecom Cup 2016 \n", "program ICE DANCE SHORT DANCE ICE DANCE SHORT DANCE \n", "name Madison CHOCK / Evan BATES Madison CHOCK / Evan BATES \n", "nation USA USA \n", "rank 1 1 \n", "starting_number 6 6 \n", "total_segment_score 75.04 75.04 \n", "total_element_score 38.35 38.35 \n", "total_component_score 36.69 36.69 \n", "total_deductions 0 0 \n", "judge_goe 0.6 0.6 \n", "is_junior False False \n", "program_type short short \n", "\n", " 214528 214529 \\\n", "aspect_id fff81cacfb fff81cacfb \n", "judge J7 J8 \n", "score 2 2 \n", "performance_id ba47e4e8f3 ba47e4e8f3 \n", "section elements elements \n", "aspect_num 2 2 \n", "aspect_desc 1MB4+kpYYY 1MB4+kpYYY \n", "info_flag NaN NaN \n", "credit_flag NaN NaN \n", "base_value 5 5 \n", "factor NaN NaN \n", "goe 1.11 1.11 \n", "ref NaN NaN \n", "scores_of_panel 6.11 6.11 \n", "competition ISU GP Rostelecom Cup 2016 ISU GP Rostelecom Cup 2016 \n", "program ICE DANCE SHORT DANCE ICE DANCE SHORT DANCE \n", "name Madison CHOCK / Evan BATES Madison CHOCK / Evan BATES \n", "nation USA USA \n", "rank 1 1 \n", "starting_number 6 6 \n", "total_segment_score 75.04 75.04 \n", "total_element_score 38.35 38.35 \n", "total_component_score 36.69 36.69 \n", "total_deductions 0 0 \n", "judge_goe 1.2 1.2 \n", "is_junior False False \n", "program_type short short \n", "\n", " 214530 \n", "aspect_id fff81cacfb \n", "judge J9 \n", "score 2 \n", "performance_id ba47e4e8f3 \n", "section elements \n", "aspect_num 2 \n", "aspect_desc 1MB4+kpYYY \n", "info_flag NaN \n", "credit_flag NaN \n", "base_value 5 \n", "factor NaN \n", "goe 1.11 \n", "ref NaN \n", "scores_of_panel 6.11 \n", "competition ISU GP Rostelecom Cup 2016 \n", "program ICE DANCE SHORT DANCE \n", "name Madison CHOCK / Evan BATES \n", "nation USA \n", "rank 1 \n", "starting_number 6 \n", "total_segment_score 75.04 \n", "total_element_score 38.35 \n", "total_component_score 36.69 \n", "total_deductions 0 \n", "judge_goe 1.2 \n", "is_junior False \n", "program_type short " ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "senior_scores.tail().T" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Calculate Total Points for Each Judge and Difference from the Mean" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Calculate the total number of points awarded for each aspect\n", "\n", "The total score given by a judge is calculated differently for elements vs. components. Technical elements are scored by adding the base value of the element to the translated Grade of Execution. Artistic components are scored by multiplying the score the judge gave by a pre-determined factor. The function below does this math for both sections of each program." ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def total_points(row):\n", " # In one edge-case, a \"J6\" is listed as providing a score of zero.\n", " # (There was no sixth judge, and the minimum score for a component is 0.25, per ISU regulations.)\n", " # In the if-clause below, we ignore this edge-case.\n", " if (row[\"section\"] == \"components\") and (row[\"score\"] == 0):\n", " return None\n", " \n", " elif row[\"section\"] == \"elements\":\n", " return round(row[\"base_value\"] + row[\"judge_goe\"], 2)\n", " \n", " elif row[\"section\"] == \"components\":\n", " return round(row[\"factor\"] * row[\"score\"], 2)\n", " \n", " else:\n", " print(\"Unknown section: {}\".format(row[\"section\"]))\n", " return None" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": true }, "outputs": [], "source": [ "senior_scores[\"total_points\"] = senior_scores.apply(total_points, axis=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Calculate the total number of points awarded for each performance by each judge\n", "\n", "\n", "After calculating the total points awarded for each aspect, it is possible to calculate the total score that a skater would have received from any individual judge. Points can be deducted from the final score for falls or other problems. These deductions are issued by the technical panel and are not the purview of any individual judge; still, we subtract them from the final score to get an accurate representation of how a judge scored the overall skate." ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": true }, "outputs": [], "source": [ "perf_judge_grps = senior_scores[\n", " ~senior_scores[\"total_points\"].isnull()\n", "].groupby([\"performance_id\", \"judge\"])" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
performance_idjudgecompetitiondeductionsnamenationpointsprogramprogram_typefinal_score
00055dd827dJ1ISU GP Trophee de France 20160.0Denis TENKAZ176.58MEN FREE SKATINGfree176.58
10055dd827dJ2ISU GP Trophee de France 20160.0Denis TENKAZ174.28MEN FREE SKATINGfree174.28
20055dd827dJ3ISU GP Trophee de France 20160.0Denis TENKAZ185.88MEN FREE SKATINGfree185.88
30055dd827dJ4ISU GP Trophee de France 20160.0Denis TENKAZ183.78MEN FREE SKATINGfree183.78
40055dd827dJ5ISU GP Trophee de France 20160.0Denis TENKAZ178.28MEN FREE SKATINGfree178.28
\n", "
" ], "text/plain": [ " performance_id judge competition deductions name \\\n", "0 0055dd827d J1 ISU GP Trophee de France 2016 0.0 Denis TEN \n", "1 0055dd827d J2 ISU GP Trophee de France 2016 0.0 Denis TEN \n", "2 0055dd827d J3 ISU GP Trophee de France 2016 0.0 Denis TEN \n", "3 0055dd827d J4 ISU GP Trophee de France 2016 0.0 Denis TEN \n", "4 0055dd827d J5 ISU GP Trophee de France 2016 0.0 Denis TEN \n", "\n", " nation points program program_type final_score \n", "0 KAZ 176.58 MEN FREE SKATING free 176.58 \n", "1 KAZ 174.28 MEN FREE SKATING free 174.28 \n", "2 KAZ 185.88 MEN FREE SKATING free 185.88 \n", "3 KAZ 183.78 MEN FREE SKATING free 183.78 \n", "4 KAZ 178.28 MEN FREE SKATING free 178.28 " ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "points_by_judge = pd.DataFrame({\n", " \"points\": perf_judge_grps[\"total_points\"].sum(),\n", " \"deductions\": perf_judge_grps[\"total_deductions\"].first(),\n", " \"name\": perf_judge_grps[\"name\"].first(),\n", " \"nation\": perf_judge_grps[\"nation\"].first(),\n", " \"program\": perf_judge_grps[\"program\"].first(),\n", " \"program_type\": perf_judge_grps[\"program_type\"].first(),\n", " \"competition\": perf_judge_grps[\"competition\"].first()\n", "}).reset_index()\n", "points_by_judge[\"final_score\"] = points_by_judge[\"points\"] - points_by_judge[\"deductions\"]\n", "\n", "points_by_judge.head()" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Deductions occur in about 30% of scores:\n" ] }, { "data": { "text/plain": [ "0 10253\n", "1 3419\n", "2 846\n", "4 72\n", "3 63\n", "6 18\n", "9 9\n", "Name: deductions, dtype: int64" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "print(\"Deductions occur in about {:.0f}% of scores:\"\\\n", " .format((points_by_judge[\"deductions\"] > 0).mean() * 100))\n", "\n", "points_by_judge[\"deductions\"].astype(int).value_counts()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Calculate the total number of points awarded for each performance" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": true }, "outputs": [], "source": [ "perf_grps = points_by_judge.groupby([\"performance_id\"])" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
performance_idtotal_judgestotal_points
00055dd827d91615.52
100693b66b59689.20
2007541009f9930.10
3007e8ef3439529.40
4008085d23791476.57
\n", "
" ], "text/plain": [ " performance_id total_judges total_points\n", "0 0055dd827d 9 1615.52\n", "1 00693b66b5 9 689.20\n", "2 007541009f 9 930.10\n", "3 007e8ef343 9 529.40\n", "4 008085d237 9 1476.57" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "perfs = pd.DataFrame({\n", " \"total_points\": perf_grps[\"final_score\"].sum(),\n", " \"total_judges\": perf_grps.size()\n", "}).reset_index()\n", "\n", "perfs.head()" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
performance_idjudgecompetitiondeductionsnamenationpointsprogramprogram_typefinal_scoretotal_judgestotal_points
00055dd827dJ1ISU GP Trophee de France 20160.0Denis TENKAZ176.58MEN FREE SKATINGfree176.5891615.52
10055dd827dJ2ISU GP Trophee de France 20160.0Denis TENKAZ174.28MEN FREE SKATINGfree174.2891615.52
20055dd827dJ3ISU GP Trophee de France 20160.0Denis TENKAZ185.88MEN FREE SKATINGfree185.8891615.52
30055dd827dJ4ISU GP Trophee de France 20160.0Denis TENKAZ183.78MEN FREE SKATINGfree183.7891615.52
40055dd827dJ5ISU GP Trophee de France 20160.0Denis TENKAZ178.28MEN FREE SKATINGfree178.2891615.52
\n", "
" ], "text/plain": [ " performance_id judge competition deductions name \\\n", "0 0055dd827d J1 ISU GP Trophee de France 2016 0.0 Denis TEN \n", "1 0055dd827d J2 ISU GP Trophee de France 2016 0.0 Denis TEN \n", "2 0055dd827d J3 ISU GP Trophee de France 2016 0.0 Denis TEN \n", "3 0055dd827d J4 ISU GP Trophee de France 2016 0.0 Denis TEN \n", "4 0055dd827d J5 ISU GP Trophee de France 2016 0.0 Denis TEN \n", "\n", " nation points program program_type final_score total_judges \\\n", "0 KAZ 176.58 MEN FREE SKATING free 176.58 9 \n", "1 KAZ 174.28 MEN FREE SKATING free 174.28 9 \n", "2 KAZ 185.88 MEN FREE SKATING free 185.88 9 \n", "3 KAZ 183.78 MEN FREE SKATING free 183.78 9 \n", "4 KAZ 178.28 MEN FREE SKATING free 178.28 9 \n", "\n", " total_points \n", "0 1615.52 \n", "1 1615.52 \n", "2 1615.52 \n", "3 1615.52 \n", "4 1615.52 " ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "points_with_comparison = pd.merge(\n", " points_by_judge,\n", " perfs,\n", " how = \"left\",\n", " on = \"performance_id\"\n", ")\n", "\n", "points_with_comparison.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Calculate the average points for each performance, excluding the given judge\n", "\n", "`points_vs_avg` is the total number of points a judge scored the performance above or below the average score of all the remaining judges for that particular performance. It is the comparison point that we will use in all of the analyses moving forward." ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "collapsed": true }, "outputs": [], "source": [ "points_with_comparison[\"avg_without_judge\"] = points_with_comparison\\\n", " .apply(lambda x: (x[\"total_points\"] - x[\"final_score\"]) / (x[\"total_judges\"] - 1), axis=1)" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "collapsed": true }, "outputs": [], "source": [ "points_with_comparison[\"points_vs_avg\"] = points_with_comparison[\"final_score\"] - \\\n", " points_with_comparison[\"avg_without_judge\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Merge Judge Data with Score Data" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
performance_idjudgecompetitiondeductionsnamenationpointsprogramprogram_typefinal_scoretotal_judgestotal_pointsavg_without_judgepoints_vs_avgsegment_categoryclean_judge_namejudge_countryclean_role
00055dd827dJ1ISU GP Trophee de France 20160.0Denis TENKAZ176.58MEN FREE SKATINGfree176.5891615.52179.8675-3.2875Free Skating|MenFrancoise DE RAPPARDBELJ1
10055dd827dJ2ISU GP Trophee de France 20160.0Denis TENKAZ174.28MEN FREE SKATINGfree174.2891615.52180.1550-5.8750Free Skating|MenMasako KUBOTAJPNJ2
20055dd827dJ3ISU GP Trophee de France 20160.0Denis TENKAZ185.88MEN FREE SKATINGfree185.8891615.52178.70507.1750Free Skating|MenYuri GUSKOVKAZJ3
30055dd827dJ4ISU GP Trophee de France 20160.0Denis TENKAZ183.78MEN FREE SKATINGfree183.7891615.52178.96754.8125Free Skating|MenSaodat NUMANOVAUZBJ4
40055dd827dJ5ISU GP Trophee de France 20160.0Denis TENKAZ178.28MEN FREE SKATINGfree178.2891615.52179.6550-1.3750Free Skating|MenElisabeth LOUESDONFRAJ5
\n", "
" ], "text/plain": [ " performance_id judge competition deductions name \\\n", "0 0055dd827d J1 ISU GP Trophee de France 2016 0.0 Denis TEN \n", "1 0055dd827d J2 ISU GP Trophee de France 2016 0.0 Denis TEN \n", "2 0055dd827d J3 ISU GP Trophee de France 2016 0.0 Denis TEN \n", "3 0055dd827d J4 ISU GP Trophee de France 2016 0.0 Denis TEN \n", "4 0055dd827d J5 ISU GP Trophee de France 2016 0.0 Denis TEN \n", "\n", " nation points program program_type final_score total_judges \\\n", "0 KAZ 176.58 MEN FREE SKATING free 176.58 9 \n", "1 KAZ 174.28 MEN FREE SKATING free 174.28 9 \n", "2 KAZ 185.88 MEN FREE SKATING free 185.88 9 \n", "3 KAZ 183.78 MEN FREE SKATING free 183.78 9 \n", "4 KAZ 178.28 MEN FREE SKATING free 178.28 9 \n", "\n", " total_points avg_without_judge points_vs_avg segment_category \\\n", "0 1615.52 179.8675 -3.2875 Free Skating|Men \n", "1 1615.52 180.1550 -5.8750 Free Skating|Men \n", "2 1615.52 178.7050 7.1750 Free Skating|Men \n", "3 1615.52 178.9675 4.8125 Free Skating|Men \n", "4 1615.52 179.6550 -1.3750 Free Skating|Men \n", "\n", " clean_judge_name judge_country clean_role \n", "0 Francoise DE RAPPARD BEL J1 \n", "1 Masako KUBOTA JPN J2 \n", "2 Yuri GUSKOV KAZ J3 \n", "3 Saodat NUMANOVA UZB J4 \n", "4 Elisabeth LOUESDON FRA J5 " ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "judge_points = pd.merge(\n", " points_with_comparison,\n", " judges[[\n", " \"program\", \"competition\", \"segment_category\",\n", " \"clean_judge_name\", \"judge_country\", \"clean_role\"\n", " ]],\n", " left_on=[ \"program\", \"competition\", \"judge\" ],\n", " right_on=[ \"program\", \"competition\", \"clean_role\" ],\n", " how=\"left\"\n", ").dropna(subset=[\"judge_country\"])\n", "\n", "judge_points.head()" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "collapsed": true }, "outputs": [], "source": [ "judge_points[\"skater_judge_same_country\"] = (judge_points[\"nation\"] == judge_points[\"judge_country\"])" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "In the dataset, there are 1,305 performance-judge combinations \n", "in which the judge and skater(s) represent the *same* country.\n", "\n", "There are 13,375 performance-judge combinations in which the \n", "judge and skater(s) represent *different* countries.\n", "\n" ] } ], "source": [ "print(\"\"\"\n", "In the dataset, there are {:,} performance-judge combinations \n", "in which the judge and skater(s) represent the *same* country.\n", "\n", "There are {:,} performance-judge combinations in which the \n", "judge and skater(s) represent *different* countries.\n", "\"\"\".format(\n", " judge_points[\"skater_judge_same_country\"].sum(),\n", " (~judge_points[\"skater_judge_same_country\"]).sum()\n", "))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Calculate Home-Country Preference" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Account for judge \"generosity\" by program type\n", "\n", "One reason that home-country preferences among groups of judges — e.g., all judges overall or for all judges representing an entire country — might appear is if the most generous-grading judges are over-represented among home-country judgements. Additionally, the range in scores is larger for \"free\" programs than \"short\" programs. So, below, we adjust each judge's \"points versus the average\" to account for their overall tendency to give scores higher or lower than the average, for both the free and short programs. Note: These calculations are *not* used for evaluating individual judges." ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
clean_judge_nameprogram_typepoints_vs_avg
0Adriana DOMANSKAfree1.944444
1Adriana DOMANSKAshort0.452632
2Agita ABELEfree1.068632
3Agita ABELEshort0.928748
4Agnieszka SWIDERSKAshort1.217361
\n", "
" ], "text/plain": [ " clean_judge_name program_type points_vs_avg\n", "0 Adriana DOMANSKA free 1.944444\n", "1 Adriana DOMANSKA short 0.452632\n", "2 Agita ABELE free 1.068632\n", "3 Agita ABELE short 0.928748\n", "4 Agnieszka SWIDERSKA short 1.217361" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "judge_means = judge_points.groupby([\"clean_judge_name\", \"program_type\"])\\\n", " [\"points_vs_avg\"].mean()\\\n", " .to_frame()\\\n", " .reset_index()\n", "\n", "judge_means.head()" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "collapsed": true }, "outputs": [], "source": [ "judge_points_with_means = pd.merge(\n", " judge_points,\n", " judge_means,\n", " on = [ \"clean_judge_name\", \"program_type\" ],\n", " how = \"left\",\n", " suffixes = [ \"_overall\", \"_mean\" ]\n", ")" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
performance_idjudgeavg_without_judgefinal_scorepoints_vs_avg_overallpoints_vs_avg_meanpoints_vs_avg_adj
00055dd827dJ1179.8675176.58-3.2875-0.058263-3.229237
10055dd827dJ2180.1550174.28-5.87500.976538-6.851538
20055dd827dJ3178.7050185.887.17501.1039226.071078
30055dd827dJ4178.9675183.784.81251.7676143.044886
40055dd827dJ5179.6550178.28-1.37500.547807-1.922807
\n", "
" ], "text/plain": [ " performance_id judge avg_without_judge final_score points_vs_avg_overall \\\n", "0 0055dd827d J1 179.8675 176.58 -3.2875 \n", "1 0055dd827d J2 180.1550 174.28 -5.8750 \n", "2 0055dd827d J3 178.7050 185.88 7.1750 \n", "3 0055dd827d J4 178.9675 183.78 4.8125 \n", "4 0055dd827d J5 179.6550 178.28 -1.3750 \n", "\n", " points_vs_avg_mean points_vs_avg_adj \n", "0 -0.058263 -3.229237 \n", "1 0.976538 -6.851538 \n", "2 1.103922 6.071078 \n", "3 1.767614 3.044886 \n", "4 0.547807 -1.922807 " ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "judge_points_with_means[\"points_vs_avg_adj\"] = \\\n", " judge_points_with_means[\"points_vs_avg_overall\"] - \\\n", " judge_points_with_means[\"points_vs_avg_mean\"]\n", " \n", "judge_points_with_means[[\n", " \"performance_id\",\n", " \"judge\",\n", " \"avg_without_judge\",\n", " \"final_score\",\n", " \"points_vs_avg_overall\",\n", " \"points_vs_avg_mean\",\n", " \"points_vs_avg_adj\"\n", " \n", "]].head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Calculate Overall Home-Country Preference\n", "\n", "To examine whether an overall home-country preference exists in figure skating, we compare the scores given by judges to skaters from their own country to those they give skaters from other countries. Then we use a t-test to determine whether this difference is statistically significant. (It is.) Finally, we then show this preference graphically." ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False 13375\n", "True 1305\n", "Name: skater_judge_same_country, dtype: int64" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "judge_points_with_means[\"skater_judge_same_country\"].value_counts()" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "- Same-country point difference: 3.088\n", "- Other-country point difference: -0.301\n", "- Overall same-country preference: 3.4\n" ] } ], "source": [ "overall_point_diffs = judge_points_with_means\\\n", " .groupby(\"skater_judge_same_country\")[\"points_vs_avg_adj\"]\\\n", " .mean()\n", "\n", "print((\n", " \"- Same-country point difference: {:.3f}\\n\"\n", " \"- Other-country point difference: {:.3f}\\n\"\n", " \"- Overall same-country preference: {:.1f}\"\n", ").format(\n", " overall_point_diffs[True],\n", " overall_point_diffs[False],\n", " overall_point_diffs[True] - overall_point_diffs[False]\n", "))" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Ttest_indResult(statistic=37.859765344104062, pvalue=5.1762242757333122e-225)" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "stats.ttest_ind(\n", " judge_points_with_means[\n", " judge_points_with_means[\"skater_judge_same_country\"]\n", " ][\"points_vs_avg_adj\"],\n", " \n", " judge_points_with_means[\n", " ~judge_points_with_means[\"skater_judge_same_country\"]\n", " ][\"points_vs_avg_adj\"],\n", " \n", " equal_var = False\n", ")" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAa0AAAENCAYAAAC8SjrZAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3XuclWW99/HPlwHRLZ4SJAwDTJxA0FFHQs0cMg8lilF7\nC2qAmUiK7azX3spOt5T5PO6yLJOtkSm6U8itecj0SVHHs8nBSUFEUDGkERRNGQ8o8Hv+uO8ZFzgD\ns2bWmrXu4ft+vdaLdV/rPvyuOf24rvu6r0sRgZmZWRZ0KXUAZmZmreWkZWZmmeGkZWZmmeGkZWZm\nmeGkZWZmmeGkZWZmmeGkZWZmmeGkZWZmmeGkZWZmmdG11AF0hJ49e0b//v3bfPw777zD9ttvX7iA\nyojrlk2uWza5bi2bN2/e6xHRa0v7bRVJq3///sydO7fNx9fW1lJTU1O4gMqI65ZNrls2uW4tk/Ry\na/Zz96CZmWWGk5aZmWWGk5aZmWXGVnFPy8yyQxIvvfQS77//fqlDKbiddtqJRYsWlTqMomht3bbd\ndlv69u1Lt27d2nQdJy0zKyvbb789O+ywA/3790dSqcMpqDVr1rDDDjuUOoyiaE3dIoLVq1fzyiuv\nMGDAgDZdx92DZlZWKioq2HXXXTtdwrKkFb3rrru2qxXtpGVmZccJq/Nq7/fWScvMzDLD97TMrLxN\nndrh56uoqGDo0KF8+OGHdO3alXHjxnHOOefQpUsX5s6dy/XXX8/ll1/O2rVrOfbYY3n99deZMmUK\nu+++O5MmTaJbt248/vjjbLfddoWNPVVbW8s222zDIYccUpTzb86yZct47LHHOOmkkzr82uCkZVY+\n8vnj3ElnVSgX2223HXV1dQCsWrWKk046ibfffpsf/vCHVFdXU11dDcBTTz0F0LTvpEmTmDJlCqec\nckqrrhMRRARduuTX6VVbW0uPHj1KlrRuvPHGZpPWunXr6Nq1uGnF3YNmZpux2267MX36dK644goi\ngtraWkaOHMmqVas45ZRTmDNnDlVVVfz617/mpptu4oILLuDkk08G4Kc//SkHHXQQ++67LxdeeCGQ\n/NGvrKxk3LhxDBkyhOXLl3PPPfdw8MEHc8ABB/DP//zPNDQ0AMkUdBdeeCEHHHAAQ4cO5bnnnmPZ\nsmVcddVVXHbZZVRVVfHwww9vFG9DQwOnnnoqQ4cOZd999+WWW24BYObMmQwdOpQhQ4Zw7rnnNu3f\no0ePpvc333wzEyZMAGDChAl85zvf4ZBDDmHPPffk5ptvBuC8887j4Ycfpqqqissuu4wZM2Zw/PHH\nM3LkSI444gjGjRvHbbfd1nTOk08+mdtvv71g3w8nLTOzLdhzzz1Zv349q1atairbbbfduPrqqzns\nsMOoq6vjjDPO4Pjjj+enP/0pN9xwA/fccw9LlizhySefpK6ujnnz5vHoo48CsGTJEs4880wWLlzI\n9ttvz49//GNmz57N/Pnzqa6u5uc//3nTdXr27Mn8+fP59re/zaWXXkr//v2ZNGkS55xzDnV1dRx2\n2GEbxXrRRRex00478cwzz/D000/zxS9+kb///e+ce+653H///dTV1TFnzpyNEktL6uvreeSRR7jz\nzjs577zzALjkkkua6nzOOecAMH/+fK6//noefPBBTjvtNGbMmAHAW2+9xWOPPcaxxx7brq9/Lict\nM7MiuOeee7jnnnvYf//9OeCAA3juued44YUXAOjXrx/Dhw8H4IknnuDZZ5/l0EMPpaqqiuuuu46X\nX/5o7tjRo0cDcOCBB7Js2bItXnf27NmcddZZTdu77LILc+bMoaamhl69etG1a1dOPvlkHnrooS2e\n64QTTqBLly4MHjyYlStXtrjfkUceySc+8QkADj/8cJYsWcJrr73GzJkz+drXvlbQLkPf0zIz24IX\nX3yRiooKdtttt1bPaBERTJkyhTPOOKOpbM2aNaxevXqjJTwigiOPPJKZM2c2e57u3bsDyeCQdevW\ntaMWzcsdgr7p81ON126MsyWbLkkybtw4fve73zFr1iyuvfbaAkWacEvLzGwzXnvtNSZNmsTkyZPz\nesbo6KOP5pprrmm6P7VixQpee+21j+03fPhwHn30UZYuXQok61I9//zzmz33DjvswJo1a5r97Mgj\nj2TatGlN22+++SbDhg3jwQcf5PXXX2f9+vXMnDmTww8/HIDevXuzaNEiNmzYwK233rrFem3u2o0m\nTJjAL37xCwAGDx68xXPmwy0tMytvhR7y3grvvfceVVVVTUPev/GNb/C9730vr3McddRRLFq0iIMP\nPhhIBjxcddVV7LTTThvt16tXL2bMmMHYsWNZu3YtAD/+8Y/Ze++9Wzz3cccdx9e//nVuv/12fvWr\nX210X+v888/nrLPOYsiQIVRUVHDhhRcyevRoLrnkEkaMGEFEcOyxxzJq1CgguUc1cuRIevXqRXV1\n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\na9Xe762TlpmVlfXr17N69Wonrk4oIli9ejXbbrttm8/h7kEzKyvvvPMOa9as4bXXXit1KAX3/vvv\nt+sPdjlrbd223XZb+vbtu8X9WuKkZWZlJSIYMGBAqcMoitra2k47MrKj6ubuQTMzywwnLTMzywwn\nLTMzywwnLTMzywwnLTMzywwnLTMzywwnLTMzywwnLTMzywwnLTMzy4wOSVqSrpG0StKCnLKpklZI\nqktfX8n5bIqkpZIWSzo6p/yYtGyppPM6InYzMysfHdXSmgEc00z5ZRFRlb7uApA0GBgD7JMe89+S\nKiRVANOALwODgbHpvmZmtpXokLkHI+IhSf1bufsoYFZErAVekrQUGJZ+tjQiXgSQNCvd99kCh2tm\nZmWq1BPmTpY0DpgLfD8i3gQ+BTyRs88raRnA8k3KP9chUZplWT4LUXrRSitzpUxaVwIXAZH++zPg\nm4U6uaSJwESA3r17U1tb2+ZzNTQ0tOv4cua6FVllZVFO29C9O7XFOHepv16UyfetSFy39itZ0oqI\nlY3vJf0GuDPdXAHskbNr37SMzZQ3d/7pwHSA6urqqKmpaXOstbW1tOf4cua6FVmRWi61lZXULF5c\n+BOPHVv4c+apLL5vReK6tV/JhrxL6pOz+VWgcWThHcAYSd0lDQAGAk8Cc4CBkgZI2oZksMYdHRmz\nmZmVVoe0tCTNBGqAnpJeAS4EaiRVkXQPLgPOAIiIhZJuIhlgsQ44KyLWp+eZDPwZqACuiYiFHRG/\nmZmVh44aPdhcn8NvN7P/xcDFzZTfBdxVwNDMzCxDPCOGmZllhpOWmZllhpOWmZllhpOWmZllhpOW\nmZllhpOWmZllhpOWmZllhpOWmZllhpOWmZllhpOWmZllhpOWmZllhpOWmZllhpOWmZllhpOWmZll\nhpOWmZllhpOWmZllhpOWmZllRoesXGzWqUydWuoIzLZabmmZmVlmdEjSknSNpFWSFuSU/VTSc5Ke\nlnSrpJ3T8v6S3pNUl76uyjnmQEnPSFoq6XJJ6oj4zcysPHRUS2sGcMwmZfcCQyJiX+B5YErOZy9E\nRFX6mpRTfiVwOjAwfW16TjMz68Q6JGlFxEPAG5uU3RMR69LNJ4C+mzuHpD7AjhHxREQEcD1wQjHi\nNTOz8qTk738HXEjqD9wZEUOa+eyPwO8j4nfpfgtJWl9vA+dHxMOSqoFLIuJL6TGHAedGxMgWrjcR\n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\nYII=\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "judge_points_with_means[\n", " ~judge_points_with_means[\"skater_judge_same_country\"]\n", "][\"points_vs_avg_adj\"].hist(\n", " color = \"red\", \n", " alpha = 0.5,\n", " bins = 30,\n", " range = (-15, 15),\n", " label = \"Different country\",\n", " figsize = (6.5, 4)\n", ")\n", " \n", "judge_points_with_means[\n", " judge_points_with_means[\"skater_judge_same_country\"]\n", "][\"points_vs_avg_adj\"].hist(\n", " color = \"blue\", \n", " alpha = 1,\n", " bins = 30,\n", " range = (-15, 15),\n", " label = \"Same country\"\n", ")\n", " \n", "matplotlib.pyplot.legend(loc = \"upper right\")\n", "matplotlib.pyplot.xlabel(\n", " \"Adj. Points vs. Avg.\",\n", " fontsize = 12\n", ")\n", "\n", "matplotlib.pyplot.ylabel(\n", " \"Frequency\",\n", " fontsize = 12\n", ")\n", "pass" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Calculate Preference by Program Type" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
skater_judge_same_countryFalseTruepreference
program
ICE DANCE FREE DANCE-0.3382884.4202234.758511
MEN FREE SKATING-0.5899904.0590684.649057
PAIRS FREE SKATING-0.2257473.8703664.096113
LADIES FREE SKATING-0.3792003.5368313.916031
ICE DANCE SHORT DANCE-0.2473232.6592542.906576
PAIRS SHORT PROGRAM-0.2318202.3334222.565242
MEN SHORT PROGRAM-0.1820662.0483382.230404
LADIES SHORT PROGRAM-0.2048282.0081692.212998
\n", "
" ], "text/plain": [ "skater_judge_same_country False True preference\n", "program \n", "ICE DANCE FREE DANCE -0.338288 4.420223 4.758511\n", "MEN FREE SKATING -0.589990 4.059068 4.649057\n", "PAIRS FREE SKATING -0.225747 3.870366 4.096113\n", "LADIES FREE SKATING -0.379200 3.536831 3.916031\n", "ICE DANCE SHORT DANCE -0.247323 2.659254 2.906576\n", "PAIRS SHORT PROGRAM -0.231820 2.333422 2.565242\n", "MEN SHORT PROGRAM -0.182066 2.048338 2.230404\n", "LADIES SHORT PROGRAM -0.204828 2.008169 2.212998" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "preference_by_program = judge_points_with_means\\\n", " .groupby([\"program\", \"skater_judge_same_country\"])[\"points_vs_avg_adj\"]\\\n", " .mean()\\\n", " .unstack()\n", " \n", "preference_by_program[\"preference\"] = preference_by_program[True] - \\\n", " preference_by_program[False]\n", "\n", "preference_by_program.sort_values(\"preference\", ascending=False)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Calculate Preference by Country\n", "\n", "This analysis repeats the approach above to calculate home-country preference on a per-country basis. The results are limited to countries with at least 50 home-country judgments in the dataset." ] }, { "cell_type": "code", "execution_count": 38, "metadata": { "collapsed": true }, "outputs": [], "source": [ "country_grps = judge_points_with_means.groupby(\"judge_country\")" ] }, { "cell_type": "code", "execution_count": 39, "metadata": { "collapsed": true }, "outputs": [], "source": [ "country_df = pd.DataFrame({\n", " \"total_performances\": country_grps.size(),\n", " \n", " \"same_performances\": country_grps.apply(lambda x: len(x[x[\"skater_judge_same_country\"]])),\n", " \n", " \"avg_null_preference\": country_grps.apply(lambda x: x[\n", " ~x[\"skater_judge_same_country\"]\n", " ][\"points_vs_avg_adj\"].mean()),\n", " \n", " \"avg_same_preference\": country_grps.apply(lambda x: x[\n", " x[\"skater_judge_same_country\"]\n", " ][\"points_vs_avg_adj\"].mean())\n", "})" ] }, { "cell_type": "code", "execution_count": 40, "metadata": { "collapsed": true }, "outputs": [], "source": [ "country_df[\"preference\"] = round(country_df[\"avg_same_preference\"] - country_df[\"avg_null_preference\"], 2)" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
avg_null_preferenceavg_same_preferencesame_performancestotal_performancespreference
judge_country
CHN-0.5835264.0051071108654.59
ITA-0.3132153.829301628204.14
RUS-0.6975273.24998122612793.95
USA-0.6340522.85738622912613.49
CAN-0.4783102.99686917712863.48
FRA-0.2779912.381595676412.66
JPN-0.3298392.03064214710522.36
\n", "
" ], "text/plain": [ " avg_null_preference avg_same_preference same_performances \\\n", "judge_country \n", "CHN -0.583526 4.005107 110 \n", "ITA -0.313215 3.829301 62 \n", "RUS -0.697527 3.249981 226 \n", "USA -0.634052 2.857386 229 \n", "CAN -0.478310 2.996869 177 \n", "FRA -0.277991 2.381595 67 \n", "JPN -0.329839 2.030642 147 \n", "\n", " total_performances preference \n", "judge_country \n", "CHN 865 4.59 \n", "ITA 820 4.14 \n", "RUS 1279 3.95 \n", "USA 1261 3.49 \n", "CAN 1286 3.48 \n", "FRA 641 2.66 \n", "JPN 1052 2.36 " ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "country_df[\n", " country_df[\"same_performances\"] >= 50\n", "].sort_values(\"preference\", ascending=False)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Analyze Preferences of Individual Judges\n", "\n", "Some judges have only a handful of instances where they judge skaters from their same country. This fact could skew the t-test calculation, so instead here we use statistical simulations to quantify the probability of a judge showing as much home-country preference as we see in the data.\n", "\n", "To perform those simulations, we calculate the judge's actual home-country preference and then compare it to the home-country preferences derived by assigning all of the judge's score differences to home-country or non-home-country skaters at random. For each judge, we repeat the simulation 1 million times, and then check how often the simulated scoring preference equals or exceeds the actual home-country preference. This provides an estimated probability of such home-country preference (or stronger) occurring by chance alone." ] }, { "cell_type": "code", "execution_count": 42, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import random\n", "import numpy as np" ] }, { "cell_type": "code", "execution_count": 43, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def shuffle_and_find_diff_by_program_length(\n", " score_diffs_short, \n", " score_diffs_free, \n", " count_same_country_short, \n", " count_same_country_free):\n", " random.shuffle(score_diffs_short)\n", " random.shuffle(score_diffs_free)\n", " same_country_diffs = score_diffs_short[:count_same_country_short] + \\\n", " score_diffs_free[:count_same_country_free]\n", " other_country_diffs = score_diffs_short[count_same_country_short:] + \\\n", " score_diffs_free[count_same_country_free:]\n", " return np.mean(same_country_diffs) - np.mean(other_country_diffs)" ] }, { "cell_type": "code", "execution_count": 44, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def find_judge_prob(row, runs=1000000):\n", " if row[\"num_same_as_skater\"] == 0:\n", " return None\n", " else:\n", " score_diffs_short = list(judge_points[\n", " (judge_points[\"clean_judge_name\"] == row[\"clean_judge_name\"]) &\n", " (judge_points[\"program_type\"] == \"short\")\n", " ][\"points_vs_avg\"])\n", " score_diffs_free = list(judge_points[\n", " (judge_points[\"clean_judge_name\"] == row[\"clean_judge_name\"]) &\n", " (judge_points[\"program_type\"] == \"free\")\n", " ][\"points_vs_avg\"])\n", " overall_preference = row[\"avg_same_preference\"] - row[\"avg_null_preference\"]\n", " calc_prefs = [ shuffle_and_find_diff_by_program_length(\n", " score_diffs_short, \n", " score_diffs_free, \n", " int(row[\"num_same_as_skater_short\"]), \n", " int(row[\"num_same_as_skater_free\"])) \n", " for i in range(runs) ]\n", " return len([ cb for cb in calc_prefs if cb >= overall_preference ]) / runs" ] }, { "cell_type": "code", "execution_count": 45, "metadata": { "collapsed": true }, "outputs": [], "source": [ "judge_grps = judge_points.groupby([\"clean_judge_name\"])" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "214" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "len(judge_grps)" ] }, { "cell_type": "code", "execution_count": 47, "metadata": { "collapsed": true }, "outputs": [], "source": [ "judged_by_judge = pd.DataFrame({\n", " \"country\": judge_grps[\"judge_country\"].first(),\n", " \n", " \"total\": judge_grps.size(),\n", " \n", " \"num_same_as_skater\": judge_grps[\"skater_judge_same_country\"].sum(),\n", " \n", " \"num_same_as_skater_short\": judge_grps\\\n", " .apply(lambda x: x[\n", " x[\"program_type\"] == \"short\"\n", " ][\"skater_judge_same_country\"].sum()),\n", " \n", " \"num_same_as_skater_free\": judge_grps\\\n", " .apply(lambda x: x[\n", " x[\"program_type\"] == \"free\"\n", " ][\"skater_judge_same_country\"].sum()),\n", " \n", " \"avg_same_preference\": judge_grps.apply(lambda x: x[\n", " x[\"skater_judge_same_country\"]\n", " ][\"points_vs_avg\"].mean()),\n", " \n", " \"avg_null_preference\": judge_grps.apply(lambda x: x[\n", " ~x[\"skater_judge_same_country\"]\n", " ][\"points_vs_avg\"].mean())\n", "}).reset_index()" ] }, { "cell_type": "code", "execution_count": 48, "metadata": { "collapsed": true }, "outputs": [], "source": [ "judged_by_judge[\"bootstrapped\"] = judged_by_judge.apply(find_judge_prob, axis=1)" ] }, { "cell_type": "code", "execution_count": 49, "metadata": { "collapsed": true }, "outputs": [], "source": [ "judged_by_judge[\"preference\"] = round(judged_by_judge[\"avg_same_preference\"] - \\\n", " judged_by_judge[\"avg_null_preference\"], 3)" ] }, { "cell_type": "code", "execution_count": 50, "metadata": { "collapsed": true }, "outputs": [], "source": [ "low_prob_judges = judged_by_judge[\n", " # We are using a conservative cutoff and looking for \n", " # judges with a probability of less than 1 in 100,000\n", " (judged_by_judge[\"bootstrapped\"] < 0.00001)\n", "]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Important Note:**\n", "\n", "Higher home-country scores do not in and of themselves show a judge is deliberately trying to raise a compatriot’s standing; the scores could reflect a preference for a regional style of skating, for example, or an inclination toward skaters the judge has taken special note of, or even just patriotism. Judges might not even be aware that they consistently up-score their compatriots.\n", "\n", "BuzzFeed News reached out to all 27 judges below for comment through their national federations, as well as to the individual judges themselves by phone, email, Facebook, or messages left at work. The US and Chinese skating federations declined to comment.\n", "\n", "Most of the judges either did not respond to messages or chose not to speak on the record. Two judges did provide comment:\n", "\n", "- Walter Toigo told BuzzFeed News, “Everybody has a different opinion and we judge what we can see.\" He added, \"We are human beings, not machines. I judge what I think. I try to be consistent with all the skaters.”\n", "\n", "- Igor Dolgushin told BuzzFeed News, “I'm a judge and signed the Ethics Code for Judges, and I judge fairly and adequately in all tournaments.”\n", "\n", "In an email, a spokesperson for Skate Canada told BuzzFeed News that “all of the Canadian judges submitted to the ISU for the PyeongChang 2018 Olympic Winter Games meet the eligibility criteria, and were approved as judges by the ISU, according to its rules and regulations.” A representative of the Figure Skating Federation of Russia declined to answer questions and said, “None of our judges want to comment.”" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
clean_judge_nameavg_null_preferenceavg_same_preferencecountrynum_same_as_skaternum_same_as_skater_freenum_same_as_skater_shorttotalbootstrappedpreference
202Walter TOIGO-2.5480904.947917ITA6.0331140.0000007.496
83Jeff LUKASIK-2.0726794.982031CAN16.0971210.0000007.055
19Anna KANTOR-0.9357755.795139ISR9.0452300.0000006.731
15Andrea DERBY-2.0187504.251250CAN10.055500.0000006.270
9Alexei BELETSKI-0.0915586.149219ISR8.0441620.0000016.241
33Cynthia BENSON-2.2771383.907292CAN12.066880.0000006.184
187Tanay OZKAN0.2843586.362500TUR9.0451880.0000006.078
73Igor DOLGUSHIN0.5214126.306250RUS12.066660.0000005.785
205Weiguang CHEN-0.6095475.152841CHN22.011112040.0000005.762
79Isabella MICHELI-1.1243514.548611ITA9.045860.0000005.673
61Feng HUANG-0.3344545.256250CHN12.0661700.0000005.591
193Tianyi ZHANG-2.2697123.044063CHN20.01010980.0000005.314
211Yuri GUSKOV0.6273205.871875KAZ10.0552040.0000005.245
132Marta OLOZAGARRE0.3239305.386607ESP7.0342290.0000045.063
68Guangying QIN-0.4295084.388393CHN14.077750.0000004.818
172Sharon ROGERS-2.2100002.583594USA32.016161620.0000004.794
189Tatiana SHARKINA0.6074654.833333RUS12.066480.0000004.226
124Maira ABASOVA-0.8714753.153795RUS28.014142000.0000004.025
170Saodat NUMANOVA1.1296695.124306UZB9.0452580.0000043.995
148Olga KOZHEMIAKINA-1.6258842.345466RUS51.025262560.0000003.971
50Elena FOMINA-0.3139563.569688RUS40.020202160.0000003.884
75Igor OBRAZTSOV-0.4248703.441319RUS18.0991140.0000013.866
146Nicole LEBLANC-RICHARD-0.2546883.503977CAN22.011111460.0000003.759
157Richard DALLEY-0.1127163.569712USA26.01313840.0000003.682
92Julia ANDREEVA0.1974303.843750RUS30.015151370.0000003.646
121Lorrie PARKER1.1178574.615417USA30.015151980.0000013.498
118Lolita LABUNSKAIYA0.7871654.203472RUS18.0991300.0000003.416
\n", "
" ], "text/plain": [ " clean_judge_name avg_null_preference avg_same_preference country \\\n", "202 Walter TOIGO -2.548090 4.947917 ITA \n", "83 Jeff LUKASIK -2.072679 4.982031 CAN \n", "19 Anna KANTOR -0.935775 5.795139 ISR \n", "15 Andrea DERBY -2.018750 4.251250 CAN \n", "9 Alexei BELETSKI -0.091558 6.149219 ISR \n", "33 Cynthia BENSON -2.277138 3.907292 CAN \n", "187 Tanay OZKAN 0.284358 6.362500 TUR \n", "73 Igor DOLGUSHIN 0.521412 6.306250 RUS \n", "205 Weiguang CHEN -0.609547 5.152841 CHN \n", "79 Isabella MICHELI -1.124351 4.548611 ITA \n", "61 Feng HUANG -0.334454 5.256250 CHN \n", "193 Tianyi ZHANG -2.269712 3.044063 CHN \n", "211 Yuri GUSKOV 0.627320 5.871875 KAZ \n", "132 Marta OLOZAGARRE 0.323930 5.386607 ESP \n", "68 Guangying QIN -0.429508 4.388393 CHN \n", "172 Sharon ROGERS -2.210000 2.583594 USA \n", "189 Tatiana SHARKINA 0.607465 4.833333 RUS \n", "124 Maira ABASOVA -0.871475 3.153795 RUS \n", "170 Saodat NUMANOVA 1.129669 5.124306 UZB \n", "148 Olga KOZHEMIAKINA -1.625884 2.345466 RUS \n", "50 Elena FOMINA -0.313956 3.569688 RUS \n", "75 Igor OBRAZTSOV -0.424870 3.441319 RUS \n", "146 Nicole LEBLANC-RICHARD -0.254688 3.503977 CAN \n", "157 Richard DALLEY -0.112716 3.569712 USA \n", "92 Julia ANDREEVA 0.197430 3.843750 RUS \n", "121 Lorrie PARKER 1.117857 4.615417 USA \n", "118 Lolita LABUNSKAIYA 0.787165 4.203472 RUS \n", "\n", " num_same_as_skater num_same_as_skater_free num_same_as_skater_short \\\n", "202 6.0 3 3 \n", "83 16.0 9 7 \n", "19 9.0 4 5 \n", "15 10.0 5 5 \n", "9 8.0 4 4 \n", "33 12.0 6 6 \n", "187 9.0 4 5 \n", "73 12.0 6 6 \n", "205 22.0 11 11 \n", "79 9.0 4 5 \n", "61 12.0 6 6 \n", "193 20.0 10 10 \n", "211 10.0 5 5 \n", "132 7.0 3 4 \n", "68 14.0 7 7 \n", "172 32.0 16 16 \n", "189 12.0 6 6 \n", "124 28.0 14 14 \n", "170 9.0 4 5 \n", "148 51.0 25 26 \n", "50 40.0 20 20 \n", "75 18.0 9 9 \n", "146 22.0 11 11 \n", "157 26.0 13 13 \n", "92 30.0 15 15 \n", "121 30.0 15 15 \n", "118 18.0 9 9 \n", "\n", " total bootstrapped preference \n", "202 114 0.000000 7.496 \n", "83 121 0.000000 7.055 \n", "19 230 0.000000 6.731 \n", "15 50 0.000000 6.270 \n", "9 162 0.000001 6.241 \n", "33 88 0.000000 6.184 \n", "187 188 0.000000 6.078 \n", "73 66 0.000000 5.785 \n", "205 204 0.000000 5.762 \n", "79 86 0.000000 5.673 \n", "61 170 0.000000 5.591 \n", "193 98 0.000000 5.314 \n", "211 204 0.000000 5.245 \n", "132 229 0.000004 5.063 \n", "68 75 0.000000 4.818 \n", "172 162 0.000000 4.794 \n", "189 48 0.000000 4.226 \n", "124 200 0.000000 4.025 \n", "170 258 0.000004 3.995 \n", "148 256 0.000000 3.971 \n", "50 216 0.000000 3.884 \n", "75 114 0.000001 3.866 \n", "146 146 0.000000 3.759 \n", "157 84 0.000000 3.682 \n", "92 137 0.000000 3.646 \n", "121 198 0.000001 3.498 \n", "118 130 0.000000 3.416 " ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "low_prob_judges.sort_values([\"preference\"], ascending=False)" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "---\n", "\n", "---\n", "\n", "---" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "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.0" } }, "nbformat": 4, "nbformat_minor": 2 }