¿Cuál es el mejor método para la reducción de dimensionalidad y la selección / extracción de características en datos de espectrometría de masas?

Estoy interesado en este tema también. Cuando pregunté a mis colegas al respecto, Bern y Yates me señalaron este documento desde 2004. Uno de sus enfoques fue una especie de selección hecha a mano de características, como el número de picos, el estado de carga, la intensidad de los pares de picos que suma a un aminoácido, tiempo de inyección de iones, cosas como esta. Puedes leer más sobre esto aquí.

Evaluación automática de la calidad de los espectros de masas de péptidos en tándem.

Una idea interesante que surge de esto es transformar los espectros de masas en “espectros de diferencia”, donde se agrega o multiplica la intensidad de pares de picos en cada posible diferencia de m / z. Entonces, para los espectros de péptido MS / MS, obtienes picos en cada masa de aminoácidos, por ejemplo. Si desea diferenciar entre los grupos “péptido” y “no péptido”, esto podría ayudar. Esta era una forma diferente de pensar sobre los espectros de masas para mí, y puede prestarse a ser la base de un clasificador. Con datos como este, se pueden buscar representaciones de dimensiones reducidas de los grupos utilizando técnicas basadas en PCA, como estimar los valores propios y los vectores propios de las matrices de covarianza de los datos para estos grupos, mantener los vectores propios correspondientes a los valores propios más grandes y multiplicar estos restantes vectores propios por los datos. El vector de características de dimensión reducida resultante podría usarse para fines de clasificación.

Ejemplos de espectros de masas convertidos en espectros de diferencia

Una función para calcular espectros de diferencia

void ComputeMassDifferences (MatrixXf & raw, VectorXf & diff, float precursorMass) {
flotante maxIntensity = 1e-6f;
umbral de flotación = 0.0f; // raw.col (INTENSITY) .maxCoeff () * 0.1;
for (int idx = 0; idx <raw.rows (); idx ++) {
float inten1 = raw (idx, INTENSITY);
if (inten1> umbral) {
float mass1 = raw (idx, MASS);
if (! IsInPrecursorRegion (mass1, precursorMass)) {
for (int jdx = idx + 1; jdx <raw.rows (); jdx ++) {
float mass2 = raw (jdx, MASS);
if (! IsInPrecursorRegion (mass2, precursorMass)) {
float inten2 = raw (jdx, INTENSITY);
// no nos importa la diferencia de 0, en virtud de jdx = idx + 1, por lo que podemos restar 1
int massDifference = (int) abs (mass2 – mass1) – 1;
if (massDifference> = 0 && massDifference <diff.rows ()) {

// agrega las intensidades de los dos picos
// multiplica esto?
diff [massDifference] + = (inten1 + inten2);

maxIntensity = max (maxIntensity, diff [massDifference]);
}
// si la diferencia de masa es mayor que el número de filas, podemos dividir, lo que podría acelerarlo
más si (massDifference> diff.rows ()) se rompe;
}
}
}
}
}
// normalizar al máximo
// diff = diff / maxIntensity;
}