import numpy as np
import matplotlib.pyplot as plt
# Define the Rastrigin functiondefrastrigin(X):
n =len(X)return10* n + np.sum(X**2-10* np.cos(2* np.pi * X))# Generate the initial population of potential solutionsdefgenerate_initial_population(pop_size, solution_size):return np.random.uniform(-5.12,5.12, size=(pop_size, solution_size))# Initialize within the search space of Rastrigin# Evaluate the fitness of each individual in the population (lower is better)defevaluate_population(population):return np.array([rastrigin(individual)for individual in population])# Select the best candidates from the population based on their fitnessdefselect_best_candidates(population, fitness, num_candidates):
indices = np.argsort(fitness)return population[indices[:num_candidates]], fitness[indices[:num_candidates]]# Clone the best candidates multiple timesdefclone_candidates(candidates, num_clones):return np.repeat(candidates, num_clones, axis=0)# Introduce random mutations to the cloned candidates to explore new solutionsdefmutate_clones(clones, mutation_rate):
mutations = np.random.rand(*clones.shape)< mutation_rate
clones[mutations]+= np.random.uniform(-1,1, np.sum(mutations))# Mutate by adding a random valuereturn clones
# Main function implementing the Clonal Selection Algorithmdefclonal_selection_algorithm(solution_size=2, pop_size=100, num_candidates=10, num_clones=10, mutation_rate=0.05, generations=100):
population = generate_initial_population(pop_size, solution_size)
best_fitness_per_generation =[]# Track the best fitness in each generationfor generation inrange(generations):
fitness = evaluate_population(population)
candidates, candidate_fitness = select_best_candidates(population, fitness, num_candidates)
clones = clone_candidates(candidates, num_clones)
mutated_clones = mutate_clones(clones, mutation_rate)
clone_fitness = evaluate_population(mutated_clones)# Replace the worst individuals in the population with the new mutated clones
population[:len(mutated_clones)]= mutated_clones
fitness[:len(clone_fitness)]= clone_fitness
# Track the best fitness of this generation
best_fitness = np.min(fitness)
best_fitness_per_generation.append(best_fitness)# Stop early if we've found a solution close to the global minimumif best_fitness <1e-6:print(f"Optimal solution found in {generation +1} generations.")break# Plot the fitness improvement over generations
plt.figure(figsize=(10,6))
plt.plot(best_fitness_per_generation, marker='o', color='blue', label='Best Fitness per Generation')
plt.xlabel('Generations')
plt.ylabel('Fitness (Rastrigin Function Value)')
plt.title('Fitness Improvement Over Generations')
plt.grid(True)
plt.show()# Return the best solution found (the one with the lowest fitness score)
best_solution = population[np.argmin(fitness)]return best_solution
# Example Usage
best_solution = clonal_selection_algorithm(solution_size=2)# Using 2D Rastrigin functionprint("Best solution found:", best_solution)print("Rastrigin function value at best solution:", rastrigin(best_solution))# Plot the surface of the Rastrigin function with the best solution found
x = np.linspace(-5.12,5.12,200)
y = np.linspace(-5.12,5.12,200)
X, Y = np.meshgrid(x, y)
Z =10*2+(X**2-10* np.cos(2* np.pi * X))+(Y**2-10* np.cos(2* np.pi * Y))
plt.figure(figsize=(8,6))
plt.contourf(X, Y, Z, levels=50, cmap='viridis')
plt.colorbar(label='Function Value')
plt.scatter(best_solution[0], best_solution[1], c='red', s=100, label='Best Solution')
plt.title('Rastrigin Function Optimization with CSA')
plt.xlabel('X')
plt.ylabel('Y')
plt.legend()
plt.grid(True)
plt.show()技术支持
import numpy as np
import matplotlib.pyplot as plt
# Generate a synthetic dataset
np.random.seed()# Parameters for bimodal distribution
num_normal_points =80# total number of normal transactions
num_points_per_cluster = num_normal_points //2# number of points in each cluster# Generate normal transactions for two clusters
cluster1_center =[2,2]
cluster2_center =[8,8]# Generate points around the first cluster center
normal_cluster1 = np.random.normal(loc=cluster1_center, scale=0.5, size=(num_points_per_cluster,2))# Generate points around the second cluster center
normal_cluster2 = np.random.normal(loc=cluster2_center, scale=0.5, size=(num_points_per_cluster,2))# Combine clusters into one dataset
normal_transactions = np.vstack([normal_cluster1, normal_cluster2])# Define random distribution for fraudulent transactions
num_fraud_points =5# number of fraudulent transactions
fraudulent_transactions = np.random.uniform(low=0, high=10, size=(num_fraud_points,2))# Combine into one dataset
data = np.vstack([normal_transactions, fraudulent_transactions])
labels = np.array([0]*len(normal_transactions)+[1]*len(fraudulent_transactions))# Function to generate detectors (random points) that don't match any of the normal datadefgenerate_detectors(normal_data, num_detectors, detector_size):
detectors =[]whilelen(detectors)< num_detectors:
detector = np.random.rand(detector_size)*10# Scale to cover the data rangeifnotany(np.allclose(detector, pattern, atol=0.5)for pattern in normal_data):
detectors.append(detector)return np.array(detectors)# Function to detect anomalies (points in the data that are close to any detector)defdetect_anomalies(detectors, data, threshold=0.5):
anomalies =[]for point in data:ifany(np.linalg.norm(detector - point)< threshold for detector in detectors):
anomalies.append(point)return anomalies
# Generate detectors that do not match the normal data
detectors = generate_detectors(normal_transactions, num_detectors=300, detector_size=2)# Detect anomalies within the entire dataset using the detectors
anomalies = detect_anomalies(detectors, data)print("Number of anomalies detected:",len(anomalies))# Convert anomalies to a numpy array for visualization
anomalies = np.array(anomalies)if anomalies else np.array([])# Define axis limits
x_min, x_max =0,10
y_min, y_max =-1,11# Visualize the dataset, detectors, and anomalies
plt.figure(figsize=(14,6))# Plot the normal transactions and fraudulent transactions
plt.subplot(1,2,1)
plt.scatter(normal_transactions[:,0], normal_transactions[:,1], color='red', marker='x', label='Normal Transactions')
plt.scatter(fraudulent_transactions[:,0], fraudulent_transactions[:,1], color='green', marker='o', label='Fraudulent Transactions')
plt.scatter(detectors[:,0], detectors[:,1], color='blue', marker='o', alpha=0.5, label='Detectors')iflen(anomalies)>0:
plt.scatter(anomalies[:,0], anomalies[:,1], color='yellow', marker='*', s=100, label='Detected Anomalies')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.title('Fraud Detection Using Negative Selection Algorithm (NSA)')
plt.legend(loc='lower right')
plt.xlim(x_min, x_max)
plt.ylim(y_min, y_max)
plt.grid(False)# Create a grid of points to classify
xx, yy = np.meshgrid(np.linspace(x_min, x_max,100), np.linspace(y_min, y_max,100))
grid_points = np.c_[xx.ravel(), yy.ravel()]# Classify grid points
decision = np.array([any(np.linalg.norm(detector - point)<0.5for detector in detectors)for point in grid_points])
decision = decision.reshape(xx.shape)# Plot the decision boundary
plt.subplot(1,2,2)
plt.contourf(xx, yy, decision, cmap='coolwarm', alpha=0.3)
plt.scatter(normal_transactions[:,0], normal_transactions[:,1], color='red', marker='x', label='Normal Transactions')
plt.scatter(fraudulent_transactions[:,0], fraudulent_transactions[:,1], color='green', marker='o', label='Fraudulent Transactions')
plt.scatter(detectors[:,0], detectors[:,1], color='blue', marker='o', alpha=0.5, label='Detectors')iflen(anomalies)>0:
plt.scatter(anomalies[:,0], anomalies[:,1], color='yellow', marker='*', s=100, label='Detected Anomalies')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.title('Decision Boundary Visualization')
plt.legend(loc='lower right')
plt.xlim(x_min, x_max)
plt.ylim(y_min, y_max)
plt.grid(False)# Show the plot
plt.show()技术支持
让我们使用 INT 基于一组经济指标预测股市趋势。我们将使用一个虚构数据集,其中每个解代表用于预测股价的一组指标权重组合。
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
# Generate synthetic data for illustration
np.random.seed(42)
n_samples =100
n_features =5
X = np.random.rand(n_samples, n_features)# Random economic indicators
true_weights = np.array([0.5,-0.2,0.3,0.1,-0.1])
y = X @ true_weights + np.random.normal(0,0.1, n_samples)# Stock prices with noise# Define the fitness functiondeffitness_function(solution, X, y):
model = LinearRegression()
model.coef_ = solution
predictions = X @ model.coef_
return mean_squared_error(y, predictions)# Generate the initial population of potential solutionsdefgenerate_initial_population(pop_size, solution_size):return np.random.uniform(-1,1, size=(pop_size, solution_size))# Create the immune networkdefcreate_immune_network(population, fitness, num_neighbors):
network =[]for i, individual inenumerate(population):
distances = np.linalg.norm(population - individual, axis=1)
neighbors = np.argsort(distances)[1:num_neighbors+1]# Exclude self
network.append(neighbors)return network
# Update the immune networkdefupdate_network(network, population, fitness, mutation_rate):
new_population = np.copy(population)for i, neighbors inenumerate(network):if np.random.rand()< mutation_rate:# Apply mutation with a smaller range
mutation = np.random.uniform(-0.05,0.05, population.shape[1])
new_population[i]+= mutation
return new_population
# Main function implementing Immune Network Theorydefimmune_network_theory(solution_size=n_features, pop_size=50, num_neighbors=5, mutation_rate=0.1, generations=50):
population = generate_initial_population(pop_size, solution_size)
best_fitness_per_generation =[]# Track the best fitness in each generationfor generation inrange(generations):
fitness = np.array([fitness_function(ind, X, y)for ind in population])
network = create_immune_network(population, fitness, num_neighbors)
new_population = update_network(network, population, fitness, mutation_rate)# Evaluate the fitness of the new population
fitness_new = np.array([fitness_function(ind, X, y)for ind in new_population])# Combine the old and new populations
combined_population = np.vstack((population, new_population))
combined_fitness = np.hstack((fitness, fitness_new))# Select the best individuals
best_indices = np.argsort(combined_fitness)[:pop_size]
population = combined_population[best_indices]
fitness = combined_fitness[best_indices]# Track the best fitness of this generation
best_fitness = np.min(fitness)
best_fitness_per_generation.append(best_fitness)# Stop early if the fitness is good enoughif best_fitness <0.01:print(f"Optimal solution found in {generation +1} generations.")break# Plot the fitness improvement over generations
plt.figure(figsize=(10,6))
plt.plot(best_fitness_per_generation, marker='o', color='blue', label='Best Fitness per Generation')
plt.xlabel('Generations')
plt.ylabel('Mean Squared Error')
plt.title('Fitness Improvement Over Generations')
plt.grid(True)
plt.show()# Return the best solution found
best_solution = population[np.argmin(fitness)]return best_solution
# Example Usage
best_solution = immune_network_theory()print("Best solution found (economic indicators weights):", best_solution)print("Mean Squared Error at best solution:", fitness_function(best_solution, X, y))# Plot the predicted vs. actual values using the best solution
model = LinearRegression()
model.coef_ = best_solution
predictions = X @ model.coef_
plt.figure(figsize=(8,6))
plt.scatter(y, predictions, c='blue', label='Predicted vs Actual')
plt.plot([min(y),max(y)],[min(y),max(y)],'r--', label='Ideal Fit')
plt.xlabel('Actual Values')
plt.ylabel('Predicted Values')
plt.title('Stock Price Prediction with INT')
plt.legend()
plt.grid(True)
plt.show()技术支持
想象一个系统,能够识别并清除从未遭遇过的威胁,同时记住以往的入侵者,从而更高效地抵御它们。您的免疫系统每天都在做这件事。
现在,想象把这种智能应用于解决复杂的计算问题。通过人工免疫系统(AIS),我们就能做到这一点。
什么是人工免疫系统?
人工免疫系统是一类强大的计算模型,灵感来自人体免疫系统保护机体免受伤害的能力。
人类免疫系统
免疫系统是我们身体的防御机制,用于识别并清除细菌、病毒和真菌等威胁。完成这些工作的关键角色包括抗体、B 细胞和 T 细胞。
抗体充当免疫系统的识别单元。这些特化蛋白会识别并附着于特定的外来物质,即抗原,并将其标记为威胁。每种抗体都是独一无二的,被设计成与特定抗原匹配,如同“锁与钥匙”。
B 细胞是生产抗体的“工厂”。它们还参与产生记忆细胞。记忆细胞通过记住上次哪些抗体有效,帮助机体对已遭遇的抗原做出更快速的反应。
T 细胞是免疫系统的“执法者”。它们会检测并摧毁被抗体标记为感染或危险的细胞,从而迅速清除威胁。
免疫系统最了不起的特性之一是其随时间进化并改进新抗体的能力。面对新病原体时,免疫系统并非只回应一次,而是不断优化策略,生成更强、更有效的抗体来应对威胁。
这些生物学概念如何转化为 AIS
人工免疫系统(AIS)是将这些生物学原理实现为算法。AIS 在问题求解中模拟免疫系统的功能。
在 AIS 中,抗原代表需要解决的问题或挑战。这些问题可能涵盖从数据异常检测到方案优化等各类任务。
AIS 中的抗体是这些问题的候选解。就像生物抗体识别特定抗原一样,AIS 会演化出针对特定挑战而定制的潜在解。
AIS 中的 B 细胞过程反映了生物系统生成多样性与记忆的方式。AIS 算法使用多样化的候选解并随时间精炼它们,从以往的问题中学习,以增强未来表现。
人工免疫系统没有与 T 细胞完全对应的部件,但会内置起到类似作用的评估机制。这些过程会淘汰无效解,并微调表现较好的解。
AIS 采用突变与选择等进化原理,不断提升解的质量。
人工免疫系统的关键概念
人工免疫系统涵盖抗体-抗原相互作用、克隆选择、负选择与免疫网络理论等关键概念。
抗体-抗原相互作用
人工免疫系统的核心是抗体-抗原相互作用,这一过程直接受免疫系统应对威胁的方式启发。可将抗体视为问题的潜在解,而抗原则是问题或挑战本身。
在生物世界中,抗体是能附着于抗原并将其中和的蛋白质。在 AIS 中,抗体代表某个计算问题的候选解,而抗原则代表需要被解决的问题。
AIS 算法会演化一组抗体种群,使之能有效识别并“中和”相应的抗原。随着时间推移,算法会对这些抗体进行微调,锁定最有效的解决方案。
克隆选择算法(CSA)
克隆选择算法(CSA)的灵感来自免疫系统的另一关键过程。当机体检测到抗原时,并不会随意部署免疫细胞,而是选择那些能够特异性识别入侵者的细胞。被选中的细胞会被大量克隆,以形成有效防御。
这些克隆体会经历突变,引入细微差异,从而提升免疫反应的多样性。这确保即使病原体发生进化,免疫系统也能适应并有效应对。
类似地,克隆选择算法会选择最有前景的解,并对它们进行多次复制或“克隆”。
随后对这些克隆体进行突变,生成多样化的潜在解。保留表现最好的克隆体并循环往复,逐步提升解的质量。该算法在优化任务中尤为强大,其目标是在众多可能性中找到最优解。
CSA 常用于求解优化问题。例如,在航空航天领域,它可通过多次迭代改进气动特性,帮助设计高效的机翼等结构。
在医学影像中,CSA 可提升图像清晰度或在噪声环境中检测异常模式,适用于 MRI 扫描或肿瘤检测。
负选择算法(NSA)
人类免疫系统必须区分自身细胞与外来入侵者。负选择算法(NSA)正是模拟了这一过程。对自身细胞反应过强的免疫细胞会被清除,从而避免免疫系统误伤自身(导致自身免疫性疾病)。
NSA 模拟这一过程以识别数据中的异常或离群点。算法会生成一组模型(称为检测器),用于识别数据中的正常模式。任何与正常数据高度匹配的检测器都会被淘汰,只保留那些与典型模式不匹配的检测器。这些剩余的检测器随后用于监测新数据。
如果这些“非典型”检测器标记出一个新的数据点,即表明它是异常。这与免疫系统检测外来入侵者的方式相似。该方法在网络安全等领域非常有效,因为识别异常模式是发现潜在威胁的关键。
NSA 非常适合用于入侵检测系统,以监测网络流量,通过比较正常模式与潜在威胁的模式来识别恶意活动。
NSA 也可用于检测电厂等复杂系统的机械或运行故障。
免疫网络理论(INT)
免疫网络理论(INT)不仅建模抗体与抗原之间的相互作用,还建模抗体之间的相互作用,从而扩展了 AIS 的概念。
在生物免疫系统中,抗体并非各自为战。它们会相互“沟通”和影响,形成一个更健壮、更具适应性的动态响应网络。这种网络化的交互有助于免疫系统维持平衡,确保能对各种威胁有效响应,同时避免对单一威胁过度反应。
INT 用于建模不同解决方案之间的复杂交互与依赖关系,使算法能够考虑更广泛的可能响应,进而形成更为复杂的求解策略。
通过模拟抗体之间的相互影响,AIS 可以同时探索通往解的多条路径,从而提升在复杂且动态环境中寻找最优解的能力。该理论支撑了一些最先进的 AIS 算法,是应对复杂计算挑战的有力工具。
免疫网络理论可应用于机器人群控。机器人之间的交互模拟抗体相互作用,从而在搜救等任务中实现协同行为与问题求解。
在金融领域,免疫网络模型可用于研究各类经济指标之间的相互作用,从而预测市场趋势或检测金融异常。
人工免疫系统的 Python 实现
由于具备丰富的库和易用性,Python 常被用于构建人工免疫系统。
克隆选择算法的实现
克隆选择算法的灵感来自生物过程:成功识别威胁的免疫细胞会被克隆,并通过突变来提升免疫反应。在 AIS 中,这些“免疫细胞”是问题的候选解,目标是演化这些解以找到最佳方案。
以下是在 Python 中实现简化版 CSA 的方法:
我们用 CSA 来求解函数优化问题。这里选择一个著名的基准函数——Rastrigin 函数。由于其存在大量局部极小值,该函数常用于测试优化算法。
下面的代码使用 CSA 寻找该函数的全局极小值:
上图展示了 CSA 如何在每一代迭代中为 Rastrigin 函数找到更好的解。
该图绘制了 Rastrigin 函数,显示其拥有众多局部极小值。中心的红点为 CSA 最终找到的最佳解。
负选择算法的实现
NSA 尤其适用于异常检测任务。该算法模拟免疫系统区分自身细胞与外来入侵者的方式。在 NSA 中,您会生成一组与正常数据模式不匹配的检测器。这些检测器随后用于监测新数据,标记任何显得异常的内容。
以下是创建 NSA 的概要:
让我们用一组虚构的交易来演示其工作方式。本示例中,我们生成围绕两个簇分布的正常交易,以及随机分散的欺诈交易。我们将采用负选择算法,将欺诈检测器分散在特征空间中,根据与这些检测器的距离来识别异常。
这里,欺诈检测器分布在整个特征空间,覆盖正常交易未出现的区域。落在这些检测器附近的欺诈交易会被识别并标记为异常。
该图展示了由欺诈检测器形成的决策边界。阴影区域代表因接近检测器而被判定为异常的区域,突出显示了相对于正常交易,欺诈交易被检测到的位置。要调整决策边界并覆盖更多或更少的区域,您可以修改用于检测异常的距离阈值,从而扩展或收缩被判定为异常的区域。
免疫网络理论的实现
INT 的灵感在于免疫反应不仅取决于单个抗体,还取决于它们之间的“沟通”。这一方法将免疫系统建模为一个网络,在其中抗体通过相互作用来增强整体免疫反应。在该语境下,每个抗体(解)都可以与其他抗体交互,从而影响并优化对最优解的搜索。
以下是在 Python 中实现基础版 INT 的方法:
让我们使用 INT 基于一组经济指标预测股市趋势。我们将使用一个虚构数据集,其中每个解代表用于预测股价的一组指标权重组合。
该图显示均方误差(MSE)随时间下降,表明模型预测逐渐更为精准。
该散点图比较了实际股价与模型预测。越接近红色虚线的点预测越准确。
人工免疫系统与其他 AI 技术的比较
AIS 是众多受生物学启发的机器学习技术之一。
神经网络
神经网络的灵感来自人脑,擅长从海量数据中学习,被用于图像识别与自然语言处理等任务。它们依赖大规模数据训练来调整互联神经元的权重。
相比之下,人工免疫系统侧重于适应性与去中心化问题求解,而无需庞大数据集。AIS 模拟免疫系统实时识别并应对新挑战的能力,适用于需要快速适应的动态环境。
遗传算法
遗传算法受自然进化启发,通过选择、交叉与变异来演化解的种群,从而有效优化复杂问题。其过程与 CSA 相似。
然而,遗传算法依靠遗传算子探索解空间,而 CSA 则通过模拟免疫反应来调整解,在应对新颖且意外的挑战时更具灵活性。包括 CSA 在内的 AIS 尤其适用于需要快速适应与持续学习的动态环境。
您可以在 遗传算法:完整指南与 Python 实现中了解更多。
群体智能算法
群体智能算法受蚂蚁、蜜蜂等社会性生物群体行为启发,利用去中心化系统和简单个体的交互来实现复杂的全局优化。
这在精神内核上与 INT 相近。二者都注重在系统内保持多样性与适应性,以解决优化问题。群体智能强调基于个体的交互,而 INT 借鉴类免疫机制,为动态问题求解提供了互补的方法。
您可以在群体智能算法:三个 Python 实现中了解更多。
人工免疫系统的最新研究
人工免疫系统有望在多个领域解决复杂问题。研究人员正致力于进一步增强这些系统,使其更具实用性。
研究者正在探索的一个方向是构建将 AIS 与其他计算智能技术相结合的混合模型,希望这些混合模型更加健壮且通用。
这些混合方法旨在发挥各自优势,例如 AIS 的适应能力与神经网络强大的学习机制。欲了解更多,请参阅Artificial Immune Systems。
另一个活跃方向是将 AIS 应用于新领域。除了传统的网络安全与优化,AIS 现正被探索用于机器人学、生物信息学,甚至金融建模。AIS 的适应性和去中心化特性使其有望在这些动态且常常难以预测的环境中解决问题。更多信息可参阅Nature-Inspired Computing: Scope and Applications of Artificial Immune Systems Toward Analysis and Diagnosis of Complex Problems。
AIS 模型不仅提供了更强的计算方法,也有助于我们理解真实的免疫系统。它们正在推动针对癌症和自身免疫性疾病等的免疫治疗策略。请查看这则克利夫兰诊所与 IBM 的合作以了解更多。
总结
人工免疫系统通过借鉴人体免疫系统,为解决复杂问题提供了独特思路。通过模拟模式识别、适应与记忆等生物过程,AIS 在从网络安全到优化等领域都能提供多样而有效的解决方案。