ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

LLM用户画像分析系统实战:多源数据融合、动态标签与情感识别

LLM用户画像分析系统实战:多源数据融合、动态标签与情感识别 简介这套基于大语言模型的智能用户画像分析系统资料面向企业用户运营、精准营销与个性化推荐场景适合中高级数据挖掘工程师、算法工程师及产品分析人员参考学习。包内共28个文件以16个Python源码为主干覆盖应用启动、数据端、LLM客户端、核心API等模块并配有多份Markdown说明文档、工程配置与依赖锁定文件及附赠资源压缩包整体144KB目录结构清晰便于快速定位源码和使用说明。已有282人学习下载。资料展示了用户行为分析、情感识别、消费习惯挖掘、价值观推断、动态标签生成与多源数据融合的完整实现路径同时说明了结构化与非结构化数据的处理方式并提供从数据接入、模型调用到动态标签输出的可运行代码框架可作为企业级用户洞察与推荐系统的实战参考也为相关课题研究和工程落地提供了完整参照。1. 先别急着上模型LLM用户画像分析系统到底解决什么问题先别急着上模型。很多用户画像项目标签体系建了上千个实际使用率不到两成原因是画像几乎全部来自结构化字段——性别、年龄、消费金额、活跃时段——工单里的抱怨、会话里的顾虑这些非结构化文本全被丢掉了。这不是数据不重要而是传统规则管线根本吃不动文本。基于大语言模型LLM的智能用户画像分析系统就是把自然语言处理这条腿接进传统画像管线读评论、读工单、读行为日志让LLM承担情感识别、消费习惯挖掘、价值观推断并动态生成标签。它回答的核心问题不再是“用户是谁”而是“用户为什么这么做”。本文按一套可落地的路径展开多源数据融合、标签生成、任务实现、调参与排错。2. 多源数据融合与动态标签生成画像系统的两条命脉2.1 多源数据怎么融合结构化与非结构化数据的对齐思路画像数据来源通常分两类结构化表格交易记录、会员信息、行为埋点和非结构化文本工单、评论、客服会话。两者最大的问题不是格式差异而是用户ID不统一。同一个用户在小程序里叫open_id在APP里叫device_id在订单库里叫手机号直接join会丢掉大量关系。常见做法是建立统一身份映射表把各端身份key收敛到一个主键上主键优先选手机号或union_id这类跨端稳定字段匿名设备ID作为补充归并而不是反过来。下面是用pandas做多源对齐的最小示例import pandas as pd behavior pd.read_json(behavior_log.jsonl, linesTrue) txn pd.read_csv(txn_records.csv) # 1. 统一用户ID有user_uid用user_uid匿名用户回退到device_id behavior[user_key] behavior[user_uid].fillna(behavior[device_id]) # 2. 时间格式对齐行为日志是毫秒时间戳交易是datetime behavior[event_time] pd.to_datetime( behavior[ts], unitms, utcTrue ).dt.tz_convert(Asia/Shanghai) txn[txn_time] pd.to_datetime(txn[pay_time]) # 3. 按用户分组把交易对齐到最近一次行为事件容忍15分钟窗口 merged pd.merge_asof( behavior.sort_values(event_time), txn.sort_values(txn_time), left_onevent_time, right_ontxn_time, byuser_key, tolerancepd.Timedelta(15min), directionnearest )逻辑说明fillna保证了匿名用户也能有一个稳定key用于后续对齐时间统一到东八区避免按天聚合时出现跨时区错位。merge_asof是“最近邻”连接和普通join不同它不会把一个用户的所有交易全铺开而是取时间距离最近的记录这样后续计算消费习惯时不会因为一对多膨胀导致同一行为被重复计数。参数说明tolerance15min定义了行为与交易的最大匹配间隔小于这个间隔才认为是同一意图链directionnearest表示向前和向后都找避免行为发生在支付之后就对不上。这个窗口不是越大越好超过30分钟容易把两个独立意图混成一个。文本数据的融合不能只靠拼接需要保留来源字段。我一般会把每条文本补上来源类型comment、ticket、chat和发生时间再按user_key聚合。来源类型非常重要用户在评论区说“价格太贵”和在工单里说“价格太贵”指向的决策完全不同——评论是公开表达工单是实际诉求。后续Prompt里需要区分这两种上下文模型才能给出不同力度的消费习惯和情感判断。2.2 用Prompt约束LLM产出结构化标签JSON Schema与Few-shot融合完数据下一步是让LLM产出画像标签。直接让模型“分析一下这个用户”会得到一大段散文没法进标签系统。常见做法是要求输出严格JSON并在Prompt里声明字段含义和取值范围。一个可用的模板如下PROFILE_PROMPT 你是用户洞察分析师。请根据提供的用户上下文输出用户画像标签。 只输出JSON不要任何前后缀说明。JSON必须符合 { user_id: string, tags: [ { name: string, category: behavior | emotion | value | consume, confidence: 0.0, evidence: 原文摘录 } ], intent: 一句话描述当前核心意图 } category解释 - behavior从行为日志观察到的规律 - emotion从文本中识别出的情感状态 - value从强证据中推断的价值观倾向 - consume消费习惯相关标签 用户上下文 {context} 这一模板的关键点有三个。第一category枚举把标签限制在四个可消费的类别里下游按类别路由不会出现无法归类的杂散标签第二confidence让模型给自己打分后续用阈值过滤低置信度噪音这比事后再用规则清洗要省力第三evidence要求模型必须摘录原文或指出数据依据这是审计和排查幻觉的抓手。Prompt末尾那句“从强证据中推断”是在刻意压价值观推断的胆子——我给模型的任务是保守不是发散。调用时配合低温度和强制JSON输出from openai import OpenAI import json client OpenAI( base_urlhttp://127.0.0.1:8000/v1, # 本地部署的兼容服务 api_keyEMPTY ) resp client.chat.completions.create( modelqwen2.5-14b-instruct, messages[ {role: system, content: PROFILE_PROMPT}, {role: user, content: context_text} ], temperature0.1, response_format{type: json_object} ) profile json.loads(resp.choices[0].message.content)temperature设0.1是为了让同一段文本每次产出的标签尽量稳定如果用的是本地vLLM部署的OpenAI兼容接口response_format可以强制走json_object模式比事后用正则抽JSON稳得多。标签不是越丰富越好模板里只给了一个示例tag实际输出一般不会超过5个这比在Prompt里硬写“最多5个标签”更自然模型会按示例格式自行收敛。2.3 动态标签生成从一次性打分到生命周期管理画像系统里最容易被低估的是标签的时效性。用户上个月是“价格敏感型”这个月可能已经买了高端机型。常见做法是两种触发方式结合事件触发用户产生新行为、新文本时增量更新和T1定时全量刷新兜底处理沉睡用户。事件触发优先定时刷新只作为补偿。环节参数建议值说明更新触发event_driven新文本/新交易产生时增量计算不重算全量置信度阈值confidence_threshold0.6低于阈值的标签不进正式标签库标签过期ttl_days45天超过45天无新证据的标签降权版本保留max_versions7保留近7天版本用于对比与回滚缓存策略cache_ttl1小时相同上下文的LLM结果缓存复用标签的生命周期分四段候选新产出、低置信度、正式过阈值、有证据、衰减TTL内无新证据、归档被新版本替代或长期未命中。归档不是删除保留历史标签对事后分析用户决策路径有参考价值。动态的另一层含义是标签本身可以被修正。比如置信度0.55的候选标签隔天用户发了一条与标签矛盾的工单系统应触发重新计算而不是继续累积。所以每个标签要带上updated_at和evidence_version两个字段重算后如果结论变了旧标签进归档新标签进正式区。这样做还有一个好处——下游业务方能看到标签的新鲜度不会拿三个月前的画像做今天的营销判断。3. 行为分析、情感识别与价值观推断三类LLM任务怎么落地3.1 行为分析从点击流事件到用户意图链行为日志本质是事件序列page_view、click、stay、search、add_cart。传统做法是对序列做统计——页面PV、停留时长、转化率——这些指标能描述“做了什么”但解释不了“为什么做”。LLM在这里的角色是把最近N个事件组合成上下文推测用户的临时意图再把意图传回给推荐或客服系统。常见做法是构造一个“意图窗口”取用户最近30个行为事件按时间正序拼成文本让LLM输出一句话意图。窗口大小是权衡点太短读不出跨页面逻辑太长噪音多、token成本高。我一般默认30重点用户频繁访问但未下单再扩到50。def build_behavior_context(user_events, max_events30): events user_events.sort_values(event_time)[-max_events:] lines [] for _, e in events.iterrows(): lines.append(f{e[event_time].strftime(%H:%M)} {e[event_name]} {e.get(page, )}) return \n.join(lines) behavior_prompt 以下是用户最近的行为事件序列按时间顺序排列。 请推断用户当前的核心意图只输出一句话不要罗列行为。 intent llm_call(behavior_prompt \n build_behavior_context(user_events))这段代码做了两件事按时间排序后截取最近30个事件再拼成带时间戳的文本。时间戳保留到分钟级就够不需要秒减少token噪音。max_events按场景调整对浏览型产品30合适对低频高客单价产品比如B2B采购窗口可以放宽到50甚至100因为用户决策周期长、事件密度低。与规则系统相比LLM能发现跨页面的意图链。比如一个用户先看了三篇产品对比评测再搜“保修政策”规则系统只会记下“评测内容高活跃”LLM能推断出“该用户处于决策后期在评估售后风险”。这个意图链信息可以直接给到客服弹窗或推荐位排序比单纯的行为统计更接近业务动作。3.2 情感识别评论文本的维度划分与强度打分情感识别最容易翻车的是只做正负二分类。真实业务场景里“失望”和“愤怒”对应的客服处置完全不同“期待”和“认可”对应的运营动作也不一样。我一般让LLM输出四到五个情感维度不满、焦虑、期待、认可、中立每个维度带1到5的强度分并强制输出trigger字段作为证据。SENTIMENT_PROMPT 分析以下会话中用户的情感状态。 输出JSON { emotions: [ {emotion: 不满|焦虑|期待|认可|中立, intensity: 3, trigger: 原文摘录} ] } 要求 - emotion只能取枚举值 - intensity为1到5的整数1极弱5极强 - trigger必须是从原文中复制的片段长度不超过50字 - 没有依据的情感不要输出 会话内容 {session_text} 强度分比单纯分类更有用。比如“不满”强度为4以上时系统应该把工单提升优先级强度为2则可能只是随口抱怨进常规队列即可。多维度输出还有一个好处——用户可以同时“焦虑”和“期待”只分出单类的模型会丢掉这种复杂状态。识别反讽是情感识别最大的坑。用户写“你们物流真快啊三天了还在本地中转”字面是夸实际是骂。单句截断基本必翻车解决办法是把最近多轮会话合并成上下文再分析不能只喂一条句子。这部分在后面的避坑章节展开讲。3.3 价值观推断高风险任务怎么降噪价值观推断是这份标题里最“玄学”的任务。消费习惯可以观察到情感可以从文本里识别但价值观只能推断——模型不可能直接看到用户的价值观。LLM在这里能做的是“从强证据中做有限归纳”比如用户连续六次在评论里强调“性价比”模型可以推断“实用主义倾向”但置信度应该打低。价值观标签的默认置信度阈值要比其他类别高。行为标签0.6可进正式库情感标签0.65价值观我建议0.75起步而且必须同时满足两个条件一是证据来自原文摘录而非模型推测二是证据条数不少于2条。单个文本片段撑不起任何价值观结论。降噪的另一个手段是限制价值观标签的输出范围。不要开放“用户是什么样的人”这种表述而是限定在可行动的类型实用主义、品牌偏好、风险厌恶、环保意识、社交驱动。每个类型在Prompt里给出定义和反例减少模型自由发挥的空间。模型对价值观的输出越模糊越不能用宁可漏标也不能硬造。4. 消费习惯挖掘与客户分层标签怎样变成业务动作4.1 消费习惯挖掘统计特征加LLM解读消费习惯这个标签建议先用传统统计方法算特征再让LLM做解读别直接拿交易流水让LLM“看”。原因有二一是交易数据量大直接全量塞Prompt成本高二是统计特征已经具备业务含义LLM解读起来更稳。我一般先算四组特征品类覆盖用户涉及多少个品类类目、复购周期同类商品两次购买间隔的中位数、客单价带订单金额的中位数和四分位区间、价格敏感度促销订单占比。样本量约束是前提注意消费次数少于3次的用户不进入消费习惯挖掘证据不足时宁可跳过也不能硬造消费习惯标签。import pandas as pd # 假设 txn 已按 user_key 归一化并过滤历史数据 txn txn[txn[user_key].isin(active_users)] consume_feat txn.groupby(user_key).agg( order_cnt(order_id, nunique), category_cnt(category, nunique), median_amount(amount, median), promo_ratio(promo_flag, mean), ) # 复购周期同类目两次购买间隔的中位数天 txn txn.sort_values(pay_time) gap txn.groupby([user_key, category])[pay_time].diff().dt.days consume_feat[repurchase_gap] gap.median(leveluser_key) # 样本量约束不足3次消费不挖消费习惯 consume_feat consume_feat[consume_feat[order_cnt] 3]聚合之后把特征按模板交给LLM解读一个典型输入是用户近90天消费特征订单数8覆盖3个品类客单价中位数420元 促销占比0.25复购周期中位数21天。 请概括该用户的消费习惯输出3条以内每条不超过30字。模型的输出一般是“中客单价、促销敏感度低、跨品类探索型”这类概括。这里有个参数要注意复购周期取了中位数而不是均值因为少数用户会有一单异常大的间隔比如退款后隔半年再买会把均值拉偏中位数对异常值更稳。促销占比这里用的是小样本均值的自然结果0.25代表四单里有一单用了促销。4.2 客户分层与画像服务化下游系统怎么消费标签画像系统做出来不给下游用就是摆设。常见做法是把标签服务化提供一个轻量的HTTP接口下游CRM、推荐、客服系统按user_key查询。标签进服务前要做一层过滤置信度低于阈值的标签不返回取数周期超过TTL的标签要降权返回。接口返回结构大致如下{ user_id: 20240801abc, tags: [ {name: 性价比敏感, category: value, confidence: 0.82}, {name: 晚间活跃, category: behavior, confidence: 0.91} ], intent: 决策后期关注售后保障 }客户分层我一般用RFM打分融合LLM标签。RFM三个维度最近消费、频率、金额给出价值分位LLM标签解决RFM解释不了的问题——例如一个RFM高价值用户LLM画像发现其情感标签为“不满”那这个用户处于高价值流失边缘应触发挽留动作而不是常规营销。反过来RFM低价值但有“期待”情感标签的用户可能是潜力型值得低成本触达。这种融合方式不需要复杂模型一张映射表就能落地业务动作按“RFM分位 情感/价值标签”组合路由。画像从“描述系统”变成“决策系统”这一步才是项目价值的开始。至于路由规则怎么配建议先拿历史数据做两次简单的交叉统计——看看有“不满”标签的高RFM用户过去30天流失率是不是显著偏高——再决定阈值和动作。5. 避坑与排查LLM画像系统上线后的几个真实问题5.1 模型幻觉标签看着合理实际是编的现象一个只注册未消费的用户画像里出现了“高消费能力”“偏好国际品牌”标签。产品经理拿用户订单截图来找人结论是系统在编。原因Prompt里没有强制证据链模型把训练数据里的普遍规律外推到当前用户身上。LLM本质是在做“补全”上下文信息少时它倾向往最常见的方向补而最常见的方向不一定是事实。这是LLM画像最危险的坑——标签越“像回事”越难被发现是编的。解决第一Prompt必填evidence字段且要求evidence是原文摘录而不是概括第二设置类别相关阈值价值观和消费类标签证据少于2条直接丢弃第三把这类“无证据推断”案例加入few-shot负面示例。给模型看一条“用户信息不足时必须输出空标签”的示例比在指令里反复强调有效得多。5.2 多源用户ID对不上画像被切成了碎块现象同一个用户在系统里出现两份画像一份只有行为标签来自APP匿名埋点一份只有交易标签来自下单手机号。运营做用户触达时看到两套完全不同的画像不知道该信哪个。原因接入数据时没有做跨端ID归并各来源表按各自的ID字段关联同一实体在画像库里没有收敛成一个主键。解决上线前先做ID映射排查——手机号、union_id、open_id、device_id四类ID的关系表必须最先建。匿名用户的行为缓存在映射表里保留3天用户登录后立即归并到正式ID。归并完成后历史画像要做一次合并重建不能只对增量生效。这个坑在前期最容易规避后期返工成本最高属于“上线前不做、上线后天天补”的典型。5.3 标签漂移频繁下游系统跟着抖动现象每天早上T1全量刷新后一部分用户的标签变了。运营按前一天画像做的活动方案第二天发现受众变了投诉系统不稳定。原因模型有随机性温度没设0加上证据选取时窗口大小不一致同一文本在不同批次里被模型注意到不同部分标签自然漂移。另有一个容易被忽略的点全量重算选了不同的截断时间比如晚上的行为日志还没落全第二天的结果就和前一天对不上。解决推理温度固定为0或0.1相同文本加缓存标签更新机制改成“有变化才覆盖、无变化保留原版本”每次更新写入updated_at下游可判断新鲜度。同时把全量刷新改成增量刷新事件触发全量重算只是兜底不作为日常更新手段。5.4 反讽被当成好评情感识别最常见翻车现象用户评论“你们家的物流真是快到离谱三天了还在原地踏步”情感标签判成“认可”客服系统把这个用户当正面用户跳过处理用户接着升级投诉。原因单条评论截断了反讽需要的上下文Prompt里也没有提示模型注意反讽或夸张语气。模型只看字面情绪词识别不出“字面褒义、实际贬义”的常见表达。解决情感识别任务输入改成多轮会话或“评论时间窗口内的回复记录”而不是孤立句子。Prompt里加一条硬性要求“遇到夸张、反讽、与现实情况矛盾的语气按负面情感处理并在evidence中标出矛盾点”。模型有了矛盾点的提取指令比单纯说“注意反讽”要更容易对齐。上线后抽500条反讽样本做回归测试反讽识别准确率低于80%不许上线。6. 收尾画像质量验证、成本控制与一个实用习惯6.1 画像质量怎么验证人工抽样与一致性检验画像系统的准确率不像分类模型那样有明确标签。常见做法是抽样人工标注每次版本更新抽500个用户让运营和客服人员对标签打“符合/不符合”计算符合率。若符合率低于80%这个版本的标签不能上线。别只看整体符合率要分标签类别看——价值观类标签符合率通常最低如果它拖了后腿就把阈值调高而不是删掉类别。6.2 成本控制小模型初筛加大模型兜底LLM画像的token成本是主要成本。省钱的常用做法是级联用7B或13B小模型处理简单明确的文本如交易记录聚合后的特征解读把高难度样本反讽、复杂情感、价值观推断路由给32B以上大模型。判断难度的信号可以是小模型输出的confidence——低于0.5的样本自动升级。这样整体成本能压到全量用大模型的三分之一。6.3 一个保持画像可信度的习惯我习惯在每个标签生成后保留完整证据链字段原文、时间、模型版本、prompt版本。线上出问题第一件事不是调prompt而是查证据链——看标签到底依据了什么。曾经有次价值观标签大面积翻车一查是上一次prompt迭代时把“从强证据中推断”这句删了模型立刻放飞自我。自此之后prompt每次改动都要跑一遍回归集也把这个习惯推荐给团队。这套LLM画像方案不一定是最先进的但把多源融合、标签生命周期、证据约束这三件事做扎实足够支撑CRM、推荐和增长场景跑起来希望帮到你。本文还有配套的精品资源点击获取
返回列表