{"id":23093184,"url":"https://github.com/crispengari/ahd-detector","last_synced_at":"2026-04-08T16:04:27.981Z","repository":{"id":141093703,"uuid":"485786999","full_name":"CrispenGari/ahd-detector","owner":"CrispenGari","description":"♻ Automatic Humour Detector (AHD) is an artificial intelligent project based on Natural Language Processing (NLP) classification task for predicting wether there's humour in given text or not.","archived":false,"fork":false,"pushed_at":"2022-08-29T15:11:20.000Z","size":66457,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-07-06T23:06:48.106Z","etag":null,"topics":["artificial-intelligence","deep-learning","flask","graphene","javascript","machine-learning","natural-language-processing","nlp","nueral-networks","pytorch","rest-api","tensorflow","text-classification","torchtext","typescript"],"latest_commit_sha":null,"homepage":"","language":"Jupyter Notebook","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CrispenGari.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-04-26T12:58:34.000Z","updated_at":"2022-05-17T06:48:35.000Z","dependencies_parsed_at":null,"dependency_job_id":"116b9e23-0e98-4ec9-a646-61df8d4a1d16","html_url":"https://github.com/CrispenGari/ahd-detector","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/CrispenGari/ahd-detector","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CrispenGari%2Fahd-detector","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CrispenGari%2Fahd-detector/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CrispenGari%2Fahd-detector/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CrispenGari%2Fahd-detector/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CrispenGari","download_url":"https://codeload.github.com/CrispenGari/ahd-detector/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CrispenGari%2Fahd-detector/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31562709,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-08T14:31:17.711Z","status":"ssl_error","status_checked_at":"2026-04-08T14:31:17.202Z","response_time":54,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["artificial-intelligence","deep-learning","flask","graphene","javascript","machine-learning","natural-language-processing","nlp","nueral-networks","pytorch","rest-api","tensorflow","text-classification","torchtext","typescript"],"created_at":"2024-12-16T21:46:38.925Z","updated_at":"2026-04-08T16:04:27.962Z","avatar_url":"https://github.com/CrispenGari.png","language":"Jupyter Notebook","funding_links":[],"categories":[],"sub_categories":[],"readme":"### Automatic Humour Detection (AHD)\n\nIn this repository I present an Application Programable Interface (API) for both `REST` and `GraphQL` in Natural Language Processing(NLP) on the topic Automatic Humour Detection (AHD) on short text.\n\n\u003cimg src=\"/images/cover.jpg\" alt=\"cover\" width=\"100%\"/\u003e\n\n---\n\nProject: `Automatic Humour Detection (AHD)`\n\nProgrammer: `@crispengari`\n\nDate: `2022-04-26`\n\nAbstract: _`Automatic Humour Detection (AHD) is a very useful topic in modern technologies. In this project we are going to create an Artificial Neural Network model(s) using Deep Learning to detect humour in short texts. AHD are very useful because in model technologies such as virtual assistance and chatbots. They help Artificial Virtual Assistance and Bot to detect wether to take the conversation serious or not`._\n\nResearch Paper: [`2004.12765`](https://arxiv.org/abs/2004.12765)\n\nKeywords: `pytorch`, `embedding`, `torchtext`, `fast-text`, `LSTM`, `RNN`, `CNN`, `tensorflow`, `keras`, `flask`, `graphql`, `rest`, `bi-directional`,\n`api`\n\nProgramming Language: `python`\n\nDataset: [`kaggle`](https://www.kaggle.com/datasets/deepcontractor/200k-short-texts-for-humor-detection)\n\n--\n\n### Approach\n\nI'm going to create two artificial neural network models using `python` and `pytorch`. These models will serve a basic binary classification on text.\n\nThe `tensorflow` model will be built using `bi-direction` Long Short Term Memory(LSTM) layers and Gated Recurrent Unit (GRU) together with some layers such as the `Flatten`, `Dropout` , `Dense`. This model will be built using the functional api refer to [this notebook](/notebooks/02_AHD_Classification.ipynb)\n\nThe pytorch model will be built using `CNN`. This model have the following code base behind the scenes:\n\n```py\nclass AHDCNN(nn.Module):\n    def __init__(self,\n       vocab_size,\n       embedding_size,\n       n_filters,\n       filter_sizes,\n       output_size,\n       dropout,\n       pad_idx):\n        super().__init__()\n        self.embedding = nn.Embedding(vocab_size,\n                                      embedding_size,\n                                      padding_idx = pad_idx\n                                      )\n        self.convs = nn.ModuleList([\n                                    nn.Conv2d(in_channels = 1,\n                                            out_channels = n_filters,\n                                            kernel_size = (fs, embedding_size))\n                                    for fs in filter_sizes\n                                    ])\n        self.fc = nn.Linear(len(filter_sizes) * n_filters, output_size)\n        self.dropout = nn.Dropout(dropout)\n\n    def forward(self, text):\n        embedded = self.embedding(text)\n        embedded = embedded.unsqueeze(1)\n        conved = [F.relu(conv(embedded)).squeeze(3) for conv in self.convs]\n        pooled = [F.max_pool1d(conv, conv.shape[2]).squeeze(2) for conv in conved]\n        cat = self.dropout(torch.cat(pooled, dim = 1))\n        return self.fc(cat)\n```\n\n### Folder structure of the server\n\nThe following is the folder structure of our `server`:\n\n```\n├───app\n│   └───__pycache__\n├───blueprints\n│   └───__pycache__\n├───exceptions\n│   └───__pycache__\n├───models\n│   ├───pytorch\n│   │   ├───static\n│   │   └───__pycache__\n│   ├───tensorflow\n│   │   ├───static\n│   │   └───__pycache__\n│   └───__pycache__\n└───schema\n    └───__pycache_\n```\n\n### Getting started\n\nIn this section we are going to show how you can use the `ADH` server to make predictions of humour on text locally.\n\nFirst you are required to have `python` installed on your computer to be more specific python version `3`\n\nFirst you need to clone this repository by running the following command:\n\n```shell\ngit clone https://github.com/CrispenGari/ahd-detector.git\n```\n\nAnd then you navigate to the server folder of this repository by running the following command:\n\n```shell\ncd ahd-detector/server\n```\n\nNext you are going to create a virtual environment `venv` by running the following command:\n\n```shell\nvirtualenv venv\n```\n\nThen you need to activate the virtual environment by running the following command:\n\n```shell\n.\\venv\\Scripts\\activate.bat\n```\n\nAfter activating the virtual environment you need to install the required packages by running the following command:\n\n```shell\npip install -r requirements.txt\n```\n\nThen you are ready to start the server. To start the server you are going to run the following command:\n\n```shell\ncd api \u0026\u0026 python app.py\n```\n\nThe above command will start the local server at default port of `3001` you can be able to make request to the server.\n\n\u003e **_Note: The tensorflow static file for the model is not available in this github repository you may need to run [this notebook](./notebooks/02_AHD_Classification.ipynb) so that you can save `.h5` model in the `./server/api/models/tensorflow/static` folder before attempting to make any request to the server._**\n\n### Making GraphQL Request to the server\n\nThe graphql endpoint is served at the following urls:\n\n1. http://127.0.0.1:3001/graphql\n2. http://localhost:3001/graphql\n\nThis endpoint can only serve one query for detecting humour using either the `tensorflow` or `pytorch` model. If you visit the specified url's you will be represented by the `GraphiQL` interface where you can run the query as follows:\n\n```\nfragment PredictionFragment on PredictionType {\n  label\n  probability\n  class_\n  text\n}\n\nfragment ErrorFragment on ErrorType {\n  field\n  message\n}\n\nfragment HumourDetectionResponseFragment on PredictionResponse {\n  ok\n  error {\n    ...ErrorFragment\n  }\n  prediction {\n    ...PredictionFragment\n  }\n}\n\n{\n  predictHumour(input: {modelType: \"tf\", text: \"What do you get if king kong sits on your piano? a flat note.\"}) {\n    ...HumourDetectionResponseFragment\n  }\n}\n```\n\nIf the query went well you are going to get the response in the following format:\n\n```json\n{\n  \"data\": {\n    \"predictHumour\": {\n      \"ok\": true,\n      \"error\": null,\n      \"prediction\": {\n        \"label\": 0,\n        \"probability\": 1,\n        \"class_\": \"HUMOUR\",\n        \"text\": \"what do you get if king kong sits on your piano? a flat note.\"\n      }\n    }\n  }\n}\n```\n\n### `input`\n\nThe input to the `predictHumour` takes in two arguments the:\n\n1. `modelType`- type of graphql string it can be either `tf` or `pt` and not case sensitive\n\n2. `text` - this is a graphql string which is the text that you want to detect if there's a humour element in it.\n\n### Making `REST` Request to the server for Humour Detection.\n\nYou can start detecting humour from text using `rest` approach with different clients. I'm going to show few examples of how to detect humour using the following clients and api's.\n\n### Using `Postman`\n\nUsing postman you send a `POST` request to `http://127.0.0.1:3001/api/detect-humour?model=tf` with the following request json body:\n\n```json\n{\n  \"text\": \"If the opposite of pro is con, then what is the opposite of progress\"\n}\n```\n\nTo get the following json response:\n\n```json\n{\n  \"class_\": \"HUMOUR\",\n  \"label\": 0,\n  \"probability\": 1.0,\n  \"text\": \"if the opposite of pro is con, then what is the opposite of progress\"\n}\n```\n\n\u003e **_Note that in the request url the `query-string` `model` is required as either `tf` for tensorflow model or `pt` for pytorch model._**\n\n### Using `cURL`\n\nTo detect humour on text using `curl` the request may look as follows:\n\n```shell\ncurl -X POST http://127.0.0.1:3001/api/detect-humour?model=tf -H \"Content-Type: application/json\" -d \"{\\\"text\\\": \\\"If the opposite of pro is con, then what is the opposite of progress\\\"}\"\n```\n\nThe response will be as follows:\n\n```json\n{\n  \"class_\": \"HUMOUR\",\n  \"label\": 0,\n  \"probability\": 1.0,\n  \"text\": \"if the opposite of pro is con, then what is the opposite of progress\"\n}\n```\n\n### Using `javascript-fetch` API\n\nYou can use the `js` fetch api to make the request to the server locally using the following snippet code:\n\n```js\nfetch(\"http://127.0.0.1:3001/api/detect-humour?model=tf\", {\n  method: \"POST\",\n  headers: {\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    text: \"If the opposite of pro is con, then what is the opposite of progress\",\n  }),\n})\n  .then((res) =\u003e res.json())\n  .then((data) =\u003e console.log(data));\n```\n\nThe response will be as follows:\n\n```json\n{\n  \"class_\": \"HUMOUR\",\n  \"label\": 0,\n  \"probability\": 1.0,\n  \"text\": \"if the opposite of pro is con, then what is the opposite of progress\"\n}\n```\n\n### Data\n\nThe data for training these notebooks was found on [`kaggle`](https://www.kaggle.com/datasets/deepcontractor/200k-short-texts-for-humor-detection) and you can also find the `csv` in the `data` folder.\n\n### Notebooks\n\nAll the notebooks for training and data preparations are found in this repository.\n\n1. [data preparation](/notebooks/00_AHD_Data_Prep.ipynb)\n2. [pytorch model with glove word vectors](/notebooks/01_AHD_Classification.ipynb)\n3. [pytorch model without glove word vectors](/notebooks/03_AHD_Classification_No_EmbeddingVectors.ipynb)\n4. [tensorflow model](/notebooks/02_AHD_Classification.ipynb)\n\n\u003e **_Note that the pytorch `model` that is being served by the server was trained in the 3rd notebook without glove word vectors._**\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcrispengari%2Fahd-detector","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcrispengari%2Fahd-detector","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcrispengari%2Fahd-detector/lists"}