AI大模型探索之路-实战篇12: 构建互动式Agent智能数据分析平台:实现多轮对话控制

系列篇章💥

AI大模型探索之路-实战篇4:深入DB-GPT数据应用开发框架调研
AI大模型探索之路-实战篇5:探索Open Interpreter开放代码解释器调研
AI大模型探索之路-实战篇6:掌握Function Calling的详细流程
AI大模型探索之路-实战篇7:Function Calling技术实战自动生成函数
AI大模型探索之路-实战篇8:多轮对话与Function Calling技术应用
AI大模型探索之路-实战篇9:探究Agent智能数据分析平台的架构与功能
AI大模型探索之路-实战篇10:数据预处理的艺术:构建Agent智能数据分析平台的基础
AI大模型探索之路-实战篇11: Function Calling技术整合:强化Agent智能数据分析平台功能


目录

  • 系列篇章💥
  • 一、前言
  • 二、引入背景知识库
    • 1、定义OpenAI客户端
    • 2、定义工具函数生成器
    • 3、两次大模型API调用封装
    • 4、user_demographics数据查询服务封装
    • 5、user_demographics函数信息生成测试
    • 6、第一次数据查询对话测试
    • 7、读取数据字典
    • 8、第二次数据查询对话测试
    • 9、数据库基本信息查询测试
    • 10、数据分析调用测试
  • 三、实现交互确认
    • 1、定义数据库基本信息获取函数
    • 2、函数信息生成测试检查:
    • 3、数据分析测试
    • 4、定义SQL提取函数
    • 5、两次次大模型API两次调用封装改造
    • 6、定义消息列表
    • 7、数据查询分析测试1
    • 8、数据查询分析测试2
    • 9、数据查询分析测试3
  • 四、实现完整的多轮对话效果
  • 五、结语


一、前言

在Agent智能数据分析平台的实战开发中,继我们之前关于Function Calling技术整合的讨论之后,本文将专注于实现一个核心功能——多轮对话控制系统。这一机制能够让用户通过自然语言与系统进行连续的交流,从而更准确、更高效地完成数据分析任务。

二、引入背景知识库

引入数据字典知识,作为大模型对话的背景知识库。

1、定义OpenAI客户端

定义大模型客户端,用于与大模型交互对话

import openai
import os
import numpy as np
import pandas as pd
import json
import io
from openai import OpenAI
import inspect
import pymysql

openai.api_key = os.getenv("OPENAI_API_KEY")

client = OpenAI(api_key=openai.api_key)

2、定义工具函数生成器

定义一个函数,用于自动生成function calling功能需要的,工具函数信息体

def auto_functions(functions_list):
    """
    Chat模型的functions参数编写函数
    :param functions_list: 包含一个或者多个函数对象的列表;
    :return:满足Chat模型functions参数要求的functions对象
    """
    def functions_generate(functions_list):
        # 创建空列表,用于保存每个函数的描述字典
        functions = []
        # 对每个外部函数进行循环
        for function in functions_list:
            # 读取函数对象的函数说明
            function_description = inspect.getdoc(function)
            # 读取函数的函数名字符串
            function_name = function.__name__

            system_prompt = '以下是某的函数说明:%s' % function_description
            user_prompt = '根据这个函数的函数说明,请帮我创建一个JSON格式的字典,这个字典有如下5点要求:\
                           1.字典总共有三个键值对;\
                           2.第一个键值对的Key是字符串name,value是该函数的名字:%s,也是字符串;\
                           3.第二个键值对的Key是字符串description,value是该函数的函数的功能说明,也是字符串;\
                           4.第三个键值对的Key是字符串parameters,value是一个JSON Schema对象,用于说明该函数的参数输入规范。\
                           5.输出结果必须是一个JSON格式的字典,只输出这个字典即可,前后不需要任何前后修饰或说明的语句' % function_name

            response = client.chat.completions.create(
                              model="gpt-3.5-turbo",
                              messages=[
                                {"role": "system", "content": system_prompt},
                                {"role": "user", "content": user_prompt}
                              ]
                            )
            json_function_description=json.loads(response.choices[0].message.content.replace("```","").replace("json",""))
            json_str={"type": "function","function":json_function_description}
            functions.append(json_str)
        return functions
    
    max_attempts = 4
    attempts = 0

    while attempts < max_attempts:
        try:
            functions = functions_generate(functions_list)
            break  # 如果代码成功执行,跳出循环
        except Exception as e:
            attempts += 1  # 增加尝试次数
            print("发生错误:", e)
            if attempts == max_attempts:
                print("已达到最大尝试次数,程序终止。")
                raise  # 重新引发最后一个异常
            else:
                print("正在重新运行...")
    return functions

