PCA e a divisão de treinamento / teste / validação

Aug 19 2020

Eu tenho um problema de classificação binária com 1.149 observações e 13.454 preditores. Pretendo aplicar a metodologia descrita por cbeleites descontentes com o SX no PCA e na divisão trem / teste .

Nesse contexto, tenho duas perguntas:

(i) Se eu fizer uma pesquisa em grade do número de PCs a serem usados, é incorreto testar um número de PCs a serem usados ​​que seja maior do que o número de observações no conjunto de teste? Parece intuitivo para mim que o número máximo de PCs que devem ser testados na pesquisa de grade deve ser igual ou inferior ao número de observações no conjunto de teste (supostamente para evitar uma situação p >> n).

(ii) É mais correto usar um conjunto de retenção? ou seja, primeiro use a validação cruzada de 10 vezes para encontrar o número ideal de PCs usando 90% dos dados conforme descrito por cbeleites insatisfeitos com SX , em seguida, ajuste um novo estimador usando o número ideal de PCs usando todos os dados que foram usados ​​no primeiro passo prever a probabilidade das classes do conjunto de resistência?

EDITAR Só para ficar mais claro, meu código é parecido com este:

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)

Esta é uma abordagem incorreta / tendenciosa?

Respostas

gunes Aug 19 2020 at 01:30

i) Sim, o número de PCs deve ser menor ou igual ao número de observações porque a matriz de dados (assume média normalizada sem perda de generalidade), $X_{n\times p}$, tem classificação $\leq \min(n,p)=n$, nesse caso. $X^TX$ terá classificação $\leq n$ também porque $\text{rank}(AB)\leq \text{rank}(A)$.

ii) Como você tem um pequeno número de observações, o uso da validação cruzada na escolha do melhor número de PCs pode ser melhor. Você precisa encontrar um critério (por exemplo, cobertura de 95% de variância) e um esquema de votação adequado para a fusão de decisões provenientes de diferentes dobras. No final, você pode usar todos os seus dados de treinamento para encontrar os PCs. O conjunto de teste deve ser separado desde o início, ou seja, você não deve usá-lo nem mesmo para selecionar o número de PCs.