2022 Infield Optimization
What was the best possible fantasy combination of infielders (1B, 2B, SS, 3B) this season? That is an easy question to answer if you use the year-to-date settings on the auction calculator and you simply look at the best player at each position. It would look like this:
1B: Paul Goldschmidt, $33.7
2B: Jose Altuve, $25.2
SS: Trea Turner, $32.5
3B: José Ramírez, $31.2
But, if you were in a 12-team roto snake draft and were able to get both José Ramírez and Trea Turner, you likely played in a league full of clowns. J-Ram’s average draft position (NFBC) was 3.2 while Turner’s was 1.2. It’s unlikely any fantasy teams had both of those top players. So, what was the best possible infield within reasonable ADP? Here’s how I tried to answer this question.
First, I downloaded our auction calculator’s 2022 YTD values. Then, I subset that dataset down to only look at players who returned over $5 in value. This is an arbitrary cut-off but it helps to include players who may have been one-category performers. In addition to this subset, I also remove everything except for ADP and category Z-scores. I tried to maximize the sum of these z-scores rather than dollar values because I wanted to avoid positional adjustments and only focus on producing the best category scores possible. I also took the first position for each player in the dataset and marked that as their position. For example, Bobby Witt Jr. is listed as a 3B/SS, but my process treats him like a 3B. Finally, I randomly select one player at each position and create a team, summing each player’s z-scores by category and I do that 30,000 times. Here’s the python code if you are interested:
import pandas as pd
ytd22 = pd.read_csv('steamerytd22.csv')
opt = ytd22[['Name', 'POS', 'mAVG', 'mRBI', 'mSB', 'mHR', 'mR', 'ADP', 'Dollars']]
opt=opt.loc[opt['Dollars']>5]
opt['POSa'] = opt['POS'].str.split('/').str[0]
infield = opt.loc[opt['POSa'].isin(['1B','2B','3B','SS'])]
team_list=[]
for i in list(range(0,30000)):
first = infield.query('(POSa == "1B")').sample(n=1)
second = infield.query('(POSa == "2B")').sample(n=1)
third = infield.query('(POSa == "3B")').sample(n=1)
ss = infield.query('(POSa == "SS")').sample(n=1)
frames = [first, second, third, ss]
points = sum(pd.concat(frames)[['mAVG', 'mRBI', 'mSB', 'mHR', 'mR']].sum(axis=1))
ADP = pd.concat(frames)['ADP'].to_list()
names = pd.concat(frames)['Name'].to_list()
summary = {'Team':names, 'ADP':ADP, 'Points':points}
team_list.append(summary)
Ready for the results? Here’s the computer program’s best team within a reasonable ADP:
Paul Goldschmidt, 1B
Jose Altuve, 2B
Trea Turner, SS
Manny Machado, 3B
Points: 81.4
In order to achieve this sicko-squad you would have taken Turner first (ADP, 1.2), Machado second (ADP, 22.6), Goldschmidt third (ADP, 47.6), and Altuve fourth (ADP, 74.8). Notice that you would have been making reach picks for both Goldschmidt and Altuve. How sweet it must feel now after listening to your league mate say something like, “Goldschmidt in the third round? Looks like someone didn’t do their homework”. You can now call/text/email/snail-mail that person and let them have it because Goldschmidt ended the year as the number one first baseman by default (12-team) auction calculator settings.
There you have it. That’s my ultimate 2022 fantasy infield. These four players, taken in the first four rounds and accumulating 81.4 z-score points. Can you do better?
Why all the math? You could have done it in your head.
For fun?…I did it for fun.
It seems like the only way this would really work if you were the 1st or 2nd pick and even then you would have to be lucky to have Machado drop to pick 23 or 24. If you were the #2 pick you would likely miss out on Turner and if you are the #1 pick you are likely to miss out on Machado. Is there anywhere you set the draft position?
Enjoy these even though I can never get the python to run.
Does seem like it needs some way to account for draft position and generate exact pick numbers. In a snake draft Machado with an ADP of 22 is unlikely to make it back to pick number 30.
Can you extend this code to generate the most optimal complete offense? The most optimal pitching staff? Most critically the most optimal team overall?
That would be incredibly cool.
Especially if I could get it to run.
Why limit it to the optimal infield OR offense OR pitching? We draft all positions, and we can probably learn something practical when looking at the optimal overall roster, rather than arbitrary segments.
That said, I would wager that the “ideal” overall roster would show that you should have drafted players like Adolis Garcia, Michael Harris, Spencer Strider, Kyle Wright, etc. Unless you’re name is Nostradamus, this obviously isn’t practical, so ideally we’d control for this by limiting our pool of players to those who had an ADP below a certain threshold. I don’t know – fun exercise though.
How about this list of players drafted outside the top 200 on average? Leaves you plenty of space to grab every top pitcher and outfielder before even thinking about your infield.
C: Alejandro Kirk: .285/14/59/63/0
1B: Nathaniel Lowe: .302/27/74/76/2
2B: Brandon Drury: .263/28/87/87/2
SS: Andres Giminez: .295/17/66/69/20
3B: Josh Rojas: .269/9/66/56/23
Heck, in a twelve-teamer, given the ADP, you could have picked Goldy fourth and Altuve seventh and two pitchers and an outfielder along the way.
Your mathematical calculus is but one reason I prefer auction leagues over draft leagues. Much easier to model an obtainable, high-performing infield when that goal is placed in the context of a team budget and all the competing goals that brings.
In a typical auction league, an owner will spend about two-thirds of his budget on 14 hitting slots (and the rest on 9 pitching slots). That works out to just over $173, or a bit more than $12 per hitting slot. In a typical roto lineup with a middle infielder and corner infielder too, that leaves you with $72 for six infield slots.
You then seek out how best you could have spent that cash using pre-season projection models and targeting players who most exceeded their projections with produced value in 2022. Create a spreadsheet that calculates excess values. Write a formula that selects combinations that add up to the projected value (say $70- $75). Then sort those combinations by produced value.