分类: 算法

  • 1.1.3 金融机构信用评估系统中的业务数据审核流程设计

    某金融机构计划引入智能信用评估系统,通过分析客户的历史交易数据和信用记录,使用机器学习算法预测客户的信用风险等级,从而辅助贷款审批和风险控制。为了确保数据的准确性和可靠性,该机构需要设计并实现一套全面的业务数据审核流程,确保数据在进入信用评估系统之前经过严格的审核和清洗。

    我们提供一个客户信用数据集(credit_data.csv),包含以下字段:

    CustomerID: 客户ID

    Name: 客户姓名

    Age: 年龄

    Income: 收入

    LoanAmount: 贷款金额

    LoanTerm: 贷款期限(月)

    CreditScore: 信用评分

    Default: 是否违约(0: 否,1: 是)

    TransactionHistory: 历史交易记录(JSON格式)

    1. 数据完整性审核:检查数据集中的每个字段是否存在缺失值和重复值。将上述审核结果截图以jpg的格式保存,命名为“1.1.3-1”。
    2. 数据合理性审核:对不合理的数据进行标记,并将审核结果截图以jpg的格式保存,命名为“1.1.3-2”。
      • 年龄:应在18到70岁之间。
      • 收入:应大于2000。
      • 贷款金额:应小于收入的5倍。
      • 信用评分:应在300到850之间。
    3. 对数据进行清洗,处理异常值。具体要求如下:将不合理的数据进行标记,并对异常值所在行进行删除;清洗后的数据保存为新文件cleaned_credit_data.csv。
    import pandas as pd
    import numpy as np
    # import matplotlib.pyplot as plt
    # 读取数据集
    data = pd.read_csv('credit_data.csv')
    
    # 1. 数据完整性审核
    missing_values = data.isnull().sum()     #数据缺失值统计 2分
    duplicate_values = data.duplicated().sum()     #数据重复值统计 2分
    # 输出结果
    print("缺失值统计:")
    print(missing_values)
    print("重复值统计:")
    print(duplicate_values)
    
    # 2. 数据合理性审核
    data['is_age_valid'] = data['Age'].between(18, 70)              #Age数据的合理性审核 2分
    data['is_income_valid'] = data['Income'] > 2000                 #Income数据的合理性审核 2分
    data['is_loan_amount_valid'] = data['LoanAmount'] < (data['Income'] * 5)      #LoanAmount数据的合理性审核 2分
    data['is_credit_score_valid'] = data['CreditScore'].between(300, 850)   #CreditScore数据的合理性审核 2分
    # 合理性检查结果
    validity_checks = data[['is_age_valid', 'is_income_valid', 'is_loan_amount_valid', 'is_credit_score_valid']].all(axis=1)
    data['is_valid'] = validity_checks
    # 输出结果
    print("数据合理性检查:")
    print(data[['is_age_valid', 'is_income_valid', 'is_loan_amount_valid', 'is_credit_score_valid', 'is_valid']].describe())
    
    # 3. 数据清洗和异常值处理
    # 标记不合理数据
    invalid_rows = data[~data['is_valid']]
    # 删除不合理数据行
    cleaned_data = data[data['is_valid']]
    # 删除标记列
    cleaned_data = cleaned_data.drop(columns=['is_age_valid', 'is_income_valid', 'is_loan_amount_valid', 'is_credit_score_valid', 'is_valid'])
    # 保存清洗后的数据
    cleaned_data.to_csv('cleaned_credit_data.csv', index=False)
    print("数据清洗完成,已保存为 'cleaned_credit_data.csv'")

  • 通过Spring AI 访问本地AI model 和避坑指南

    Spring 脚手架的准备

    通过 spring initializr 在线创建 agentdemo

    下载copy到项目目录并解压,Initializr 已经创建了项目框架和下面的入口文件和配置文件

    通过VS code 自带的agent, 添加spring AI的依赖和 ollama 依赖

    这里会创建三个文件并修改pom.xml


    OllamaConfig.java 主要作用是通过OllamaChatModel 的builder构建Spring AI 的 ChatClient(类似如果是OpenAI等其他AI service,应该是相同的结构)

    ChatController 主要通过注入Chatclient 对外提供对话的RESTful 服务

    application.yml 主要定义外部model 和 swagger 等资源

    pom.xml 中添加下面两个依赖

    安装依赖并执行:

    ./mvnw clean install -U
    ./mvnw spring-boot:run


    测试效果

    坑点:
    1. Spring AI 版本, 正式版是1.0.0,是2025年五月19发布的,AI Agent 不能直接识别,使用的是1.0.0-M3, M3 不在中央仓储,在milestone里面,所以直接install 回找不到


    2. M3 版本中的ChatClient 和 正式版的构造方法不一样,M版本中的构造在正式版中不兼容,正式版参考正文截图(通过OllamaAPI 和 OllamaOptions来实现)

    @Bean
    public ChatClient chatClient() {
        OllamaChatModel ollamaChatModel = OllamaChatModel.builder()
            .baseUrl(baseUrl)
            .model(modelName)
            .build();
        return ChatClient.builder(ollamaChatModel).build();
    }
  • 缪胥哲的暑假安排

    暑假作业,上午 9:00 – 10:00,
    11:00-12:00

    14:30 – 15:30

    眼保健操 13:00

    读书 13:30 – 2:30

  • AI Agent 工作模式

    想借助AI 整理一下AI Agent的工作模式,结果问了豆包,元宝,Kimi, DS, 每一家的回答都不一样。
    为什么答案都不一样?
    一个应该是分类的标准不一样

    AI Agent 是不是也像人类社会的分工一样,有不同的工作模式,而人类的工作模式何其之多。

    明确分类标准之后DS的答案就合理得多,如下:


    下面是原始的回答(有点乱):
    豆包的回答

    元宝的回答

    Kimi的回答

    DS 的回答

  • 一张图读懂内网穿透-FRP

    前提条件:云端有ubuntu服务器,且开启公网访问,防火墙开启 7000 + 其它端口,如图中6000(ssh), 7500(dashboard),8080(应用端口)

    内网机器可以是Ubuntu,也可是是windows

    通过FRP 7000端口,FRP client 与 FRP 服务端建立连接

    FRP 在server 端通过端口7500,提供Dashboard 来监控网络情况

    如图,其他应用通过在client 端配置端口映射来个服务端建立连接


    用户可以通过云端的服务器域名/IP:port 的方式来访问部署在内网的应用,比如Deepseek 本地模型部署 (这个后面单独写一篇)

    安装教程:
    云端:
    1. 安装FRP

    wget https://github.com/fatedier/frp/releases/download/v0.49.0/frp_0.49.0_linux_amd64.tar.gz
    tar -zxvf frp_0.49.0_linux_amd64.tar.gz
    cd frp_0.49.0_linux_amd64

    2. 配置服务端

    [common]
    bind_port = 7000          # 服务端与客户端通信端口(默认7000,可自定义)
    dashboard_port = 7500     # 仪表盘端口(默认7500,可自定义)
    dashboard_user = admin    # 改成自己的
    dashboard_pwd = admin     # 改成自己的
    # 可选:设置日志级别
    log_level = info
    log_max_days = 3

    3. 启动服务端服务

    # 前台运行(测试用)
    ./frps -c frps.ini
    
    # 后台运行(推荐)
    nohup ./frps -c frps.ini &

    4. 开启防火墙

    # UFW防火墙示例(放行7000,7500,8080端口)
    sudo ufw allow 7000/tcp
    sudo ufw allow 6000/tcp
    sudo ufw allow 7500/tcp
    sudo ufw allow 8080/tcp

    本地

    1. 安装FRP(同云端一样,只是配置文件不一样)
    wget https://github.com/fatedier/frp/releases/download/v0.49.0/frp_0.49.0_linux_amd64.tar.gz
    tar -zxvf frp_0.49.0_linux_amd64.tar.gz
    cd frp_0.49.0_linux_amd64

    2. 配置FRP

    [common]
    server_addr = 云端服务器公网IP   # 替换为云端Ubuntu的公网IP
    server_port = 7000                # 服务端的bind_port
    
    # SSH转发规则(重点!)
    [ssh]
    type = tcp                        # 转发类型为TCP
    local_ip = 127.0.0.1              # 本地SSH服务IP(内网Ubuntu的SSH地址,通常是127.0.0.1或内网IP)
    local_port = 22                   # 本地SSH端口(默认22)
    remote_port = 6000                # 云端服务器映射的公网端口(可自定义,需与服务端防火墙放行)
    
    [web]
    type = tcp                        # Web应用通常使用TCP协议
    local_ip = 127.0.0.1              # 内网Web应用所在IP(通常是本机)
    local_port = 3000                 # 内网Web应用端口
    remote_port = 8080                # 云端服务器映射的公网端口(自定义,需确保未被占用)

    3. 启动客户端服务

    # 前台运行(测试用)
    ./frpc -c frpc.ini
    
    # 后台运行(推荐,需创建systemd服务)
    # 1. 创建服务文件
    sudo nano /etc/systemd/system/frpc.service

    4. 配置系统服务,允许自动启动

    修改frpc.ini 文件

    [Unit]
    Description=frp client
    After=network.target
    
    [Service]
    Type=simple
    User=root
    ExecStart=/path/to/frpc -c /path/to/frpc.ini  # 替换为实际路径
    Restart=on-failure
    
    [Install]
    WantedBy=multi-user.target

    保存后启动服务

    sudo systemctl daemon-reload
    sudo systemctl start frpc
    sudo systemctl enable frpc  # 开机自启

    测试

    云端通过7500端口访问Dashboard

    云端通过6000 端口ssh 内网机器
    云端通过8080 端口访问web服务

    改进:配置安全连接(两端都需要配置)

    # 服务端(frps.ini)
    [common]
    token = your_secure_token  # 设置连接密钥,增强安全性
    
    # 客户端(frpc.ini)
    [common]
    token = your_secure_token  # 与服务端一致
    compress = true            # 启用数据压缩,减少流量

  • 破解深度学习-跟梗直哥学习AI

    听了8节免费课,感觉懂了点,又感觉没懂!先记下来


    什么是深度学习 – 深度神经网络的权重参数学习

    从系统论来看,万事万物可以看成下面的基础结构(多层感知机)

    从 Y = f(Wx + b)
    到 Y = fnfn-1…fo(Wx + b)

    深度学习就是 求这个W
    深度就是线性模型外面套激活函数,一层一层来逼近目标

    CNN,卷积神经网络->空间维度的一个截面- 把W通过w卷积

    RNN:循环神经网络 -> 考虑时间/时序维度的关系

    Yn = f(Ux + WYn-1 + B )

    注意力网络: Transformer -> 认知科学维度,聚焦关键特征

    Y = softmax(QK / [d])V

    AIGC

    机器视觉 CV

    语音

    NLP – 文本,以及背后的语义,逻辑,情感,意图等 -> LLM -> AI2.0

    多模态 – 多媒体 – 文本,图形,视频,语音的生成和交互

    线性代数 – 数据表达 – 前向传播

    概率统计 – 损失函数 – 优化引擎

    微积分 -链式法则- 反向传播

    向量和矩阵:数据在AI领域的数字表达
    神经网络的核心操作是线性变换 + 非线性激活,就是前面讲的:输入向量 x 通过权重矩阵 W 完成线性变换 y=Wx+b

    卷积神经网络(CNN)中的卷积操作可视为稀疏矩阵乘法,利用局部连接和权值共享减少计算量

    AI 模型(如神经网络)通过损失函数(如交叉熵)衡量预测误差,需利用微积分中的导数找到使损失最小的参数。
    梯度(Gradient)是损失函数对参数的偏导数向量,指引参数更新的方向(沿梯度反方向更新可最快降低损失)

    反向传播算法(Backpropagation)本质是链式法则的应用,递归计算每个参数的梯度,实现端到端的优化。

    动量法(Momentum)引入梯度的一阶惯性(类似物理中的动量),通过指数加权平均加速收敛;

    Adam 算法结合梯度的一阶矩(均值)和二阶矩(方差),自适应调整学习率,其推导依赖泰勒展开、牛顿法等微积分理论。

    为了使用梯度下降优化,激活函数(如 ReLU、Sigmoid、Tanh)必须可导(或近似可导)。

    微积分支持对连续变量的建模(如回归问题预测房价、温度等连续值),而离散优化(如组合问题)常通过连续松弛(如将 0-1 变量松弛为 [0,1] 区间的实数)转化为微积分问题求解。

    分类模型通过 Sigmoid 函数将线性变换结果映射为概率(如二分类中 \(P(y=1|X) = \sigma(\mathbf{w}^T\mathbf{x})\)),损失函数(交叉熵)对应极大似然估计的优化目标

    生成模型变分自编码器(VAE)假设隐变量 z 服从先验分布(如标准正态分布),通过编码器 \(q(z|X)\) 近似后验分布 \(p(z|X)\),解码器 \(p(X|z)\) 生成新样本,目标是最大化对数似然的变分下界

    归一化流(Normalizing Flow)通过可逆变换将简单分布(如高斯分布)转化为复杂数据分布,利用概率密度变换公式(雅可比行列式)计算似然

    多头注意力机制(Multi-Head Attention)通过线性变换(矩阵乘法)将查询(Query)、键(Key)、值(Value)映射到多个子空间,计算注意力权重时使用点积(内积)和 Softmax 函数(归一化概率分布)

    位置编码(Positional Encoding)利用正弦余弦函数(微积分中的周期函数)引入序列顺序信息,避免纯线性变换的排列不变性

    总结:微积分中的链式法则支撑反向传播算法,而线性代数中的矩阵求导(如雅可比矩阵、海森矩阵)提供参数梯度的计算框架,概率论中的期望运算(如损失函数的数学期望)将样本层面的优化扩展到总体分布。

  • 偶遇Dijkstra

    今天做题,偶遇Dijkstra,记录下来
    Dijkstra算法由计算机科学家Edsger Dijkstra在1956年提出。该算法适用于有向图和无向图,且图中的边权重必须为非负数。
    算法理解
    假设有如下图,我们需要计算从A到D的最短路径

    我们用一个数组记录A到所有节点的距离[]

    1. 第一步初始化,到自己为0,到其他节点为无穷, 所以得到 [0, ∞, ∞, ∞]
    2. 第二步计算A直接相连节点,更新A到所有节点的距离,得到 [0, 1,4,∞]
    3. 第三步移到节点B, 计算B直接相连的,更新A到所有节点的距离,得到 [0, 1,3,6]
    4. 第四步移到节点C, 计算C直接相连的距离,更新A到所有节点的距离,得到 [0, 1,3,4]
    5. D是最后一个节点,不需要计算了~

    所以我们就得到了A 到其他节点的最短路径

    强调一下:所有边的权重非负,因为负的权重会破坏数组是已知节点的最优解(比如重复走负权重这条路会让总距离越来越短~)

    实际应用场景举例:

    1. 地图导航-计算最短/最快路径
    2. 网络数据包路由
    3. 物流运输
    4. 社交网络-找朋友
    5. 电力/交通系统规划


    如果权重为负,比如计算最小成本的时候,某些路径上出现了收益…

    下一篇介绍Bellman-Ford算法来正确处理负权重的问题。