I'm working on code where a star rating system was implemented, allowing users to rate between 1 & 5 stars. Instead of displaying an item's actual rating it uses this algorithm:
( rating_votes / ( rating_votes+10 ) ) * ( rating_total/rating_votes ) ) + ( 10 / ( rating_votes+10 ) ) * 4
Based on my intuition it seems like the intent of this is to default the rating to "4 stars" and to not drop the rating too quickly when there's under 10 votes.
Does anyone know what the mathematical name of this algorithm is called? Also can it's implementation be simplified and still produce the same output?
I got:
(rating_votes / ( rating_votes +10 )) * ( rating_total / rating_votes ) +
( 10 / ( rating_votes +10 ) ) *4
= (rating_total / (rating_votes + 10)) + (40 / (rating_votes + 10))
= (rating_total + 40) / (rating_votes + 10)
... you seem to have missed an opening bracket but is that what you meant? If so then your intuition is correct — it pretends that 10 people voted '4' before anyone else jumped in.
Other than integer rounding, depending on your language, simplification should produce the same result.
This is known as a "Bayesian average", a variant of additive smoothing. The basic idea is, you front-load a new estimator with a prior estimate of what the "real" average probably is, and then additional votes are added to that existing evidence. It means that it takes a lot of votes to move the average up or down.
And yes, its implementation can be simplified. See https://en.wikipedia.org/wiki/Bayesian_average for the basic formula.
You are right - the final rating can be rewritten as
final = (1-f) * rating + f * 4
Where the factor f decides how much the "actual" rating matters vs the "default" of 4.
Now you just have to convince yourself that f can be written as
f = 10 / (votes + 10)
Related
Amdahl’s law states that a speed up of the entire system is
an_old_time / a_new_time
where the a_new_time can be represented as ( 1 - f ) + f / s’, where f is the fraction of the system that is enhanced by some modification, and s’ is the amount by which that fraction of the system is enhanced. However, after solving this equation for s’, it seems like there are many cases in which s’ is negative, which makes no physical sense.
Taking the case that s = 2 (a 100% increase in the speed for entire system) and f = 0.1 (a 10% of the system is impacted by some speed enhancement s’), we solve for s’ by setting an_old time = 1 and s’ = f / ( f + 1 / s - 1 ).
Plugging on the values for f and s, we find that : s’ = 0.1 / ( 0.1 + 0.5 - 1 ) = 0.1 / -0.4 which means that the s’ value is negative.
How can this be possible, and what is the physical meaning of this? Also, how can I avoid negative s’ values when answering questions like these?
Amdahl's Law, also known as Amdahl's argument, is used to find the maximum expected improvement to an overall process when only a part of the process is improved.
1 | where S is the maximum theoretical Speedup achievable
S = __________________________; | s is the pure-[SERIAL]-section fraction
( 1 - s ) | ( 1 - s ) a True-[PARALLEL]-section fraction
s + _________ | N is the number of processes doing the [PAR.]-part
N |
Due to the algebra, the s + ( 1 - s ) == 1, s being anything from < 0.0 .. 1.0 >, there is no chance to get negative values here.
The full context of the Amdahl's argument& the contemporary criticism,adding all principal add-on overheads factors&a better handling of an atomicity-of-work
It is often applied in the field of parallel-computing to predict the theoretical maximum speedup achievable by using multiple processors. The law is named after Dr. Gene M. AMDAHL ( IBM Corporation ) and was presented at the AFIPS Spring Joint Computer Conference in 1967.
His paper was extending a prior work, cited by Amdahl himself as "... one of the most thorough analyses of relative computer capabilities currently published ...", published in 1966/Sep by prof. Kenneth E. KNIGHT, Stanford School of Business Administration.
The paper keeps a general view on process improvement.
Fig.1:
a SPEEDUP
BETWEEN
a <PROCESS_B>-[SEQ.B]-[PAR.B:N]
[START] and
[T0] [T0+tsA] a <PROCESS_A>-[SEQ.A]-ONLY
| |
v v
| |
PROCESS:<SEQ.A>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>|
| |
+-----------------------------------------+
| |
[T0] [T0+tsB] [T0+tsB+tpB]
| | |
v v v
|________________|R.0: ____.____.____.____|
| |R.1? ____.____| :
| |R.2? ____| : :
| |R.3? ____| : :
| |R.4? : : :
| |R.5? : : :
| |R.6? : : :
| |R.7? : : :
| | : : :
PROCESS:<SEQ.B>>>>>>>>>>|<PAR.B:4>: : :
| |<PAR.B:2>:>>>>: :
|<PAR.B:1>:>>>>:>>>>>>>>>: ~~ <PAR.B:1> == [SEQ]
: : :
: : [FINISH] using 1 PAR-RESOURCE
: [FINISH] if using 2 PAR-RESOURCEs
[FINISH] if using 4 PAR-RESOURCEs
( Execution time flows from left to right, from [T0] .. to [T0 + ts1 + tp1].The sketched order of [SEQ], [PAR] sections was chosen just for illustrative purpose here, can be opposite, in principle, as the process-flow sections' durations ordering is commutative in principle )
The speedup of a { program | process }, coming from using multiple processors in parallel computing, was derived to be ( maybe to a surprise of audience ) principally limited by the very fraction of time, that was consumed for the non-improved part of the processing, typically the sequential fraction of the program processing, executed still in a pure [SERIAL] process-schedulling manner ( be it due to not being parallelised per-se, or non-parallelisable by nature ).
For example, if a program needs 20 hours using a single processor core, and a particular portion of the program which takes one hour to execute cannot be parallelized ( having been processed in a pure-[SERIAL] process-scheduling manner ) , while the remaining 19 hours (95%) of execution time can be parallelized ( using a true-[PARALLEL] ( not a "just"-[CONCURRENT] ) process-scheduling ), then out of the question the minimum achievable execution time cannot be less than that ( first ) critical one hour, regardless of how many processors are devoted to a parallelized process execution of the rest of this program.
Hence the Speedup achievable is principally limited up to 20x, even if an infinite amount of processors would have been used for the [PARALLEL]-fraction of the process.
See also:
CRI UNICOS has a useful command amlaw(1) which does simple
number crunching on Amdahl's Law.
------------
On a CRI system type: man amlaw.
1 1
S = lim ------------ = ---
P->oo 1-s s
s + ---
P
S = speedup which can be achieved with P processors
s (small sigma) = proportion of a calculation which is serial
1-s = parallelizable portion
Speedup_overall
= 1 / ( ( 1 - Fraction_enhanced ) + ( Fraction_enhanced / Speedup_enhanced ) )
Articles to parallel#ctc.com (Administrative: bigrigg#ctc.com)
Archive: http://www.hensa.ac.uk/parallel/internet/usenet/comp.parallel
Criticism:
While Amdahl has formulated process-oriented speedup comparison, many educators keep repeating the formula, as if it were postulated for the multiprocessing process rearrangement, without taking into account also the following cardinal issues:
atomicity of processing ( some parts of the processing are not further divisible, even if more processing-resources are available and free to the process-scheduler -- ref. the resources-bound, further indivisible, atomic processing-section in Fig. 1 above )
add-on overheads, that are principally present and associated with any new process creation, scheduler re-distribution thereof, inter-process communication, processing results re-collection and remote-process resources' release and termination ( it's proportional dependence on N is not widely confirmed, ref. Dr. J. L. Gustafson, Jack Dongarra, et el, who claimed approaches with better than linear scaling in N )
Both of these group of factors have to be incorporated in the overhead-strict, resources-aware Amdahl's Law re-formulation, if it ought serve well to compare apples to apples in contemporary parallel-computing realms. Any kind of use of an overhead-naive formula results but in a dogmatic result, which was by far not formulated by Dr. Gene M. Amdahl in his paper ( ref. above ) and comparing apples to oranges have never brought anything positive to any scientific discourse in any rigorous domain.
Overhead-strict re-formulation of the Amdahl's Law speedup S:
1
S = __________________________; where s, ( 1 - s ), N were defined above
( 1 - s ) pSO:= [PAR]-Setup-Overhead add-on
s + pSO + _________ + pTO pTO:= [PAR]-Terminate-Overhead add-on
N
Overhead-strict and resources-aware re-formulation:
1 where s, ( 1 - s ), N
S = ______________________________________________ ; pSO, pTO
/ ( 1 - s ) \ were defined above
s + pSO + max| _________ , atomicP | + pTO atomicP:= further indivisible duration of atomic-process-block
\ N /
Interactive Tool for a maximum effective speedup :
Due to reasons described above, one picture might be worth million words here. Try this, where a fully interactive tool for using the overhead-strict Amdahl's Law is cross-linked.
I use reddit's ranking algorithm on my site in order to rank what's "hot" and what's not. Here is a simple explanation of how reddit's ranking algorithm works:
https://medium.com/hacking-and-gonzo/how-reddit-ranking-algorithms-work-ef111e33d0d9#.igk62pe0x
Specifically, this part:
# Rewritten code from /r2/r2/lib/db/_sorts.pyx
from datetime import datetime, timedelta
from math import log
epoch = datetime(1970, 1, 1)
def epoch_seconds(date):
td = date - epoch
return td.days * 86400 + td.seconds + (float(td.microseconds) / 1000000)
def score(ups, downs):
return ups - downs
def hot(ups, downs, date):
s = score(ups, downs)
order = log(max(abs(s), 1), 10)
sign = 1 if s > 0 else -1 if s < 0 else 0
seconds = epoch_seconds(date) - 1134028003
return round(sign * order + seconds / 45000, 7)
However, I found that, although this algorithm works very well, it doesn't change up content as often as I would like it to.
How can I modify the algorithm to do this? What numbers or parts of the algorithm would I need to modify in order for content on my site to change more frequently?
Instead of dividing seconds by 45000, you can divide it by a smaller number so that recent posts will have more significant impact and the feed will change more frequently. You can also tweak with the base of the logarithmic function or use a function with a different growth rate like square root function.
Below is the covariance equation for two variables, ABC and XYZ.
Below is the algorithm to find the covariance between ABC and XYZ.
Algorithm 1: Calculate Covariance
1. cov = 0
2. for i = 0 to size - 1
3. cov = cov + (return_abc[i] - avg_abc) * (return_xyz[i] - avg_xyz)
4. end for
5. cov = cov / size - 1
6. end
How do I design an algorithm to find the covariance between one variable to the rest of the variables in a sample?
For example, how do I find the covariance between APPLE's stock and the rest of the stocks in NASDAQ (about 3,100 companies) ?
http://www.investopedia.com/articles/financial-theory/11/calculating-covariance.asp
If you're looking at only end of day prices (for simplicity), and you would like to compare a single stock to all of the rest of the stocks, try treating the rest of them all as one element, ie:
n=number of days to analyze
marketReturn = average(return of each stock that isn't APPLE)
marketAverage = (sum of marketReturn's)/n
appleAverage = (sum of APPLE returns)/n
then apply the summation across a sample size of the number of days you are analyzing.
Answer = (((day 1 APPLE return %)-(appleAverage))*((day 1 marketReturn %)-(marketAverage)) + ((day 2 APPLE return %)-(appleAverage))*((day 2 marketReturn %)-(marketAverage)) + ...)/(n-1)
I suppose if you want to check each stock individually:
for(x=0;x<numStocksNotAPPLE;++x)//increment through each stock
{
covariantList[x]=(((day 1 APPLE return percent)-(appleAverage))*((day 1 stock[x] percent)-(stock[x] average)) + ... + (((day n APPLE return %)-(appleAverage))*((day n stock[x] %)-(stock[x] average)))/(n-1)
}//that should give you a covariant APPLE vs each stock
and then if you want just one number, you could take the average of the covariantList:
foreach(covariantList c)
{
sum+=c
}
averageCovariant = sum/covariantList.size
Keep in mind this is all psuedo-code, i'm not claiming any of it is functional
UseCase:
Assume that rating of object is from 1 to 5 stars.
It is already 50 votes with avarage rating 4.1.
When user make a vote(1-5stars), whe need to recalculate rating.
How to implement that logic? Problem is we don't know the value of every vote, only current rating and total votes.
newRating = (oldRating * oldCount + currentVote) / (oldCount + 1)
Well, basic arithmetic tells us that (50 * 4.1 + newvote) / 51 is the same as the average of all votes. You'll end up with roundoff errors if you do it repeatedly, and after a certain number of votes it's not even worth bothering with averaging in a single vote, but the basic formula is sound.
Assuming:
f = (1+2+3)/3 = 6/3 = 2
= (2+2+2)/3 = 6/3 = 2
We know that f=g. If we know the current rating is 2, and the total number of votes is 3, 2*3=6 as the sum of all votes. Let's add 4 to our average like so:
f = 6/3
f' = (6+4)/4 = 2.5
One of my friend was asked this question in the interview.
You have 5 zeros. using these 5 zeros and any mathematical functions, you have to get the result of 120.
He could not answer this. Neither I am able to see any valid answers.
Does anyone have any solution to this?
( 0! + 0! + 0! + 0! + 0! ) ! = 120
(cos(0) + cos(0) + cos(0) + cos(0) + cos(0))!
I can do it with 4 zeros: ((0! + 0! + 0!)! - 0!)!
Use factorial
0! = 1
(0! + 0! + 0! + 0! + 0!)! = 120
I recently came across this beautiful approach to represent any number using one zero!
The explanation is as follows:
Consider a right-angled triangle with sides (1,1,√2). Thus,
√2 = Sec ( Tan-1( 0! ) ). Now, consider a another right-angled triangle with sides (1,√2, √3). Here, √3 = Sec ( Tan-1 (Sec ( Tan-1( 0! ) ) ) ). Extrapolating this idea futher, for any number x, we can represent √x using one 0 as, √x = Sec ( Tan-1 (…… Sec ( Tan-1 (0!)) ……)), where Sec ( Tan-1 ….) is taken x-1 times.
There you go, 120 can be represented as, √14400 = Sec ( Tan-1 (…… Sec ( Tan-1 (0!)) ……)), with Sec ( Tan-1 ….) taken 14399 times.
I would buy the pure solution by #Iarsman, but I bet they were looking for something like:
factorial(not(0)+not(0)+not(0)+not(0)+not(0))
If you want to show you really know mathematical functions better than the interviewer, state it in terms of http://en.wikipedia.org/wiki/Peano_axioms:
SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS0 = 120
Or if you want to be too clever by half:
0/0 = 120 [Yes, that's not good practice, but it's as justifiable as any other answer]
Or if you want to show that mathematicians are often also comfortable using programming operators in the right circumstance:
(!0+!0+!0+!0+!0)!
I admit when I first saw it I was confused, because mostly this sort of question assumes that by mathematical function you mean "plus times minus divide" and maybe exponentiation. And I agree factorials are the intended answer. I agree it's an amusing question, and maybe it's sour grapes, but I really don't see the point of distinguishing people who've seen too many of these "think of the trick" questions from those who haven't, which is what this question does. (OK, it also sorts out who's never heard of a factorial, but so would asking "what's a factorial". This just makes sure you get the middle ground.)
"Mathematical" functions, hmmm, what else? Chemical ones?
let
zeroes = [0,0,0,0,0]
five = length zeroes
in five*five*five - five
Turns out we do not even need the zeores:
let
zeroes = [[], [], [], [], []]
five = length zeroes
in five*five*five - five
Use Factorial .
fact(fact(0)+....+fact(0))
0^0*1111 = 1111 (2 zeroes)
1111000 = 120 in binary (remaining 3 zeroes used here)
(0!0!*0!0!)-0! =(11*11) -1 =121-1 =120 is how i solved in an interview and the interviewer was amazed :)
how about one zero :P
(((((0!)++)++)++)++)!
RoL(RoL(RoL(RoL(NOT(RoL(NOT(RoL(NOT(RoL(NOT(0)))))))))))
One zero strictly logical using Windows Programming Calc