Пример #1
0
    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)
Пример #2
0
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
Пример #3
0
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])
Пример #4
0
    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)