DjPapzin commited on
Commit
4fce22f
·
1 Parent(s): 5638f9d

Removed Model from root directory

Browse files
Files changed (4) hide show
  1. .gitattributes +0 -1
  2. FINAL_MODEL.keras +0 -3
  3. app.py +0 -520
  4. logistic_regression_model.pkl +0 -3
.gitattributes CHANGED
@@ -35,6 +35,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
  frontend/react-code/src/assets/falcondemo.mp4 filter=lfs diff=lfs merge=lfs -text
37
  frontend/FINAL_MODEL.keras filter=lfs diff=lfs merge=lfs -text
38
- FINAL_MODEL.keras filter=lfs diff=lfs merge=lfs -text
39
  *.jpeg filter=lfs diff=lfs merge=lfs -text
40
  *.jpg filter=lfs diff=lfs merge=lfs -text
 
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
  frontend/react-code/src/assets/falcondemo.mp4 filter=lfs diff=lfs merge=lfs -text
37
  frontend/FINAL_MODEL.keras filter=lfs diff=lfs merge=lfs -text
 
38
  *.jpeg filter=lfs diff=lfs merge=lfs -text
39
  *.jpg filter=lfs diff=lfs merge=lfs -text
FINAL_MODEL.keras DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:dff0eafd711bccd941d3cca9bff29202c4b4e40a4ef2d814986137d997ccfd13
3
- size 228465191
 
 
 
 
app.py DELETED
@@ -1,520 +0,0 @@
1
- import streamlit as st
2
- import requests
3
- from utils.ai71_utils import get_ai71_response
4
- from datetime import datetime
5
- import cv2
6
- import numpy as np
7
- from PIL import Image
8
- import supervision as sv
9
- import matplotlib.pyplot as plt
10
- import io
11
- import os
12
- from inference_sdk import InferenceHTTPClient
13
- from bs4 import BeautifulSoup
14
- import tensorflow as tf
15
- import pandas as pd
16
- from sklearn.feature_extraction.text import CountVectorizer
17
- from sklearn.model_selection import train_test_split
18
- from sklearn.linear_model import LogisticRegression
19
- from sklearn.metrics import accuracy_score, classification_report
20
- import nltk
21
- import re
22
- from nltk.tokenize import word_tokenize
23
- from nltk.corpus import stopwords
24
-
25
- # --- Preprocess text function (moved outside session state) ---
26
- def preprocess_text(text):
27
- # Convert to lowercase
28
- text = text.lower()
29
-
30
- cleaned_text = re.sub(r'[^a-zA-Z0-9\s\,]', ' ', text)
31
- # Tokenize text
32
- tokens = word_tokenize(cleaned_text)
33
-
34
- # Remove stop words
35
- stop_words = set(stopwords.words('english'))
36
- tokens = [word for word in tokens if word not in stop_words]
37
-
38
- # Rejoin tokens into a single string
39
- cleaned_text = ' '.join(tokens)
40
-
41
- return cleaned_text
42
-
43
- st.title("Medi Scape Dashboard")
44
-
45
- # --- Session State Initialization ---
46
- if 'disease_model' not in st.session_state:
47
- try:
48
- model_path = 'frontend/FINAL_MODEL.keras'
49
- print(f"Attempting to load disease model from: {model_path}")
50
- print(f"Model file exists: {os.path.exists(model_path)}")
51
- st.session_state.disease_model = tf.keras.models.load_model(model_path)
52
- print("Disease model loaded successfully!")
53
- except FileNotFoundError:
54
- st.error("Disease classification model not found. Please ensure 'FINAL_MODEL.keras' is in the same directory as this app.")
55
- st.session_state.disease_model = None
56
-
57
- # Load the vectorizer
58
- if 'vectorizer' not in st.session_state:
59
- # Always create and save the vectorizer
60
- print("Creating and saving vectorizer...")
61
- # Load your training data here (replace with your actual data loading)
62
- dataset_1 = pd.read_csv("Symptoms_Detection/training_data.csv")
63
- dataset_2 = pd.read_csv("Symptoms_Detection/Symptom2Disease.csv")
64
-
65
- # --- Data Preprocessing ---
66
- # Create symptoms_text column
67
- dataset_1['symptoms_text'] = dataset_1.apply(lambda row: ','.join([col for col in dataset_1.columns if row[col] == 1]), axis=1)
68
- final_dataset = pd.DataFrame(dataset_1[["prognosis", "symptoms_text"]])
69
- final_dataset.columns = ['label', 'text']
70
-
71
- # Combine datasets
72
- df_combined = pd.concat([final_dataset, dataset_2[['label', 'text']]], axis=0, ignore_index=True)
73
-
74
- # Preprocess text (apply the preprocess_text function to the 'text' column)
75
- df_combined['text'] = df_combined['text'].apply(preprocess_text)
76
-
77
- # --- End of Data Preprocessing ---
78
-
79
- # Create and fit the vectorizer
80
- vectorizer = CountVectorizer()
81
- vectorizer.fit(df_combined['text'])
82
-
83
- # Save the vectorizer
84
- vectorizer_path = "vectorizer.pkl"
85
- pd.to_pickle(vectorizer, vectorizer_path)
86
- st.session_state.vectorizer = vectorizer
87
- print("Vectorizer saved successfully!")
88
-
89
- if 'model_llm' not in st.session_state:
90
- # --- Load pre-trained model and vectorizer ---
91
- st.session_state.model_llm = LogisticRegression()
92
- try:
93
- llm_model_path = "logistic_regression_model.pkl"
94
- print(f"Attempting to load LLM model from: {llm_model_path}")
95
- print(f"LLM Model file exists: {os.path.exists(llm_model_path)}")
96
- st.session_state.model_llm = pd.read_pickle(llm_model_path)
97
- print("LLM model loaded successfully!")
98
- except FileNotFoundError:
99
- st.error("LLM model file not found. Please ensure 'logistic_regression_model.pkl' is in the same directory.")
100
- st.session_state.model_llm = None
101
-
102
- # Load datasets (only for reference, not used for training)
103
- dataset_1 = pd.read_csv("Symptoms_Detection/training_data.csv")
104
- dataset_2 = pd.read_csv("Symptoms_Detection/Symptom2Disease.csv")
105
-
106
- # Create symptoms_text column (only for reference, not used for training)
107
- dataset_1['symptoms_text'] = dataset_1.apply(lambda row: ','.join([col for col in dataset_1.columns if row[col] == 1]), axis=1)
108
- final_dataset = pd.DataFrame(dataset_1[["prognosis", "symptoms_text"]])
109
- final_dataset.columns = ['label', 'text']
110
-
111
- # Combine datasets (only for reference, not used for training)
112
- df_combined = pd.concat([final_dataset, dataset_2[['label', 'text']]], axis=0, ignore_index=True)
113
-
114
- # Store in session state (only for reference, not used for training)
115
- st.session_state.df_combined = df_combined
116
- # --- End of Session State Initialization ---
117
-
118
- # Load the disease classification model
119
- try:
120
- disease_model = tf.keras.models.load_model('FINAL_MODEL.keras')
121
- except FileNotFoundError:
122
- st.error("Disease classification model not found. Please ensure 'FINAL_MODEL.keras' is in the same directory as this app.")
123
- disease_model = None
124
-
125
- # Sidebar Navigation
126
- st.sidebar.title("Navigation")
127
- page = st.sidebar.radio("Go to", ["Home", "AI Chatbot Diagnosis", "Drug Identification", "Disease Detection", "Outbreak Alert"])
128
-
129
- # Access secrets using st.secrets
130
- if "INFERENCE_API_URL" not in st.secrets or "INFERENCE_API_KEY" not in st.secrets:
131
- st.error("Please make sure to set your secrets in the Streamlit secrets settings.")
132
- else:
133
- # Initialize the Inference Client
134
- CLIENT = InferenceHTTPClient(
135
- api_url=st.secrets["INFERENCE_API_URL"],
136
- api_key=st.secrets["INFERENCE_API_KEY"]
137
- )
138
-
139
- # Function to preprocess the image
140
- def preprocess_image(image_path):
141
- # Load the image
142
- image = cv2.imread(image_path)
143
-
144
- # Convert to grayscale
145
- gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
146
-
147
- # Remove noise
148
- blurred = cv2.GaussianBlur(gray, (5, 5), 0)
149
-
150
- # Thresholding/Binarization
151
- _, binary = cv2.threshold(blurred, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
152
-
153
- # Dilation and Erosion
154
- kernel = np.ones((1, 1), np.uint8)
155
- dilated = cv2.dilate(binary, kernel, iterations=1)
156
- eroded = cv2.erode(dilated, kernel, iterations=1)
157
-
158
- # Edge detection
159
- edges = cv2.Canny(eroded, 100, 200)
160
-
161
- # Deskewing
162
- coords = np.column_stack(np.where(edges > 0))
163
- angle = cv2.minAreaRect(coords)[-1]
164
- if angle < -45:
165
- angle = -(90 + angle)
166
- else:
167
- angle = -angle
168
-
169
- (h, w) = edges.shape[:2]
170
- center = (w // 2, h // 2)
171
- M = cv2.getRotationMatrix2D(center, angle, 1.0)
172
- deskewed = cv2.warpAffine(edges, M, (w, h), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REPLICATE)
173
-
174
- # Find contours
175
- contours, _ = cv2.findContours(deskewed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
176
-
177
- # Draw contours on the original image
178
- contour_image = image.copy()
179
- cv2.drawContours(contour_image, contours, -1, (0, 255, 0), 2)
180
-
181
- return contour_image
182
-
183
- def get_x1(detection):
184
- return detection.xyxy[0][0]
185
-
186
- # Access secrets using st.secrets
187
- if "INFERENCE_API_URL" not in st.secrets or "INFERENCE_API_KEY" not in st.secrets:
188
- st.error("Please make sure to set your secrets in the Streamlit secrets settings.")
189
- else:
190
- # Initialize the Inference Client
191
- CLIENT = InferenceHTTPClient(
192
- api_url=st.secrets["INFERENCE_API_URL"],
193
- api_key=st.secrets["INFERENCE_API_KEY"]
194
- )
195
-
196
- # Function to preprocess the image
197
- def preprocess_image(image_path):
198
- # Load the image
199
- image = cv2.imread(image_path)
200
-
201
- # Convert to grayscale
202
- gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
203
-
204
- # Remove noise
205
- blurred = cv2.GaussianBlur(gray, (5, 5), 0)
206
-
207
- # Thresholding/Binarization
208
- _, binary = cv2.threshold(blurred, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
209
-
210
- # Dilation and Erosion
211
- kernel = np.ones((1, 1), np.uint8)
212
- dilated = cv2.dilate(binary, kernel, iterations=1)
213
- eroded = cv2.erode(dilated, kernel, iterations=1)
214
-
215
- # Edge detection
216
- edges = cv2.Canny(eroded, 100, 200)
217
-
218
- # Deskewing
219
- coords = np.column_stack(np.where(edges > 0))
220
- angle = cv2.minAreaRect(coords)[-1]
221
- if angle < -45:
222
- angle = -(90 + angle)
223
- else:
224
- angle = -angle
225
-
226
- (h, w) = edges.shape[:2]
227
- center = (w // 2, h // 2)
228
- M = cv2.getRotationMatrix2D(center, angle, 1.0)
229
- deskewed = cv2.warpAffine(edges, M, (w, h), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REPLICATE)
230
-
231
- # Find contours
232
- contours, _ = cv2.findContours(deskewed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
233
-
234
- # Draw contours on the original image
235
- contour_image = image.copy()
236
- cv2.drawContours(contour_image, contours, -1, (0, 255, 0), 2)
237
-
238
- return contour_image
239
-
240
- def get_x1(detection):
241
- return detection.xyxy[0][0]
242
-
243
- # --- Prediction function (using session state) ---
244
- def predict_disease(symptoms):
245
- if st.session_state.vectorizer is not None and st.session_state.model_llm is not None:
246
- preprocessed_symptoms = preprocess_text(symptoms)
247
- symptoms_vectorized = st.session_state.vectorizer.transform([preprocessed_symptoms])
248
- prediction = st.session_state.model_llm.predict(symptoms_vectorized)
249
- return prediction[0]
250
- else:
251
- st.error("Unable to make prediction. Vectorizer or LLM model is not loaded.")
252
- return None
253
-
254
- # --- New function to analyze X-ray with LLM ---
255
- def analyze_xray_with_llm(predicted_class):
256
- prompt = f"""
257
- Based on a chest X-ray analysis, the predicted condition is {predicted_class}.
258
- Please provide a concise summary of this condition, including:
259
- - A brief description of the condition.
260
- - Common symptoms associated with it.
261
- - Potential causes.
262
- - General treatment approaches.
263
- - Any other relevant information for a patient.
264
- """
265
- llm_response = get_ai71_response(prompt)
266
- st.write("## LLM Analysis of X-ray Results:")
267
- st.write(llm_response)
268
-
269
- if page == "Home":
270
- st.markdown("## Welcome to Medi Scape")
271
- st.write("Medi Scape is an AI-powered healthcare application designed to streamline the process of understanding and managing medical information. It leverages advanced AI models to provide features such as prescription analysis, disease detection from chest X-rays, and symptom-based diagnosis assistance.")
272
-
273
- st.markdown("## Features")
274
- st.write("Medi Scape provides various AI-powered tools for remote healthcare, including:")
275
- features = [
276
- "**AI Chatbot Diagnosis:** Interact with an AI chatbot for preliminary diagnosis and medical information.",
277
- "**Drug Identification:** Upload a prescription image to identify medications and access relevant details.",
278
- "**Doctor's Handwriting Identification:** Our system can accurately recognize and process doctor's handwriting.",
279
- "**Disease Detection:** Upload a chest X-ray image to detect potential diseases.",
280
- "**Outbreak Alert:** Stay informed about potential disease outbreaks in your area."
281
- ]
282
- for feature in features:
283
- st.markdown(f"- {feature}")
284
-
285
- st.markdown("## How it Works")
286
- steps = [
287
- "**Upload:** You can upload a prescription image for drug identification or a chest X-ray image for disease detection.",
288
- "**Process:** Our AI models will analyze the image and extract relevant information.",
289
- "**Results:** You will receive identified drug names, uses, side effects, and more, or a potential disease diagnosis."
290
- ]
291
- for i, step in enumerate(steps, 1):
292
- st.markdown(f"{i}. {step}")
293
-
294
- st.markdown("## Key Features")
295
- key_features = [
296
- "**AI-Powered:** Leverages advanced AI models for accurate analysis and diagnosis.",
297
- "**User-Friendly:** Simple and intuitive interface for easy navigation and interaction.",
298
- "**Secure:** Your data is protected and handled with confidentiality."
299
- ]
300
- for feature in key_features:
301
- st.markdown(f"- {feature}")
302
-
303
- st.markdown("Please use the sidebar to navigate to different features.")
304
-
305
- elif page == "AI Chatbot Diagnosis":
306
- st.write("Enter your symptoms separated by commas:")
307
- symptoms_input = st.text_area("Symptoms:")
308
- if st.button("Diagnose"):
309
- if symptoms_input:
310
- # --- Pipeline 1 Implementation ---
311
- # 1. Symptom Input (already done with st.text_area)
312
- # 2. Regression Prediction
313
- regression_prediction = predict_disease(symptoms_input)
314
-
315
- if regression_prediction is not None:
316
- # 3. LLM Prompt Enhancement
317
- prompt = f"""The predicted condition based on a symptom analysis is {regression_prediction}.
318
- Provide a detailed explanation of this condition, including possible causes, common symptoms,
319
- and general treatment approaches. Also, suggest when a patient should consult a doctor."""
320
-
321
- # 4. LLM Output
322
- llm_response = get_ai71_response(prompt)
323
-
324
- # 5. Combined Output
325
- st.write("## Logistic Regression Prediction:")
326
- st.write(regression_prediction)
327
-
328
- st.write("## LLM Explanation:")
329
- st.write(llm_response)
330
- # --- End of Pipeline 1 Implementation ---
331
-
332
- else:
333
- st.write("Please enter your symptoms.")
334
-
335
- elif page == "Drug Identification":
336
- st.write("Upload a prescription image for drug identification.")
337
- uploaded_file = st.file_uploader("Upload prescription", type=["png", "jpg", "jpeg"])
338
-
339
- if uploaded_file is not None:
340
- # Display the uploaded image
341
- image = Image.open(uploaded_file)
342
- st.image(image, caption="Uploaded Prescription", use_column_width=True)
343
-
344
- if st.button("Process Prescription"):
345
- # Save the image to a temporary file
346
- temp_image_path = "temp_image.jpg"
347
- image.save(temp_image_path)
348
-
349
- # Preprocess the image
350
- preprocessed_image = preprocess_image(temp_image_path)
351
-
352
- # Perform inference
353
- result_doch1 = CLIENT.infer(preprocessed_image, model_id="doctor-s-handwriting/1")
354
-
355
- # Extract labels and detections
356
- labels = [item["class"] for item in result_doch1["predictions"]]
357
- detections = sv.Detections.from_inference(result_doch1)
358
-
359
- # Sort detections and labels
360
- sorted_indices = sorted(range(len(detections)), key=lambda i: get_x1(detections[i]))
361
- sorted_detections = [detections[i] for i in sorted_indices]
362
- sorted_labels = [labels[i] for i in sorted_indices]
363
-
364
- # Convert list to string
365
- resulting_string = ''.join(sorted_labels)
366
-
367
- # Display results
368
- st.subheader("Processed Prescription")
369
- fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 6))
370
-
371
- # Plot bounding boxes
372
- image_with_boxes = preprocessed_image.copy()
373
- for detection in sorted_detections:
374
- x1, y1, x2, y2 = detection.xyxy[0]
375
- cv2.rectangle(image_with_boxes, (int(x1), int(y1)), (int(x2), int(y2)), (255, 0, 0), 2)
376
- ax1.imshow(cv2.cvtColor(image_with_boxes, cv2.COLOR_BGR2RGB))
377
- ax1.set_title("Bounding Boxes")
378
- ax1.axis('off')
379
-
380
- # Plot labels
381
- image_with_labels = preprocessed_image.copy()
382
- for i, detection in enumerate(sorted_detections):
383
- x1, y1, x2, y2 = detection.xyxy[0]
384
- label = sorted_labels[i]
385
- cv2.putText(image_with_labels, label, (int(x1), int(y1) - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)
386
- ax2.imshow(cv2.cvtColor(image_with_labels, cv2.COLOR_BGR2RGB))
387
- ax2.set_title("Labels")
388
- ax2.axis('off')
389
-
390
- st.pyplot(fig)
391
-
392
- st.write("Extracted Text from Prescription:", resulting_string)
393
-
394
- # Prepare prompt for LLM
395
- prompt = f"""Analyze the following prescription text:
396
- {resulting_string}
397
-
398
- Please provide:
399
- 1. Identified drug name(s)
400
- 2. Full name of each identified drug
401
- 3. Primary uses of each drug
402
- 4. Common side effects
403
- 5. Recommended dosage (if identifiable from the text)
404
- 6. Any warnings or precautions
405
- 7. Potential interactions with other medications (if multiple drugs are identified)
406
- 8. Any additional relevant information for the patient
407
-
408
- If any part of the prescription is unclear or seems incomplete, please mention that and provide information about possible interpretations or matches. Always emphasize the importance of consulting a healthcare professional for accurate interpretation and advice."""
409
-
410
- # Get LLM response
411
- llm_response = get_ai71_response(prompt)
412
-
413
- st.subheader("AI Analysis of the Prescription")
414
- st.write(llm_response)
415
-
416
- # Remove the temporary image file
417
- os.remove(temp_image_path)
418
-
419
- else:
420
- st.info("Please upload a prescription image to proceed.")
421
-
422
- elif page == "Disease Detection":
423
- st.write("Upload a chest X-ray image for disease detection.")
424
- uploaded_image = st.file_uploader("Choose an image...", type=["jpg", "jpeg", "png"])
425
-
426
- if uploaded_image is not None and st.session_state.disease_model is not None:
427
- # Display the image
428
- img_opened = Image.open(uploaded_image).convert('RGB')
429
- image_pred = np.array(img_opened)
430
- image_pred = cv2.resize(image_pred, (150, 150))
431
-
432
- # Convert the image to a numpy array
433
- image_pred = np.array(image_pred)
434
-
435
- # Rescale the image (if the model was trained with rescaling)
436
- image_pred = image_pred / 255.0
437
-
438
- # Add an extra dimension to match the input shape (1, 150, 150, 3)
439
- image_pred = np.expand_dims(image_pred, axis=0)
440
-
441
- # Predict using the model
442
- prediction = st.session_state.disease_model.predict(image_pred)
443
-
444
- # Get the predicted class
445
- predicted_ = np.argmax(prediction)
446
-
447
- # Decode the prediction
448
- if predicted_ == 0:
449
- predicted_class = "Covid"
450
- elif predicted_ == 1:
451
- predicted_class = "Normal Chest X-ray"
452
- else:
453
- predicted_class = "Pneumonia"
454
-
455
- st.image(image_pred, caption='Input image by user', use_column_width=True)
456
- st.write("Prediction Classes for different types:")
457
- st.write("COVID: 0")
458
- st.write("Normal Chest X-ray: 1")
459
- st.write("Pneumonia: 2")
460
- st.write("\n")
461
- st.write("DETECTED DISEASE DISPLAY")
462
- st.write(f"Predicted Class : {predicted_}")
463
- st.write(predicted_class)
464
-
465
- # Analyze X-ray results with LLM
466
- analyze_xray_with_llm(predicted_class)
467
- else:
468
- st.write("Please upload an image file or ensure the disease model is loaded.")
469
-
470
- elif page == "Outbreak Alert":
471
- st.markdown("## **Disease Outbreak News (from WHO)**")
472
-
473
- # Fetch WHO news page
474
- url = "https://www.who.int/news-room/events"
475
- response = requests.get(url)
476
- response.raise_for_status() # Raise an exception for bad status codes
477
-
478
- soup = BeautifulSoup(response.content, 'html.parser')
479
-
480
- # Find news articles (adjust selectors if WHO website changes)
481
- articles = soup.find_all('div', class_='list-view--item')
482
-
483
- for article in articles[:5]: # Display the top 5 news articles
484
- title_element = article.find('a', class_='link-container')
485
- if title_element:
486
- title = title_element.text.strip()
487
- link = title_element['href']
488
- date_element = article.find('span', class_='date')
489
- date = date_element.text.strip() if date_element else "Date not found"
490
-
491
- # Format date
492
- date_parts = date.split()
493
- if len(date_parts) >= 3:
494
- try:
495
- formatted_date = datetime.strptime(date, "%d %B %Y").strftime("%Y-%m-%d")
496
- except ValueError:
497
- formatted_date = date # Keep the original date if formatting fails
498
- else:
499
- formatted_date = date
500
-
501
- # Display news item in a card-like container
502
- with st.container():
503
- st.markdown(f"**{formatted_date}**")
504
- st.markdown(f"[{title}]({link})")
505
- st.markdown("---")
506
- else:
507
- st.write("Could not find article details.")
508
-
509
- # Auto-scroll to the bottom of the chat container
510
- st.markdown(
511
- """
512
- <script>
513
- const chatContainer = document.querySelector('.st-chat-container');
514
- if (chatContainer) {
515
- chatContainer.scrollTop = chatContainer.scrollHeight;
516
- }
517
- </script>
518
- """,
519
- unsafe_allow_html=True,
520
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
logistic_regression_model.pkl DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:cfd5b38cded9c2b4426bb8cc9f337cd078973f5488e2692f3ecd21db3cc41c96
3
- size 601655