DreamStream-1 commited on
Commit
831ab6e
·
verified ·
1 Parent(s): 597bbca

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +74 -43
app.py CHANGED
@@ -7,7 +7,6 @@ from transformers import AutoTokenizer, AutoModelForSequenceClassification, Auto
7
  from sentence_transformers import SentenceTransformer, util
8
  from groq import Groq
9
  import gradio as gr
10
- from docxtpl import DocxTemplate
11
 
12
  # Set your API key for Groq
13
  os.environ["GROQ_API_KEY"] = "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"
@@ -66,17 +65,18 @@ def extract_experience(text):
66
  experience_years = [int(year[0]) for year in experience_years]
67
  return experience_years, job_titles
68
 
69
- # --- Summarization Function --- #
70
- def summarize_experience(experience_text):
71
- """Summarizes the experience text using a pre-trained model."""
72
- model_name = "facebook/bart-large-cnn"
73
  tokenizer = AutoTokenizer.from_pretrained(model_name)
74
- model = AutoModelForSeq2SeqLM.from_pretrained(model_name)
75
 
76
- inputs = tokenizer(experience_text, return_tensors="pt", max_length=1024, truncation=True)
77
- summary_ids = model.generate(inputs['input_ids'], max_length=150, min_length=30, length_penalty=2.0, num_beams=4, early_stopping=True)
78
- summary = tokenizer.decode(summary_ids[0], skip_special_tokens=True)
79
- return summary
 
80
 
81
  # --- Semantic Similarity Calculation --- #
82
  def calculate_semantic_similarity(text1, text2):
@@ -90,7 +90,7 @@ def calculate_semantic_similarity(text1, text2):
90
  similarity_percentage = similarity_score * 100
91
  return similarity_percentage
92
 
93
- # --- Communication Generation with Enhanced Response --- #
94
  def communication_generator(resume_skills, job_description_skills, skills_similarity, qualifications_similarity, experience_similarity, candidate_experience):
95
  """Generates a detailed communication response based on similarity scores and additional criteria."""
96
  # Assess candidate fit based on similarity scores
