Logarithmic scale - Ranking in PHP

I am currently building a system that requires ranking based on internal actions / points. The account itself can vary from anywhere in the range from 0 to 20,000.

I need a function that I create to rank users in order to return a value between 1-100. If this is not possible, it would be nice to return any result sets of more than 100 as 100. Currently, I am having difficulty creating a logarithmic algorithm for determining points.

I tried the following function:

echo 1 + sqrt(500 + 2000 * $score) / 50; 

However, the results of this return do not change sufficiently for lower values ​​and increase exponentially for higher ones.

Examples of entry points at the small / middle end of the scale:

  • 0.15
  • 1
  • 7
  • 12

Input example at the upper end of the scale

  • 236.4
  • 1211
  • 17899.70

Any help would be greatly appreciated. Stuck on this for a few days. The above function is the best attempt that I have so far, however, as you know, not a low enough level between average and average results and too many higher ones.

Thanks,

Daniel

+5
source share
3 answers

thanks for the help. Here's what I got (thanks to the help of Jake L Price)

The score changed slightly after the initial question (with 120,000 being the top of the scale), however, the logic for the algorithm should remain unchanged. As you can see below, we used log * 10 to get an acceptable low number. Then we multiply this by a number that provides 120,000 upper levels of 100.

  echo $this->rank($score); public function rank($score) { //-- log reg time // 7.143963378055477 being the numberic multiplier to ensure 120,000 has the score of 100. $res = 7.143963378055477 * log($score * 10); return $res; } 

Now coming back

 $scores = [0.15,1,7,12,236.4,1211,17899.70, 120000]; foreach ($scores as $score){ echo "Score: " . $score . ", Rank: " . $this->rank($score) . "</br>"; } 

Output:

 Score: 0.15, Rank: 2.896627883404 Score: 1, Rank: 16.449583579206 Score: 7, Rank: 30.351094421044 Score: 12, Rank: 34.201665683178 Score: 236.4, Rank: 55.495096060882 Score: 1211, Rank: 67.166020848577 Score: 17899.7, Rank: 86.407125230156 Score: 120000, Rank: 100 
+1
source

This is an open question and there is no clear answer to the various compromises. I am not a PHP programmer, but something like the following should work.

 # THESE PARAMETERS CONTROL THE RANKING ALGORITHM. $rescale = 0; $spread = 1; function rescore ($n) { return log($n) + $rescale; } function rank ($scores) { return 100 / (1 + exp(- $spread * array_sum(array_map("rescore", $scores)))); } 

You must select $rescale so that the average score is reset to something close to 0. And play with $spread until you are happy with how much your scores are scattered.

The idea is that log turns a wide range of scores into numbers in a comparable range, which can be positive or negative. Add a bunch of combined points together and you get an arbitrary real number. Then move this to the logistic function (see https://en.wikipedia.org/wiki/Logistic_function for more details) to turn this into a number in the desired range.

+4
source

Attempting to closely monitor the definition in Wikepedia, where "each label in the [logarithmic] scale is the previous label multiplied by the value," we set value^100 = 20000 and get value = 1.104104805 . Can this logarithmic scale be implemented using a function similar to the following?

 function rank($score){ return log($score,1.104104805); } 

Output:

 $scores = [0.15,1,7,12,236.4,1211,17899.70]; foreach ($scores as $score){ echo "Score: " . $score . ", Rank: " . rank($score) . "\n"; } /* Score: 0.15, Rank: -19.156079885479 Score: 1, Rank: 0 Score: 7, Rank: 19.648736275112 Score: 12, Rank: 25.091228109202 Score: 236.4, Rank: 55.187884698844 Score: 1211, Rank: 71.683855953272 Score: 17899.7, Rank: 98.879704658993 */ 
+1
source

Source: https://habr.com/ru/post/1239049/


All Articles