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 28 """
29 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 33 Set initial parameters.
34 34 """
35 35 self.item_score = item_score
36 36 self.size = len(item_score)
  37 + if ranking:
  38 + self.ranking = ranking
37 39  
38 40 def __str__(self):
39 41 """
... ... @@ -64,13 +66,13 @@ class Recommender:
64 66 """
65 67 Set initial parameters.
66 68 """
  69 + self.cfg = cfg
67 70 self.items_repository = xapian.Database(cfg.axi)
68 71 self.set_strategy(cfg.strategy)
69 72 if cfg.weight == "bm25":
70 73 self.weight = xapian.BM25Weight()
71 74 else:
72 75 self.weight = xapian.TradWeight()
73   - self.cfg = cfg
74 76  
75 77 def set_strategy(self,strategy_str):
76 78 """
... ... @@ -83,10 +85,10 @@ class Recommender:
83 85 if strategy_str == "cbd":
84 86 self.strategy = strategy.ContentBasedStrategy("desc")
85 87 if strategy_str == "col":
86   - self.strategy = strategy.CollaborativeStrategy(20)
87 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 93 Produces recommendation using previously loaded strategy.
92 94 """
... ...
src/strategy.py
... ... @@ -42,6 +42,26 @@ class PkgMatchDecider(xapian.MatchDecider):
42 42 """
43 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 65 class UserMatchDecider(xapian.MatchDecider):
46 66 """
47 67 Extend xapian.MatchDecider to match similar profiles.
... ... @@ -73,7 +93,32 @@ class PkgExpandDecider(xapian.ExpandDecider):
73 93 True if the term is a package.
74 94 """
75 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 123 class TagExpandDecider(xapian.ExpandDecider):
79 124 """
... ... @@ -100,7 +145,7 @@ class ContentBasedStrategy(RecommendationStrategy):
100 145 self.content = content
101 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 150 Perform recommendation strategy.
106 151 """
... ... @@ -113,35 +158,40 @@ class ContentBasedStrategy(RecommendationStrategy):
113 158 enquire.set_query(query)
114 159 try:
115 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 165 except xapian.DatabaseError as error:
118 166 logging.critical("Content-based strategy: "+error.get_msg())
119 167 # compose result dictionary
120 168 item_score = {}
  169 + ranking = []
121 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 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 179 class CollaborativeStrategy(RecommendationStrategy):
126 180 """
127 181 Colaborative recommendation strategy.
128 182 """
129   - def __init__(self,k,clustering=1):
  183 + def __init__(self,k):
130 184 self.description = "Collaborative"
131   - self.clustering = clustering
132 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 189 Perform recommendation strategy.
137 190 """
138   - profile = user.pkg_profile
  191 + profile = ["XP"+package for package in user.pkg_profile]
139 192 # prepair index for querying user profile
140 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 195 enquire.set_weighting_scheme(rec.weight)
146 196 enquire.set_query(query)
147 197 try:
... ... @@ -155,27 +205,39 @@ class CollaborativeStrategy(RecommendationStrategy):
155 205 rset.add_document(m.document.get_docid())
156 206 logging.debug(m.document.get_data())
157 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 211 # compose result dictionary
160 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 219 return recommender.RecommendationResult(item_score)
164 220  
165 221 class DemographicStrategy(RecommendationStrategy):
166 222 """
167 223 Recommendation strategy based on demographic data.
168 224 """
  225 + #def __init__(self, result):
  226 + #self.result = result
169 227 def __init__(self):
170 228 self.description = "Demographic"
171 229 logging.debug("Demographic recommendation not yet implemented.")
172 230 raise Error
173 231  
174   - def run(self,user,items_repository):
  232 + def run(self,rec,user,recommendation_size):
175 233 """
176 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 242 class KnowledgeBasedStrategy(RecommendationStrategy):
181 243 """
... ...