手推粒子群算法,并求最大值(单目标函数和多目标函数)

本文介绍了使用Python实现的粒子群优化算法,分别处理单目标函数和多目标函数求解,通过迭代更新粒子位置和速度寻找最优解。

单目标函数

import random


# 定义适应度函数
def fitness_function(position):
    x = position[0]
    return -(x ** 2 - 4 * x + 4)  # 求反 PSO 以求最大值


class Particle:
    def __init__(self, position):
        self.position = position
        self.velocity = [random.uniform(-1, 1) for _ in range(len(position))]
        self.best_position = position
        self.best_fitness = fitness_function(position)


# 粒子群优化功能
def particle_swarm_optimization(pop_size, num_generations, inertia_weight, cognitive_weight, social_weight, lower_bound,
                                upper_bound):
    particles = [Particle([random.uniform(lower_bound, upper_bound)]) for _ in range(pop_size)]
    global_best_position = particles[0].position
    global_best_fitness = particles[0].best_fitness

    for generation in range(num_generations):
        for particle in particles:
            # 更新粒子速度和位置
            for i in range(len(particle.position)):
                r1 = random.random()
                r2 = random.random()
                cognitive_component = cognitive_weight * r1 * (particle.best_position[i] - particle.position[i])
                social_component = social_weight * r2 * (global_best_position[i] - particle.position[i])
                particle.velocity[i] = inertia_weight * particle.velocity[i] + cognitive_component + social_component
                particle.position[i] += particle.velocity[i]

            # 更新粒子最佳位置和适应度
            fitness = fitness_function(particle.position)
            if fitness > particle.best_fitness:
                particle.best_position = particle.position
                particle.best_fitness = fitness

            # 更新全局最佳位置和适应度
            if fitness > global_best_fitness:
                global_best_position = particle.position
                global_best_fitness = fitness

    return global_best_position, -global_best_fitness


if __name__ == "__main__":
    pop_size = 50
    num_generations = 100
    inertia_weight = 0.7
    cognitive_weight = 1.4
    social_weight = 1.4
    lower_bound = -10
    upper_bound = 10

    best_position, best_fitness = particle_swarm_optimization(pop_size, num_generations, inertia_weight,
                                                              cognitive_weight, social_weight, lower_bound, upper_bound)

    print("Best position:", best_position)
    print("Best fitness:", best_fitness)

多目标函数

import random
import time

import numpy as np


# 多目标函数,我们需要优化的函数,求解该函数的最小值
def objective_function(x):
    return x[0] ** 2 + x[1] ** 2


# 粒子类
class Particle:
    def __init__(self, bounds):
        self.bounds = bounds  # 粒子的位置范围
        # 初始化粒子的位置
        self.position = np.array([random.uniform(bounds[i][0], bounds[i][1]) for i in range(len(bounds))])
        self.velocity = np.array([0.0 for _ in range(len(bounds))])  # 初始化粒子的速度
        self.best_position = self.position.copy()  # 粒子的最佳位置
        self.best_value = float('inf')  # 粒子的最佳值

    def update(self, global_best):
        # 参数设置
        w = 0.5  # 惯性权重
        c1 = 1  # 个体学习因子
        c2 = 2  # 社会学习因子
        v_max = 5  # 最大速度

        # 更新速度
        self.velocity = w * self.velocity + c1 * random.random() * (
                self.best_position - self.position) + c2 * random.random() * (global_best - self.position)

        # 限制速度,防止速度过大
        self.velocity = np.clip(self.velocity, -v_max, v_max)

        # 更新位置
        self.position += self.velocity

        # 确保粒子的位置在范围内
        self.position = np.clip(self.position, [b[0] for b in self.bounds], [b[1] for b in self.bounds])

        # 更新个体最优
        current_value = objective_function(self.position)
        if current_value < self.best_value:
            self.best_position = self.position.copy()
            self.best_value = current_value


# PSO算法
def particle_swarm_optimization(num_particles, bounds, num_iterations):
    particles = [Particle(bounds) for _ in range(num_particles)]  # 初始化粒子群
    global_best = np.array([float('inf'), float('inf')])  # 全局最佳位置
    global_best_value = float('inf')  # 全局最佳值

    for _ in range(num_iterations):
        for particle in particles:
            particle.update(global_best)

            # 更新全局最优
            if particle.best_value < global_best_value:
                global_best = particle.best_position.copy()
                global_best_value = particle.best_value

    return global_best, global_best_value


