Thanks to some connections at Microsoft I was made aware of some very interesting data that was published on the Windows Azure Data Marketplace by Practice Fusion – deidentified medical records of 5000 patients. Of course, I had to take a look. What I found was a very compelling and interesting set of data, that was more interesting when looked through the lens of Predixion Insight. Of course, as with any data that you may get from anywhere, there are first some issues in the data itself that need to be “corrected” before used for any analysis.
In this post I’ll show you how to get that data, explore a little bit of it, and clean up one particular part. There’s lots more to do, but this is just getting your feet wet.
In order to follow along at home, you will need Excel 2010, PowerPivot (get here), Predixion Insight for Excel (get here).
Step 1 – Loading the data
After you have all that software installed and running on your machine, you will want to go to the Practice Fusion Data page on Windows Azure and subscribe to their feed. If you haven’t subscribed to any the data market before, you will first have to agree to the MS terms of service to subscribe to the data market. After that you will have to agree to Practice Fusion’s terms of service and that will give you access to the data. Ignore the button there that allows you to load data directly into PowerPivot.The most efficient way to get all of the data is to go directly into PowerPivot, so launch Excel (or just create a new workbook since you probably already have Excel running anyway) and click on the PowerPivot button to get to the PowerPivot window.
The From Azure Marketplace Button launches the import wizard where you want to paste in the root URL for the data feed which is: https://api.datamarket.azure.com/Data.ashx/PracticeFusion/MedicalResearchData/
Also you will need to enter your account key, which, up to this point, you probably didn’t know you have. However clicking on the Find button will launch a web page displaying your unreadable key that you can copy and paste here.
Step 2 – Initial Data Exploration
One of the somewhat interesting things about loading data from an unknown source is that you have absolutely no idea what you’re looking at. This is where you can leverage the awesomeness of Predixion Insight’s Profile Data tool. This tool provides a quick summary of the data in an Excel worksheet or PowerPivot table so you can at a very minimum determine if the data makes any sense at all.To run Profile Data, switch back to the Excel interface, click on the Insight Analytics ribbon and choose Profile Data under the Explore Data menu button. In the Profile Data Wizard, you just need to select that you are choosing PowerPivot and the source of the data and which table you want – in this case, let’s use the SyncChart table which documents the basic patient measurements over a series of doctor’s visits.
Step 3 – Cleaning up the data
Cleaning up data like this is never automatic – you need to use tools and apply your judgment. Just like we were able to use the Profile Data tool to help us understand the nature and deduce the units of the data, we need to apply the same common sense treatment to cleaning the data.The first question to ask is what do you really want to do with the erroneous data? Since these are medical records recording actual values of patients, the safest thing to do may be simply to null out the data for values that are out of range. However, since there are several rows for each patient, and people (once fully grown) generally don’t change in height too much, it may be OK to simply take a height measurement from another chart reading for the same patient. It really depends on how you’re going to use the data, so I’ll perform both methods.
Let’s take the “whack the bad data” approach first. To do this, I’m going to use the Outliers tool from Predixion Insight which is under the Clean Data menu button on the Insight Analytics ribbon.
=IF(AND('SyncChart'[Height]>= 48.99, 'SyncChart'[Height]
<85.28),'SyncChart'[Height],BLANK())
This expression simply copies the in-range values and replaces the out of range values with blanks.
Before looking at the results, I want to try the other method of removing outliers I proposed – using the average of a patient’s other visits. To do this I used the following custom DAX expression:
CALCULATE(AVERAGEX(SyncChart, SyncChart[Height]),
ALLEXCEPT(SyncChart, SyncChart[PatientGuid]),
SyncChart[Height]>48.99,
SyncChart[Height]<85.28)
This expression basically says, calculate the average of the Height column by first removing all filters except for a filter on the current rows PatientGuid Column, and also exclude any rows where the Height is out of range. I copied the IF expression created by Predixion Insight and replaced the part that says “BLANK()” with this custom expression. I renamed the new column “Height with Outliers Replaced”
The next thing I want to do before looking further is calculating the BMI. The BMI was included with the data, but is really a derived column. The formula for BMI using inches and pounds is BMI=Weight * 703/Height^2. In order to protect against divide by zero errors, I put an IF in the DAX expression to check for blanks and created two columns like this:
=IF(ISBLANK(SyncChart[Height with Outliers Removed]),
BLANK(),
SyncChart[Weight]*703/POWER(SyncChart[Height with Outliers Removed],2))
(Obviously one had the Outliers Replaced version of the column).
To see the impact of the results, I re-ran Profile Data against the SyncChart table with the new columns. Here are the results:
The first thing I noticed is that the Height with Outliers Replaced column has no blanks – this means two things – one, that every patient has at least one doctor’s visit where they have a height measurement, and two, I should have checked for ISBLANK in my expression to calculate that Height value!
The other things to notice is that the fixed height values are much more in line with reality - we’ve eliminated the pixies and the hill giants (frost giants are much taller). Also, the recomputed BMI values are starting to be more realistic as well. In fact we reduced the maximum BMI from over 5500 to 250 by only removing 317 values from 59193 rows – about 1/2%!
To complete the exercise and ensure that the BMI values were reasonable we would have to clean the Weight column as well, which we do by running through the Remove Outliers wizard again. However, there’s actually one more trick. When looking at the outliers for the Weight column, we get a chart that looks like this:
This occurs when you have a range of outliers that includes extremely large outliers that obscures the resolution of the data. To get a better view of the data, you can click the logarithm button – circled below – and get a much more usable visual – I also increased the resolution:
I removed the extreme outliers (rather arbitrarily choosing a range of about 33 – 510 lbs, which is still probably pretty extreme) replacing them with nulls. I didn’t try to do the “replace with other visits” trick, since people’s weight can fluctuate quote a bit from visit to visit.
Creating a new BMI column and re-running the Profile Data gave me results like this (other rows hidden):
You can see the range of BMI values went from an original 5511 to a more reasonable 78. It’s very likely (pretty much guaranteed) that I could have more tightly truncated both the height and weight variables to make them more inline with reality, but this is a good start.
Some deeper inspection of the data may be necessary to find the correct boundaries, and of course it always depends on how you are going to use the data. For predictive purposes, it generally is better to eliminate extreme values even if they are valid since they can skew the results. For traditional BI reporting – e.g. “how many visits were by people over 9 feet tall” – you generally want to keep any valid value, no matter how extreme. In either case, however, you do want to eliminate invalid values. Luckily with this data set, by combining common sense with the tools at hand we’re able to carve away at the bad data to make the remaining data useful for analysis.
That just may happen in a future post… ;)