3、两次大模型API调用封装

封装funcation calling中两次大模型API得调用

def run_conversation(messages, functions_list=None, model="gpt-3.5-turbo"):
    """
    能够自动执行外部函数调用的对话模型
    :param messages: 必要参数,字典类型,输入到Chat模型的messages参数对象
    :param functions_list: 可选参数,默认为None,可以设置为包含全部外部函数的列表对象
    :param model: Chat模型,可选参数,默认模型为gpt-3.5-turbo
    :return:Chat模型输出结果
    """
    # 如果没有外部函数库,则执行普通的对话任务
    if functions_list == None:
        response = client.chat.completions.create(
                        model=model,
                        messages=messages,
                        )
        response_message = response.choices[0].message
        final_response = response_message.content
        
    # 若存在外部函数库,则需要灵活选取外部函数并进行回答
    else:
        # 创建functions对象
        tools = auto_functions(functions_list)

        # 创建外部函数库字典
        available_functions = {func.__name__: func for func in functions_list}

        # 第一次调用大模型
        response = client.chat.completions.create(
                        model=model,
                        messages=messages,
                        tools=tools,
                        tool_choice="auto", )
        response_message = response.choices[0].message

        tool_calls = response_message.tool_calls
        if tool_calls:
            messages.append(response_message) 
            for tool_call in tool_calls:
                function_name = tool_call.function.name
                function_to_call = available_functions[function_name]
                function_args = json.loads(tool_call.function.arguments)
                
                function_response = function_to_call(**function_args)
                messages.append(
                    {
                        "tool_call_id": tool_call.id,
                        "role": "tool",
                        "name": function_name,
                        "content": function_response,
                    }
                ) 
            ## 第二次调用模型
            second_response = client.chat.completions.create(
                model=model,
                messages=messages,
            ) 
            # 获取最终结果
            final_response = second_response.choices[0].message.content
        else:
            final_response = response_message.content
                
    return final_response

4、user_demographics数据查询服务封装

定义一个get_user_demographics函数,用于获取user_demographics 表的相关信息

def get_user_demographics(sql_query):
    """
    用户获取user_demographics 表的相关信息
    :param sql_query: 字符串形式的SQL语句
    :return SQL查询的user_demographics 表的相关信息
    """
    mysql_pw="iquery_agent"
    
    connection = pymysql.connect(
    host='localhost',  # 数据库地址
    user='iquery_agent',  # 数据库用户名
    passwd=mysql_pw,  # 数据库密码
    db='iquery',  # 数据库名
    charset='utf8'  # 字符集选择utf8   
    )
    try:
        with connection.cursor() as cursor:
            sql = sql_query
            cursor.execute(sql)
            results = cursor.fetchall()
    finally:
        cursor.close()
    
    column_names = [desc[0] for desc in cursor.description]

    # 使用results和column_names创建DataFrame
    df = pd.DataFrame(results, columns=column_names)
        
    return df.to_json(orient = "records")         

5、user_demographics函数信息生成测试

使用工具函数生成器,对测试是否能够正常生成user_demographics相关数据查询的工具函数信息

#定义工具函数列表(当前只有user_demographics信息获取的函数)
functions_list = [get_user_demographics]

#user_demographics相关数据查询的工具函数信息,生成测试
tools = auto_functions(functions_list)
tools

生成的函数信息如下:
在这里插入图片描述

注意:结构生成不一定正确,大模型缺少稳定性;可能需要多次调用测试;也可以再生成函数中,加入校验;比如:如果缺失关键key、value,就让大模型重新生成。

6、第一次数据查询对话测试

使用自然语言对话的方式,进行数据查询分析

messages=[
            {"role": "user", "content": "请问user_demographics表中个人属性为老年男性的数据总共有多少条?"}
        ]
    
response = client.chat.completions.create(
        model="gpt-3.5-turbo",
        messages=messages,
        tools=tools,
        tool_choice="auto",  
    )

response.choices[0].message       

输出:

