4
\$\begingroup\$

I was looking for a way to calculate a score 'x' for each pair of elements in two separate arrays. The goal of the code is to return an output array containing the score for each entry in the input arrays.

from math import sqrt
import numpy as np

downs = np.genfromtxt('path\file.csv', dtype=long, delimiter=',', skiprows=1, usecols=(1,))
ups = np.genfromtxt('path\file.csv', dtype=long, delimiter=',', skiprows=1, usecols=(2,))

n = np.add(ups,downs)

def _confidence(n):

   for i, j in zip[n, ups]:

    z = 1.0 #1.0 = 85%, 1.6 = 95%

    if n == 0:
        return 0 

    phat = float(ups) / n

    x = ((phat + z*z/(2*n) - z * sqrt((phat*(1-phat)+z*z/(4*n))/n))/(1+z*z/n))

    print [x]
\$\endgroup\$
5
  • \$\begingroup\$ Welcome to Code Review! I would recommend that you remove your original code and leave only your improved version, as I'm not sure there would be much point to reviewing code that you no longer use. I hope you get some good reviews! \$\endgroup\$
    – Phrancis
    Dec 12, 2014 at 16:58
  • \$\begingroup\$ The formatting seems pretty wrong from here. \$\endgroup\$
    – SylvainD
    Dec 12, 2014 at 17:02
  • \$\begingroup\$ zip[n, ups]? This does not look like working code. \$\endgroup\$ Dec 12, 2014 at 17:17
  • \$\begingroup\$ @Janne I may have made a mistake, I only had it with for i in n before. I just tried to extend it to two variables in parallel. \$\endgroup\$
    – user61033
    Dec 12, 2014 at 17:18
  • 1
    \$\begingroup\$ Have you tested this version of the code -- that it runs, and also produces the correct result? \$\endgroup\$ Dec 13, 2014 at 10:05

1 Answer 1

3
\$\begingroup\$

It looks like you are trying to calculate the Wilson Score lower confidence bound for ranking as described here: http://www.evanmiller.org/how-not-to-sort-by-average-rating.html

There are a couple issues with the code. The main one that jumps out is that only some of the needed variables (n) are passed into the function and the other simply read from the module namespace (ups, downs). Encapsulating into functions can help. Another issue is where i and j are not actually used within the loop and are bad variable names anyway.

The following code also generates synthetic data so I could test the full code.

from math import sqrt
import numpy as np

def generate_data(filename):
    """ Generate synthetic data for StackExchange example """
    ratings_per_example = 10
    ratings = np.random.binomial(ratings_per_example,0.4,100)
    fake_ups = ratings
    fake_downs = ratings_per_example-ratings
    fake_ids = np.arange(len(ratings))
    merged = np.asarray(zip(fake_ids, fake_downs, fake_ups))
    np.savetxt(filename, merged, fmt='%d', delimiter=",", header='Fake Header')


def confidence(filename):
    """ Returns an array of lower confidence bounds from up/down rankings in file """    
    downs = np.genfromtxt(filename, dtype=long, delimiter=',', skip_header=1, usecols=(1,))
    ups = np.genfromtxt(filename, dtype=long, delimiter=',', skip_header=1, usecols=(2,))

    lower_bound_ranks = [wilson_lower_bound(up, down) for up, down in zip(ups, downs)]

    return lower_bound_ranks

def wilson_lower_bound(up, down, z=1.0):
    """ http://www.evanmiller.org/how-not-to-sort-by-average-rating.html """
    n = up + down
    if n == 0:
        return 0.0
    else:
        phat = float(up) / n
        return ((phat + z*z/(2*n) - z * sqrt((phat*(1-phat)+z*z/(4*n))/n))/(1+z*z/n))

generate_data('foo.csv')
confidence('foo.csv')
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.