大模型实战—用户反馈概要提取早期的做法大模型的做法具体代码最后整体的效果补充更新
大模型实战—用户反馈概要提取
前面我们已经本地部署了大模型,正好公司有一个业务,可以用来练练手,业务背景是这样的,我们的产品上有一个用户反馈的功能,里面积累了有史以来用户对产品的反馈,公司现在想要分析一下用户目前对产品的评价,以及用户关注的点是什么。关于之前大模型部署的文档,可以参考之前的文章。
我们希望做的就是通过提取出用户反馈的观点,观点要求浓缩在10个字以内。
早期的做法
早期我们是怎么做这个事情的呢,其实对用户的反馈分析做的很浅,没有上什么NLP 技术去分析,主要就是人工去处理,进行一个分类,以及对反馈的一个处理,唯一有的就是对用户的反馈进行了分词,做了一个词云图。
而且我们看到这个里面停用词过滤也不够好,里面出现了大量没有意义的词汇,因为涉及到特定的行业,所以这里还定了了很多自定义的词,及时做到这一步还有很多问题,就是同义词的问题。
举个例子定位不准 是我们的一个关键词,但是用户反馈的时候,表达定位不准会有很多种形式,例如位置不对,定位有偏差,位置偏差大,等,其实这些表达的都是同一个含义,所以我们做了一个同义词词典,并且做了合并同义词的操作。
代码大致如下,word_map 就是我们统计出来的分词信息,synonym_map 就是同义词词典
def compactWordMap():
for k,v in word_map.items():
# 同义词列表
synonym_value=synonym_map.get(k)
# 当前key 存在同义词
if synonym_value is not None:
new_word_map[synonym_value] = new_word_map.get(synonym_value,0)+v
else:
new_word_map[k]=v
这里我们给一个同义词词典的例子。
{
'位置不对':'定位不准',
'定位有偏差':'定位不准',
'位置偏差大':'定位不准'
}
大模型的做法
有了大模型之后,我们的做法其实就比较简单了,我们定义了一批关键词,然后让大模型对用户反馈进行观点提取,然后让大模型提取观点的时候,尽量从我们的观点列表里获取,如果观点列表里没有合适的观点,就让模型自己去提取一个观点,然后针对提取出来的观点不正确的进行纠正,正确的可以加入到观点列表里。
其实这个场景比我们熟知的用户情感分析还是要复杂很多,因为用户评论的情感分析,我们往往只需要分析出正面,负面,中性即可,但是这个场景下我们需要的是提取出用的观点。
这里模型我们尝试过下面几种
[root@bigdata02 ~]# ollama list
NAME ID SIZE MODIFIED
llama2-chinese:13b 990f930d55c5 7.4 GB 22 hours ago
llama2-chinese:latest cee11d703eee 3.8 GB 24 hours ago
qwen:14b 80362ced6553 8.2 GB 42 minutes ago
wizardlm2:latest c9b1aff820f2 4.1 GB 2 days ago
说实话,qwen 作为国产大模型的佼佼者,其实还是很让人失望的
目前使用的是llama2-chinese ,整体效果不算是很好,但是还行
这里的谁出第一行是反馈表的id,第二行是用户的反馈,第三行是大模型提取的观点,整体效果来说比之前单纯分词的效果好很多,后面通过人工对数据打标签,进行模型微调,效果应该还是要上升的。
具体代码
import ollama
import sys
model=sys.argv[0]
opinions="""[
]"""
host="bigdata00"
template=[
{
"role": "system",
"content": """
xxxxxxxxxxxxxxxx 现在一些用户的反馈信息,我需要你对反馈的内容进行概要提取,
我提供了一个观点列表:{},你可以参考,尽量从列表中选择,如果列表中的观点无法表示反馈的内容,那就需要你生成观点,生成的观点可以是多个,观点之间逗号隔开,要求每个观点不超过10个字
""".format(opinions)
}
]
# 添加对话模板,将样例数据放进去
def buildTemplate():
with open("./opus.txt","r",encoding="utf-8") as f:
lines=f.readlines()
for line in lines:
tline=line.split("#")
if len(tline)>=2:
title=tline[0]
content=tline[1]
userOpus={
"role": "user",
"content": content
}
assistantOpus={
"role": "assistant",
"content": title
}
template.append(userOpus)
template.append(assistantOpus)
feedbackMap={}
def loadDataFromDB():
import pymysql
connection = pymysql.connect(
host=host,
user='xxxx',
password='xxxxx',
database='ods',
port=9030
)
rows=[]
try:
with connection.cursor() as cursor:
sql="""
SELECT
content,id
FROM
ods_user_manage_feedback_df
where
!starts_with(content,'测试')
and !starts_with(content,'反馈测试')
and content !='">\nalert(1)'
"""
cursor.execute(sql)
rows =cursor.fetchall()
finally:
# 关闭数据库连接
connection.close()
for row in rows:
# 去掉读取每一行数据的\n
text=row[0].replace("\n", "")
id=row[1]
if text != "" and len(text)>=4:
question= {
"role": "user",
"content": f"content: {text}"
}
# 添加反馈到template
template.append(question)
response = ollama.chat(
model=model,
messages=template
)
feedback_title=response['message']['content']
# 回答完毕后将这个反馈删除
template.pop()
print("==============================================================")
print(id)
print(text)
print(feedback_title.replace("\n",""))
feedbackMap[id]=feedback_title
buildTemplate()
loadDataFromDB()
print(feedbackMap)
最后整体的效果
我们看一下最后整体的一个效果
补充更新
llama3 出来之后第一时间尝试使用llama3 进行了测试,对中文支持不是很好,但是速度很快,所以就自己进行了微调,现在使用的是微调后的模型,准确率可以达到90%