如何在Python的KMeans中使用R的随机种子123复现聚类结果
如何用Python的KMeans复现R中set.seed(123)的聚类结果
你的错误出在random_state参数的使用上——sklearn的KMeans要求该参数为整数、numpy RandomState实例或None,但你传入了R生成的FloatVector对象,类型不匹配导致报错。
R和sklearn的KMeans实现(包括随机初始化逻辑、默认算法)存在差异,直接用相同的随机种子无法保证结果一致,最可靠的方式是复用R中KMeans的初始质心,或者直接调用R的KMeans获取结果。
方案1:用rpy2直接调用R的KMeans获取结果
这种方法最直接,完全复用R的计算逻辑:
import rpy2.robjects as robjects from rpy2.robjects import pandas2ri import pandas as pd import numpy as np # 启用pandas与R数据格式的自动转换 pandas2ri.activate() # 读取数据 df = pd.read_excel(r'E:\Superservicios\Modelo de riesgo\Escenarios\Base_indicadores.xlsx') X = df[["ACTIVO","INGRESOS"]] # 在R环境中执行KMeans计算 robjects.r(''' set.seed(123) # 将Python传入的DataFrame转为R矩阵 r_data <- as.matrix(X) # 指定algorithm="Lloyd"对齐sklearn默认算法(可选,若需完全匹配) r_kmeans_result <- kmeans(r_data, centers=4, algorithm="Lloyd") ''') # 提取R的聚类结果到Python r_cluster_labels = np.array(robjects.r['r_kmeans_result$cluster']) - 1 # 转换为sklearn风格的0起始标签 r_centroids = np.array(robjects.r['r_kmeans_result$centers']) print("R生成的聚类标签:", r_cluster_labels) print("R生成的质心:", r_centroids)
方案2:在sklearn中复用R的初始质心复现结果
如果你希望用sklearn的API完成后续计算,可以先获取R的初始质心,再传入sklearn的KMeans:
import rpy2.robjects as robjects from rpy2.robjects import pandas2ri import pandas as pd import numpy as np from sklearn.cluster import KMeans pandas2ri.activate() df = pd.read_excel(r'E:\Superservicios\Modelo de riesgo\Escenarios\Base_indicadores.xlsx') X = df[["ACTIVO","INGRESOS"]].values # 在R中生成与set.seed(123)对应的初始质心 robjects.r(''' set.seed(123) r_data <- as.matrix(X) # 仅生成初始质心(模拟R的KMeans初始化逻辑) r_init_centers <- kmeans(r_data, centers=4, nstart=1, algorithm="Lloyd")$centers ''') # 获取R生成的初始质心 r_init_centers = np.array(robjects.r['r_init_centers']) # 在sklearn中使用该质心初始化KMeans,n_init=1避免重新生成质心 kmeans = KMeans(n_clusters=4, init=r_init_centers, n_init=1, random_state=123) kmeans.fit(X) print("sklearn复现的聚类标签:", kmeans.labels_) print("sklearn复现的质心:", kmeans.cluster_centers_)
关键注意事项
- 算法对齐:R的
kmeans()默认使用Hartigan-Wong算法,而sklearn的KMeans默认使用Lloyd算法。若需完全匹配结果,必须在R中指定algorithm="Lloyd"。 - 标签索引:R的聚类标签从1开始,sklearn从0开始,需要做减1转换。
- 初始化次数:sklearn的
n_init默认值为10(会多次初始化取最优结果),而R的nstart默认值为1。因此在sklearn中需设置n_init=1,确保仅使用传入的初始质心计算。
内容的提问来源于stack exchange,提问作者Manuel Gustavo Vergara Murillo
相关产品推荐
相关产品推荐

