scmlewis commited on
Commit
bfe1780
·
verified ·
1 Parent(s): 5ba25fe

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +108 -1
app.py CHANGED
@@ -415,6 +415,78 @@ def generate_skill_pie_chart(resumes):
415
  st.session_state.pie_chart_time = time.time() - start_time
416
  return fig
417
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
418
  def main():
419
  """Main function to run the Streamlit app for resume screening."""
420
  # Render sidebar
@@ -525,4 +597,39 @@ def main():
525
  st.write(f"Total Analyze Time: {st.session_state.total_analyze_time:.2f} seconds")
526
  st.write(f"Model Load Time: {getattr(st.session_state, 'load_models_time', 0):.2f} seconds")
527
  st.write(f"Tokenize Time: {getattr(st.session_state, 'tokenize_time', 0):.2f} seconds")
528
- st.write(f"Extract Skills Time:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
415
  st.session_state.pie_chart_time = time.time() - start_time
416
  return fig
417
 
418
+ def render_sidebar():
419
+ """Render sidebar content."""
420
+ with st.sidebar:
421
+ st.markdown("""
422
+ <h1 style='text-align: center; font-size: 32px; margin-bottom: 10px;'>📄 Resume Screening Assistant for Databricks</h1>
423
+ <p style='text-align: center; font-size: 16px; margin-top: 0;'>
424
+ Welcome to our AI-powered resume screening tool, specialized for data science and tech roles! This app evaluates multiple resumes against a single job description, providing suitability classifications, skill summaries, and a skill frequency visualization.
425
+ </p>
426
+ """, unsafe_allow_html=True)
427
+
428
+ # Persist expander states
429
+ if 'expander1' not in st.session_state:
430
+ st.session_state.expander1 = True
431
+ if 'expander2' not in st.session_state:
432
+ st.session_state.expander2 = False
433
+ if 'expander3' not in st.session_state:
434
+ st.session_state.expander3 = False
435
+ if 'expander4' not in st.session_state:
436
+ st.session_state.expander4 = False
437
+
438
+ with st.expander("How to Use the App", expanded=st.session_state.expander1):
439
+ st.session_state.expander1 = True
440
+ st.markdown("""
441
+ - Enter up to 5 candidate resumes in the text boxes below, listing data/tech skills and experience (e.g., "Expert in python, databricks, 6 years experience").
442
+ - Enter the job description, specifying required skills and experience (e.g., "Data engineer requires python, spark, 5 years+").
443
+ - Click the "Analyze" button to evaluate all non-empty resumes (at least one resume required).
444
+ - Use the "Add Resume" or "Remove Resume" buttons to adjust the number of resume fields (1-5).
445
+ - Use the "Reset" button to clear all inputs and results.
446
+ - Results can be downloaded as a CSV file for record-keeping.
447
+ - View the skill frequency pie chart to see the distribution of skills across resumes.
448
+ """)
449
+
450
+ with st.expander("Example Test Cases", expanded=st.session_state.expander2):
451
+ st.session_state.expander2 = True
452
+ st.markdown("""
453
+ - **Test Case 1**:
454
+ - Resume 1: "Expert in python, machine learning, tableau, 4 years experience"
455
+ - Resume 2: "Skilled in sql, pandas, 2 years experience"
456
+ - Resume 3: "Proficient in java, python, 5 years experience"
457
+ - Job Description: "Data scientist requires python, machine learning, 3 years+"
458
+ - **Test Case 2**:
459
+ - Resume 1: "Skilled in databricks, spark, python, 6 years experience"
460
+ - Resume 2: "Expert in sql, tableau, business intelligence, 3 years experience"
461
+ - Resume 3: "Proficient in rust, langchain, 2 years experience"
462
+ - Job Description: "Data engineer requires python, spark, 5 years+"
463
+ """)
464
+
465
+ with st.expander("Guidelines", expanded=st.session_state.expander3):
466
+ st.session_state.expander3 = True
467
+ st.markdown("""
468
+ - Use comma-separated skills from a comprehensive list including python, sql, databricks, etc. (79 skills supported, see Project Report for full list).
469
+ - Include experience in years (e.g., "3 years experience" or "1 year experience") or as "senior".
470
+ - Focus on data/tech skills for accurate summarization.
471
+ - Resumes with only irrelevant skills (e.g., sales, marketing) will be classified as "Irrelevant".
472
+ """)
473
+
474
+ with st.expander("Classification Criteria", expanded=st.session_state.expander4):
475
+ st.session_state.expander4 = True
476
+ st.markdown("""
477
+ Resumes are classified based on:
478
+ - **Skill Overlap**: The resume's data/tech skills are compared to the job's requirements. A skill overlap below 40% results in an "Irrelevant" classification.
479
+ - **Model Confidence**: A finetuned BERT model evaluates skill relevance. If confidence is below 85%, the classification is "Uncertain".
480
+ - **Experience Match**: The resume's experience (in years or seniority) must meet or exceed the job's requirement.
481
+
482
+ **Outcomes**:
483
+ - **Relevant**: Skill overlap ≥ 50%, sufficient experience, and high model confidence (≥ 85%).
484
+ - **Irrelevant**: Skill overlap < 40% or high confidence in low skill relevance.
485
+ - **Uncertain**: Skill overlap ≥ 50% but experience mismatch (e.g., resume has 2 years, job requires 5 years+), or low model confidence (< 85%).
486
+
487
+ **Note**: An experience mismatch warning is shown if the resume's experience is below the job's requirement, overriding the skill overlap and confidence to classify as Uncertain.
488
+ """)
489
+
490
  def main():
491
  """Main function to run the Streamlit app for resume screening."""
492
  # Render sidebar
 
597
  st.write(f"Total Analyze Time: {st.session_state.total_analyze_time:.2f} seconds")
598
  st.write(f"Model Load Time: {getattr(st.session_state, 'load_models_time', 0):.2f} seconds")
599
  st.write(f"Tokenize Time: {getattr(st.session_state, 'tokenize_time', 0):.2f} seconds")
600
+ st.write(f"Extract Skills Time: {getattr(st.session_state, 'extract_skills_time', 0):.2f} seconds")
601
+ if st.session_state.results:
602
+ for idx, result in enumerate(st.session_state.results):
603
+ st.write(f"Inference Time for {result['Resume']}: {result['Inference Time']:.2f} seconds")
604
+ st.write(f"Pie Chart Time: {getattr(st.session_state, 'pie_chart_time', 0):.2f} seconds")
605
+
606
+ # Performance note
607
+ if st.session_state.total_analyze_time > 60:
608
+ st.warning("The runtime is longer than expected due to server load on Hugging Face Spaces. For a smoother experience, consider testing locally or deploying on a different platform (e.g., Streamlit Community Cloud or a personal server).")
609
+
610
+ # Display results
611
+ if st.session_state.results:
612
+ with st.container():
613
+ st.subheader("Results")
614
+ df = pd.DataFrame(st.session_state.results)
615
+ df = df[["Resume", "Suitability", "Data/Tech Related Skills Summary", "Warning"]] # Exclude Inference Time from display
616
+ st.dataframe(df, use_container_width=True)
617
+
618
+ csv = df.to_csv(index=False)
619
+ st.download_button(
620
+ label="Download Results as CSV",
621
+ data=csv,
622
+ file_name="resume_screening_results.csv",
623
+ mime="text/csv",
624
+ )
625
+
626
+ # Display pie chart
627
+ if st.session_state.pie_chart:
628
+ with st.container():
629
+ st.subheader("Skill Frequency Across Resumes")
630
+ st.pyplot(st.session_state.pie_chart)
631
+ elif st.session_state.results and not st.session_state.pie_chart:
632
+ st.warning("No recognized data/tech skills found in the resumes to generate a pie chart.")
633
+
634
+ if __name__ == "__main__":
635
+ main()