2011-12-18 6 views
0

これは初心者の質問ですので、あいにくご容赦ください。私は、基本的なPythonの使用に関する数冊の本を読んで、今「集合知プログラミング」のチュートリアルに取り組んでいますが、私は、コードの私のブロックでエラーを取得しています:私は、このエラーがでたくさん見ValueError:関数への送信時に数学的なドメインエラーが発生しました。

ValueError: math domain error 

私はなぜ起こっているのか分からない。プログラムは、基本的に映画批評家とそのレビューでdictを取った後、最初の関数(sim_pearson)は、似たような2人の批評家がどのようになっているかを示します。この部分は単独で動作します。問題は、私が他の人と比較して1人のユーザーを比較しようとしているときに批評家がランク付けできるときです。

ここでは、コードです:

# A dictionary of movie critics and their ratings of a small 
# set of movies 
critics={'Lisa Rose': {'Lady in the Water': 2.5, 'Snakes on a Plane': 3.5, 
'Just My Luck': 3.0, 'Superman Returns': 3.5, 'You, Me and Dupree': 2.5, 
'The Night Listener': 3.0}, 
'Gene Seymour': {'Lady in the Water': 3.0, 'Snakes on a Plane': 3.5, 
'Just My Luck': 1.5, 'Superman Returns': 5.0, 'The Night Listener': 3.0, 
'You, Me and Dupree': 3.5}, 
'Michael Phillips': {'Lady in the Water': 2.5, 'Snakes on a Plane': 3.0, 
'Superman Returns': 3.5, 'The Night Listener': 4.0}, 
'Claudia Puig': {'Snakes on a Plane': 3.5, 'Just My Luck': 3.0, 
'The Night Listener': 4.5, 'Superman Returns': 4.0, 
'You, Me and Dupree': 2.5}, 
'Mick LaSalle': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0, 
'Just My Luck': 2.0, 'Superman Returns': 3.0, 'The Night Listener': 3.0, 
'You, Me and Dupree': 2.0}, 
'Jack Matthews': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0, 
'The Night Listener': 3.0, 'Superman Returns': 5.0, 'You, Me and Dupree': 3.5}, 
'Toby': {'Snakes on a Plane':4.5,'You, Me and Dupree':1.0,'Superman Returns':4.0}} 

from math import sqrt 
#now lets use the pearson correlation score to see if we can get better results 
#Returns the pearson correlation coefficient for p1 and p2 
def sim_pearson(prefs, p1, p2): 
    #get the list of mutually rated items 
    si={} 
    for item in prefs[p1]: 
     if item in prefs[p2]: 
      si[item]=1 

    #find the number of elements 
    n=len(si) 

    # if they have no rating in common, return 0 
    if n == 0: return 0 

    #add up all the preferences 
    sum1=sum([prefs[p1][it] for it in si]) 
    sum2=sum([prefs[p2][it] for it in si]) 

    #sum up the squares 
    sum1Sq=sum([pow(prefs[p1][it],2) for it in si]) 
    sum2Sq=sum([pow(prefs[p2][it],2) for it in si]) 

    #sum up the products 
    pSum=sum([prefs[p1][it]*prefs[p2][it] for it in si]) 

    #Calculate Pearson score 
    num=pSum-(sum1*sum2/n) 
    den=sqrt((sum1Sq-pow(sum1,2)/n)* sum2Sq-pow(sum2,2)/n) 

    if den == 0: return 0 
    r=num/den 

    return r 


#lets check out the results 
print 'here are the results from the Pearson algo:' 
print sim_pearson(critics, 'Lisa Rose', 'Gene Seymour') 
print sim_pearson(critics, 'Mick LaSalle', 'Jack Matthews') 

#now lets rank critics to see who is the most simlair 
#Returns the best matches for person from prefs dictionary 
#Number of results and similarity functions are optional params. 

def topMatches(prefs, person, n=5, similarity=sim_pearson): 
    scores=[(similarity(prefs, person, other),other) 
      for other in prefs if other != person] 
    #sort the list so the highest scores appear at the top 
    scores.sort() 
    scores.reverse() 
    return scores[0:n] 


#lets see the ranking 
print 'here are the top matches:' 
print topMatches(critics, 'Toby', n=3) 

トレースバックが3行に問題があると言う:私はここで何が起こっているかわからないんだけど

print topMatches(critics, 'Toby', n=3) 
for other in prefs if other != person] 
den=sqrt((sum1Sq-pow(sum1,2)/n)* sum2Sq-pow(sum2,2)/n) 

: トレースバック(最新の呼び出し最後は) 。ここで(本から)期待される答えは次のとおりです。事前

[(0.9912, 'Lisa Rose')], (0.9244, 'Mick LaSalle'), (0.8934, 'Claudia Puig')]

おかげで(完全な情報開示:私は数学で吸うと多分そうそこに私は欠けているいくつかの主要な根本的な問題をのpythonを学んでいますが、私本からコードをダブルチェックして、私はタイプミスや何かを作ったとは思わない)。

答えて

1

私はあなたがこのラインからの括弧のペアが欠落していると思う:

den=sqrt((sum1Sq-pow(sum1,2)/n)* sum2Sq-pow(sum2,2)/n) 

私は、あなたのコードを取り、この変更を行った、それを実行し、それそれが

den=sqrt((sum1Sq-pow(sum1,2)/n)* (sum2Sq-pow(sum2,2)/n)) 

されるべきだと思います期待される答えを出した。

+0

あなたの権利!私は単身者のためのレビューを送ったときに働いた。それは唯一の新しいことだったので、問題がランキング機能であると思った。本当にありがとう。 – Lostsoul

1

math.sqrt()で負の数値の平方根をとることはできません。あなたが(私はあなたがreally don't...と思われるが)確信している場合は、代わりにcmath.sqrt()を使用してください。

+0

私は負の数が必要ではないと考えています。本の例では、[(0.9912、 'Lisa Rose')]、(0.9244、 'Mick LaSalle')、(0.8934、 'Claudia Puig ')] – Lostsoul

関連する問題