Monthly Archives: August 2012

I Need Your Help!

Last week, I posted an idea about how to evaluate pitching. It would help if you read that first, but not necessary. My question isn’t really about the idea, but how to implement it.

Basically, I want to give fans an opportunity to rate balls in play as they watch games. However, in order for my idea to work, this needs to happen almost immediately after the play is over, or people will forget what happened.

Unfortunately, the game data just doesn’t update fast enough for fans to be able to do this. They would have to wait at least 10-15 seconds, and probably much longer, before they could choose which play to rate. By that time, memories of the play will have been muddled, and the data would be much less valuable.

What this means is that I will need to collect these responses from fans somehow, BEFORE the information about that play (pitcher, batter, inning, base/out state, etc.) is released online. Here are the solutions I can think of so far:

  1. Have fans input all the contextual information themselves.
  2. Have fans input just batter and pitcher and get the rest based on time that the response was submitted.
  3. Have fans input inning and base/out state (and maybe score), and fill in the other info later.
  4. Accept that there will be a delay and hope that fans remember the play well enough to answer accurately.

I think option 3 is by far the best so far, but I’m sure there are better options out there. That’s where I need your help. How should I do this with as much accuracy and as little work on my part and the part of fans as possible?

Tagged

Simulating Head-to-Head Fantasy Baseball

Pat Sheridan approves of my fantasy baseball programming posts.

In this post, I will, yet again, not only bring together two nerdy activities, fantasy baseball and programming, but I will also write about the amalgamation of said activities in moderate detail, which is enough detail to make the vast majority of you bored and somewhat uncomfortable. Pumped? Me too, my friends, me too.

Last week, I talked about my experimenting with creating a z-score spreadsheet for fantasy baseball projections. The other project that I’ve been working on is, or at least will be, a little more theoretical. Well, I’m not sure theoretical is the right word for it. Let me explain.

The question: What makes a fantasy baseball team win? More specifically, in head-to-head leagues, do certain types of teams, or teams with certain types of players, perform better than others, even if their overall stats are similar?

The end goal: Simulate fantasy baseball seasons using various types of team builds.

The process: Ha. As if I actually know how to go about doing this. But I’ll try, because I have a week until I start my new job and nothing to do. Instead of telling you what I’ll do, I’ll show you what I’ve done so far, then my plan – if I have one – for the future of the program.

Here are my two functions so far:

def createTeams(numOfTeams,numOfCategories):
    teams = {}
    records = {}
    for i in range(numOfTeams):
        teams[i+1] = []
        for j in range(numOfCategories):
            teams[i+1].append(random.random())
        records[i+1] = [0,0]
    return teams, recordsdef simulateWeek(teamDict,records,numOfTeams,numOfCategories):
    teamsYetToPlay = []
    team1 = 0
    team2 = 0
    for i in range(numOfTeams):
        #List of teams that have yet to play this week.
        teamsYetToPlay.append(i+1)
    while len(teamsYetToPlay)>1:  
        while team1 not in teamsYetToPlay:
            #Creates random integers until one it finds a team that hasn't played yet.
            team1 = random.randint(1,numOfTeams)
        teamsYetToPlay.remove(team1)
        while team2 not in teamsYetToPlay:
            team2 = random.randint(1,numOfTeams)
        teamsYetToPlay.remove(team2)
        for i in range(numOfCategories):
            A = teamDict[team1][i]
            B = teamDict[team2][i]
            log5 = (A-A*B)/(A+B-(2*A*B))
            z = numpy.random.geometric(log5, size=1)
            if z==1:
                records[team1][0] += 1
                records[team2][1] += 1
            else:
                records[team1][1] += 1
                records[team2][0] += 1
    return records

Yay giant blocks of code! But what does this mean?

Well it’s pretty simple. “createTeams” creates two dictionaries: the first pairs the number of the team with a list of values that represent the probability of that team winning a particular category against an average opponent in one week. The second dictionary pairs the team number with their win-loss record. (As I write this, I’m realizing that there is no point in these being dictionaries if the keys are just numbers, since lists are ordered anyway.)

The second function, “simulateWeek”, is my attempt to – you guessed it! – simulate a week in a fantasy baseball head-to-head league. Basically, I iterate through teamDict and create matchups so that each team plays once (probably only works with an even number of teams).

Determining the probability of one team beating another in a category given two probabilities was tough, but after some research I came across Bill James’ “log5” formula, which calculates a team’s chance of beating another team given their respective winning percentages. I used this formula to calculate the chance of one team beating the other in a category, then used numpy’s geometric distribution sample function to generate one trial based on the log5 probability. If the trial “succeeds”, team1 wins; otherwise, team2 wins, and their records are consequently updated.

