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) wich correspond to saturated part of the spectra. Note taht 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 fonctionalities 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

model.fit(dataset)
# Get the results
# ---------------
#
# The concentration :math:`C` and the transposed matrix of spectra :math:`S^T` can
# be obtained as follow
C = model.transform()
St = model.components
violation: 1.0
violation: 0.14017421024502041
violation: 0.06158195065493267
violation: 0.0347777445287253
violation: 0.023155912689776938
violation: 0.01628956483660748
violation: 0.011732197722809833
violation: 0.00926117915319011
violation: 0.007770502529914483
violation: 0.006957471610159211
violation: 0.006457414370354846
violation: 0.006191115125282067
violation: 0.006057238974457611
violation: 0.006000777806339554
violation: 0.005868357891308898
violation: 0.005802918028533922
violation: 0.005772367658829914
violation: 0.005756947971777885
violation: 0.00573333288991907
violation: 0.005700606624644977
violation: 0.00566782707879076
violation: 0.005587736630048396
violation: 0.005529135183167129
violation: 0.005460760674075842
violation: 0.005375194673451756
violation: 0.005288054442075032
violation: 0.005203284939611525
violation: 0.005110269931845334
violation: 0.005004969613317457
violation: 0.004889401944567234
violation: 0.004778610916794628
violation: 0.004657040705272501
violation: 0.00452764230838307
violation: 0.004393717477174954
violation: 0.0042671241389256286
violation: 0.004133928133016143
violation: 0.004012755928138879
violation: 0.0038914653519268017
violation: 0.003765260270042613
violation: 0.003637514821862858
violation: 0.003514710166154396
violation: 0.003396513830358391
violation: 0.003292520557980715
violation: 0.003194164813272314
violation: 0.0031049470293335116
violation: 0.0030221674035500524
violation: 0.002938964639033761
violation: 0.002856115850045505
violation: 0.0027738912186804432
violation: 0.002692711668736953
violation: 0.0026129548289077764
violation: 0.002535164470212207
violation: 0.0024587403634380757
violation: 0.002384202690791301
violation: 0.0023133039094783495
violation: 0.0022437367434812974
violation: 0.0021751169925787145
violation: 0.0021084094490926263
violation: 0.0020436678052479043
violation: 0.0019806643593505645
violation: 0.0019243270194357657
violation: 0.001871326163205807
violation: 0.0018195678200695568
violation: 0.0017692749012867995
violation: 0.001720465749119268
violation: 0.00167316926869969
violation: 0.00162749503514714
violation: 0.001583917332970141
violation: 0.0015418960309273543
violation: 0.0015014385431315615
violation: 0.001462927201215993
violation: 0.0014262081321618793
violation: 0.0013907597658088567
violation: 0.0013601582805157447
violation: 0.001332846482400469
violation: 0.0013065923988234882
violation: 0.0012813357494812464
violation: 0.0012569657401120319
violation: 0.0012363658727397807
violation: 0.0012190114699550743
violation: 0.001199211654450114
violation: 0.0011775622624512873
violation: 0.0011582609085416242
violation: 0.001138941592363325
violation: 0.001119912492936014
violation: 0.0011006754884539882
violation: 0.001083277704027657
violation: 0.0010661363692306795
violation: 0.0010491933694701846
violation: 0.001031824410260743
violation: 0.001015079232123992
violation: 0.0009988201809301264
violation: 0.0009841318528817729
violation: 0.0009699922960875574
violation: 0.0009545966012008706
violation: 0.0009396363331385377
violation: 0.000926659916814387
violation: 0.0009140262172600321
violation: 0.0009015875006374982
violation: 0.0008902182357106645
violation: 0.0008780499311868962
violation: 0.0008660457470919061
violation: 0.0008543517499939036
violation: 0.0008428706003289161
violation: 0.0008315536804371906
violation: 0.000820884715880313
violation: 0.0008104269807765193
violation: 0.0007997522484735471
violation: 0.0007893350738953518
violation: 0.0007791326607915071
violation: 0.0007691414390020002
violation: 0.0007597179067854188
violation: 0.0007504652538891348
violation: 0.0007412456856972278
violation: 0.0007322966170541202
violation: 0.0007235915691686499
violation: 0.0007151920055394382
violation: 0.0007069372346703667
violation: 0.0006987637535246366
violation: 0.0006907733550825812
violation: 0.0006830298779798872
violation: 0.0006754181243923978
violation: 0.0006679795936492528
violation: 0.0006606893398229733
violation: 0.0006536091296352499
violation: 0.0006466641120995417
violation: 0.0006399762615475603
violation: 0.0006335488650770339
violation: 0.0006273957420692294
violation: 0.0006215236000712418
violation: 0.0006161518203754807
violation: 0.0006113918151772443
violation: 0.0006071251736134421
violation: 0.0006030938520871471
violation: 0.0005992255771887147
violation: 0.0005955122189366687
violation: 0.0005919356405961311
violation: 0.0005884735105285491
violation: 0.0005851626197891424
violation: 0.0005819472966805701
violation: 0.0005788624242481255
violation: 0.0005759087479597093
violation: 0.0005730546137307119
violation: 0.0005702968600986298
violation: 0.0005676053787181434
violation: 0.0005650176785172587
violation: 0.0005624480584369683
violation: 0.0005599281471047185
violation: 0.0005574208102720135
violation: 0.0005549930907515299
violation: 0.0005526263090687214
violation: 0.0005503237863512744
violation: 0.0005480875748009416
violation: 0.0005458976082896048
violation: 0.0005437570853969354
violation: 0.0005416726314724905
violation: 0.0005396329582219294
violation: 0.0005376381718606437
violation: 0.0005358628850810331
violation: 0.0005342566446345556
violation: 0.000532713494435716
violation: 0.0005311700256180445
violation: 0.0005296374901746347
violation: 0.0005281469649349101
violation: 0.0005266549474162894
violation: 0.0005251860718894278
violation: 0.0005237318107588684
violation: 0.000522295557066357
violation: 0.0005208942964239038
violation: 0.0005195265168844733
violation: 0.0005181813428112534
violation: 0.0005168846752735063
violation: 0.0005156608680271015
violation: 0.0005144616554312485
violation: 0.0005132891688188079
violation: 0.0005121515266401841
violation: 0.0005110364330893946
violation: 0.0005099447315065514
violation: 0.0005088753613790898
violation: 0.000507823661058193
violation: 0.0005067909112023937
violation: 0.0005057740763560116
violation: 0.0005047767175615771
violation: 0.0005037958933647958
violation: 0.0005028222129278192
violation: 0.0005018650428478386
violation: 0.0005009224423798432
violation: 0.0004999974962487583
violation: 0.0004990872395198337
violation: 0.0004981962000747596
violation: 0.0004973147318189917
violation: 0.0004964417296742836
violation: 0.0004955753197879101
violation: 0.0004946901218457972
violation: 0.0004938210437306547
violation: 0.0004929673596846137
violation: 0.0004921226355847229
violation: 0.0004912871202793357
violation: 0.0004904596528538642
violation: 0.0004896376456532529
/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(
violation: 1.0
violation: 0.27811881011284917
violation: 0.21103839273441807
violation: 0.16365897573754845
violation: 0.1263812450285721
violation: 0.09689398092857968
violation: 0.07386553913526442
violation: 0.05726304883639126
violation: 0.04639710696895095
violation: 0.03776270101072437
violation: 0.030324671559648506
violation: 0.02400007799856987
violation: 0.018705054318855694
violation: 0.014282427091628313
violation: 0.010676123451468827
violation: 0.008016534827385884
violation: 0.0062386161148284165
violation: 0.005124394633030145
violation: 0.004490757479656501
violation: 0.004053115751123361
violation: 0.003744302603668814
violation: 0.003428962811660854
violation: 0.0030323190347559164
violation: 0.0027272537391467653
violation: 0.002386505694047059
violation: 0.002085162862784081
violation: 0.0017697484695162445
violation: 0.0014925716272857696
violation: 0.001248860197404516
violation: 0.0010438675111378026
violation: 0.0008573236692762445
violation: 0.0006991377766200931
violation: 0.0005706218431927264
violation: 0.0004636286240955476
violation: 0.0003748723547990016
violation: 0.0003032579084427284
violation: 0.0002463663859384371
violation: 0.00019825804790408585
violation: 0.0001582773351929951
violation: 0.00012439075792820687
violation: 9.611089606619722e-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
[]

This ends the example ! The following line can be uncommented if no plot shows when running the .py script with python

# scp.show()

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