先说明一下我做这个项目的背景很简单我所在的团队当时想搞清楚一件事——“大模型岗位到底需要什么样的人”。招聘网站上一堆JD写得天花乱坠光靠人眼翻根本看不过来而且每个岗位描述里都藏着技能要求、经验门槛、薪资区间这些关键信息要是能把这些信息结构化、量化再画成图直接呈现在管理层面前决策起来会顺畅很多。于是就有了这个项目用Python抓取并整理招聘数据用BERT模型做语义理解最后把所有分析结果做成可视化图表。整个项目跑完我能明确告诉你哪类技能最抢手、哪些城市释放的岗位最多、不同经验要求下的薪资分布长什么样。这篇文章我就把这个项目的完整链路拆开讲包括思路、代码、参数调整和坑尽量做到给你一份可以直接照着复现的参考。1. 项目全貌与思路拆解1.1 标题背后的真实需求不只是画几张图先别急着写代码我们把标题拆开看。这个项目的名字是“BERT模型基于Python的大模型岗位人才需求可视化分析”里面其实藏了三个独立但关联的需求。第一层需求是“岗位人才需求”这属于数据收集和业务理解问题。你需要知道大模型相关岗位有哪些类型比如算法工程师、训练工程师、推理优化工程师、Prompt工程师、RAG应用工程师、数据标注员甚至大模型产品经理。每种岗位的职责描述、技能要求、学历要求和薪资结构都不一样必须逐条拆清楚。第二层需求是“BERT模型基于Python”这是技术实现路径。BERT是预训练语言模型的代表它能捕捉文本上下文语义比传统的TF-IDF或词袋模型强太多。用人话解释传统方法看“会使用深度学习框架”和“精通PyTorch”会当成完全不同的词但BERT能理解这两句话在谈论同一个技能方向。这是文本向量化和智能分析的核心。第三层需求是“可视化分析”这是交付层。分析结果不能只停留在CSV表格里而是要通过柱状图、折线图、热力图、词云、关系图谱等形式让人一眼看懂哪类岗位最火、哪些技能需求在上涨、薪资待遇如何分布。我的建议是做任何数据分析项目先想清楚业务问题再决定模型选型最后再谈可视化。顺序反了很容易做成“为了用BERT而用BERT”的空壳项目。1.2 为什么选择BERT而不是其他文本方案做文本处理和分析有几种路径我分别试过给你对比一下方案优点缺点适合场景正则表达式速度快规则精确写起来累语义能力为零提取明确的薪资数值、学历关键词TF-IDF 余弦相似度无需训练可解释性强无法理解同义词、近义词粗粒度文档去重、关键词匹配Word2Vec能表达词向量无法处理一词多义忽略上下文基础的词汇相似度计算BERT上下文语义建模能力强迁移学习效果好需要GPU推理较慢文本分类、语义相似度、实体抽取大语言模型API能力最强自然语言理解非常灵活有成本数据出网有合规风险概念宽泛、规则难以覆盖的文本在这个项目里我需要完成两类核心任务一是把岗位描述转化成高维向量用于计算岗位之间的相似度二是做技能实体识别从自由文本里抽取“Python”“PyTorch”“分布式训练”等技能词。BERT对这两项任务都有天然优势。最直接的方案是直接用bert-base-chinese做句子级向量化。每个岗位JD经过BERT编码后会输出一个768维的向量。之后无论做聚类、相似度计算还是下游分类都是在这个向量空间里操作。为什么不用更新的模型如果你现在重新做一遍可以换成其他更新的中文预训练模型比如基于Transformer的各种开源中文模型。不过BERT依然值得一学——它结构清晰、资料多、部署生态成熟足够理解整套流程。项目跑通了换模型只是一行代码的事。1.3 系统流程总览整个项目的处理流程如下数据采集通过公开渠道抓取大模型相关岗位JD限定标题或描述中包含指定关键词。数据清洗去除HTML标签、空白字符、重复内容统一格式。字段解析用正则从文本中提取薪资范围、学历要求、经验要求。BERT语义处理用BERT做句子向量化和技能实体抽取。聚类与分类基于BERT向量做岗位类型聚簇结合业务经验打标签。可视化分析生成图表形成结论。后面每个环节我都会展开讲并且给出关键代码。2. 数据准备与预处理2.1 数据源选择与采集策略数据是分析的基础数据源选得不好后边做得再花哨都是白搭。我建议选主流的综合招聘平台和垂直类招聘社区抓取公开的职位搜索页面。这里有几个关键策略关键词覆盖要全面。只搜“大模型”这个词会漏掉大量信息。实际中很多岗位JD里写的是“LLM”“AIGC”“GPT应用开发”“生成式AI”等说法。建议准备一个关键词池keywords [大模型, LLM, AIGC, 生成式AI, 自然语言处理, GPT, Transformer, 深度学习, 机器学习, NLP]每个关键词单独抓取最后合并去重。去重时以“公司名称岗位名称发布时间”作为唯一键因为同一家公司可能在不同时间重复发布相同的岗位。分页和翻页控制要温和。别短时间猛请求一个站点容易触发反爬。我用的策略是每个页面之间sleep随机2到4秒请求头带上随机的User-Agent并且开启会话保持。采集过程本身不是这个项目的主角为了保证合规性和复现性我在模拟项目X中构建了一份模拟数据文件包含大约2000条大模型相关岗位记录每条记录包含公司、岗位名称、城市、薪资区间、经验要求、学历要求、岗位描述等字段。这样既绕开了数据合规问题又保证了整个分析链路是可复现的。提示如果你要采集真实平台的公开数据务必遵守平台robots协议和用户协议仅用于个人学习和研究不要用于商业用途更不要大规模采集。这个项目里的分析代码和逻辑不依赖于任何特定数据源换成自己的合法数据集一样能跑通。2.2 岗位文本的清洗与标准化原始JD文本里通常混着各种杂质比如“职位诱惑五险一金、弹性工作”、“发布于昨天”、“公司亮点AI独角兽”这些信息跟岗位技能关系不大。清洗步骤是必要的。清洗流程我分四步走第一步是去HTML标签。很多数据存的是网页源码用正则或者解析库处理掉div、span、p这类标签。第二步是统一空白。全角空格、换行符、制表符统一替换成半角空格连续多个空格合并成一个。第三步是去除无意义信息。像“公司地址北京朝阳区”这类键值对如果跟分析无关可以按规则剔除。经验总结保留“岗位职责”和“任职要求”两大段这是分析的核心内容其他内容存入单独字段但不再参与语义计算。第四步是文本截断。BERT输入上限是512个token中文大约700字左右再长的JD就需要截断或者分段。我的做法是优先保留“任职要求”段落因为技能词主要出现在那里。如果截段后还是超过长度对后半段做截断。import re import unicodedata def clean_jd_text(raw_text): # 去掉HTML标签 text re.sub(r[^], , raw_text) # 全角转半角 text unicodedata.normalize(NFKC, text) # 替换空白字符为空格 text re.sub(r\s, , text) # 去掉常见噪声词行 noise_patterns [ r职位诱惑[:].*?(\n|$), r发布时间[:].*?(\n|$), r公司地址[:].*?(\n|$), ] for pattern in noise_patterns: text re.sub(pattern, , text) return text.strip()2.3 结构化字段的解析除了花在语义处理上的功夫很多结构化信息其实用正则就能拿。薪资解析。中文岗位薪资常见格式是“15K-25K”“15k-25k·14薪”“2万-4万”“30K以上”。统一转成一个统一区间方便后面做统计和绘图def parse_salary(salary_str): if not isinstance(salary_str, str): return None, None m re.search(r(\d\.?\d*)\s*[Kk万]\s*[-~—至]\s*(\d\.?\d*)\s*[Kk万], salary_str) if m: low, high float(m.group(1)), float(m.group(2)) if 万 in salary_str: low, high low * 10, high * 10 return low, high m re.search(r(\d\.?\d*)\s*[Kk万]\s*以上, salary_str) if m: low float(m.group(1)) return low, low * 1.2 return None, None经验要求解析。常见值包括“不限经验”“1-3年”“3-5年”“5-10年”“10年以上”。直接映射成区间中值。学历要求解析。包括“大专及以上”“本科及以上”“硕士及以上”“博士”等映射成等级编码。这些结构化字段是后续可视化分析的基础比如分析不同学历要求的岗位数量分布或者不同经验要求对应的薪资中位数。3. 核心模型BERT语义分析与技能抽取3.1 BERT如何理解岗位文本BERT的原理可以简化成一句话它通过在大规模语料上做“完形填空”和“下一句预测”两个预训练任务学会了词汇在上下文里的真实含义。拿岗位文本举例“熟悉Python”和“精通Python”这两个短语如果让传统词向量方法处理公司名可能完全不同但在BERT里同一个“Python”会被编码进模型根据它后面跟着的动词不同向量的局部表示会有微妙差别——这样下游任务就能区分“会用”和“精通”是两种层次的能力要求。BERT的输入需要做三部分处理token嵌入、段嵌入、位置嵌入。在Python里用Transformers库处理这些封装得非常好不需要自己实现细节。我用的是bert-base-chinese可以从HuggingFace上直接加载。为什么选这个因为岗位描述是中文这个模型原生用中文预训练词表里囊括了大量中文常用词不需要额外做繁重的分词处理。3.2 岗位向量化的完整实现核心代码实际上很简单难的是怎么用好from transformers import AutoTokenizer, AutoModel import torch model_name bert-base-chinese tokenizer AutoTokenizer.from_pretrained(model_name) model AutoModel.from_pretrained(model_name) # 单条文本编码 def encode_jd(text, max_len128): inputs tokenizer( text, max_lengthmax_len, paddingmax_length, truncationTrue, return_tensorspt ) with torch.no_grad(): outputs model(**inputs) # 取CLS位置的输出作为句子级向量 cls_vec outputs.last_hidden_state[:, 0, :].squeeze().numpy() return cls_vec这里有一个实践细节取哪一层的向量不同层向量语义侧重点不同。我用过最后一层的CLS向量也用过倒数第二层还试过对最后四层做平均池化。实测下来最后四层平均池化的效果相对稳定更适合做相似度计算。实现方式如下def encode_jd_pool(text, max_len128, num_layers4): inputs tokenizer(text, max_lengthmax_len, paddingmax_length, truncationTrue, return_tensorspt) with torch.no_grad(): outputs model(**inputs, output_hidden_statesTrue) hidden_states outputs.hidden_states[-num_layers:] # 对指定层做均值池化 pooled torch.cat([h[:, 0, :].unsqueeze(0) for h in hidden_states], dim0) pooled pooled.mean(dim0).squeeze().numpy() return pooled向量化之后每个岗位变成768维向量。接下来可以做几件事计算岗位相似度找“相近岗位”对全部岗位做聚类看岗位自然分成哪几类作为下游分类模型的特征输入判断岗位方向3.3 技能实体抽取的两种路线分析技能需求的思路比较简单我提供两种路线你可以根据情况选择。路线A标准技能词典匹配。提前维护一个技能词典包含常见的编程语言、框架、工具和方向关键词。然后用BERT做语义匹配——注意这里的精髓是新增技能时也需要向量化后和岗位文本片段比对语义。实际项目里我用的是基于词典的快速匹配加上BERT语义辅助的混合方式skill_base [Python, Java, C, PyTorch, TensorFlow, Transformer, 分布式训练, 深度学习, 机器学习, NLP, GPU编程, CUDA, RAG, Prompt, LangChain, 向量数据库, 微调, LoRA, 推理加速, 量化压缩, 多模态, 强化学习] def extract_skills(jd_text, skill_list): found [] text_lower jd_text.lower() for skill in skill_list: if skill.lower() in text_lower: found.append(skill) return found这种方法简单可靠缺点是覆盖不了没收录的新技能所以需要定期补充词典。但用于业务分析已经够用。路线BBERT-CRF做序列标注。如果要做精细化抽取可以标注一批数据用BERT加CRF识别“技能”实体。这个方法的前期成本比较高——需要至少几万条人工标注数据但对复杂文本的抽取效果远超词典匹配。我做这个项目时采用的是路线A加人工修正理由是岗位JD里的技能词往往是标准化术语不需要复杂的实体识别就能找到词典能控制精确率减少误匹配。如果追求全自动、全召回路线B是更完整的方向。4. 可视化分析从数据到结论4.1 岗位类型分布有了结构化字段和语义向量可视化分析就顺理成章了。第一步是看整体情况大模型相关岗位的类别分布。这里我用聚类加业务规则混合分桶。简单做法是对BERT向量做K-Means聚类然后根据每个簇中高频词给簇命名from sklearn.cluster import KMeans # vectors 是所有岗位JD的768维向量矩阵 kmeans KMeans(n_clusters6, random_state42, n_init10) labels kmeans.fit_predict(vectors) # 对每个簇挑出高频技能词 for i in range(6): cluster_indices np.where(labels i)[0] skills_in_cluster [] for idx in cluster_indices[:50]: skills_in_cluster.extend(extract_skills(jd_texts[idx], skill_base)) top_skills Counter(skills_in_cluster).most_common(5) print(f簇{i}: {top_skills})聚类簇画成柱状图基本能看出哪一类岗位数量最多。我做出来的结果大致显示算法工程类、应用开发类、训练优化类岗位数量排名靠前提示词工程师和数据标注员也有不少需求。4.2 技能需求图谱技能需求是这类分析最受关注的部分。我用了两种图第一种技能频次条形图。对所有JD做技能抽取统计每个技能的频次取Top15画横向条形图。这个图表直观展示“哪个技能最缺人”。第二种技能共现关系图。如果变量“PyTorch”和“分布式训练”在多个JD里同时出现说明这两个技能高度关联。把所有词对计算共现频率超过阈值后画成关系图from collections import defaultdict import networkx as nx import matplotlib.pyplot as plt co_occur defaultdict(int) for skills in skills_per_jd: for i in range(len(skills)): for j in range(i1, len(skills)): co_occur[(skills[i], skills[j])] 1 G nx.Graph() for (a, b), cnt in co_occur.items(): if cnt threshold: G.add_edge(a, b, weightcnt) pos nx.spring_layout(G, k3, seed42) nx.draw(G, pos, with_labelsTrue, node_size800, font_size10) plt.show()图谱出来之后能看到很明显的现象深度学习、PyTorch、分布式训练、NLP这些技能节点聚集在核心区域RAG、LangChain、Prompt等新技能形成了次级热点。这说明企业要的人才不是单一技术而是“一主多辅”的复合结构。4.3 需求趋势和薪资分布分析有了时间字段后可以分析“大模型岗位需求近几个月的变化趋势”。按月统计发布的岗位数量画折线图。我观察到的一个明显趋势是应用开发类岗位数量在后期显著上升而单纯算法研究类岗位占比下降。这和企业大模型落地节奏吻合——先用算法人才打基础再大规模招应用开发人才做产品化。薪资分析按岗位类型分组绘制箱线图是最直观的方式。箱线图能看到每个岗位薪资的中位数、四分位数和异常值。我做出来大致的结论是算法训练类岗位薪资最高中位数明显高于其他岗位应用开发和产品类岗位薪资稍低但供给充足数据标注类岗位薪资分布较平天花板比较明显。毛利率般的结论我就不展开了每个数据集结果都有差异但你至少可以照这套方法画出下面这几张图岗位类别频次柱状图技能需求Top15条形图技能共现关系网络图各岗位薪资箱线图学历要求分布饼图需求数量月度趋势折线图经验要求与薪资交叉热力图5. 完整实操过程与代码实现5.1 环境准备与依赖安装我跑这个项目的硬件环境是一台常规的开发者笔记本等级设备没有独立GPU的话CPU也能跑只是慢一些。BERT模型推理在CPU上单条文本大约零点几秒整体2000条数据约十几分钟能跑完完全可接受。依赖包列表如下pip install pandas numpy matplotlib seaborn pip install scikit-learn pip install transformers torch pip install networkx pip install pyecharts需要留意的是torch和transformers的版本要兼容装的时候让pip自动解析就能解决。pyecharts用于生成交互式HTML图表matplotlib用于静态图。为什么同时用两套画图库matplotlib适合快速出图、贴到报告里pyecharts适合做交互展示、在浏览器里缩放看细节。我在汇报时用pyecharts写文档时用matplotlib。5.2 数据读取与预处理数据假设是CSV格式字段包括job_title、company、city、salary_text、experience、education、jd_text、publish_date。读取并做基础解析import pandas as pd df pd.read_csv(llm_jobs.csv, encodingutf-8-sig) print(df.shape, df.columns.tolist()) df[jd_clean] df[jd_text].apply(clean_jd_text) df[[salary_low, salary_high]] df[salary_text].apply( lambda x: pd.Series(parse_salary(x)) ) # 计算薪资中位值 df[salary_mid] (df[salary_low] df[salary_high]) / 2薪资解析完记得做一步类型检查数值类型的NaN会导致后续绘图报错统一用dropna处理。5.3 BERT编码批量执行批量编码时注意不要让内存爆掉。如果一次性把所有文本传进模型显存或内存会吃得非常紧。稳妥的做法是分batch处理from transformers import AutoTokenizer, AutoModel import torch import numpy as np def batch_encode(texts, batch_size16, max_len128): tokenizer AutoTokenizer.from_pretrained(bert-base-chinese) model AutoModel.from_pretrained(bert-base-chinese) model.eval() all_vectors [] with torch.no_grad(): for i in range(0, len(texts), batch_size): batch_texts texts[i:i batch_size] inputs tokenizer( batch_texts, max_lengthmax_len, paddingmax_length, truncationTrue, return_tensorspt ) outputs model(**inputs, output_hidden_statesTrue) hidden outputs.hidden_states[-4:] pooled torch.stack([h[:, 0, :] for h in hidden], dim0).mean(dim0) all_vectors.append(pooled.numpy()) return np.vstack(all_vectors) vectors batch_encode(df[jd_clean].tolist(), batch_size16) print(vectors.shape) # (N, 768)小细节model.eval()是必须的模型会关闭Dropout保证推理结果稳定。5.4 聚类与标签生成聚类数怎么定我试了肘部法则同时结合实际业务判断。大模型岗位通称多、分类粗6到8类是合理的范围from sklearn.cluster import KMeans from sklearn.metrics import silhouette_score def find_best_k(vectors, k_rangerange(4, 15)): scores [] for k in k_range: km KMeans(n_clustersk, random_state42, n_init10) labels km.fit_predict(vectors) sil silhouette_score(vectors, labels) scores.append((k, sil)) best_k, best_score max(scores, keylambda x: x[1]) return best_k, best_score best_k, score find_best_k(vectors) print(f最佳聚类数: {best_k}, 轮廓系数: {score:.3f})轮廓系数选出的簇数结合簇内Top技能词做人工校验最终我定格在6类。5.5 关键图表的绘制技能Top15条形图import matplotlib.pyplot as plt from collections import Counter skill_series df[skills].explode() skill_counter Counter(skill_series.dropna()) top15 skill_counter.most_common(15) skills [x[0] for x in top15][::-1] counts [x[1] for x in top15][::-1] plt.figure(figsize(10, 6)) plt.barh(skills, counts, color#2b6cb0) plt.xlabel(出现频次) plt.title(大模型岗位技能需求Top15) plt.tight_layout() plt.savefig(skill_top15.png, dpi150) plt.show()个人经验条形图用水平布局便于技能名称完整显示不会互相遮挡。薪资与经验交叉热力图import seaborn as sns # 经验等级映射 exp_map {不限经验: 0, 1年以下: 1, 1-3年: 2, 3-5年: 3, 5-10年: 4, 10年以上: 5} df[exp_level] df[experience].map(exp_map) pivot df.pivot_table(indexexp_level, columnseducation, valuessalary_mid, aggfuncmedian) sns.heatmap(pivot, annotTrue, fmt.1f, cmapYlOrRd) plt.xlabel(学历要求) plt.ylabel(经验要求) plt.title(不同学历经验要求的薪资中位数) plt.tight_layout() plt.savefig(salary_heatmap.png, dpi150)技能共现网络我在上面的章节已经给出了代码注意阈值设置。阈值太低图就是一团乱麻阈值太高图就没几个点。实际操作中我先看共现频次的分布取P75百分位左右作为阈值效果比较均衡。5.6 词云辅助分析另一项工作生成词云用来直观展示岗位描述里最常出现的关键词。词云可以用wordcloud库from wordcloud import WordCloud all_text .join(df[jd_clean].tolist()) wc WordCloud(font_pathsimhei.ttf, width800, height500, background_colorwhite, max_words100) wc.generate(all_text) wc.to_file(jd_wordcloud.png)注意中文词云必须指定中文字体路径否则中文会显示成方块。我就是被这个坑过。6. 常见问题与排查技巧实录6.1 典型问题和排查方案汇总问题现象可能原因排查与解决方案BERT推理时CUDA内存不足batch_size太大或者显存被其他进程占用降低batch_size为8或4使用torch.cuda.empty_cache()释放缓存切换到CPU跑中文显示为乱码或方块Matplotlib或WordCloud缺少中文字体指定系统已安装的中文字体路径比如在macOS上用/System/Library/Fonts/PingFang.ttc聚类结果很差所有岗位归为一类向量分布过于集中或没有对向量做归一化编码前做好文本清洗对向量做L2归一化尝试调整聚类数技能抽取频次整体偏低技能词典覆盖不全很多新词没匹配上定期补充词典或用BERT语义相似度先定位包含技术方向的句子再人工确认薪资中位值出现明显的离群值解析时“万”与“K”混用没分清回顾parse_salary中单位判断逻辑做成单元测试用例对常见格式做验证大批量编码耗时太长用CPU逐条编码batch_size过小增大batch_size有多个CPU核时调整PyTorch线程数文本超过512个token被截断长JD被强行截断可能导致尾部的关键要求丢失优先保留“任职要求”段落并把最长输入限制放宽到512考虑分段向量后加权平均6.2 必须避开的几个坑坑一BERT向量直接做相似度计算前不归一化。我一开始直接把原始768维向量做余弦相似度结果发现大部分数据相似度都很高区分度很低。原因是向量模长不一致对余弦值影响没有体现充分。解决办法是先对向量做L2归一化再做后续计算。效果立竿见影。坑二所有JD一股脑儿塞进模型不处理空值和异常值。我吃过一次亏某公司JD字段是空的清洗后得到一个空字符串BERT照样编码出一个固定向量。这导致一条无效样本影响了聚类结果。所以对空值要提前dropna()或者用占位符“无描述”替代。坑三过早投入复杂模型基础统计没做透。我刚开始做这个项目时直接开始调BERT后来发现其实简单的字段统计已经能回答一部分业务问题。正确的做法是先用pandas把薪资、地域、学历、经验这些结构化字段都查一遍形成初步结论再用BERT处理非结构化文本做补充分析。两层结合才能得到更完整的结论。6.3 关于模型结果的可信度分析岗位数据时还有一点很重要模型输出的相似度、聚类标签并不等于业务事实。比如BERT能识别出“RAG”和“向量数据库”强相关但它不会告诉你这个关系是否已经成为行业标配。我的习惯做法是每个模型产出结果都人工抽检。聚类结果抽10条样本看是否符合业务常识技能抽取结果人工数100条看准确率大约在多少。如果准确率在80%以上这个结果就可以拿来辅助判断低于这个线需要再优化词典或预处理方式。6.4 效率优化的补充建议如果JD数量达到几万甚至上十万逐条调用BERT的开销就变大了。这时候有两个优化方向第一用batch推理加大吞吐量。把编码批次从16提高到32或64充分利用显存。单卡显存有限时可以用torch.utils.data.DataLoader做流水线处理。第二考虑缓存。对清洗后的文本先做去重同一条JD只编码一次其他重复记录直接用索引映射能省下大量重复计算。第三如果对延迟要求高可以把BERT模型转成ONNX格式推理速度能快不少。我做这个项目时CPU推理时间是0.3秒一条转ONNX之后下降到0.1秒左右。这个优化在数据量大的场景下非常划算。7. 数据伦理与合规建议做招聘数据相关项目有一些合规细节一定要留意。第一数据采集务必在公开允许的范围内进行不绕过登录权限、不暴力抓取、不利用漏洞获取非公开数据。第二个人敏感信息处理要严格。招聘数据里往往包含联系人邮箱、手机号码这些信息分析过程中尽量脱敏保留公司和岗位信息即可。第三分析结论不要为歧视性决策提供依据。比如在不同地域、性别、年龄等维度上的统计结果只能用于了解市场情况不能用来设计任何可能涉及歧视的筛选策略。这些不只是法律要求也是数据分析从业者应有的底线。8. 项目延伸的三种玩法如果你照着这篇文章把项目跑通了其实还有很多值得深挖的方向。第一种是加时间维度做需求预测。把每月岗位数量、技能出现频次组成时间序列用预测模型预测下个月哪种技能需求会增长。这对个人学习和企业招聘策略都有参考价值。第二种是做“岗位匹配系统”。把候选人的简历文本也用BERT编码成向量计算简历和岗位的相似度做一个简单的推荐系统。相似度可以用余弦距离也可以接一层全连接网络做排序。第三种是接入更多数据源。不只分析招聘数据还可以分析GitHub上的项目、论文、技术社区的热门话题把这几个维度联合起来就可以更全面地看清大模型行业的人才需求版图。我自己做下来的感受是BERT在这个项目里不是主角它是个得力的工具真正核心的是一套能把“文本里的信息抽出来、整理成图谱和数字”的思维方式。把数据链路走通之后换任何一个文本分析场景这套方法论都能直接迁移过去。最后再分享一个小细节项目做完交付时我把所有图表都做成了动态交互版汇报现场点击技能节点看关联岗位效果确实比静态图好很多。如果时间有限优先做交互式图表收获感会强很多。
阅读完成 · 觉得有帮助?