質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

1回答

2028閲覧

pythonの辞書型について

gik

総合スコア152

Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2016/04/09 21:01

編集2016/04/09 21:21

集合地プログラミングを読んで質問があります。
以前答えてもらった方の説明でわかったと思っていたのですが、
わかっていませんでした。
第2章のアイテムベースのレコメンドエンジンを作る場合

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},

critics['Lisa Rose']['Lady in the Water']

2.5

critics['Toby']['Snakes on a Plane']=4.5
critics['Toby']
{'Snakes on a Plane':4.5,'You, Me and Dupree':1.0}

{'Lisa Rose': {'Lady in the Water': 2.5, 'Snakes on a Plane': 3.5},
'Gene Seymour': {'Lady in the Water': 3.0, 'Snakes on a Plane': 3.5}}
これを次のように変換する。
{'Lady in the Water':{'Lisa Rose':2.5,'Gene Seymour':3.0},
'Snakes on a Plane':{'Lisa Rose':3.5,'Gene Seymour':3.5}} etc..

def transformPrefs(prefs):
result={}
for person in prefs:
for item in prefs[person]:
result.setdefault(item,{})

itemとpersonを入れ替える

result[item][person]=prefs[person][item] ** ←------------前回ここの部分がわかりませんでした**
return result

質問です。
def transformPrefs(prefs):
result={}
for person in prefs:
for item in prefs[person]:
result.setdefault(item,{}) # <= この行は if item not in result: result[item] = {}と同義
result[item][person]=prefs[person][item] ** # <= この行で result[item][person]に値をセット **
return result
という回答をいただきました。

result[item] = {}と同義の意味がよくわかりません。
**result[item][person]=prefs[person][item] **
の部分はresult[item]{[person][item]}←--------アイテムが最初に来るため
ということはresult[item]{'Lady in the Water':{'Lisa Rose'[person]:2.5[item]}
ということでしょうか。

**result[item][person]=prefs[person][item] # <= この行で result[item][person]に値をセット **
はなんの値をセットしているのでしょうか?
教えてください。

すいませんが、もう一度教えてください

本のソースコード↓
ftp://ftp.oreilly.co.jp/9784873113647/PCI_sample.pdf
ここにもあります。

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

Returns a distance-based similarity score for person1 and person2

def sim_distance(prefs,person1,person2):

Get the list of shared_items

si={}
for item in prefs[person1]:
if item in prefs[person2]: si[item]=1

if they have no ratings in common, return 0

if len(si)==0: return 0

Add up the squares of all the differences

sum_of_squares=sum([pow(prefs[person1][item]-prefs[person2][item],2)
for item in prefs[person1] if item in prefs[person2]])

return 1/(1+sum_of_squares)

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

if they are no ratings in common, return 0

if len(si)==0: return 0

Sum calculations

n=len(si)

Sums of all the preferences

sum1=sum([prefs[p1][it] for it in si])
sum2=sum([prefs[p2][it] for it in si])

Sums of 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 of the products

pSum=sum([prefs[p1][it]*prefs[p2][it] for it in si])

Calculate r (Pearson score)

num=pSum-(sum1sum2/n)
den=sqrt((sum1Sq-pow(sum1,2)/n)
(sum2Sq-pow(sum2,2)/n))
if den==0: return 0

r=num/den

return r

Returns the best matches for person from the prefs dictionary.

Number of results and similarity function 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]
scores.sort()
scores.reverse()
return scores[0:n]

Gets recommendations for a person by using a weighted average

of every other user's rankings

def getRecommendations(prefs,person,similarity=sim_pearson):
totals={}
simSums={}
for other in prefs:
# don't compare me to myself
if other==person: continue
sim=similarity(prefs,person,other)

# ignore scores of zero or lower if sim<=0: continue for item in prefs[other]: # only score movies I haven't seen yet if item not in prefs[person] or prefs[person][item]==0: # Similarity * Score totals.setdefault(item,0) totals[item]+=prefs[other][item]*sim # Sum of similarities simSums.setdefault(item,0) simSums[item]+=sim

Create the normalized list

