0

这是一个推荐系统:

在 Python 中,我输入:1.081743 / 0.540871 结果是:2.0000018488696933 没错。

但在程序中:结果是:2.0

Python代码如下:

def getRecommendations(prefs, person, n = 50, k = 5, similarity = sim_cosine):
    totals = {}
    simSums = {}
    sims = topMatches(prefs, person, n, similarity) 
    print("Neigh: " +str(sims) + "\n")
    for item in sims:
        other = item[1]
        for i in prefs[other]:
            if i not in filterKeys:
                if i not in prefs[person] or prefs[person][i] == 0 :
                    totals.setdefault(i,0)
                    totals[i] += prefs[other][i] * item[0]
                    simSums.setdefault(i,0)
                    simSums[i] += item[0]

    rankings = []
    for item,total in totals.items():
        if simSums[item] == 0 : continue
        print("Person: %s, Total :%f , simSum :%f, Item: %s" %(person, total,  
    simSums[item], item))

我在这里将浮点数和字符串列表附加到排名中

    rankings.append([float(total / (simSums[item] * 1.0)), item])



    print("\nRankings Before Sort:")
    print(rankings)
    rankings.sort()
    rankings.reverse()
    print("\nRankings After Sort:")
    print(rankings)
    print("***************************************************************\n")
    return rankings[0:k]

结果如下:


邻居:[(0.5408713866765542, '3'), (0.510809444238797, '7')]

人:2,总数:2.163486,simSum:0.540871,项目:1

人:2,总数:1.081743,simSum:0.540871,项目:2

人:2,总数:1.021619,simSum:0.510809,项目:7

排序前的排名:[[4.0, '1'], [2.0, '2'], [2.0, '7']]

排序后的排名:[[4.0, '1'], [2.0, '7'], [2.0, '2']]

实际上, 1.081743 / 0.540871 = 2.0000018488696933 1.021619 / 0.510809 = 2.0000019576788977 但是当我附加到列表时,它将被截断为 2.0

在这段代码中:

rankings = []

total = 1.081743
sim = 0.540871

rankings.append([total / sim,'ttt'])
print(rankings)

结果正常:[[2.0000018488696933, 'ttt']]

这是另一个数据


邻居:[(0.5204800389058843, '3'), (0.510809444238797, '2')]

人:7,总数:2.081920,simSum:0.520480,项目:1

人:7,总数:4.115487,simSum:1.031289,项目:9

人:7,总数:1.040960,simSum:0.520480,项目:2

人:7,总数:2.043238,simSum:0.510809,项目:10

排序前的排名:[[4.0, '1'], [3.9906228126775822, '9'], [2.0, '2'], [4.0, '10']]

排序后的排名:[[4.0, '10'], [4.0, '1'], [3.9906228126775822, '9'], [2.0, '2']]


我认为格式字符串没有什么为什么?

对不起我的英语不好

4

1 回答 1

2

该问题与分配值时的精度损失无关,而是与数字在 Python 中显示的默认精度为 6 的事实有关。注意:

>>> x = 1.081743 / 0.540871
>>> x
2.0000018488696933
>>> "%f" % x
'2.000002'

要显示更高的精度,请在格式字符串中添加宽度和精度

>>> "%21.19f" % x
'2.0000018488696933439'

现在,如果 1.081743 和 0.540871 确实是您的值,那么分配它们将不会有任何问题:

>>> total = 1.081743
>>> sum = 0.540871
>>> rankings = []
>>> rankings.append([float(total/sum), 'ttt'])
>>> rankings
[[2.0000018488696933, 'ttt']]
>>> rankings.sort()
>>> rankings
[[2.0000018488696933, 'ttt']]

但这是真正的问题。您声称使用这些值:

Person: 2, Total :2.163486 , simSum :0.540871, Item: 1
Person: 2, Total :1.081743 , simSum :0.540871, Item: 2
Person: 2, Total :1.021619 , simSum :0.510809, Item: 7

您可能希望看到这样的值:

>>> 2.163486 / 0.540871
4.000003697739387
>>> 1.081743 / 0.540871
2.0000018488696933
>>> 1.021619 / 0.510809
2.0000019576788977

但您真正看到的是 4.0、2.0 和 2.0。为什么是这样?原因是您显示的值已经四舍五入到小数点后六位,因此不是您计算的实际值!

因此,您并没有真正进行除法1.081743 / 0.540871,因为_这两个数字是您要除法的实际值的近似值。而这两个实际数字之比正好是2.0。这就是您看到 2.0 的原因。

我会尽量让它更清楚。请研究这个脚本。它显示了你做了什么。你取了两个非常好的数字,然后将它们四舍五入为六位小数,并尝试用它们计算,你发现了一个不同的商。

>>> total = 1.0817427733531084
>>> sim = 0.5408713866765542
>>> total / sim
2.0
>>> print "%f" % total 
1.081743
>>> print "%f" % sim
0.540871
>>> 1.081743 / 0.540871
2.0000018488696933
于 2013-10-08T08:24:56.160 回答