def request_to_parameters(self, criticize_type, track, request_parameters): if criticize_type != TrackCriticizeType.Parameter and not track: raise Exception("Target track is None") parameters = [] if criticize_type == TrackCriticizeType.Parameter: if "bpm" in request_parameters: parameters.append(Parameter("bpm", request_parameters["bpm"])) elif criticize_type == TrackCriticizeType.Pattern: criticize = CriticizePattern(pattern=request_parameters["pattern"]) direction = criticize.get_direction() parameters.append(Parameter("pattern", criticize.pattern)) for c in criticize.get_targets(): parameters.append(Parameter(c.name, vector_utils.to_value(getattr(track, c.name)), direction)) elif criticize_type == TrackCriticizeType.Like: for c in self.__get_criticizables(): parameters.append(Parameter(c, vector_utils.to_value(getattr(track, c)))) if "q" in request_parameters and request_parameters["q"]: parameters.append(Parameter("q", request_parameters["q"])) if Parameter.first_or_default("genre", parameters) and not Parameter.first_or_default("genre_score", parameters): genre = Parameter.first_or_default("genre", parameters) if Track.genre_to_score(genre): g_score = Track.genre_to_score(genre) parameters.append(Parameter("genre_score", g_score)) return parameters
def is_fit_pattern(self, base_item, target_item): is_fit = [] if base_item is None or target_item is None: return False for p in self.get_targets(): base_value = vector_utils.to_value(getattr(base_item, p.name)) target_value = vector_utils.to_value(getattr(target_item, p.name)) v = 0 if target_value and base_value: if target_value > base_value: v = 1 elif target_value < base_value: v = -1 is_fit.append(v) if self.get_direction() == CriticizeDirection.Up and sum(is_fit) == len(is_fit): # pattern is positive, and exactly all pattern is True return True elif self.get_direction() == CriticizeDirection.Down and - sum(is_fit) == len(is_fit): # pattern is negative, and exactly all pattern is False return True elif self.get_direction() == CriticizeDirection.Around and sum(is_fit) == 0: # pattern is around, and exactly all pattern is equal return True else: return False
def __assert_vector_integrity(self, obj_list, target_attribute, is_print=True): attributes = vector_manager.to_vector(target_attribute, obj_list) self.assertEquals(len(obj_list), len(attributes)) for index, value in enumerate(attributes): if is_print: print(value) self.assertEquals(vector_manager.to_value(getattr(obj_list[index], target_attribute)), value)
def __normalize(cls, values, normalize_value_type="", prop=None): normalized = [] without_none = [x for x in values if x is not None] if len(without_none) == 0: return [None] * len(values) value_max = max(without_none) value_min = min(without_none) value_range = value_max - value_min if value_max == value_min: value_range = 1 value = vector_utils.to_value(prop) eval = lambda v, c: None if v is None else c(v) if value: normalized = [eval(v, lambda x: (x - value) / value_range) for v in values] elif normalize_value_type == "max": normalized = [eval(v, lambda x: (value_max - x) / value_range) for v in values] elif normalize_value_type == "min": normalized = [eval(v, lambda x: (x - value_min) / value_range) for v in values] else: mean = reduce(lambda a, b: a + b, without_none) / len(without_none) normalized = [eval(v, lambda x: (x - mean) / value_range) for v in values] return normalized
def is_fit_track(self, base_track, target_track): result = True parameters = self.track_to_parameters(base_track) for p in parameters: key = p.name target_value = vector_utils.to_value(target_track.__dict__[key]) if not self.is_none_or_empty(p.value) and not self.is_none_or_empty(target_value): compare_value = self.adjust_parameter(key, p.value, False) if compare_value and not (compare_value <= target_value <= self.adjust_parameter(key, p.value, True)): result = False return result
def calc_text_token_distance(cls, attr_name, item_list, selected_item): if selected_item and getattr(selected_item, attr_name): item_tokens = vector_utils.to_vector(attr_name, item_list) tokens = vector_utils.to_value(getattr(selected_item, attr_name)) clusters, vectors = vector_utils.make_text_clusters(item_tokens) target_vector = vector_utils.classify_text_tokens(tokens, clusters) distances = [vector_utils.calc_vector_distance(target_vector, v) for v in vectors] inv_distance = [4 if d == 0 else 1 - math.log(d) for d in distances] # 4 is large enough in f(x) = 1-log(x) return cls.normalize(inv_distance) else: raise NotCalculatable("selected item's " + attr_name + " is None")