diff options
author | navanchauhan <navanchauhan@gmail.com> | 2021-06-28 00:48:18 +0530 |
---|---|---|
committer | navanchauhan <navanchauhan@gmail.com> | 2021-06-28 00:48:18 +0530 |
commit | 68b8bdf371a8b325f75d7fa369c57c04bb886d9e (patch) | |
tree | 8059e2fccb818d9f4c777738fe3e1eec77fc333d | |
parent | b6ef899a6c1365b334110bc8f229ef8b95ae9527 (diff) |
added CoreML Chatbot
13 files changed, 123 insertions, 0 deletions
diff --git a/Content/posts/2021-06-27-Crude-ML-AI-Powered-Chatbot-Swift.md b/Content/posts/2021-06-27-Crude-ML-AI-Powered-Chatbot-Swift.md new file mode 100644 index 0000000..0dcabec --- /dev/null +++ b/Content/posts/2021-06-27-Crude-ML-AI-Powered-Chatbot-Swift.md @@ -0,0 +1,123 @@ +--- +date: 2021-06-27 23:26 +description: Writing a simple Machine-Learning powered Chatbot (or, daresay virtual personal assistant ) in Swift using CoreML. +tags: Swift, CoreML, NLP +--- + +# Making a Crude ML Powered Chatbot in Swift using CoreML + +A chatbot/virtual assistant, on paper, looks easy to build. +The user says something, the programs finds the best action, checks if additional input is required and sends back the output. +To do this in Swift, I used two separate ML Models created using Apple's Create ML App. +First is a Text Classifier to classify intent, and the other a word tagger for extracting input from the input message. +Disclaimer: This is a very crude proof-of-concept, but it does work. + +## Text Classifier + +I opened a CSV file and added some sample entries, with a corresponding label. + + + + +## Word Tagging + +This is useful to extract the required variables directly from the user's input. +This model will be only called if the intent from the classifier is a custom action. +I created a sample JSON with only 3 examples (I know, very less, but works for a crude PoC). + + + + +## Time to Get Swift-y + +The initial part is easy, importing CoreML and NaturalLanguage and then initializing the models and the tagger. + + + +```swift +import CoreML +import NaturalLanguage + +let mlModelClassifier = try IntentDetection_1(configuration: MLModelConfiguration()).model +let mlModelTagger = try CompoundTagger(configuration: MLModelConfiguration()).model + +let intentPredictor = try NLModel(mlModel: mlModelClassifier) +let tagPredictor = try NLModel(mlModel: mlModelTagger) + +let tagger = NLTagger(tagSchemes: [.nameType, NLTagScheme("Apple")]) +tagger.setModels([tagPredictor], forTagScheme: NLTagScheme("Apple")) +``` + +Now, we define a simple structure which the custom function(s) can use to access the provided input. +It can also be used to hold additional variables. +This custom action for our third label, uses the Word Tagger model to check for the compound in the user's message. +If it is present then it displays the name, otherwise it tells the user that they have not provided the input. +The latter can be replaced with a function which asks the user for the input. + + +```swift +struct User { + static var message = "" +} + +func customAction() -> String { + let sampleMessage = User.message + var actionable_item = "" + tagger.string = sampleMessage + tagger.enumerateTags(in: sampleMessage.startIndex..<sampleMessage.endIndex, unit: .word, + scheme: NLTagScheme("Apple"), options: .omitWhitespace) { tag, tokenRange in + if let tag = tag { + if tag.rawValue == "COMPOUND" { + actionable_item += sampleMessage[tokenRange] + } + } + return true + } + if actionable_item == "" { + return "You did not provide any input" + } else { + return "You provided input \(actionable_item) for performing custom action" + } + +} +``` + +Sometimes, no action needs to be performed, and the bot can use a predefined set of responses. +Otherwise, if an action is required, it can call the custom action. + + +```swift +let defaultResponses = [ + "greetings": "Hello", + "banter": "no, plix no" +] + +let customActions = [ + "deez-drug": customAction +] + + +``` + +In the sample input, the program is updating the User.message and checking if it has a default response. +Otherwise, it calls the custom action. + + + +```swift +let defaultResponses = [ + "greetings": "Hello", + "banter": "no, plix no" +] + +let customActions = [ + "deez-drug": customAction +] +``` + + + +So easy. + +If I ever release a part-2, it will either be about implementing this in Tensorflow.JS or an iOS app using SwiftUI ;) + diff --git a/Resources/assets/posts/cheminformatics-web/postera-demo.png b/Resources/assets/posts/cheminformatics-web/postera-demo.png Binary files differnew file mode 100644 index 0000000..bc0268f --- /dev/null +++ b/Resources/assets/posts/cheminformatics-web/postera-demo.png diff --git a/Resources/assets/posts/cheminformatics-web/rdkit-demo.png b/Resources/assets/posts/cheminformatics-web/rdkit-demo.png Binary files differnew file mode 100644 index 0000000..a23881c --- /dev/null +++ b/Resources/assets/posts/cheminformatics-web/rdkit-demo.png diff --git a/Resources/assets/posts/cheminformatics-web/webina-demo.png b/Resources/assets/posts/cheminformatics-web/webina-demo.png Binary files differnew file mode 100644 index 0000000..4bfea04 --- /dev/null +++ b/Resources/assets/posts/cheminformatics-web/webina-demo.png diff --git a/Resources/assets/posts/swift-chatbot/carbon-2.png b/Resources/assets/posts/swift-chatbot/carbon-2.png Binary files differnew file mode 100644 index 0000000..3f05e7f --- /dev/null +++ b/Resources/assets/posts/swift-chatbot/carbon-2.png diff --git a/Resources/assets/posts/swift-chatbot/carbon-3.png b/Resources/assets/posts/swift-chatbot/carbon-3.png Binary files differnew file mode 100644 index 0000000..d02a85f --- /dev/null +++ b/Resources/assets/posts/swift-chatbot/carbon-3.png diff --git a/Resources/assets/posts/swift-chatbot/carbon-4.png b/Resources/assets/posts/swift-chatbot/carbon-4.png Binary files differnew file mode 100644 index 0000000..0c17806 --- /dev/null +++ b/Resources/assets/posts/swift-chatbot/carbon-4.png diff --git a/Resources/assets/posts/swift-chatbot/carbon.png b/Resources/assets/posts/swift-chatbot/carbon.png Binary files differnew file mode 100644 index 0000000..2ba1a48 --- /dev/null +++ b/Resources/assets/posts/swift-chatbot/carbon.png diff --git a/Resources/assets/posts/swift-chatbot/create-intent.png b/Resources/assets/posts/swift-chatbot/create-intent.png Binary files differnew file mode 100644 index 0000000..92413f5 --- /dev/null +++ b/Resources/assets/posts/swift-chatbot/create-intent.png diff --git a/Resources/assets/posts/swift-chatbot/create-tagger.png b/Resources/assets/posts/swift-chatbot/create-tagger.png Binary files differnew file mode 100644 index 0000000..0e3363c --- /dev/null +++ b/Resources/assets/posts/swift-chatbot/create-tagger.png diff --git a/Resources/assets/posts/swift-chatbot/drugs-json.png b/Resources/assets/posts/swift-chatbot/drugs-json.png Binary files differnew file mode 100644 index 0000000..adf9348 --- /dev/null +++ b/Resources/assets/posts/swift-chatbot/drugs-json.png diff --git a/Resources/assets/posts/swift-chatbot/intent-csv.png b/Resources/assets/posts/swift-chatbot/intent-csv.png Binary files differnew file mode 100644 index 0000000..bba4d09 --- /dev/null +++ b/Resources/assets/posts/swift-chatbot/intent-csv.png diff --git a/Resources/assets/posts/swift-chatbot/output.png b/Resources/assets/posts/swift-chatbot/output.png Binary files differnew file mode 100644 index 0000000..121f1fd --- /dev/null +++ b/Resources/assets/posts/swift-chatbot/output.png |