dnth commited on
Commit
e0510bc
·
verified ·
1 Parent(s): a1b9f82

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +53 -87
app.py CHANGED
@@ -5,8 +5,10 @@ import pandas as pd
5
  from sentence_transformers import SentenceTransformer
6
  from collections import OrderedDict
7
 
 
8
  class RiasecPredictor:
9
- def __init__(self, regressor_path='riasec_regressor.pkl',
 
10
  embedding_model_path='all-MiniLM-L6-v2'):
11
  """
12
  Load saved models for RIASEC prediction
@@ -14,21 +16,21 @@ class RiasecPredictor:
14
  print("Loading models...")
15
  self.embedding_model = SentenceTransformer(embedding_model_path)
16
  self.regressor = joblib.load(regressor_path)
 
 
 
 
 
17
  self.riasec_labels = ['R', 'I', 'A', 'S', 'E', 'C']
18
- print("✅ Models loaded successfully!")
 
 
 
 
19
 
20
  def predict(self, job_title=None, job_description=None, full_text=None, sort_by_score=True):
21
  """
22
- Predict RIASEC scores for a job
23
-
24
- Args:
25
- job_title (str): Job title
26
- job_description (str): Job description
27
- full_text (str): Complete job text (alternative to title + description)
28
- sort_by_score (bool): If True, return results sorted by score (highest to lowest)
29
-
30
- Returns:
31
- dict or OrderedDict: RIASEC scores clamped to [1.0, 7.0]
32
  """
33
  # Handle input
34
  if full_text is not None:
@@ -41,109 +43,73 @@ class RiasecPredictor:
41
  # Generate embedding
42
  embedding = self.embedding_model.encode([text], convert_to_numpy=True)
43
 
44
- # Make prediction
45
- prediction = self.regressor.predict(embedding)[0]
46
- prediction = np.clip(prediction, 1.0, 7.0)
 
 
 
47
 
48
  # Create dictionary
49
  riasec_dict = dict(zip(self.riasec_labels, prediction.tolist()))
50
 
51
- # Sort by score if requested
52
  if sort_by_score:
53
- # Sort by value (score) in descending order
54
- sorted_riasec = OrderedDict(
55
- sorted(riasec_dict.items(), key=lambda x: x[1], reverse=True)
56
- )
57
- return sorted_riasec
58
  else:
59
  return riasec_dict
60
 
61
  def predict_with_names(self, job_title=None, job_description=None, full_text=None):
62
- """
63
- Predict RIASEC scores with full names in R-I-A-S-E-C order
64
-
65
- Returns:
66
- OrderedDict: Full RIASEC names with scores, in R-I-A-S-E-C order
67
- """
68
- # Get results with codes (not sorted by score)
69
  results = self.predict(job_title, job_description, full_text, sort_by_score=False)
70
-
71
- # Map codes to full names in R-I-A-S-E-C order
72
- code_to_name = {
73
- 'R': 'Realistic',
74
- 'I': 'Investigative',
75
- 'A': 'Artistic',
76
- 'S': 'Social',
77
- 'E': 'Enterprising',
78
- 'C': 'Conventional'
79
- }
80
-
81
- # Create ordered dict with full names in R-I-A-S-E-C order
82
  ordered_with_names = OrderedDict()
83
- riasec_order = ['R', 'I', 'A', 'S', 'E', 'C']
84
-
85
- for code in riasec_order:
86
- if code in results:
87
- ordered_with_names[code_to_name[code]] = results[code]
88
-
89
  return ordered_with_names
90
 
91
- # Initialize predictor once when the script runs
 
92
  predictor = RiasecPredictor()
93
 
 
94
  def predict_riasec(job_title, job_description):
95
- """
96
- Wrapper function for Gradio interface
97
- """
98
  try:
99
- if job_title.strip() and job_description.strip():
100
- # Use job_title and job_description
101
- # Always use abbreviations (R, I, A, S, E, C) as default
102
- # Use sort_by_score=False to maintain R-I-A-S-E-C order for the bar chart
103
- result = predictor.predict(job_title=job_title, job_description=job_description, sort_by_score=False)
104
- else:
105
  return None, "Please provide both job title and job description."
106
 
107
- # Skip text formatting since we're removing the text output
 
 
 
 
108
 
109
- # Prepare data for gr.BarPlot
110
- # Convert to the format expected by gr.BarPlot (pandas DataFrame)
111
- # Maintain R-I-A-S-E-C order regardless of scores
112
  riasec_order = ['R', 'I', 'A', 'S', 'E', 'C']
113
-
114
- # Get the scores in the correct order
115
  ordered_labels = []
116
- ordered_values = []
117
 
118
- for riasec_type in riasec_order:
119
- if riasec_type in result:
120
- ordered_labels.append(riasec_type)
121
- ordered_values.append(result[riasec_type])
122
 
123
- # Create pandas DataFrame for BarPlot
124
  bar_data = pd.DataFrame({
125
- "RIASEC": ordered_labels,
126
- "Score": ordered_values
127
  })
128
 
129
- # Prepare data for Top 3 RIASEC panel - only codes without scores, formatted as markdown
130
- # Sort results by score for the top 3 display
131
- sorted_result = OrderedDict(sorted(result.items(), key=lambda x: x[1], reverse=True))
132
-
133
  top_3_result = "### Top 3 RIASEC Types\n\n"
134
- for i, (key, value) in enumerate(sorted_result.items()):
135
- if i < 3: # Only take top 3
136
- # Add some styling to make each RIASEC code more prominent with better contrast
137
- top_3_result += f"<div style='font-size: 1.5em; font-weight: bold; margin: 5px 0; padding: 10px; background-color: #f0f0f0; color: #000000; border-radius: 5px; text-align: center; border: 1px solid #cccccc;'>{key}</div>\n"
138
- else:
139
- break
140
 
141
  return bar_data, top_3_result
 
142
  except Exception as e:
143
- print(f"Error in predict_riasec: {str(e)}") # Add debug output
144
  return None, f"Error: {str(e)}"
145
 
146
- # Create Gradio interface
 
147
  with gr.Blocks(title="RIASEC Predictor") as demo:
148
  gr.Markdown("# RIASEC Predictor")
149
  gr.Markdown("Predict RIASEC personality type scores for job descriptions")
@@ -156,11 +122,11 @@ with gr.Blocks(title="RIASEC Predictor") as demo:
156
 
157
  with gr.Column():
158
  output_chart = gr.BarPlot(
159
- x="RIASEC",
160
  y="Score",
161
  title="RIASEC Scores",
162
- orientation="h", # horizontal orientation
163
- color="RIASEC",
164
  show_legend=False,
165
  height=400
166
  )
@@ -177,7 +143,6 @@ with gr.Blocks(title="RIASEC Predictor") as demo:
177
  show_progress=True
178
  )
179
 
180
- # Example inputs
181
  gr.Examples(
182
  examples=[
183
  ["Data Scientist", "Analyze large datasets and build machine learning models"],
@@ -190,5 +155,6 @@ with gr.Blocks(title="RIASEC Predictor") as demo:
190
  cache_examples=False,
191
  )
192
 
 
193
  if __name__ == "__main__":
194
- demo.queue().launch(share=True)
 
5
  from sentence_transformers import SentenceTransformer
6
  from collections import OrderedDict
7
 
8
+
9
  class RiasecPredictor:
10
+ def __init__(self, regressor_path='riasec_regressor_v1.pkl',
11
+ scaler_path='riasec_scaler.pkl',
12
  embedding_model_path='all-MiniLM-L6-v2'):
13
  """
