Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add UR estimation to the osu!mania ruleset #22613

Open
wants to merge 98 commits into
base: master
Choose a base branch
from

Conversation

Natelytle
Copy link
Contributor

@Natelytle Natelytle commented Feb 12, 2023

Massive thanks to Frost for the majority of the math behind this rework, and to Evening, Molneya, and Komirin for guidance.

Estimates Unstable Rate and replaces Accuracy with it

Changes

  • Raw accuracy percentages are no longer used to scale performance
  • Instead, the UR value of the score is estimated from the judgements of the play and the sizes of the hit windows, and used to scale performance in an hit window agnostic way

Reasoning

  • Between Scorev1, Scorev2, and osu!lazer Score, the way hit windows work differ massively. Because of this, the same play will receive a different accuracy value depending on which system is used.
  • Performance previously did not scale with OD.
  • Unstable rate is an easier metric to work with, as there is a true "perfect" value.

Estimation Theory

In order to estimate UR, we assume all hits are normally distributed, with a mean of ±0 and a deviation σ. This gives us the probability that with a certain σ, any given hit lands in a given window. We can compare these percentages to the true percentages of any given judgement in a play, and return whichever σ value is the closest match.
image
Further documentation can be found in a google doc here.

Considerations

  • Mania hit windows may potentially change as mania in lazer is ironed out. This will require addressing and an update to the current tests.
  • Classic mod doesn't change the results of a replay, forcing me to use a workaround that causes note-only classic mod plays to give incorrect values when replayed.
  • Requires MathNet.Numerics, a package for advanced mathematical formulas not present in C#.

SR/PP spreadsheet: https://docs.google.com/spreadsheets/d/1SBFrFOWIxJM-gACZrOk-2I6mH35MN9FRUDXbrTcGnJs/edit
As of a2197e2

@Natelytle
Copy link
Contributor Author

Tests should be more manageable now.

@smoogipoo
Copy link
Contributor

I've run an SR/PP spreadsheet for these changes, and attached it to the OP. Please have a look over it to make sure that the values are expected :)

@Natelytle
Copy link
Contributor Author

Sheet looks fine, I cross checked a few values and theyre all fine

@Eve-ning Eve-ning self-requested a review August 17, 2023 05:40
Copy link
Member

@Eve-ning Eve-ning left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@Natelytle
Copy link
Contributor Author

Will require reapproval due to #24636

@smoogipoo
Copy link
Contributor

Just to be safe...

!diffcalc
RULESET=mania

Copy link

github-actions bot commented May 28, 2024

Comment on lines +19 to +21
<ItemGroup>
<PackageReference Include="MathNet.Numerics" Version="5.0.0" />
</ItemGroup>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How feasible is it to eliminate this mathnet reference in a way similar to #20963?

Yes I keep banging on about that and it's probably inconvenient but it matters if it's going to decrease binary size / dependency blast radius.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, tsunyoku ported the relevant functions to a file. I just have to clean up the implementation

@@ -12,6 +12,12 @@ public class ManiaPerformanceAttributes : PerformanceAttributes
[JsonProperty("difficulty")]
public double Difficulty { get; set; }

[JsonProperty("estimated_ur")]
public double? EstimatedUr { get; set; }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as #20963, would prefer this to be called EstimatedUnstableRate

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure.

Comment on lines +56 to +58
OverallDifficulty = values[ATTRIB_ID_OVERALL_DIFFICULTY];
NoteCount = (int)values[ATTRIB_ID_NOTE_COUNT];
HoldNoteCount = (int)values[ATTRIB_ID_HOLD_NOTE_COUNT];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was going to ask why these are not just being read from the IBeatmapOnlineInfo param here and skipped entirely in .ToDatabaseAttributes(), but then realised that wouldn't work because of keymods. I'm not sure how intentional this was but yeah.

This is going to be something that we need to be wary of going forward unless realtime calculation becomes a thing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part in particular was added by smoogi to calculate a sheet for the rework

@bdach
Copy link
Collaborator

bdach commented May 29, 2024

Deployment considerations:

  • 3 added difficulty attributes
    • 3 rows per 13 B
    • we have ~19400 mania-specific beatmaps, for which only 16 mod combinations need to be considered = ~12 MB of storage overhead
    • plus ~111700 converts, which have 16 * 14 available mod combinations (keymods) = ~976 MB of storage overhead

Seemingly nothing further to point out from the infra side.

@Natelytle
Copy link
Contributor Author

@bdach Before you start any code structure reviews, what are your passing thoughts on the structure of https://github.com/Natelytle/osu/blob/maniastataccrefactor (specifically Utils/LogProb.cs)? I find it's much better for parsing the mathematics since the log stuff is abstracted away, but I'd like a second opinion.

@bdach
Copy link
Collaborator

bdach commented May 31, 2024

what are your passing thoughts on the structure of https://github.com/Natelytle/osu/blob/maniastataccrefactor (specifically Utils/LogProb.cs)

I'm not sure I'm going to be doing math/methodology correctness reviews on diffcalc anymore myself as I'm not sure that it's productive or even needed at this point. I was more angling to do just general code quality stuff. That said, since you asked directly, I'm not sure what to think of that thing. Some of the operations there have me worried about correctness of function domain and/or numerical stability - specifically I'm talking about stuff like presenting

$$ \log (x+y) = \log \left( x \cdot \left( 1 + \frac{y}{x} \right) \right) = \log x + \log \left( 1 + \frac{y}{x} \right) $$

etc (assuming $y &gt; x$). It seems to be symbolically correct but I'm not sure how it's going to behave in the wild as I'm rusty on my analysis. Some other operations in there just seem plain arbitrary (what is LogProb.Combine()? does it represent some real operation / have any semantic meaning rather than be an arbitrary expression on logs that happens to be useful in this case?)

Again as per my opening post I'd probably not ding this in review because I'm not sure I care about the meat and potatoes of diffcalc changes at this point, but yeah. If these operations are meant to have some probabilistical interpretation then there should be xmldoc that explains what it is, otherwise it just doesn't seem like a very robust abstraction.

Oh and if that thing is gonna stay then please change the name to something resembling full words, LogProbability is fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Blocked
Development

Successfully merging this pull request may close these issues.

7 participants