How to specify hyperparameter configuration to enable HPO in Amazon Personalize? - amazon-web-services

Do we need to specify the hyperparameters both in algorithmHyperParameters and algorithmHyperParameterRanges? If yes, then should we specify a single value (string as per documentation) in algorithmHyperParameters, but a range (integer in case of integer-valued hyperparameter) in algorithmHyperParameterRanges?
For example: Similar-Items recipe has an integer-valued hyperparameter item_id_hidden_dimension. If I use the following solution_config, where item_id_hidden_dimension is specified only in algorithmHyperParameterRanges and not in algorithmHyperParameters, I get the error:
An error occurred (InvalidInputException) when calling the CreateSolution operation: Provide a hyperparameter that is used in the algorithm: arn:aws:personalize:::algorithm/aws-similar-items
"solution_config": {
"algorithmHyperParameters": {},
"hpoConfig": {
"algorithmHyperParameterRanges": {
"integerHyperParameterRanges": [
{
"name": "item_id_hidden_dimension",
"minValue": 30,
"maxValue": 200
}
],
"categoricalHyperParameterRanges": [],
"continuousHyperParameterRanges": []
},
"hpoResourceConfig": {
"maxNumberOfTrainingJobs": "4",
"maxParallelTrainingJobs": "2"
}
}
}
But if I use the following solution_config, where item_id_hidden_dimension is specified both in algorithmHyperParameterRanges and in algorithmHyperParameters, I still get the same error:
An error occurred (InvalidInputException) when calling the CreateSolution operation: Provide a hyperparameter that is used in the algorithm: arn:aws:personalize:::algorithm/aws-similar-items
"solution_config": {
"algorithmHyperParameters": {
"item_id_hidden_dimension": "100"
},
"hpoConfig": {
"algorithmHyperParameterRanges": {
"integerHyperParameterRanges": [
{
"name": "item_id_hidden_dimension",
"minValue": 30,
"maxValue": 200
}
],
"categoricalHyperParameterRanges": [],
"continuousHyperParameterRanges": []
},
"hpoResourceConfig": {
"maxNumberOfTrainingJobs": "4",
"maxParallelTrainingJobs": "2"
}
}
}

This is caused by an error in the documentation. The hyperparameter names should be item_id_hidden_dim and item_metadata_hidden_dim (note they are dim and not dimension as the documentation states).
This can be confirmed by calling the DescribeRecipe API to get the algorithmArn for the Similar-Items recipe and then calling the DescribeAlgorithm API to get details on the algorithm.
import boto3
import json
personalize = boto3.client('personalize')
response = personalize.describe_recipe(recipeArn = 'arn:aws:personalize:::recipe/aws-similar-items')
print(json.dumps(response['recipe'], indent=2, default=str))
{
"name": "aws-similar-items",
"recipeArn": "arn:aws:personalize:::recipe/aws-similar-items",
"algorithmArn": "arn:aws:personalize:::algorithm/aws-similar-items",
"featureTransformationArn": "arn:aws:personalize:::feature-transformation/similar-items",
"status": "ACTIVE",
"description": "Predicts items similar to a given item based on co-occurrence of items in the user-item interactions dataset and item metadata in the item dataset.",
"creationDateTime": "2019-06-10 00:00:00+00:00",
"recipeType": "RELATED_ITEMS",
"lastUpdatedDateTime": "2022-08-17 00:25:42.935000+00:00"
}
algo_arn = response['recipe']['algorithmArn']
response = personalize.describe_algorithm(algorithmArn = algo_arn)
print(json.dumps(response['algorithm'], indent=2, default=str))
{
"name": "aws-similar-items",
"algorithmArn": "arn:aws:personalize:::algorithm/aws-similar-items",
"algorithmImage": {
"name": "Item Similarity"
},
"defaultHyperParameters": {
"item_id_hidden_dim": "100",
"item_metadata_hidden_dim": "100"
},
"defaultHyperParameterRanges": {
"integerHyperParameterRanges": [
{
"name": "item_id_hidden_dim",
"minValue": 30,
"maxValue": 200,
"isTunable": true
},
{
"name": "item_metadata_hidden_dim",
"minValue": 30,
"maxValue": 200,
"isTunable": true
}
],
"continuousHyperParameterRanges": [],
"categoricalHyperParameterRanges": []
},
"defaultResourceConfig": {
"maxNumberOfTrainingJobs": "20",
"maxParallelTrainingJobs": "5"
},
"trainingInputMode": "File",
"creationDateTime": "2019-06-10 00:00:00+00:00",
"lastUpdatedDateTime": "2022-08-17 00:24:41.307000+00:00"
}
Note the hyperparameter names in the last response above.
We will get this error fixed in the documentation ASAP.

Related

google-cloud-recommendation How to get next page for Prediction?