14
  Load saved models for RIASEC prediction
 
16
  print("Loading models...")
17
  self.embedding_model = SentenceTransformer(embedding_model_path)
18
  self.regressor = joblib.load(regressor_path)
19
+ try:
20
+ self.scaler = joblib.load(scaler_path) # 👈 Load scaler
21
+ except FileNotFoundError:
22
+ raise FileNotFoundError(f"Scaler file not found at {scaler_path}. "
23
+ "Did you save it during training?")
24
  self.riasec_labels = ['R', 'I', 'A', 'S', 'E', 'C']
25
+ self.code_to_name = {
26
+ 'R': 'Realistic', 'I': 'Investigative', 'A': 'Artistic',
27
+ 'S': 'Social', 'E': 'Enterprising', 'C': 'Conventional'
28
+ }
29
+ print("✅ Models and scaler loaded successfully!")
30
 
31
  def predict(self, job_title=None, job_description=None, full_text=None, sort_by_score=True):
32
  """
33
+ Predict RIASEC scores for a job (in original 1-7 scale)
 
 
 
 
 
 
 
 
 
34
  """
35
  # Handle input
36
  if full_text is not None:
 
43
  # Generate embedding
44
  embedding = self.embedding_model.encode([text], convert_to_numpy=True)
45
 
