def recalculate_concepts(self, concepts, lang=None): """ Recalculated given concepts for given users Args: concepts (dict): user id (int -> set of concepts to recalculate) lang(Optional[str]): language used to get items in all concepts (cached). Defaults to None, in that case are get items only in used concepts """ if len(concepts) == 0: return if lang is None: items = Concept.objects.get_concept_item_mapping(concepts=Concept.objects.filter(pk__in=set(flatten(concepts.values())))) else: items = Concept.objects.get_concept_item_mapping(lang=lang) environment = get_environment() mastery_threshold = get_mastery_trashold() for user, concepts in concepts.items(): all_items = list(set(flatten([items[c] for c in concepts]))) answer_counts = dict(list(zip(all_items, environment.number_of_answers_more_items(all_items, user)))) correct_answer_counts = dict(list(zip(all_items, environment.number_of_correct_answers_more_items(all_items, user)))) predictions = dict(list(zip(all_items, get_predictive_model(). predict_more_items(environment, user, all_items, time=None)))) new_user_stats = [] stats_to_delete_condition = Q() for concept in concepts: answer_aggregates = Answer.objects.filter(user=user, item__in=items[concept]).aggregate( time_spent=Sum("response_time"), sessions=Count("session", True), time_first=Min("time"), time_last=Max("time"), ) stats = { "answer_count": sum(answer_counts[i] for i in items[concept]), "correct_answer_count": sum(correct_answer_counts[i] for i in items[concept]), "item_count": len(items[concept]), "practiced_items_count": sum([answer_counts[i] > 0 for i in items[concept]]), "mastered_items_count": sum([predictions[i] >= mastery_threshold for i in items[concept]]), "prediction": sum([predictions[i] for i in items[concept]]) / len(items[concept]), "time_spent": answer_aggregates["time_spent"] / 1000, "session_count": answer_aggregates["sessions"], "time_first": answer_aggregates["time_first"].timestamp(), "time_last": answer_aggregates["time_last"].timestamp(), } stats_to_delete_condition |= Q(user=user, concept=concept) for stat_name, value in stats.items(): new_user_stats.append(UserStat(user_id=user, concept_id=concept, stat=stat_name, value=value)) self.filter(stats_to_delete_condition).delete() self.bulk_create(new_user_stats)
def prediction(request, json_list, nested): if 'stats' not in request.GET: return object_item_ids = [x['item_id'] for x in json_list] user = get_user_id(request) time = models.get_time_for_knowledge_overview(request) predictions = _predictive_model().predict_more_items(_environment(request), user, object_item_ids, time) mastery_threshold = get_mastery_trashold() for object_json, prediction in zip(json_list, predictions): object_json['prediction'] = float("{0:.2f}".format(prediction)) object_json['mastered'] = prediction >= mastery_threshold if "new_user_predictions" in request.GET: user = -1 predictions = _predictive_model().predict_more_items(_environment(request), user, object_item_ids, time) for object_json, prediction in zip(json_list, predictions): object_json['new_user_prediction'] = float("{0:.2f}".format(prediction)) return json_list
def avg_prediction(request, json_list, nested): if 'stats' not in request.GET: return object_item_ids = [x['item_id'] for x in json_list] leaves = models.Item.objects.get_leaves(object_item_ids, language=get_language(request)) all_leaves = list(set(flatten(leaves.values()))) user = get_user_id(request) time = models.get_time_for_knowledge_overview(request) predictions = dict(list(zip(all_leaves, _predictive_model().predict_more_items( _environment(request), user, all_leaves, time )))) mastery_threshold = get_mastery_trashold() for object_json in json_list: leaf_predictions = [predictions[leave] for leave in leaves[object_json['item_id']]] object_json['avg_predicton'] = numpy.mean(leaf_predictions) object_json['mastered'] = sum([p > mastery_threshold for p in leaf_predictions])
def recalculate_concepts(self, concepts, lang=None): """ Recalculated given concepts for given users Args: concepts (dict): user id (int -> set of concepts to recalculate) lang(Optional[str]): language used to get items in all concepts (cached). Defaults to None, in that case are get items only in used concepts """ if len(concepts) == 0: return if lang is None: items = Concept.objects.get_concept_item_mapping( concepts=Concept.objects.filter( pk__in=set(flatten(concepts.values())))) else: items = Concept.objects.get_concept_item_mapping(lang=lang) environment = get_environment() mastery_threshold = get_mastery_trashold() for user, concepts in concepts.items(): all_items = list(set(flatten([items[c] for c in concepts]))) answer_counts = dict( list( zip( all_items, environment.number_of_answers_more_items( all_items, user)))) correct_answer_counts = dict( list( zip( all_items, environment.number_of_correct_answers_more_items( all_items, user)))) predictions = dict( list( zip( all_items, get_predictive_model().predict_more_items(environment, user, all_items, time=None)))) new_user_stats = [] stats_to_delete_condition = Q() for concept in concepts: answer_aggregates = Answer.objects.filter( user=user, item__in=items[concept]).aggregate( time_spent=Sum("response_time"), sessions=Count("session", True), time_first=Min("time"), time_last=Max("time"), ) stats = { "answer_count": sum(answer_counts[i] for i in items[concept]), "correct_answer_count": sum(correct_answer_counts[i] for i in items[concept]), "item_count": len(items[concept]), "practiced_items_count": sum([answer_counts[i] > 0 for i in items[concept]]), "mastered_items_count": sum([ predictions[i] >= mastery_threshold for i in items[concept] ]), "prediction": sum([predictions[i] for i in items[concept]]) / len(items[concept]), "time_spent": answer_aggregates["time_spent"] / 1000, "session_count": answer_aggregates["sessions"], "time_first": answer_aggregates["time_first"].timestamp(), "time_last": answer_aggregates["time_last"].timestamp(), } stats_to_delete_condition |= Q(user=user, concept=concept) for stat_name, value in stats.items(): new_user_stats.append( UserStat(user_id=user, concept_id=concept, stat=stat_name, value=value)) self.filter(stats_to_delete_condition).delete() self.bulk_create(new_user_stats)