So that’s what my program does so far. The good news is that it works! In my main function I called the simulateWeek function 20 times to simulate a season, with 12 teams in the league and 10 categories. It returned the probabilities of each team winning the categories as well as their final records.

The bad news is that it’s pretty much useless at this point. I’ve created a nice little simulation of a season using random probabilities, but remember that my goal is to simulate with teams of differing structures and types of players. For example, would a team with a bunch of good relievers and only a few good starters be better than a team with a ton of middle-of-the-pack starters and only a few mediocre closers? What about a team that punts batting average in exchange for more home runs and RBIs?

To do that kind of simulation, I need to do more than provide random probabilities for the categories. I probably need to use some sort of projection system so that for every week simulation, the program creates totals for the categories based on the projections and random variation. This seems doable at first, but like all programmable ideas, I’m sure it will take a lot more time and effort than one would initially think.

I’ll get working on this and sometime in the future, write up another post updated you all on my progress. Until then, let me know if you have any suggestions, comments, questions, etc. I’m writing up these posts partly because I think writing my thoughts down will help me think about these projects, but also because a lot of you are much better at this than I am, and I want help. So help me.

Tagged , , , , ,

How to Evaluate Pitching: An Incomplete Idea

I had an idea today, but I’m not sure if it would work, first of all, and even if it did work theoretically, it may be astoundingly impractical. But I’ll spell it out here, and you all can decide.

So a big question among sabermetricians – no, really just all baseball analysts/fans – is how to evaluate pitching. That is, what metrics/stats should we employ when trying to determine how well a pitcher has performed? Traditionally, Cy Young and sometimes MVP voters have used wins and ERA, but as countless smart people have pointed out, there are major flaws with these metrics.

Wins are very strongly influenced by offense, defense, the bullpen, and luck. Over a very large sample, win totals are indicative of how talented a pitcher is, but even then the variance is huge. ERA is better, but it is still influenced by defense and luck. If you have only Mike Trout’s in the outfield and only Ben Zobrist’s in the infield, A.J. Burnett becomes Roy Halladay (well not really, but you get the idea). Not to mention the fact that a large sample size is needed just to remove the random noise from ERA.

Sabermetricians have come up with various solutions. One of them is FIP, or Fielding Independent Pitching, which uses only strikeouts, walks, and home runs as the contributing factors to pitching performance. This solutions removes the defense and luck components out of balls in play, but it ignores any skill that may be, and often is, involved in turning balls in play into outs.

Others prefer to use methods based on runs allowed to measure pitching, thus including a pitcher’s ability to affect the outcome of balls in play. Of course, in doing so, they include luck and defense, which aren’t under the pitcher’s control.

My solution: wisdom of the crowds.

Good idea, right? Oh, you want more? Fine, I’ll explain.

What if there was a website in which baseball fans could, as they were watching a game, answer questions about every batted ball? The answers to these questions would determine the likelihood of that ball turning into an out, or a single or double or triple, given an average defense. With enough responses and data, we could determine what a pitcher’s true BABIP is, based on the types of balls that batters put into play against him.

The hard part is determining which questions to include, and how well fans would be able to accurately describe the plays they saw without being biased by the result. Here are some of the types of questions I’ve been thinking about:

  1. How hard was the ball hit, on a scale from 1-10?
  2. What type of batted ball was it (Choose one)?  Options: Weak grounder, Grounder, Weak Liner, Liner, Fliner, Flyball, Popup
  3. Where was the ball hit (Choose one)?  Options: Infield (3rd base line, left side, middle, right side, 1st base line), Shallow outfield (left, center, right), Deep Outfield (left, center, right)
  4. How much credit, or blame, do you think the pitcher deserves for the outcome of this batted ball, taking into account both defense and luck, from 0%-100%?

I’m certain that there are a multitude of issues with these questions. How well would fans really be able to determine how hard a ball was hit? The options in the second question overlap with the answer the first question – is this a problem, or would it lead to more accuracy? Does the location of the ball really matter, or only how hard it was hit? Obviously a shallow fly ball is different than a deep flyball, but can a pitcher really control whether a groundball is hit to short or down the middle? I don’t know. These are all important issues that I don’t know the answers to.

The fourth question would probably not be important once enough data had been collected, as the answers from the first three would be compared to the actual results of the batted balls in question. However, it may still matter, since two batted balls with identical answers to the first three questions could potentially be very different with regards to the fourth.

