import gradio as gr import numpy as np import pickle import pandas as pd from sklearn.preprocessing import StandardScaler # Define the questions and their possible answers questions = { 'age': { 'type': 'number', 'label': 'Age' }, 'A2': { 'type': 'radio', 'label': 'How would you rate your health generally?', 'choices': ['Very poor', 'Poor', 'Average', 'Well', 'Very well', "Don't know"], 'values': [0, 1, 1, 2, 3, -1] }, 'A1': { 'type': 'radio', 'label': 'How content or discontent do you presently feel about your life in general?', 'choices': ['Neither nor', 'Content', 'Very discontent', 'Very content', 'Discontent', "Don't know", 'Refuse to answer'], 'values': [0, 1, 2, 3, 4, 5, 6] }, 'M6': { 'type': 'number', 'label': 'In the past year, how much have you spent on medicine, nutritional supplement, vitamins (in local currency)?' }, 'M7': { 'type': 'number', 'label': 'In the past year, how much have you spent on gambling, lottery, pools, poker (in local currency)?' }, 'E5_a': { 'type': 'radio', 'label': 'In the past year, have you consulted other practitioners or therapists than your doctor?', 'choices': ['No', 'Yes', "Don't know"], 'values': [0, 1, -1] }, 'education': { 'type': 'radio', 'label': 'Education Level', 'choices': ['Completed secondary school or more (eksamensskole)', 'Completed compulsory school (folkeskole, 9 years)'], 'values': [0, 1] }, 'F10': { 'type': 'radio', 'label': 'Have you been dismissed from your job within the past 4 years?', 'choices': ['No', 'Yes', "Don't know"], 'values': [0, 1, -1] }, 'E3': { 'type': 'radio', 'label': 'How often are you in pain?', 'choices': ['Never', 'Rarely', 'Sometimes', 'Often', 'Always', "Don't know"], 'values': [0, 1, 2, 3, 4, -1] }, 'B3': { 'type': 'radio', 'label': 'Can you walk 100 meters (328 ft) on flat terrain?', 'choices': ['Not at all', 'With much difficulty', 'With some difficulty', 'Without difficulty'], 'values': [3, 0, 1, 2] }, 'B4': { 'type': 'radio', 'label': 'Can you climb up and down 12 steps?', 'choices': ['Not at all', 'With much difficulty', 'With some difficulty', 'Without difficulty'], 'values': [3, 0, 1, 2] }, 'E1': { 'type': 'number', 'label': 'How tall are you? (in centimeters)' }, 'E2': { 'type': 'number', 'label': 'How much do you weigh? (in kilos)' }, 'B1': { 'type': 'radio', 'label': 'Can you see with or without glasses?', 'choices': ['Not at all', 'With much difficulty', 'With some difficulty', 'Without difficulty'], 'values': [3, 0, 1, 2] }, 'B2': { 'type': 'radio', 'label': 'How well do you hear with or without a hearing aid?', 'choices': ['Not at all', 'With much difficulty', 'With some difficulty', 'Without difficulty'], 'values': [3, 0, 1, 2] }, 'E11': { 'type': 'number', 'label': 'How many hours a week do you normally exercise so you become warm and lose your breath?' }, 'B5': { 'type': 'radio', 'label': 'Can you concentrate and remember recent occurrences, agreements, consumed meals?', 'choices': ['Not at all', 'With much difficulty', 'With some difficulty', 'Without difficulty'], 'values': [3, 0, 1, 2] }, 'F15': { 'type': 'radio', 'label': 'On a scale from 0-10, where 0 signifies very low and 10 signifies very high, how content are you generally with your job?', 'choices': ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', "Don't know", 'Refuse to answer'], 'values': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1.5] }, 'B6': { 'type': 'radio', 'label': 'Can you eat on your own?', 'choices': ['Not at all', 'With much difficulty', 'With some difficulty', 'Without difficulty'], 'values': [3, 0, 1, 2] }, 'J14': { 'type': 'radio', 'label': 'Not counting online newspapers, how often have you read a newspaper in the past year?', 'choices': ['Never', 'Rarely', 'Sometimes', 'Often', 'Always', "Don't know"], 'values': [0, 1, 2, 3, 4, -1] }, 'J15': { 'type': 'radio', 'label': 'In the past year, how often have you discussed politics with colleagues, friends?', 'choices': ['Never', 'Rarely', 'Sometimes', 'Often', 'Always', "Don't know"], 'values': [0, 1, 2, 3, 4, -1] }, 'J17': { 'type': 'radio', 'label': 'In the past year, how often have you been abroad on holiday or family visit?', 'choices': ['Never', 'Rarely', 'Sometimes', 'Often', 'Always', "Don't know"], 'values': [0, 1, 2, 3, 4, -1] }, 'K2': { 'type': 'radio', 'label': 'How often do you use the Internet for shopping, banking transactions or paying bills?', 'choices': ['Never', 'Once a month', 'Less frequently', 'Several times a month', 'Once a week', 'Several times a week', 'Daily'], 'values': [0, 2, 1, 4, 3, 5, 6] }, 'J1': { 'type': 'radio', 'label': 'In the past year, how often have you spent time with your children and/or parents?', 'choices': ['Never', 'Once a month', 'Less frequently', 'Several times a month', 'Once a week', 'Several times a week', 'Daily'], 'values': [0, 2, 1, 4, 3, 5, 6] }, 'J2': { 'type': 'radio', 'label': 'In the past year, how often have you spent time with other relatives?', 'choices': ['Never', 'Once a month', 'Less frequently', 'Several times a month', 'Once a week', 'Several times a week', 'Daily', "Don't know", 'Refuse to answer'], 'values': [0, 2, 1, 4, 3, 5, 6, -1, -1] }, 'J4': { 'type': 'radio', 'label': 'In the past year, how often have you spent time with acquaintances?', 'choices': ['Never', 'Once a month', 'Less frequently', 'Several times a month', 'Once a week', 'Several times a week', 'Daily', "Don't know", 'Refuse to answer'], 'values': [0, 2, 1, 4, 3, 5, 6, -1, -1] }, 'E12': { 'type': 'radio', 'label': 'How often do you drink alcohol?', 'choices': ['Never', 'Less frequently', 'Less than once a month, but several times a year', 'Once a month', 'Once every fortnight', 'Once a week', '2-3 times a week', 'Almost every day', 'Every day', "Don't know"], 'values': [0, 1, 4, 3, 5, 6, 7, 8, 9, -1] }, 'E6': { 'type': 'radio', 'label': 'Have you ever smoked cigarettes, cigars, cheroot or pipe?', 'choices': ['No', 'Yes', 'Refuse to answer'], 'values': [0, 1, -1] }, 'B8': { 'type': 'radio', 'label': 'Can you do the shopping?', 'choices': ['Not at all', 'With much difficulty', 'With some difficulty', 'Without difficulty', "Don't know"], 'values': [3, 0, 1, 2, -1] }, 'B9': { 'type': 'radio', 'label': 'Can you do household chores such as cleaning and cooking?', 'choices': ['Not at all', 'With much difficulty', 'With some difficulty', 'Without difficulty', "Don't know"], 'values': [3, 0, 1, 2, -1] } } def predict_ncd(*inputs): # Convert inputs to appropriate format input_dict = {name: value for name, value in zip(questions.keys(), inputs)} # Encode categorical variables for col, value in input_dict.items(): if col in questions and questions[col]['type'] == 'radio': # Find the index of the selected choice try: choice_index = questions[col]['choices'].index(value) # Get the corresponding encoded value input_dict[col] = questions[col]['values'][choice_index] except ValueError: # Handle case where value is not in choices input_dict[col] = -1 # default value for unknown/invalid choices # Create DataFrame with encoded values df = pd.DataFrame([input_dict]) # Load the model and scaler with open('model.pkl', 'rb') as f: model = pickle.load(f) with open('scaler.pkl', 'rb') as f: scaler = pickle.load(f) # Ensure column order matches training data expected_columns = ['age', 'A2', 'A1', 'M6', 'M7', 'E5_a', 'education', 'F10', 'E3', 'B3', 'B4', 'E1', 'E2', 'B1', 'B2', 'E11', 'B5', 'F15', 'B6', 'J14', 'J15', 'J17', 'K2', 'J1', 'J2', 'J4', 'E12', 'E6', 'B8', 'B9'] df = df[expected_columns] # Convert all values to float df = df.astype(float) # Preprocess the input X = scaler.transform(df) # Make prediction pred = model.predict_proba(X)[0] return { 'No NCD': float(pred[0]), 'Has NCD': float(pred[1]) } # Create Gradio interface inputs = [] for name, config in questions.items(): if config['type'] == 'number': inputs.append(gr.Number(label=config['label'])) elif config['type'] == 'radio': inputs.append(gr.Radio(choices=config['choices'], label=config['label'])) output = gr.Label(label="Model Prediction:") iface = gr.Interface( fn=predict_ncd, inputs=inputs, outputs=output, title="NCD Risk Prediction Tool", description="Enter your health and lifestyle information to assess your risk of Noncommunicable Diseases (NCDs)", theme='huggingface' ) if __name__ == "__main__": iface.launch()