I want to use predict method in order to get recommendation devided by page.
This method has pageToken parameter used for paging. The parameter should be received in the previous prediction response.
But this method in v2 API doesn't return pageToken or nextPageToken that is in v1beta1 API.
Why it disappeared? How can I get next page for prediction?
Request url is
https://retail.googleapis.com/v2/projects/{PROJECT_NUMBER}/locations/global/catalogs/default_catalog/placements/recently_viewed_default:predict
Request body is
{
"filter": "tag=(\"成人作品\") filterOutOfStockItems",
"userEvent": {
"eventType": "home-page-view",
"visitorId": "1254704470.1607003607",
"productDetails": [
{
"product": {
"id": "220604"
},
"quantity": 1
}
]
}
}
The response is here. There is no nextPageToken
{
"results": [
{
"id": "170706"
},
{
"id": "64081"
},
:
(snip)
:
{
"id": "132940"
},
{
"id": "17557"
}
],
"attributionToken": "ChQxNzkzOTg1NDI3MTk1OTMyNzU0MhACGiNvZnRlbl9wdXJjX2ZyZXF1ZW50bHlfMTYxNDMwNjk3OTQyNSIYb2Z0ZW5fcHVyY2hhc2VkX3RvZ2V0aGVyKAA"
}

How to I get just the temperature from the new google SDM for nest thermostat

Using : Get
https://smartdevicemanagement.googleapis.com/v1/enterprises/project-id/devices/device-id/
It returns all the info below. i just want the temperature. I am using postnam with: Content-Type and Authorization.
{
"name": "enterprises/c7ad210f-e05d-418c-a52a-1efc0891b3cf/devices/AVPHwEu-AUnrc2QEy_wmf7_u1hXWh_fH2V4q_DA5S1C3_bnLc2H-IxPEsNKtbc5NJZGCXFNAgK9HyZ96slFUQuyShlqauw",
"type": "sdm.devices.types.THERMOSTAT",
"assignee": "enterprises/c7ad210f-e05d-418c-a52a-1efc0891b3cf/structures/AVPHwEsL0trQSBq4GoBJFNrt_eBujz2A9uQvOxg112ZkvUSGMw3A2l3BBFGrLQ-Q8nyc-Mvvqb-Dy6YabT4625fGH1fcIg/rooms/AVPHwEuauRh8KXX1R_kRoTnxKUXRomQ_u80JOyjhfVKKCbn-OPPPigjoAOIJ7kFFwy1-PEs9z6BIP4DugImZLQ2bL59Uv0nZuHLjVsb0If9q0-pGQZcFgY5dxx7iIX63GuIezOW4paE8NNE",
"traits": {
"sdm.devices.traits.Info": {
"customName": ""
},
"sdm.devices.traits.Humidity": {
"ambientHumidityPercent": 63
},
"sdm.devices.traits.Connectivity": {
"status": "ONLINE"
},
"sdm.devices.traits.Fan": {},
"sdm.devices.traits.ThermostatMode": {
"mode": "HEAT",
"availableModes": [
"HEAT",
"OFF"
]
},
"sdm.devices.traits.ThermostatEco": {
"availableModes": [
"OFF",
"MANUAL_ECO"
],
"mode": "OFF",
"heatCelsius": 8.82,
"coolCelsius": 24.44443
},
"sdm.devices.traits.ThermostatHvac": {
"status": "OFF"
},
"sdm.devices.traits.Settings": {
"temperatureScale": "CELSIUS"
},
"sdm.devices.traits.ThermostatTemperatureSetpoint": {
"heatCelsius": 16
},
"sdm.devices.traits.Temperature": {
"ambientTemperatureCelsius": 20.23
}
},
"parentRelations": [
{
"parent": "enterprises/c7ad210f-e05d-418c-a52a-1efc0891b3cf/structures/AVPHwEsL0trQSBq4GoBJFNrt_eBujz2A9uQvOxg112ZkvUSGMw3A2l3BBFGrLQ-Q8nyc-Mvvqb-Dy6YabT4625fGH1fcIg/rooms/AVPHwEuauRh8KXX1R_kRoTnxKUXRomQ_u80JOyjhfVKKCbn-OPPPigjoAOIJ7kFFwy1-PEs9z6BIP4DugImZLQ2bL59Uv0nZuHLjVsb0If9q0-pGQZcFgY5dxx7iIX63GuIezOW4paE8NNE",
"displayName": "Hallway"
}
]
}
According to the API documentation, it's not possible to only get the temperature.
But you can get it from the response body you posted, in Postman's test tab:
const resBody = pm.response.json();
temperature = resBody.traits['sdm.devices.traits.Temperature'].ambientTemperatureCelsius;
console.log(temperature);

Monitoring api in Google gives "By" as response

