CR7CAD commited on
Commit
41d8604
·
verified ·
1 Parent(s): 406e4e6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +69 -38
app.py CHANGED
@@ -3,8 +3,6 @@ import io
3
  import streamlit as st
4
  import docx
5
  from transformers import pipeline
6
- import numpy as np
7
- from scipy.spatial.distance import cosine
8
  import time
9
 
10
  # Set page title and hide sidebar
@@ -30,10 +28,10 @@ def load_models():
30
  with st.spinner("Loading AI models... This may take a minute on first run."):
31
  models = {}
32
  # Load summarization model
33
- models['summarizer'] = pipeline("summarization", model="marianna13/flan-t5-base-summarization")
34
 
35
- # Load feature extraction model for similarity
36
- models['feature_extractor'] = pipeline("feature-extraction", model="bert-base-uncased")
37
 
38
  return models
39
 
@@ -101,31 +99,64 @@ def summarize_resume_text(resume_text, models):
101
  return candidate_summary, execution_time
102
 
103
  #####################################
104
- # Function: Compare Candidate Summary to Company Prompt
105
  #####################################
106
- def compute_suitability(candidate_summary, company_prompt, models):
107
  """
108
- Compute the similarity between candidate summary and company prompt.
109
- Returns a score in the range [0, 1] and execution time.
110
  """
111
  start_time = time.time()
112
 
113
- feature_extractor = models['feature_extractor']
114
 
115
- # Extract features (embeddings)
116
- candidate_features = feature_extractor(candidate_summary)
117
- company_features = feature_extractor(company_prompt)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
 
119
- # Convert to numpy arrays and flatten if needed
120
- candidate_vec = np.mean(np.array(candidate_features[0]), axis=0)
121
- company_vec = np.mean(np.array(company_features[0]), axis=0)
122
 
123
- # Compute cosine similarity (1 - cosine distance)
124
- similarity = 1 - cosine(candidate_vec, company_vec)
 
 
 
 
 
 
 
 
 
 
 
125
 
126
  execution_time = time.time() - start_time
127
 
128
- return similarity, execution_time
129
 
130
  #####################################
131
  # Main Streamlit Interface
