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

「数据挖掘岗」和「数据分析岗」都是相通的,你中有我,我中有你。
不过「数据挖掘岗」中算法是第一位要求,更高级,更难学…