This is development documentation. Some features are not available in the stable release. View stable documentation.

NMF analysis example

Import the spectrochempy API package

import spectrochempy as scp

Prepare the dataset to NMF factorize

Here we use a FTIR dataset corresponding the dehydration of a NH4Y zeolite and recorded in the OMNIC format.

dataset = scp.read_omnic("irdata/nh4y-activation.spg")

Mask some columns (features) which correspond to saturated parts of the spectra. Note that we use float number for defining the limits for masking as coordinates (integer numbers would mean point index and s would lead t incorrect results)

dataset[:, 882.0:1280.0] = scp.MASKED

Make sure all data are positive. For this we use the math functionalities of NDDataset objects (min function to find the minimum value of the dataset and the - operator for subtrating this value to all spectra of the dataset.

Plot it for a visual check

plot nmf

Create a NMF object

As argument of the object constructor we define log_level to "INFO" to obtain verbose output during fit, and we set the number of component to use at 4.

model = scp.NMF(n_components=4, log_level="INFO")

Fit the model

violation: 1.0
violation: 0.14017421024501978
violation: 0.06158195065493221
violation: 0.03477774452872501
violation: 0.023155912689776823
violation: 0.01628956483660752
violation: 0.011732197722809609
violation: 0.009261179153190057
violation: 0.0077705025299144095
violation: 0.006957471610158959
violation: 0.006457414370355041
violation: 0.006191115125281941
violation: 0.00605723897445779
violation: 0.006000777806339436
violation: 0.005868357891308794
violation: 0.0058029180285339545
violation: 0.0057723676588296545
violation: 0.005756947971777936
violation: 0.005733332889918971
violation: 0.005700606624644993
violation: 0.005667827078790952
violation: 0.005587736630048312
violation: 0.0055291351831669765
violation: 0.00546076067407589
violation: 0.005375194673451805
violation: 0.0052880544420750054
violation: 0.005203284939611545
violation: 0.005110269931845315
violation: 0.005004969613317465
violation: 0.004889401944567091
violation: 0.004778610916794593
violation: 0.0046570407052727025
violation: 0.004527642308383069
violation: 0.0043937174771749386
violation: 0.004267124138925658
violation: 0.004133928133016254
violation: 0.004012755928138647
violation: 0.0038914653519267393
violation: 0.003765260270042767
violation: 0.0036375148218629424
violation: 0.0035147101661543727
violation: 0.0033965138303583215
violation: 0.0032925205579807768
violation: 0.0031941648132723043
violation: 0.003104947029333535
violation: 0.003022167403549754
violation: 0.002938964639033824
violation: 0.0028561158500457866
violation: 0.002773891218680556
violation: 0.002692711668736734
violation: 0.0026129548289076624
violation: 0.0025351644702122896
violation: 0.0024587403634380458
violation: 0.0023842026907913115
violation: 0.0023133039094785277
violation: 0.0022437367434807428
violation: 0.0021751169925786898
violation: 0.0021084094490922594
violation: 0.002043667805248059
violation: 0.001980664359350545
violation: 0.0019243270194358609
violation: 0.001871326163205701
violation: 0.001819567820069797
violation: 0.0017692749012866815
violation: 0.0017204657491189052
violation: 0.0016731692686994823
violation: 0.0016274950351469178
violation: 0.0015839173329699756
violation: 0.0015418960309273352
violation: 0.0015014385431314906
violation: 0.0014629272012161344
violation: 0.0014262081321621573
violation: 0.0013907597658087093
violation: 0.001360158280515712
violation: 0.001332846482400384
violation: 0.0013065923988232623
violation: 0.0012813357494812598
violation: 0.0012569657401121366
violation: 0.0012363658727398705
violation: 0.0012190114699549238
violation: 0.001199211654450186
violation: 0.0011775622624515274
violation: 0.0011582609085414863
violation: 0.0011389415923634813
violation: 0.001119912492936003
violation: 0.0011006754884536833
violation: 0.0010832777040279864
violation: 0.001066136369230457
violation: 0.001049193369469935
violation: 0.0010318244102606874
violation: 0.001015079232123502
violation: 0.0009988201809299508
violation: 0.0009841318528816649
violation: 0.0009699922960875727
violation: 0.000954596601200507
violation: 0.000939636333138409
violation: 0.0009266599168148363
violation: 0.0009140262172600672
violation: 0.0009015875006380176
violation: 0.0008902182357105717
violation: 0.0008780499311868547
violation: 0.0008660457470920251
violation: 0.0008543517499940744
violation: 0.0008428706003286759
violation: 0.0008315536804371956
violation: 0.0008208847158800266
violation: 0.0008104269807765217
violation: 0.0007997522484735853
violation: 0.0007893350738951069
violation: 0.0007791326607913865
violation: 0.0007691414390015572
violation: 0.0007597179067853403
violation: 0.0007504652538892901
violation: 0.0007412456856971612
violation: 0.0007322966170541699
violation: 0.0007235915691682001
violation: 0.0007151920055395187
violation: 0.0007069372346704164
violation: 0.0006987637535249098
violation: 0.000690773355082591
violation: 0.0006830298779800107
violation: 0.0006754181243926496
violation: 0.0006679795936492813
violation: 0.000660689339823054
violation: 0.0006536091296354339
violation: 0.0006466641120993735
violation: 0.000639976261547623
violation: 0.0006335488650772266
violation: 0.0006273957420691281
violation: 0.0006215236000710713
violation: 0.0006161518203757748
violation: 0.000611391815177429
violation: 0.0006071251736133687
violation: 0.0006030938520872772
violation: 0.0005992255771887873
violation: 0.0005955122189367935
violation: 0.0005919356405962723
violation: 0.0005884735105284439
violation: 0.0005851626197889266
violation: 0.0005819472966804671
violation: 0.0005788624242478493
violation: 0.0005759087479599911
violation: 0.0005730546137307416
violation: 0.0005702968600985684
violation: 0.0005676053787178566
violation: 0.0005650176785170801
violation: 0.0005624480584368149
violation: 0.0005599281471047554
violation: 0.0005574208102721025
violation: 0.0005549930907513811
violation: 0.0005526263090687897
violation: 0.0005503237863508481
violation: 0.0005480875748006955
violation: 0.0005458976082893933
violation: 0.0005437570853970197
violation: 0.000541672631472797
violation: 0.00053963295822222
violation: 0.0005376381718606111
violation: 0.0005358628850810123
violation: 0.0005342566446343103
violation: 0.0005327134944357346
violation: 0.0005311700256180605
violation: 0.000529637490174598
violation: 0.0005281469649345943
violation: 0.0005266549474161373
violation: 0.0005251860718895543
violation: 0.0005237318107594774
violation: 0.0005222955570666922
violation: 0.0005208942964237183
violation: 0.0005195265168842639
violation: 0.0005181813428111678
violation: 0.0005168846752737275
violation: 0.000515660868027273
violation: 0.0005144616554310434
violation: 0.0005132891688189135
violation: 0.0005121515266402728
violation: 0.0005110364330893817
violation: 0.0005099447315064996
violation: 0.000508875361379317
violation: 0.0005078236610580443
violation: 0.0005067909112021123
violation: 0.0005057740763562431
violation: 0.0005047767175615706
violation: 0.0005037958933651539
violation: 0.0005028222129276457
violation: 0.0005018650428481442
violation: 0.0005009224423797528
violation: 0.0004999974962489264
violation: 0.0004990872395196999
violation: 0.0004981962000749717
violation: 0.000497314731819205
violation: 0.0004964417296741098
violation: 0.0004955753197882271
violation: 0.0004946901218457502
violation: 0.0004938210437306786
violation: 0.0004929673596844068
violation: 0.0004921226355846822
violation: 0.0004912871202793572
violation: 0.0004904596528537678
violation: 0.0004896376456531641
/home/runner/work/spectrochempy/spectrochempy/.venv/lib/python3.13/site-packages/sklearn/decomposition/_nmf.py:1723: ConvergenceWarning: Maximum number of iterations 200 reached. Increase it to improve convergence.
  warnings.warn(

Get the results

The concentration \(C\) and the transposed matrix of spectra \(S^T\) can be obtained as follow

violation: 1.0
violation: 0.2781188101128553
violation: 0.211038392734422
violation: 0.16365897573755053
violation: 0.1263812450285727
violation: 0.0968939809285794
violation: 0.0738655391352637
violation: 0.05726304883639084
violation: 0.04639710696895044
violation: 0.03776270101072367
violation: 0.030324671559647784
violation: 0.02400007799856906
violation: 0.018705054318854837
violation: 0.014282427091627473
violation: 0.010676123451468131
violation: 0.008016534827385471
violation: 0.006238616114828137
violation: 0.005124394633030094
violation: 0.004490757479656539
violation: 0.004053115751123447
violation: 0.003744302603668902
violation: 0.00342896281166094
violation: 0.003032319034755973
violation: 0.0027272537391468004
violation: 0.002386505694047012
violation: 0.002085162862784046
violation: 0.0017697484695161896
violation: 0.0014925716272857238
violation: 0.0012488601974044455
violation: 0.001043867511137715
violation: 0.0008573236692761628
violation: 0.0006991377766200344
violation: 0.0005706218431926783
violation: 0.0004636286240955126
violation: 0.00037487235479896473
violation: 0.000303257908442684
violation: 0.0002463663859384144
violation: 0.00019825804790408018
violation: 0.00015827733519296815
violation: 0.000124390757928168
violation: 9.611089606616128e-05
Converged at iteration 42

Plot results

_ = C.T.plot(title="Concentration", colormap=None, legend=C.k.labels)
Concentration
m = St.ptp()
for i in range(St.shape[0]):
    St.data[i] -= i * m / 2
ax = St.plot(title="Components", colormap=None, legend=St.k.labels)
_ = ax.set_yticks([])
Components

Uncomment the following line to display all figures when running the script directly with Python.

# scp.show()

Total running time of the script: (0 minutes 1.162 seconds)