ChatCompletionMessage(content=None, role='assistant', function_call=None, tool_calls=[ChatCompletionMessageToolCall(id='call_5VK3ywSsn76wNBfAEc17FaWr', function=Function(arguments='{"sql_query":"SELECT COUNT(*) FROM user_demographics WHERE age >= 60 AND gender = \'male\'"}', name='get_user_demographics'), type='function')])

可以从结果中检查大模型是否正常找到自己生成的工具函数,以及生成的相关SQL是否正确;
查询SQL中使用了年龄大于60岁,来查询老年人。

7、读取数据字典

读取本地的数据字典

# 打开并读取Markdown文件
with open('/root/autodl-tmp/iquery项目/data/数据字典/iquery数据字典.md', 'r', encoding='utf-8') as f:
    md_content = f.read()
    
md_content

输出

'# iquery数据字典:iquery数据库数据字典\n\n本数据字典记录了iquery数据库中各张数据表的基本情况。\n\n## 1.user_demographics数据表\n\n- 基本解释\n\n  \u200b\t\tuser_demographics数据表记录了电信用户的个人基本情况,主要涵盖客户基本生物属性,包括性别、年龄状况、是否结婚以及是否经济独立等。\n\n- 数据来源\n\n  \u200b\tuser_demographics数据集由一线业务人员人工采集记录,并且通过回访确认相关信息,数据集的准确性和可信度都非常高。\n\n- 各字段说明\n\n| Column Name | Description | Value Range | Value Explanation | Type |\n|-------------|-------------|-------------|-------------------|------|\n| customerID | 客户ID,user_demographics数据表主键 |              | 由数字和字母组成的 | VARCHAR(255) |\n| gender | 用户的性别 | Female, Male | Female (女性), Male (男性) | VARCHAR(255) |\n| SeniorCitizen | 是否为老人 | 0, 1 | 0 (不是), 1 (是) | INT |\n| Partner | 用户是否有伴侣 | Yes, No | Yes (有), No (没有) | VARCHAR(255) |\n| Dependents | 用户经济是否独立,往往用于判断用户是否已经成年 | No, Yes | Yes (有), No (没有) | VARCHAR(255) |\n\n## 2.user_services数据表\n\n- 基本解释\n\n  \u200b        user_services数据表记录了每位用户订购电信服务的基本情况,截至目前,电信服务商提供了种类多样的服务,包括电话类服务和网络类服务等,本数据集表记录了每位用户订阅电信服务的基本情况。\n\n- 数据来源\n\n  \u200b\t\tuser_services数据表由后台系统自动创建生成,并未经过人工校验。\n\n- 各字段说明\n\n| Column Name | Description | Value Range | Value Explanation | Type |\n|-------------|-------------|-------------|-------------------|------|\n| customerID | 客户ID,user_services数据表主键 |  | 由数字和字母组成的 | VARCHAR(255) |\n| PhoneService | 用户是否有电话服务 | No, Yes | Yes (有), No (没有) | VARCHAR(255) |\n| MultipleLines | 用户是否开通了多条电话业务 | No phone service, No, Yes | Yes (有多条电话线业务), No (没有多条电话线业务), No phone service (没有电话服务) | VARCHAR(255) |\n| InternetService | 用户的互联网服务类型 | DSL, Fiber optic, No | DSL (DSL), Fiber optic (光纤), No (没有) | VARCHAR(255) |\n| OnlineSecurity | 是否开通网络安全服务 | No, Yes, No internet service | Yes(有)、No(无) or No internetservice(没有网路服务) | VARCHAR(255) |\n| OnlineBackup | 是否开通在线备份服务 | Yes, No, No internet service | Yes(有)、No(无) or No internetservice(没有网路服务) | VARCHAR(255) |\n| DeviceProtection | 是否开通设备保护服务 | No, Yes, No internet service | Yes(有)、No(无) or No internetservice(没有网路服务) | VARCHAR(255) |\n| TechSupport | 是否开通技术支持业务 | No, Yes, No internet service | Yes(有)、No(无) or No internetservice(没有网路服务) | VARCHAR(255) |\n| StreamingTV | 是否开通网络电视 | No, Yes, No internet service | Yes(有)、No(无) or No internetservice(没有网路服务) | VARCHAR(255) |\n| StreamingMovies | 是否开通网络电影 | No, Yes, No internet service | Yes(有)、No(无) or No internetservice(没有网路服务) | VARCHAR(255) |\n\n## 3.user_payments数据表\n\n- 基本解释\n\n  \u200b\t\tuser_payments数据表记录了每一位用户支付状况,既包括用户的支付方式和合同类型,同时也包含用户具体支付金额,包括月付金额和总金额等。\n\n- 数据来源\n\n  \u200b\t\tuser_payments数据表由后台自动记录生成,并未经过校验。\n\n- 各字段说明\n\n| Column Name | Description | Value Range | Value Explanation | Type |\n|-------------|-------------|-------------|-------------------|------|\n| customerID | 客户ID,user_payments数据表主键 |  | 由数字和字母组成的 | VARCHAR(255) |\n| Contract | 合同类型 | Month-to-month, One year, Two year | Month-to-month (月付), One year (一年付), Two year (两年付) | VARCHAR(255) |\n| PaperlessBilling | 是否无纸化账单 | Yes, No | Yes (是), No (否) | VARCHAR(255) |\n| PaymentMethod | 支付方式 | Electronic check, Mailed check, Bank transfer (automatic), Credit card (automatic) | Electronic check (电子检查), Mailed check (邮寄支票), Bank transfer (automatic) (银行转账), Credit card (automatic) (信用卡) | VARCHAR(255) |\n| MonthlyCharges | 月费用 |  | 用户平均每月支付费用 | FLOAT        |\n| TotalCharges | 总费用 |  | 截至目前用户总消费金额 | VARCHAR(255) |\n\n## 4.user_churn\n\n- 基本解释\n\n  \u200b\t\tuser_churn数据表记录了当前用户流失情况。\n\n- 数据来源\n\n  \u200b\t\tuser_churn数据表由后台自动创建并记录,当合同截至后但用户未续费,则判断该用户目前处于流失状态。\n\n- 各字段说明\n\n| Column Name | Description | Value Range | Value Explanation | Type |\n|-------------|-------------|-------------|-------------------|------|\n| customerID | 客户ID,user_churn数据表主键 |             | 由数字和字母组成的 | VARCHAR(255) |\n| Churn | 用户是否流失 | No, Yes | Yes (是), No (否) | VARCHAR(255) |\n\n'

