$30 off During Our Annual Pro Sale. View Details »

Mastering Feature Engineering: Mining the Hidde...

tlyu0419
December 09, 2023

Mastering Feature Engineering: Mining the Hidden Salary Formula with CakeResume

特徵工程是在建置數據模型時相當重要也最藝術的部分,能幫助模型捕捉解釋變數和目標變數間的聯繫。而藝術的地方在於進行特徵工程相當大程度取決於研究者對於領域知識、專案需求的理解,沒有一體適用的方法
在這次的演講中我將以 CakeResume 上的職缺資料為例,和大家分享我建置的薪資預測模型,以及如何經過一系列的特徵工程後,將模型的效度(R^2) 從原本的 0.06 逐步提升至 0.51
要強調這次分享的重點並不在於模型的效度本身,而是該如何反覆分析與診斷模型的問題,有目的性的根據遇到的問題來進行對應的特徵工程,讓模型效度能滿足業務端的需求
#sciwork 2023 conference

tlyu0419

December 09, 2023
Tweet

More Decks by tlyu0419

Other Decks in Science

Transcript

  1. • 特徵工程是在建置數據模型時相當重要也最藝術的部分,能 幫助模型捕捉解釋變數和目標變數間的聯繫。而藝術的地方 在於進行特徵工程相當大程度取決於研究者對於領域知識、 專案需求的理解,沒有一體適用的方法 • 在這次的演講中我將以 CakeResume 上的職缺資料為例, 和大家分享我建置的薪資預測模型,以及如何經過一系列的

    特徵工程後,將模型的效度(R^2) 從原本的 0.06 逐步提升 至 0.51 • 要強調這次分享的重點並不在於模型的效度本身,而是該如 何反覆分析與診斷模型的問題,有目的性的根據遇到的問題 來進行對應的特徵工程,讓模型效度能滿足業務端的需求 Sciwork 2023 December 9-10 Mastering Feature Engineering: Mining the Hidden Salary Formula with CakeResume #Python #薪資預測 #特徵工程 游騰林(tlyu0419) 騰林是國泰數據部的資料科學家,擅長透過 Python, R 建置機器學習/深度學習模型、網路 爬蟲、資料視覺化以及圖形演算法 Speaker of PyCon, PyData, AIAcademic, MOPCON, COSCUP, Sciwork conference
  2. 資料源評估 – 104人力銀行 • 104 人力銀行上的職缺薪資大多寫面議,沒有具體的薪資範圍 5 Ref: 產業、應用與待遇 -

    Python 在勞動市場中的職缺分析 產業、程式語言的待遇在 4萬 以上的職缺比例 待遇面議 待遇面議
  3. 資料源評估2 – CakeResume 6 Ref: Amazon、LINE都在這徵才——CakeResume用什麼贏得新世代求職者的心? 具體的薪資範圍 豐富的職缺數量 跨各產業與職階 Cakeresume

    是新興、熱門的求職 平台,協助求職者製作專業、精美 的履歷,並協助企業搜尋人才 目前在網站上已經有數千間公司, 上萬份的職缺資料
  4. 期望產出 • 期望 • 模型告訴我們哪些因子會影響待遇, 而各自的影響程度又有多少? • 模型 • 多元線性回歸(Linear

    Regression) • 用一條線來描述 X 跟 y 之間的關係 • 選線性回歸的原因 • 簡單 • 容易解釋 • 綁住大家的雙手 7 多元線性回歸
  5. CakeResume 的職缺資料 • CakeResume 爬蟲程式(github) • tlyu0419/DataScience/26_WebCrawler/cakeresume/CakeResume.ipynb • CakeResume 上的職缺資訊(16275

    rows * 14 columns) • job_name • comp_name • job_desc • job_tags • profession • fa_business_time • fa_dollar_sign • … 9
  6. 資料清理邏輯 • 排除條件 • 職務類型: 排除兼職、實習類型的職缺 • 薪資: • 排除

    日薪、時薪、論件計酬 • 排除 沒有寫薪資 的職缺 (空值/只寫4萬以上) • 排除 非台幣計價 的職缺 • 職務描述: 排除 沒有寫職務描述 的職缺 • 地區: 排除不在台灣的職缺 • 排除後還剩 11,143 筆職缺資料 • 以 職務類別 做分層隨機抽樣 • 並以 80% / 20% 的比例切分訓練/測試資料 10
  7. 目標變數的處理邏輯 • 目標變數 • fa-dollar-sign >> mean_salary • 處理方式 •

    取薪資範圍的中間數作為模型的目標變數 • 處理目標變數時會遇到的問題 • 有些職缺的單位是千,有些是萬 • 有些職缺是寫年薪,有些是月薪 • 這裡統一將年薪除上14轉為月薪 • 有些職缺把年薪寫成月薪(或反過來) • 有些職缺只有寫在多少萬元以上 11 整理前 整理後 直接將年薪除 14 轉為月薪的方式其實有些暴力 不過這次的分享主題是 特徵工程 和 調整模型 就先請大家先略過這個問題!
  8. 探索性分析(EDA) • 解釋變數列表 • 職缺名稱 • 公司名稱 • 職缺描述 •

    職缺標籤 • 職務大類 • 職務小類 • 工作年資 • 工作地點 • 管理責任 • 職務階級 14
  9. 初版模型效度 • 建線性回歸模型 • formula = 'mean_salary ~ profession +

    work_years + location + fa_sitemap + fa_user’ • reg = sm.OLS.from_formula(formula, training_set).fit() • 模型效度 • Training • R^2: 0.091 / MAE: 29,204 • Testing • R^2: -0.172 / MAE: 25,809 • 模型內容 • 效度太差,先不著急檢視模型內容 16
  10. 離群值處理 • 到底該不該清掉離群值? • 離群值的進行方式 • 截尾 • Log2, 10,

    e,… • 1.5 * IQR • 9 * MAE • 3 * std • 混合: Domain + 1.5*IQR • 樣本數 • Training: 8,067 > 7,225 • Testing: 2,017 > 1,826 21 IQR*1.5 是常用的數值,可以再依需求調大/小
  11. 去除離群值後重新建模 • formula = 'mean_salary ~ profession + work_years +

    location + fa_sitemap + fa_user’ • reg = sm.OLS.from_formula(formula, training_set).fit() 22 Training Set R^2: 0.470 MAE: 10959 Testing Set R^2: 0.443 MAE: 11371
  12. 特徵交互 • 交互兩個或多個特徵,檢視特定變數在另一個變數不同類別上的影響力 • 假設地區變數為 4 個類別,類型變數有 2 個類別 •

    會生成 “地區:類型”的新變數,包含下面 4 個資料值 • 分為 全職-北部、全職-中部、全職-南部,以及 其他(Ref) • 通過這個方式可以捕捉全職在不同地區的影響力 23 地區\類型 全職 兼職(Ref) 北部 1 0 中部 2 0 南部 3 0 東部(Ref) 0 0
  13. 特徵交互 formula = 'mean_salary ~ profession + work_years + location

    + fa_sitemap + fa_user + profession:fa_user’ reg = sm.OLS.from_formula(formula, training_set).fit() 24 特徵交互沒有明顯幫助,反而還增加了一些過擬合qq Training Set R^2: 0.480 MAE: 10818 Testing Set R^2: 0.445 MAE: 11291
  14. 為什麼特徵交互後容易出現過擬合? • 特徵交互後產生太多特徵,讓模型變得非常複雜,增加了應用和解釋的困難度 • 在這邊對 Profession 和 fa_user 交互後,模型增加了 76

    個變數(19*4) • 這樣的處理在測試資料集的效度僅增加 0.002,因此評估不做特徵交互 25 Profession\fa_user 助理 初階 中高階 經理 經營層 生物醫療 1 2 3 4 0 建設 5 6 7 8 0 … … … … … 0 政府機關 73 74 75 76 0 業務 0 0 0 0 0 20-1(對照組)=19 5 – 1(對照組) = 4
  15. 業務類型的職缺 • 針對 業務性質 的職缺,是否需要排除&重新建模? • 方法1: 僅在算效度時排除業務類的職缺 • 方法2:

    排除業務類的職缺&重新建模 29 Training Set R^2: 0.490 MAE: 10630 Testing Set R^2: 0.463 MAE: 11000
  16. 剖析職缺描述 -職缺強調的技能 formula = 'mean_salary ~ profession + work_years +

    location + fa_sitemap + fa_user + pthon + javascript + linux + sql + word + excel + powerpoint’ reg = sm.OLS.from_formula(formula, training_set).fit() 30 Training Set R^2: 0.494 MAE: 10597 Testing Set R^2: 0.464 MAE: 11026
  17. 技能清單從哪裡來? • 檢視 職務描述 中是否出現特定的關鍵詞 • 方法1: by Domain 新增關鍵詞

    • 方法2: 通過各職缺的 Tag 來建立關鍵詞詞典 • 方法3: 對職缺描述做斷詞後轉詞頻,TFIDF • 注意事項 • 要做斷詞,不能直接下正則抓關鍵字 ex: r, c 是程式語言,容易誤抓無關的單詞 • 特定程式語言要做轉換 ex: c++, c# 的特殊符號會跟建模公式衝突 31
  18. 抽 Tags formula = 'mean_salary ~ profession + work_years +

    location + fa_sitemap + fa_user + excel + word + powerpoint + … + python + javascript + java’ 32 Training Set R^2: 0.519 MAE: 10304 Testing Set R^2: 0.488 MAE: 10771
  19. 截距 Intercept*50025 + 工作年資 work_years*3207 + 專業領域 Ref: 人資 其他*-2743

    + 客服*-4435 + 工程研發*9277 + 建設*-93 + 政府機關*-4557 + 教育*-3489 + 文字編輯*-7095 + 業務*-1209 + 法律*5151 + 物流貿易*-4229 + 生物醫療*401 + 經營管理*-1464 + 行銷*-4045 + 製造*3445 + 設計*-1046 + 軟體*12723 + 遊戲製作*7591 + 金融]*544 + 餐飲*-8406 + 地區 Ref: 其他 台中*-3405 + 台北*3298 + 台南*-6048 + 新北*67 + 新竹*3819 + 桃園*-1781 + 高雄*-4942 + 管理人數 Ref: 無責任 管10_15人*4943 + 管15人以上*9765 + 管1_5人*-83 + 管5_10人*1337 + 管理人數未定*3715 + 職階 Ref: 中高階 初階*-9618 + 助理*-10501 + 經營層*6575 + 經理*7337 + 技能 excel*-1033 + word*-4444 + powerpoint*-878 + outlook*-2347 + photoshop*-3744 + illustrator*-2108 + figma*1229 + premiere*-533 + linux*-1484 + android*-2178 + ios*3484 + flutter*734 + python*3455 + javascript*604 + java*1594 + c#*-4833 + php*-3064 + sql*-171 + c++*7401 + git*2827 + golang*10126 + vue.js*-1298 + c*-2328 + node.js*4011 + react*2667 + google analytics*-1576 + css*-2816 + html*-1514 + asp.net*-2266 + gcp*756 + aws*3921 + laravel*-4471 + autocad*-2190 + jquery*-4389 + devops*6553 + kotlin*614 + sketch*4117 模型解析 34 雖然模型考量很多面向,但實務上好像不太容易使用qq
  20. 當你提交程式給 HR 後… • 精準度不是選模型的唯一標準, 還需要考量解釋性、維運…等面向 • 投入太多特徵的優缺點 • 優點

    • 增加模型在訓練集的擬合程度 • 缺點 • 可能導致過擬合的問題 • 降低模型的可解釋性 35 這是個很精準的模型, 足足考量了 70 個面向 資料科學家 人資
  21. 特徵選擇方法 • 特徵選擇方法 • 向前 • 向後 • 向前向後 36

    Ref: 【机器学习】特征选择(Feature Selection)方法汇总 透過多輪迭代,逐步增加/移除變數, 直到達成停止條件(如顯著性都小於0.05) 優先移除 x2 變數,接著用剩餘的變數重新建模和 排除不顯著的變數,直到所有剩餘變數都顯著為止
  22. 模型解析 37 經過特徵選擇後,犧牲 0.001 的模型效度, 卻減少了過擬合以及大幅增加模型的可解釋性 截距 Intercept*35802 + 工作年資

    work_years*3230 + 專業領域 Ref: 其他 人資*3961 + 工程研發*13180 + 文字編輯*-3036 + 法律*9204 + 生物醫療*4403 + 經營管理*2505 + 製造*7255 + 設計*3077 + 軟體*16755 + 遊戲製作*11861 + 金融*4491 + 餐飲*-3789 + 業務*2821 + 地區 Ref: 其他 台北*3525 + 台南*-5769 + 新竹*4067 + 高雄*-4654 + 台中*-3139 + 管理人數 Ref: 無責任 管理人數未定*3683 + 職階 Ref: 其他 中高階*9892 + 經理*17587 + 經營層*17991 + 技能 word*-5767 + photoshop*-4798 + ios*2406 + python*3531 + c#*-5490 + php*-2925 + c++*6060 + git*2570 + golang*10112 + node.js*4092 + react*2797 + css*-3779 + aws*4008 + laravel*-4985 + jquery*-4429 + devops*6550 Training Set R^2: 0.519 >> 0.516 MAE: 10304 >> 10340 Testing Set R^2: 0.488 >> 0.487 MAE: 10771 >> 10796
  23. 繼續優化模型效度的方式 1. 繼續做錯誤分析 2. 特徵面 • Target encoding • 葉編碼

    • stacking 3. 模型面 • Tree-based model • NN 39 Target encoding 葉編碼 Stacking
  24. 不足的地方 • 技能也會有熟悉度的差異 • 但目前的資料缺少技能的年資 • 缺乏求職者自身的資訊 • 例如求職者的學歷,年齡 •

    存在共線性的問題 • 如 Python 跟 R 都可以建模型,有可能會互搶回歸係數 • Ridge regression 也會有同樣的問題! 40