Skip to content

Commit f1fb1ac

Browse files
committed
initial groundwork
0 parents  commit f1fb1ac

22 files changed

+522
-0
lines changed

.gitignore

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Byte-compiled / optimized / DLL files
2+
__pycache__/
3+
*.py[cod]
4+
5+
# C extensions
6+
*.so
7+
8+
# Distribution / packaging
9+
.Python
10+
env/
11+
build/
12+
develop-eggs/
13+
dist/
14+
downloads/
15+
eggs/
16+
.eggs/
17+
lib/
18+
lib64/
19+
parts/
20+
sdist/
21+
var/
22+
*.egg-info/
23+
.installed.cfg
24+
*.egg
25+
26+
# PyInstaller
27+
# Usually these files are written by a python script from a template
28+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
29+
*.manifest
30+
*.spec
31+
32+
# Installer logs
33+
pip-log.txt
34+
pip-delete-this-directory.txt
35+
36+
# Unit test / coverage reports
37+
htmlcov/
38+
.tox/
39+
.coverage
40+
.coverage.*
41+
.cache
42+
nosetests.xml
43+
coverage.xml
44+
*,cover
45+
46+
# Translations
47+
*.mo
48+
*.pot
49+
50+
# Django stuff:
51+
*.log
52+
media/
53+
54+
# Sphinx documentation
55+
docs/_build/
56+
57+
# PyBuilder
58+
target/
59+
60+
# DB
61+
*.sqlite3
62+
*.db

chronic_medicare/.admin.py.swp

12 KB
Binary file not shown.

chronic_medicare/__init__.py

Whitespace-only changes.

chronic_medicare/admin.py

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from django.contrib import admin
2+
from .models import MedicareFile, ChronicConditionLinearRegression
3+
4+
5+
admin.site.register(MedicareFile)
6+
admin.site.register(ChronicConditionLinearRegression)

chronic_medicare/constants.py

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
CHRONIC_COLUMN_NAMES = [
2+
('BENE_SEX_IDENT_CD', 'BENE_SEX_IDENT_CD'),
3+
('BENE_AGE_CAT_CD', 'BENE_AGE_CAT_CD'),
4+
('CC_ALZHDMTA', 'CC_ALZHDMTA'),
5+
('CC_CANCER', 'CC_CANCER'),
6+
('CC_CHF', 'CC_CHF'),
7+
('CC_CHRNKIDN', 'CC_CHRNKIDN'),
8+
('CC_COPD', 'CC_COPD'),
9+
('CC_DEPRESSN', 'CC_DEPRESSN'),
10+
('CC_DIABETES', 'CC_DIABETES'),
11+
('CC_ISCHMCHT', 'CC_ISCHMCHT'),
12+
('CC_OSTEOPRS', 'CC_OSTEOPRS'),
13+
('CC_RA_OA', 'CC_RA_OA'),
14+
('CC_STRKETIA', 'CC_STRKETIA'),
15+
('CC_2_OR_MORE', 'CC_2_OR_MORE'),
16+
('DUAL_STUS', 'DUAL_STUS'),
17+
('BENE_COUNT_PA_LT_12', 'BENE_COUNT_PA_LT_12'),
18+
('AVE_MO_EN_PA_LT_12', 'AVE_MO_EN_PA_LT_12'),
19+
('AVE_PA_PAY_PA_LT_12', 'AVE_PA_PAY_PA_LT_12'),
20+
('AVE_IP_PAY_PA_LT_12', 'AVE_IP_PAY_PA_LT_12'),
21+
('AVE_SNF_PAY_PA_LT_12', 'AVE_SNF_PAY_PA_LT_12'),
22+
('AVE_OTH_PAY_PA_LT_12', 'AVE_OTH_PAY_PA_LT_12'),
23+
('AVE_IP_ADM_PA_LT_12', 'AVE_IP_ADM_PA_LT_12'),
24+
('AVE_SNF_DAYS_PA_LT_12', 'AVE_SNF_DAYS_PA_LT_12'),
25+
('BENE_COUNT_PA_EQ_12', 'BENE_COUNT_PA_EQ_12'),
26+
('AVE_PA_PAY_PA_EQ_12', 'AVE_PA_PAY_PA_EQ_12'),
27+
('AVE_IP_PAY_PA_EQ_12', 'AVE_IP_PAY_PA_EQ_12'),
28+
('AVE_SNF_PAY_PA_EQ_12', 'AVE_SNF_PAY_PA_EQ_12'),
29+
('AVE_OTH_PAY_PA_EQ_12', 'AVE_OTH_PAY_PA_EQ_12'),
30+
('AVE_IP_ADM_PA_EQ_12', 'AVE_IP_ADM_PA_EQ_12'),
31+
('AVE_SNF_DAYS_PA_EQ_12', 'AVE_SNF_DAYS_PA_EQ_12'),
32+
('BENE_COUNT_PB_LT_12', 'BENE_COUNT_PB_LT_12'),
33+
('AVE_MO_EN_PB_LT_12', 'AVE_MO_EN_PB_LT_12'),
34+
('AVE_PB_PAY_PB_LT_12', 'AVE_PB_PAY_PB_LT_12'),
35+
('AVE_CA_PAY_PB_LT_12', 'AVE_CA_PAY_PB_LT_12'),
36+
('AVE_OP_PAY_PB_LT_12', 'AVE_OP_PAY_PB_LT_12'),
37+
('AVE_OTH_PAY_PB_LT_12', 'AVE_OTH_PAY_PB_LT_12'),
38+
('AVE_CA_VST_PB_LT_12', 'AVE_CA_VST_PB_LT_12'),
39+
('AVE_OP_VST_PB_LT_12', 'AVE_OP_VST_PB_LT_12'),
40+
('BENE_COUNT_PB_EQ_12', 'BENE_COUNT_PB_EQ_12'),
41+
('AVE_PB_PAY_PB_EQ_12', 'AVE_PB_PAY_PB_EQ_12'),
42+
('AVE_CA_PAY_PB_EQ_12', 'AVE_CA_PAY_PB_EQ_12'),
43+
('AVE_OP_PAY_PB_EQ_12', 'AVE_OP_PAY_PB_EQ_12'),
44+
('AVE_OTH_PAY_PB_EQ_12', 'AVE_OTH_PAY_PB_EQ_12'),
45+
('AVE_CA_VST_PB_EQ_12', 'AVE_CA_VST_PB_EQ_12'),
46+
('AVE_OP_VST_PB_EQ_12', 'AVE_OP_VST_PB_EQ_12'),
47+
('BENE_COUNT_PC_LT_12', 'BENE_COUNT_PC_LT_12'),
48+
('AVE_MO_EN_PC_LT_12', 'AVE_MO_EN_PC_LT_12'),
49+
('BENE_COUNT_PC_EQ_12', 'BENE_COUNT_PC_EQ_12'),
50+
('BENE_COUNT_PD_LT_12', 'BENE_COUNT_PD_LT_12'),
51+
('AVE_MO_EN_PD_LT_12', 'AVE_MO_EN_PD_LT_12'),
52+
('AVE_PDE_CST_PD_LT_12', 'AVE_PDE_CST_PD_LT_12'),
53+
('AVE_PDE_PD_LT_12', 'AVE_PDE_PD_LT_12'),
54+
('BENE_COUNT_PD_EQ_12', 'BENE_COUNT_PD_EQ_12'),
55+
('AVE_PDE_CST_PD_EQ_12', 'AVE_PDE_CST_PD_EQ_12'),
56+
('AVE_PDE_PD_EQ_12', 'AVE_PDE_PD_EQ_12'),
57+
]
58+
59+
DEPENDENT_VARIABLE = 'AVE_PA_PAY_PA_LT_12'