8、第二次数据查询对话测试

将数据字典作为背景知识,再次使用自然语言对话的方式,进行数据查询分析

messages=[
      {"role": "system", "content": md_content}, 
      {"role": "user", "content": "请问user_demographics表中个人属性为老年男性的数据总共有多少条?"}
]
response = client.chat.completions.create(
        model="gpt-3.5-turbo",
        messages=messages,
        tools=tools,
        tool_choice="auto",  
    )

response.choices[0].message

输出:

ChatCompletionMessage(content=None, role='assistant', function_call=None, tool_calls=[ChatCompletionMessageToolCall(id='call_e4LEDDcytWdGUx0m98plDpUa', function=Function(arguments='{"sql_query":"SELECT * FROM user_demographics WHERE SeniorCitizen = 1 AND gender = \'Male\'"}', name='get_user_demographics'), type='function')])

通过输出结果可以看到,这一次数据查询中使用了SeniorCitizen 字段,因为背景知识中,这个字段是用来标识老人的,不需要通过年龄判断。
在这里插入图片描述

9、数据库基本信息查询测试

调用大模型API查询数据库的基本情况信息

messages=[
      {"role": "system", "content": md_content}, 
      {"role": "user", "content": "请帮我介绍下iquery这个数据库的基本情况"}
]
response = client.chat.completions.create(
        model="gpt-3.5-turbo",
        messages=messages,
    )

response.choices[0].message.content

输出:

'iquery数据库是一个用于电信用户数据分析的数据库,主要包括了四张数据表:user_demographics、user_services、user_payments和user_churn。这些数据表记录了电信用户的个人基本情况、订购的电信服务情况、支付情况以及流失情况。用户可以通过iquery数据库中的数据来进行用户行为分析、用户流失预测、产品定价优化等工作。每张数据表都有各自的字段说明,方便用户了解和利用数据库中的数据。'

10、数据分析调用测试

让大模型帮忙分析user_demographics数据表和user_services数据表的数据可信度。

