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.1401742102450195
violation: 0.061581950654932265
violation: 0.03477774452872503
violation: 0.023155912689776934
violation: 0.01628956483660722
violation: 0.011732197722809824
violation: 0.009261179153190028
violation: 0.007770502529914469
violation: 0.006957471610159097
violation: 0.0064574143703551865
violation: 0.0061911151252819
violation: 0.006057238974457559
violation: 0.006000777806339346
violation: 0.0058683578913088065
violation: 0.005802918028533946
violation: 0.005772367658829752
violation: 0.005756947971778015
violation: 0.005733332889919005
violation: 0.0057006066246449725
violation: 0.005667827078790806
violation: 0.005587736630048296
violation: 0.005529135183167096
violation: 0.00546076067407594
violation: 0.005375194673451687
violation: 0.005288054442074941
violation: 0.005203284939611594
violation: 0.005110269931845304
violation: 0.005004969613317427
violation: 0.004889401944567221
violation: 0.004778610916794573
violation: 0.0046570407052725984
violation: 0.004527642308383079
violation: 0.004393717477174767
violation: 0.004267124138925867
violation: 0.004133928133016069
violation: 0.004012755928138727
violation: 0.003891465351926821
violation: 0.003765260270042751
violation: 0.003637514821862858
violation: 0.003514710166154475
violation: 0.0033965138303583588
violation: 0.0032925205579806232
violation: 0.003194164813272195
violation: 0.003104947029333712
violation: 0.0030221674035500576
violation: 0.002938964639033844
violation: 0.002856115850045703
violation: 0.002773891218680406
violation: 0.002692711668736625
violation: 0.0026129548289078666
violation: 0.002535164470212189
violation: 0.002458740363438106
violation: 0.0023842026907910266
violation: 0.0023133039094785173
violation: 0.0022437367434814427
violation: 0.002175116992578687
violation: 0.002108409449092379
violation: 0.002043667805247778
violation: 0.0019806643593508594
violation: 0.0019243270194360034
violation: 0.001871326163205714
violation: 0.001819567820069839
violation: 0.001769274901286672
violation: 0.0017204657491193588
violation: 0.0016731692686998655
violation: 0.0016274950351471652
violation: 0.0015839173329699442
violation: 0.0015418960309271765
violation: 0.0015014385431316435
violation: 0.001462927201216058
violation: 0.0014262081321618528
violation: 0.0013907597658089582
violation: 0.00136015828051582
violation: 0.0013328464824004477
violation: 0.001306592398823352
violation: 0.001281335749481067
violation: 0.0012569657401119933
violation: 0.0012363658727397604
violation: 0.0012190114699551745
violation: 0.001199211654450208
violation: 0.0011775622624515748
violation: 0.0011582609085415273
violation: 0.0011389415923631326
violation: 0.0011199124929361674
violation: 0.0011006754884535456
violation: 0.0010832777040277418
violation: 0.0010661363692305711
violation: 0.0010491933694700493
violation: 0.0010318244102609426
violation: 0.001015079232123545
violation: 0.0009988201809302114
violation: 0.0009841318528817226
violation: 0.0009699922960876842
violation: 0.0009545966012007475
violation: 0.0009396363331386256
violation: 0.0009266599168144139
violation: 0.0009140262172601255
violation: 0.0009015875006379739
violation: 0.0008902182357109091
violation: 0.0008780499311870553
violation: 0.0008660457470918176
violation: 0.0008543517499938851
violation: 0.0008428706003287468
violation: 0.0008315536804368636
violation: 0.0008208847158799463
violation: 0.00081042698077657
violation: 0.000799752248473481
violation: 0.0007893350738953559
violation: 0.0007791326607912741
violation: 0.0007691414390016423
violation: 0.0007597179067851808
violation: 0.0007504652538890883
violation: 0.0007412456856972428
violation: 0.000732296617053917
violation: 0.0007235915691686236
violation: 0.0007151920055395749
violation: 0.0007069372346704943
violation: 0.0006987637535249822
violation: 0.000690773355082284
violation: 0.0006830298779800764
violation: 0.0006754181243921606
violation: 0.0006679795936493902
violation: 0.0006606893398232923
violation: 0.0006536091296353378
violation: 0.0006466641120993949
violation: 0.0006399762615477144
violation: 0.0006335488650773121
violation: 0.0006273957420689223
violation: 0.0006215236000713394
violation: 0.000616151820375796
violation: 0.0006113918151771438
violation: 0.000607125173613368
violation: 0.0006030938520872195
violation: 0.0005992255771889807
violation: 0.0005955122189365321
violation: 0.0005919356405960497
violation: 0.0005884735105286606
violation: 0.0005851626197892168
violation: 0.0005819472966804465
violation: 0.0005788624242479865
violation: 0.0005759087479597454
violation: 0.0005730546137309274
violation: 0.000570296860098721
violation: 0.0005676053787181987
violation: 0.0005650176785172125
violation: 0.0005624480584370263
violation: 0.0005599281471046751
violation: 0.0005574208102719973
violation: 0.000554993090751032
violation: 0.0005526263090687532
violation: 0.0005503237863508764
violation: 0.0005480875748005724
violation: 0.0005458976082895555
violation: 0.0005437570853968428
violation: 0.0005416726314725618
violation: 0.000539632958222077
violation: 0.0005376381718606552
violation: 0.0005358628850811806
violation: 0.0005342566446342101
violation: 0.0005327134944355384
violation: 0.000531170025617819
violation: 0.0005296374901746361
violation: 0.0005281469649348817
violation: 0.0005266549474160894
violation: 0.0005251860718891862
violation: 0.0005237318107593949
violation: 0.0005222955570668194
violation: 0.0005208942964237043
violation: 0.0005195265168842367
violation: 0.0005181813428111001
violation: 0.0005168846752737317
violation: 0.0005156608680268734
violation: 0.0005144616554313512
violation: 0.0005132891688190957
violation: 0.0005121515266404877
violation: 0.0005110364330896266
violation: 0.0005099447315067341
violation: 0.0005088753613795146
violation: 0.0005078236610580725
violation: 0.000506790911202268
violation: 0.0005057740763563934
violation: 0.0005047767175616544
violation: 0.0005037958933648376
violation: 0.0005028222129279222
violation: 0.0005018650428477881
violation: 0.0005009224423796476
violation: 0.0004999974962487199
violation: 0.000499087239519841
violation: 0.0004981962000747332
violation: 0.0004973147318189154
violation: 0.0004964417296740981
violation: 0.0004955753197881298
violation: 0.0004946901218458151
violation: 0.0004938210437305635
violation: 0.0004929673596845518
violation: 0.000492122635584602
violation: 0.0004912871202792031
violation: 0.0004904596528541679
violation: 0.000489637645653223
/home/runner/work/spectrochempy/spectrochempy/.venv/lib/python3.13/site-packages/sklearn/decomposition/_nmf.py:1720: ConvergenceWarning: Maximum number of iterations 200 reached. Increase it to improve convergence.
  warnings.warn(
violation: 1.0
violation: 0.27811881011285355
violation: 0.21103839273442096
violation: 0.1636589757375501
violation: 0.12638124502857304
violation: 0.09689398092858
violation: 0.0738655391352644
violation: 0.05726304883639153
violation: 0.04639710696895119
violation: 0.037762701010724514
violation: 0.030324671559648606
violation: 0.024000077998569857
violation: 0.018705054318855625
violation: 0.014282427091628176
violation: 0.010676123451468766
violation: 0.008016534827385896
violation: 0.006238616114828377
violation: 0.005124394633030212
violation: 0.004490757479656622
violation: 0.004053115751123457
violation: 0.0037443026036689583
violation: 0.0034289628116609292
violation: 0.0030323190347559988
violation: 0.0027272537391467956
violation: 0.0023865056940471033
violation: 0.0020851628627841083
violation: 0.001769748469516271
violation: 0.0014925716272857989
violation: 0.0012488601974045247
violation: 0.0010438675111377664
violation: 0.0008573236692762294
violation: 0.0006991377766200634
violation: 0.0005706218431927171
violation: 0.0004636286240955753
violation: 0.00037487235479898126
violation: 0.0003032579084427427
violation: 0.00024636638593842345
violation: 0.00019825804790409252
violation: 0.00015827733519297729
violation: 0.0001243907579281729
violation: 9.611089606614148e-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.118 seconds)