使用 Python 資料分析和視覺化上市櫃公司薪資公開資料
前言
證交所今(28)日在公開資訊觀測站公布上市公司申報之107年度「非擔任主管職務之全時員工薪資」資訊。藉由提升員工薪酬資訊透明度,讓摳門老闆無所遁形。
根據新聞媒體的報導 證交所公布上市公司非主管全時員工薪資,讓我們可以一窺近兩千家(853 + 733)上市櫃公司的薪資水準,也可以看看哪些公司薪資水準相對較低(順便看看各種逗趣的理由?本文 cover 圖即是將低薪公司的理由放入 wordcloud 產生器產生的圖片!),當作我們尋找合適工作的參考依據之一(但薪資高低不是決定合適工作的唯一標準)。
當然身為一個略懂略懂資料分析的軟體工程師,我們當然不能只看新聞媒體所提供的加工過的二手資料,更應該親自動手 hands on 來進行資料探索看看有哪些有趣的小 insight。因此接下來我們將使用 Python 網路爬蟲爬取證交所公開資訊觀測站上的上市櫃公司「非擔任主管職務之全時員工薪資」資訊並使用 python pandas、matplotlib 和 jupyter notebook 進行資料分析和資訊視覺化,看到更多有趣的薪水數據分析。
資料蒐集 Data Collect / Data Scraping
正所謂巧婦難為無米之炊,資料分析難為沒 data!
所以在決定要進行上市櫃公司的薪資資料後,我們必須蒐集相關的資料以利後續分析。
一開始我們先來到 證交所公開資訊觀測站 來觀察如何爬取非擔任主管職務之全時員工薪資資訊。
經過一番觀察後發現當下拉選單選擇時會使用 ajax 去後端 api 擷取資料。所以我們可以透過 POST https://mops.twse.com.tw/mops/web/ajax_t100sb15
這個 endpoint 去取得薪資資料。
由於資料集的欄位有合併的部分,所以我們拿掉 非擔任主管職務之全時員工資訊
、同業公司資訊
和 薪資統計情形
讓 columns 可以更單純,以利於接下來使用 pandas 進行資料分析。
1 | from collections import OrderedDict |
資料前處理 Data Preprocessing
資料前處理是資料探勘和資料分析流程步驟之一,主要目的是將真實世界的資料進行整理轉化,變得可以閱讀和分析。
在蒐集完資料後,我們將使用 pandas 載入我們抓取的上市櫃公司薪資的 .csv 檔案來進行分析 並進行資料前處理。我們蠻幸運的是這個資料集算是完整且是結構化資料,不太需要做太多的資料前處理(例如:補值、刪除遺漏值等),主要要做的是 columns 名稱調整和員工薪資值的取代和轉換成整數。
上市公司的 107_sii.csv 檔案:
上櫃公司的 107_otc.csv 檔案:
接著我們來進行資料的前處理,方便接下來的探索性資料分析,首先載入 pandas、matplotlib 函式庫並使用 pandas 載入資料集
1 | import pandas as pd |
整體資料資訊:
1 | df_sii.info() |
觀看前面幾筆資料長相:
1 | $ df_sii.head() |
將 columns 名稱調整成英文,方便分析操作
1 | headers = ['industry','company_code', 'company_people_count', 'company_name', 'company_total_salary', 'company_average_salary', 'company_eps', 'industry_average_salary', 'industry_average_eps', 'is_under_50', 'high_eps_low_salary', 'growth_but_low_salary', 'low_salary_reason'] |
調整 column 過後:
1 | df_sii.info() |
將員工薪資-平均數(仟元/人) , 去除並將字串 str 轉為 float
1 | df_sii['company_average_salary'] = df_sii['company_average_salary'].str.replace(',', '').astype(int) |
新的資料長相:
1 | df_sii.head() |
探索性資料分析 Explore Data Analytics
探索性資料分析是資料分析的一個步驟,透過敘述統計、圖表分析等方式來了解資料(例如:最大、最小值、平均值、標準差、離群值等),找出假設和可能的特徵值。
在進行完資料前處理後我們要來進行探索性資料分析,看看有哪些有趣的資料組合、相關性和圖表。
首先我們來看看一些基本的敘述統計:
1
df_sii.describe()
喔喔,853 家上是公司平均薪資達 82 萬,挺不錯的呀!但記得這是平均數(首富跟你的平均)。EPS 平均有 2.73 左右。來看看薪資排名:
1
df_sii.sort_values(['company_average_salary'], ascending=False)
最大值當然就是媒體爭相報導的發哥聯發科的 270 萬,郭董事長的鴻海也是榜上有名啦,當然我們台灣之光台積電也是名列前茅(讓人肅然起敬的還是台積電員工數量也是相當多):
最小值則是食品公司興泰的 34 萬(嗯,月薪約 NT 28,500,比 22k 好一點)
1
df_sii.sort_values(['company_average_salary'], ascending=True)
去台灣股市資訊網 弄來的台灣前 20 大市值公司名單:
1
2top20_valuable_stock_list = [2330, 2317, 6505, 2412, 1301, 3008, 1303, 1326, 2882, 2454, 1216, 2881, 2886, 2891, 2308, 2002, 3045, 2912, 3711, 2892]
df_sii[df_sii['company_code'].isin(top20_valuable_stock_list)]嗯,看來公司市值比較高,薪水不一定比較高。
台股前二十大市值公司薪資排行:
聯發科、鴻海、台積電、中鋼、中華電、台達電、兆豐金、台塑石化、台塑、台化
<= 抓到了,公司市值大薪資又高的公司!讀者準備 CV 中(大誤)最後來關心一下,咱們網路軟體業的薪資水平好了。若以純網路軟體可以看一下目前獨立出來的上市櫃公司的電子商務類別:
1
df_otc[df_otc['industry'].isin(['電子商務'])].sort_values(['company_average_salary'], ascending=False)
好吧,革命尚未成功,同志仍需努力。台灣半導體、電子業還是很強,網路軟體業還是得加點油。
1
2
3df_otc_ec = df_otc[df_otc['industry'].isin(['電子商務'])]
df_otc_ec.company_average_salary = pd.to_numeric(df_otc_ec.company_average_salary)
df_otc_ec.loc[:, ['company_code', 'company_average_salary']].plot(kind='bar', x='company_code', y='company_average_salary', title ="TW EC", figsize=(15, 10), legend=True, fontsize=12)EPS 和 薪資的相關性:
接著我們想了解公司賺錢是否有合理分配到員工身上,因為依照正常的邏輯假設來講,公司賺錢(這邊簡單用 EPS 每股盈餘來看,稅後 EPS = 淨利/在外流通股數),應該員工的薪資會相對較高,但真的是這樣嗎?在畫散佈圖之前,我們先把 dataFrame 取子集合(僅含公司平均薪資和公司 eps)
1
df_sii_average_salary_eps = df_sii[['company_average_salary', 'company_eps']]
sort 發現有 大立光、國巨、華新科 index [488, 252, 372] 這幾個 eps 超高的 outliner,簡單起見先把它們去除:
1
df_sii_average_salary_eps.sort_values(['company_eps'], ascending=False)
1
2filter_df_sii_average_salary_eps = df_sii_average_salary_eps.drop(df_sii_average_salary_eps.index[[488, 252, 372]])
filter_df_sii_average_salary_eps.sort_values(['company_eps'], ascending=False)看起來正常多了:
將 company_eps 當作 x 軸,company_average_salary 當 y 軸畫出 scatter,看起來大部分公司 eps 都在 0-10 之間,但 eps 和薪資相關性看起來沒辦法很確定是否相關:
1
filter_df_sii_average_salary_eps.plot(kind='scatter', x='company_eps', y='company_average_salary')
使用 Pearson correlation coefficient 來看看 eps 和薪資的相關程度:
皮爾森相關分析用於探討兩連續變數 (X, Y) 之間的線性相關性,若兩變數之間的相關係數絕對值較大,則表示彼此相互共變的程度較大。一般而言,若兩變數之間為正相關,則當 X 提升時,Y 也會隨之提升;反之,若兩變數之間為負相關,則當 X 提升時,Y 也會隨之下降。一般研究學者認為,相關係數 0.3 以下為低相關,0.3-0.7 為中等相關,0.7 以上為高度相關。
1
filter_df_sii_average_salary_eps.corr(method ='pearson')
結果是 0.307071。所以台灣上市公司 eps 和公司薪資應該可以算是中等相關,也就是說公司賺錢和你賺不賺錢不一定高度相關,還要看老闆產業和老闆摳不摳門呀!
公司經營績效與員工薪酬之關聯性及合理性說明:
這次證交所公布的公開資料蠻有趣的,特別要求若是屬於低薪的公司需要公布低薪理由。若有興趣的讀者可以研究看看,可以拓展視野,開了不少眼界XD,也更加印證了:高薪的理由只有一個(產業、公司賺錢發大財),低薪的理由卻可以有很多種。
本公司地處偏鄉,人才要求不易致外籍員工人數較高拉低平均薪資,且對個人的學經歷及技能要求無法提高,僅能於就職過程中予以訓練及培養,雖無法達到規定金額仍盡力提高員工所得。
為何外籍員工只能低薪?可以雇用高級技術員工?
1.全球經濟不景氣2.過度教育讓學歷貶值、同儕效應使薪資過低3.外勞人數多,拉低平均薪資4.派遣員工的比例高,拉低對員工平均薪資的成長
過度教育讓學歷貶值?全球經濟不景氣?(千錯萬錯都是別人的錯?黑人問號?)
因總公司座落在「新竹科學園區」外,相較薪資水準與園區內的同業較低。且公司大部份員工是在地居民,所以薪資福利項目屬於外縣市之交通、住宿補助福利較少。
新竹科學園區 OS:低薪怪我囉~
總結
以上我們透過簡單使用 Python 資料分析和視覺化上市櫃公司薪水公開資料,進行資料分析的步驟:
- 資料蒐集 Data Collect / Data Scraping
- 資料前處理 Data Preprocessing
- 探索性資料分析 Explore Data Analytics
主要是透過一個難得的公開資料集進行簡單的資料分析(政府部門德政應該好好的鼓勵一下,也期許自己未來有機會也不要成為員工口中的慣老闆?)。未來我們也可以更進一步整合更多資料集來進行選股、公司低薪理由文字分析或是分析各區域的薪資地圖等更多有趣的資料分析應用。我們下回見啦!
參考文件
(image via twimg、topjavatutorial、Hacker Noon )
關於作者:
@kdchang 文藝型開發者,夢想是做出人們想用的產品和辦一所心目中理想的學校。A Starter & Maker. JavaScript, Python & Arduino/Android lover.:)
留言討論