messages=[
      {"role": "system", "content": md_content}, 
      {"role": "user", "content": "user_demographics数据表和user_services数据表哪张表的数据可信度更高呢?"}
]
response = client.chat.completions.create(
        model="gpt-3.5-turbo",
        messages=messages,
    )

print(response.choices[0].message.content)

输出:

根据描述,user_demographics数据表由一线业务人员人工采集记录,并通过回访确认相关信息,数据集的准确性和可信度都非常高。而user_services数据表由后台系统自动生成,并未经过人工校验。因此,user_demographics数据表的数据可信度更高。

三、实现交互确认

在数据查询分析前,让大模型输出将要执行的SQL,让用户确认检查;同时咨询是否需要执行

1、定义数据库基本信息获取函数

定义一个获取数据库基本信息的工具函数

def sql_inter(sql_query):
    """
    用于获取iquery数据库中各张表的有关相关信息,\
    核心功能是将输入的SQL代码传输至iquery数据库所在的MySQL环境中进行运行,\
    并最终返回SQL代码运行结果。需要注意的是,本函数是借助pymysql来连接MySQL数据库。
    :param sql_query: 字符串形式的SQL查询语句,用于执行对MySQL中iquery数据库中各张表进行查询,并获得各表中的各类相关信息
    :return:sql_query在MySQL中的运行结果。
    """
    
    mysql_pw = "iquery_agent"
    
    connection = pymysql.connect(
            host='localhost',  # 数据库地址
            user='iquery_agent',  # 数据库用户名
            passwd=mysql_pw,  # 数据库密码
            db='iquery',  # 数据库名
            charset='utf8'  # 字符集选择utf8
        )
    
    try:
        with connection.cursor() as cursor:
            # SQL查询语句
            sql = sql_query
            cursor.execute(sql)

            # 获取查询结果
            results = cursor.fetchall()

    finally:
        connection.close()
    
    
    return json.dumps(results)

2、函数信息生成测试检查:

#定义工具函数列表
functions_list = [sql_inter]

#工具函数信息生成
tools = auto_functions(functions_list)
tools

输出:
在这里插入图片描述

检查生成的函数信息结构是否正确,是否有缺失的key、value

3、数据分析测试

messages = [
    {"role": "system", "content": md_content},
    {"role": "user", "content": "请问user_demographics数据表的主键和user_services数据表的主键是否完全一致?"}
]
run_conversation(messages, functions_list=functions_list, model="gpt-3.5-turbo")

输出:
在这里插入图片描述

4、定义SQL提取函数

def extract_sql(json_str):
    # 提取并返回'sql_query'的值
    return json_str.get('sql_query', None)

5、两次次大模型API两次调用封装改造

改造二次大模型API两次调用的封装函数,引入用户确认的逻辑

def check_code_run(messages, functions_list=None, model="gpt-3.5-turbo",auto_run = True):
    """
    能够自动执行外部函数调用的对话模型
    :param messages: 必要参数,字典类型,输入到Chat模型的messages参数对象
    :param functions_list: 可选参数,默认为None,可以设置为包含全部外部函数的列表对象
    :param model: Chat模型,可选参数,默认模型为gpt-3.5-turbo
    :return:Chat模型输出结果
    """
    # 如果没有外部函数库,则执行普通的对话任务
    if functions_list == None:
        response = client.chat.completions.create(
                        model=model,
                        messages=messages,
                        )
        response_message = response.choices[0].message
        final_response = response_message.content
        
    # 若存在外部函数库,则需要灵活选取外部函数并进行回答
    else:
        # 创建functions对象
        tools = auto_functions(functions_list)
        

        # 创建外部函数库字典
        available_functions = {func.__name__: func for func in functions_list}

        # 第一次调用大模型
        response = client.chat.completions.create(
                        model=model,
                        messages=messages,
                        tools=tools,
                        tool_choice="auto", )
        response_message = response.choices[0].message
        tool_calls = response_message.tool_calls
        if tool_calls:
            messages.append(response_message) 
            for tool_call in tool_calls:
                function_name = tool_call.function.name
                function_to_call = available_functions[function_name]
                function_args = json.loads(tool_call.function.arguments)
              
              
                if auto_run == False:
                    sql_query = extract_sql(function_args)

                    res = input('即将执行以下代码:%s。是否确认并继续执行(1),或者退出本次运行过程(2)' % sql_query)
                    if res == '2':
                        print("终止运行")
                        return None
                    else:
                        print("正在执行代码,请稍后...")
                        
                function_response = function_to_call(**function_args)
                messages.append(
                    {
                        "tool_call_id": tool_call.id,
                        "role": "tool",
                        "name": function_name,
                        "content": function_response,
                    }
                ) 
            ## 第二次调用模型
            second_response = client.chat.completions.create(
                model=model,
                messages=messages,
            ) 
            # 获取最终结果
            final_response = second_response.choices[0].message.content
        else:
            final_response = response_message.content
    del messages
                
    return final_response