@@ -136,7 +167,7 @@ st.markdown(
136
  Upload your resume file in **.docx** or **.txt** format. The app performs the following tasks:
137
  1. Extracts text from the resume.
138
  2. Uses a transformer-based model to generate a concise candidate summary.
139
- 3. Compares the candidate summary with a company profile to produce a suitability score.
140
  """
141
  )
142
 
@@ -167,21 +198,21 @@ if uploaded_file is not None and company_prompt and st.button("Analyze Resume"):
167
  st.write(summary)
168
  st.info(f"Summarization completed in {summarization_time:.2f} seconds")
169
 
170
- # Only compute similarity if company description is provided
171
- if company_prompt:
172
- similarity_score, similarity_time = compute_suitability(summary, company_prompt, models)
173
-
174
- # Display similarity score
175
- st.subheader("Suitability Assessment")
176
- st.markdown(f"**Matching Score:** {similarity_score:.2%}")
177
- st.info(f"Similarity computation completed in {similarity_time:.2f} seconds")
178
-
179
- # Provide interpretation
180
- if similarity_score >= 0.85:
181
- st.success("Excellent match! This candidate's profile is strongly aligned with the company requirements.")
182
- elif similarity_score >= 0.70:
183
- st.success("Good match! This candidate shows strong potential for the position.")
184
- elif similarity_score >= 0.50:
185
- st.warning("Moderate match. The candidate meets some requirements but there may be gaps.")
186
- else:
187
- st.error("Low match. The candidate's profile may not align well with the requirements.")
 
3
  import streamlit as st
4
  import docx
5
  from transformers import pipeline
 
 
6
  import time
7
 
8
  # Set page title and hide sidebar
 
28
  with st.spinner("Loading AI models... This may take a minute on first run."):
29
  models = {}
30
  # Load summarization model
31
+ models['summarizer'] = pipeline("summarization", model="google/pegasus-xsum")
32
 
33
+ # Load text generation model for suitability assessment
34
+ models['text_generator'] = pipeline("text-generation", model="gpt2") # You can use different models
35
 
36
  return models
37
 
 
99
  return candidate_summary, execution_time
100
 
101
  #####################################
102
+ # Function: Generate Suitability Assessment
103
  #####################################
104
+ def generate_suitability_assessment(candidate_summary, company_prompt, models):
105
  """
106
+ Generate a suitability assessment using text generation instead of similarity.
107
+ Returns the generated assessment text and execution time.
108
  """
109
  start_time = time.time()
110
 
111
+ text_generator = models['text_generator']
112
 
113
+ # Create a prompt for the text generation model
114
+ prompt = f"""
115
+ Resume Summary: {candidate_summary}
116
+
117
+ Company Description: {company_prompt}
118
+
119
+ Suitability Assessment:
120
+ This candidate is a"""
121
+
122
+ # Generate text
123
+ max_length = 80 + len(prompt.split()) # Limit output length
124
+ generated_text = text_generator(
125
+ prompt,
126
+ max_length=max_length,
127
+ num_return_sequences=1,
128
+ temperature=0.7,
129
+ top_p=0.9,
130
+ do_sample=True
131
+ )[0]['generated_text']
132
+
133
+ # Extract only the assessment part (after the prompt)
134
+ assessment = generated_text[len(prompt):].strip()
135
+
136
+ # Determine a numerical score from the text
137
+ # This is a simplified approach - we're looking for positive and negative words
138
+ positive_words = ['excellent', 'perfect', 'great', 'good', 'strong', 'ideal', 'qualified']
139
+ negative_words = ['poor', 'weak', 'bad', 'insufficient', 'inadequate', 'not a good']
140
 
141
+ assessment_lower = assessment.lower()
 
 
142
 
143
+ # Simple heuristic for score estimation
144
+ score = 0.5 # Default middle score
145
+
146
+ for word in positive_words:
147
+ if word in assessment_lower:
148
+ score += 0.1 # Increase score for positive words
149
+
150
+ for word in negative_words:
151
+ if word in assessment_lower:
152
+ score -= 0.1 # Decrease score for negative words
153
+
154
+ # Clamp the score between 0 and 1
155
+ score = max(0.1, min(0.9, score))
156
 
157
  execution_time = time.time() - start_time
158
 
159
+ return assessment, score, execution_time
160
 
161
  #####################################
162
  # Main Streamlit Interface
 
167
  Upload your resume file in **.docx** or **.txt** format. The app performs the following tasks:
168
  1. Extracts text from the resume.
169
  2. Uses a transformer-based model to generate a concise candidate summary.
170
+ 3. Uses text generation to assess the candidate's suitability for the company.
171
  """
172
  )
173
 
 
198
  st.write(summary)
199
  st.info(f"Summarization completed in {summarization_time:.2f} seconds")
200
 
201
+ # Generate suitability assessment with text generation
202
+ assessment, estimated_score, generation_time = generate_suitability_assessment(summary, company_prompt, models)
203
+
204
+ # Display assessment
205
+ st.subheader("Suitability Assessment")
206
+ st.write(assessment)
207
+ st.markdown(f"**Estimated Matching Score:** {estimated_score:.2%}")
208
+ st.info(f"Assessment generated in {generation_time:.2f} seconds")
209
+
210
+ # Provide interpretation based on estimated score
211
+ if estimated_score >= 0.85:
212
+ st.success("Excellent match! This candidate's profile is strongly aligned with the company requirements.")
213
+ elif estimated_score >= 0.70:
214
+ st.success("Good match! This candidate shows strong potential for the position.")
215
+ elif estimated_score >= 0.50:
216
+ st.warning("Moderate match. The candidate meets some requirements but there may be gaps.")
217
+ else:
218
+ st.error("Low match. The candidate's profile may not align well with the requirements.")