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.1401742102450198
violation: 0.06158195065493227
violation: 0.03477774452872503
violation: 0.023155912689776636
violation: 0.016289564836607297
violation: 0.011732197722809605
violation: 0.009261179153190264
violation: 0.007770502529914414
violation: 0.00695747161015906
violation: 0.006457414370354923
violation: 0.00619111512528209
violation: 0.006057238974457714
violation: 0.006000777806339368
violation: 0.005868357891308825
violation: 0.005802918028534199
violation: 0.0057723676588298765
violation: 0.005756947971777946
violation: 0.005733332889918965
violation: 0.005700606624644985
violation: 0.005667827078790786
violation: 0.0055877366300484035
violation: 0.005529135183166947
violation: 0.005460760674075994
violation: 0.005375194673451752
violation: 0.005288054442075066
violation: 0.00520328493961162
violation: 0.0051102699318453775
violation: 0.0050049696133176915
violation: 0.004889401944567089
violation: 0.004778610916794713
violation: 0.004657040705272716
violation: 0.004527642308382939
violation: 0.004393717477174846
violation: 0.00426712413892594
violation: 0.0041339281330161366
violation: 0.0040127559281388
violation: 0.0038914653519267557
violation: 0.0037652602700427307
violation: 0.0036375148218629107
violation: 0.0035147101661544165
violation: 0.0033965138303582126
violation: 0.0032925205579803674
violation: 0.0031941648132721096
violation: 0.0031049470293336313
violation: 0.0030221674035501027
violation: 0.0029389646390339365
violation: 0.002856115850045626
violation: 0.002773891218680528
violation: 0.002692711668736714
violation: 0.0026129548289076866
violation: 0.0025351644702121335
violation: 0.0024587403634380883
violation: 0.002384202690791052
violation: 0.0023133039094783273
violation: 0.002243736743480821
violation: 0.0021751169925784035
violation: 0.0021084094490921856
violation: 0.0020436678052478934
violation: 0.001980664359350613
violation: 0.00192432701943594
violation: 0.0018713261632060853
violation: 0.0018195678200696543
violation: 0.0017692749012866724
violation: 0.0017204657491190856
violation: 0.0016731692686998499
violation: 0.0016274950351468866
violation: 0.0015839173329702204
violation: 0.001541896030927372
violation: 0.0015014385431316901
violation: 0.001462927201215929
violation: 0.001426208132161989
violation: 0.0013907597658088418
violation: 0.0013601582805154967
violation: 0.0013328464824004331
violation: 0.0013065923988234771
violation: 0.0012813357494808766
violation: 0.0012569657401119182
violation: 0.0012363658727399468
violation: 0.0012190114699551008
violation: 0.0011992116544503155
violation: 0.0011775622624514773
violation: 0.001158260908541374
violation: 0.0011389415923629142
violation: 0.001119912492936077
violation: 0.0011006754884537433
violation: 0.0010832777040278034
violation: 0.0010661363692305052
violation: 0.0010491933694698622
violation: 0.00103182441026068
violation: 0.0010150792321233146
violation: 0.0009988201809299848
violation: 0.0009841318528816835
violation: 0.0009699922960873943
violation: 0.0009545966012007843
violation: 0.0009396363331387057
violation: 0.0009266599168144163
violation: 0.000914026217259915
violation: 0.0009015875006377784
violation: 0.0008902182357105151
violation: 0.0008780499311871759
violation: 0.0008660457470920556
violation: 0.0008543517499941953
violation: 0.000842870600328632
violation: 0.000831553680437185
violation: 0.0008208847158800826
violation: 0.0008104269807763582
violation: 0.0007997522484733993
violation: 0.0007893350738952975
violation: 0.0007791326607913418
violation: 0.0007691414390018058
violation: 0.0007597179067853633
violation: 0.000750465253889182
violation: 0.0007412456856970411
violation: 0.0007322966170540217
violation: 0.0007235915691683385
violation: 0.0007151920055395772
violation: 0.0007069372346703547
violation: 0.0006987637535247771
violation: 0.0006907733550824582
violation: 0.000683029877980107
violation: 0.0006754181243926704
violation: 0.0006679795936489944
violation: 0.0006606893398231435
violation: 0.000653609129635259
violation: 0.0006466641120996633
violation: 0.0006399762615476095
violation: 0.0006335488650771175
violation: 0.0006273957420690978
violation: 0.0006215236000711284
violation: 0.0006161518203756149
violation: 0.0006113918151773443
violation: 0.0006071251736134768
violation: 0.0006030938520873971
violation: 0.0005992255771886872
violation: 0.0005955122189368102
violation: 0.0005919356405961
violation: 0.0005884735105285376
violation: 0.0005851626197890825
violation: 0.0005819472966805649
violation: 0.000578862424247998
violation: 0.0005759087479596191
violation: 0.0005730546137310958
violation: 0.0005702968600985901
violation: 0.0005676053787179394
violation: 0.0005650176785169583
violation: 0.0005624480584367397
violation: 0.000559928147104912
violation: 0.0005574208102717348
violation: 0.0005549930907514798
violation: 0.000552626309068661
violation: 0.0005503237863511384
violation: 0.0005480875748007408
violation: 0.0005458976082891676
violation: 0.0005437570853968155
violation: 0.0005416726314724169
violation: 0.000539632958221955
violation: 0.0005376381718607186
violation: 0.0005358628850807991
violation: 0.0005342566446345066
violation: 0.0005327134944358332
violation: 0.0005311700256181376
violation: 0.0005296374901747168
violation: 0.0005281469649349668
violation: 0.0005266549474162529
violation: 0.0005251860718892653
violation: 0.0005237318107592209
violation: 0.0005222955570666103
violation: 0.0005208942964237144
violation: 0.0005195265168843954
violation: 0.0005181813428111702
violation: 0.0005168846752738591
violation: 0.0005156608680271962
violation: 0.0005144616554312847
violation: 0.0005132891688188153
violation: 0.000512151526640299
violation: 0.0005110364330891649
violation: 0.0005099447315065614
violation: 0.0005088753613793788
violation: 0.00050782366105795
violation: 0.0005067909112023824
violation: 0.0005057740763560319
violation: 0.000504776717561682
violation: 0.0005037958933649077
violation: 0.0005028222129278155
violation: 0.0005018650428481096
violation: 0.0005009224423797214
violation: 0.0004999974962489177
violation: 0.0004990872395198657
violation: 0.0004981962000748344
violation: 0.0004973147318191101
violation: 0.0004964417296739457
violation: 0.0004955753197882528
violation: 0.0004946901218457088
violation: 0.00049382104373046
violation: 0.0004929673596847309
violation: 0.0004921226355844233
violation: 0.0004912871202794856
violation: 0.000490459652853948
violation: 0.0004896376456530538
/home/runner/work/spectrochempy/spectrochempy/.venv/lib/python3.13/site-packages/sklearn/decomposition/_nmf.py:1742: ConvergenceWarning: Maximum number of iterations 200 reached. Increase it to improve convergence.
  warnings.warn(
violation: 1.0
violation: 0.27811881011285444
violation: 0.2110383927344215
violation: 0.16365897573755064
violation: 0.1263812450285737
violation: 0.09689398092858058
violation: 0.07386553913526493
violation: 0.057263048836391335
violation: 0.046397106968950746
violation: 0.03776270101072397
violation: 0.030324671559648134
violation: 0.024000077998569437
violation: 0.018705054318855174
violation: 0.014282427091627808
violation: 0.010676123451468416
violation: 0.008016534827385515
violation: 0.00623861611482806
violation: 0.005124394633030048
violation: 0.004490757479656533
violation: 0.00405311575112343
violation: 0.0037443026036689093
violation: 0.00342896281166094
violation: 0.003032319034755939
violation: 0.002727253739146761
violation: 0.0023865056940469828
violation: 0.002085162862784008
violation: 0.0017697484695161584
violation: 0.001492571627285644
violation: 0.0012488601974044143
violation: 0.0010438675111376639
violation: 0.0008573236692761656
violation: 0.0006991377766199977
violation: 0.0005706218431926388
violation: 0.000463628624095508
violation: 0.000374872354798941
violation: 0.00030325790844269897
violation: 0.00024636638593839504
violation: 0.0001982580479040581
violation: 0.00015827733519295482
violation: 0.00012439075792815938
violation: 9.611089606615744e-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.102 seconds)