Python數據可視化:淺談數據挖掘崗

  • 2019 年 10 月 8 日
  • 筆記

作者 | 小F

來源 | 法納斯特

/ 01 / PostgreSQL

本次使用的資料庫為PostgreSQL。

它是一個開源對象關係資料庫管理系統(ORDBMS)。

通過psycopg2模組與Python集成。

可視化工具使用Navicat for PostgreSQL,免費試用14天…

沒找到如何用Python創建PG資料庫,所以資料庫的創建在Navicat for PostgreSQL中完成。

資料庫的連接通過Pyhton的psycopg2模組,具體如下。

import psycopg2  # 連接資料庫  conn = psycopg2.connect(database="lagou_job", user="postgres", password="774110919", host="127.0.0.1", port="5432")  print("Opened database successfully")  # 創建工作表  cur = conn.cursor()  cur.execute('''CREATE TABLE job (id INT PRIMARY KEY NOT NULL, job_title TEXT NOT NULL, job_salary TEXT NOT NULL, job_city TEXT NOT NULL, job_experience TEXT NOT NULL, job_education TEXT NOT NULL, company_name TEXT NOT NULL, company_type TEXT NOT NULL, company_status TEXT NOT NULL, company_people TEXT NOT NULL, job_tips TEXT NOT NULL, job_welfare TEXT NOT NULL);''')  print("Table created successfully")  # 關閉資料庫  conn.commit()  conn.close()

希望以後能出一期PostgreSQL的教程,網上關於它的教程並不多,還是選擇自力更生…

/ 02 / 數據獲取

程式碼和之前的差不多,有變化的就是「關鍵詞」和「資料庫」。

同時還獲取了職位詳情頁的URL,不過我沒對詳情頁進行爬取,有興趣的小夥伴可以試試。

import requests  import psycopg2  import random  import time  import json    count = 0  url = 'https://www.lagou.com/jobs/positionAjax.json?needAddtionalResult=false'  headers = {      'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36',      'Cookie': '你的cookie值',      'Accept': 'application/json, text/javascript, */*; q=0.01',      'Connection': 'keep-alive',      'Host': 'www.lagou.com',      'Origin': 'https://www.lagou.com',      'Referer': 'https://www.lagou.com/jobs/list_%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90?labelWords=sug&fromSearch=true&suginput=shuju'  }    # 連接資料庫  db = psycopg2.connect(database="lagou_job", user="postgres", password="774110919", host="127.0.0.1", port="5432")      def add_Postgresql(id, job_title, job_salary, job_city, job_experience, job_education, company_name, company_type, company_status, company_people, job_tips, job_welfare):      # 將數據寫入資料庫中      try:          cursor = db.cursor()          sql = "insert into job (id, job_title, job_salary, job_city, job_experience, job_education, company_name, company_type, company_status, company_people, job_tips, job_welfare) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')" % (int(id), job_title, job_salary, job_city, job_experience, job_education, company_name, company_type, company_status, company_people, job_tips, job_welfare);          print(sql)          cursor.execute(sql);          print(cursor.lastrowid)          db.commit()      except Exception as e:          print(e)          db.rollback()      def get_message():      for i in range(1, 31):          print('第' + str(i) + '頁')          time.sleep(random.randint(10, 20))          data = {              'first': 'false',              'pn': i,              'kd': '數據挖掘'          }          response = requests.post(url=url, data=data, headers=headers)          result = json.loads(response.text)          job_messages = result['content']['positionResult']['result']          # 職位詳情頁URL獲取          job_urls = result['content']['hrInfoMap'].keys()          for k in job_urls:              url_1 = 'https://www.lagou.com/jobs/' + k + '.html'              print(url_1)              with open('job_urls.csv', 'a+', encoding='utf-8-sig') as f:                  f.write(url_1 + 'n')          for job in job_messages:              global count              count += 1              # 崗位名稱              job_title = job['positionName']              print(job_title)              # 崗位薪水              job_salary = job['salary']              print(job_salary)              # 崗位地點              job_city = job['city']              print(job_city)              # 崗位經驗              job_experience = job['workYear']              print(job_experience)              # 崗位學歷              job_education = job['education']              print(job_education)              # 公司名稱              company_name = job['companyShortName']              print(company_name)              # 公司類型              company_type = job['industryField']              print(company_type)              # 公司狀態              company_status = job['financeStage']              print(company_status)              # 公司規模              company_people = job['companySize']              print(company_people)              # 工作技能              if len(job['positionLables']) > 0:                  job_tips = ','.join(job['positionLables'])              else:                  job_tips = 'None'              print(job_tips)              # 工作福利              job_welfare = job['positionAdvantage']              print(job_welfare + 'nn')              add_Postgresql(count, job_title, job_salary, job_city, job_experience, job_education, company_name, company_type, company_status, company_people, job_tips, job_welfare)      if __name__ == '__main__':      get_message()

獲取拉勾網數據挖掘崗數據如下。

獲取到詳情頁的URL資訊後,直接點擊文件里的鏈接,並不會跳轉到詳情頁頁面。

需複製網址,粘貼到瀏覽器上,才能訪問成功。

具體原因我也不知道,可能和請求頭有關吧…

/ 03 / 數據可視化

01 工作經驗薪水圖

這裡1年以下的數據只有一個,所以直接去除。

