Article Request: "About the Tiers"

My apologies then. With the tier lists not up, I was not sure if there actually was a BL tier in either, espcially RBY with its only having 151 pokemon.
 

Jumpman16

np: Michael Jackson - "Mon in the Mirror" (DW mix)
is a Site Content Manager Alumnusis a Top Team Rater Alumnusis a Battle Simulator Admin Alumnusis a Smogon Discord Contributor Alumnusis a Researcher Alumnusis a Top Tiering Contributor Alumnusis a Top Contributor Alumnusis an Administrator Alumnus
I have missed the IRC sessions, since I have been working 8-5 this week, so pardon me if this has been gone over, but should there not be some mention of RBY/GSC not really having a BL tier at all? I mean, things like Tentacruel who are BL in RBY (and pretty much BL in GSC too!) just get shoved in OU there!

Also, this is just minor, and I understand you say rank to emphasize that it is a way of separating power and all, but

"Smogon's tier system is used to rank Pokemon into several groups based on their perceived power and usage in competitive play."

I am pretty sure 'rank into' is not quite right, so I would replace it with separate Pokemon into.
i brought that up on irc but it was decided that we wanted the work "rank" in there, and "sort into different ranks" didn't accomplish what we wanted. i agree with you but seemingly nobody else does, whatever
 

Blue Kirby

Never back down.
is a Top Tutor Alumnusis a Site Content Manager Alumnusis a Battle Simulator Admin Alumnusis a Programmer Alumnusis a Smogon Discord Contributor Alumnusis a Top Contributor Alumnusis a Smogon Media Contributor Alumnusis an Administrator Alumnusis a Past SPL Championis a Three-Time Past WCoP Champion
We could always take another look at that particular qualm when we sweep the document to make sure nothing has been left out.
 

X-Act

np: Biffy Clyro - Shock Shock
is a Site Content Manager Alumnusis a Programmer Alumnusis a Smogon Discord Contributor Alumnusis a Top Researcher Alumnusis a Top CAP Contributor Alumnusis a Top Tiering Contributor Alumnusis a Top Contributor Alumnusis a Smogon Media Contributor Alumnusis an Administrator Alumnus
As per chaos' request. I decided to leave the mathematical details out of the document, since I don't think that the majority are really interested in the exact percentages and mathematical distributions that are used to get to the DP OU tier (and they can always refer to the thread if they are). If this is not what you wanted, then I'll update it with the 'boring' mathematical stuff. Please fix.

<h3>How the OU tier is constructed</h3>

<p>The OU tier contains, as already mentioned, the Pokemon that are used commonly in the standard metagame. The reader might be interested to know how the Pokemon in the OU tier are selected to make part of the tier.</p>

<p>For RB, GS and RS, the OU tier is formed from the experience of our community of which Pokemon are commonly used in Smogon's standard metagame tournaments. In tournaments, people use Pokemon that can compete at the highest level to allow them to win, so naturally they are an excellent means of determining the OU tier.</p>

<p>The OU tier for DP is constructed from the league statistics extracted from the current DP Pokemon battling medium. These statistics provide the number of times each Pokemon was used in the standard metagame league during each month, and those of the three months prior to the OU tier creation are utilised in particular. The Pokemon commonly used by expert players, who are highly-ranked in the league, receive heavier weighting than those used by less expert ones. Furthermore, the statistics from the previous month are made to influence the OU tier more than those from the two months before it. This is done to make the OU tier reflect the frequently used Pokemon of the current standard metagame. Since, compared to the previous three generations, the DP standard metagame is still in its infancy, the OU tier for DP is continually updated on a three-month basis.</p>
 

chaos

is a Site Content Manageris a Battle Simulator Administratoris a Programmeris a Smogon Discord Contributoris a Contributor to Smogonis an Administratoris a Tournament Director Alumnusis a Researcher Alumnus
Owner
I recommend documenting the mathematical side too, except at the very end of the document. Math is cool ^____________________________________^
 

Blue Kirby

Never back down.
is a Top Tutor Alumnusis a Site Content Manager Alumnusis a Battle Simulator Admin Alumnusis a Programmer Alumnusis a Smogon Discord Contributor Alumnusis a Top Contributor Alumnusis a Smogon Media Contributor Alumnusis an Administrator Alumnusis a Past SPL Championis a Three-Time Past WCoP Champion
<p>The OU tier contains, as already mentioned, the Pokemon that are used commonly in the standard metagame. The reader might be interested to know how the Pokemon in the OU tier are selected to make part of the tier.</p>

