Parkinson’s disease is a progressive disorder of the central nervous system affecting movement and inducing tremors and stiffness. It has 5 stages to it and affects more than 10 million individuals every year in the world. This is chronic and has no cure yet. It is a neurodegenerative disorder affecting dopamine-producing neurons in the brain.
My own grandfather who struggled his whole life and gave up all of his comforts to make me the person I am today was detected with Parkinson's Disease. By the time it was detected, it was too late and doctors informed that nothing can be done to cure it. Parkinson's disease has affected his gait and body balance very badly, a few weeks ago, at night, when he was trying to go to the washroom, he lost his balance and fell on the ground in such a way that his femur bone got fractured. He is currently in the hospital fighting between life and death and even if he survives, I am not sure if I will ever be able to watch him stand on his legs again.
From that moment I decided that something needs to be done to address this issue. Something needs to be developed to detect the presence of Parkinson's disease in a person before it is too late. So at first, I decided to build an app that will diagnose by asking the user to hold the phone flat in their hand sensors can measure the presence of tremor, or by slipping the phone into a back pocket an assessment of gait can be generated as someone walks around. Then there are tasks on the device itself, like onscreen tapping tests, as well as simple questionnaires that collect self-assessment data, replicating how a specialist would assess the non-motor symptoms of Parkinson’s in areas such as mood, anxiety, and memory. So I used the NVIDIA Jetson Nano Developer Kit which was awarded to me as free hardware to learn how to respond to certain actions, so it uses my predefined algorithms and historical Parkinson's data to create a propensity model.
But what I observed after testing it in real-life scenarios was that it was not accurate enough and measuring just the non-motor symptoms is not sufficient. I needed to develop a mechanism to measure the motor symptoms of Parkinson's Disease that too at the patient's convenience because a Parkinson's Disease patient cannot walk or travel long distances. So I needed to develop a portable machine that can detect the symptoms preferably at the home of the patient. While thinking this, my eyes fell on the drone which I had made for my college project and I was like Eurekaaaaa!! Why not integrate the NVIDIA Jetson Platform with this drone so it can autonomously conduct a 360-degree scan of a patient's body movements at his/her home and detect the warning signs/symptoms of Parkinson's Disease.
Then my tough journey began of bringing this project to reality.I had already assembled, programmed and tuned the drone for my college project. In case you don't have a self-made drone, you can buy the parts mentioned in the BoM of this project and follow the video links given below to build, program and assemble the drone.
- Assembly & Programming The Drone
- Setup the Transmitter
- PID Tuning the Drone
Now that the drone was ready, the next step was to learn AI fundamentals. Taking the free self-paced NVIDIA Deep Learning Institute course on Getting Started With AI On Jetson Nano was really very very helpful. This course really helped me build strong fundamentals about what is the true meaning of AI and how ML and DL are connected to it. It taught me everything from how to power,boot,train and perform inference on the Jetson Nano. Huge thanks to the interactive python notebooks provided in the course.
Now as the foundations were built, it was time to construct a tower on it. I started doing extensive research about which model is best to detect Parkinson's Disease Symptoms. This is an excerpt from a research:
Data for the project was provided through the MJFF and the BioFIND observational clinic study, which was designed to discover and verify biomarkers of Parkinson’s disease. A proprietary clustering method was used to identify twelve clusters of patients based on the test results available for each patient.
Prior to model selection, we used two feature selection algorithms to produce two lists of medical tests for each cluster. A random forest algorithm (called Boruta) was used to produce an all relevant tests list. Potentially useful for scientific research, this list included all tests the algorithm found useful for disease prediction. We then used a recursive elimination algorithm to generate a minimal test list, representing the smallest set of tests needed for accurate disease prediction. Each cluster was further divided into ten subgroups, and algorithms were trained on each set of 90% and validated on the remaining, held-out 10%. This 10-fold cross-validation allowed us to:
Accurately score how well our algorithms performed
Determine how often a test was chosen within each cluster, as well as between clusters, enabling us to rank the importance of each medical test for disease prediction.
Several models were trained on each cluster and the most accurate model was selected. Target shuffling was then used to further validate the statistical accuracy of our model results.
Model ensembles outperformed single models in 6 of the 12 clusters. Extreme Gradient Boosting (XGBoost) achieved superior performance in 4 of 12 clusters, while the C5.0 decision tree and feed-forward neural net each won for a single cluster. By target shuffling over 300 times, we confidently estimated the performance of our models (Figure1).
Our models yielded better accuracy and specificity metrics than those obtained from target shuffling nearly 100% of the time for 10 of the 12 clusters. This comes at very little cost to sensitivity in clusters 1 through 10, which had performance above 95% in six of the ten clusters and above 84% among the remaining four clusters. We observed reduced performance in clusters 11 and 12, where very few patient observations or available tests provided limited data for model training.
So it was evident that the best model to detect Parkinson's Disease symptoms was XGBoost. As it is a new Machine Learning algorithm designed with speed and performance in mind. XGBoost stands for eXtreme Gradient Boosting and is based on decision trees. I imported the XGBClassifier from the xgboost library; this is an implementation of the scikit-learn API for XGBoost classification.
DatasetWe can create our own dataset for the gait and other motor symptoms analysis for detecting Parkinson's Disease using the human pose estimation repository for the Jetson Nano.(https://github.com/RTK221B/trt_pose)
But that would require analyzing hundreds of Parkinson's Disease patients, which was not quite practically possible for me so I used UCI ML Parkinsons' dataset for this; you can download it here. The dataset has 24 columns and 195 records and is only 39.7 KB.
I had already installed the following libraries in my jetson nano with pip:
- pip install numpy pandas sklearn xgboost
1. In a new JupyterLab window in my browser in my jetson nano, I created a new console and typed in the code, I made the necessary imports:
- import numpy as np
- import pandas as pd
- import os, sys
- from sklearn.preprocessing import MinMaxScaler
- from xgboost import XGBClassifier
- from sklearn.model_selection import train_test_split
- from sklearn.metrics import accuracy_score
Screenshot:
2. Now, I read the data into a DataFrame and got the first 5 records.
- #DataFlair - Read the data
- df=pd.read_csv('D:\\DataFlair\\parkinsons.data')
- df.head()
Output Screenshot:
3. I got the features and labels from the DataFrame (dataset). The features are all the columns except ‘status’, and the labels are those in the ‘status’ column.
- #DataFlair - Get the features and labels
- features=df.loc[:,df.columns!='status'].values[:,1:]
- labels=df.loc[:,'status'].values
Screenshot:
4. The ‘status’ column has values 0 and 1 as labels; let’s get the counts of these labels for both- 0 and 1.
- #DataFlair - Get the count of each label (0 and 1) in labels
- print(labels[labels==1].shape[0], labels[labels==0].shape[0])
Output Screenshot:
We have 147 ones and 48 zeros in the status column in our dataset.
5. Initialize a MinMaxScaler and scale the features to between -1 and 1 to normalize them. The MinMaxScaler transforms features by scaling them to a given range. The fit_transform() method fits the data and then transforms it. We don’t need to scale the labels.
- #DataFlair - Scale the features to between -1 and 1
- scaler=MinMaxScaler((-1,1))
- x=scaler.fit_transform(features)
- y=labels
Screenshot:
6. Now, I split the dataset into training and testing sets keeping 20% of the data for testing.
- #DataFlair - Split the dataset
- x_train,x_test,y_train,y_test=train_test_split(x, y, test_size=0.2, random_state=7)
Screenshot:
7. Now I initialized an XGBClassifier and trained the model. This classifies using eXtreme Gradient Boosting- using gradient boosting algorithms for modern data science problems. It falls under the category of Ensemble Learning in ML, where we train and predict using many models to produce one superior output.
- #DataFlair - Train the model
- model=XGBClassifier()
- model.fit(x_train,y_train)
Output Screenshot:
8. Finally, I generated y_pred (predicted values for x_test) and calculate the accuracy of the model. Print it out.
- # DataFlair - Calculate the accuracy
- y_pred=model.predict(x_test)
- print(accuracy_score(y_test, y_pred)*100)
Output Screenshot:
It gave me an accuracy of 94.87%, which is great considering the number of lines of code.
Implementation with the Drone
After training the model as discussed above, Jetson Nano can also be used for performing inference. It can be fixed on the drone as shown in the images below along with the USB Webcam. It can be powered either by an external battery bank attached below the drone or by taking up 11.1V * 4A from the LiPo battery through the power distribution board of the drone and then bringing it down to 5V*4A by using onboard buck converter.
This same drone can be used to detect skin diseases such as Melanoma and various other diseases across the world and thousands of lives can be saved.
Comments