探索多分類變數與連續變數間的關係,採用單因素方差分析。

原假設為工作經驗對薪水無顯著影響。

from scipy import stats  import pandas as pd  import psycopg2  # 獲取資料庫數據  conn = psycopg2.connect(database="lagou_job", user="postgres", password="774110919", host="127.0.0.1", port="5432")  cursor = conn.cursor()  sql = "select * from job"  df = pd.read_sql(sql, conn)  # 清洗數據,生成薪水列  dom = []  for i in df['job_salary']:      i = ((float(i.split('-')[0].replace('k', '').replace('K', '')) + float(i.split('-')[1].replace('k', '').replace('K', ''))) / 2) * 1000      dom.append(i)  df['salary'] = dom  # 去除無效列  data = df[df.job_experience != '不限']  # 生成不同工作經驗的薪水列表  exp = []  for i in ['應屆畢業生', '1-3年', '3-5年', '5-10年']:      exp.append(data[data['job_experience'] == i]['salary'])  # 單因素方差分析  print(stats.f_oneway(*exp))  # 得到的結果  F_onewayResult(statistic=34.8568474246936, pvalue=5.894831071529752e-20)

得到F值為34.85,P值接近於0,其中取顯著性水平為0.05。

所以拒絕原假設,即工作經驗會顯著影響薪水。

02 學歷薪水圖

這裡大部分崗位的學歷要求,為本科和碩士,極少部分為學歷不限和大專。

同上,也對學歷和薪水做假設,為無顯著差異。

# 去除無效列  data = df[df.job_education != '不限']  # 生成不同學歷的薪水列表  edu = []  for i in ['大專', '本科', '碩士']:      edu.append(data[data['job_education'] == i]['salary'])  # 單因素方差分析  print(stats.f_oneway(*edu))  # 得到的結果  F_onewayResult(statistic=5.29713465351118, pvalue=0.005345061949394161)

得到F值為5.29,P值為0.005,其中取顯著性水平為0.05。

所以拒絕原假設,即學歷會顯著影響薪水。

綜合兩個F值和P值,可以看出工作經驗比起學歷更能影響薪水。

那麼我們就通過有交互效應的多元方差分析來看看具體情況。

import statsmodels.formula.api as smf  import statsmodels.api as sm  import pandas as pd  import psycopg2  # 消除pandas輸出省略號情況及換行情況  pd.set_option('display.max_columns', 500)  pd.set_option('display.width', 1000)  # 獲取資料庫數據  conn = psycopg2.connect(database="lagou_job", user="postgres", password="774110919", host="127.0.0.1", port="5432")  cursor = conn.cursor()  sql = "select * from job"  df = pd.read_sql(sql, conn)  # 清洗數據,生成薪水列  dom = []  for i in df['job_salary']:      i = ((float(i.split('-')[0].replace('k', '').replace('K', '')) + float(i.split('-')[1].replace('k', '').replace('K', ''))) / 2) * 1000      dom.append(i)  df['salary'] = dom  # 去除學歷不限  data = df[df.job_education != '不限']  # 去除工作經驗不限及1年以下  data = data[data.job_experience != '不限']  data = data[data.job_experience != '1年以下']  # smf:最小二乘法,構建線性回歸模型  anal = smf.ols('salary ~ C(job_experience) + C(job_education) + C(job_experience)*C(job_education)', data=data).fit()  # anova_lm:多因素方差分析  print(sm.stats.anova_lm(anal))  # 基本資訊輸出  print(anal.summary())

輸出結果。

這裡看出學歷和工作經驗的交互項對薪水影響並不顯著。

其F值為1.33,P值為0.2,則無法拒絕原假設。

R²的值為0.277,說明工作經驗和學歷僅僅解釋了薪水變異性的27.7%。

R²的值大於0.8時,則說明模型擬合效果好,本次實驗看來是遠遠達不到要求了。

這是帶交互項的多元方差分析的回歸係數。

參考標準是工作經驗「1-3年」和學歷「 大專」。

按理說應該是選擇工作經驗「應屆畢業生」和學歷「 大專」做參考標準的。

這裡是由於我沒用數字對資訊進行歸類,導致這一現象出現,所以湊合著看吧!

從表中可以看出:

①「3-5年」的「 大專」較「1-3年」的「 大專」,P值為0.081,略大於0.05,說明兩種情況薪水差異較顯著。

②「5-10年」的「 大專」較「1-3年」的「 大專」,P值為0,說明沒有樣本。

③「應屆生」的「 大專」較「1-3年」的「 大專」,P值為0.911,說明兩種情況薪水無差異。

④「1-3年」的「本科」較「1-3年」的「 大專」,P值為0.021,說明兩種情況薪水差異顯著。

⑤「1-3年」的「 碩士」較「1-3年」的「 大專」,P值為0.012,說明兩種情況薪水差異顯著。

03 公司類型TOP10

數據挖掘崗也是集中在互聯網行業,「數據服務」「O2O」「金融」「電子商務」。

目前認識的數據挖掘大佬,還真是在「數據服務」「O2O」「金融」行業里。

04 工作技能圖

「數據挖掘崗」和「數據分析崗」都是相通的,你中有我,我中有你。

不過「數據挖掘崗」中演算法是第一位要求,更高級,更難學…