大数据岗位招聘数据采集与特征工程实践报告一、项目概述1.1 项目背景随着大数据技术的快速发展企业对大数据人才的需求日益增长。本项目旨在通过爬虫技术采集主流招聘网站的大数据相关岗位信息并进行深度特征工程分析为企业人才招聘和个人职业规划提供数据支持。1.2 技术目标采集智联招聘、BOSS直聘、拉勾网等平台的大数据岗位信息构建包含岗位名称、薪资、地点、要求、技能等关键字段的数据集实现自动化批量采集与数据清洗进行深度特征工程提取关键特征二、数据采集实现2.1 技术选型# 核心工具库 - DrissionPage: 自动化浏览器控制 - pandas: 数据处理 - jieba: 中文文本分词 - sklearn: 特征工程 - matplotlib: 数据可视化2.2 数据源分析数据来源: 智联招聘(zhaopin.com)、BOSS直聘(zhipin.com)、拉勾网(lagou.com) 采集字段: 1. 岗位基础信息: 职位名称、公司名称、工作地点 2. 薪资信息: 薪资范围、薪资结构 3. 要求信息: 学历要求、工作经验、发布日期 4. 技能要求: 技术要求、工具要求、证书要求 5. 公司信息: 公司规模、行业领域、融资阶段2.3 爬虫实现代码from DrissionPage import ChromiumPage import pandas as pd import time import re from datetime import datetime class BigDataJobCrawler: def __init__(self): self.dp ChromiumPage() self.jobs_data [] def crawl_zhaopin(self, keyword大数据, pages10): 采集智联招聘数据 for page in range(1, pages 1): url fhttps://sou.zhaopin.com/?jl北京kw{keyword}p{page} self.dp.get(url) time.sleep(2) # 解析职位列表 job_list self.dp.eles(css:.joblist-box__item) for job in job_list: try: job_info { source: 智联招聘, title: job.ele(css:.jobname__title).text, company: job.ele(css:).text, salary: job.ele(css:.job-salary).text, location: job.ele(css:.job-area).text, experience: self.extract_experience(job), education: self.extract_education(job), skills: self.extract_skills(job), post_time: datetime.now().strftime(%Y-%m-%d), url: job.ele(css:a).attr(href) } self.jobs_data.append(job_info) except Exception as e: print(f解析失败: {e}) continue def save_to_csv(self, filenamebigdata_jobs.csv): 保存数据到CSV df pd.DataFrame(self.jobs_data) df.to_csv(filename, indexFalse, encodingutf-8-sig) print(f数据已保存到 {filename}共 {len(df)} 条记录) # 执行爬虫 crawler BigDataJobCrawler() crawler.crawl_zhaopin(pages5) crawler.save_to_csv()三、特征工程实现3.1 数据清洗与预处理import pandas as pd import numpy as np import jieba from sklearn.preprocessing import LabelEncoder, MinMaxScaler class JobFeatureEngineering: def __init__(self, data_path): self.df pd.read_csv(data_path) self.feature_df pd.DataFrame() def clean_salary(self): 清洗薪资字段提取数值特征 def parse_salary(salary_str): pattern r(\d\.?\d*)-(\d\.?\d*)万/月|(\d)-(\d)K match re.search(pattern, str(salary_str)) if match: if match.group(1): # 万/月格式 min_sal float(match.group(1)) * 10 max_sal float(match.group(2)) * 10 else: # K格式 min_sal float(match.group(3)) max_sal float(match.group(4)) return (min_sal max_sal) / 2, max_sal - min_sal return np.nan, np.nan self.df[[salary_avg, salary_range]] pd.DataFrame( self.df[salary].apply(parse_salary).tolist(), indexself.df.index ) def extract_experience_level(self): 提取工作经验等级 exp_map { 不限: 0, 经验不限: 0, 应届生: 0, 1年以内: 1, 1-3年: 2, 3-5年: 3, 5-10年: 4, 10年以上: 5 } self.df[exp_level] self.df[experience].map(exp_map).fillna(0) def process_skills(self): 处理技能要求提取技术栈特征 # 定义大数据技术关键词 tech_keywords { hadoop: [hadoop, hdfs, mapreduce], spark: [spark, sparksql, sparkstreaming], flink: [flink, flinksql], kafka: [kafka], hive: [hive], hbase: [hbase], python: [python], java: [java], scala: [scala], sql: [sql, mysql, oracle], linux: [linux, shell] } for tech, keywords in tech_keywords.items(): pattern |.join(keywords) self.df[fskill_{tech}] self.df[skills].str.contains( pattern, caseFalse, naFalse ).astype(int) def extract_location_features(self): 提取地理位置特征 # 城市等级划分 tier1_cities [北京, 上海, 广州, 深圳] tier2_cities [杭州, 南京, 成都, 武汉, 西安] self.df[city_tier] self.df[location].apply( lambda x: 1 if any(city in str(x) for city in tier1_cities) else 2 if any(city in str(x) for city in tier2_cities) else 3 ) def encode_categorical_features(self): 编码分类特征 categorical_cols [education, company_size, industry] encoders {} for col in categorical_cols: if col in self.df.columns: le LabelEncoder() self.df[f{col}_encoded] le.fit_transform( self.df[col].fillna(未知) ) encoders[col] le def normalize_features(self): 特征标准化 numeric_cols [salary_avg, salary_range, exp_level] scaler MinMaxScaler() self.df[numeric_cols] scaler.fit_transform( self.df[numeric_cols].fillna(0) ) def extract_text_features(self): 从职位描述中提取文本特征 # 分词并统计关键词频 stopwords set([的, 了, 和, 是, 在, 等, 有, 与]) def extract_keywords(text): if pd.isna(text): return [] words jieba.lcut(str(text)) return [w for w in words if len(w) 1 and w not in stopwords] self.df[keywords] self.df[skills].apply(extract_keywords) # 统计热门技能词频 from collections import Counter all_keywords [] for keywords in self.df[keywords]: all_keywords.extend(keywords) keyword_counts Counter(all_keywords) top_keywords [k for k, v in keyword_counts.most_common(20)] # 创建技能词特征 for keyword in top_keywords: self.df[fkw_{keyword}] self.df[keywords].apply( lambda x: 1 if keyword in x else 0 ) def engineer_all_features(self): 执行完整的特征工程流程 print(开始特征工程处理...) # 1. 数据清洗 self.clean_salary() self.extract_experience_level() # 2. 特征提取 self.process_skills() self.extract_location_features() self.extract_text_features() # 3. 特征编码与标准化 self.encode_categorical_features() self.normalize_features() # 4. 特征选择 feature_cols [ salary_avg, salary_range, exp_level, city_tier, education_encoded, company_size_encoded, industry_encoded ] # 添加技能特征 skill_cols [col for col in self.df.columns if col.startswith(skill_)] kw_cols [col for col in self.df.columns if col.startswith(kw_)] all_feature_cols feature_cols skill_cols kw_cols self.feature_df self.df[all_feature_cols] print(f特征工程完成共生成 {len(all_feature_cols)} 个特征) return self.feature_df3.2 特征重要性分析from sklearn.ensemble import RandomForestRegressor import matplotlib.pyplot as plt def analyze_feature_importance(features, target): 分析特征重要性 # 使用随机森林评估特征重要性 rf RandomForestRegressor(n_estimators100, random_state42) rf.fit(features.fillna(0), target) # 获取特征重要性 importances rf.feature_importances_ indices np.argsort(importances)[-20:] # 取前20个重要特征 # 可视化 plt.figure(figsize(10, 8)) plt.title(大数据岗位特征重要性分析) plt.barh(range(len(indices)), importances[indices]) plt.yticks(range(len(indices)), features.columns[indices]) plt.xlabel(特征重要性) plt.tight_layout() plt.savefig(feature_importance.png, dpi300) plt.show() return importances四、数据分析与应用4.1 数据探索性分析import seaborn as sns import matplotlib.pyplot as plt def exploratory_analysis(df): 执行探索性数据分析 # 1. 薪资分布分析 plt.figure(figsize(12, 6)) plt.subplot(1, 2, 1) sns.histplot(df[salary_avg].dropna(), bins30, kdeTrue) plt.title(平均薪资分布) plt.xlabel(平均薪资(千元)) plt.subplot(1, 2, 2) city_salary df.groupby(city_tier)[salary_avg].mean() city_salary.plot(kindbar) plt.title(不同城市等级的平均薪资) plt.xlabel(城市等级) plt.ylabel(平均薪资) plt.tight_layout() plt.savefig(salary_analysis.png, dpi300) # 2. 技能需求分析 skill_cols [col for col in df.columns if col.startswith(skill_)] skill_demand df[skill_cols].sum().sort_values(ascendingFalse) plt.figure(figsize(10, 6)) skill_demand.plot(kindbarh) plt.title(大数据技能需求热度) plt.xlabel(岗位数量) plt.tight_layout() plt.savefig(skill_demand.png, dpi300) # 3. 学历要求分析 if education in df.columns: plt.figure(figsize(8, 6)) df[education].value_counts().plot(kindpie, autopct%1.1f%%) plt.title(学历要求分布) plt.ylabel() plt.tight_layout() plt.savefig(education_dist.png, dpi300)4.2 构建岗位推荐系统from sklearn.metrics.pairwise import cosine_similarity from sklearn.feature_extraction.text import TfidfVectorizer class JobRecommender: def __init__(self, job_data): self.job_data job_data self.tfidf_vectorizer TfidfVectorizer(max_features1000) def build_recommendation_model(self): 构建基于内容的推荐系统 # 合并技能和描述信息 job_texts self.job_data[skills].fillna() \ self.job_data[title].fillna() # 计算TF-IDF特征 self.tfidf_matrix self.tfidf_vectorizer.fit_transform(job_texts) def recommend_jobs(self, skills, n5): 基于技能推荐岗位 query_vec self.tfidf_vectorizer.transform([skills]) # 计算相似度 similarities cosine_similarity(query_vec, self.tfidf_matrix).flatten() # 获取最相似的岗位 top_indices similarities.argsort()[-n:][::-1] recommendations [] for idx in top_indices: job self.job_data.iloc[idx] recommendations.append({ title: job[title], company: job[company], salary: job[salary], similarity: similarities[idx], url: job.get(url, ) }) return recommendations