NLP address parser: From concept to production MVP in a weekend
Tags: spacy, nlp, ner, serverless
Published: 2022-04-26 23:13:42


Last week I came across two problems that intersected.
1. Users not coming back to my app because it's not top of mind when they sign up. Then they get busy planning, making them less likely to come back.
2. Collecting addresses for a wedding

I decided to come up with a solution - an address parser using NLP. This would help solve the log-in once issue by becoming the system of record for weddings. It also solves the issue of collecting addresses. You need them to send save the dates, invites, and thank you cards. They are a pain to gather and keep up to date, especially if you have 100+ guests. We ended up texting our friends and family to gather the addresses. While we were able to gather them, the manual entry was time-consuming. I decided to investigate adding an address parser to [Text My Wedding](https://text-my-wedding.com) using [Spacy](https://spacy.io/) and AWS Lambdas. I'll go over the how and why I chose this route.

## Wait, before we start, what is Spacy and named entity recognition?

Spacy is an open sourced library for Natural Language Processing. 

> "spaCy is designed specifically for production use and helps you build applications that process and “understand” large volumes of text. It can be used to build information extraction or natural language understanding systems, or to pre-process text for deep learning." - [Spacy.io](https://spacy.io/usage/spacy-101) 

Named entity recognition is using a model to recognize and predict named entities - anything assigned a name like people, products, places, etc. NER is helpful in pulling out these entities from a large volume of text you wan't to analyze.

Heres an example of Spacy pulling out `ORG`, `GPE`, and `MONEY` entities. 

![Spacy parsing text with NER](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3frpm1habil9q1a280ky.png)

## Got it, so how did you build this?

I decided to run this on AWS lambda. You may be asking "why in the world would you run a serverless NLP application?" That's a very fair question and I decided this for a few reasons:

1. Go with what you know.
It's as simple as that - I know my way around Lambdas pretty well. No reason to reinvent the wheel and try to learn other tools even if they are better suited for the long term.
2. It allowed me to get up and running in a weekend.
I was able to spend my time learning how to train a custom model with Spacy. I didn't need to worry about spinning up servers or maintaining them. The rest of the time was learning the nuances of Python as a javascript developer. That's a story for another day...
3. I'm not 100% sure how users will adopt the feature. I'll let the photo below speak for itself...

![Users using software meme](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w680pn5x6n9njzu45o21.png)

## What does it look like?

![Spacy on lambda](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/58k9mam33f3jgwh6xyf7.png)

A Lambda is used to process the Twilio webhook events for incoming messages. This function updates the DB with the incoming message info. It then sends an SNS message to the Python lambda with the Spacy model. If the model recognizes an address in a message, it will send an SNS message to another Lambda. This Lambda then validates the parsed address using AWS Location Service and updates the DB with address info.

## So is this scalable? 

Absolutely not! But that wasn't the point of adding this feature. I wanted to quickly and cheaply build something to validate the address parser idea. It will also allow me to collect more training data and further improve the parsing. If users adopt the feature and we gather more training data, it will be time to move to a scalable solution. 

## Great, this works for now but what does a 'complex model' look like?

If users adopt the parser, the goal is to train a more advanced model. Right now, it will only process the text if there is one address. There are some cases to solve if a text contains two addresses. For example, if someone responds back with: 

> "Hey there! I live at 123 Main st now but am moving in 6 weeks to 144 Beacon st". 

The model then needs to:
1. Classify there are two addresses
2. Recognize both addresses
3. Determine the order. Is the new or old address in position 1 or 2?

This is a much more complex use case. More data and tons more exploration is needed before we get there. Once there, better solutions would be to use [SageMaker Serverless Inference](https://aws.amazon.com/about-aws/whats-new/2021/12/amazon-sagemaker-serverless-inference/) or Fargate. Will I get there? That's to be determined by how users adopt the feature. 

In the end, don't be afraid to just ship and figure out how to scale later. Thats half the fun of running a small startup. I was able to build something useful in a weekend and learn new skills.


![Text my wedding interface](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o959yauxne3lpjr8bq7g.png)  

Have questions or feedback? Feel free to leave a comment.