我正在scikitlearn(python3上的0.20)中探索PCA,使用Pandas构建数据。当我应用测试/训练分割(并且仅当),我的输入标签似乎不再与PCA输出匹配。你知道吗
import pandas
import sklearn.datasets
from matplotlib import pyplot
import seaborn
def load_bc_as_dataframe():
data = sklearn.datasets.load_breast_cancer()
df = pandas.DataFrame(data.data, columns=data.feature_names)
df['diagnosis'] = pandas.Series(data.target_names[data.target])
return data.feature_names.tolist(), df
feature_names, bc_data = load_bc_as_dataframe()
from sklearn.model_selection import train_test_split
# bc_train, _ = train_test_split(bc_data, test_size=0)
bc_train = bc_data
from sklearn.decomposition import PCA
pca = PCA(n_components=2)
bc_pca_raw = pca.fit_transform(bc_train[feature_names])
bc_pca = pandas.DataFrame(bc_pca_raw, columns=('PCA 1', 'PCA 2'))
bc_pca['diagnosis'] = bc_train['diagnosis']
seaborn.scatterplot(
data=bc_pca,
x='PCA 1',
y='PCA 2',
hue='diagnosis',
style='diagnosis'
)
pyplot.show()
这看起来很合理,准确的分类结果也证明了这一点。如果我将bc_train = bc_data
替换为train_test_split()
调用(即使使用test_size=0
),我的标签似乎不再与原始标签对应。你知道吗
我意识到train_test_split()
正在洗牌我的数据(通常我希望它洗牌),但我不明白为什么这会是一个问题,因为PCA和标签分配使用相同的洗牌数据。PCA的变换只是一个投影,虽然它显然没有保留相同的特征(列),但它不应该改变哪个标签与哪个帧匹配。你知道吗
如何正确重新标记PCA输出?你知道吗
这个问题有三个部分:
train_test_split()
中的洗牌导致bc_train
中的索引处于随机顺序(与行位置相比)。你知道吗DataFrame
会重新创建顺序索引(与行位置相比)。你知道吗bc_train
中有随机索引,在bc_pca
中有顺序索引。当我做bc_pca['diagnosis'] = bc_train['diagnosis']
时,bc_train
是reindexed,有bc_pca
s索引。这将重新排序bc_train
数据,使其索引与bc_pca
匹配换句话说,当我用} )。你知道吗
bc_pca['diagnosis']
(即__setitem__()
)赋值时,Pandas对索引进行左连接,而不是逐行复制(类似于^{我不觉得这很直观,也找不到源代码以外的
__setitem__()
行为文档,但我希望这对更有经验的Pandas用户来说是有意义的,也许它是在一个我从未见过的更高级别的地方被记录的。你知道吗有很多方法可以避免这种情况。我可以重置训练/测试数据的索引:
或者,我可以从
values
成员分配:在构建数据帧之前,我也可以做类似的事情(可以说更合理,因为PCA在
bc_train[feature_names].values
上有效地运行)。你知道吗相关问题 更多 >
编程相关推荐