chronic_medicare/forms.py

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from django import forms
2+
from .models import MedicareFile, ChronicConditionLinearRegression
3+
from .constants import CHRONIC_COLUMN_NAMES
4+
5+
6+
class ChronicConditionAnalysisQueryForm(forms.Form):
7+
'''
8+
This form validates that valid query choices have been made
9+
'''
10+
parameters = forms.MultipleChoiceField(choices=CHRONIC_COLUMN_NAMES,
11+
widget=forms.CheckboxSelectMultiple())
12+
create_dummies = forms.BooleanField(required=False)
13+
input_file = forms.ModelChoiceField(queryset=MedicareFile.objects.all())
14+
15+
def clean_input_file(self):
16+
return self.cleaned_data['input_file'].csv_file
17+
18+
class ChronicConditionLinearRegressionForm(forms.ModelForm):
19+
'''
20+
This model form is used to validate output from
21+
sklearn LinearRegression to ensure data saved is legitimate
22+
'''
23+
class Meta:
24+
model = ChronicConditionLinearRegression
25+
fields = ['parameters', 'coefficient', 'constant', 'r_squared']
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# -*- coding: utf-8 -*-
2+
from __future__ import unicode_literals
3+
4+
from django.db import migrations, models
5+
6+
7+
class Migration(migrations.Migration):
8+
9+
dependencies = [
10+
]
11+
12+
operations = [
13+
migrations.CreateModel(
14+
name='ChronicConditionLinearRegression',
15+
fields=[
16+
('id', models.AutoField(primary_key=True, verbose_name='ID', serialize=False, auto_created=True)),
17+
('parameters', models.CharField(max_length=512)),
18+
('coefficient', models.FloatField(max_length=64)),
19+
('constant', models.FloatField(default=0, max_length=64)),
20+
('p_value', models.FloatField(max_length=64)),
21+
],
22+
),
23+
migrations.CreateModel(
24+
name='MedicareFile',
25+
fields=[
26+
('id', models.AutoField(primary_key=True, verbose_name='ID', serialize=False, auto_created=True)),
27+
('csv_file', models.FileField(upload_to='medicare-files/')),
28+
],
29+
),
30+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# -*- coding: utf-8 -*-
2+
from __future__ import unicode_literals
3+
4+
from django.db import migrations, models
5+
6+
7+
class Migration(migrations.Migration):
8+
9+
dependencies = [
10+
('chronic_medicare', '0001_initial'),
11+
]
12+
13+
operations = [
14+
migrations.RenameField(
15+
model_name='chronicconditionlinearregression',
16+
old_name='p_value',
17+
new_name='r_squared',
18+
),
19+
]

chronic_medicare/migrations/__init__.py

Whitespace-only changes.

chronic_medicare/models.py

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from django.db import models
2+
from django.utils.encoding import python_2_unicode_compatible
3+
4+
import numpy as np
5+
6+
7+
class MedicareFile(models.Model):
8+
csv_file = models.FileField(upload_to='medicare-files/')
9+
10+
def __str__(self):
11+
return self.csv_file.name.split('/')[-1]
12+
13+
14+
@python_2_unicode_compatible
15+
class ChronicConditionLinearRegression(models.Model):
16+
# source_file = models.ForeignKey(MedicareFile, related_name="linear_regressions")
17+
parameters = models.CharField(max_length=512)
18+
coefficient = models.FloatField(max_length=64)
19+
constant = models.FloatField(max_length=64, default=0)
20+
r_squared = models.FloatField(max_length=64)
21+
22+
def __str__(self):
23+
return str(self.id)
24+
25+
def chart_x_values(self, min_value=0, max_value=100, intervals=10):
26+
initial_range = np.arange(min_value, max_value, max_value/intervals)
27+
x_values = initial_range.tolist()
28+
x_values.append(max_value)
29+
x_values = [int(value) for value in x_values]
30+
return x_values
31+
32+
def chart_y_values(self):
33+
chart_y_values = []
34+
for x in self.chart_x_values()[1:]:
35+
y_value = self.coefficient * x + self.constant
36+
chart_y_values.append(y_value)
37+
return chart_y_values

chronic_medicare/regression.py

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import pandas as pd
2+
from sklearn.linear_model import LinearRegression
3+
4+
from .models import ChronicConditionLinearRegression
5+
from .forms import ChronicConditionLinearRegressionForm
6+
from .constants import DEPENDENT_VARIABLE
7+
8+
9+
def run_linear_regression(input_data):
10+
# df is standard short form for DataFrame object
11+
df = pd.read_csv(input_data['input_file'])
12+
13+
independent = input_data['parameters'][0]
14+
try:
15+
dependent = input_data['dependent']
16+
except KeyError:
17+
dependent = DEPENDENT_VARIABLE
18+
19+
# FIXME: Implement dummy variable logic
20+
X = df[[independent]].fillna(df[independent].mean())
21+
Y = df[[dependent]].fillna(df[dependent].mean())
22+
23+
reg = LinearRegression()
24+
reg.fit(X, Y)
25+
results = {
26+
'parameters': independent,
27+
'coefficient': reg.coef_,
28+
'constant': reg.intercept_,
29+
'r_squared': reg.score(X, Y),
30+
}
31+
return results
32+
33+
34+
def save_linear_regression(results):
35+
form = ChronicConditionLinearRegressionForm(results)
36+
if form.is_valid():
37+
regression_results, created = ChronicConditionLinearRegression.objects.get_or_create(**form.cleaned_data)
38+
return regression_results
39+
else:
40+
raise Exception("Invalid regression results!")

chronic_medicare/tests.py

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from django.test import TestCase
2+
3+
# Create your tests here.

chronic_medicare/urls.py

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from django.conf.urls import patterns, url
2+
from . import views
3+
4+
5+
urlpatterns = patterns('reports.views',
6+
url(r'^$', views.results_list, name='results_list'),
7+
url(r'^query/$', views.query_view, name='query'),
8+
url(r'^results/(?P<pk>[0-9]+)/$', views.results_detail, name='results_detail'),
9+
)
10+

chronic_medicare/views.py

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from django.shortcuts import render, redirect, get_object_or_404
2+
from .models import ChronicConditionLinearRegression
3+
from .forms import ChronicConditionAnalysisQueryForm
4+
from .regression import run_linear_regression, save_linear_regression
5+
6+
7+
def query_view(request):
8+
if request.method == 'POST':
9+
form = ChronicConditionAnalysisQueryForm(request.POST)
10+
if form.is_valid():
11+
regression_results = run_linear_regression(form.cleaned_data)
12+
saved_regression = save_linear_regression(regression_results)
13+
return redirect('chronic:results_detail', pk=saved_regression.pk)
14+
else:
15+
form = ChronicConditionAnalysisQueryForm()
16+
return render(request, 'chronic_medicare/query.html', {'form': form})
17+
18+
19+
def results_list(request):
20+
results = ChronicConditionLinearRegression.objects.all()
21+
return render(request, 'chronic_medicare/results_list.html', {'results': results})
22+
23+
24+
def results_detail(request, pk):
25+
result = get_object_or_404(ChronicConditionLinearRegression, pk=pk)
26+
return render(request, 'chronic_medicare/results_detail.html', {'result': result})

config/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)