Slide 1

Slide 1 text

• 特徵工程是在建置數據模型時相當重要也最藝術的部分,能 幫助模型捕捉解釋變數和目標變數間的聯繫。而藝術的地方 在於進行特徵工程相當大程度取決於研究者對於領域知識、 專案需求的理解,沒有一體適用的方法 • 在這次的演講中我將以 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

Slide 2

Slide 2 text

程式路徑 2 github.com/tlyu0419/mastering_feature_engineering_tutorial

Slide 3

Slide 3 text

Outline • 業務場景(10min) • 初步嘗試建模型(20min) • 第二版模型(20min) • 第三版模型(20min) • 模型解析(10min) • 總結(5min) • QA(5min) 3

Slide 4

Slide 4 text

HR 的業務痛點 • 面對公司的 人才招募 與 慰留 需求,HR 缺乏可靠、有依據的參考資料 4 身為資料科學家,可以怎麼幫 HR 解題?

Slide 5

Slide 5 text

資料源評估 – 104人力銀行 • 104 人力銀行上的職缺薪資大多寫面議,沒有具體的薪資範圍 5 Ref: 產業、應用與待遇 - Python 在勞動市場中的職缺分析 產業、程式語言的待遇在 4萬 以上的職缺比例 待遇面議 待遇面議

Slide 6

Slide 6 text

資料源評估2 – CakeResume 6 Ref: Amazon、LINE都在這徵才——CakeResume用什麼贏得新世代求職者的心? 具體的薪資範圍 豐富的職缺數量 跨各產業與職階 Cakeresume 是新興、熱門的求職 平台,協助求職者製作專業、精美 的履歷,並協助企業搜尋人才 目前在網站上已經有數千間公司, 上萬份的職缺資料

Slide 7

Slide 7 text

期望產出 • 期望 • 模型告訴我們哪些因子會影響待遇, 而各自的影響程度又有多少? • 模型 • 多元線性回歸(Linear Regression) • 用一條線來描述 X 跟 y 之間的關係 • 選線性回歸的原因 • 簡單 • 容易解釋 • 綁住大家的雙手 7 多元線性回歸

Slide 8

Slide 8 text

8 幾個分享目標 特徵工程 時間與品質 效度與解釋性 特徵工程在做什麼? 又應該要怎麼做? 清理資料需要投時間 但該怎麼權衡時間與品質? 模型是越準越好嗎? 什麼情況下反而不想模型這麼準?

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

資料清理邏輯 • 排除條件 • 職務類型: 排除兼職、實習類型的職缺 • 薪資: • 排除 日薪、時薪、論件計酬 • 排除 沒有寫薪資 的職缺 (空值/只寫4萬以上) • 排除 非台幣計價 的職缺 • 職務描述: 排除 沒有寫職務描述 的職缺 • 地區: 排除不在台灣的職缺 • 排除後還剩 11,143 筆職缺資料 • 以 職務類別 做分層隨機抽樣 • 並以 80% / 20% 的比例切分訓練/測試資料 10

Slide 11

Slide 11 text

目標變數的處理邏輯 • 目標變數 • fa-dollar-sign >> mean_salary • 處理方式 • 取薪資範圍的中間數作為模型的目標變數 • 處理目標變數時會遇到的問題 • 有些職缺的單位是千,有些是萬 • 有些職缺是寫年薪,有些是月薪 • 這裡統一將年薪除上14轉為月薪 • 有些職缺把年薪寫成月薪(或反過來) • 有些職缺只有寫在多少萬元以上 11 整理前 整理後 直接將年薪除 14 轉為月薪的方式其實有些暴力 不過這次的分享主題是 特徵工程 和 調整模型 就先請大家先略過這個問題!

Slide 12

Slide 12 text

探索性分析 12

Slide 13

Slide 13 text

探索性分析(EDA)技巧 • 資料視覺化 • Box-plot • Scatter • Tips • x, y 軸的界限 • 透明度 13

Slide 14

Slide 14 text

探索性分析(EDA) • 解釋變數列表 • 職缺名稱 • 公司名稱 • 職缺描述 • 職缺標籤 • 職務大類 • 職務小類 • 工作年資 • 工作地點 • 管理責任 • 職務階級 14

Slide 15

Slide 15 text

初步嘗試建模型 15

Slide 16

Slide 16 text

初版模型效度 • 建線性回歸模型 • 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

Slide 17

Slide 17 text

• R^2 在評估模型效度時,對於殘差大的樣本點會嚴重扣分! • 物理意義就是有離群的偏差,但又是什麼原因導致這麼偏差呢? 模型效度分析 17 模型高估薪資 模型高估薪資 模型低估薪資 模型低估薪資 Training Set R^2: 0.091 MAE: 29204 Testing Set R^2: -0.172 MAE: 25809

Slide 18

Slide 18 text

• 計算模型預測值的殘差(res),檢視模型低估的樣本(依殘差由小到大排序) • 測試性質的職缺 >> 應該排除資料 • ”不小心”把年薪寫成月薪 >> 不太容易人工識別&修正,後續可以做離群值偵測 錯誤分析 18

Slide 19

Slide 19 text

• 計算模型預測值的殘差(res),檢視模型高估的樣本(依殘差由大到小排序) • 猜測: 職缺等級清一色都是 經營層,模型可能看到這個特徵就會往上猜 >> 應該對職缺和產業做特徵交互,讓模型學習交互關係 錯誤分析 19

