Esempio n. 1
0
def generateModel(building_name, row_limit_per_location=25):
    """

    :param building_name: Name of building
    :rtype: ScikitModel
    :return: Machine learning model matching building
    """
    log_task_start("Generating model")
    column_names, rows, classes, rooms, null_value, most_recent = generateData(building_name, row_limit_per_location)
    model = ScikitModel(rows, classes, rooms, column_names, null_value, row_limit_per_location, most_recent)
    log_task_end("Generating model")
    return model
Esempio n. 2
0
def generateModel(building_name, row_limit_per_location=25):
    """

    :param building_name: Name of building
    :rtype: ScikitModel
    :return: Machine learning model matching building
    """
    log_task_start("Generating model")
    column_names, rows, classes, rooms, null_value, most_recent = generateData(
        building_name, row_limit_per_location)
    model = ScikitModel(rows, classes, rooms, column_names, null_value,
                        row_limit_per_location, most_recent)
    log_task_end("Generating model")
    return model
Esempio n. 3
0
 def add_fingerprint(self, fingerprint):
     self.last_updated = fingerprint.timestamp
     # check for input errors
     log_task_start("Adding fingerprint")
     assert fingerprint.confirmed and fingerprint.location is not None
     # check for new base station
     self.update_if_new_base_stations(fingerprint)
     # append new row (don't forget to append to both DATA and CLASSES)
     vector, scan_min = _to_row(self.column_names, self.null_value,
                                fingerprint)
     # check if we can append this fingerprint, or have to replace an existing old one
     if self.location_counts[
             fingerprint.location.pk] < self.row_limit_per_location:
         log.debug("Appending new row as existing location count, " +
                   str(self.location_counts[fingerprint.location.pk]) +
                   ", is less than limit, " +
                   str(self.row_limit_per_location))
         self.data.append(vector)
         self.classes.append(fingerprint.location.pk)
         # keep counter of fingerprints at this fingerprint's location up to date
         self.location_counts[fingerprint.location.pk] += 1
     else:
         log.debug(
             "Replaced old row with new, and updated old as existing location count, "
             + str(self.location_counts[fingerprint.location.pk]) +
             ", is greater than limit, " + str(self.row_limit_per_location))
         oldrow = self.oldest_fingerprints[fingerprint.location.pk]
         log.debug("Rownum replaced: " + str(oldrow))
         self.data[oldrow] = vector
         assert self.classes[oldrow] == fingerprint.location.pk
         # linear search for the next oldest instance
         oldrow += 1
         while self.classes[oldrow] != fingerprint.location.pk:
             oldrow += 1
             if oldrow == len(self.classes):
                 oldrow = 0
                 # oldrow now points to the next instance of the fingerprint location
         self.oldest_fingerprints[fingerprint.location.pk] = oldrow
         # check for new weakest signal
     self.update_if_weakest_signal(scan_min)
     log_task_start("Retraining model on updated data")
     log.debug(str(len(self.data)) + " rows")
     self.train()
     log_task_end("Retraining model on updated data")
     log_task_end("Adding fingerprint")
Esempio n. 4
0
def generateData(building_name, row_limit_per_location=25):
    log_task_start("Getting fingerprints from database")
    if row_limit_per_location > 0:
        locations = Location.objects.filter(building__name=building_name)
        matchingFingerprints = []
        for location in locations:
            # take only the most recent n fingerprints at each location
            fingerprintsAtLocation = \
                Fingerprint.objects.filter(location=location, confirmed=True) \
                    .order_by("-timestamp")[:row_limit_per_location]
            matchingFingerprints += fingerprintsAtLocation
    else:
        matchingFingerprints = \
            Fingerprint.objects.filter(location__building__name=building_name, confirmed=True)  # take all fingerprints
    column_names = _get_all_base_stations(matchingFingerprints)
    log_task_end("Getting fingerprints from database")
    log_task_start("Parsing into rows")
    rows, classes, rooms, null_value, most_recent = _to_rows(column_names, matchingFingerprints)
    log_task_end("Parsing into rows")
    return column_names, rows, classes, rooms, null_value, most_recent
Esempio n. 5
0
 def add_fingerprint(self, fingerprint):
     self.last_updated = fingerprint.timestamp
     # check for input errors
     log_task_start("Adding fingerprint")
     assert fingerprint.confirmed and fingerprint.location is not None
     # check for new base station
     self.update_if_new_base_stations(fingerprint)
     # append new row (don't forget to append to both DATA and CLASSES)
     vector, scan_min = _to_row(self.column_names, self.null_value, fingerprint)
     # check if we can append this fingerprint, or have to replace an existing old one
     if self.location_counts[fingerprint.location.pk] < self.row_limit_per_location:
         log.debug("Appending new row as existing location count, " + str(
             self.location_counts[fingerprint.location.pk]) + ", is less than limit, " + str(
             self.row_limit_per_location))
         self.data.append(vector)
         self.classes.append(fingerprint.location.pk)
         # keep counter of fingerprints at this fingerprint's location up to date
         self.location_counts[fingerprint.location.pk] += 1
     else:
         log.debug("Replaced old row with new, and updated old as existing location count, " + str(
             self.location_counts[fingerprint.location.pk]) + ", is greater than limit, " + str(
             self.row_limit_per_location))
         oldrow = self.oldest_fingerprints[fingerprint.location.pk]
         log.debug("Rownum replaced: " + str(oldrow))
         self.data[oldrow] = vector
         assert self.classes[oldrow] == fingerprint.location.pk
         # linear search for the next oldest instance
         oldrow += 1
         while self.classes[oldrow] != fingerprint.location.pk:
             oldrow += 1
             if oldrow == len(self.classes):
                 oldrow = 0
                 # oldrow now points to the next instance of the fingerprint location
         self.oldest_fingerprints[fingerprint.location.pk] = oldrow
         # check for new weakest signal
     self.update_if_weakest_signal(scan_min)
     log_task_start("Retraining model on updated data")
     log.debug(str(len(self.data)) + " rows")
     self.train()
     log_task_end("Retraining model on updated data")
     log_task_end("Adding fingerprint")