6、定义消息列表

messages = [
    {"role": "system", "content": md_content},
    {"role": "user", "content": "请问iquery数据库下user_demographics表的第10条数据内容是?"}
]
#函数列表查看
functions_list

在这里插入图片描述

7、数据查询分析测试1

check_code_run(messages, 
               functions_list=functions_list, 
               model="gpt-3.5-turbo", 
               auto_run = False)

输出:
在这里插入图片描述

8、数据查询分析测试2

messages = [
    {"role": "system", "content": md_content},
    {"role": "user", "content": "请问iquery数据库下user_demographics表有多少条数据?"}
]
check_code_run(messages, 
               functions_list=functions_list, 
               model="gpt-3.5-turbo", 
               auto_run = False)

输出:
在这里插入图片描述

9、数据查询分析测试3

messages = [
    {"role": "system", "content": md_content},
    {"role": "user", "content": "请问iquery数据库下user_demographics表中,男性和女性的分别有多少人"}
]
check_code_run(messages, 
               functions_list=functions_list, 
               model="gpt-3.5-turbo", 
               auto_run = False)

输出:
在这里插入图片描述

四、实现完整的多轮对话效果

经过上述步骤的不断优化和测试,我们最终实现了一个完整的多轮对话控制系统。该系统不仅能够理解用户的查询意图,还能够在需要时向用户确认信息,从而使得整个数据分析过程更加透明、可控。

import tiktoken

def chat_with_inter(functions_list=None, 
                    prompt="你好呀", 
                    model="gpt-3.5-turbo", 
                    system_message=[{"role": "system", "content": "你是一个智能助手。"}], 
                    auto_run = True):
    
    # 创建函数列表对应的参数解释列表
    functions = auto_functions(functions_list)
    
    # 多轮对话阈值
    if 'gpt-4' in model:
        tokens_thr = 6000
    elif '16k' in model:
        tokens_thr = 14000
    else:
        tokens_thr = 3000
    
    messages = system_message
    messages.append({"role": "user", "content": prompt})
    ## 计算token大小
    embedding_model = "text-embedding-ada-002"
    # 模型对应的分词器(TOKENIZER)
    embedding_encoding = "cl100k_base"
    encoding = tiktoken.get_encoding(embedding_encoding)
    tokens_count = len(encoding.encode((prompt + system_message[0]["content"])))
    
    while True:           
        answer = check_code_run(messages, 
                                functions_list=functions_list, 
                                model=model, 
                                auto_run = auto_run)
        
        
        print(f"模型回答: {answer}")

        # 询问用户是否还有其他问题
        user_input = input("您还有其他问题吗?(输入退出以结束对话): ")
        if user_input == "退出":
            del messages
            break

        # 记录新一轮问答
        messages.append({"role": "assistant", "content": answer})
        messages.append({"role": "user", "content": user_input})
        
        # 计算当前总token数
        tokens_count += len(encoding.encode((answer + user_input)))
        
        # 删除超出token阈值的对话内容
        while tokens_count >= tokens_thr:
            tokens_count -= len(encoding.encode(messages.pop(1)["content"]))
chat_with_inter(functions_list=functions_list, 
                prompt="我想根据iquery数据库中数据分析用户流失情况,请问需要用到iquery数据库中的哪几张表呢?", 
                model="gpt-3.5-turbo", 
                system_message=[{"role": "system", "content": md_content}], 
                auto_run = False)

对话效果
在这里插入图片描述

五、结语

在本篇章中,我们进一步强化了Agent智能数据分析平台的功能,通过实现可控的多轮对话交互确认逻辑,极大地提升了用户体验和系统的安全性。这一进步将为未来更加复杂、更加智能化的数据分析平台的构建奠定坚实的基础。

在这里插入图片描述

🎯🔖更多专栏系列文章:AIGC-AI大模型探索之路

