Vrajesharma commited on
Commit
6cc5288
·
verified ·
1 Parent(s): ce7f667

Upload 3 files

Browse files
Files changed (3) hide show
  1. Dockerfile +9 -0
  2. app.py +141 -0
  3. requirements.txt +10 -0
Dockerfile ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.9
2
+
3
+ WORKDIR /app
4
+
5
+ COPY . /app
6
+
7
+ RUN pip install --no-cache-dir flask gunicorn tensorflow-cpu numpy joblib scikit-learn
8
+
9
+ CMD ["gunicorn", "--bind", "0.0.0.0:7860", "app:app"]
app.py ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from flask import Flask, render_template, request, session, redirect, url_for
2
+ import joblib
3
+ import numpy as np
4
+ import tensorflow as tf
5
+
6
+ app = Flask(__name__)
7
+ app.secret_key = "verysecretkey"
8
+
9
+ # Load model & preprocessors
10
+ scaler = joblib.load('preprocessing/scaler.joblib')
11
+ le_gender = joblib.load('preprocessing/le_gender.joblib')
12
+ le_edu = joblib.load('preprocessing/le_edu.joblib')
13
+ le_interest = joblib.load('preprocessing/le_interest.joblib')
14
+ le_personality = joblib.load('preprocessing/le_personality.joblib')
15
+ deep_model = tf.keras.models.load_model('model/deep_mbti_model.h5')
16
+
17
+ mbti_descriptions = {
18
+ 'ENTJ': 'The Commander: Strategic leaders, motivated to organize change',
19
+ 'INTJ': 'The Mastermind: Analytical problem-solvers, eager to improve systems and processes',
20
+ 'ENTP': 'The Visionary: Inspired innovators, seeking new solutions to challenging problems',
21
+ 'INTP': 'The Architect: Philosophical innovators, fascinated by logical analysis',
22
+ 'ENFJ': 'The Teacher: Idealist organizers, driven to do what is best for humanity',
23
+ 'INFJ': 'The Counselor: Creative nurturers, driven by a strong sense of personal integrity',
24
+ 'ENFP': 'The Champion: People-centered creators, motivated by possibilities and potential',
25
+ 'INFP': 'The Healer: Imaginative idealists, guided by their own values and beliefs',
26
+ 'ESTJ': 'The Supervisor: Hardworking traditionalists, taking charge to get things done',
27
+ 'ISTJ': 'The Inspector: Responsible organizers, driven to create order out of chaos',
28
+ 'ESFJ': 'The Provider: Conscientious helpers, dedicated to their duties to others',
29
+ 'ISFJ': 'The Protector: Industrious caretakers, loyal to traditions and institutions',
30
+ 'ESTP': 'The Dynamo: Energetic thrillseekers, ready to push boundaries and dive into action',
31
+ 'ISTP': 'The Craftsperson: Observant troubleshooters, solving practical problems',
32
+ 'ESFP': 'The Entertainer: Vivacious entertainers, loving life and charming those around them',
33
+ 'ISFP': 'The Composer: Gentle caretakers, enjoying the moment with low-key enthusiasm'
34
+ }
35
+
36
+ # Mapping for MCQ answers (A/B/C/D) to numeric scores (customize as needed)
37
+ MCQ_MAP = {'A': 10, 'B': 7, 'C': 4, 'D': 1}
38
+
39
+ # MCQ config: 4 MBTI traits, 5 Qs each
40
+ TRAITS = [
41
+ ('extroversion', "Extroversion (E/I)", [
42
+ "Are you comfortable with public speaking?",
43
+ "Do you enjoy being the center of attention?",
44
+ "Do you thrive in group settings?",
45
+ "Do you make friends easily at new places?",
46
+ "Do group activities energize you more than being alone?"
47
+ ]),
48
+ ('sensing', "Sensing vs Intuition (S/N)", [
49
+ "Do you focus more on immediate details than the big picture?",
50
+ "Do you trust experience over theories?",
51
+ "Do you prefer practical applications over abstract concepts?",
52
+ "Do you rely on your five senses rather than gut feelings?",
53
+ "Do you prefer dealing with practical facts rather than imaginative ideas?"
54
+ ]),
55
+ ('thinking', "Thinking vs Feeling (T/F)", [
56
+ "Do you prioritize logic over emotions when deciding?",
57
+ "Do you value objective truth over social harmony?",
58
+ "Are you comfortable giving critical feedback?",
59
+ "Do you analyze problems objectively rather than considering people's feelings first?",
60
+ "Is it more important for you to be fair than to be compassionate?"
61
+ ]),
62
+ ('judging', "Judging vs Perceiving (J/P)", [
63
+ "Do you prefer planned activities over spontaneous ones?",
64
+ "Do you enjoy making schedules and to-do lists?",
65
+ "Are you uncomfortable with last-minute changes?",
66
+ "Do you prefer closure and completion over keeping options open?",
67
+ "Do you prefer having a structured plan rather than keeping options open?"
68
+ ])
69
+ ]
70
+
71
+ # Step 0: Demographics collection
72
+ @app.route('/', methods=['GET', 'POST'])
73
+ def demographics():
74
+ if request.method == 'POST':
75
+ session['demographics'] = {
76
+ 'age': request.form['age'],
77
+ 'gender': request.form['gender'],
78
+ 'education': request.form['education'],
79
+ 'interest': request.form['interest']
80
+ }
81
+ return redirect(url_for('mcq', step=1))
82
+ return render_template('index.html',
83
+ gender_classes=le_gender.classes_,
84
+ edu_classes=le_edu.classes_,
85
+ interest_classes=le_interest.classes_)
86
+
87
+ # Step 1-N: MCQ stepper for MBTI traits
88
+ @app.route('/mcq/<int:step>', methods=['GET', 'POST'])
89
+ def mcq(step):
90
+ total_steps = len(TRAITS)
91
+ if request.method == 'POST' and step > 1:
92
+ prev_trait_key = TRAITS[step - 2][0]
93
+ session[prev_trait_key] = [
94
+ request.form.get(f'{prev_trait_key}_q{i}', None) for i in range(1, 6)
95
+ ]
96
+ if step > total_steps:
97
+ return redirect(url_for('results'))
98
+ trait_key, trait_label, questions = TRAITS[step - 1]
99
+ return render_template('mcq_step.html',
100
+ trait_key=trait_key,
101
+ trait_label=trait_label,
102
+ questions=questions,
103
+ step=step,
104
+ total_steps=total_steps)
105
+
106
+ # Final: Results calculation and personality prediction
107
+ @app.route('/results')
108
+ def results():
109
+ try:
110
+ data = session.get('demographics', {})
111
+ age = float(data.get('age', 25))
112
+ gender = le_gender.transform([data.get('gender', le_gender.classes_[0])])[0]
113
+ education = le_edu.transform([data.get('education', le_edu.classes_[0])])[0]
114
+ interest = le_interest.transform([data.get('interest', le_interest.classes_[0])])[0]
115
+
116
+ # Collect trait scores, average each over 5 MCQs
117
+ trait_keys = ['extroversion', 'sensing', 'thinking', 'judging']
118
+ trait_scores = []
119
+ for trait_key in trait_keys:
120
+ answers = session.get(trait_key, ['C'] * 5) # default 5 'C'
121
+ numeric_scores = [MCQ_MAP.get(ans, 4) for ans in answers]
122
+ trait_scores.append(float(sum(numeric_scores)) / 5)
123
+
124
+ # Features: [age, gender, education, extroversion, sensing, thinking, judging, interest]
125
+ features = np.array([[age, gender, education] + trait_scores + [interest]])
126
+ features_scaled = scaler.transform(features)
127
+ pred_proba = deep_model.predict(features_scaled)
128
+ pred_class = np.argmax(pred_proba)
129
+ mbti_pred = le_personality.inverse_transform([pred_class])[0]
130
+ class_probs = dict(zip(le_personality.classes_, pred_proba[0].round(3)))
131
+ description = mbti_descriptions.get(mbti_pred, '')
132
+ except Exception as e:
133
+ mbti_pred, class_probs, description = None, None, f"Error: {e}"
134
+ session.clear()
135
+ return render_template('results.html',
136
+ mbti_pred=mbti_pred,
137
+ class_probs=class_probs,
138
+ description=description)
139
+
140
+ if __name__ == '__main__':
141
+ app.run(debug=True)
requirements.txt ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ Flask==3.0.0
2
+ numpy==1.26.2
3
+ pandas==2.1.2
4
+ joblib==1.3.2
5
+ scikit-learn==1.3.2
6
+ tensorflow==2.15.0
7
+ gunicorn==21.2.0
8
+ Werkzeug==3.0.1
9
+ setuptools>=68.0.0
10
+ wheel>=0.42.0