I am reading monitoring data through Google Timeseries api. The api is working correctly and if give alignment period=3600s it gives me the values for that time series between start and end time for any metric type.
I am calling it through Python like this:
service.projects().timeSeries().list(
name=api_args["project_name"],
filter=api_args["metric_filter"],
aggregation_alignmentPeriod=api_args["aggregation_alignment_period"],
# aggregation_crossSeriesReducer=api_args["crossSeriesReducer"],
aggregation_perSeriesAligner=api_args["perSeriesAligner"],
aggregation_groupByFields=api_args["group_by"],
interval_endTime=api_args["end_time_str"],
interval_startTime=api_args["start_time_str"],
pageSize=config.PAGE_SIZE,
pageToken=api_args["nextPageToken"]
).execute()
and in Postman:
https://monitoring.googleapis.com/v3/projects/my-project/timeSeries?pageSize=500&interval.startTime=2020-07-04T16%3A39%3A37.230000Z&aggregation.alignmentPeriod=3600s&aggregation.perSeriesAligner=ALIGN_SUM&filter=metric.type%3D%22compute.googleapis.com%2Finstance%2Fnetwork%2Freceived_bytes_count%22+&pageToken=&interval.endTime=2020-07-04T17%3A30%3A01.497Z&alt=json&aggregation.groupByFields=metric.labels.key
I face an issue here:
{
"metric": {
"labels": {
"instance_name": "insta-demo1",
"loadbalanced": "false"
},
"type": "compute.googleapis.com/instance/network/received_bytes_count"
},
"resource": {
"type": "gce_instance",
"labels": {
"instance_id": "1234343552",
"zone": "us-central1-f",
"project_id": "my-project"
}
},
"metricKind": "DELTA",
"valueType": "INT64",
"points": [
{
"interval": {
"startTime": "2020-07-04T16:30:01.497Z",
"endTime": "2020-07-04T17:30:01.497Z"
},
"value": {
"int64Value": "6720271"
}
}
]
},
{
"metric": {
"labels": {
"loadbalanced": "true",
"instance_name": "insta-demo2"
},
"type": "compute.googleapis.com/instance/network/received_bytes_count"
},
"resource": {
"type": "gce_instance",
"labels": {
"instance_id": "1234566343",
"project_id": "my-project",
"zone": "us-central1-f"
}
},
"metricKind": "DELTA",
"valueType": "INT64",
"points": [
{
"interval": {
"startTime": "2020-07-04T16:30:01.497Z",
"endTime": "2020-07-04T17:30:01.497Z"
},
"value": {
"int64Value": "579187"
}
}
]
}
],
"unit": "By". //This "By" is the value which is causing problem,
I am getting this value like "unit": "By" or "unit":"ms" or something like that at the end, Also if I don't find any data for a range I'm getting this value, as I am evaluating this response in Python I am getting key error as there is not key called "unit"
logMessage: "Key Error: ' '"
severity: "ERROR"
As the response is empty I am getting the single key called "unit". Also at the end of any response I am getting this "unit":"ms" or "unit":"by" - is there any way to prevent that unit value coming in the response?
I am new to Google Cloud APIs and Python. What can I try next?
The "unit" field expresses the kind of resource the metric is counting. For bytes, it is "By". Read this. I understand it is always returned, so there is no way of not receiving it; I recommend you to adapt your code to correctly deal with its appearance in the responses.

Is there any way to sort the result of Lambda function of DynamoDB?

I am using AWS Lambda to get result from Dynamo DB. The returned result from Lambda is this:
Response:
{
"Items": [
{
"name": "unknown",
"rid": "1589816220971",
"rtime": "2020-05-18 23:37:12",
"status": "unsuccessful"
},
{
"name": "acap",
"rid": "1589816876343",
"rtime": "2020-05-18 23:48:10",
"status": "successful"
},
],
"Count": 2,
"ScannedCount": 2
}
But i wanted the returned result inverted as this because i want the recent result first.
Response:
{
"Items": [
{
"name": "acap",
"rid": "1589816876343",
"rtime": "2020-05-18 23:48:10",
"status": "successful"
},
{
"name": "unknown",
"rid": "1589816220971",
"rtime": "2020-05-18 23:37:12",
"status": "unsuccessful"
},
],
"Count": 2,
"ScannedCount": 2
}
Is there any way of doing that or more better way to return the latest item first from DynamoDB using Lambda?

Unable to map a list of numbers in API-Gateway

How do I create a mapping for a list of numbers object in API gateway? I am trying to post a list of integers using POST request. I tried working with NS attribute but got the Error.
Error:
{
"__type": "com.amazon.coral.service#SerializationException"
}
However, it works well when I have N attribute and post a single integer value.
Is there any way to resolve this issue?
I believe you are trying to map your request payload to DynamoDB JSON String. You can apply a velocity template like this one,
{
"TableName":"ABC",
"Item": {
"id": {
"S": "$context.requestId"
},
"name": {
"S": "$input.path('$.name')"
},
"price": {
"L": [
#set($prices=$input.path('$.price'))
#foreach($p in $prices)
{
"N": "$p"
}#if ($velocityCount < $prices.size()), #end
#end
]
}
}
}
Method Request Body:
{
"name":"Test",
"price": [1, 2, 3]
}
Endpoint Request Body:
{
"TableName": "ABC",
"Item": {
"id": {
"S": "test-invoke-request"
},
"name": {
"S": "Test"
},
"price": {
"L": [
{
"N": "1"
},
{
"N": "2"
},
{
"N": "3"
}
]
}
}
}