Commit 8a5b273cbe0b6b86390d5f40b92e867e1bfcb54d

Authored by Tássia Camões Araújo
1 parent 842edc0b
Exists in master and in 1 other branch add_vagrant

Added ranking to RecommendationResults and small fixes for strategies.

Showing 2 changed files with 85 additions and 21 deletions   Show diff stats
src/recommender.py
@@ -28,12 +28,14 @@ class RecommendationResult: @@ -28,12 +28,14 @@ class RecommendationResult:
28 """ 28 """
29 Class designed to describe a recommendation result: items and scores. 29 Class designed to describe a recommendation result: items and scores.
30 """ 30 """
31 - def __init__(self,item_score): 31 + def __init__(self,item_score,ranking=0):
32 """ 32 """
33 Set initial parameters. 33 Set initial parameters.
34 """ 34 """
35 self.item_score = item_score 35 self.item_score = item_score
36 self.size = len(item_score) 36 self.size = len(item_score)
  37 + if ranking:
  38 + self.ranking = ranking
37 39
38 def __str__(self): 40 def __str__(self):
39 """ 41 """
@@ -64,13 +66,13 @@ class Recommender: @@ -64,13 +66,13 @@ class Recommender:
64 """ 66 """
65 Set initial parameters. 67 Set initial parameters.
66 """ 68 """
  69 + self.cfg = cfg
67 self.items_repository = xapian.Database(cfg.axi) 70 self.items_repository = xapian.Database(cfg.axi)
68 self.set_strategy(cfg.strategy) 71 self.set_strategy(cfg.strategy)
69 if cfg.weight == "bm25": 72 if cfg.weight == "bm25":
70 self.weight = xapian.BM25Weight() 73 self.weight = xapian.BM25Weight()
71 else: 74 else:
72 self.weight = xapian.TradWeight() 75 self.weight = xapian.TradWeight()
73 - self.cfg = cfg  
74 76
75 def set_strategy(self,strategy_str): 77 def set_strategy(self,strategy_str):
76 """ 78 """
@@ -83,10 +85,10 @@ class Recommender: @@ -83,10 +85,10 @@ class Recommender:
83 if strategy_str == "cbd": 85 if strategy_str == "cbd":
84 self.strategy = strategy.ContentBasedStrategy("desc") 86 self.strategy = strategy.ContentBasedStrategy("desc")
85 if strategy_str == "col": 87 if strategy_str == "col":
86 - self.strategy = strategy.CollaborativeStrategy(20)  
87 self.users_repository = data.PopconXapianIndex(self.cfg) 88 self.users_repository = data.PopconXapianIndex(self.cfg)
  89 + self.strategy = strategy.CollaborativeStrategy(20)
88 90
89 - def get_recommendation(self,user,result_size=20): 91 + def get_recommendation(self,user,result_size=100):
90 """ 92 """
91 Produces recommendation using previously loaded strategy. 93 Produces recommendation using previously loaded strategy.
92 """ 94 """
src/strategy.py
@@ -42,6 +42,26 @@ class PkgMatchDecider(xapian.MatchDecider): @@ -42,6 +42,26 @@ class PkgMatchDecider(xapian.MatchDecider):
42 """ 42 """
43 return doc.get_data() not in self.pkgs_list 43 return doc.get_data() not in self.pkgs_list
44 44
  45 +class AppMatchDecider(xapian.MatchDecider):
  46 + """
  47 + Extend xapian.MatchDecider to not consider only applications packages.
  48 + """
  49 + def __init__(self, pkgs_list, axi):
  50 + """
  51 + Set initial parameters.
  52 + """
  53 + xapian.MatchDecider.__init__(self)
  54 + self.pkgs_list = pkgs_list
  55 + self.axi = axi
  56 +
  57 + def __call__(self, doc):
  58 + """
  59 + True if the package is not already installed.
  60 + """
  61 + tags = axi_search_pkg_tags(self.axi,doc.get_data())
  62 + return (("XTrole::program" in tags) and
  63 + (doc.get_data() not in self.pkgs_list))
  64 +
