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

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

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

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

配列

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

Q&A

解決済

1回答

1952閲覧

pythonの辞書型について

gik

総合スコア152

Python 2.7

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

配列

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

0グッド

0クリップ

投稿2016/03/24 09:42

編集2016/03/24 15:25

集合地プログラミングを読んで質問があります。
第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

なぜresult[item][person]=prefs[person][item]をひっくり返しただけで
key値がかわるのでしょうか?
この辞書型がよくわかりません。

また

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}
これがこういう風に数値がでるのもわかっていないです。←--------
この配列についても教えてください。

教えてください。
よろしくお願いします。
またこれと同じことはphpやjavaでもできるのでしょうか。

本のソースコード↓
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

ベストアンサー

なぜresult[item][person]=prefs[person][item]をひっくり返しただけでkey値がかわるのでしょうか?

ひっくり返しただけではないのでは。
ソースにコメントを入れてみました。

Python

1def transformPrefs(prefs): 2 result={} 3 for person in prefs: 4 for item in prefs[person]: 5 result.setdefault(item,{}) # <= この行は if item not in result: result[item] = {}と同義 6 result[item][person]=prefs[person][item] # <= この行で result[item][person]に値をセット 7 return result 8

ご参考になれば。

投稿2016/03/24 10:06

編集2016/03/24 16:36
tkanda

総合スコア2425

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

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

gik

2016/03/24 10:30 編集

'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} この配列って辞書型ですよね? この配列がすいません。あんまりよくわかってなくて
tkanda

2016/03/24 16:33 編集

辞書を二階層で使っていますね。 単純な辞書は {key:value, key:vakue, ...} のように宣言されますが、この場合は各要素の value がさらに辞書になっている、という構造です。
gik

2016/03/25 01:47 編集

すいません。 この場合 {'Lisa Rose': {'Lady in the Water': 2.5, 'Snakes on a Plane': 3.5}, Lisa Roseがkeyでvalueが{'Lady in the Water': 2.5, 'Snakes on a Plane': 3.5}, 'Lady in the Water'がkeyのとき valueは2.5であっていますか?
tkanda

2016/03/25 03:33

はい、あっています。
gik

2016/03/25 16:01

ありがとうございます。 理解出来ました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問