{"id":56,"date":"2024-09-10T14:10:43","date_gmt":"2024-09-10T14:10:43","guid":{"rendered":"https:\/\/www.mhtechin.com\/news\/?p=56"},"modified":"2024-09-10T14:10:43","modified_gmt":"2024-09-10T14:10:43","slug":"coding-a-high-school-fantasy-football-league-draft-simulator-using-ml-and-python","status":"publish","type":"post","link":"https:\/\/www.mhtechin.com\/news\/coding-a-high-school-fantasy-football-league-draft-simulator-using-ml-and-python\/","title":{"rendered":"Coding a High School Fantasy Football League\/Draft Simulator using ML and Python"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\" id=\"5f79\"><strong>Overview<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"4438\">Around 42 million people play fantasy football every fall, hoping to outsmart their friends and family and win a coveted fantasy championship. Fantasy football usually uses stats from the NFL, the highest level of football play in the world. As a result, college and high school level football are rarely included in fantasy football apps like ESPN and Sleeper. So, being a high-school football fanatic, I decided to create a fantasy football \u201capp\u201d using stats from my high-school\u2019s league. This article will detail my process in creating the app, my challenges, and my sources.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ba9f\">Background<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"1c45\">Most fantasy apps create their own rankings using previous player performances and free agency. Once these rankings are released, teams will draft a quarterback, running-back, wide-receiver, tight-end, kicker, a defense, and multiple bench players. When the draft finishes, each team will receive a draft grade. Draft grades vary based on the fantasy app but they all use their projected rankings in their calculations. Once a grade is given, players will use that information to better their team by trading and picking up new players in free agency.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:560\/1*HDNaV__fqxRdl_aWRnIAaQ.jpeg\" alt=\"\"\/><figcaption class=\"wp-element-caption\">Yahoo Sports Draft Grade<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"caf3\">My Plan<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Predict fantasy performance of the players using training data from the NFL<\/li>\n\n\n\n<li>Create my own system of ranking players using prediction and position value<\/li>\n\n\n\n<li>Find a way to grade the draft picks<\/li>\n\n\n\n<li>Create a draft simulator<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"3c40\">The Prediction<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"6431\"><strong>Advice<\/strong>: Predicting NFL player performance is a much easier starting project(I recommend it). With hundreds of datasets and analysis, NFL ML projects can be easier to code and there\u2019s less of a hassle with formatting data.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"ec65\">Now, let\u2019s get into the good stuff.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"a875\">When I was beginning this project, I found enough data to create a list of draftable players but not enough to predict player performance. So, I decided to use NFL data instead to train my model. Thanks to&nbsp;<a href=\"https:\/\/github.com\/bpabraham123\" rel=\"noreferrer noopener\" target=\"_blank\">Benjamin Abraham<\/a>\u2019s&nbsp;<a href=\"https:\/\/github.com\/bpabraham123\/FantasyFootball21-22\" rel=\"noreferrer noopener\" target=\"_blank\">fantasy football project<\/a>, I was able to collect data from the last 10 years and create a model of 66% testing-accuracy using a simple linear regression. However, I found the accuracy to be too low so I decided to make some changes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"56f7\">My first change was to remove the age parameter, which I considered unrelated to my current goal. Age matters a lot in the NFL because as you get older, your body deteriorates which then hurts your performance. At the high school level, all the players are relatively young and have had less injuries than their NFL counterparts. As a result, I removed age from my list of parameters for all positions.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">#removed age parameter <br>if position == 'QB':<br>        X = df[['PassAtt\/G','PassYds\/G', 'PassTD\/G', 'RushAtt\/G', 'Y\/A','RushYds\/G','RushTD\/G', 'TotTD\/G','PPG','VBD']]    elif position == 'RB':<br>        X = df[['RushAtt\/G', 'Y\/A','RushYds\/G', 'RushTD\/G','Rec\/G','RecYds\/G','Y\/R','RecTD\/G','TotTD\/G','PPG','VBD']]<br>    elif position == 'WR' or 'TE':<br>        X = df[['Rec\/G','RecYds\/G','Y\/R', 'RecTD\/G','TotTD\/G','PPG','VBD']]<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"c829\">Creating a Ranking System<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"040e\">You might have a few questions at this point regarding the need of a ranking system. Well, it all comes down to availability and positional value. In fantasy football, each position has a different value. Usually, WRs and RBs have more value than QBs and TEs due to their ability to catch the ball reliably. In conjunction with that, there are less high scoring RBs and WRs than QBs, a low supply but a high demand. As a result, running-backs and wide-receivers should have a higher value then other positions. This idea is known as biased draft value.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"6d1b\">VBD<\/h2>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:560\/1*sj6kz4AtXLfcTjuOi06Fxw.jpeg\" alt=\"\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"c829\">Draft Simulator<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"98c3\">For the simulator, I had to store and update each team regularly so I decided to use csv files. Because there are 8 teams, I had to create 8 separate csv files with the headers: Position, Name, VBD, and Score.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Position,Name,VBD,Score<br>QB,,,<br>RB,,,<br>WR,,,<br>TE,,,<br>FLEX,,,<br>K,,,<br>DST,,,<br>Bench1,,,<br>Bench2,,,<br>Bench3,,,<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"446f\">Using pandas and the .read_csv function, I stored the csv data in a dataframe, making it easier for data manipulation. Then, each team has its own function, taking in 3 inputs: Position, Name, and VBD. I then add the inputs into the csv and save it. So, if the program crashes in the middle of the draft, all the data will be saved. After the csv is updated with the draft pick, using the draft analysis algorithm, the script calculates the draft score and saves it in the score column.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">def t1():<br>  position = input(\"Enter position: \")<br>  name = input(\"Enter name: \")<br>  vbd = float(input(\"Enter VBD: \"))<br>  df_t1.loc[position, 'Name'] = name<br>  df_t1.loc[position, 'VBD'] = vbd<br>  df_t1.to_csv('t1.csv')<br>  change = calc(count) - vbd<br>  global t1_score<br>  t1_score = t1_score - (4*change)<br>  df_t1.loc['QB','Score'] = t1_score<br>  df_t1.to_csv('t1.csv')<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"23ee\">Then, using two functions called firstround() and secondround(), the simulator imitates the snake draft.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">def firstround():<br>  global count<br>  t1()<br>  count+=1<br>  print(\"------Pick Number: \" + str(count) + \" ------\")<br>  t2()<br>  count+=1<br>  print(\"------Pick Number: \" + str(count) + \" ------\")<br>  t3()<br>  count+=1<br>  print(\"------Pick Number: \" + str(count) + \" ------\")<br>  t4()<br>  count+=1<br>  print(\"------Pick Number: \" + str(count) + \" ------\")<br>  t5()<br>  count+=1<br>  print(\"------Pick Number: \" + str(count) + \" ------\")<br>  t6()<br>  count+=1<br>  print(\"------Pick Number: \" + str(count) + \" ------\")<br>  t7()<br>  print(\"------Pick Number: \" + str(count) + \" ------\")<br>  count+=1<br>  t8()<br>  count+=1def secondround():<br>  global count<br>  print(\"------Pick Number: \" + str(count) + \" ------\")<br>  t8()<br>  count+=1<br>  print(\"------Pick Number: \" + str(count) + \" ------\")<br>  t7()<br>  count+=1<br>  print(\"------Pick Number: \" + str(count) + \" ------\")<br>  t6()<br>  count+=1<br>  print(\"------Pick Number: \" + str(count) + \" ------\")<br>  t5()<br>  count+=1<br>  print(\"------Pick Number: \" + str(count) + \" ------\")<br>  t4()<br>  count+=1<br>  print(\"------Pick Number: \" + str(count) + \" ------\")<br>  t3()<br>  count+=1<br>  print(\"------Pick Number: \" + str(count) + \" ------\")<br>  t2()<br>  count+=1 <br>  print(\"------Pick Number: \" + str(count) + \" ------\")<br>  t1()<br>  count+=1<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"9cab\">Takeaways<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"d28f\">Even though I had to gather and format the data for quite some time, I had a great time working on this project. I learned a lot about building models and creating new tools for data analysis using python.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/github.com\/SreekarKutagulla\/WCAL_FantasyFootball\/tree\/main?source=post_page-----500bad3af450--------------------------------\" rel=\"noreferrer noopener\" target=\"_blank\"><\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><a href=\"https:\/\/github.com\/SreekarKutagulla\/WCAL_FantasyFootball\/tree\/main?source=post_page-----500bad3af450--------------------------------\" rel=\"noreferrer noopener\" target=\"_blank\">GitHub &#8211; SreekarKutagulla\/WCAL_FantasyFootball: Fantasy Football for WCAL<\/a><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><a href=\"https:\/\/github.com\/SreekarKutagulla\/WCAL_FantasyFootball\/tree\/main?source=post_page-----500bad3af450--------------------------------\" rel=\"noreferrer noopener\" target=\"_blank\">You can&#8217;t perform that action at this time. You signed in with another tab or window. You signed out in another tab or\u2026<\/a><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/github.com\/SreekarKutagulla\/WCAL_FantasyFootball\/tree\/main?source=post_page-----500bad3af450--------------------------------\" rel=\"noreferrer noopener\" target=\"_blank\">github.com<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"5320\"><em>Hi, my name is Sreekar Kutagulla. I am a 16 year old developer from the Bay Area. Check out my sports analytics work with&nbsp;<\/em><a href=\"https:\/\/www.lanceranalytics.org\/\" rel=\"noreferrer noopener\" target=\"_blank\"><em>Lancer Analytics<\/em><\/a><em>&nbsp;and my&nbsp;<\/em><a href=\"https:\/\/github.com\/SreekarKutagulla\" rel=\"noreferrer noopener\" target=\"_blank\"><em>Github<\/em><\/a><em>. Thanks for reading!<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/medium.com\/tag\/fantasy-football?source=post_page-----500bad3af450---------------fantasy_football-----------------\"><\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/medium.com\/tag\/fantasy-football?source=post_page-----500bad3af450---------------fantasy_football-----------------\">Fantasy Football<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/medium.com\/tag\/machine-learning?source=post_page-----500bad3af450---------------machine_learning-----------------\"><\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/medium.com\/tag\/machine-learning?source=post_page-----500bad3af450---------------machine_learning-----------------\">Machine Learning<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/medium.com\/tag\/data-analysis?source=post_page-----500bad3af450---------------data_analysis-----------------\"><\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"c829\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Overview Around 42 million people play fantasy football every fall, hoping to outsmart their friends and family and win a&hellip;<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-56","post","type-post","status-publish","format-standard","hentry","category-news"],"_links":{"self":[{"href":"https:\/\/www.mhtechin.com\/news\/wp-json\/wp\/v2\/posts\/56","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mhtechin.com\/news\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mhtechin.com\/news\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mhtechin.com\/news\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mhtechin.com\/news\/wp-json\/wp\/v2\/comments?post=56"}],"version-history":[{"count":1,"href":"https:\/\/www.mhtechin.com\/news\/wp-json\/wp\/v2\/posts\/56\/revisions"}],"predecessor-version":[{"id":57,"href":"https:\/\/www.mhtechin.com\/news\/wp-json\/wp\/v2\/posts\/56\/revisions\/57"}],"wp:attachment":[{"href":"https:\/\/www.mhtechin.com\/news\/wp-json\/wp\/v2\/media?parent=56"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mhtechin.com\/news\/wp-json\/wp\/v2\/categories?post=56"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mhtechin.com\/news\/wp-json\/wp\/v2\/tags?post=56"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}