45 class UserMatchDecider(xapian.MatchDecider): 65 class UserMatchDecider(xapian.MatchDecider):
46 """ 66 """
47 Extend xapian.MatchDecider to match similar profiles. 67 Extend xapian.MatchDecider to match similar profiles.
@@ -73,7 +93,32 @@ class PkgExpandDecider(xapian.ExpandDecider): @@ -73,7 +93,32 @@ class PkgExpandDecider(xapian.ExpandDecider):
73 True if the term is a package. 93 True if the term is a package.
74 """ 94 """
75 # [FIXME] return term.startswith("XP") 95 # [FIXME] return term.startswith("XP")
76 - return not term.startswith("XT") 96 + #return not term.startswith("XT")
  97 + return term.startswith("XP")
  98 +
  99 +class AppExpandDecider(xapian.ExpandDecider):
  100 + """
  101 + Extend xapian.ExpandDecider to consider applications only.
  102 + """
  103 + def __init__(self,axi):
  104 + xapian.ExpandDecider.__init__(self)
  105 + self.axi = axi
  106 +
  107 + def __call__(self, term):
  108 + """
  109 + True if the term is a package.
  110 + """
  111 + if not term.startswith("XT"):
  112 + package = term.lstrip("XP")
  113 + print package
  114 + tags = axi_search_pkg_tags(self.axi,package)
  115 + if "XTrole::program" in tags:
  116 + print tags
  117 + return True
  118 + else:
  119 + return False
  120 + else:
  121 + return False
77 122
78 class TagExpandDecider(xapian.ExpandDecider): 123 class TagExpandDecider(xapian.ExpandDecider):
79 """ 124 """
@@ -100,7 +145,7 @@ class ContentBasedStrategy(RecommendationStrategy): @@ -100,7 +145,7 @@ class ContentBasedStrategy(RecommendationStrategy):
100 self.content = content 145 self.content = content
101 self.profile_size = profile_size 146 self.profile_size = profile_size
102 147
103 - def run(self,rec,user,limit): 148 + def run(self,rec,user,recommendation_size):
104 """ 149 """
105 Perform recommendation strategy. 150 Perform recommendation strategy.
106 """ 151 """
@@ -113,35 +158,40 @@ class ContentBasedStrategy(RecommendationStrategy): @@ -113,35 +158,40 @@ class ContentBasedStrategy(RecommendationStrategy):
113 enquire.set_query(query) 158 enquire.set_query(query)
114 try: 159 try:
115 # retrieve matching packages 160 # retrieve matching packages
116 - mset = enquire.get_mset(0, limit, None, PkgMatchDecider(user.items())) 161 + mset = enquire.get_mset(0, recommendation_size, None,
  162 + PkgMatchDecider(user.items()))
  163 + #AppMatchDecider(user.items(),
  164 + # rec.items_repository))
117 except xapian.DatabaseError as error: 165 except xapian.DatabaseError as error:
118 logging.critical("Content-based strategy: "+error.get_msg()) 166 logging.critical("Content-based strategy: "+error.get_msg())
119 # compose result dictionary 167 # compose result dictionary
120 item_score = {} 168 item_score = {}
  169 + ranking = []
121 for m in mset: 170 for m in mset:
  171 + #[FIXME] set this constraint somehow
  172 + #tags = axi_search_pkg_tags(rec.items_repository,m.document.get_data())
  173 + #if "XTrole::program" in tags:
122 item_score[m.document.get_data()] = m.weight 174 item_score[m.document.get_data()] = m.weight
123 - return recommender.RecommendationResult(item_score) 175 + ranking.append(m.document.get_data())
  176 +
  177 + return recommender.RecommendationResult(item_score,ranking)
