用于聚类的二值数据集降维: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
相关产品推荐
相关产品推荐