😎 作者介绍:我是寻道AI小兵,资深程序老猿,从业10年+、互联网系统架构师,目前专注于AIGC的探索。
📖 技术交流:建立有技术交流群,可以扫码👇 加入社群,500本各类编程书籍、AI教程、AI工具等你领取!
如果文章内容对您有所触动,别忘了点赞、⭐关注,收藏!加入我,让我们携手同行AI的探索之旅,一起开启智能时代的大门!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/668350.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【CPP】双端队列简介(deque)

简介&#xff1a;双端队列(deque) 目录 1.概述2.特点3.底层原理 1.概述 双端队列&#xff1a;是一种顺序表和顺序表的结合数据结构&#xff0c;不是队列。 它提供顺序表的[]下标访问和链表的中间头部的较高效率插入删除操作。 2.特点 顺序表的优缺点&#xff1a; 优点&…

网络安全基础技术扫盲篇 — 名词解释之“数据包“

用通俗易懂的话说&#xff1a; 数据包就像是一个信封。当你写信给某个人时&#xff0c;你将内容写在一张纸上&#xff0c;然后将纸叠起来并放入信封中&#xff0c;就形成了一个完整要发送的数据内容。信封上有发件人和收件人的详细地址&#xff0c;还有一些其他必要的信息&…

动态规划(Dynamic-Programming)问题讲解

动态规划类问题 从已知子问题的解&#xff0c;推导出当前问题的解 推导过程可以表达为一个数学公式用一维或二维数组来保存之前的计算结果&#xff08;可以进一步降维优化&#xff09; 将当前问题 分解成子问题 &#xff0c;找出递归公式&#xff0c;分阶段进行求解 求解过程中…

【scau大数据技术与原理2】综合性实验Spark集群的安装和使用——安装启动spark shell篇

实验内容简介&#xff1a; Spark是一个分布式计算框架&#xff0c;常用于大数据处理。本次实验中&#xff0c;首先设计一个包含主节点和从节点的Spark集群架构&#xff0c;并在CentOS的Linux环境下进行搭建。通过下载并解压Spark安装包&#xff0c;配置环境变量和集群参数&…

python分别保存聚类分析结果+KeyError: ‘CustomerID‘报错

如何在完成聚类分析后按聚类编号保存数据并且带上原数据所属ID # 将每个聚类的数据保存到不同的文件中 for cluster_id in range(6): # 假设共有6个聚类cluster_data data[data[cluster] cluster_id]cluster_data_with_customer_id cluster_data.copy()cluster_data_with_…

量化研究---强大的可转债分析系统上线,提供api,实时数据支持

今天把可转债实盘的分析模型拿出来&#xff0c;放在服务器方便选股分析&#xff0c;方便后面对接大qmt直接选股交易 强大的禄得可转债自定义因子轮动系统完成&#xff0c;可转债三低为例子 自定义因子实盘的框架 自定义因子轮动框架非常强大 网页 http://120.78.132.143:8023/…

MongoDB~俩大特点管道聚合和数据压缩(snappy)

场景 在MySQL中&#xff0c;通常会涉及多个表的一些操作&#xff0c;MongoDB也类似&#xff0c;有时需要将多个文档甚至是多个集合汇总到一起计算分析&#xff08;比如求和、取最大值&#xff09;并返回计算后的结果&#xff0c;这个过程被称为 聚合操作 。 根据官方文档介绍&…

day1、2-数1

数学一主要考查高数、线性代数、概率统计这三个方面&#xff0c;其中高数占比56%、线性代数占比22%、概率统计占比22% 题做完 要产生1套理论 24年真题 1. 选C sinx的话不影响奇偶 奇偶函数的积分 0到a的积分为一个常数 求导的话 奇函数导出来一定是偶函数&#xff0c;偶函…

【机器学习系列】掌握随机森林:从基础原理到参数优化的全面指南

目录 目录 一、随机森林简介 (一)随机森林模型的基本原理如下&#xff1a; (二)随机森林模型的优点包括&#xff1a; (三)森林中的树的生成规则如下&#xff1a; (四)在随机森林中&#xff0c;每棵树都使用不同的训练集进行训练&#xff0c;原因如下 随机森林的分类性能&…

day-36 删除链表的倒数第 N 个结点