124 178
125 class CollaborativeStrategy(RecommendationStrategy): 179 class CollaborativeStrategy(RecommendationStrategy):
126 """ 180 """
127 Colaborative recommendation strategy. 181 Colaborative recommendation strategy.
128 """ 182 """
129 - def __init__(self,k,clustering=1): 183 + def __init__(self,k):
130 self.description = "Collaborative" 184 self.description = "Collaborative"
131 - self.clustering = clustering  
132 self.neighbours = k 185 self.neighbours = k
133 186
134 - def run(self,rec,user,result_size): 187 + def run(self,rec,user,recommendation_size):
135 """ 188 """
136 Perform recommendation strategy. 189 Perform recommendation strategy.
137 """ 190 """
138 - profile = user.pkg_profile 191 + profile = ["XP"+package for package in user.pkg_profile]
139 # prepair index for querying user profile 192 # prepair index for querying user profile
140 query = xapian.Query(xapian.Query.OP_OR,profile) 193 query = xapian.Query(xapian.Query.OP_OR,profile)
141 - if self.clustering:  
142 - enquire = xapian.Enquire(rec.clustered_users_repository)  
143 - else:  
144 - enquire = xapian.Enquire(rec.users_repository) 194 + enquire = xapian.Enquire(rec.users_repository)
145 enquire.set_weighting_scheme(rec.weight) 195 enquire.set_weighting_scheme(rec.weight)
146 enquire.set_query(query) 196 enquire.set_query(query)
147 try: 197 try:
@@ -155,27 +205,39 @@ class CollaborativeStrategy(RecommendationStrategy): @@ -155,27 +205,39 @@ class CollaborativeStrategy(RecommendationStrategy):
155 rset.add_document(m.document.get_docid()) 205 rset.add_document(m.document.get_docid())
156 logging.debug(m.document.get_data()) 206 logging.debug(m.document.get_data())
157 # retrieve most relevant packages 207 # retrieve most relevant packages
158 - eset = enquire.get_eset(result_size,rset,PkgExpandDecider()) 208 + #eset = enquire.get_eset(recommendation_size,rset,
  209 + # AppExpandDecider(rec.items_repository))
  210 + eset = enquire.get_eset(recommendation_size,rset,PkgExpandDecider())
159 # compose result dictionary 211 # compose result dictionary
160 item_score = {} 212 item_score = {}
161 - for package in eset:  
162 - item_score[package.term.lstrip("XP")] = package.weight 213 + for e in eset:
  214 + package = e.term.lstrip("XP")
  215 + tags = axi_search_pkg_tags(rec.items_repository,package)
  216 + #[FIXME] set this constraint somehow
  217 + #if "XTrole::program" in tags:
  218 + item_score[package] = e.weight
163 return recommender.RecommendationResult(item_score) 219 return recommender.RecommendationResult(item_score)
164 220
165 class DemographicStrategy(RecommendationStrategy): 221 class DemographicStrategy(RecommendationStrategy):
166 """ 222 """
167 Recommendation strategy based on demographic data. 223 Recommendation strategy based on demographic data.
168 """ 224 """
  225 + #def __init__(self, result):
  226 + #self.result = result
169 def __init__(self): 227 def __init__(self):
170 self.description = "Demographic" 228 self.description = "Demographic"
171 logging.debug("Demographic recommendation not yet implemented.") 229 logging.debug("Demographic recommendation not yet implemented.")
172 raise Error 230 raise Error
173 231
174 - def run(self,user,items_repository): 232 + def run(self,rec,user,recommendation_size):
175 """ 233 """
176 Perform recommendation strategy. 234 Perform recommendation strategy.
177 """ 235 """
178 - pass 236 + ordered_result = self.result.get_prediction()
  237 +
  238 + for item,weight in ordered_result:
  239 + pass
  240 +
179 241
180 class KnowledgeBasedStrategy(RecommendationStrategy): 242 class KnowledgeBasedStrategy(RecommendationStrategy):
181 """ 243 """