一个很恶心的现,:不管你在一家公司工作多久,无论你多忠诚,多卖力,一旦公司赚的少了那你就成了眼中钉,肉中刺
刚刷到个贴子,说不管你在公司干多久,多忠诚卖力,只要公司盈利下滑,你立马就成了眼中钉。
我觉得这事吧,说到底就是职场的本质:公司看的是价值,而不是情怀。网友有的感慨“人心凉薄”,但换个角度想,老板也在算账,本质上是用钱投票。你能带来收入,那就是香饽饽;一旦成本高于产出,再深的感情也抵不过一行报表📊。
不过话说回来,这现象虽然恶心,但也提醒我们别把“忠诚”当底气。职场不像婚姻,它更像租房子,房东今天觉得你合适就续租,明天嫌贵了就换人。网友里有人说“干脆别拼命”,我倒不全认同。努力当然要有,但同时要学会让努力可见,提升自己随时跳槽的筹码。【备注:文末可领最新资料】
面试题:低质量的问题
昨天晚上十一点多,在公司楼下抽烟…咳咳少抽,反正那会儿有点困,产品在群里丢了句:平台“低质量的问题”太多了,能不能用点算发…算法把这类问题先拦一拦。我一想这不就文本二分类嘛,但别上来就堆深度模型,先把能落地的小招数做起来,第二天不至于被追着打。对吧。
先把“低质量”说清楚,不然模型学不明白:太短(十几个字“帮忙急求”那种)、没有上下文(无代码无数据无环境)、关键词像是求资源/伸手党、重复标点拉满、还有那种“在线等”口水话。就是这些…不绝对,但够当第一层过滤。等等有人问训练集呢?没关系,先规则打底,模型兜底,能跑起来再说。
我回工位敲了个最小可用的 Python,小李在旁边还问我正则咋写,别打岔…先上代码,真的很短:
import re
from typing import Dict
STOPWORDS = {"怎么", "如何", "求", "急", "在线", "谢谢", "大神", "跪求"}
RESOURCE_WORDS = {"资料", "源码", "安装包", "完整项目", "网盘"}
CODE_HINTS = re.compile(r"```|class\s+\w+|def\s+\w+|;|{|\(|#include|public\s+static|SELECT\s+", re.I)
defscore_question(q: str) -> Dict[str, float]:
text = q.strip()
length = len(text)
punct_ratio = len(re.findall(r"[!??!]{1}", text)) / max(1, length)
upper_ratio = len([c for c in text if c.isupper()]) / max(1, length)
url_count = len(re.findall(r"https?://", text))
code_present = bool(CODE_HINTS.search(text))
stop_cnt = sum(w in text for w in STOPWORDS)
res_cnt = sum(w in text for w in RESOURCE_WORDS)
digit_ratio = len(re.findall(r"\d", text)) / max(1, length)
zh_ratio = len(re.findall(r"[\u4e00-\u9fa5]", text)) / max(1, length)
# 简单可解释的子分
s = 0.0
if length < 20: s += 2.0
if length < 8: s += 4.0
if punct_ratio > 0.05: s += 1.0
if stop_cnt: s += 1.0 + 0.5 * stop_cnt
if res_cnt: s += 1.5
ifnot code_present: s += 0.8# 技术问答里没最小复现就加分
if url_count andnot code_present: s += 0.5# 光丢链接也不行
if upper_ratio > 0.1: s += 0.5
if zh_ratio < 0.2and length < 40: s += 0.5# 非本语种短句
if digit_ratio > 0.3andnot code_present: s += 0.5
return {
"risk": s,
"length": length,
"has_code": float(code_present),
"punct_ratio": punct_ratio
}
defis_low_quality(q: str, threshold: float = 3.5) -> bool:
return score_question(q)["risk"] >= threshold
你们看意思就行,别拘泥分数,门槛 threshold 我是拿历史问题随手扫了几百条,手标了个大概…呃对,半自动调参,先糊住效果。核心点就是:用可解释的信号先把噪音压下去,比如“求源码!!”“在线等谢谢谢谢”,这些命中率离谱高。代码痕迹(`def/SELECT/``` 等)能显著降低风险分,哪怕描述一般,也给个机会。
有人问那重复/抄袭怎么办?我第二杯咖啡的时候加了个简单相似度去重,BM25 太重了就没上,先用字符 n-gram + Jaccard,够快:
defjaccard(a: str, b: str, n: int = 3) -> float:
defshingles(s):
s = re.sub(r"\s+", "", s)
return {s[i:i+n] for i in range(max(0, len(s)-n+1))}
A, B = shingles(a), shingles(b)
return len(A & B) / max(1, len(A | B))
deflooks_duplicate(q: str, recent: list, bar: float = 0.8) -> bool:
return any(jaccard(q, r) >= bar for r in recent[:200])
就是那个…效果咋样?凌晨一点做了个小评估,抽了 500 条历史问答,粗分三类:正常、可改进、低质。规则器召回“低质”大概 0.83,准确率 0.78,主要误杀是“新手一句话但附了截图”的那种,截图我们没解析到。临时补了个附件占位检测,误杀降了点。等等我接个电话…好了继续。
上线怎么接?别直接删帖,建议三段式:① 告警 → 弹窗引导“补充环境/日志/最小复现”,② 降权排序,不推首页,③ 允许申诉白名单。这个流程比粗暴拒绝更友好,也能反向“教育”用户把问题写完整。哦对,埋点要加:被拦截后用户是否补充、补充量多少、最终被采纳率,这些是后面训练监督模型的金矿。
有人问要不要搞个轻量学习器?可以,等规则稳定一周,把特征导出(长度、标点比、停用词计数、是否含代码、历史被采纳率、提问者信用分等),扔个 LogisticRegression 或 XGBoost 上去,规则分作为一个特征输入,冷启动也不丢。代码我就不贴了,库装起来麻烦,先把上面这套跑通吧。
行了我真的困了,总结…算了不总结,你们先把 is_low_quality 接到网关前做预判,门槛别设太狠,先 3.5,观察一周再说,出了锅别喊我名字就行。
-END-
我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html
虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》,总量高达650GB,点击下方公众号回复关键字 python 全部免费领