如何将训练完成的PCA模型应用到无标签加速度计新数据上
已训练PCA模型迁移到无标签新数据的实现方法
核心逻辑非常简单:sklearn中所有通过fit()方法训练得到的预处理器、模型对象,只要不重新执行拟合操作,直接调用transform()方法即可按照训练集学到的映射规则处理新数据。你之前找不到对应方法,核心是原代码里没有保存拟合好的标准化器和PCA对象,且容易踩「在新数据上重新拟合」的坑。
现有代码的问题
你当前的代码中,StandardScaler是匿名实例化后直接调用fit_transform(),拟合完成后对象就被回收了,无法复用到新数据上;同时很多人容易犯的错误是处理新数据时重新调用fit()/fit_transform(),导致新的标准化规则、PCA主成分方向和原训练集不一致,投影结果完全失真。
具体实现步骤
1. 修改原训练代码,持久化拟合好的对象
首先调整原训练逻辑,把标准化器、PCA模型都赋值给独立变量,训练完成后可以保存到本地,方便跨脚本/跨时间调用:
import pandas as pd import os import joblib from sklearn.preprocessing import StandardScaler import matplotlib.pyplot as plt from sklearn.decomposition import PCA os.chdir(r'C:\Users\##\OneDrive - ##\##\Pyth\data\runFlume1') # 读入带标签训练数据 df = pd.read_csv('dataframe_0.csv', delimiter=',', names = ['x','y','z','gradient_x','gradient_y','gradient_z','target']) features = ['x', 'y', 'z'] x = df.loc[:, features].values y = df.loc[:,['target']].values # 实例化标准化器,用训练数据拟合,不要用匿名对象 scaler = StandardScaler() x_scaled = scaler.fit_transform(x) # 实例化PCA并拟合 pca = PCA(n_components=2) principalComponents = pca.fit_transform(x_scaled) # 保存拟合好的两个对象到本地,后续处理新数据直接加载即可 joblib.dump(scaler, 'acc_pca_scaler.pkl') joblib.dump(pca, 'acc_trained_pca.pkl') # 后续原有的可视化逻辑不需要改动 principalDf = pd.DataFrame(data = principalComponents , columns = ['principal component 1', 'principal component 2']) finalDf = pd.concat([principalDf, df[['target']]], axis = 1) # ...... 省略你原有的绘图代码
2. 无标签新数据转换逻辑
处理新数据时,只需要加载之前保存的模型,仅调用transform()方法即可:
import pandas as pd import joblib # 加载已训练好的预处理器和PCA模型 scaler = joblib.load('acc_pca_scaler.pkl') pca = joblib.load('acc_trained_pca.pkl') # 读入无标签新数据,必须保证包含和训练时完全一致的x/y/z三个特征列 new_df = pd.read_csv('your_new_unlabeled_data.csv') features = ['x', 'y', 'z'] x_new = new_df.loc[:, features].values # 用训练集的均值/方差做标准化 x_new_scaled = scaler.transform(x_new) # 用训练好的PCA主成分方向做投影 new_data_pca = pca.transform(x_new_scaled) # 转换为DataFrame,可直接用于后续分析、和原标签数据混合可视化 new_pca_df = pd.DataFrame( data=new_data_pca, columns=['principal component 1', 'principal component 2'] )
关键注意事项
核心红线:处理新数据时,不管是
StandardScaler还是PCA对象,都只能调用transform(),绝对不能调用fit()或fit_transform()。一旦重新拟合,就会基于新数据的分布重新计算标准化参数、主成分方向,得到的投影结果和原训练集的投影空间完全不匹配,没有任何对比意义。
- 必须保证新数据的特征顺序、特征含义和训练时完全一致:训练时输入的是
['x','y','z']的原始加速度值,新数据就不能传入梯度列,也不能调换x/y/z的顺序,否则转换结果完全错误。 - 如果你是在同一个脚本内跑完训练数据立刻处理新数据,不需要执行
joblib存/读的操作,直接用已经拟合完成的scaler和pca对象调用transform()即可。 - 如果你需要把新数据的投影结果和原标签数据的投影画在同一张图里对比,直接复用原绘图代码的坐标轴配置即可,两者的投影空间是完全对齐的。
内容的提问来源于stack exchange,提问作者SimonDL
相关产品推荐
相关产品推荐

