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.06158195065493279
violation: 0.03477774452872518
violation: 0.023155912689776882
violation: 0.016289564836607432
violation: 0.01173219772280993
violation: 0.0092611791531903
violation: 0.007770502529914437
violation: 0.006957471610159153
violation: 0.00645741437035502
violation: 0.006191115125282056
violation: 0.006057238974457854
violation: 0.006000777806339404
violation: 0.005868357891308816
violation: 0.0058029180285339285
violation: 0.005772367658829997
violation: 0.00575694797177785
violation: 0.0057333328899191556
violation: 0.005700606624644885
violation: 0.005667827078790939
violation: 0.005587736630048376
violation: 0.005529135183167173
violation: 0.005460760674076014
violation: 0.005375194673451879
violation: 0.005288054442075101
violation: 0.005203284939611464
violation: 0.005110269931845371
violation: 0.005004969613317498
violation: 0.004889401944567372
violation: 0.004778610916794778
violation: 0.004657040705272582
violation: 0.004527642308382955
violation: 0.00439371747717499
violation: 0.004267124138925782
violation: 0.004133928133016235
violation: 0.004012755928138795
violation: 0.003891465351926913
violation: 0.003765260270042737
violation: 0.003637514821862991
violation: 0.003514710166154446
violation: 0.0033965138303582256
violation: 0.003292520557980451
violation: 0.003194164813272323
violation: 0.003104947029333307
violation: 0.003022167403549953
violation: 0.0029389646390339
violation: 0.002856115850045833
violation: 0.0027738912186804294
violation: 0.002692711668736904
violation: 0.0026129548289079117
violation: 0.0025351644702120493
violation: 0.002458740363438046
violation: 0.002384202690791246
violation: 0.002313303909478692
violation: 0.002243736743481074
violation: 0.0021751169925787956
violation: 0.0021084094490924896
violation: 0.0020436678052477347
violation: 0.0019806643593505494
violation: 0.0019243270194359847
violation: 0.0018713261632059529
violation: 0.0018195678200696294
violation: 0.0017692749012865965
violation: 0.001720465749119317
violation: 0.0016731692686996716
violation: 0.001627495035147085
violation: 0.0015839173329701421
violation: 0.001541896030927164
violation: 0.0015014385431315587
violation: 0.0014629272012159494
violation: 0.0014262081321618476
violation: 0.0013907597658088027
violation: 0.0013601582805155548
violation: 0.001332846482400419
violation: 0.001306592398823223
violation: 0.001281335749481036
violation: 0.0012569657401119872
violation: 0.001236365872739849
violation: 0.0012190114699549045
violation: 0.0011992116544501505
violation: 0.0011775622624512869
violation: 0.0011582609085413976
violation: 0.0011389415923631209
violation: 0.0011199124929362199
violation: 0.001100675488454189
violation: 0.0010832777040279235
violation: 0.0010661363692305724
violation: 0.0010491933694702017
violation: 0.0010318244102606696
violation: 0.0010150792321237281
violation: 0.000998820180930072
violation: 0.000984131852881896
violation: 0.0009699922960877787
violation: 0.0009545966012009791
violation: 0.0009396363331386564
violation: 0.0009266599168142453
violation: 0.000914026217260302
violation: 0.000901587500638073
violation: 0.0008902182357106973
violation: 0.0008780499311869405
violation: 0.0008660457470918363
violation: 0.0008543517499937797
violation: 0.0008428706003288043
violation: 0.0008315536804370722
violation: 0.0008208847158805384
violation: 0.0008104269807764539
violation: 0.0007997522484736408
violation: 0.0007893350738953973
violation: 0.000779132660791601
violation: 0.0007691414390018386
violation: 0.0007597179067852992
violation: 0.0007504652538894058
violation: 0.0007412456856971169
violation: 0.000732296617053866
violation: 0.0007235915691684696
violation: 0.0007151920055395258
violation: 0.0007069372346704057
violation: 0.0006987637535244059
violation: 0.00069077335508258
violation: 0.0006830298779797686
violation: 0.0006754181243923415
violation: 0.0006679795936493315
violation: 0.0006606893398231861
violation: 0.0006536091296355953
violation: 0.0006466641120997459
violation: 0.0006399762615478671
violation: 0.0006335488650774163
violation: 0.0006273957420690748
violation: 0.000621523600071285
violation: 0.0006161518203754314
violation: 0.0006113918151773738
violation: 0.0006071251736133423
violation: 0.0006030938520873144
violation: 0.0005992255771887996
violation: 0.0005955122189366189
violation: 0.0005919356405960711
violation: 0.0005884735105284915
violation: 0.0005851626197891578
violation: 0.000581947296680579
violation: 0.000578862424248209
violation: 0.00057590874796007
violation: 0.0005730546137307515
violation: 0.0005702968600982668
violation: 0.0005676053787180874
violation: 0.0005650176785172169
violation: 0.0005624480584366808
violation: 0.0005599281471046341
violation: 0.0005574208102720574
violation: 0.0005549930907512596
violation: 0.0005526263090685983
violation: 0.0005503237863510769
violation: 0.0005480875748006514
violation: 0.0005458976082892131
violation: 0.0005437570853969508
violation: 0.0005416726314725001
violation: 0.0005396329582219735
violation: 0.0005376381718609082
violation: 0.0005358628850811115
violation: 0.0005342566446346755
violation: 0.0005327134944356273
violation: 0.0005311700256179362
violation: 0.0005296374901745594
violation: 0.0005281469649349427
violation: 0.0005266549474162252
violation: 0.0005251860718892189
violation: 0.0005237318107591456
violation: 0.000522295557066549
violation: 0.0005208942964236286
violation: 0.0005195265168843653
violation: 0.0005181813428108586
violation: 0.0005168846752735559
violation: 0.0005156608680268241
violation: 0.0005144616554312127
violation: 0.0005132891688187897
violation: 0.0005121515266404943
violation: 0.0005110364330892439
violation: 0.0005099447315065849
violation: 0.0005088753613795389
violation: 0.0005078236610582524
violation: 0.0005067909112021736
violation: 0.0005057740763560076
violation: 0.0005047767175617761
violation: 0.0005037958933648317
violation: 0.0005028222129278951
violation: 0.0005018650428479046
violation: 0.0005009224423800481
violation: 0.0004999974962487544
violation: 0.0004990872395199329
violation: 0.0004981962000750675
violation: 0.0004973147318188801
violation: 0.0004964417296738061
violation: 0.0004955753197883882
violation: 0.0004946901218459494
violation: 0.0004938210437303676
violation: 0.0004929673596845492
violation: 0.0004921226355845086
violation: 0.0004912871202793249
violation: 0.0004904596528540011
violation: 0.0004896376456529276
/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.27811881011284645
violation: 0.2110383927344165
violation: 0.1636589757375474
violation: 0.12638124502857173
violation: 0.09689398092857955
violation: 0.07386553913526445
violation: 0.057263048836391245
violation: 0.046397106968950955
violation: 0.03776270101072439
violation: 0.03032467155964869
violation: 0.02400007799857008
violation: 0.018705054318855985
violation: 0.014282427091628577
violation: 0.01067612345146911
violation: 0.008016534827386084
violation: 0.006238616114828526
violation: 0.0051243946330301856
violation: 0.004490757479656509
violation: 0.004053115751123296
violation: 0.003744302603668759
violation: 0.0034289628116608074
violation: 0.0030323190347559432
violation: 0.002727253739146757
violation: 0.002386505694047058
violation: 0.0020851628627841117
violation: 0.001769748469516298
violation: 0.0014925716272857904
violation: 0.00124886019740455
violation: 0.001043867511137805
violation: 0.0008573236692762428
violation: 0.0006991377766200875
violation: 0.0005706218431927272
violation: 0.0004636286240955877
violation: 0.0003748723547990151
violation: 0.0003032579084427631
violation: 0.0002463663859384357
violation: 0.00019825804790409024
violation: 0.00015827733519298704
violation: 0.00012439075792816266
violation: 9.611089606618687e-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.105 seconds)