This is the Fetch assessment for the Machine Learning Intern position. The objective is to develop a machine learning model to predict the number of scanned receipts for each month in 2022, based on daily data from 2021.
I began by visualizing the data, identifying it as a regression problem. After aggregating the daily receipt counts into monthly totals, I initially tried fitting a simple line to the data, but it proved inadequate. To better capture non-linearity in the data, I opted for a simple neural network (NN) model.
The neural network architecture is as follows:
class NeuralNetModel(nn.Module):
def __init__(self):
super(NeuralNetModel, self).__init__()
self.fc1 = nn.Linear(1, 64)
self.relu = nn.ReLU()
self.fc2 = nn.Linear(64, 64)
self.fc3 = nn.Linear(64, 1)
def forward(self, x):
x = self.relu(self.fc1(x))
x = self.relu(self.fc2(x))
return self.fc3(x)I trained the model to predict receipt counts for each month of 2022 based on monthly data from 2021. The neural network is simple but provides the flexibility needed to model the underlying non-linear relationships in the data.
- Data Aggregation: I aggregated the daily data into monthly totals using
pandas. The receipt counts were normalized usingMinMaxScalerfromscikit-learn. - Training: The model is trained using PyTorch with the Adam optimizer and MSELoss as the loss function. I trained it for 5000 epochs to ensure proper convergence.
- Inference: The trained model can predict the number of receipts for the next 12 months, based on the input months (13-24 corresponding to 2022).
You can run this project in two ways:
- Activate poetry shell
poetry shell
- Install the dependencies using Poetry:
poetry install
- Run the FastAPI server with
uvicorn:poetry run uvicorn fetch_receipt_predictor.api:app --reload
Alternatively, you can use Docker to build and run the image:
-
Build the Docker image:
docker build -t fetch-receipt-predictor . -
Run the container:
docker run -p 8000:8000 fetch-receipt-predictor
Note: I have also pushed a pre-built Docker image to Docker Hub. You can pull it directly instead of building it locally, (but the image is too big ~12GB due to the torch dependency):
docker pull batra98/receipt-predictor:latest
docker run -p 8000:8000 batra98/receipt-predictor:latestImportant: The server might take a second to respond because the model is retrained every time the application starts. This needs optimization.
- FastAPI: For building the web API.
- PyTorch: For building and training the neural network.
- pandas: For data manipulation and aggregation.
- scikit-learn: For data scaling (MinMaxScaler).
- Uvicorn: To serve the FastAPI application.
- Docker: For containerization and easy deployment.
- Poetry: For dependency management.
- Method: POST
- Request Body: Accepts a list of months and years.
- Example:
{ "months": [1, 2, 3], "years": [2022, 2022, 2022] }
- Example:
- Response: Returns the predicted number of receipts for each month.
- Example:
[ { "month": 1, "year": 2022, "predicted_receipts": 320623840 }, { "month": 2, "year": 2022, "predicted_receipts": 332023360 }, { "month": 3, "year": 2022, "predicted_receipts": 344512512 } ]
- Example:
-
Model Persistence: Currently, the model is trained each time the server starts, which can be inefficient. A future improvement would be to train the model and MinMaxScaler once, save them using
.pthandpickle, and load them during inference. This would significantly reduce startup time and improve performance. -
Simplify Neural Network: The dependency on
torch(PyTorch) is quite large. A more lightweight solution could be to implement the simple neural network myself, reducing the project size and unnecessary overhead.
This project demonstrates a complete pipeline, from data preprocessing to model deployment using FastAPI. Future optimizations will focus on reducing startup time and dependency size.