You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

用于聚类的二值数据集降维:Autoencoder效果不及MCA的问题排查

二值问卷数据集降维:Autoencoder效果不如MCA的问题排查

我有一个源于是非问卷的二值数据集,包含31个特征、约50000个样本,存在严重多重共线性,计划用于后续无监督聚类分析,因此先做降维处理。

尝试用Autoencoder降维,但用k-medoids聚类(考虑到数据的名义特性及抗噪稳定性优于k-means)后发现,MCA(经碎石图选取前5个主成分,解释约75%方差)得到的簇更清晰,k=5时轮廓系数达到明显最大值。同样将Autoencoder的瓶颈维度设为5,提取的特征聚类效果却差很多,目前问题似乎出在瓶颈层数据存在失真。

已对层数、学习率、批量大小等超参数做随机搜索,但没有实质性改善;训练集与验证集损失相近,约40轮后稳定在0.15左右。也查找过相关研究,但没找到有用信息,以下是Autoencoder的构建代码,恳请排查是否是超参数或架构细节问题。

import numpy as np
import tensorflow as tf
from tensorflow.keras.layers import Input, Dense
from tensorflow.keras.models import Model
from tensorflow.keras.optimizers import Adam
import matplotlib.pyplot as plt


input_dim = 31
layer_1_dim = 18
layer_2_dim = 10
bottleneck_dim = 5
learning_rate = 0.001
epochs = 100
batch_size = 300


# split data into training and validation
training_n = int(data.shape[0] * 0.8)
train_data = data[:training_n, :]
val_data = data[training_n:, :]

# define autoencoder initializer
initializer = tf.keras.initializers.GlorotUniform()

# autoencoder layers
input_layer = Input(shape=(input_dim,))
layer = Dense(layer_1_dim, activation='relu')(input_layer)
layer = Dense(layer_2_dim, activation='relu', kernel_initializer=initializer)(layer)
layer = Dense(bottleneck_dim, activation='relu', kernel_initializer=initializer, name="bottleneck-output")(layer)
layer = Dense(layer_2_dim, activation='relu', kernel_initializer=initializer)(layer) 
layer = Dense(layer_1_dim, activation='relu', kernel_initializer=initializer)(layer)
output_layer = Dense(input_dim, activation='sigmoid', kernel_initializer=initializer)(layer)

# define and compile autoencoder model
autoencoder = Model(inputs=input_layer, outputs=output_layer)
optimizer = Adam(learning_rate=learning_rate)
autoencoder.compile(optimizer=optimizer, loss='binary_crossentropy')

# train the autoencoder model
history = autoencoder.fit(train_data, train_data, epochs=epochs, batch_size=batch_size, validation_data=(val_data, val_data))

# get bottleneck output
bottleneck_autoencoder = Model(inputs=autoencoder.input, outputs=autoencoder.get_layer('bottleneck-output').output)
bottleneck_output = bottleneck_autoencoder.predict(data)

# plot loss in traning and validation set
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('Autoencoder loss (binary cross-entropy)')
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.legend(['Train', 'Validation'], loc='upper right')
plt.savefig('output/embedding.png')

可能的问题与优化方向

1. 瓶颈层激活函数不合理

当前瓶颈层使用relu激活,会导致部分神经元输出为0,造成有效信息丢失。对于二值数据的降维,瓶颈层更适合用线性激活(无激活函数),保留连续的数值分布,更利于后续聚类:

layer = Dense(bottleneck_dim, activation=None, kernel_initializer=initializer, name="bottleneck-output")(layer)

2. 模型容量与结构匹配问题

当前编码器和解码器为对称结构,但中间层维度可能不足以捕捉二值数据的复杂关联:

  • 可尝试简化结构,直接从31维压缩到5维,跳过中间的18、10层,避免过度压缩导致信息损耗
  • 也可增加中间层维度,比如将layer_1_dim设为64、layer_2_dim设为32,提升模型的特征学习容量

3. 加入稀疏约束强化特征区分度

在瓶颈层加入L1正则,强制模型学习更稀疏、更具区分度的特征,适配聚类需求:

layer = Dense(bottleneck_dim, activation=None, kernel_initializer=initializer, 
              activity_regularizer=tf.keras.regularizers.L1(1e-4), name="bottleneck-output")(layer)

4. 优化训练策略

  • 增大批量大小(如1024),50000样本的数据集用300批量偏小,易导致训练不稳定
  • 加入早停机制,当验证损失不再下降时停止训练,避免无效迭代并保留最优权重:
from tensorflow.keras.callbacks import EarlyStopping
early_stop = EarlyStopping(monitor='val_loss', patience=10, restore_best_weights=True)
history = autoencoder.fit(train_data, train_data, epochs=epochs, batch_size=batch_size, 
                          validation_data=(val_data, val_data), callbacks=[early_stop])

5. 调整数据预处理与输出配置

将二值数据转换为[-1,1]区间,配合tanh输出层与MSE损失,可能提升模型对二值特征的拟合能力:

# 数据转换
train_data = 2 * train_data - 1
val_data = 2 * val_data - 1

# 修改输出层激活与损失函数
output_layer = Dense(input_dim, activation='tanh', kernel_initializer=initializer)(layer)
autoencoder.compile(optimizer=optimizer, loss='mse')

内容的提问来源于stack exchange,提问作者display-name-is-missing

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 11:05:14