<p>For RB, GS and RS, the OU tier is formed from the experience of our community, of which Pokemon are commonly used in Smogon's standard metagame tournaments. In tournaments, people use Pokemon that can compete at the highest level to allow them to win, so naturally they are an excellent means of determining the OU tier.</p>

<p>The OU tier for DP is constructed from the league statistics extracted from the current DP Pokemon battling medium. These statistics provide the number of times each Pokemon was used in the standard metagame league during each month, and those of the three months prior to the OU tier creation are utilised in particular. The Pokemon commonly used by expert players, who are highly-ranked in the league, receive heavier weighting than those used by less experienced opponents. Furthermore, the statistics from the previous month are made to influence the OU tier more than those from the two months before it. This is done to make the OU tier reflect the frequently used Pokemon of the current standard metagame. Since, compared to the previous three generations, the DP standard metagame is still in its infancy, the OU tier for DP is continually updated on a three-month basis.</p>
Bolded indicates a minor edit. Some of the changes I made were purely because I saw redundant words in a few sentences (I was corrected on this many times in the sections I wrote). This is just my own opinion, of course; people many disagree on how it is presented.

That aside, this will be an excellent inclusion to the article, giving it a real sense of extra depth. The content, as we'd all expect coming from someone as experienced with the defining of the OU tier, is right on the mark. Personally, I'd like some of the 'boring' mathematical concepts included, but I'm not really sure how much importance this is to your average battler.

Great stuff. :)
 

X-Act

np: Biffy Clyro - Shock Shock
is a Site Content Manager Alumnusis a Programmer Alumnusis a Smogon Discord Contributor Alumnusis a Top Researcher Alumnusis a Top CAP Contributor Alumnusis a Top Tiering Contributor Alumnusis a Top Contributor Alumnusis a Smogon Media Contributor Alumnusis an Administrator Alumnus
I'll do that while discussion is again ripe in the other thread, lol. At least, the mathematical part shouldn't be affected in the discussion (hopefully!).

EDIT: Edited with Blue Kirby's suggestions.
 

X-Act

np: Biffy Clyro - Shock Shock
is a Site Content Manager Alumnusis a Programmer Alumnusis a Smogon Discord Contributor Alumnusis a Top Researcher Alumnusis a Top CAP Contributor Alumnusis a Top Tiering Contributor Alumnusis a Top Contributor Alumnusis a Smogon Media Contributor Alumnusis an Administrator Alumnus
Here's the mathematical bit. I'm a bit tired, so you'll probably find a few English errors here and there, but I made sure that there are no mathematical mistakes. :)

I used LateX to typeset a few mathematical formulae, and saved them as GIF images, which the HTML later uses in the document.

<h3>The mathematical details of how the OU list is generated in DP</h3>

<p>Shoddybattle's weighted Pokemon usages lists of the three months prior to the OU update are first extracted from their website. The weighted usage of a Pokemon is the summation of the rankings of every player that used that Pokemon. For example, say both Blissey and Celebi are used three times during a day, and say that the players using Blissey had ranking 1650, 1360 and 1470, while those using Celebi had ranking 1520, 1360 and 1190. Their weighted usage for that day would be 4480 for Blissey and 4070 for Celebi. This would rank Blissey above Celebi in the weighted usage list, even though they were both used the same number of times during that day.</p>

<p>Each weighted usage of each month is then divided by the total of the weighted usages during that particular month, so that the probability of that particular Pokemon being used during that month. Afterwards, these probabilities are raised to a power depending on the month that the statistics are taken from. The probabilities for Month 1 are all raised to the power of 1/2, those for Month 2 are all raised to the power of (sqrt(5)-1)/4 and those for Month 3 are all raised to the power of (3-sqrt(5))/4, where "Month <em>x</em>" refers to <em>x</em> months before the OU tier creation, and sqrt(<em>x</em>) denotes the square root of <em>x</em>. The significance of these strange-looking weightings is the following:</p>

