Partial Least Squares (PLS), Kernel-based Orthogonal Projections to Latent Structures (K-OPLS) and NIPALS based OPLS
PLS regression algorithm based on the Yi Cao implementation:
K-OPLS regression algorithm based on this paper.
OPLS implementation based on the R package Metabomate using NIPALS factorization loop.
$ npm i ml-pls
import{PLS}from'ml-pls';constX=[[0.1,0.02],[0.25,1.01],[0.95,0.01],[1.01,0.96],];constY=[[1,0],[1,0],[1,0],[0,1],];constoptions={latentVectors: 10,tolerance: 1e-4,};constpls=newPLS(options);pls.train(X,Y);import{getNumbers,getClassesAsNumber,getCrossValidationSets,}from'ml-dataset-iris';import{OPLS}from'ml-pls';constcvFolds=getCrossValidationSets(7,{idx: 0,by: 'trainTest'});constdata=getNumbers();constirisLabels=getClassesAsNumber();constmodel=newOPLS(data,irisLabels,{ cvFolds });console.log(model.mode);// 'regression'The OPLS class is intended for exploratory modeling, that is not for the creation of predictors. Therefore there is a built-in k-fold cross-validation loop and Q2y is an average over the folds. Q2y is an array with one entry per fitted component:
console.log(model.model[0].Q2y[0]);should give 0.9209227614652846
import{getNumbers,getClasses,getCrossValidationSets,}from'ml-dataset-iris';import{OPLS}from'ml-pls';constcvFolds=getCrossValidationSets(7,{idx: 0,by: 'trainTest'});constdata=getNumbers();constirisLabels=getClasses();constmodel=newOPLS(data,irisLabels,{ cvFolds });console.log(model.mode);// 'discriminantAnalysis'// auc is an array with one entry per fitted componentconsole.log(model.model[0].auc[0]);// 0.6816If for some reason a predictor is necessary the following code may serve as an example
import{getNumbers,getClassesAsNumber,getCrossValidationSets,}from'ml-dataset-iris';import{OPLS}from'ml-pls';// get frozen folds for testing purposesconst{ testIndex, trainIndex }=getCrossValidationSets(7,{idx: 0,by: 'trainTest',})[0];// Getting the data of selected foldconstirisNumbers=getNumbers();consttestData=irisNumbers.filter((el,idx)=>testIndex.includes(idx));consttrainingData=irisNumbers.filter((el,idx)=>trainIndex.includes(idx));// Getting the labels of selected foldconstirisLabels=getClassesAsNumber();consttestLabels=irisLabels.filter((el,idx)=>testIndex.includes(idx));consttrainingLabels=irisLabels.filter((el,idx)=>trainIndex.includes(idx));constmodel=newOPLS(trainingData,trainingLabels);console.log(model.mode);// 'regression'constprediction=model.predict(testData,{trueLabels: testLabels});// Get the predicted Q2 valueconsole.log(prediction.Q2y);// 0.9243354801393767importKernelfrom'ml-kernel';import{KOPLS}from'ml-pls';constkernel=newKernel('gaussian',{sigma: 25,});constX=[[0.1,0.02],[0.25,1.01],[0.95,0.01],[1.01,0.96],];constY=[[1,0],[1,0],[1,0],[0,1],];constcls=newKOPLS({orthogonalComponents: 10,predictiveComponents: 1,kernel: kernel,});cls.train(X,Y);const{
prediction,// prediction
predScoreMat,// Score matrix over prediction
predYOrthVectors,// Y-Orthogonal vectors over prediction}=cls.predict(X);console.log(prediction);console.log(predScoreMat);console.log(predYOrthVectors);