大模型实战—用户反馈概要提取

197 阅读5分钟


大模型实战—用户反馈概要提取
早期的做法大模型的做法具体代码最后整体的效果补充更新

大模型实战—用户反馈概要提取

前面我们已经本地部署了大模型,正好公司有一个业务,可以用来练练手,业务背景是这样的,我们的产品上有一个用户反馈的功能,里面积累了有史以来用户对产品的反馈,公司现在想要分析一下用户目前对产品的评价,以及用户关注的点是什么。关于之前大模型部署的文档,可以参考之前的文章。

ollama 本地部署大模型

大模型web服务部署—open-webui

WizardLM-2大模型 重磅来袭

我们希望做的就是通过提取出用户反馈的观点,观点要求浓缩在10个字以内。

早期的做法

早期我们是怎么做这个事情的呢,其实对用户的反馈分析做的很浅,没有上什么NLP 技术去分析,主要就是人工去处理,进行一个分类,以及对反馈的一个处理,唯一有的就是对用户的反馈进行了分词,做了一个词云图。

image-20240419171731606

而且我们看到这个里面停用词过滤也不够好,里面出现了大量没有意义的词汇,因为涉及到特定的行业,所以这里还定了了很多自定义的词,及时做到这一步还有很多问题,就是同义词的问题。

举个例子定位不准 是我们的一个关键词,但是用户反馈的时候,表达定位不准会有很多种形式,例如位置不对定位有偏差位置偏差大,等,其实这些表达的都是同一个含义,所以我们做了一个同义词词典,并且做了合并同义词的操作。

代码大致如下,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 ,整体效果不算是很好,但是还行

image-20240419170336115

这里的谁出第一行是反馈表的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)

最后整体的效果

我们看一下最后整体的一个效果

image-20240419171748287

补充更新

llama3 出来之后第一时间尝试使用llama3 进行了测试,对中文支持不是很好,但是速度很快,所以就自己进行了微调,现在使用的是微调后的模型,准确率可以达到90%