<ul>
<li>The three weightings add up to 1:
<p><img src="1.gif" width="504" height="59" alt="" /></p>
<li>The powers for Months 2 and 3 sum up to 0.5, which is the same power used for Month 1 alone:
<p><img src="2.gif" width="440" height="61" alt="" /></p>
<li>Month 1's exponent is 61.8% larger than that of Month 2, and Month 2's exponent is 61.8% larger than that of Month 3 (the number 1.618 is called the Golden Ratio):
<p><img src="3.gif" width="379" height="399" alt="" /> <img src="4.gif" width="432" height="400" alt="" /></p>
</ul>

<p>This means that the probabilities for Month 1 (the most recent month of the three) have overall preference.</p>

<p>After doing this, the probabilities raised to these powers are multiplied together for each Pokemon. This produces a weighted geometric mean of the probabilities of the three months, and provides the overall weighted probability that a particular Pokemon was used in the previous three months.</p>

<p>These probabilities are then sorted in descending order and made into a cumulative frequency, so that the 30th number, say, would be the probability that one of the top 30 used Pokemon is used in battle. Finally, the OU list is made to consist of all the Pokemon whose cumulative probability of being used does not exceed 0.75. This would mean that, whenever a Pokemon switches in or leads, it has a 75% chance of being a member of the OU tier.</p>

<p>It can be shown that the probabilities of the usage of each Pokemon follow an exponential distribution. This means that the <em>n</em>th most used Pokemon will roughly have a <em>b</em>exp(<em>-bn</em>) probability of being used, where <em>b</em> is a constant that determines the shape of the exponential curve. The best value of <em>b</em> can be found using regression analysis on a spreadsheet program like Microsoft Excel. For Pokemon usages, it usually results in a value between 0.025 and 0.027.</p>

<p>In addition, the cumulative exponential distribution can be found using integration to be 1-exp(<em>-bn</em>). This means that the probability that a Pokemon used in battle is among the first <em>n</em> most used Pokemon is 1-exp(<em>-bn</em>). Since we are saying that the OU Pokemon are those with a 75% chance of being used, we can effectively solve the equation 1-exp(<em>-bn</em>) = 0.75 to find the number of Pokemon that the OU tier will contain:</p>

<p><img src="5.gif" width="192" height="197" alt="" /></p>

<p>Assuming that <em>b</em> is between 0.025 and 0.027, the number of Pokemon in the OU tier would roughly contain between 1.386/0.025 and 1.386/0.027 Pokemon, or between 51 and 55 Pokemon.</p>


----------------------------------
Images used:

1.gif



2.gif



3.gif



4.gif



5.gif
 

chaos

is a Site Content Manageris a Battle Simulator Administratoris a Programmeris a Smogon Discord Contributoris a Contributor to Smogonis an Administratoris a Tournament Director Alumnusis a Researcher Alumnus
Owner
<p>After this is done, each of these overall usages is divided by the total of overall usages, so that each value becomes the probability of that Pokemon being used in battle. These probabilities are then sorted in descending order and made into a cumulative frequency, so that the 30th number, say, would be the probability that one of the top 30 used Pokemon is used in battle. Finally, the OU list is made to consist of all the Pokemon whose cumulative probability of being used does not exceed 0.75. This would mean that, whenever a Pokemon switches in or leads, it has a 75% chance of being a member of the OU tier.</p>
in my implementation of this there is no need for a descending sort, so i see no need to mention it here.

this is my draft implementation:

Code:
    def read_month(month_weight):
        for pokemon, value in read_part():
            unweighted, weighted = usage.get(pokemon, (0, 0))
            usage[pokemon] = unweighted + value, weighted
            
        for pokemon, value in read_part():
            unweighted, weighted = usage.get(pokemon, (0, 0))
            usage[pokemon] = unweighted, weighted + value * month_weight
    
    read_month(0.5)
    read_month(0.30901699437494745)
    read_month(0.19098300562505255)
    
    ou = []
    uu = []
    
    frequencies = ((pokemon, weighted/unweighted) 
                   for pokemon, (unweighted, weighted) in usage.iteritems())
    for pokemon, frequency in frequencies:
        if frequency <= 0.75:
            ou.append(pokemon)
        else:
            uu.append(pokemon)
read_part is not supplied because its just text manipulation.
 

X-Act

