import streamlit as st
import pandas as pd
import numpy as np
# Try importing packages, if not available, show error
try:
from sklearn.ensemble import RandomForestClassifier
from sklearn.preprocessing import StandardScaler, LabelEncoder
import plotly.graph_objects as go
except ImportError:
st.error("Required packages not installed. This app needs scikit-learn and plotly.")
st.stop()
# Page config
st.set_page_config(
page_title="ni - Neuron Inputs Career Finder",
page_icon="๐ง ",
layout="wide"
)
# Custom CSS
st.markdown("""
<style>
.main {
padding: 2rem;
}
.stButton>button {
width: 100%;
background-color: #4CAF50;
color: white;
height: 3em;
border-radius: 10px;
font-size: 18px;
}
</style>
""", unsafe_allow_html=True)
# Initialize session state
if 'model_trained' not in st.session_state:
st.session_state.model_trained = False
@st.cache_resource
def generate_training_data():
"""Generate diverse synthetic career dataset"""
np.random.seed(42)
# 40+ diverse career paths for Indian students
careers = [
# Tech & Engineering
'Software Engineer', 'Data Scientist', 'AI/ML Engineer', 'Cybersecurity Specialist',
'Web Developer', 'Mobile App Developer', 'Cloud Architect', 'DevOps Engineer',
# Medical & Healthcare
'Doctor (MBBS)', 'Dentist', 'Pharmacist', 'Physiotherapist', 'Nursing', 'Medical Research',
# Business & Finance
'Chartered Accountant', 'Investment Banker', 'Business Analyst', 'Financial Advisor',
'Entrepreneur', 'Marketing Manager', 'HR Manager', 'Management Consultant',
# Creative & Design
'Graphic Designer', 'UI/UX Designer', 'Content Writer', 'Filmmaker', 'Animator',
'Fashion Designer', 'Photographer', 'Video Editor',
# Traditional Professions
'Civil Engineer', 'Mechanical Engineer', 'Electrical Engineer', 'Architect',
# Social & Legal
'Lawyer', 'Teacher/Professor', 'Psychologist', 'Social Worker', 'Journalist',
# Other
'Chef', 'Interior Designer', 'Environmental Scientist', 'Biotechnologist'
]
career_profiles = {
'Software Engineer': {
'math': (85, 8), 'science': (82, 8), 'english': (70, 12), 'social': (65, 12),
'openness': (8, 1), 'conscientiousness': (7, 1.5), 'extraversion': (5, 2),
'agreeableness': (6, 1.5), 'neuroticism': (5, 2),
'technical': (9, 1), 'creative': (5, 2), 'business': (4, 2), 'social_service': (4, 2),
'coding': (8, 1.5), 'communication': (6, 2), 'analysis': (8, 1.5), 'leadership': (5, 2)
},
'Data Scientist': {
'math': (90, 6), 'science': (85, 8), 'english': (72, 10), 'social': (68, 12),
'openness': (9, 1), 'conscientiousness': (8, 1), 'extraversion': (5, 2),
'agreeableness': (6, 1.5), 'neuroticism': (4, 2),
'technical': (9, 1), 'creative': (6, 2), 'business': (6, 2), 'social_service': (4, 2),
'coding': (9, 1), 'communication': (7, 1.5), 'analysis': (9, 1), 'leadership': (6, 2)
},
'Doctor (MBBS)': {
'math': (75, 10), 'science': (92, 6), 'english': (70, 12), 'social': (68, 12),
'openness': (7, 1.5), 'conscientiousness': (9, 1), 'extraversion': (6, 2),
'agreeableness': (8, 1.5), 'neuroticism': (4, 2),
'technical': (5, 2), 'creative': (4, 2), 'business': (4, 2), 'social_service': (9, 1),
'coding': (3, 2), 'communication': (7, 1.5), 'analysis': (8, 1.5), 'leadership': (6, 2)
},
'Chartered Accountant': {
'math': (88, 8), 'science': (70, 12), 'english': (75, 10), 'social': (72, 12),
'openness': (6, 1.5), 'conscientiousness': (9, 1), 'extraversion': (5, 2),
'agreeableness': (7, 1.5), 'neuroticism': (5, 2),
'technical': (5, 2), 'creative': (3, 2), 'business': (9, 1), 'social_service': (4, 2),
'coding': (4, 2), 'communication': (7, 2), 'analysis': (9, 1), 'leadership': (6, 2)
},
'Graphic Designer': {
'math': (60, 15), 'science': (60, 15), 'english': (75, 10), 'social': (70, 12),
'openness': (9, 1), 'conscientiousness': (7, 1.5), 'extraversion': (6, 2),
'agreeableness': (7, 1.5), 'neuroticism': (5, 2),
'technical': (6, 2), 'creative': (9, 1), 'business': (5, 2), 'social_service': (4, 2),
'coding': (5, 2), 'communication': (7, 1.5), 'analysis': (6, 2), 'leadership': (5, 2)
},
'Content Writer': {
'math': (60, 15), 'science': (60, 15), 'english': (90, 6), 'social': (80, 10),
'openness': (9, 1), 'conscientiousness': (7, 1.5), 'extraversion': (6, 2),
'agreeableness': (7, 1.5), 'neuroticism': (5, 2),
'technical': (4, 2), 'creative': (9, 1), 'business': (5, 2), 'social_service': (5, 2),
'coding': (3, 2), 'communication': (9, 1), 'analysis': (7, 1.5), 'leadership': (5, 2)
},
'Lawyer': {
'math': (70, 12), 'science': (65, 15), 'english': (88, 8), 'social': (85, 8),
'openness': (7, 1.5), 'conscientiousness': (9, 1), 'extraversion': (7, 1.5),
'agreeableness': (6, 2), 'neuroticism': (4, 2),
'technical': (4, 2), 'creative': (5, 2), 'business': (6, 2), 'social_service': (7, 1.5),
'coding': (3, 2), 'communication': (9, 1), 'analysis': (9, 1), 'leadership': (8, 1.5)
},
'Entrepreneur': {
'math': (75, 12), 'science': (70, 12), 'english': (78, 10), 'social': (75, 10),
'openness': (9, 1), 'conscientiousness': (8, 1.5), 'extraversion': (8, 1.5),
'agreeableness': (6, 2), 'neuroticism': (3, 2),
'technical': (6, 2), 'creative': (7, 1.5), 'business': (9, 1), 'social_service': (5, 2),
'coding': (5, 2), 'communication': (8, 1.5), 'analysis': (8, 1.5), 'leadership': (9, 1)
},
'Teacher/Professor': {
'math': (75, 12), 'science': (75, 12), 'english': (82, 10), 'social': (78, 10),
'openness': (8, 1.5), 'conscientiousness': (8, 1.5), 'extraversion': (7, 1.5),
'agreeableness': (9, 1), 'neuroticism': (4, 2),
'technical': (5, 2), 'creative': (6, 2), 'business': (4, 2), 'social_service': (9, 1),
'coding': (4, 2), 'communication': (9, 1), 'analysis': (7, 1.5), 'leadership': (7, 1.5)
},
'Architect': {
'math': (80, 10), 'science': (75, 12), 'english': (72, 12), 'social': (70, 12),
'openness': (9, 1), 'conscientiousness': (8, 1.5), 'extraversion': (6, 2),
'agreeableness': (7, 1.5), 'neuroticism': (5, 2),
'technical': (7, 1.5), 'creative': (9, 1), 'business': (5, 2), 'social_service': (5, 2),
'coding': (4, 2), 'communication': (7, 1.5), 'analysis': (8, 1.5), 'leadership': (6, 2)
},
'Psychologist': {
'math': (65, 15), 'science': (70, 12), 'english': (80, 10), 'social': (85, 8),
'openness': (9, 1), 'conscientiousness': (8, 1.5), 'extraversion': (6, 2),
'agreeableness': (9, 1), 'neuroticism': (4, 2),
'technical': (4, 2), 'creative': (6, 2), 'business': (4, 2), 'social_service': (9, 1),
'coding': (3, 2), 'communication': (9, 1), 'analysis': (8, 1.5), 'leadership': (6, 2)
},
'Marketing Manager': {
'math': (70, 12), 'science': (65, 15), 'english': (82, 10), 'social': (78, 10),
'openness': (8, 1.5), 'conscientiousness': (7, 1.5), 'extraversion': (8, 1.5),
'agreeableness': (7, 1.5), 'neuroticism': (4, 2),
'technical': (5, 2), 'creative': (7, 1.5), 'business': (9, 1), 'social_service': (5, 2),
'coding': (4, 2), 'communication': (9, 1), 'analysis': (7, 1.5), 'leadership': (8, 1.5)
},
}
# Generate generic profiles for remaining careers
for career in careers:
if career not in career_profiles:
career_profiles[career] = {
'math': (70, 15), 'science': (70, 15), 'english': (70, 15), 'social': (70, 15),
'openness': (6, 2), 'conscientiousness': (6, 2), 'extraversion': (6, 2),
'agreeableness': (6, 2), 'neuroticism': (5, 2),
'technical': (5, 2), 'creative': (5, 2), 'business': (5, 2), 'social_service': (5, 2),
'coding': (5, 2), 'communication': (6, 2), 'analysis': (6, 2), 'leadership': (5, 2)
}
data = []
samples_per_career = 80
for career in careers:
profile = career_profiles[career]
for _ in range(samples_per_career):
record = {
'math_score': np.clip(np.random.normal(*profile['math']), 0, 100),
'science_score': np.clip(np.random.normal(*profile['science']), 0, 100),
'english_score': np.clip(np.random.normal(*profile['english']), 0, 100),
'social_score': np.clip(np.random.normal(*profile['social']), 0, 100),
'openness': np.clip(np.random.normal(*profile['openness']), 1, 10),
'conscientiousness': np.clip(np.random.normal(*profile['conscientiousness']), 1, 10),
'extraversion': np.clip(np.random.normal(*profile['extraversion']), 1, 10),
'agreeableness': np.clip(np.random.normal(*profile['agreeableness']), 1, 10),
'neuroticism': np.clip(np.random.normal(*profile['neuroticism']), 1, 10),
'technical_interest': np.clip(np.random.normal(*profile['technical']), 1, 10),
'creative_interest': np.clip(np.random.normal(*profile['creative']), 1, 10),
'business_interest': np.clip(np.random.normal(*profile['business']), 1, 10),
'social_interest': np.clip(np.random.normal(*profile['social_service']), 1, 10),
'coding_skill': np.clip(np.random.normal(*profile['coding']), 1, 10),
'communication': np.clip(np.random.normal(*profile['communication']), 1, 10),
'analysis': np.clip(np.random.normal(*profile['analysis']), 1, 10),
'leadership': np.clip(np.random.normal(*profile['leadership']), 1, 10),
'career': career
}
data.append(record)
return pd.DataFrame(data)
@st.cache_resource
def train_model():
"""Train the AI model"""
df = generate_training_data()
X = df.drop('career', axis=1)
y = df['career']
scaler = StandardScaler()
label_encoder = LabelEncoder()
X_scaled = scaler.fit_transform(X)
y_encoded = label_encoder.fit_transform(y)
model = RandomForestClassifier(n_estimators=200, max_depth=20, random_state=42)
model.fit(X_scaled, y_encoded)
return model, scaler, label_encoder, X.columns.tolist()
def predict_careers(user_data, model, scaler, label_encoder, feature_names):
"""Get career predictions"""
user_df = pd.DataFrame([user_data])
user_scaled = scaler.transform(user_df)
probabilities = model.predict_proba(user_scaled)[0]
top_indices = np.argsort(probabilities)[-7:][::-1]
recommendations = []
for idx in top_indices:
career = label_encoder.inverse_transform([idx])[0]
score = probabilities[idx] * 100
# Get top contributing features
feature_importances = model.feature_importances_
user_values = user_df.values[0]
weighted = user_values * feature_importances
top_features_idx = np.argsort(weighted)[-3:][::-1]
top_features = [feature_names[i].replace('_', ' ').title() for i in top_features_idx]
recommendations.append({
'career': career,
'score': score,
'strengths': top_features
})
return recommendations
# Main App
st.title("๐ง ni - Neuron Inputs")
st.subheader("AI-Powered Career Path Finder")
st.markdown("---")
# Sidebar
with st.sidebar:
st.markdown("### ๐ About ni")
st.info("""
**ni** analyzes:
- ๐ Academic Performance
- ๐งฌ Personality (Big Five)
- ๐ก Interests & Skills
Get recommendations from 40+ careers!
""")
user_type = st.selectbox(
"I am a:",
["Class 10 Student", "Class 12 Student", "Undergraduate", "Graduate", "Working Professional"]
)
st.markdown("---")
st.caption("Built by a startup founder ๐")
# Train model
with st.spinner("๐ค Training AI Model..."):
model, scaler, label_encoder, feature_names = train_model()
st.success("โ
Model Ready! Complete assessment below.")
# Assessment Form
st.markdown("## ๐ Your Assessment")
tab1, tab2, tab3, tab4 = st.tabs(["๐ Academic", "๐งฌ Personality", "๐ก Interests", "๐ฏ Skills"])
with tab1:
st.markdown("### Academic Scores")
col1, col2 = st.columns(2)
with col1:
math_score = st.slider("Math (%)", 0, 100, 75)
science_score = st.slider("Science (%)", 0, 100, 75)
with col2:
english_score = st.slider("English (%)", 0, 100, 75)
social_score = st.slider("Social Studies (%)", 0, 100, 75)
with tab2:
st.markdown("### Personality (1-10)")
col1, col2 = st.columns(2)
with col1:
openness = st.slider("Openness", 1, 10, 6, help="Curiosity, creativity")
conscientiousness = st.slider("Conscientiousness", 1, 10, 6, help="Organization, discipline")
extraversion = st.slider("Extraversion", 1, 10, 6, help="Sociability")
with col2:
agreeableness = st.slider("Agreeableness", 1, 10, 6, help="Cooperation")
neuroticism = st.slider("Emotional Stability", 1, 10, 6, help="Stress handling")
with tab3:
st.markdown("### Interests (1-10)")
col1, col2 = st.columns(2)
with col1:
technical_interest = st.slider("Technical/STEM", 1, 10, 5)
creative_interest = st.slider("Creative/Arts", 1, 10, 5)
with col2:
business_interest = st.slider("Business", 1, 10, 5)
social_interest = st.slider("Social Service", 1, 10, 5)
with tab4:
st.markdown("### Skills (1-10)")
col1, col2 = st.columns(2)
with col1:
coding_skill = st.slider("Coding", 1, 10, 5)
communication = st.slider("Communication", 1, 10, 6)
with col2:
analysis = st.slider("Analysis", 1, 10, 6)
leadership = st.slider("Leadership", 1, 10, 5)
st.markdown("---")
# Generate Button
if st.button("๐ Get My Career Recommendations", type="primary"):
user_data = {
'math_score': math_score, 'science_score': science_score,
'english_score': english_score, 'social_score': social_score,
'openness': openness, 'conscientiousness': conscientiousness,
'extraversion': extraversion, 'agreeableness': agreeableness,
'neuroticism': neuroticism, 'technical_interest': technical_interest,
'creative_interest': creative_interest, 'business_interest': business_interest,
'social_interest': social_interest, 'coding_skill': coding_skill,
'communication': communication, 'analysis': analysis,
'leadership': leadership
}
with st.spinner("๐ฎ Analyzing..."):
recommendations = predict_careers(user_data, model, scaler, label_encoder, feature_names)
st.markdown("---")
st.markdown("## ๐ฏ Your Top Career Matches")
# Top 5 careers
for i, rec in enumerate(recommendations[:5], 1):
col1, col2 = st.columns([4, 1])
with col1:
st.markdown(f"### {i}. {rec['career']}")
st.caption(f"๐ช Strengths: {', '.join(rec['strengths'])}")
with col2:
st.metric("Match", f"{rec['score']:.0f}%")
st.progress(rec['score'] / 100)
st.markdown("")
# More options
with st.expander("๐ More Career Options"):
for i, rec in enumerate(recommendations[5:], 6):
st.write(f"**{i}. {rec['career']}** - {rec['score']:.1f}%")
st.success("๐ Done! Research these careers and explore learning paths.")
# Simple viz
st.markdown("### ๐ Your Profile")
profile_scores = {
'Academic': (math_score + science_score + english_score + social_score) / 4,
'Technical': technical_interest * 10,
'Creative': creative_interest * 10,
'Business': business_interest * 10,
'Social': social_interest * 10
}
st.bar_chart(profile_scores)
# Footer
st.markdown("---")
st.markdown("""
<div style='text-align: center; color: gray;'>
<p>๐ง <strong>ni - Neuron Inputs</strong> | Beta v1.0</p>
<p style='font-size: 12px;'>Feedback? DM on LinkedIn!</p>
</div>
""", unsafe_allow_html=True)