PCA et la division train / test / validation
J'ai un problème de classification binaire avec 1149 observations et 13 454 prédicteurs. Je souhaite appliquer la méthodologie décrite par des cbeleites mécontents de SX en PCA et du partage train / test .
Dans ce contexte, j'ai deux questions:
(i) Si je fais une recherche de grille pour le nombre de PC à utiliser, est-il incorrect de tester un nombre de PC à utiliser qui est supérieur au nombre d'observations dans l'ensemble de test? Il me semble intuitif que le nombre maximal de PC qui devraient être testés dans la recherche de grille doit être égal ou inférieur au nombre d'observations dans l'ensemble de test (censé empêcher une situation p >> n).
(ii) Est-il plus correct d'utiliser un ensemble de retenue? c'est-à-dire utiliser d'abord la validation croisée par 10 pour trouver le nombre optimal de PC en utilisant 90% des données comme décrit par les cbeleites mécontents de SX , puis ajuster un nouvel estimateur en utilisant le nombre optimal de PC en utilisant toutes les données utilisées dans le première étape prédire la probabilité des classes de l'ensemble de retenue?
EDIT Pour être plus clair, mon code ressemble à ceci:
tests=[]
pps=[]
pcs=[]
skf=model_selection.StratifiedKFold(n_splits=10,random_state=61,shuffle=True)
for i in (2,5,10,25,50,100,114):
tmp_pps=[]
tmp_tests=[]
for train_index, test_index in skf.split(X, y):
estimator = SVC(probability=True)
pca = PCA(i, svd_solver='arpack')
scaler= StandardScaler()
X_train, X_test = X[train_index], X[test_index]
y_train, y_test = y[train_index], y[test_index]
fScaler = scaler.fit(X_train)
X_train_scaled = fScaler.transform(X_train)
X_test_scaled = fScaler.transform(X_test)
fpca = pca.fit(X_train_scaled)
X_train_PCA = pca.transform(X_train_scaled)
X_test_PCA = pca.transform(X_test_scaled)
ft = estimator.fit(X_train_PCA, y_train)
pp = estimator.predict_proba(X_test_PCA)[:, 1]
tmp_tests.append(y_test)
tmp_pps.append(pp)
tests.append(tmp_tests)
pps.append(tmp_pps)
pcs.append(i)
for i in range(len(pcs)):
pp = np.concatenate(res[i]).ravel()
y_test = np.concatenate(tests[i]).ravel()
score = roc_auc_score(y_test, pp)
print(pcs[i],score)
Est-ce une approche incorrecte / biaisée?
Réponses
i) Oui, le nombre de PC doit être inférieur ou égal au nombre d'observations car la matrice de données (suppose une moyenne normalisée sans perte de généralité), $X_{n\times p}$, a rang $\leq \min(n,p)=n$, dans ce cas. $X^TX$ aura rang $\leq n$ aussi parce que $\text{rank}(AB)\leq \text{rank}(A)$.
ii) Puisque vous avez un petit nombre d'observations, il peut être préférable d'utiliser la validation croisée pour choisir le meilleur nombre de PC. Vous devez trouver un critère (par exemple, couvrir une variance de 95%) et un système de vote approprié pour fusionner les décisions provenant de différents plis. En fin de compte, vous pouvez utiliser toutes vos données d' entraînement pour trouver les PC. L'ensemble de test doit être séparé du début, c'est-à-dire que vous ne devez pas l'utiliser même pour sélectionner le nombre de PC.