np: Biffy Clyro - Shock Shock
is a Site Content Manager Alumnusis a Programmer Alumnusis a Smogon Discord Contributor Alumnusis a Top Researcher Alumnusis a Top CAP Contributor Alumnusis a Top Tiering Contributor Alumnusis a Top Contributor Alumnusis a Smogon Media Contributor Alumnusis an Administrator Alumnus
First of all, I barely know any Python, but I could understand the code a bit using my programming knowledge of around 10 years ago. ._.

As I understood it, you're dividing the weighted data by the total of the unweighted ones, whereas you should be dividing by the total of the weighted ones. In fact, you don't even need to store the total of the unweighted data at all.

Then you'll need to sort this data. It won't always be already in descending order, even though the data supplied from Shoddybattle is sorted. There might be slight fluctuations. After sorting, you add them up cumulatively... you don't do it before, and allow those Pokemon having cumulative frequency less than or equal to 0.75.

I'll be at my fiancee's house for practically all day, so I'll barely be able to post anything today.
 

chaos

is a Site Content Manageris a Battle Simulator Administratoris a Programmeris a Smogon Discord Contributoris a Contributor to Smogonis an Administratoris a Tournament Director Alumnusis a Researcher Alumnus
Owner
As I understood it, you're dividing the weighted data by the total of the unweighted ones, whereas you should be dividing by the total of the weighted ones. In fact, you don't even need to store the total of the unweighted data at all.
After this is done, each of these overall usages is divided by the total of overall usages, so that each value becomes the probability of that Pokemon being used in battle.
I misunderstood because you used the word "usages". On the the Shoddybattle website, the Unweighted data uses the word "usages". This needs a clarification. I'm dividing by the sum of all of the "points", correct?

Then you'll need to sort this data. It won't always be already in descending order, even though the data supplied from Shoddybattle is sorted. There might be slight fluctuations. After sorting, you add them up cumulatively... you don't do it before, and allow those Pokemon having cumulative frequency less than or equal to 0.75.
Okay, this makes more sense with the usages/points clarification. I'll try to do another draft Monday. This actually simplifies the code a whole lot.
 

X-Act

np: Biffy Clyro - Shock Shock
is a Site Content Manager Alumnusis a Programmer Alumnusis a Smogon Discord Contributor Alumnusis a Top Researcher Alumnusis a Top CAP Contributor Alumnusis a Top Tiering Contributor Alumnusis a Top Contributor Alumnusis a Smogon Media Contributor Alumnusis an Administrator Alumnus
A quickie post from my fiancee's laptop, lol.

Yeah I'm sure that the mathematical part of the article requires a bit of rewording. I'll look into it when I have a bit of a chance.

I'll explain the process here with a little example. Examples are always the best way to explain things, as my teaching experience tells me, lol.

For a simple example, suppose there are only 13 Pokemon. Say their weighted usage from Shoddybattle is the following:

October:
Blissey (40285488 points)
Garchomp (35346459 points)
Gyarados (28413709 points)
Tyranitar (27631112 points)
Gengar (26956962 points)
Salamence (22501062 points)
Heracross (21822407 points)
Metagross (20926458 points)
Weavile (20380183 points)
Skarmory (20060534 points)
Cresselia (18936160 points)
Infernape (18850879 points)
Bronzong (18816978 points)

November:
Blissey (44130823 points)
Garchomp (34891188 points)
Gengar (27724428 points)
Tyranitar (26970786 points)
Gyarados (24250783 points)
Salamence (23468595 points)
Infernape (22943536 points)
Cresselia (22057297 points)
Skarmory (21613795 points)
Bronzong (21073134 points)
Weavile (18943588 points)
Metagross (18557630 points)
Heracross (15446025 points)

December:
Blissey (43156141 points)
Garchomp (35287522 points)
Gengar (28356758 points)
Salamence (25934232 points)
Gyarados (24894520 points)
Tyranitar (23424985 points)
Bronzong (22921436 points)
Skarmory (21943289 points)
Cresselia (21534982 points)
Infernape (20976580 points)
Metagross (19568973 points)
Heracross (19034258 points)
Weavile (18858763 points)

Every month's number of points are first divided by the total number of points for that month, so as to find the probabilities of each Pokemon being used in that month:

Code:
 Pokemon    October      November     December
