客户情绪分析
基于客服聊天记录的情绪分析对提升企业服务质量具有重要意义。通过实时监测情绪波动,企业可以迅速识别高风险会话(如持续负面情绪),触发预警机制并优先分配高级客服介入,从而提升客户体验,降低流失风险。本文介绍如何在AnalyticDB PostgreSQL 7.0版中使用pgml进行客户情绪分析。
前提条件
已购买内核版本为v7.2.1.0及以上的AnalyticDB for PostgreSQL7.0版实例。
实例的协调节点(Master):8CU及以上规格。
实例的计算节点(Segment):8C32G及以上规格。
说明您可以通过Master资源管理和计算节点变配获取协调节点和计算节点的配置变更方法。
实例资源类型为存储弹性模式。
已经安装pgml插件。
说明如果您已安装,在数据库的Schema列表中可以看到pgml。如未安装请提交工单,联系技术支持协助安装(需要重启实例)。如有卸载插件需求,也请提交工单联系技术支持协助卸载。
操作步骤
步骤一:创建业务表
在已安装pgml插件的目标数据库中,创建Schema和业务表并写入测试数据。
-- 创建SCHEMA
CREATE SCHEMA testschema;
-- 创建原始聊天记录表
CREATE TABLE testschema.chat_records (
session_id VARCHAR(40),
dialog_time TIMESTAMP,
role VARCHAR(10), -- 角色: customer/service
dialog_text TEXT
);
-- 创建推理结果记录表
CREATE TABLE testschema.sentiment_raw_results (
session_id character varying(40),
raw_response text
);
-- 写入测试数据
INSERT INTO testschema.chat_records VALUES
('S001', '2024-05-01 09:30:00', 'customer', '你们的产品质量太差了!刚用三天就坏了!'),
('S001', '2024-05-01 09:31:00', 'service', '非常抱歉给您带来不便,我们可以安排免费换新'),
('S002', '2024-05-01 10:15:00', 'customer', '感谢客服耐心指导,问题已完美解决'),
('S003', '2024-05-01 11:20:00', 'customer', '我需要查询订单物流信息');
步骤二:使用模型进行单条数据推理
下载DeepSeek模型至协调节点(Master)。
说明当前仅支持DeepSeek-R1-Distill-Qwen-7B模型。该模型不收费。
SELECT pgml.download_built_in_model('deepseek-ai/DeepSeek-R1-Distill-Qwen-7B');
使用该模型实现单条数据推理。
SELECT pgml.transform( task => '{ "task": "text-generation", "model": "deepseek-ai/DeepSeek-R1-Distill-Qwen-7B", "load_in_8bit": false, "device_map": "auto" }'::JSONB, inputs => ARRAY[ '请分析以下聊天记录中的客户情绪,正面表示用户很满意,负面表示有较大的流失风险,中性表示没有表现出情感倾向,不需要给出思考过程和理由,直接返回结果即可。 例如: # 用户消息为:你好,我想咨询一下你们的套餐。 # 情绪:中性 现在根据下面的输入进行评分: # 用户消息为:'||'感谢客服耐心指导,问题已完美解决'||' # 情绪:</think>' ], args => '{ "max_new_tokens": 10, "temperature": 0.1 }'::JSONB ) AS response;
参数说明
参数名称
描述
子参数
示例值
task
指定所使用的预训练模型以及任务类型。
task:任务类型。
task => '{ "task": "text-generation", "model": "deepseek-ai/DeepSeek-R1-Distill-Qwen-7B", "load_in_8bit": false, "device_map": "auto" }'::JSONB
model:模型名称。
load_in_8bit:与模型加载和量化(8bit量化)相关的参数。取值为:
false:禁用8-bit量化。
true:启用8-bit量化。
device_map:与模型加载和设备分配相关的参数。
auto
表示框架自动将模型的不同部分分配到可用的设备上,以优化内存使用和计算效率。该设置非常适合处理大型模型或多设备场景。args
将一组配置选项传递给某个逻辑单元(如函数、存储过程、API或模型)。
max_new_tokens:限制模型在生成文本时的token数量。
args => '{ "max_new_tokens": 10, "temperature": 0.1 }'::JSONB
temperature:温度系数,控制生成随机性的参数。
值越小,生成结果更加确定和稳定。适用于需要生成稳定、一致的结果的场景,例如问答系统、代码生成等。
值越大,生成结果更加随机和多样化。适用于需要生成多样化、创造性的内容的场景,例如对话生成、故事创作等场景。
inputs
需要分类的文本。
无
ARRAY['产品的质量很好']
步骤三:使用模型处理历史聊天记录
下载DeepSeek模型至计算节点(Segment)。
SELECT pgml.download_built_in_model('deepseek-ai/DeepSeek-R1-Distill-Qwen-7B') FROM gp_dist_random('gp_id');
处理历史聊天记录。
WITH model_output AS ( SELECT session_id, pgml.transform( task => '{ "task": "text-generation", "model": "deepseek-ai/DeepSeek-R1-Distill-Qwen-7B", "load_in_8bit": false, "device_map": "auto" }'::JSONB, inputs => ARRAY[ '请分析以下聊天记录中的客户情绪,正面表示用户很满意,负面表示有较大的流失风险,中性表示没有表现出情感倾向,不需要给出思考过程和理由,直接返回结果即可。 例如: # 用户消息为:你好,我想咨询一下你们的套餐。 # 情绪:中性 现在根据下面的输入进行评分: # 用户消息为:'|| string_agg(dialog_text, '; ')||' # 情绪:</think>' ], args => '{ "max_new_tokens": 10, "temperature": 0.1 }'::JSONB ) AS response FROM chat_records WHERE role = 'customer' -- 仅分析客户发言 GROUP BY session_id ) INSERT INTO testschema.sentiment_raw_results SELECT session_id, response->0->0->>'generated_text' AS raw_response FROM model_output;
参数说明
参数名称
描述
子参数
示例值
task
指定所使用的预训练模型以及任务类型。
task:任务类型。
task => '{ "task": "text-generation", "model": "deepseek-ai/DeepSeek-R1-Distill-Qwen-7B", "load_in_8bit": false, "device_map": "auto" }'::JSONB
model:模型名称。
load_in_8bit:与模型加载和量化(8bit量化)相关的参数。取值为:
false:禁用8-bit量化。
true:启用8-bit量化。
device_map:与模型加载和设备分配相关的参数。
auto
表示框架自动将模型的不同部分分配到可用的设备上,以优化内存使用和计算效率。该设置非常适合处理大型模型或多设备场景。args
将一组配置选项传递给某个逻辑单元(如函数、存储过程、API或模型)。
max_new_tokens:限制模型在生成文本时的token数量。
args => '{ "max_new_tokens": 10, "temperature": 0.1 }'::JSONB
temperature:温度系数,控制生成随机性的参数。
值越小,生成结果更加确定和稳定。适用于需要生成稳定、一致的结果的场景,例如问答系统、代码生成等。
值越大,生成结果更加随机和多样化。适用于需要生成多样化、创造性的内容的场景,例如对话生成、故事创作等场景。
inputs
需要分类的文本。
无
ARRAY['产品的质量很好']
查询结果。
SELECT * FROM testschema.sentiment_raw_results limit 1;
结果如下。
session_id | raw_response ------------+---------------------------------------------------------------------------------------------------------------------------------------------- S002 | 请分析以下聊天记录中的客户情绪,正面表示用户很满意,负面表示有较大的流失风险,中性表示没有表现出情感倾向,不需要给出思考过程和理由,直接返回结果即可。例如 | # 用户消息为:你好,我想咨询一下你们的套餐。 | # 情绪:中性 | | 现在根据下面的输入进行评分: | # 用户消息为: | 感谢客服耐心指导,问题已完美解决 | # 情绪:</think> | 正面 (1 row)
步骤四:转换为量化标签
转化为风险等级,以便企业后续跟进。
WITH sentiment_results AS(
SELECT split_part(
raw_response,
'</think>',
(length(raw_response) - length(replace(raw_response, '</think>', '')))/8 + 1
) AS raw_label,
session_id
FROM testschema.sentiment_raw_results
)
SELECT
r.session_id,
r.dialog_time,
r.dialog_text,
CASE
WHEN s.raw_label~'负面' THEN '高风险(需优先跟进)'
WHEN s.raw_label~'正面' THEN '低风险(归档观察)'
ELSE '中风险(常规处理)'
END AS risk_level
FROM testschema.chat_records r
JOIN sentiment_results s ON r.session_id = s.session_id
WHERE r.role = 'customer';
结果如下。
session_id | dialog_time | dialog_text | risk_level
----------------+-----------------------+-----------------------------------+-------------------
S001 | 2024-05-01 09:30:00 | 你们的产品质量太差了!刚用三天就坏了! | 高风险(需优先跟进)
S003 | 2024-05-01 11:20:00 | 我需要查询订单物流信息。 | 中风险(常规处理)
S002 | 2024-05-01 10:15:00 | 感谢客服耐心指导,问题已完美解决 | 低风险(归档观察)
(3 rows)