46
+ # Make prediction in scaled space
47
+ prediction_scaled = self.regressor.predict(embedding)[0]
48
+
49
+ # Convert back to original scale
50
+ prediction = self.scaler.inverse_transform(prediction_scaled.reshape(1, -1))[0]
51
+ prediction = np.clip(prediction, 1.0, 7.0) # Enforce valid range
52
 
53
  # Create dictionary
54
  riasec_dict = dict(zip(self.riasec_labels, prediction.tolist()))
55
 
 
56
  if sort_by_score:
57
+ return OrderedDict(sorted(riasec_dict.items(), key=lambda x: x[1], reverse=True))
 
 
 
 
58
  else:
59
  return riasec_dict
60
 
61
  def predict_with_names(self, job_title=None, job_description=None, full_text=None):
62
+ """Predict with full names in R-I-A-S-E-C order"""
 
 
 
 
 
 
63
  results = self.predict(job_title, job_description, full_text, sort_by_score=False)
 
 
 
 
 
 
 
 
 
 
 
 
64
  ordered_with_names = OrderedDict()
65
+ for code in ['R', 'I', 'A', 'S', 'E', 'C']:
66
+ ordered_with_names[self.code_to_name[code]] = results[code]
 
 
 
 
67
  return ordered_with_names
68
 
69
+
70
+ # Initialize predictor
71
  predictor = RiasecPredictor()
72
 
73
+
74
  def predict_riasec(job_title, job_description):
75
+ """Wrapper for Gradio"""
 
 
76
  try:
77
+ if not job_title.strip() or not job_description.strip():
 
 
 
 
 
78
  return None, "Please provide both job title and job description."
79
 
80
+ result = predictor.predict(
81
+ job_title=job_title,
82
+ job_description=job_description,
83
+ sort_by_score=False # Don't sort by score, maintain R-I-A-S-E-C order
84
+ )
85
 
86
+ # Prepare bar chart data in R-I-A-S-E-C order with abbreviations
 
 
87
  riasec_order = ['R', 'I', 'A', 'S', 'E', 'C']
 
 
88
  ordered_labels = []
89
+ ordered_scores = []
90
 
91
+ for code in riasec_order:
92
+ ordered_labels.append(code) # Use abbreviations
93
+ ordered_scores.append(result[code])
 
94
 
 
95
  bar_data = pd.DataFrame({
96
+ "Category": ordered_labels,
97
+ "Score": ordered_scores
98
  })
99
 
100
+ # Prepare top 3 (sorted by score)
101
+ sorted_result = sorted(result.items(), key=lambda x: x[1], reverse=True)
 
 
102
  top_3_result = "### Top 3 RIASEC Types\n\n"
103
+ for key, _ in sorted_result[:3]:
104
+ top_3_result += f"<div style='font-size: 1.5em; font-weight: bold; margin: 5px 0; padding: 10px; background-color: #f0f0f0; color: #000000; border-radius: 5px; text-align: center; border: 1px solid #cccccc;'>{key}</div>\n"
 
 
 
 
105
 
106
  return bar_data, top_3_result
107
+
108
  except Exception as e:
 
109
  return None, f"Error: {str(e)}"
110
 
111
+
112
+ # Updated Gradio UI
113
  with gr.Blocks(title="RIASEC Predictor") as demo:
114
  gr.Markdown("# RIASEC Predictor")
115
  gr.Markdown("Predict RIASEC personality type scores for job descriptions")
 
122
 
123
  with gr.Column():
124
  output_chart = gr.BarPlot(
125
+ x="Category",
126
  y="Score",
127
  title="RIASEC Scores",
128
+ vertical=False, # Horizontal bars
129
+ tooltip=["Category", "Score"],
130
  show_legend=False,
131
  height=400
132
  )
 
143
  show_progress=True
144
  )
145
 
 
146
  gr.Examples(
147
  examples=[
148
  ["Data Scientist", "Analyze large datasets and build machine learning models"],
 
155
  cache_examples=False,
156
  )
157
 
158
+
159
  if __name__ == "__main__":
160
+ demo.queue().launch(share=True)