-----------------------------------------------
Blissey   0.125527966  0.137021774  0.132424493
Bronzong  0.058632949  0.065429965  0.07033436
Cresselia 0.059004315  0.068485692  0.06608003
Garchomp  0.110138149  0.108333635  0.108279658
Gengar    0.083996813  0.086081565  0.087012629
Gyarados  0.088535978  0.075296246  0.076388762
Heracross 0.067997745  0.047958357  0.058406565
Infernape 0.058738583  0.071237375  0.064366575
Metagross 0.065206004  0.057619578  0.060047337
Salamence 0.070112407  0.072867631  0.079579115
Skarmory  0.06250782   0.067108663  0.067332918
Tyranitar 0.086097437  0.083741582  0.071879498
Weavile   0.063503833  0.058817938  0.057868059
These numbers are then raised to the power of 0.191 for October, 0.309 for November and 0.5 for December:

Code:
 Pokemon    October      November     December
-----------------------------------------------
Blissey   0.672782599  0.541069822  0.363901763
Bronzong  0.581749484  0.430581009  0.265206259
Cresselia 0.582451394  0.436697359  0.257060362
Garchomp  0.656185148  0.503182422  0.329058746
Gengar    0.623092434  0.468672139  0.294979032
Gyarados  0.629387007  0.449680307  0.27638517
Heracross 0.598447825  0.391169197  0.241674503
Infernape 0.581949506  0.442045778  0.253705685
Metagross 0.593675436  0.413994993  0.245045581
Salamence 0.601958341  0.445147436  0.282097705
Skarmory  0.588903212  0.433964941  0.259485873
Tyranitar 0.626038774  0.464697691  0.268103522
Weavile   0.590683901  0.41663679   0.240557809
Then the product of these numbers is found for every Pokemon:

Code:
 Pokemon    Overall
---------------------
Blissey   0.132468379
Bronzong  0.06643159
Cresselia 0.065384585
Garchomp  0.108648891
Gengar    0.086141566
Gyarados  0.078223344
Heracross 0.056574637
Infernape 0.065265362
Metagross 0.060226974
Salamence 0.075590961
Skarmory  0.066315078
Tyranitar 0.077996347
Weavile   0.059201432
These are then sorted:
Code:
 Pokemon    Overall
---------------------
Blissey   0.132468379
Garchomp  0.108648891
Gengar    0.086141566
Gyarados  0.078223344
Tyranitar 0.077996347
Salamence 0.075590961
Bronzong  0.06643159
Skarmory  0.066315078
Cresselia 0.065384585
Infernape 0.065265362
Metagross 0.060226974
Weavile   0.059201432
Heracross 0.056574637
These are then made into a cumulative frequency:
Code:
 Pokemon   Cumulative
---------------------
Blissey   0.132468379
Garchomp  0.241117269
Gengar    0.327258835
Gyarados  0.405482179
Tyranitar 0.483478526
Salamence 0.559069487
Bronzong  0.625501077
Skarmory  0.691816156
Cresselia 0.75720074
Infernape 0.822466102
Metagross 0.882693076
Weavile   0.941894508
Heracross 0.998469144
(Heracross is not exactly 1 due to rounding errors.) Those having a cumulative frequency of 0.75 or less are chosen for OU. These are:

Blissey
Garchomp
Gengar
Gyarados
Tyranitar
Salamence
Bronzong
Skarmory

Hope this helps to understand the process better. It ended up not being a quickie post at all, lol.

Note: A large number of Pokemon were chosen for OU in this example because the data is not in an exponential distribution here, so the example kinda sucks in that regard. It gives a good account of how the process works, though.
 

chaos

is a Site Content Manageris a Battle Simulator Administratoris a Programmeris a Smogon Discord Contributoris a Contributor to Smogonis an Administratoris a Tournament Director Alumnusis a Researcher Alumnus
Owner
Yeah, that's what I figured second time around. My bad, just got confused by the whole "usage" thing. Just a quick clarification (and maybe that example wouldn't hurt either) to this document would do a lot of good.
 

chaos

is a Site Content Manageris a Battle Simulator Administratoris a Programmeris a Smogon Discord Contributoris a Contributor to Smogonis an Administratoris a Tournament Director Alumnusis a Researcher Alumnus
Owner
ok its almost 8 am and i havent been to bed yet but

