SubashUbahs commited on
Commit
450b204
·
verified ·
1 Parent(s): a1844e3

Upload 5 files

Browse files
Files changed (5) hide show
  1. Dockerfile +17 -0
  2. index.py +166 -0
  3. requirements.txt +101 -0
  4. rf_model.pkl +3 -0
  5. server.py +51 -0
Dockerfile ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Use Python 3.10 as the base image
2
+ FROM python:3.10
3
+
4
+ # Set the working directory
5
+ WORKDIR /app
6
+
7
+ # Copy all files to the container
8
+ COPY . /app
9
+
10
+ # Install dependencies
11
+ RUN pip install --no-cache-dir -r requirements.txt
12
+
13
+ # Expose port 7860
14
+ EXPOSE 7860
15
+
16
+ # Run the Flask app
17
+ CMD ["python", "server.py"]
index.py ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import numpy as np
3
+ from sklearn.ensemble import RandomForestClassifier
4
+ from sklearn.metrics import recall_score,accuracy_score,roc_auc_score,average_precision_score,roc_curve,auc
5
+ from sklearn.feature_selection import RFECV
6
+ import seaborn as sns
7
+ from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay
8
+ from sklearn.model_selection import cross_val_score,train_test_split
9
+ from sklearn.preprocessing import LabelEncoder
10
+ from sklearn.impute import KNNImputer
11
+ import joblib
12
+ df=pd.read_excel('appendicitis.xlsx')
13
+ columns=['AppendixDiameter','ReboundTenderness','CoughingPain','FreeFluids','MigratoryPain','BodyTemp','KetonesInUrine','Nausea',
14
+ 'WBCCount','NeutrophilPerc','CRPEntry','Peritonitis','DiagnosisByCriteria']
15
+
16
+ df=df[columns]
17
+
18
+ usg_col =['AppendixDiameter','FreeFluids']
19
+
20
+ df[usg_col]=df[usg_col].fillna(0)
21
+
22
+ mapping ={
23
+ '+++' : 3,
24
+ '++': 2,
25
+ '+': 1,
26
+ 'no':0,
27
+ 'yes':1,
28
+ 'local':1,
29
+ 'generalised':2,
30
+ 'normal':0,
31
+ 'noAppendicitis':0,
32
+ 'appendicitis':1
33
+ }
34
+
35
+ for col in df.columns:
36
+ df[col]=df[col].replace(mapping)
37
+
38
+ x = df.iloc[:, 0:-1]
39
+ y = df.iloc[:, -1]
40
+
41
+
42
+ x_tempi, x_testi, y_temp, y_testi = train_test_split(x,y,test_size=0.2,random_state=17)
43
+ x_traini,x_vali,y_traini,y_vali = train_test_split(x_tempi,y_temp,test_size=0.25,random_state=17)
44
+
45
+ imputer_train = KNNImputer(n_neighbors=5)
46
+ imputer_val = KNNImputer(n_neighbors=5)
47
+ imputer_test = KNNImputer(n_neighbors=5)
48
+ imputer_temp=KNNImputer(n_neighbors=5)
49
+
50
+ x_temp=pd.DataFrame(imputer_temp.fit_transform(x_tempi),columns=x_tempi.columns,index=x_tempi.index)
51
+ x_train = pd.DataFrame(imputer_train.fit_transform(x_traini), columns=x_traini.columns, index=x_traini.index)
52
+ x_val = pd.DataFrame(imputer_val.fit_transform(x_vali), columns=x_vali.columns, index=x_vali.index)
53
+ x_test = pd.DataFrame(imputer_test.fit_transform(x_testi), columns=x_testi.columns, index=x_testi.index)
54
+
55
+ y_train=y_traini.squeeze()
56
+ y_val=y_vali.squeeze()
57
+ y_test=y_testi.squeeze()
58
+ y_temp=y_temp.squeeze()
59
+
60
+ columns_round = [ 'MigratoryPain','ReboundTenderness','CoughingPain','Peritonitis','KetonesInUrine','Nausea']
61
+
62
+ for col in columns_round:
63
+ if col in x_temp.columns:
64
+ x_temp[col]=x_temp[col].round().astype(int)
65
+ if col in x_train.columns:
66
+ x_train[col] = x_train[col].round().astype(int)
67
+ if col in x_val.columns:
68
+ x_val[col] = x_val[col].round().astype(int)
69
+ if col in x_test.columns:
70
+ x_test[col] = x_test[col].round().astype(int)
71
+
72
+
73
+ rf_model=RandomForestClassifier(
74
+ n_estimators=700,
75
+ min_samples_split=12,
76
+ min_samples_leaf=1,
77
+ max_depth=35,
78
+ random_state=17
79
+ )
80
+ scores = cross_val_score(rf_model, x_train, y_train, cv=10, scoring='accuracy', n_jobs=2)
81
+ print("Mean cross_val accuracy Score:", scores.mean())
82
+ print("Standard Deviation of cross_val accuracy Scores:", scores.std())
83
+
84
+ rf_model.fit(x_train,y_train)
85
+ joblib.dump(rf_model, 'rf_model.pkl')
86
+
87
+
88
+
89
+ # y_pred_prob=rf_model.predict_proba(x_val)[:,1]
90
+ # fpr, tpr, thresholds = roc_curve(y_val, y_pred_prob)
91
+ # youden_index = tpr - fpr
92
+ # optimal_idx = np.argmax(youden_index)
93
+ # optimal_threshold = thresholds[optimal_idx]
94
+
95
+ # distances = np.sqrt((1 - tpr)**2 + fpr**2)
96
+ # optimal_idx = np.argmin(distances)
97
+ # optimal_threshold = thresholds[optimal_idx]
98
+
99
+ # print(f"Optimal Threshold: {optimal_threshold}")
100
+
101
+ threshold=0.7032966204148201
102
+
103
+ y_pred_prob=rf_model.predict_proba(x_val)[:,1]
104
+ y_thres=(y_pred_prob >= threshold).astype(int)
105
+ auc_score = roc_auc_score(y_val, y_pred_prob)
106
+ print("Val AUC:", auc_score)
107
+ val_conf_matrix = confusion_matrix(y_val, y_thres)
108
+ TNv, FPv, FNv, TPv = val_conf_matrix.ravel()
109
+ val_sensitivity = TPv / (TPv + FNv)
110
+ val_specificity = TNv / (TNv + FPv)
111
+ val_ppv = TPv/(TPv+FPv)
112
+ val_npv = TNv/(TNv+FNv)
113
+ print(f"Sensitivity: {val_sensitivity:.3f} ({val_sensitivity * 100:.2f}%)")
114
+ print(f"Specificity: {val_specificity:.3f} ({val_specificity * 100:.2f}%)")
115
+
116
+ print (f"Positive predictive value : {val_ppv:.3f}({val_ppv*100:.2f}%)")
117
+ print (f"Negative predictive value : {val_npv:.3f}({val_npv*100:.2f}%)")
118
+
119
+ print("Val Confusion Matrix:\n", val_conf_matrix)
120
+ val_acu=accuracy_score(y_val,y_thres)
121
+ print("Val accuracy score:",val_acu)
122
+
123
+ y_test_prob=rf_model.predict_proba(x_test)[:,1]
124
+ y_thres_test=(y_test_prob >= threshold).astype(int)
125
+ auc_score = roc_auc_score(y_test, y_test_prob)
126
+ print("Test AUC:", auc_score)
127
+ test_conf_matrix = confusion_matrix(y_test, y_thres_test)
128
+ print("Test Confusion Matrix:\n", test_conf_matrix)
129
+ TNt, FPt, FNt, TPt = test_conf_matrix.ravel()
130
+ test_sensitivity = TPt / (TPt + FNt)
131
+ test_specificity = TNt / (TNt + FPt)
132
+
133
+ test_ppv = TPt/(TPt+FPt)
134
+ test_npv = TNt/(TNt+FNt)
135
+
136
+ print(f"Sensitivity: {test_sensitivity:.3f} ({test_sensitivity * 100:.2f}%)")
137
+ print(f"Specificity: {test_specificity:.3f} ({test_specificity * 100:.2f}%)")
138
+
139
+ print (f"Positive predictive value : {test_ppv:.3f}({test_ppv*100:.2f}%)")
140
+ print (f"Negative predictive value : {test_npv:.3f}({test_npv*100:.2f}%)")
141
+
142
+ test_acu=accuracy_score(y_test,y_thres_test)
143
+ print("Test Accuracy score:",test_acu)
144
+ rf_model.fit(x_temp,y_temp)
145
+ y_test1_prob=rf_model.predict_proba(x_test)[:,1]
146
+ y_thres1_test=(y_test1_prob >= threshold).astype(int)
147
+ auc_score1 = roc_auc_score(y_test, y_test1_prob)
148
+ print("Test AUC:", auc_score1)
149
+ test1_conf_matrix = confusion_matrix(y_test, y_thres1_test)
150
+ print("Test Confusion Matrix:\n", test1_conf_matrix)
151
+ TNt1, FPt1, FNt1, TPt1 = test1_conf_matrix.ravel()
152
+
153
+ test_sensitivity1 = TPt1 / (TPt1 + FNt1)
154
+ test_specificity1 = TNt1 / (TNt1 + FPt1)
155
+
156
+ test_ppv1 = TPt1/(TPt1+FPt1)
157
+ test_npv1 = TNt1/(TNt1+FNt1)
158
+
159
+ print(f"Sensitivity: {test_sensitivity1:.3f} ({test_sensitivity1 * 100:.2f}%)")
160
+ print(f"Specificity: {test_specificity1:.3f} ({test_specificity1 * 100:.2f}%)")
161
+
162
+ print (f"Positive predictive value : {test_ppv1:.3f}({test_ppv1*100:.2f}%)")
163
+ print (f"Negative predictive value : {test_npv1:.3f}({test_npv1*100:.2f}%)")
164
+
165
+ test1_acu=accuracy_score(y_test,y_thres1_test)
166
+ print("Test Accuracy score:",test1_acu)
requirements.txt ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ absl-py==2.1.0
2
+ alembic==1.13.3
3
+ asttokens==2.4.1
4
+ astunparse==1.6.3
5
+ blinker==1.8.2
6
+ certifi==2024.8.30
7
+ charset-normalizer==3.3.2
8
+ Choco==1.0.5
9
+ click==8.1.7
10
+ cloudpickle==3.1.0
11
+ colorama==0.4.6
12
+ colorlog==6.8.2
13
+ comm==0.2.2
14
+ contourpy==1.3.0
15
+ cycler==0.12.1
16
+ debugpy==1.8.6
17
+ decorator==5.1.1
18
+ et_xmlfile==2.0.0
19
+ executing==2.1.0
20
+ Flask==3.0.3
21
+ Flask-Cors==5.0.0
22
+ flatbuffers==24.3.25
23
+ fonttools==4.54.1
24
+ gast==0.6.0
25
+ google-pasta==0.2.0
26
+ gower==0.1.2
27
+ greenlet==3.1.1
28
+ grpcio==1.66.2
29
+ h5py==3.12.1
30
+ idna==3.10
31
+ ipykernel==6.29.5
32
+ ipython==8.28.0
33
+ itsdangerous==2.2.0
34
+ jedi==0.19.1
35
+ Jinja2==3.1.4
36
+ joblib==1.4.2
37
+ jupyter_client==8.6.3
38
+ jupyter_core==5.7.2
39
+ keras==3.6.0
40
+ kiwisolver==1.4.7
41
+ libclang==18.1.1
42
+ llvmlite==0.43.0
43
+ Mako==1.3.5
44
+ Markdown==3.7
45
+ markdown-it-py==3.0.0
46
+ MarkupSafe==2.1.5
47
+ matplotlib==3.9.2
48
+ matplotlib-inline==0.1.7
49
+ mdurl==0.1.2
50
+ ml-dtypes==0.4.1
51
+ namex==0.0.8
52
+ nest-asyncio==1.6.0
53
+ numba==0.60.0
54
+ numpy==1.26.4
55
+ openpyxl==3.1.5
56
+ opt_einsum==3.4.0
57
+ optree==0.13.0
58
+ optuna==4.0.0
59
+ packaging==24.1
60
+ pandas==2.2.3
61
+ parso==0.8.4
62
+ pillow==10.4.0
63
+ platformdirs==4.3.6
64
+ prompt_toolkit==3.0.48
65
+ protobuf==4.25.5
66
+ psutil==6.0.0
67
+ pure_eval==0.2.3
68
+ Pygments==2.18.0
69
+ pyparsing==3.1.4
70
+ python-dateutil==2.9.0.post0
71
+ pytz==2024.2
72
+ PyYAML==6.0.2
73
+ pyzmq==26.2.0
74
+ requests==2.32.3
75
+ rich==13.9.2
76
+ scikit-learn==1.5.2
77
+ scipy==1.14.1
78
+ seaborn==0.13.2
79
+ setuptools==75.1.0
80
+ shap==0.46.0
81
+ six==1.16.0
82
+ slicer==0.0.8
83
+ SQLAlchemy==2.0.36
84
+ stack-data==0.6.3
85
+ tensorboard==2.17.1
86
+ tensorboard-data-server==0.7.2
87
+ tensorflow==2.17.0
88
+ tensorflow-intel==2.17.0
89
+ termcolor==2.4.0
90
+ threadpoolctl==3.5.0
91
+ tornado==6.4.1
92
+ tqdm==4.66.5
93
+ traitlets==5.14.3
94
+ typing_extensions==4.12.2
95
+ tzdata==2024.2
96
+ urllib3==2.2.3
97
+ wcwidth==0.2.13
98
+ Werkzeug==3.0.4
99
+ wheel==0.44.0
100
+ wrapt==1.16.0
101
+ xgboost==2.1.1
rf_model.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:41b44ae921d87879451237b3195675f3c475cbd1fd904c734c12f16bd0a0be1f
3
+ size 1935849
server.py ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, request, render_template
2
+ import pandas as pd
3
+ import joblib
4
+
5
+ app = Flask(__name__)
6
+
7
+ # Load your pre-trained model
8
+ model = joblib.load('rf_model.pkl')
9
+ threshold = 0.7032966204148201
10
+
11
+ @app.route('/')
12
+ def home():
13
+ return render_template('index.html')
14
+
15
+ @app.route('/predict', methods=['POST'])
16
+ def predict():
17
+ try:
18
+ # Extract values from the form
19
+ features = [
20
+ float(request.form.get('AppendixDiameter')),
21
+ float(request.form.get('ReboundTenderness')),
22
+ float(request.form.get('CoughingPain')),
23
+ float(request.form.get('FreeFluids')),
24
+ float(request.form.get('MigratoryPain')),
25
+ float(request.form.get('BodyTemp')),
26
+ float(request.form.get('KetonesInUrine')),
27
+ float(request.form.get('Nausea')),
28
+ float(request.form.get('WBCCount')),
29
+ float(request.form.get('NeutrophilPerc')),
30
+ float(request.form.get('CRPEntry')),
31
+ float(request.form.get('Peritonitis'))
32
+ ]
33
+ print("features",features)
34
+ except Exception as e:
35
+ return render_template('index.html', prediction_text="Error in input: " + str(e))
36
+
37
+ # Create a DataFrame with proper column names
38
+ columns = ['AppendixDiameter', 'ReboundTenderness', 'CoughingPain', 'FreeFluids', 'MigratoryPain',
39
+ 'BodyTemp', 'KetonesInUrine', 'Nausea', 'WBCCount', 'NeutrophilPerc', 'CRPEntry', 'Peritonitis']
40
+ data = pd.DataFrame([features], columns=columns)
41
+
42
+ # Get the predicted probability and apply your threshold
43
+ pred_prob = model.predict_proba(data)[0][1]
44
+ prediction = 1 if pred_prob >= threshold else 0
45
+
46
+ result = "Appendicitis" if prediction == 1 else "No Appendicitis"
47
+
48
+ return render_template('index.html', prediction_text=f"Prediction: {result}")
49
+
50
+ if __name__ == "__main__":
51
+ app.run(debug=True)