ESMATUGBA commited on
Commit
6ecc11a
·
verified ·
1 Parent(s): f373840

Upload 3 files

Browse files
Files changed (3) hide show
  1. app.py +134 -0
  2. best_model.pkl +3 -0
  3. tfidf_vectorizer.pkl +3 -0
app.py ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import joblib
3
+ from textblob import TextBlob
4
+ import mammoth
5
+ import pdfplumber
6
+ import io
7
+ import re
8
+ import os
9
+
10
+ # --- 1. MODEL FUNCTION ---
11
+ def ekkok(text):
12
+ try:
13
+ words = TextBlob(str(text)).words
14
+ return [word.lemmatize() for word in words]
15
+ except:
16
+ return str(text).split()
17
+
18
+ # --- PAGE CONFIG ---
19
+ st.set_page_config(page_title="AI Resume Analyzer", layout="centered", page_icon="🎯")
20
+
21
+ # --- SECTOR KEYWORDS ---
22
+ SECTOR_KEYWORDS = {
23
+ "Hospitality & Management": ["hospitality", "restaurant", "hotel", "waiter", "bartender", "bar manager", "chef", "tourism"],
24
+ "Marketing / Advertising": ["marketing", "advertising", "social media", "branding", "seo", "store manager", "salesman"],
25
+ "Information Technology": ["software", "developer", "java", "python", "javascript", "cloud", "data science"],
26
+ "Finance & Accounting": ["finance", "accounting", "audit", "banking", "tax", "budget"],
27
+ "Human Resources": ["recruitment", "hr", "payroll", "onboarding", "talent acquisition"]
28
+ }
29
+
30
+ # --- FILE EXTRACTOR ---
31
+ def extract_text(uploaded_file):
32
+ try:
33
+ if uploaded_file.name.lower().endswith('.docx'):
34
+ return mammoth.extract_raw_text(io.BytesIO(uploaded_file.getvalue())).value
35
+ elif uploaded_file.name.lower().endswith('.pdf'):
36
+ full_text = ""
37
+ with pdfplumber.open(io.BytesIO(uploaded_file.getvalue())) as pdf:
38
+ for page in pdf.pages:
39
+ page_text = page.extract_text()
40
+ if page_text: full_text += page_text + "\n"
41
+ return full_text if full_text.strip() else "ERR_SCAN"
42
+ except: return None
43
+
44
+ # --- LOAD ASSETS ---
45
+ @st.cache_resource
46
+ def load_assets():
47
+ m_p, v_p = "best_model.pkl", "tfidf_vectorizer.pkl"
48
+ if os.path.exists(m_p) and os.path.exists(v_p):
49
+ try: return joblib.load(m_p), joblib.load(v_p)
50
+ except: return None, None
51
+ return None, None
52
+
53
+ model, vectorizer = load_assets()
54
+
55
+ # --- BILINGUAL TITLE (İNGİLİZCE & TÜRKÇE BAŞLIK) ---
56
+ st.markdown("""
57
+ <div style="text-align: center;">
58
+ <h1 style="color: #1E3A8A; margin-bottom: 0;">🎯 AI Resume Classifier / Akıllı CV Sınıflandırıcı</h1>
59
+ <p style="color: #666; font-size: 1.1rem; margin-top: 5px;">Automated Department Prediction System / Otomatik Bölüm Tahmin Sistemi</p>
60
+ </div>
61
+ """, unsafe_allow_html=True)
62
+
63
+ st.divider()
64
+
65
+ # --- INPUT SECTION ---
66
+
67
+ # 1. Metin Girişi
68
+ manual_input = st.text_area("✍️ Paste CV Text / CV Metnini Yapıştırın:", height=150, key="m_input")
69
+
70
+ # 2. Dosya Yükleme
71
+ uploaded_file = st.file_uploader("📂 Upload CV (PDF/DOCX) / Dosya Yükleyin:", type=['pdf', 'docx'], key="f_input")
72
+
73
+ # --- VALIDATION ---
74
+ final_cv_text = ""
75
+
76
+ if manual_input.strip() and uploaded_file:
77
+ st.error("⚠️ Please use ONLY ONE method! Delete text OR remove file. / Lütfen SADECE BİR yöntem kullanın! Metni silin VEYA dosyayı kaldırın.")
78
+ elif manual_input.strip():
79
+ final_cv_text = manual_input
80
+ elif uploaded_file:
81
+ with st.spinner('Reading...'):
82
+ res = extract_text(uploaded_file)
83
+ if res == "ERR_SCAN":
84
+ st.error("❌ This PDF is an image. Please paste text instead. / Bu PDF resimden oluşuyor, lütfen metni kopyalayıp kutuya yapıştırın.")
85
+ elif res:
86
+ final_cv_text = res
87
+ st.success(f"✅ {uploaded_file.name} ready!")
88
+
89
+ st.divider()
90
+
91
+ # --- ANALYSIS BUTTON ---
92
+ if st.button("🚀 START ANALYSIS / ANALİZİ BAŞLAT", use_container_width=True):
93
+ if not final_cv_text or len(final_cv_text.strip()) < 10:
94
+ st.warning("⚠️ Please provide CV content! / Lütfen CV içeriği sağlayın!")
95
+ else:
96
+ with st.spinner('Processing...'):
97
+ # Email Identity
98
+ email_id = "NOT FOUND"
99
+ match = re.search(r'([a-zA-Z0-9_.+-]+)@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+', final_cv_text)
100
+ if match: email_id = match.group(1).upper()
101
+
102
+ # Prediction
103
+ low_txt = final_cv_text.lower()
104
+ scores = {s: sum(1 for k in kw if k in low_txt) for s, kw in SECTOR_KEYWORDS.items()}
105
+ prediction = max(scores, key=scores.get)
106
+
107
+ if scores[prediction] == 0 and model:
108
+ try: prediction = model.predict(vectorizer.transform([final_cv_text]))[0]
109
+ except: prediction = "Unclassified"
110
+
111
+ st.balloons()
112
+ st.success("### Results / Sonuçlar")
113
+ c1, c2 = st.columns(2)
114
+ c1.metric("Email Identity / E-posta", email_id)
115
+ c2.metric("Department / Bölüm", prediction)
116
+
117
+ # --- FOOTER ---
118
+ st.markdown("<br><br><br><hr>", unsafe_allow_html=True)
119
+ footer_html = """
120
+ <div style="display: flex; justify-content: space-between; align-items: center; font-family: sans-serif;">
121
+ <div style="text-align: left;">
122
+ <h4 style="margin:0; color: #1E3A8A;">Developed by Data Science Dept.</h4>
123
+ <p style="margin:0; font-size: 0.8rem; color: #666;">Advanced HR Analytics Solutions</p>
124
+ </div>
125
+ <div style="text-align: right;">
126
+ <h4 style="margin:0; color: #1E3A8A;">Veri Bilimi Departmanı</h4>
127
+ <p style="margin:0; font-size: 0.8rem; color: #666;">Gelişmiş İK Analitik Çözümleri</p>
128
+ </div>
129
+ </div>
130
+ <div style="text-align: center; margin-top: 15px; border-top: 1px solid #eee; padding-top: 10px;">
131
+ <span style="color: #444; font-size: 0.9rem;">Developer / Geliştirici: <b>EsmaTuğba MERGEN</b> | <b>v37.0</b></span>
132
+ </div>
133
+ """
134
+ st.markdown(footer_html, unsafe_allow_html=True)
best_model.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:be4a35e6e614b78d533da996920d32572a3d41e62fecb76154d80b0ef3a13f1f
3
+ size 1001583
tfidf_vectorizer.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c9682403882e7d81b7dfb2a10b7a6376015771d2f2f028e42df36c9ee446ebe7
3
+ size 191865