@@ -118,19 +118,6 @@ def communication_generator(resume_skills, job_description_skills, skills_simila
118
 
119
  return message
120
 
121
- # --- Sentiment Analysis --- #
122
- def analyze_sentiment(text):
123
- """Analyzes the sentiment of the text."""
124
- model_name = "mrm8488/distiluse-base-multilingual-cased-v2-finetuned-stsb_multi_mt-es"
125
- tokenizer = AutoTokenizer.from_pretrained(model_name)
126
- model = AutoModelForSequenceClassification.from_pretrained(model_name)
127
-
128
- inputs = tokenizer(text, return_tensors="pt", padding=True, truncation=True)
129
- with torch.no_grad():
130
- outputs = model(**inputs)
131
- predicted_sentiment = torch.argmax(outputs.logits).item()
132
- return ["Negative", "Neutral", "Positive"][predicted_sentiment]
133
-
134
  # --- Updated Resume Analysis Function --- #
135
  def analyze_resume(resume_file, job_description_file):
136
  # Load and preprocess resume and job description
@@ -150,10 +137,13 @@ def analyze_resume(resume_file, job_description_file):
150
  required_experience = sum(job_description_experience) # Assuming total years required
151
 
152
  # Calculate similarity scores
153
- skills_similarity = len(set(resume_skills).intersection(set(job_description_skills))) / len(job_description_skills) * 100
154
- qualifications_similarity = len(set(resume_qualifications).intersection(set(job_description_qualifications))) / len(job_description_qualifications) * 100
155
  experience_similarity = 1.0 if total_experience >= required_experience else 0.0
156
 
 
 
 
157
  # Fit assessment logic
158
  fit_score = 0
159
  if total_experience >= required_experience:
@@ -171,38 +161,79 @@ def analyze_resume(resume_file, job_description_file):
171
  else:
172
  fit_assessment = "Not a fit"
173
 
174
- # Prepare output message
175
- response_message = (
176
- f"Skills Similarity: {skills_similarity:.2f}%\n"
177
- f"Qualifications Similarity: {qualifications_similarity:.2f}%\n"
178
- f"Experience Similarity: {experience_similarity * 100:.2f}%\n"
179
- f"Candidate Experience: {total_experience} years\n"
180
- f"Sentiment: Neutral\n"
181
- f"Response Message: After a detailed analysis of the candidate's resume, we found the following insights:\n\n"
182
- f"Skills Match: {skills_similarity:.2f}% (based on required technologies: {', '.join(job_description_skills)})\n"
183
- f"Qualifications Match: {qualifications_similarity:.2f}%\n"
184
- f"Experience Match: {experience_similarity * 100:.2f}% (relevant experience: {total_experience} years)\n"
185
- f"The overall assessment indicates that the candidate is a {fit_assessment} for the role."
 
 
 
 
 
 
 
 
 
186
  )
187
 
188
- return response_message
 
 
 
 
 
 
 
 
 
189
 
190
  def run_gradio_interface():
191
  with gr.Blocks() as demo:
192
  gr.Markdown("## Resume and Job Description Analyzer")
193
  resume_file = gr.File(label="Upload Resume")
194
  job_description_file = gr.File(label="Upload Job Description")
195
- output_display = gr.Textbox(label="Analysis Output", interactive=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
196
 
197
  def analyze(resume, job_desc):
198
  if resume and job_desc:
199
- return analyze_resume(resume, job_desc)
 
200
  return "Please upload both files."
201
 
202
  analyze_button = gr.Button("Analyze")
203
- analyze_button.click(analyze, inputs=[resume_file, job_description_file], outputs=output_display)
204
 
205
  demo.launch()
206
 
207
  if __name__ == "__main__":
208
- run_gradio_interface()
 
7
  from sentence_transformers import SentenceTransformer, util
8
  from groq import Groq
9
  import gradio as gr
 
10
 
11
  # Set your API key for Groq
12
  os.environ["GROQ_API_KEY"] = "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"
 
65
  experience_years = [int(year[0]) for year in experience_years]
66
  return experience_years, job_titles
67
 
68
+ # --- Sentiment Analysis --- #
69
+ def analyze_sentiment(text):
70
+ """Analyzes the sentiment of the text."""
71
+ model_name = "mrm8488/distiluse-base-multilingual-cased-v2-finetuned-stsb_multi_mt-es"
72
  tokenizer = AutoTokenizer.from_pretrained(model_name)
73
+ model = AutoModelForSequenceClassification.from_pretrained(model_name)
74
 
75
+ inputs = tokenizer(text, return_tensors="pt", padding=True, truncation=True)
76
+ with torch.no_grad():
77
+ outputs = model(**inputs)
78
+ predicted_sentiment = torch.argmax(outputs.logits).item()
79
+ return ["Negative", "Neutral", "Positive"][predicted_sentiment]
80
 
81
  # --- Semantic Similarity Calculation --- #
82
  def calculate_semantic_similarity(text1, text2):
 
90
  similarity_percentage = similarity_score * 100
91
  return similarity_percentage
92
 
93
+ # --- Communication Generation --- #
94
  def communication_generator(resume_skills, job_description_skills, skills_similarity, qualifications_similarity, experience_similarity, candidate_experience):
95
  """Generates a detailed communication response based on similarity scores and additional criteria."""
96
  # Assess candidate fit based on similarity scores
 
118
 
119
  return message
120
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
  # --- Updated Resume Analysis Function --- #
122
  def analyze_resume(resume_file, job_description_file):
123
  # Load and preprocess resume and job description
 
137
  required_experience = sum(job_description_experience) # Assuming total years required
138
 
139
  # Calculate similarity scores
140
+ skills_similarity = len(set(resume_skills).intersection(set(job_description_skills))) / len(job_description_skills) * 100 if job_description_skills else 0
141
+ qualifications_similarity = len(set(resume_qualifications).intersection(set(job_description_qualifications))) / len(job_description_qualifications) * 100 if job_description_qualifications else 0
142
  experience_similarity = 1.0 if total_experience >= required_experience else 0.0
143
 
144
+ # Sentiment analysis of the resume
145
+ sentiment_analysis_result = analyze_sentiment(resume_text)
146
+
147
  # Fit assessment logic
148
  fit_score = 0
149
  if total_experience >= required_experience:
 
161
  else:
162
  fit_assessment = "Not a fit"
163
 
164
+ # Prepare output messages for tab display
165
+ summary_message = (
166
+ f"### Summary of Analysis\n"
167
+ f"- **Skills Similarity**: {skills_similarity:.2f}%\n"
168
+ f"- **Qualifications Similarity**: {qualifications_similarity:.2f}%\n"
169
+ f"- **Experience Similarity**: {experience_similarity * 100:.2f}%\n"
170
+ f"- **Candidate Experience**: {total_experience} years\n"
171
+ f"- **Fit Assessment**: {fit_assessment}\n"
172
+ f"- **Sentiment Analysis**: {sentiment_analysis_result}\n"
173
+ )
174
+
175
+ skills_message = (
176
+ f"### Skills Overview\n"
177
+ f"- **Resume Skills:**\n" + "\n".join(f" - {skill}" for skill in resume_skills) + "\n"
178
+ f"- **Job Description Skills:**\n" + "\n".join(f" - {skill}" for skill in job_description_skills) + "\n"
179
+ )
180
+
181
+ qualifications_message = (
182
+ f"### Qualifications Overview\n"
183
+ f"- **Resume Qualifications:** " + ", ".join(resume_qualifications) + "\n" +
184
+ f"- **Job Description Qualifications:** " + ", ".join(job_description_qualifications) + "\n"
185
  )
186
 
187
+ experience_message = (
188
+ f"### Experience Overview\n"
189
+ f"- **Total Experience:** {total_experience} years\n"
190
+ f"- **Required Experience:** {required_experience} years\n"
191
+ )
192
+
193
+ # Generate communication based on analysis
194
+ communication = communication_generator(resume_skills, job_description_skills, skills_similarity, qualifications_similarity, experience_similarity, total_experience)
195
+
196
+ return summary_message, skills_message, qualifications_message, experience_message, communication
197
 
198
  def run_gradio_interface():
199
  with gr.Blocks() as demo:
200
  gr.Markdown("## Resume and Job Description Analyzer")
201
  resume_file = gr.File(label="Upload Resume")
202
  job_description_file = gr.File(label="Upload Job Description")
203
+
204
+ # Define outputs for each tab
205
+ summary_output = gr.Textbox(label="Summary of Analysis", interactive=False, lines=10)
206
+ skills_output = gr.Textbox(label="Skills Overview", interactive=False, lines=10)
207
+ qualifications_output = gr.Textbox(label="Qualifications Overview", interactive=False, lines=10)
208
+ experience_output = gr.Textbox(label="Experience Overview", interactive=False, lines=10)
209
+ communication_output = gr.Textbox(label="Communication", interactive=False, lines=10)
210
+
211
+ # Create tabs for output sections
212
+ with gr.Tab("Analysis Summary"):
213
+ summary_output.render()
214
+
215
+ with gr.Tab("Skills Overview"):
216
+ skills_output.render()
217
+
218
+ with gr.Tab("Qualifications Overview"):
219
+ qualifications_output.render()
220
+
221
+ with gr.Tab("Experience Overview"):
222
+ experience_output.render()
223
+
224
+ with gr.Tab("Communication"):
225
+ communication_output.render()
226
 
227
  def analyze(resume, job_desc):
228
  if resume and job_desc:
229
+ summary, skills, qualifications, experience, communication = analyze_resume(resume, job_desc)
230
+ return summary, skills, qualifications, experience, communication
231
  return "Please upload both files."
232
 
233
  analyze_button = gr.Button("Analyze")
234
+ analyze_button.click(analyze, inputs=[resume_file, job_description_file], outputs=[summary_output, skills_output, qualifications_output, experience_output, communication_output])
235
 
236
  demo.launch()
237
 
238
  if __name__ == "__main__":
239
+ run_gradio_interface()