Some of them are available on NecroRankings.
Input example: 8:52 → 9:22 → 8:44 → 8:33 → 8:22 → 8:48 → 7:49 → 8:11 → 7:53 → ... (You can put scorerun results instead.)
Note: Actually just using linear regression sounds fine either.
Note: How should we treat dying runs? idk lol
What is Kalman filter: https://en.wikipedia.org/wiki/Kalman_filter
The problem is: what kind of model you assume? - Realistically, I think you just assume your improvement and time variance follow the normal distribution. (Of course you can try anything you want though.)
Note: Kalman filter has a lot of variants and techniques, this is just the most simple one.
Basic Example: (You can get my codes here.)
↓thanks to sc2, I was able to use this on actual data (applied for sc2's Cadence runs, using Ensemble Kalman Filter + smoothing).
Input: Players' PBs, basically you can use my site.
Note: I don't actually think all of this makes a lot of sense.
What is PCA: https://en.wikipedia.org/wiki/Principal_component_analysis
When you input Players' PBs and just run PCA, you'll find that PC1 will show some kind of "power" like necrolab points. Thus contributions of each characters for PC1 shows a correlation to "power". Although in necrondancer's case, they aren't very different. (This is using the speedrun PBs at 10/14/2021)
You can try to find some meaning in PC2, PC3... They would be like "PC2: Heavy character - Light character" or "PC3: 1-1 Movedig resetting character index".
↓using all unseeded non-coop non-custommusic PBs instead of just speedruns'
What is t-SNE: https://www.jmlr.org/papers/volume9/vandermaaten08a/vandermaaten08a.pdf
Fortunately, you can easily do this since scikit-learn contains t-SNE.
This is a result of t-SNE for all (speed/score/extra/deathless) pbs of top100 influence players. (Colored areas/texts are just my interpretation.)
It's more difficult to get some sense from the result with more dimensions.
What is BT-model: https://en.wikipedia.org/wiki/Bradley%E2%80%93Terry_model
Note: This model is actually a natural idea: when you assume there's no rock-paper-scissors relations in some way, you can derive it. Elo rating assumes the same model but uses incremental system instead of MLE.
Now that you have a model, you can calculate maximum likelihood estimation of each players' ratings.
You can use python library choix to do that without coding it yourself. (Although you also can just ask scipy or something to calculate argmin log-likelihood: which can be useful if you want to include some kind of prior distribution for each players' rating, since choix doesn't support that. )
Note that you can use any average/scaling for ratings. (And actually you can use e^(rating) instead for easier win/loss prediction.)
Example: (You can get codes here. : it's just using a library though.)
Friendly reminder: MLE estimation for zero-win/zero-loss players would be 0, ∞. Just ignore them until they eventually win/lose.
The expected number of tries until you achieve a thing which happens with probability of p is 1/p. (Ex: If you want to roll "1" on the dice - which happens with probability of 1/6, your expected number of tries is 6.)
(More specifically, it follows geometric distribution with parameter p, and the average of it is 1/p. - You can look at the shape of probability distribution itself if you want.)
With this knowledge, now you just need to know how much chance you have to get x:xx or better. For that, you need to assume some kind of probability distribution of your run duration.
If you assume the normal distribution, you can use a table like this: https://www.mathsisfun.com/data/standard-normal-distribution-table.html
In this case, you need to know your average and standard deviation (SD) of the run duration. Since you can't actually know the true values, you collect some sample run records of yourself and calculate sample mean and unbiased sample SD.
You can think like this: 0 is your average. 1 means 1*SD. (In the normal distribution 68.3% of your runs end up with "Average - SD ~ Average + SD" time.)
Ex: Your chance of getting "Average - 2*SD" or better time is 0.0228. Your expected number of runs to achieve it is about 44.
Ex: Your chance of getting "Average - 3*SD" or better time is 0.0013. Your expected number of runs to achieve it is about 769.
Ex: Your chance of getting "Average - 4*SD" or better time is 0.00003. Your expected number of runs to achieve it is about 33333.
Ex: Your chance of getting "Average - 5*SD" or better time is 0.000003. Your expected number of runs to achieve it is about 333333.
Generally, whatever distribution (like extremely luck-based one) you assume, your chance of getting "Average - k*SD" time is 1/k^2 at most. (Chebyshev's inequality)
...Yes, the problem is, we don't actually know what kind of distributon do necrodancer's run durations actually follow.
(off topic) If run duration (clear time of the run) follows the cumulative distribution function F(x), PB of N runs follows the cumulative distribution function 1 - (1 - F(x))^N.
I used random forest regression. NN didn't work well, due to small size of data, I guess. Ridge regression, SVR didn't work well too.
↓Example:
Input - AllZones PBs (Speed, Score) except Cadence Speed (33 dimensions)
Data - Players with ~WR x2.0 PB and ~5000th Influence (460 players)
You can use every data except yours as train data to estimate your PB.