{ "cells": [ { "cell_type": "code", "execution_count": 1, "id": "f73c1560", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Defaulting to user installation because normal site-packages is not writeable\n", "Requirement already satisfied: selenium in c:\\users\\cavaciar\\appdata\\roaming\\python\\python313\\site-packages (4.43.0)\n", "Requirement already satisfied: webdriver-manager in c:\\users\\cavaciar\\appdata\\roaming\\python\\python313\\site-packages (4.0.2)\n", "Requirement already satisfied: beautifulsoup4 in c:\\python\\lib\\site-packages (4.13.5)\n", "Requirement already satisfied: pandas in c:\\python\\lib\\site-packages (2.3.3)\n", "Requirement already satisfied: scikit-learn in c:\\python\\lib\\site-packages (1.7.2)\n", "Requirement already satisfied: certifi>=2026.1.4 in c:\\users\\cavaciar\\appdata\\roaming\\python\\python313\\site-packages (from selenium) (2026.4.22)\n", "Requirement already satisfied: trio<1.0,>=0.31.0 in c:\\users\\cavaciar\\appdata\\roaming\\python\\python313\\site-packages (from selenium) (0.33.0)\n", "Requirement already satisfied: trio-websocket<1.0,>=0.12.2 in c:\\users\\cavaciar\\appdata\\roaming\\python\\python313\\site-packages (from selenium) (0.12.2)\n", "Requirement already satisfied: typing_extensions<5.0,>=4.15.0 in c:\\python\\lib\\site-packages (from selenium) (4.15.0)\n", "Requirement already satisfied: urllib3<3.0,>=2.6.3 in c:\\users\\cavaciar\\appdata\\roaming\\python\\python313\\site-packages (from urllib3[socks]<3.0,>=2.6.3->selenium) (2.6.3)\n", "Requirement already satisfied: websocket-client<2.0,>=1.8.0 in c:\\python\\lib\\site-packages (from selenium) (1.8.0)\n", "Requirement already satisfied: attrs>=23.2.0 in c:\\python\\lib\\site-packages (from trio<1.0,>=0.31.0->selenium) (25.4.0)\n", "Requirement already satisfied: sortedcontainers in c:\\python\\lib\\site-packages (from trio<1.0,>=0.31.0->selenium) (2.4.0)\n", "Requirement already satisfied: idna in c:\\python\\lib\\site-packages (from trio<1.0,>=0.31.0->selenium) (3.11)\n", "Requirement already satisfied: outcome in c:\\users\\cavaciar\\appdata\\roaming\\python\\python313\\site-packages (from trio<1.0,>=0.31.0->selenium) (1.3.0.post0)\n", "Requirement already satisfied: sniffio>=1.3.0 in c:\\python\\lib\\site-packages (from trio<1.0,>=0.31.0->selenium) (1.3.0)\n", "Requirement already satisfied: cffi>=1.14 in c:\\python\\lib\\site-packages (from trio<1.0,>=0.31.0->selenium) (2.0.0)\n", "Requirement already satisfied: wsproto>=0.14 in c:\\users\\cavaciar\\appdata\\roaming\\python\\python313\\site-packages (from trio-websocket<1.0,>=0.12.2->selenium) (1.3.2)\n", "Requirement already satisfied: pysocks!=1.5.7,<2.0,>=1.5.6 in c:\\python\\lib\\site-packages (from urllib3[socks]<3.0,>=2.6.3->selenium) (1.7.1)\n", "Requirement already satisfied: requests in c:\\users\\cavaciar\\appdata\\roaming\\python\\python313\\site-packages (from webdriver-manager) (2.33.1)\n", "Requirement already satisfied: python-dotenv in c:\\python\\lib\\site-packages (from webdriver-manager) (1.1.0)\n", "Requirement already satisfied: packaging in c:\\python\\lib\\site-packages (from webdriver-manager) (25.0)\n", "Requirement already satisfied: soupsieve>1.2 in c:\\python\\lib\\site-packages (from beautifulsoup4) (2.5)\n", "Requirement already satisfied: numpy>=1.26.0 in c:\\python\\lib\\site-packages (from pandas) (2.3.5)\n", "Requirement already satisfied: python-dateutil>=2.8.2 in c:\\python\\lib\\site-packages (from pandas) (2.9.0.post0)\n", "Requirement already satisfied: pytz>=2020.1 in c:\\python\\lib\\site-packages (from pandas) (2025.2)\n", "Requirement already satisfied: tzdata>=2022.7 in c:\\python\\lib\\site-packages (from pandas) (2025.2)\n", "Requirement already satisfied: scipy>=1.8.0 in c:\\python\\lib\\site-packages (from scikit-learn) (1.16.3)\n", "Requirement already satisfied: joblib>=1.2.0 in c:\\python\\lib\\site-packages (from scikit-learn) (1.5.2)\n", "Requirement already satisfied: threadpoolctl>=3.1.0 in c:\\python\\lib\\site-packages (from scikit-learn) (3.5.0)\n", "Requirement already satisfied: pycparser in c:\\python\\lib\\site-packages (from cffi>=1.14->trio<1.0,>=0.31.0->selenium) (2.23)\n", "Requirement already satisfied: six>=1.5 in c:\\python\\lib\\site-packages (from python-dateutil>=2.8.2->pandas) (1.17.0)\n", "Requirement already satisfied: h11<1,>=0.16.0 in c:\\python\\lib\\site-packages (from wsproto>=0.14->trio-websocket<1.0,>=0.12.2->selenium) (0.16.0)\n", "Requirement already satisfied: charset_normalizer<4,>=2 in c:\\python\\lib\\site-packages (from requests->webdriver-manager) (3.4.4)\n", "Note: you may need to restart the kernel to use updated packages.\n" ] } ], "source": [ "pip install selenium webdriver-manager beautifulsoup4 pandas scikit-learn" ] }, { "cell_type": "code", "execution_count": null, "id": "d5c065ab", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Scraping: data+analyst\n", " [1] Found: Data Analyst I | $60,512\n", " [2] Found: Business Intelligence & Digital Analyst | $104,940\n", " [3] Found: Data Analyst, Production Finance Operations & Innovation | $190,000\n", " [4] Found: Data Analyst | $90,000\n", " [5] Found: Product Analyst | $101,750\n", "\n", "Scraping: data+scientist\n", " [1] Found: Research Scientist | $300,000\n", " [2] Found: Machine Learning Engineer, AI | $250,000\n", " [3] Found: Machine Learning Engineer, AI | $250,000\n", " [4] Found: Data Scientist | $138,750\n", " [5] Found: Data Scientist, Analytics | $170,000\n", "\n", "Scraping: business+analyst\n", " [1] Found: Business Analyst - Operations Analytics | $54,847\n", " [2] Found: Business Analyst | $62,565\n", " [3] Found: Business Analyst, Monetization | $164,200\n", " [4] Found: Business Analyst | $62,565\n", " [5] Found: Business Analyst | $102,500\n", "Data saved to linkedin_data_v2.csv\n" ] } ], "source": [ "import os\n", "import re\n", "import time\n", "import pandas as pd\n", "from selenium import webdriver\n", "from selenium.webdriver.chrome.service import Service\n", "from selenium.webdriver.chrome.options import Options\n", "from webdriver_manager.chrome import ChromeDriverManager\n", "from bs4 import BeautifulSoup\n", "\n", "def get_driver():\n", " options = Options()\n", " # options.add_argument(\"--headless\") # Comment this out if you want to WATCH the scraper work!\n", " options.add_argument(\"--no-sandbox\")\n", " options.add_argument(\"--disable-dev-shm-usage\")\n", " \n", " # This automatically finds your local Chrome version and downloads the right driver\n", " service = Service(ChromeDriverManager().install())\n", " return webdriver.Chrome(service=service, options=options)\n", "\n", "def clean_text(text):\n", " if pd.isna(text): return \"\"\n", " return re.sub(r'[^a-zA-Z0-9\\s]', ' ', str(text)).lower()\n", "\n", "def get_state(loc):\n", " state_match = re.findall(r'\\b[A-Z]{2}\\b', str(loc))\n", " return state_match[0] if state_match else \"Remote\" if \"Remote\" in str(loc) else \"Other\"\n", "\n", "def scrape_linkedin(titles, max_jobs=50):\n", " driver = get_driver()\n", " results = []\n", " \n", " for t in titles:\n", " url = f\"https://www.linkedin.com/jobs/search?keywords={t}&location=United%20States\"\n", " print(f\"\\nScraping: {t}\")\n", " driver.get(url)\n", " time.sleep(3) \n", " \n", " soup = BeautifulSoup(driver.page_source, \"html.parser\")\n", " cards = soup.find_all(\"div\", class_=\"base-search-card\")\n", " \n", " count = 0\n", " for card in cards:\n", " if count >= max_jobs: break\n", " try:\n", " title = card.find(\"h3\").text.strip()\n", " if any(k in title.lower() for k in [\"senior\", \"lead\", \"manager\", \"sr.\", \"principal\"]):\n", " continue\n", " \n", " link = card.find(\"a\", class_=\"base-card__full-link\")[\"href\"]\n", " loc = card.find(\"span\", class_=\"job-search-card__location\").text.strip()\n", "\n", " driver.get(link)\n", " time.sleep(2)\n", " desc_soup = BeautifulSoup(driver.page_source, \"html.parser\")\n", " desc_tag = desc_soup.find(\"div\", class_=\"description__text\")\n", " desc = desc_tag.text.strip() if desc_tag else \"\"\n", " \n", " sal_data = re.findall(r'\\$[\\d,]+', desc)\n", " if sal_data:\n", " nums = [int(s.replace('$', '').replace(',', '')) for s in sal_data[:2]]\n", " avg_sal = sum(nums)/len(nums)\n", " if avg_sal < 1000: avg_sal *= 2000 \n", " \n", " results.append({\n", " \"title\": title, \n", " \"state\": get_state(loc), \n", " \"salary_numeric\": avg_sal, \n", " \"skills_cleaned\": clean_text(desc)\n", " })\n", " count += 1\n", " print(f\" [{count}] Found: {title} | ${avg_sal:,.0f}\")\n", " except: continue\n", " \n", " driver.quit()\n", " return pd.DataFrame(results)\n", "\n", "# RUN IT\n", "df_linkedin = scrape_linkedin([\"data+analyst\", \"data+scientist\", \"business+analyst\"])\n", "# Use an absolute path to your Desktop\n", "df_linkedin.to_csv(r\"M:\\ISA 414\\Project\\linkedin_data_2026.csv\", index=False)\n", "print(\"Data saved to linkedin_data_2026.csv\")" ] }, { "cell_type": "code", "execution_count": 3, "id": "b2d73d53", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Kaggle datasets loaded successfully.\n", "(944, 13)\n", "(742, 33)\n" ] } ], "source": [ "import pandas as pd\n", "import numpy as np\n", "from sklearn.feature_extraction.text import TfidfVectorizer\n", "from sklearn import preprocessing, metrics\n", "from sklearn.model_selection import train_test_split\n", "from sklearn.ensemble import RandomForestRegressor\n", "\n", "# --- PART 1: LOAD ALL DATASETS ---\n", "# Load your newly scraped data\n", "df_linkedin = pd.read_csv(r\"M:\\ISA 414\\Project\\linkedin_data_v2.csv\") # Uses the file_path from the previous step\n", "\n", "# Load your Kaggle/Drive files (Ensure these files are in your VS Code folder)\n", "# If they are still only on Google Drive, you'll need to download them to your computer first.\n", "try:\n", " df1 = pd.read_csv(r\"M:\\ISA 414\\Project\\data_science_job_posts_2025.csv\")\n", " df2 = pd.read_csv(r\"M:\\ISA 414\\Project\\eda_data.csv\")\n", " print(\"Kaggle datasets loaded successfully.\")\n", "except FileNotFoundError:\n", " print(\"Kaggle files not found locally. Using LinkedIn data only for now.\")\n", " df1 = pd.DataFrame(columns=['job_title', 'salary_numeric', 'skills_cleaned', 'state'])\n", " df2 = pd.DataFrame(columns=['Job Title', 'salary_numeric', 'skills_cleaned', 'state'])\n", "\n", "print(df1.shape)\n", "print(df2.shape)" ] }, { "cell_type": "code", "execution_count": 6, "id": "1bdfc196", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Success! Total Rows for Training: 643\n" ] } ], "source": [ "# --- PART 2: DATA RECOVERY (FIXED FOR DUAL SALARY COLUMNS) ---\n", "\n", "def clean_salary_column(series):\n", " \"\"\"Forcefully converts various string formats into numbers.\"\"\"\n", " # If the function accidentally gets a DataFrame (2 columns), take the first one\n", " if isinstance(series, pd.DataFrame):\n", " series = series.iloc[:, 0]\n", " \n", " series = series.astype(str).str.lower()\n", " series = series.str.replace('k', '000', regex=False)\n", " series = series.str.replace(r'[$,\\s]', '', regex=True)\n", " series = series.str.split('-').str[0]\n", " return pd.to_numeric(series, errors='coerce')\n", "\n", "def standardize_df(df):\n", " # 1. Start by dropping exact name duplicates\n", " df = df.loc[:, ~df.columns.duplicated()].copy()\n", " \n", " cols = df.columns.tolist()\n", " rename_map = {}\n", " \n", " for c in cols:\n", " low_c = str(c).lower()\n", " if any(x in low_c for x in ['salary', 'avg', 'amount']) and 'numeric' not in low_c:\n", " rename_map[c] = 'salary_numeric'\n", " if any(x in low_c for x in ['description', 'skills', 'text']) and 'cleaned' not in low_c:\n", " rename_map[c] = 'skills_cleaned'\n", " if any(x in low_c for x in ['state', 'location', 'city']) and 'state' != low_c:\n", " rename_map[c] = 'state'\n", " if 'title' in low_c and 'title' != low_c:\n", " rename_map[c] = 'title'\n", " \n", " df = df.rename(columns=rename_map)\n", " \n", " # 2. IMPORTANT: If renaming created new duplicates (e.g., 'avg_salary' -> 'salary_numeric' \n", " # AND 'max_salary' -> 'salary_numeric'), keep only the first one.\n", " df = df.loc[:, ~df.columns.duplicated()].copy()\n", " \n", " # 3. Ensure required columns exist\n", " for required in ['salary_numeric', 'skills_cleaned', 'state', 'title']:\n", " if required not in df.columns:\n", " df[required] = 0 if required == 'salary_numeric' else \"Unknown\"\n", " \n", " # 4. Clean the salary\n", " df['salary_numeric'] = clean_salary_column(df['salary_numeric'])\n", " return df\n", "\n", "# --- RUN THE CLEANING ---\n", "df1_clean = standardize_df(df1)\n", "df2_clean = standardize_df(df2)\n", "df_linkedin_clean = standardize_df(df_linkedin)\n", "\n", "needed_cols = ['salary_numeric', 'skills_cleaned', 'state', 'title']\n", "combined_df = pd.concat([\n", " df1_clean[needed_cols],\n", " df2_clean[needed_cols],\n", " df_linkedin_clean[needed_cols]\n", "], axis=0).reset_index(drop=True)\n", "\n", "# Final Clean Up\n", "combined_df = combined_df[(combined_df['salary_numeric'] >= 40000) & (combined_df['salary_numeric'] <= 150000)]\n", "combined_df = combined_df.dropna(subset=['skills_cleaned'])\n", "\n", "print(f\"Success! Total Rows for Training: {len(combined_df)}\")" ] }, { "cell_type": "code", "execution_count": 28, "id": "7c989258", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Training Model on 514 rows...\n", "\n", "==============================\n", " MODEL PERFORMANCE\n", "==============================\n", "Mean Absolute Error: $11,374.24\n", "R-Squared (R²): 0.6368\n", "==============================\n" ] } ], "source": [ "# --- PART 3: MACHINE LEARNING with R-SQUARED ---\n", "\n", "# 1. Simplify Titles\n", "def simplify_title(t):\n", " t = str(t).lower()\n", " if 'scientist' in t: return 'scientist'\n", " if 'engineer' in t: return 'engineer'\n", " return 'analyst'\n", "\n", "combined_df['title_simple'] = combined_df['title'].apply(simplify_title)\n", "\n", "# 2. Encoding State & Title\n", "enc_loc = preprocessing.OneHotEncoder(handle_unknown='ignore', sparse_output=False)\n", "loc_df = pd.DataFrame(enc_loc.fit_transform(combined_df[['state']]), columns=enc_loc.get_feature_names_out(['state']), index=combined_df.index)\n", "\n", "enc_title = preprocessing.OneHotEncoder(handle_unknown='ignore', sparse_output=False)\n", "title_df = pd.DataFrame(enc_title.fit_transform(combined_df[['title_simple']]), columns=enc_title.get_feature_names_out(['title_simple']), index=combined_df.index)\n", "\n", "# 3. TF-IDF for Skills\n", "# Add these last few 'filler' words to the list\n", "noise_words = [\n", " \"support\", \"requirements\", \"teams\", \"team\", \"work\", \"responsibilities\", \n", " \"duties\", \"including\", \"job\", \"new\", \"make\", \"learning\", \"equal\", \n", " \"opportunity\", \"develop\", \"developing\", \"high\", \"plus\", \"ability\",\n", " \"analysis\", \"technologies\", \"tools\", \"gender\", \"using\", \"experience\", \"understanding\", \"looking\", \"time\"\n", "]\n", "from sklearn.feature_extraction import text\n", "base_stop_words = list(text.ENGLISH_STOP_WORDS.union(noise_words))\n", "\n", "# Use max_df to automatically filter out words that appear in too many postings (filler)\n", "tfidf_enc = TfidfVectorizer(\n", " stop_words=base_stop_words, \n", " max_features=100, \n", " ngram_range=(1, 2),\n", " max_df=0.7 # If a word is in >70% of jobs, it's 'noise'—ignore it!\n", ") \n", "\n", "skills_tfidf = tfidf_enc.fit_transform(combined_df['skills_cleaned'].astype(str))\n", "skills_df = pd.DataFrame(skills_tfidf.toarray(), columns=tfidf_enc.get_feature_names_out(), index=combined_df.index)\n", "\n", "# 4. Create X and y\n", "X = pd.concat([loc_df, title_df, skills_df], axis=1)\n", "y = combined_df['salary_numeric']\n", "FEATURE_COLS = list(X.columns)\n", "\n", "# 5. Train/Test Split\n", "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20, random_state=100)\n", "\n", "# 6. Fit Model\n", "print(f\"Training Model on {len(X_train)} rows...\")\n", "rf_model = RandomForestRegressor(n_estimators=500, random_state=100, n_jobs=-1)\n", "rf_model.fit(X_train, y_train)\n", "\n", "# --- EVALUATION ---\n", "y_pred = rf_model.predict(X_test)\n", "\n", "# Calculate Metrics\n", "mae = metrics.mean_absolute_error(y_test, y_pred)\n", "r2 = metrics.r2_score(y_test, y_pred) # <--- THIS IS YOUR R-SQUARED\n", "\n", "print(\"\\n\" + \"=\"*30)\n", "print(\" MODEL PERFORMANCE\")\n", "print(\"=\"*30)\n", "print(f\"Mean Absolute Error: ${mae:,.2f}\")\n", "print(f\"R-Squared (R²): {r2:.4f}\")\n", "print(\"=\"*30)\n", "\n", "if r2 < 0.3:\n", " print(\"Note: Low R² suggests salary is influenced by factors not in your data (like company size or interview performance).\")\n", "elif r2 > 0.7:\n", " print(\"Note: High R² suggests your skill and location features are very strong predictors!\")" ] }, { "cell_type": "code", "execution_count": 29, "id": "e1627275", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Model Training Complete.\n", "Mean Absolute Error: $11,374.24\n" ] } ], "source": [ "# --- PART 4: TRAIN RANDOM FOREST ---\n", "\n", "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20, random_state=100)\n", "\n", "rf_model = RandomForestRegressor(n_estimators=500, random_state=100, n_jobs=-1)\n", "rf_model.fit(X_train, y_train)\n", "\n", "# Evaluation\n", "y_pred = rf_model.predict(X_test)\n", "mae = metrics.mean_absolute_error(y_test, y_pred)\n", "print(f\"\\nModel Training Complete.\")\n", "print(f\"Mean Absolute Error: ${mae:,.2f}\")" ] }, { "cell_type": "code", "execution_count": 30, "id": "9907843e", "metadata": {}, "outputs": [ { "data": { "image/png": "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7ty5Y50tu0yZMtbP6m3SpImef/55vfnmm4qJiZGvr68WL16stWvX6ssvv0zTZyinxM3NTfXq1dOUKVOUN29e+fj4aNOmTZo/f75y5cpl0zZxZt569erpnXfeUUBAgK5fv661a9dq4MCB8vf3V4kSJeTs7KyvvvpKpUuXlouLiwoVKqRChQrp/fffV8eOHfXiiy/qjTfeUGxsrKZMmaLr169r0qRJj6z14MGD6tOnj1q3bq2SJUvKwcFBGzZs0MGDB21GL1Ozd+9eubu76969e7pw4YLCw8O1aNEi5c+fX999950cHBwe5zJahYSEaOnSperTp4+KFCmS5H75Jxo3bqzatWtr0KBBiomJUZUqVbRjxw7rP3Ee9XFj7733nrZt26a2bdtaP/bozJkz+vDDD3X16lVNmTJFUvruiYf9k32T069fP+s/gszv/85MtWvXVo8ePdS1a1ft2bNH9erVU86cORUdHa2tW7cqICBAb775pnLnzq3Bgwdr/Pjxev3119W6dWudP39eoaGhj3z0WpI++OAD1alTRzVq1NCwYcPk6+urixcvavXq1fr000/l6upqfVpk7ty5cnV1lZOTk4oVK5bs0yrPP/+8GjVqpKFDhyomJka1a9fWwYMHNXr0aFWqVCnZjy97lBo1aujFF19U+fLllTt3bkVFRWnRokWP9Y8tAJkoy6YRAwD8az0867VhGMbVq1eNnj17Gp6enoa9vb3h7e1tDB8+3Pj7779t2kkyevfubcyZM8coUaKEkT17dsPf39/46quv0nTslGajVjIzGN+8edPo27evUbBgQcPBwcEoX768sXjx4nQdJ6UZn3///XfjlVdeMXLnzm24uroajRs3Nn799VfD29vb6NKli03b8+fPGyEhIUbBggWN7NmzG4UKFTLatGljXLx40dpm8eLFhr+/v5E9e/Yk57Jq1SqjRo0ahpOTk5EzZ06jQYMGxrZt29JU78WLF43g4GDD39/fyJkzp+Hi4mKUL1/emD59unH//v00XYPExdHR0fD09DReeOEFY+bMmUZMTEySfQIDA42yZcsm29/Ds14nio+PN7y8vAxJxogRI5JsT23W64fPN3HmZ/OM1H/99ZfRtWtXI1euXEaOHDmM559/3ti5c6chyWZG6eTs3LnT6N27t1GhQgUjT548hp2dnZEvXz6jcePGxpo1a2zapvWe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oEE2/yw5cOCA6tevn+qoMgAAAAD8E2kOyrt27dKECRO0Z88enTt3TitWrNDly5etAcnHx0cHDx7UsWPHdOXKFd27d0++vr46d+6clixZolOnTmnWrFnWYJ3Ix8dHZ86cUWRkpK5cuaLY2Fg1bNhQNWvWVMuWLbVu3TqdPXtW27dv18iRI63vbU7Nq6++qunTp2vXrl367bffFBERod69e8vPz0/+/v7KnTu3PDw8NHfuXJ08eVIbNmywmRH7SfL19dWePXu0bt06HT9+XKNGjdLu3bvT1YePj4+6dOmikJAQrVq1SmfOnFFERISWLVuWbPv+/ftr3bp1OnPmjPbt26cNGzZYv499+vRRTEyM2rVrpz179ujEiRNatGiRjh07JunBY+WTJ0/W0qVLdezYMQ0bNkyRkZHq169fmutt06aN2rZtq/bt22vixInas2ePfvvtN33//fdq2LCh9eOi9u3bp9dff13lypWzWdq3b68vvvjiiX28FgAAAIBnS5qDspubmzZv3qymTZvKz89PI0eO1LRp06wTZHXv3l2lSpWyvtd227ZtatGihQYMGKA+ffqoYsWK2r59u0aNGmXT7yuvvKLGjRurfv36ypcvnxYvXiyLxaI1a9aoXr16CgkJkZ+fn9q1a6ezZ8+qQIECj6y1UaNG+u6779S8eXP5+fmpS5cu8vf31/r162Vvb2+dBGvv3r0qV66cBgwYoClTpqTz0mWMnj17qlWrVmrbtq1q1Kihq1evqlevXunu5+OPP9arr76qXr16yd/fX927d9ft27eTbRsfH6/evXurdOnSaty4sUqVKqU5c+ZIkjw8PLRhwwbdunVLgYGBqlKliubNm2d99Ltv374aNGiQBg0apICAAK1du1arV6+2mfE6KChIwcHBKdZqsVj09ddf64MPPtDKlSsVGBio8uXLKzQ0VC1atFCjRo00f/58lSlTJtlJ01q2bKm//vpL3333XbqvEwAAAAA8SppnvQbSysfHR6GhoamG5SclcWY7Zr1GRmLWawAAgKdPpsx6DaTF0aNH5erqajPTNwAAAAA8TZ7KoFy2bFmbj40yL1999VVWl/dM8/f316FDh5Qt21N5awEAAACA7LO6gMexZs2aFCdySst7mAEAAAAASMlTGZS9vb2zugQAAAAAwL8Uz8cCAAAAAGBCUAYAAAAAwISgDAAAAACA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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import matplotlib.pyplot as plt\n", "\n", "# 1. Extract Feature Importances from your trained Random Forest\n", "importances = rf_model.feature_importances_\n", "feature_names = X.columns\n", "\n", "# 2. Create a DataFrame for easy sorting\n", "feat_df = pd.DataFrame({'Feature': feature_names, 'Importance': importances})\n", "feat_df = feat_df.sort_values(by='Importance', ascending=False).head(10)\n", "\n", "# 3. Plot it\n", "plt.figure(figsize=(10, 6))\n", "plt.barh(feat_df['Feature'], feat_df['Importance'], color='skyblue')\n", "plt.xlabel('Importance Score')\n", "plt.title('Top 10 Factors Driving Salary Predictions')\n", "plt.gca().invert_yaxis() # Highest importance at the top\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 32, "id": "9c1d638d", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "--- PREDICTION FOR ALEX ---\n", "Location: OH | Role: Data Analyst\n", "Estimated Market Salary: $60,528.64\n", "\n", "Prediction 2 (CA, Data Scientist): $81,822.62\n", "Prediction 3 (OH, Data Analyst): $57,855.26\n" ] } ], "source": [ "\n", "# --- PART 5: THE CHATBOT PREDICTOR ---\n", "\n", "def chatbot_predict(state_input, title_input, skills_input):\n", " # Process inputs exactly like training data\n", " loc_encoded = enc_loc.transform(pd.DataFrame([{'state': state_input.upper()}]))\n", " loc_input_df = pd.DataFrame(loc_encoded, columns=enc_loc.get_feature_names_out(['state']))\n", " \n", " simple_t = simplify_title(title_input)\n", " title_encoded = enc_title.transform(pd.DataFrame([{'title_simple': simple_t}]))\n", " title_input_df = pd.DataFrame(title_encoded, columns=enc_title.get_feature_names_out(['title_simple']))\n", " \n", " skills_encoded = tfidf_enc.transform([skills_input.lower()])\n", " skills_input_df = pd.DataFrame(skills_encoded.toarray(), columns=tfidf_enc.get_feature_names_out())\n", " \n", " final_input = pd.concat([loc_input_df, title_input_df, skills_input_df], axis=1)\n", " return rf_model.predict(final_input)[0]\n", "\n", "# --- TEST THE CHATBOT ---\n", "test_state = \"OH\"\n", "test_title = \"Data Analyst\"\n", "test_skills = \"python sql tableau excel communication\"\n", "\n", "predicted_val = chatbot_predict(test_state, test_title, test_skills)\n", "print(f\"\\n--- PREDICTION FOR ALEX ---\")\n", "print(f\"Location: {test_state} | Role: {test_title}\")\n", "print(f\"Estimated Market Salary: ${predicted_val:,.2f}\")\n", "\n", "predict2 = chatbot_predict(\"CA\", \"Data Scientist\", \"python machine learning communication skills projects\")\n", "predict3 = chatbot_predict(\"OH\", \"Data Analyst\", \"excel sql\")\n", "print(f\"\\nPrediction 2 (CA, Data Scientist): ${predict2:,.2f}\")\n", "print(f\"Prediction 3 (OH, Data Analyst): ${predict3:,.2f}\")" ] } ], "metadata": { "kernelspec": { "display_name": "base", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.13.9" } }, "nbformat": 4, "nbformat_minor": 5 }