Spaces:
Sleeping
Sleeping
Update app.py
Browse files
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="
|
34 |
|
35 |
-
# Load
|
36 |
-
models['
|
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:
|
105 |
#####################################
|
106 |
-
def
|
107 |
"""
|
108 |
-
|
109 |
-
Returns
|
110 |
"""
|
111 |
start_time = time.time()
|
112 |
|
113 |
-
|
114 |
|
115 |
-
#
|
116 |
-
|
117 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
118 |
|
119 |
-
|
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 |
-
#
|
124 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
125 |
|
126 |
execution_time = time.time() - start_time
|
127 |
|
128 |
-
return
|
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.
|
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 |
-
#
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
|
|
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.")
|