Maybe some examples would help my thinking and clarify what I’m suggesting. Below is the first video highlight that came up on mlb.com (I have a feeling the embed won’t work. If it doesn’t, just click on the picture and it’ll bring you to the vid).

 

  1. How hard was the ball hit, on a scale from 1-10? 3. This is a pretty slowly hit ground ball, but it could be slower. It’s hard to place a number on it, but 3 sounds reasonable.
  2. What type of batted ball was it?  Weak grounder. It might be a regular grounder, but the results would probably be mixed, and would show that it’s somewhere in between.
  3. Where was the ball hit?  Infield – left side.
  4. How much credit, or blame, do you think the pitcher deserves for the actual outcome of this batted ball, taking into account both defense and luck, from 0%-100%? 10%. Ok, I’m realizing now that this is a very confusing question. Maybe it would be better if there were only two choices, credit or no credit. I’m not sure.

Let’s try another:

  1. How hard was the ball hit, on a scale from 1-10? 7. This is a fairly hard hit ball, but it’s not a screaming line drive and it’s not too deep. Maybe 6 or 8 would be better, but I’ll go with 7.
  2. What type of batted ball was it ?  Fliner. This is exactly what I think of what I think of a fliner.
  3. Where was the ball hit ? Shallow outfield – right. I’m thinking maybe I should add left-center and right-center, but that implies that a pitcher can control the location of a batted ball that precisely, which I’m not confident he can.
  4. How much credit, or blame, do you think the pitcher deserves for the actual outcome of this batted ball, taking into account both defense and luck, from 0%-100%? 20%. The pitcher probably doesn’t deserve to get rewarded for an out here, but at least it wasn’t a deep, hard-it fly ball.

So there you have it. Theoretically, if there were hundreds of responses for each play, we could estimate, with some degree of accuracy, how much credit a pitcher deserves for a given batted ball, and by combining all of the batted balls, determine the pitcher’s skill at turning batted balls into outs.

Now it’s your turn. Is my idea completely idiotic? Would it work theoretically? Would it work practically? How could I change the questions to improve accuracy and response frequency? Once I perfected it, how could I implement it? And what would I do with the results? I would love to hear any and all comments.

Tagged , , , , ,

Z-Scores in Python, Part 1

Ready to get your nerd on?

I’ve decided to start playing around with programming. I took a couple computer science classes in college, and I’ve always wanted to get better at it, plus I’m about to start work at a software company, so I guess it’s a good thing to be good at. Obviously, I’m building baseball-related programs, and ideally, I’ll get good enough at this that I can start doing some real research, or at least build some handy tools for fantasy baseball.

Full disclosure before I start: I’m not very good at this, so I’m going to basically be walking through some of the things I’m doing and what I’m struggling with. If you know nothing about programming, then this will probably be very uninteresting for you. If you are an expert software developer, then I encourage you to laugh at how badly I’m screwing up the simplest code. If you’re a nice expert software developer, then after you are done laughing, I would appreciate any advice you might have about my particular code, or any other baseball-related projects that you think would be good practice for me.

Ok, so for the past few days, I’ve been fiddling with two different projects. The first is fantasy baseball related. Usually when I’m making my preseason rankings, I download an Excel projections spreadsheet, then I make a bunch of columns with z-Scores for the categories I want, total them, and adjust for position and the like. It’s a painfully long and arduous process, so I want to create a program that does it for me.

There are a lot of ways I could do this, and I probably chose the worst one. I decided to use mySQL, and after hours and hours of figuring out how to install the mySQL for Python module thing on my computer, I finally got it working and started coding. First I had to write a script to move the data (ZiPS hitting projections for 2012) from the .csv file to an SQL table, with columns for every stat in the projection sheet. Easy enough.

Then came the fun part. My end goal: have a .csv file with all the projections for the categories of my choice, plus z-scores for each category, total of the z-scores, somehow normalized and adjusted for position. So how the hell would I do that?

Here’s what I did. I’m realizing now that I went about this project in probably the entirely wrong way, so right now I’m at the point where I can either keep moving forward or start over using a different method.

  1. Got data from the SQL table based on inputted stat categories, and created a dictionary with the keys being player names and the values being lists containing their projections in the order that the stats were inputted.
  2. Iterated through the dictionary to create a “statPopulations” list of lists, each list containing every value for a certain category.
  3. Iterated through the dictionary again, this time creating z-scores (using statlib) for each category for each player and appending that to the dictionary entry. For batting average, since it is a rate stat, added another entry that was the z-score times number of AB (called zBATimesAB)
  4. Iterated through the dictionary a third time (you see why I think this was a bad way to do it now) to find z-scores for zBATimesAB and added that to each dictionary entry.
  5. Used csv.writer to create a header row with stat names and a row for each player, containing each of the original projections plus z-scores for each one and the extra two calculations for batting average.