Code:
# Mapping of {access_id: weighted points}
    usage = defaultdict(int)
    
    # How much to weigh each month. The len of this sequence is how many months are expected.
    month_weights = [0.5, 0.30901699437494745, 0.19098300562505255]
    
    for month_weight in month_weights:
        for pokemon, points in read_part():
            usage[pokemon] += points * month_weight

    total = sum(usage.itervalues())
    
    # Sort by weight descending.
    usage = sorted(usage.iteritems(), key=itemgetter(1), reverse=True)
    cumulative_frequency = 0
    ou, uu = [], []
    
    for pokemon, weighted_points in usage:
        cumulative_frequency += weighted_points / total
        if cumulative_frequency <= 0.75:
            ou.append(pokemon)
        else:
            uu.append(pokemon)
 
X-Act:

You know, if the granularity of your stats are whole months, I don't see why you weigh in previous months. If you had daily stats, maybe it would make sense to do it, but over a month you absorb pretty much all variability that needs to be accounted for. Unless you can show that it really improves the tiering, I suggest to cut them off and just use the last month. It will simplify the math. Also, I don't think that using the arithmetic mean on an exponential distribution will give you the intended results: even with lesser weights for previous months, the highest value will absorb too much of the mean and the ranks will change at a snail's pace. I advise using the geometric mean instead.

Edit: you need to normalize the points by the total of the month before you add them up: if for some reason (downtime?) the activity of a month drops to half of what it was the month before, the previous month will count more than the current month...

It would be cool if the tiers could be figured out by clustering (if there were big jumps in the usage statistics). Alas, I plotted the statistics in logspace and it's pretty much a line. There's no place where you could say "ok we cut there". There's no natural clustering of the data, so to cut at 0.75 seems a bit arbitrary.

I'd be interested in trying to cluster the data using more complete statistics: amount of users for pokemon x, amount of kills, longevity of the pokemon, co-occurrence statistics, etc.
 

chaos

is a Site Content Manageris a Battle Simulator Administratoris a Programmeris a Smogon Discord Contributoris a Contributor to Smogonis an Administratoris a Tournament Director Alumnusis a Researcher Alumnus
Owner
It takes like half a minute to write the implementation of these algorithms so don't worry about changing it around. When month 3 statistics come out you all can try both algorithms on the data and see which one produces more favorable results.

I'm always up for the simplest version though.
 
so this will be implemented into the site sometime after jan. 1st? Just wondering because more accurate tiers are always nice.
 
oh, I know... It's just that the script seems to be right there. I'm not rushing you or anything, just curious.
 

X-Act

np: Biffy Clyro - Shock Shock
is a Site Content Manager Alumnusis a Programmer Alumnusis a Smogon Discord Contributor Alumnusis a Top Researcher Alumnusis a Top CAP Contributor Alumnusis a Top Tiering Contributor Alumnusis a Top Contributor Alumnusis a Smogon Media Contributor Alumnusis an Administrator Alumnus
X-Act:

You know, if the granularity of your stats are whole months, I don't see why you weigh in previous months. If you had daily stats, maybe it would make sense to do it, but over a month you absorb pretty much all variability that needs to be accounted for. Unless you can show that it really improves the tiering, I suggest to cut them off and just use the last month. It will simplify the math. Also, I don't think that using the arithmetic mean on an exponential distribution will give you the intended results: even with lesser weights for previous months, the highest value will absorb too much of the mean and the ranks will change at a snail's pace. I advise using the geometric mean instead.

Edit: you need to normalize the points by the total of the month before you add them up: if for some reason (downtime?) the activity of a month drops to half of what it was the month before, the previous month will count more than the current month...

It would be cool if the tiers could be figured out by clustering (if there were big jumps in the usage statistics). Alas, I plotted the statistics in logspace and it's pretty much a line. There's no place where you could say "ok we cut there". There's no natural clustering of the data, so to cut at 0.75 seems a bit arbitrary.

I'd be interested in trying to cluster the data using more complete statistics: amount of users for pokemon x, amount of kills, longevity of the pokemon, co-occurrence statistics, etc.
Pity I'm receiving such an interesting post this late. :(

First of all, I was considering changing the tiers every month instead of every three months, exactly for the reason you're mentioning. But people complained that the tiers would change too frequently if we did that. Whether or not data from before the last month are important or not is a matter of conjecture at this point, although I do see your point that they are 'useless' in the sense that they are not current statistics.

