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 工作技能图

「数据挖掘岗」和「数据分析岗」都是相通的,你中有我,我中有你。

不过「数据挖掘岗」中算法是第一位要求,更高级,更难学…