Skip to content

Commit

Permalink
Merge pull request #546 from Ilhasoft/feature/add_router_compare_results
Browse files Browse the repository at this point in the history
Feature/add router compare results
  • Loading branch information
mldzs committed Mar 1, 2021
2 parents 9d33685 + 88c95af commit aaf41fa
Show file tree
Hide file tree
Showing 3 changed files with 171 additions and 0 deletions.
16 changes: 16 additions & 0 deletions bothub/api/v2/evaluate/views.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from django.utils.decorators import method_decorator
from drf_yasg2 import openapi
from drf_yasg2.utils import swagger_auto_schema
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet
from rest_framework import mixins
from rest_framework.permissions import IsAuthenticatedOrReadOnly
Expand Down Expand Up @@ -186,3 +188,17 @@ def retrieve(self, request, *args, **kwargs):
self.serializer_class = RepositoryEvaluateResultSerializer
self.filter_class = EvaluateResultFilter
return super().retrieve(request, *args, **kwargs)

@action(detail=False, methods=["GET"], url_name="compare_results")
def compare_results(self, request, **kwargs):
try:
results_ids_to_compare = request.query_params.get("ids", "").split(",")
results = self.get_queryset().filter(pk__in=results_ids_to_compare)
serializer = RepositoryEvaluateResultSerializer(results, many=True, context={"request": request})
except ValueError:
return Response(
{"detail": "Send only integers in the 'ids' parameter. If there is a ',' left, remove it."},
400
)

return Response(serializer.data, 200)
8 changes: 8 additions & 0 deletions bothub/api/v2/routers.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@

class Router(routers.SimpleRouter):
routes = [
# Dynamically generated list routes. Generated using
# @action(detail=False) decorator on methods of the viewset.
routers.DynamicRoute(
url=r'^{prefix}/{url_path}{trailing_slash}$',
name='{basename}-{url_name}',
detail=False,
initkwargs={}
),
# Dynamically generated list routes.
# Generated using @action decorator
# on methods of the viewset.
Expand Down
147 changes: 147 additions & 0 deletions bothub/api/v2/tests/test_evaluate.py
Original file line number Diff line number Diff line change
Expand Up @@ -860,3 +860,150 @@ def test_crossvalidation_true_filter(self):
self.assertEqual(content_data["cross_validation"], True)
self.assertEqual(len(content_data["log"]["results"]), 0)
self.assertEqual(response.status_code, status.HTTP_200_OK)


class CompareEvaluateResultsTestCase(TestCase):
def setUp(self):
self.factory = RequestFactory()

self.owner, self.owner_token = create_user_and_token("owner")
self.user, self.token = create_user_and_token()

self.repository = Repository.objects.create(
owner=self.owner,
name="Testing",
slug="test",
language=languages.LANGUAGE_EN,
)

for x in range(0, 2):
intent_results = RepositoryEvaluateResultScore.objects.create(
f1_score=0.976, precision=0.978, accuracy=0.976
)

entity_results = RepositoryEvaluateResultScore.objects.create(
f1_score=0.977, precision=0.978, accuracy=0.978
)

evaluate_log = [
{
"text": "hey",
"intent": "greet",
"intent_prediction": {
"name": "greet",
"confidence": 0.9263743763408538,
},
"status": "success",
},
{
"text": "howdy",
"intent": "greet",
"intent_prediction": {
"name": "greet",
"confidence": 0.8099720606047796,
},
"status": "success",
},
{
"text": "hey there",
"intent": "greet",
"intent_prediction": {
"name": "greet",
"confidence": 0.8227075176309955,
},
"status": "success",
},
{
"text": "test with nlu",
"intent": "restaurant_search",
"intent_prediction": {
"name": "goodbye",
"confidence": 0.3875259420712092,
},
"status": "error",
},
]

sample_url = "https://s3.amazonaws.com/bothub-sample"
evaluate_result = RepositoryEvaluateResult.objects.create(
repository_version_language=self.repository.current_version(),
intent_results=intent_results,
entity_results=entity_results,
matrix_chart="{}/confmat.png".format(sample_url),
confidence_chart="{}/hist.png".format(sample_url),
log=json.dumps(evaluate_log),
)

intent_score_1 = RepositoryEvaluateResultScore.objects.create(
precision=1.0, recall=1.0, f1_score=1.0, support=11
)

intent_score_2 = RepositoryEvaluateResultScore.objects.create(
precision=0.89, recall=1.0, f1_score=0.94, support=8
)

intent_score_3 = RepositoryEvaluateResultScore.objects.create(
precision=1.0, recall=1.0, f1_score=1.0, support=8
)

intent_score_4 = RepositoryEvaluateResultScore.objects.create(
precision=1.0, recall=0.93, f1_score=0.97, support=15
)

RepositoryEvaluateResultIntent.objects.create(
evaluate_result=evaluate_result, intent="affirm", score=intent_score_1
)

RepositoryEvaluateResultIntent.objects.create(
evaluate_result=evaluate_result, intent="goodbye", score=intent_score_2
)

RepositoryEvaluateResultIntent.objects.create(
evaluate_result=evaluate_result, intent="greet", score=intent_score_3
)

RepositoryEvaluateResultIntent.objects.create(
evaluate_result=evaluate_result,
intent="restaurant_search",
score=intent_score_4,
)

entity_score_1 = RepositoryEvaluateResultScore.objects.create(
precision=1.0, recall=0.90, f1_score=0.95, support=10
)

entity_score_2 = RepositoryEvaluateResultScore.objects.create(
precision=1.0, recall=0.75, f1_score=0.86, support=8
)

RepositoryEvaluateResultEntity.objects.create(
evaluate_result=evaluate_result, entity="cuisine", score=entity_score_1
)

RepositoryEvaluateResultEntity.objects.create(
evaluate_result=evaluate_result, entity="greet", score=entity_score_2
)

def request(self, token):
ids = f"{RepositoryEvaluateResult.objects.first().pk},{RepositoryEvaluateResult.objects.last().pk}"
authorization_header = {"HTTP_AUTHORIZATION": "Token {}".format(token.key)}
request = self.factory.get(
"/v2/evaluate/results/compare_results/?repository_uuid={}&ids={}".format(self.repository.uuid, ids),
**authorization_header,
)
response = ResultsListViewSet.as_view({"get": "compare_results"})(
request, repository_uuid=self.repository.uuid
)
response.render()
content_data = json.loads(response.content)
return (response, content_data)

def test_okay(self):
response, content_data = self.request(self.owner_token)
self.assertEqual(len(response.data), 2)
self.assertEqual(response.status_code, status.HTTP_200_OK)

def test_compare_two_results(self):
response, content_data = self.request(self.owner_token)
self.assertEqual(RepositoryEvaluateResult.objects.last().pk, response.data[1].get("id"))
self.assertEqual(RepositoryEvaluateResult.objects.first().pk, response.data[0].get("id"))

0 comments on commit aaf41fa

Please sign in to comment.