Slide 20

Slide 20 text

第二次嘗試建模型 20

Slide 21

Slide 21 text

離群值處理 • 到底該不該清掉離群值? • 離群值的進行方式 • 截尾 • 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 是常用的數值,可以再依需求調大/小

Slide 22

Slide 22 text

去除離群值後重新建模 • 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

Slide 23

Slide 23 text

特徵交互 • 交互兩個或多個特徵,檢視特定變數在另一個變數不同類別上的影響力 • 假設地區變數為 4 個類別,類型變數有 2 個類別 • 會生成 “地區:類型”的新變數,包含下面 4 個資料值 • 分為 全職-北部、全職-中部、全職-南部,以及 其他(Ref) • 通過這個方式可以捕捉全職在不同地區的影響力 23 地區\類型 全職 兼職(Ref) 北部 1 0 中部 2 0 南部 3 0 東部(Ref) 0 0

Slide 24

Slide 24 text

特徵交互 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

Slide 25

Slide 25 text

為什麼特徵交互後容易出現過擬合? • 特徵交互後產生太多特徵,讓模型變得非常複雜,增加了應用和解釋的困難度 • 在這邊對 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

Slide 26

Slide 26 text

錯誤分析 • 計算模型預測值的殘差,檢視模型高估的樣本 • 原因1: 工作內容超過給出的薪資導致模型高估 >> 模型不一定是錯的 • 原因2: 需要進一步抽取 職缺描述 中的資訊來加入模型 26

Slide 27

Slide 27 text

錯誤分析 • 計算模型預測值的殘差,檢視模型低估的樣本 • 發現一些業務性質的工作,會將額外的獎金納入薪資範圍中,導致薪資級距超大 >> 處理方式: 在算模型效度時忽略這些職缺,或排掉這些職缺後重新建模 27 也許模型預測出的薪資反而是更貼近真實的數字(?)

Slide 28

Slide 28 text

第三次嘗試建模型 28

Slide 29

Slide 29 text

業務類型的職缺 • 針對 業務性質 的職缺,是否需要排除&重新建模? • 方法1: 僅在算效度時排除業務類的職缺 • 方法2: 排除業務類的職缺&重新建模 29 Training Set R^2: 0.490 MAE: 10630 Testing Set R^2: 0.463 MAE: 11000

Slide 30

Slide 30 text

剖析職缺描述 -職缺強調的技能 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

Slide 31

Slide 31 text

技能清單從哪裡來? • 檢視 職務描述 中是否出現特定的關鍵詞 • 方法1: by Domain 新增關鍵詞 • 方法2: 通過各職缺的 Tag 來建立關鍵詞詞典 • 方法3: 對職缺描述做斷詞後轉詞頻,TFIDF • 注意事項 • 要做斷詞,不能直接下正則抓關鍵字 ex: r, c 是程式語言,容易誤抓無關的單詞 • 特定程式語言要做轉換 ex: c++, c# 的特殊符號會跟建模公式衝突 31

Slide 32

Slide 32 text

抽 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

Slide 33

Slide 33 text

所以模型說了些什麼? 33

Slide 34

Slide 34 text

截距 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

Slide 35

Slide 35 text

當你提交程式給 HR 後… • 精準度不是選模型的唯一標準, 還需要考量解釋性、維運…等面向 • 投入太多特徵的優缺點 • 優點 • 增加模型在訓練集的擬合程度 • 缺點 • 可能導致過擬合的問題 • 降低模型的可解釋性 35 這是個很精準的模型, 足足考量了 70 個面向 資料科學家 人資

Slide 36

Slide 36 text

特徵選擇方法 • 特徵選擇方法 • 向前 • 向後 • 向前向後 36 Ref: 【机器学习】特征选择(Feature Selection)方法汇总 透過多輪迭代,逐步增加/移除變數, 直到達成停止條件(如顯著性都小於0.05) 優先移除 x2 變數,接著用剩餘的變數重新建模和 排除不顯著的變數,直到所有剩餘變數都顯著為止

Slide 37

Slide 37 text

模型解析 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

Slide 38

Slide 38 text

還可以再優化模型效度嗎? 38

Slide 39

Slide 39 text

繼續優化模型效度的方式 1. 繼續做錯誤分析 2. 特徵面 • Target encoding • 葉編碼 • stacking 3. 模型面 • Tree-based model • NN 39 Target encoding 葉編碼 Stacking

Slide 40

Slide 40 text

不足的地方 • 技能也會有熟悉度的差異 • 但目前的資料缺少技能的年資 • 缺乏求職者自身的資訊 • 例如求職者的學歷,年齡 • 存在共線性的問題 • 如 Python 跟 R 都可以建模型,有可能會互搶回歸係數 • Ridge regression 也會有同樣的問題! 40

Slide 41

Slide 41 text

總結 41

Slide 42

Slide 42 text

總結 42 特徵工程 不是一次性的整理類別/數值變數, 而是多輪迭代逐幫模型學習的過程 效率與品質 不是一次把資料都清理乾淨才建模型, 工作上會先做一個基本版,再接著做優化 效度與解釋性 模型效度不是選模型的唯一標準, 實務上更傾向好解釋而效果又不差的模型

Slide 43

Slide 43 text

Any questions?