高斯混合模型(GMM)聚类结果与训练数据无关的原因排查

问题原因
- 坐标顺序完全颠倒:训练GMM时输入的特征顺序是
[x坐标, y坐标],但预测掩膜时传入的是[行号, 列号],行号对应图像的y轴、列号对应x轴,输入模型的特征顺序和训练时不一致,直接导致聚类结果完全错位,这是最核心的故障原因。 - 协方差类型不匹配数据分布:你选择了
spherical球形协方差,该类型假设每个聚类分量的各个维度方差一致,如果你的出入口点分布是狭长型、或者x/y轴分布方差差异较大,球形协方差无法拟合真实数据分布,得到的聚类结果自然和实际点无关。 - 特征未做归一化处理:如果你的坐标数据x、y的数值范围差距较大,K-means初始化GMM参数时会被数值更大的维度主导,直接导致聚类偏移。
- 无意义区域干扰判断:你对整图所有像素做了GMM预测,远离你34个原始样本点的区域本身属于GMM的外推范围,预测结果没有实际意义,大片无意义的染色区域会覆盖和原始数据匹配的有效聚类结果,看起来就像完全不相关。
- 坐标单位不匹配:需要确认你原始数据里的enter_x、enter_y的单位是否和图像像素坐标一致,如果原始坐标是归一化到0-1的相对坐标,你直接用像素级的0-1920/0-1080数值预测,结果肯定完全错位。
修复建议
- 调整预测时的输入顺序,把
[[row_index, column_index]]改成[[column_index, row_index]],和训练时的x在前y在后的顺序对齐。 - 把GMM的
covariance_type参数改成diag或者full,适配不同维度方差不同的场景。 - 训练前对
mini_data做标准差归一化,预测时也对像素坐标做同样的归一化处理。 - 给掩膜染色加概率阈值,只有
predict_proba返回的最高概率大于阈值(比如0.5)的像素才染色,其余区域保持透明/黑色,过滤无意义的外推结果。
拟合GMM的原始代码
def calculate_zones(self): mini_data = [] for id, enter_x, enter_y, enter_time, exit_x, exit_y, exit_time in self.data: mini_data.append([enter_x, enter_y]) mini_data.append([exit_x, exit_y]) K = range(2, 4) for k in K: # Set the model and its parameters self.gms.append( GaussianMixture(n_components=k, n_init=20, covariance_type='spherical', init_params='kmeans').fit( mini_data))
生成掩膜的原始代码
def display_zones(self): video = cv2.VideoCapture(self.video_path) if not video.isOpened(): print("Cannot open stream") exit() _, frame = video.read() mask = [] colors = random_color(11) for model in self.gms: curr_mask = np.zeros_like(frame) mask.append(curr_mask) row_index = 0 for pixel_row in frame: column_index = 0 for _ in pixel_row: prediction = model.predict_proba([[row_index, column_index]]) best_proba = 0 counter = 0 for one_prediction in prediction[0]: if one_prediction > prediction[0][best_proba]: best_proba = counter counter += 1 curr_mask[row_index][column_index] = colors[best_proba] column_index += 1 row_index += 1
内容的提问来源于stack exchange,提问作者Hassan Kanso
相关产品推荐
相关产品推荐