start_time = time.time()
# 使用示例
bounds = [(-10, 10), (-10, 10)]  # x和y的范围
best_position, best_value = particle_swarm_optimization(1000, bounds, 100)
print(f"最佳位置: {best_position}, 最佳值: {best_value}")
end_time = time.time()
print(f"函数执行时间为: {end_time - start_time} 秒")
<think>嗯,用户这次明确要查找Adaboost算法的手动推导过程。从对话历史看,用户之前提供的参考引用中提到了Adaboost的权重特性(样本权重D特征权重W),但核心需是推导过程而非概念对比。 用户可能正在学习集成算法,需要从数学层面理解Adaboost的权重更新机制。考虑到算法推导涉及迭代公式,准备重点拆解三个核心步骤:初始化权重、弱分类器训练、权重更新规则,补充关键公式的数学解释。 注意到用户提供的引用[1]提到“加权决定结果”,这印证了推导中需要强调分类器权重α_t的计算逻辑。而引用[2]的因果推理内容与当前需无关,可以忽略。 推导过程需要特别注意两点:一是样本权重归一化的处理(如公式$\sum_{i=1}^n D_t(i)=1$),二是误差率ϵ_t与分类器权重α_t的反比关系(通过$α_t = \frac{1}{2}\ln(\frac{1-ϵ_t}{ϵ_t})$体现)。对于指数损失函数,计划用$H(x) = sign(\sum_{t=1}^T α_th_t(x))$说明加权投票机制。 用户可能是工程背景的研究者,因此会在最后补充手动实现建议(如分类器权重列表维护)迭代停止条件等实用细节。相关问题设计也侧重推导延伸(前向分步算法)而非概念对比,避免重复已有引用内容。 </think>以下是Adaboost算法的手动推导过程详解(以二分类问题为例): --- ### **Adaboost推导核心步骤** #### **1. 初始化样本权重** 设训练集 $\( \{(x_1,y_1), (x_2,y_2), ..., (x_n,y_n)\} \)$,其中 $\( y_i \in \{-1, +1\} \)$。 初始样本权重均匀分布: $$ D_1(i) = \frac{1}{n}, \quad i=1,2,...,n $$ #### **2. 迭代训练弱分类器(共T轮)** **For t=1 to T:** **(a) 训练弱分类器** 使用当前权重 $\( D_t \)$ 训练弱分类器 $\( h_t(x) \)$,目标是最小化加权错误率: $$ \epsilon_t = P_{i \sim D_t} [h_t(x_i) \neq y_i] = \sum_{i: h_t(x_i) \neq y_i} D_t(i) $$ **(b) 计算分类器权重** 根据错误率 $\( \epsilon_t \)$ 计算当前分类器的权重 $\( \alpha_t \)$: $$ \alpha_t = \frac{1}{2} \ln \left( \frac{1 - \epsilon_t}{\epsilon_t} \right) $$ > 推导说明:$\alpha_t$ 是损失函数(指数损失)最小化的解,当 $\epsilon_t < 0.5$ 时 $\alpha_t > 0$;错误率越低,权重越大。 **(c) 更新样本权重** 更新下一轮样本权重 $\( D_{t+1} \)$: $$ D_{t+1}(i) = \frac{D_t(i) \exp \left( -\alpha_t y_i h_t(x_i) \right)}{Z_t} $$ 其中 $\( Z_t \)$ 是归一化因子: $$ Z_t = \sum_{i=1}^n D_t(i) \exp \left( -\alpha_t y_i h_t(x_i) \right) $$ > **权重更新逻辑**: > - 若样本分类正确($y_i h_t(x_i) = +1$),则 $\exp(-\alpha_t) < 1$,权重降低; > - 若分类错误($y_i h_t(x_i) = -1$),则 $\exp(\alpha_t) > 1$,权重升高。 #### **3. 组合强分类器** 最终模型为弱分类器的加权投票: $$ H(x) = \text{sign} \left( \sum_{t=1}^T \alpha_t h_t(x) \right) $$ --- ### **关键公式推导(指数损失最小化)** Adaboost本质是优化指数损失函数: $$ L(H) = \frac{1}{n} \sum_{i=1}^n \exp \left( -y_i H(x_i) \right) $$ 其中 $\( H(x) = \sum_{t} \alpha_t h_t(x) \)$。 通过**前向分步算法**逐轮优化: 1. 假设第 $t$ 轮已得到 $H_{t-1}(x)$; 2. 新增弱分类器 $h_t(x)$ 时,优化目标为: $$ (\alpha_t, h_t) = \arg \min_{\alpha, h} \sum_{i=1}^n \exp \left( -y_i [H_{t-1}(x_i) + \alpha h(x_i)] \right) $$ 3. 推导可得最优 $\alpha_t$ 为前述公式,样本权重更新由损失函数的梯度决定[^1]。 --- ### **手动实现要点** ```python import numpy as np class AdaBoost: def __init__(self, n_estimators=50): self.n_estimators = n_estimators self.alphas = [] # 分类器权重列表 self.classifiers = [] # 弱分类器列表 def fit(self, X, y): n = X.shape[0] D = np.ones(n) / n # 初始化样本权重 for t in range(self.n_estimators): # 1. 训练弱分类器(例如决策树桩) h_t = self._train_weak_classifier(X, y, D) # 2. 计算加权错误率 pred = h_t.predict(X) err = D[(pred != y)].sum() # 3. 计算分类器权重 alpha_t = 0.5 * np.log((1 - err) / max(err, 1e-10)) # 避免除零 # 4. 更新样本权重 D *= np.exp(-alpha_t * y * pred) D /= D.sum() # 归一化 # 存储结果 self.alphas.append(alpha_t) self.classifiers.append(h_t) def predict(self, X): score = np.zeros(X.shape[0]) for alpha, h in zip(self.alphas, self.classifiers): score += alpha * h.predict(X) return np.sign(score) ``` --- **注意事项**: 1. 弱分类器需支持**加权训练**(如 `sklearn.tree.DecisionTreeClassifier(max_depth=1)`); 2. 迭代停止条件可以是 $\epsilon_t \geq 0.5$ 或达到预设轮数; 3. 样本权重更新可能导致数值溢出,需加入平滑项[^1]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值