After a lot of fiddling and error handling (banging my head on the computer), it somehow worked! I created a .csv file, which I opened in Excel, that looked just how I wanted it to look. Just a few huge problems though.

First of all, it is a horribly inefficient program, and takes about 20 seconds to run.

Secondly, I don’t have the z-score totals there, and I really don’t want to have to iterate through the dictionary again to make it. This makes me think that building a dictionary wasn’t the best course of action.

I also still need to adjust for position, and figure out what my population is. I have about 1000 players so far, but obviously not all of them are getting drafted. I need to figure out who is getting drafted, and then calculate z-scores based on that. But that’s going to depend on position and the z-scores themselves! Yeah, it’s a pain.

So that’s where I’m at with this. I’m happy that I’ve managed to actually write a program that works to some extent, but I have a feeling that if I really want it to be useful, I’m going to have to rewrite it completely. Using mySQL might be completely pointless, and building dictionaries instead of lists might be wrong too. I have a feeling that I either need to use SQL the whole time, adding z-scores to the SQL table instead of making dictionaries, or scrap SQL altogether and figure out a better way to transfer the original data to Python form.

Wow, I can’t believe I just wrote all that. Well, if you got through it all and have any suggestions, questions, or comments for me, let me know. Sometime later, I’ll talk about the other project I’ve been messing with: simulations (also related to fantasy baseball – I have no life)!

Tagged , , ,

The Fundamentals – Revival Edition

Hello friends! I’m back! Miss me?

I read somewhere that if you want people to read your blog, you should probably not write nothing on your blog. That sounds like a good idea. So I’m going to write not nothing on my blog. And, because I studied philosophy in college and I’m well-versed in the intricacies of logic and rational thought, I will reveal to you a little tautology of which you may not have been aware: “not nothing” is, necessarily, something. Yes, dear readers, you heard me right; I am going to write something on my blog. Maybe, probably, hopefully, more than something. Lots of things, ideally.

What am going to write, you ask? Well, you’re in for a treat. See, if you know only one thing about me (unlikely, since you’re probably either my mom or a complete stranger), it’s that I like baseball. A lot. For example, Chrome says that my “Most Visited Sites” are Yahoo Fantasy Baseball, Twitter (in which I follow exclusively baseball people), Ottoneu Fantasy Baseball, FanGraphs.com, MLB.com, Facebook, YanksGoYard.com – the awesome Yankees fan blog that lets me occasionally write things for them – and the dashboard on which I write said things.

That’s 3 sites where I read about baseball, 1 site where I write about baseball, 1 site where I interact across the interwebs with other people who like baseball, 2 sites where I pretend that I manage a baseball team, and Facebook.

So yeah, I like baseball.

Now, if you are still reading this (unlikely), you may be thinking to yourself, “Who is this miserable person, and why is my life so boring that I’m reading his god-awful post about seemingly nothing? Seriously, I’m sitting here alone on my computer, wasting my life away. Is there any point to it all? Why was I put on this Earth? Just so I could listen to this random nobody go on about his equally miserable life?”

Why yes, my beautiful reader, that is why you exist. I’m truly sorry. I know you wanted more out of your life than this, but alas, the fates have landed you here, so you might as well make the most of it. And trust me, if you’ve managed to stay with me for this long, then there is undoubtedly some metaphysical, supernatural force that has led you to this place for a reason.

Let’s see if we can make the most out of your unfortunate fate. If all goes as planned, I’m going to start writing, on this very blog, about things that I’m thinking about, things that I’m doing, things that are going on in the world, and things I consider important. Yes, a lot of those things will be about baseball. Some of them will be excruciatingly nerdy. I apologize in advance for those posts.

But maybe, if I am in fact correct about your purpose in life being to read this blog, you will get something out of the words that I write on these virtual pages. Maybe you’ll be inspired, or you’ll think of an important question that you must answer, or you’ll find the answer to a question you had been asking yourself. Maybe, for some odd reason, you’ll read what I write just because you enjoy hearing what I have to say and how I have to say it. I hope that this happens to you.

So, without further ado, I welcome you to The Fundamentals – Revival Edition. I’ll try not to disappoint.

P.S.

Tagged