I never thought of using the geometric mean, and, on second thoughts you're right about using it instead of the arithmetic mean. And yeah I understand that the data needs to be normalised so that they end up having the same 'total'. Dividing each value by their month total would be enough. That's a mistake. This is, of course, if we end up still using the previous three months instead of just the last month.

Yeah I plotted the values repeatedly and there are no clusters whatsoever. In the original thread, I repeatedly state that the 0.75 is arbitrary. I tried to find a better value, but I don't know enough statistics to do that (statistics is not my subject at all). The only reason I ended up using 0.75 as the cut-off point is that it ends up having an OU list of around 50 to 55 Pokemon, which seems a nice amount to have.

As for your last paragraph, we currently don't have that much data about our Pokemon, so, of course, we can't do that yet. This method should be good enough to start us off, though.

As chaos says, any changes we'll do will probably not do a complete overhaul to the code. I already have an implementation of the process in Excel (although I think I'll change the arithmetic mean to the geometric mean and I'll definitely normalise the data so that they have the same total).

EDIT: I normalised the data (dividing each usage by the total number of usages during that month), and used the geometric mean instead of the arithmetic mean (raising October's stats to the power of 0.191, November's stats to the power of 0.309 and December's stats to the power of 0.5 and then multiplying them out. It did produce a slightly better weighting.)

EDIT2: I edited the mathematics article to reflect the changes talked about in the previous paragraph.

EDIT3: Edited also the example.
 

chaos

is a Site Content Manageris a Battle Simulator Administratoris a Programmeris a Smogon Discord Contributoris a Contributor to Smogonis an Administratoris a Tournament Director Alumnusis a Researcher Alumnus
Owner
Please double post in cases like this so I know the topic has been updated! I'll look at it a bit later tonight.
 

chaos

is a Site Content Manageris a Battle Simulator Administratoris a Programmeris a Smogon Discord Contributoris a Contributor to Smogonis an Administratoris a Tournament Director Alumnusis a Researcher Alumnus
Owner
untested implementation of this:

Code:
def calculate(tierfile, output):
    """
    Calculate the correct tiers from `tierfile` and write them in SCMS format to `output`.
    
    `tierfile` should consist of the weighted usages copied and pasted 
    from http://shoddybattle.com/stats for the last 3 months. 
    The format is as follows:
        <Month 1>
        -
        <Month 2>
        - 
        <Month 3>
    Note: The - is a literal -. It separates the logs from each other.
    """
    
    from collections import defaultdict
    from operator import itemgetter
    
    if isinstance(tierfile, basestring):
        tierfile = open(tierfile)
    
    # Mapping of {access_id: weighted points}
    usage = defaultdict(lambda: 1)
    
    # How much to weigh each month. The len of this sequence is how many months are expected.
    month_weights = [0.5, 0.30901699437494745, 0.19098300562505255]
    
    for month_weight in month_weights:
        month_total = 0
        month_pokemon = {}
        
        # Collection all the Pokemon and their points and accumulate a total.
        for pokemon, points in read_part(tierfile):
            month_pokemon[pokemon] = points
            month_total += points
        
        for pokemon, points in month_pokemon.iteritems():
            # Normalize the points by dividing by the total, and then raise to the power of the month weight.
            # Accumuluate the product of the months in usage.
            usage[pokemon] *= (points / month_total) ** month_weight
        
    # Sort by weight descending.
    sorted_usage = sorted(usage.iteritems(), key=itemgetter(1), reverse=True)
    cumulative_frequency = 0
    ou, uu = [], []
    
    for pokemon, weighted_points in sorted_usage:
        cumulative_frequency += weighted_points
        if cumulative_frequency <= 0.75:
            ou.append(pokemon)
        else:
            uu.append(pokemon)
            
    # Merge with current tier list? I don't know what we're doing here.
    # Write result to `output`
that leads me to my next question: what are we doing after we have the list of OU and UU pokemon? my thought was:

* Previous tier was Uber: set to Uber.
* Calculated tier is UU and previous tier was BL: set to BL.
* Otherwise, set to calculated tier.

This leads to a problem though - say Pokemon X starts out BL, then is promoted to OU, and then demoted to UU. X will never become BL again.

Also food for thought - what about NU?

Edit: Alternatively, we could remove BL every iteration and hand-pick all of them.
 

X-Act

np: Biffy Clyro - Shock Shock
is a Site Content Manager Alumnusis a Programmer Alumnusis a Smogon Discord Contributor Alumnusis a Top Researcher Alumnusis a Top CAP Contributor Alumnusis a Top Tiering Contributor Alumnusis a Top Contributor Alumnusis a Smogon Media Contributor Alumnusis an Administrator Alumnus
My implementation would first start with the following tiers:

Code:
[Uber]
arceus
darkrai
deoxys
deoxys-a
deoxys-d
deoxys-s
dialga
giratina
groudon
ho-oh
kyogre
latias
latios
lugia
manaphy
mew
mewtwo
palkia
rayquaza
wobbuffet
[OU]
<empty>
[BL]
abomasnow
aerodactyl
alakazam
ambipom
arcanine
articuno
azelf
azumarill
blaziken
blissey
breloom
bronzong
charizard
celebi
cresselia
crobat
donphan
drapion
dragonite
dugtrio
dusknoir
electivire
empoleon
entei
espeon
exeggutor
feraligatr
floatzel
flygon
forretress
gallade
garchomp
gardevoir
gengar
gliscor
gyarados
hariyama
heatran
heracross
hippowdon
honchkrow
houndoom
infernape
jirachi
jolteon
jynx
kingdra
leafeon
lickilicky
lucario
ludicolo
machamp
magmortar
magnezone
mamoswine
marowak
medicham
mesprit
metagross
milotic
miltank
mismagius
moltres
ninjask
porygon2
porygon-z
raikou
rampardos
regice
regigigas
regirock
registeel
rhyperior
roserade
salamence
sceptile
scizor
skarmory
slaking
slowbro
slowking
shaymin
shedinja
smeargle
snorlax
spiritomb
staraptor
starmie
steelix
suicune
swampert
tangrowth
tauros
togekiss
torterra
typhlosion
tyranitar
umbreon
ursaring
uxie
vaporeon
venusaur
weavile
weezing
yanmega
zangoose
zapdos
[UU]
absol
aggron
altaria
ampharos
arbok
ariados
armaldo
banette
bastiodon
beautifly
beedrill
bellossom
bibarel
blastoise
butterfree
cacturne
camerupt
carnivine
castform
chatot
cherrim
chimecho
claydol
clefable
cloyster
corsola
cradily
crawdaunt
delcatty
delibird
dewgong
ditto
dodrio
drifblim
dunsparce
dustox
electrode
exploud
farfetchd
fearow
flareon
froslass
furret
gastrodon
girafarig
glaceon
glalie
golduck
golem
gorebyss
granbull
grumpig
hitmonchan
hitmonlee
hitmontop
huntail
hypno
illumise
jumpluff
kabutops
kangaskhan
kecleon
kingler
kricketune
lanturn
lapras
ledian
linoone
lopunny
lumineon
lunatone
luvdisc
luxray
magcargo
manectric
mantine
masquerain
mawile
meganium
mightyena
minun
mothim
mr_mime
muk
nidoking
nidoqueen
ninetales
noctowl
octillery
omastar
pachirisu
parasect
pelipper
persian
pidgeot
pikachu
pinsir
plusle
politoed
poliwrath
primeape
probopass
purugly
quagsire
qwilfish
raichu
rapidash
raticate
relicanth
rotom
sableye
sandslash
scyther
seaking
seviper
sharpedo
shiftry
shuckle
skuntank
solrock
spinda
stantler
sudowoodo
sunflora
swalot
swellow
tentacruel
torkoal
toxicroak
tropius
unown
venomoth
vespiquen
victreebel
vileplume
volbeat
wailord
walrein
whiscash
wigglytuff
wormadam
wormadam-g
wormadam-s
xatu
[NU]
[Limbo]
[NFE]
.
.
.
The above is the current tier list, except all OUs are written as BLs.

Then each Pokemon chosen for OU would move from the tier it currently resides in to OU.

The reason I'm assuming this is that our initial tier list didn't depend much on usage but on what we thought it would be used (based on how much we think the Pokemon are useable due to their typing/movepool/ability/stats). So it's fair to assume that all the current OU/BLs would overcentralise UU, and hence, always starting from this hypothetical tier list wouldn't give us any problems about where a Pokemon should go, whether to BL or to UU, since its starting position is already 'set in stone'.
 

Users Who Are Viewing This Thread (Users: 1, Guests: 0)

Top