rankings=[(total/simSums[item],item) for item,total in totals.items()]

Return the sorted list

rankings.sort()
rankings.reverse()
return rankings

def transformPrefs(prefs):
result={}
for person in prefs:
for item in prefs[person]:
result.setdefault(item,{})

# Flip item and person result[item][person]=prefs[person][item]

return result

def calculateSimilarItems(prefs,n=10):

Create a dictionary of items showing which other items they

are most similar to.

result={}

Invert the preference matrix to be item-centric

itemPrefs=transformPrefs(prefs)
c=0
for item in itemPrefs:
# Status updates for large datasets
c+=1
if c%100==0: print "%d / %d" % (c,len(itemPrefs))
# Find the most similar items to this one
scores=topMatches(itemPrefs,item,n=n,similarity=sim_distance)
result[item]=scores
return result

def getRecommendedItems(prefs,itemMatch,user):
userRatings=prefs[user]
scores={}
totalSim={}

Loop over items rated by this user

for (item,rating) in userRatings.items( ):

# Loop over items similar to this one for (similarity,item2) in itemMatch[item]: # Ignore if this user has already rated this item if item2 in userRatings: continue # Weighted sum of rating times similarity scores.setdefault(item2,0) scores[item2]+=similarity*rating # Sum of all the similarities totalSim.setdefault(item2,0) totalSim[item2]+=similarity

Divide each total score by total weighting to get an average

rankings=[(score/totalSim[item],item) for item,score in scores.items( )]

Return the rankings from highest to lowest

rankings.sort( )
rankings.reverse( )
return rankings

def loadMovieLens(path='/data/movielens'):

Get movie titles

movies={}
for line in open(path+'/u.item'):
(id,title)=line.split('|')[0:2]
movies[id]=title

Load data

prefs={}
for line in open(path+'/u.data'):
(user,movieid,rating,ts)=line.split('\t')
prefs.setdefault(user,{})
prefs[user][movies[movieid]]=float(rating)
return prefs

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

2つの変数を person='Lisa Rose'、item='Lady in the Water' と仮定した場合

result[item][person]=prefs[person][item]

この式は次のように表すことができます。

result['Lady in the Water']['Lisa Rose']=prefs['Lisa Rose']['Lady in the Water']

そして右辺(prefs['Lisa Rose']['Lady in the Water'])の評価結果は 2.5 になります。
つまり冒頭の式は次のように表すことができます。

result['Lady in the Water']['Lisa Rose']=2.5

このように順を追って考えていくと整理しやすいと思います。
ご参考になれば。

投稿2016/04/10 06:21

tkanda

総合スコア2425

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gik

2016/04/10 07:04 編集

ありがとうございます。 あと2つ質問なんですが、 result.setdefault(item,{}) はなぜ必要なんでしょうか。 http://yuutookun.hatenablog.com/entry/20120328/1332933078 みたく{}中に{'Lisa Rose':2.5}を入れるためですか? もうひとつ result['Lady in the Water']['Lisa Rose']=prefs['Lisa Rose']['Lady in the Water']は同じだということを表している式ですか? すいません。根本からまちがっているかもしれないのですが、回答よろしくお願いします。
tkanda

2016/04/10 07:30

> result.setdefault(item,{}) はなぜ必要なんでしょうか。 この行は、「result(辞書)に item('Lady in the Water')というキーが存在していない場合、つまり ('Lady in the Water' not in result) である場合、result['Lady in the Water'] = {} を実行(つまり辞書result のキー'Lady in the Water'の値を、空の辞書で初期化)せよ。」という意味です。 result['Lady in the Water']に空の辞書をセットしておくことで、後続の行で {人名:スコア} をセットすることが可能になるわでけす。 二つ目の質問ですが、答えはNoです。 Pythonに限らず、あらゆるプログラミング言語で使われる等号は両辺が等しいことを示しているのではなく、右辺の評価結果を左辺に示される変数に代入せよ、という意味でつかわれます。この点、数学での等号と意味が違います。
gik

2016/04/10 09:53

前回に続き教えてくださりありがとうございます。 わかりました。 本当にありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問