Esempio n. 6
0
def generateData(building_name, row_limit_per_location=25):
    log_task_start("Getting fingerprints from database")
    if row_limit_per_location > 0:
        locations = Location.objects.filter(building__name=building_name)
        matchingFingerprints = []
        for location in locations:
            # take only the most recent n fingerprints at each location
            fingerprintsAtLocation = \
                Fingerprint.objects.filter(location=location, confirmed=True) \
                    .order_by("-timestamp")[:row_limit_per_location]
            matchingFingerprints += fingerprintsAtLocation
    else:
        matchingFingerprints = \
            Fingerprint.objects.filter(location__building__name=building_name, confirmed=True)  # take all fingerprints
    column_names = _get_all_base_stations(matchingFingerprints)
    log_task_end("Getting fingerprints from database")
    log_task_start("Parsing into rows")
    rows, classes, rooms, null_value, most_recent = _to_rows(
        column_names, matchingFingerprints)
    log_task_end("Parsing into rows")
    return column_names, rows, classes, rooms, null_value, most_recent
Esempio n. 7
0
def confirm(request, fingerprint_pk, location_pk=-1):
    """Allows a kind client to confirm that the location sent was correct,
or alternatively send a new location for the fingerprint. This will cause
the building learning model to be updated to include the confirmed fingerprint,
improving performance for the user.

    If the location pk is not known, it can be determined if a location object is provided in the request body."""
    log_task_start("Confirm location request")
    stored_fingerprint = Fingerprint.objects.get(pk=fingerprint_pk)
    if not request.user.is_authenticated(
    ) or not request.user == stored_fingerprint.owner:
        print request.user
        print stored_fingerprint.owner
        return Response(data={
            'detail':
            "Only the owner of the fingerprint is allowed to modify it"
        },
                        status=403)
    if location_pk == -1:
        try:
            name = request.DATA['name']
            building_name = request.DATA['building_obj']['name']
        except Exception, e:
            log.error(
                "Could not retrieve name and building name from this message:"
                + str(request.DATA))
            log.exception(e)
        try:
            location = Location.objects.get(name=name,
                                            building__name=building_name)
        except ObjectDoesNotExist:
            location = Location.objects.create(name=name,
                                               building__name=building_name,
                                               owner=request.user)
            location.save()
        location_pk = location.pk
Esempio n. 8
0
def retrieve(request, limit):
    """
    Guesses the location at which the fingerprint was taken, and saves the fingerprint.

    If the limit argument is supplied, up to that number of results will be returned, in a list
    ordered by probability. Otherwise, limit defaults to 1.

    The parameters of the returned message are 'locations', and 'fingerprint_id'.

    {
        'locations': [best_matching_location, second_best_location,..., limit_matching_location],
        'fingerprint_id': fingerprint_id   // of the fingerprint that you sent
    }

    fingerprint -- A new fingerprint (see /fingerprints/)

    """
    log_task_start("Find current location request")
    limit = int(limit)
    f_dict = request.DATA['fingerprint']
    fingerprint = createFingerprint(f_dict, request.user)
    building_name = request.DATA['building']
    tracker = getTracker(building_name)
    if tracker is None:
        return Response(data={
            'detail':
            "Server is still loading data for that building... This usually occurs if "
            "the server had to be restarted for some reason. Please wait a few minutes "
            "and try again"
        },
                        status=503)  # 503 Service Unavailable
    if limit > 1:
        locations_ordered_by_prob = tracker.guess_all(fingerprint)
        log.debug("location id's ordered by prob: " +
                  str(locations_ordered_by_prob))
        # turn the pk's into locations
        locations_ordered_by_prob = map(
            lambda location_pk: Location.objects.get(pk=location_pk),
            locations_ordered_by_prob)
        # locations_prob_tuples.sort(key=lambda tup: tup[1])
        # log.debug("Tuples prob sorting: " + str(locations_prob_tuples))
        # locations_ordered_by_prob = map(lambda tup: tup[0], locations_prob_tuples)
    else:
        location = tracker.guess(fingerprint)
        location_obj = Location.objects.get(pk=location)
        locations_ordered_by_prob = [location_obj]
    log.debug("locations ordered by prob: " + str(locations_ordered_by_prob))
    try:
        fingerprint.location = locations_ordered_by_prob[0]
    except:
        log.warn("No locations found")
        pass
    fingerprint.save()
    # return the ordered list of locations, and an id for the new fingerprint
    if limit <= 1:
        log.debug("Invalid limit: " + str(limit))
        limit = 1
    serial = LocationViewSerializer(locations_ordered_by_prob[:limit],
                                    context={'request': request},
                                    many=True)
    response_data = {
        'locations': serial.data,
        'fingerprint_id': fingerprint.pk
    }
    # log.debug("response: "+str(response_data))  # remove me; verbose
    log_task_end("Find current location request")
    return Response(data=response_data)