使用GeneticAlgorithmPython实现基于遗传算法的数据聚类分析
引言
数据聚类是机器学习中一项重要的无监督学习任务,其目标是将数据样本划分为若干个组(簇),使得同一组内的样本相似度高,不同组间的样本相似度低。传统的聚类算法如K-means虽然简单有效,但容易陷入局部最优解。本文将介绍如何使用GeneticAlgorithmPython项目中的遗传算法来实现更优的聚类效果。
项目概述
GeneticAlgorithmPython是一个专注于遗传算法实现的Python库,它提供了完整的遗传算法框架,可以方便地应用于各种优化问题。本文展示的示例演示了如何利用该库解决二维数据的聚类问题。
数据准备
首先我们需要准备一些测试数据。示例中创建了两个明显分离的簇:
import numpy
import matplotlib.pyplot
import pygad
# 第一个簇的数据生成
cluster1_num_samples = 10
cluster1_x1_start, cluster1_x1_end = 0, 5
cluster1_x2_start, cluster1_x2_end = 2, 6
cluster1_x1 = numpy.random.random(size=(cluster1_num_samples)) * (cluster1_x1_end - cluster1_x1_start) + cluster1_x1_start
cluster1_x2 = numpy.random.random(size=(cluster1_num_samples)) * (cluster1_x2_end - cluster1_x2_start) + cluster1_x2_start
# 第二个簇的数据生成
cluster2_num_samples = 10
cluster2_x1_start, cluster2_x1_end = 10, 15
cluster2_x2_start, cluster2_x2_end = 8, 12
cluster2_x1 = numpy.random.random(size=(cluster2_num_samples)) * (cluster2_x1_end - cluster2_x1_start) + cluster2_x1_start
cluster2_x2 = numpy.random.random(size=(cluster2_num_samples)) * (cluster2_x2_end - cluster2_x2_start) + cluster2_x2_start
通过可视化可以清楚地看到两个分离的簇:
matplotlib.pyplot.scatter(cluster1_x1, cluster1_x2)
matplotlib.pyplot.scatter(cluster2_x1, cluster2_x2)
matplotlib.pyplot.title("原始数据分布")
matplotlib.pyplot.show()
遗传算法实现聚类
1. 距离计算函数
使用欧氏距离作为样本与聚类中心之间的相似性度量:
def euclidean_distance(X, Y):
return numpy.sqrt(numpy.sum(numpy.power(X - Y, 2), axis=1)
2. 聚类函数
该函数根据当前遗传算法生成的解(即聚类中心位置)对数据进行聚类:
def cluster_data(solution, solution_idx):
global num_clusters, data
feature_vector_length = data.shape[1]
cluster_centers = []
all_clusters_dists = []
clusters = []
clusters_sum_dist = []
# 从解中提取聚类中心
for clust_idx in range(num_clusters):
cluster_centers.append(solution[feature_vector_length*clust_idx:feature_vector_length*(clust_idx+1)])
cluster_center_dists = euclidean_distance(data, cluster_centers[clust_idx])
all_clusters_dists.append(numpy.array(cluster_center_dists))
# 确定每个样本所属的簇
cluster_indices = numpy.argmin(all_clusters_dists, axis=0)
for clust_idx in range(num_clusters):
clusters.append(numpy.where(cluster_indices == clust_idx)[0])
if len(clusters[clust_idx]) == 0:
clusters_sum_dist.append(0)
else:
clusters_sum_dist.append(numpy.sum(all_clusters_dists[clust_idx, clusters[clust_idx]]))
return cluster_centers, all_clusters_dists, cluster_indices, clusters, clusters_sum_dist
3. 适应度函数
适应度函数评估当前聚类方案的质量,距离和越小,适应度越高:
def fitness_func(ga_instance, solution, solution_idx):
_, _, _, _, clusters_sum_dist = cluster_data(solution, solution_idx)
fitness = 1.0 / (numpy.sum(clusters_sum_dist) + 0.00000001)
return fitness
4. 遗传算法配置
配置遗传算法的各项参数:
num_clusters = 2
num_genes = num_clusters * data.shape[1]
ga_instance = pygad.GA(
num_generations=100,
sol_per_pop=10,
num_parents_mating=5,
init_range_low=-6,
init_range_high=20,
keep_parents=2,
num_genes=num_genes,
fitness_func=fitness_func,
suppress_warnings=True
)
5. 运行遗传算法并可视化结果
ga_instance.run()
# 获取最佳解
best_solution, best_solution_fitness, best_solution_idx = ga_instance.best_solution()
print(f"最佳解: {best_solution}")
print(f"最佳解的适应度: {best_solution_fitness}")
print(f"找到最佳解的代数: {ga_instance.best_solution_generation}")
# 可视化聚类结果
cluster_centers, all_clusters_dists, cluster_indices, clusters, clusters_sum_dist = cluster_data(best_solution, best_solution_idx)
for cluster_idx in range(num_clusters):
cluster_x = data[clusters[cluster_idx], 0]
cluster_y = data[clusters[cluster_idx], 1]
matplotlib.pyplot.scatter(cluster_x, cluster_y)
matplotlib.pyplot.scatter(cluster_centers[cluster_idx, 0], cluster_centers[cluster_idx, 1], linewidths=5)
matplotlib.pyplot.title("遗传算法聚类结果")
matplotlib.pyplot.show()
算法优势分析
与传统K-means算法相比,遗传算法在聚类问题中具有以下优势:
- 全局搜索能力:遗传算法通过种群搜索和多代进化,能够有效避免陷入局部最优解
- 鲁棒性:对初始聚类中心的位置不敏感
- 灵活性:可以方便地调整适应度函数,适应不同的聚类评价标准
实际应用建议
在实际应用中,可以考虑以下优化:
- 调整遗传算法的参数(如种群大小、变异率等)以获得更好的性能
- 对于高维数据,可以考虑使用其他距离度量(如余弦相似度)
- 对于大规模数据,可以结合采样技术或分布式计算
总结
本文展示了如何使用GeneticAlgorithmPython库实现基于遗传算法的数据聚类。通过遗传算法的全局搜索能力,我们能够找到更优的聚类中心位置,从而获得更好的聚类效果。这种方法特别适用于传统聚类算法容易陷入局部最优解的场景。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考