思路 首先计算出链表的长度&#xff0c;然后删除第n个节点即可&#xff0c;但要注意考虑特殊情况 解题方法 特殊情况&#xff1a;1.删除节点为最后一个节点 2.删除节点为头结点 Code /*** Definition for singly-linked list.* public class ListNode {* int val;* …

函数:计算数组的元素和

一、计算数组的元素和 参数传递给函数时&#xff0c;实际上只有数组的首地址作为指针传递给了函数。 在函数定义中的int a[ ]等价于int *a。在只有地址信息的情况下&#xff0c;是无法知道数组里有多少个元素的&#xff0c;因此在计算数组中的元素和时&#xff0c;要加一个参…

MongoDB下载安装入门 + SpringBoot简单集成

MongoDB安装入门 SpringBoot简单集成 MongoDB下载安装下载安装连接图形化界面MongoDB Compass Navicat Premium Spring Boot集成API操作添加maven配置数据库连接调用Mongo API MongoDB下载安装 下载安装 MongoDB官网地址&#xff1a;https://www.mongodb.com/ 下载地址&…

CobaltStrike基本渗透

目录 CobaltStrike简介 主要功能&#xff1a; 使用注意&#xff1a; 在使用CobaltStrike进行渗透测试时&#xff0c;务必遵守法律法规&#xff0c;并获得合法授权。 CobaltStrike安装 前提 安装 服务端安装 windows安装 CS基本使用 监听器配置 一些基本的攻击…

UnityAPI学习之游戏物体的方法使用

目录 游戏物体 创建游戏物体的三种方式 组建的获取和查找 游戏物体的方法与其他成员变量 游戏物体的生成 游戏物体的激活状态/标签(tag)/层级(layer) 游戏物体的激活与失活 游戏物体的查找 1. 名称查找(Find) 2. 通过标签查找游戏物体&#xff08;FindGameObjectWithT…

Leecode---动态规划---打家劫舍 / 乘积最大子数组

动态规划法&#xff1a; 思路&#xff1a; &#xff08;1&#xff09;状态定义&#xff1a;dp[i]代表前i家能偷盗的最大金额 &#xff08;2&#xff09;状态初始化&#xff1a;如果只有一家&#xff0c;只能偷这家dp[0]nums[0]&#xff1b;如果有两家&#xff0c;因为是连通的&…

fluent UI v9版本Dialog右上角x按钮聚焦问题解决

右上角x按钮聚焦效果展示 第一次点击不会聚焦&#xff0c;第二次或多次点击会出现这种情况。如果多个地方公用一个页面里&#xff0c;这个页面包含这个组件&#xff0c;那其它页面刚打开弹框就是聚焦状态&#xff0c;是个样式的问题。 解决&#xff1a; import * as React fr…

pytorch-Normalization

目录 1. 为什么Normalization2. Normalization2.1 image Normalization2.2 Batch Normalization 3. Normalization pytorch实现3.1 Normalization标准公式3.2 2d normalization3.3 normalize test 4. 使用normalization的好处 1. 为什么Normalization 下图使用sigmoid激活函数…

【2024新版】银系统源码/超市收银系统/智慧新零售/ERP进销存管理/线上商城/商户助手

>>>系统简述&#xff1a;本系统适用于超吃便利店&#xff0c;美妆母婴行业&#xff0c;服装鞋帽行业&#xff0c;食品零售行业&#xff0c;3C数码电子行业&#xff0c;食品生鲜等一切零售行业&#xff0c;产品功能角色介绍如下 合伙人&#xff1a;无限发展代理商和商…

Jetpack架构组件_1.基本知识

1.什么是Jetpack&#xff1f; Jetpack 是一个由多个库组成的套件&#xff0c;可帮助开发者遵循最佳做法、减少样板代码并编写可在各种 Android 版本和设备中一致运行的代码&#xff0c;让开发者可将精力集中于真正重要的编码工作。Jetpack 包含一系列 Android 库&#xff0c;它…

RTPS协议之Behavior Module

目录 交互要求基本要求RTPS Writer 行为RTPS Reader行为 RTPS协议的实现与Reader匹配的Writer的行为涉及到的类型RTPS Writer实现RTPS WriterRTPS StatelessWriterRTPS ReaderLocatorRTPS StatefulWriterRTPS ReaderProxyRTPS ChangeForReader RTPS StatelessWriter BehaviorBe…