Skip to main content

How I did customize "rasa-nlu-trainer" as my own tool


Check out my implementation here

Background

I wanted to have a tool for human beings to classify intents and extract entities of texts which were obtained from a raw dataset such as Rocket.chat's conversation, Maluuba Frames or here. Then, the output (labeled texts) could be consumed by an NLU tool such as Rasa NLU.

rasa-nlu-trainer was a potential one which I didn't need to build an app from scratch. However, I needed to add more of my own features to fulfill my needs. They were:

1. Loading/displaying raw texts stored by a database such as MongoDB
2. Manually labeling intents and entities for the loaded texts
3. Persisting labeled texts into the database

I firstly did look up what rasa-nlu-trainer's technologies were used in order to see how to implement my mentioned features.

At first glance

rasa-nlu-trainer was bootstrapped with Create React App. Create React App is a tool to create a React app with no build configuration, as it said. This tool is also recommended by the official React.js tutorial. I actually was very new to React.js. I wondered what problem Creat React App tried to solve so that I first wanted to set up a project without Create React App. I followed this post.

Well, let me say if I built a React app from scratch then I needed to do some manual configurations for Webpack and Babel including webpack.config.json and .babelrc

Then, I tried to use Create React App, and I followed this guide. All right, let me say Create React App helped me create a React boilerplate project with hiding Webpack and Babel's configuration so that as a developer I only needed to focus on writing production code.

The nuts and bolts

I went on starting to watch how rasa-nlu-trainer's source code was organized and what its techniques are used.

Folder structure

1. Auto-created stuff by Create React App
   - public/index.html
   - src/index.js
2. Overrides
   - They didn't use "react-script", they created their own way instead! That was the reason why some additional folder/files were added such as server.js, scripts and config.

Used technologies

- Programming language: Javascript
- Babel: ES6 transpiler
- Project bundle: Webpack
- Dependencies management: npm
- Backend: Node.js
- Fronted framework/project-based: React.js
- React model storing: React-Redux
- React UI extension components: Ant Design
- TypeScript

Hooray! Welcome me to Javascript world!

Architecture

- index.js: Provider{store} <---> LocaleProvider ---> App
- How "separation of concerns" works: import and  export
- Global data (store) is immutable and only changed by files actions.js and reducer.js

Proposed changes

Finally, I could start to add my needs to the existing rasa-nlu-trainer app. I listed out what my features:
- Creating an overview page as a custom React component to display all loaded texts
- Customizing the existing page for classifying intents and extracting entities.
- Implementing Node.js methods to load/stores texts (as JSON)  which stored in MongoDB

The rule of thumb was I needed to follow the mentioned architecture for modifying the global data which were managed by React-Redux.

You can take a look at the changes from this pull request.

Conclusion

Sometimes, the best way to learn new techs is to get down into an existing tool and customize it with your own needs. 💪

Comments

Popular posts from this blog

Junit - Test fails on French or German string assertion

In my previous post about building a regex to check a text without special characters but allow German and French . I met a problem that the unit test works fine on my machine using Eclipse, but it was fail when running on Jenkins' build job. Here is my test: @Test public void shouldAllowFrenchAndGermanCharacters(){ String source = "ÄäÖöÜüß áÁàÀâÂéÉèÈêÊîÎçÇ"; assertFalse(SpecialCharactersUtils.isExistSpecialCharater(source)); } Production code: public static boolean isExistNotAllowedCharacters(String source){ Pattern regex = Pattern.compile("^[a-zA-Z_0-9_ÄäÖöÜüß áÁàÀâÂéÉèÈêÊîÎçÇ]*$"); Matcher matcher = regex.matcher(source); return !matcher.matches(); } The result likes the following: Failed tests: SpecialCharactersUtilsTest.shouldAllowFrenchAndGermanCharacters:32 null A guy from stackoverflow.com says: "This is probably due to the default encoding used for your Java source files. The ö in the string literal in the J...

Gzip upload on browsers

Today, I faced a problem that I could not upload my archive file with gzip format on Firefox, even it worked on Chrome. I was using macOS. My application had a setting to whitelist accepted files. I’ve already added "application/gzip" to that list. "It’s strange!", I thought. I finally figured out that my uploaded file's type actually was "application/x-gzip" on Firefox. I also asked my colleagues to check their uploaded files on Window and Ubuntu. Hmm… they were totally different! It was "application/x-compressed" on Window, and was "application/x-compressed-tar" on Ubuntu. In fact, gzip is already standardized by IANA. There is a note in RFC-6713 as below: "Some applications have informally used media types such as application/gzip-compressed, application/gzipped, application/x-gunzip, application/x-gzip, application/x-gzip-compressed, and gzip/document to describe data compressed with gzip. The media types defin...

Java 8 - Persistent data structure

The following is a series of posts about "functional programming in Java" which is the result of my understanding by reading the book " Java 8 in Action: Lambdas, Streams, and Functional-style Programming, by Alan Mycroft and Mario Fusco ". 1. Why functional programming? 2. Functional programming in Java 8 3. Java 8 - Using Functions as Values 4. Java 8 - Persistent data structure Persistent data structure is also known as a simple technique but it's very important. Its other names are functional data structure and immutable data structure. Why is it "persistent"? Their values persist and are isolated from changes happening elsewhere. That's it! This technique is described as below: If you need a data structure to represent the result of a computation, you should make a new one and not mutable an existing data structure. Destructive updates version public static A doSomething(A a){ a.setProp1("new value"); return...

DevOps Toolchain Enhancement

 Historically, our company ubitec had started with a customer project. Agile/Scrum was our proposal for working with customers. Time by time, Agile/Scrum also became our culture for software development. To be successful with this development approach, we somehow needed to have a fast release for customers (i.e. every one week). Back then, we had a build tool Jenkins which was responsible for having sprint release packages for our customers. The build job pipelines contain some steps such as gathering the artifacts, checking the code convention, running the tests, building docker images, and packaging an archived file (a zip file). The set of tools involved in a pipeline is roughly called a toolchain. It is just a part of a bigger process called the DevOps toolchain. Source: https://www.ibm.com/blogs/cloud-archive/2016/11/devops-architecture-available-on-bluemix-garage-method-site/ DevOps is a proven method that fits Agile. Today,  it is even treated as a mandatory factor...

Fulfilling Your Contribution Needs

Human resource management motivation Managing human today is quite different from the industrial age which treats people as just "chickens". Rather than people now are very important to the success of an organization. People are an organization's special resource. They should be encouraged to grow to contribute their effort and creativeness to their beloved working environment because the contribution is one of their most needs in life. Training people: getting rid of the ineffective model and adopting the new one The ineffective model of training people: Hiring new people --> giving them a crash course once --> expecting them working effectively.  That somehow makes sense but you're about to expect a luck because you do not really spend your effort for mentoring them. If they can work effectively, well...lucky you! Otherwise, you will blame that these people are ineffective and you let them go and hire the new ones. What a waste of time! The new effe...