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.14017421024501941
violation: 0.06158195065493229
violation: 0.03477774452872508
violation: 0.02315591268977655
violation: 0.016289564836607325
violation: 0.011732197722809555
violation: 0.009261179153190253
violation: 0.0077705025299145145
violation: 0.006957471610158891
violation: 0.006457414370355166
violation: 0.006191115125282175
violation: 0.006057238974457561
violation: 0.006000777806339308
violation: 0.0058683578913088326
violation: 0.005802918028534232
violation: 0.005772367658829893
violation: 0.005756947971777774
violation: 0.005733332889918987
violation: 0.005700606624644896
violation: 0.005667827078790777
violation: 0.005587736630048376
violation: 0.005529135183167049
violation: 0.005460760674075931
violation: 0.005375194673451755
violation: 0.005288054442075046
violation: 0.005203284939611475
violation: 0.005110269931845333
violation: 0.0050049696133175154
violation: 0.0048894019445671335
violation: 0.004778610916794479
violation: 0.004657040705272638
violation: 0.004527642308382957
violation: 0.004393717477175302
violation: 0.004267124138925928
violation: 0.004133928133016168
violation: 0.004012755928138983
violation: 0.0038914653519266738
violation: 0.0037652602700427007
violation: 0.0036375148218631284
violation: 0.0035147101661543788
violation: 0.003396513830358381
violation: 0.0032925205579805864
violation: 0.003194164813272294
violation: 0.0031049470293334183
violation: 0.0030221674035502072
violation: 0.0029389646390337904
violation: 0.002856115850045542
violation: 0.0027738912186806024
violation: 0.0026927116687365895
violation: 0.0026129548289078714
violation: 0.0025351644702118967
violation: 0.0024587403634383693
violation: 0.0023842026907912356
violation: 0.0023133039094786127
violation: 0.002243736743481001
violation: 0.002175116992578796
violation: 0.002108409449092226
violation: 0.002043667805247964
violation: 0.001980664359350845
violation: 0.0019243270194360385
violation: 0.0018713261632059244
violation: 0.0018195678200697255
violation: 0.001769274901286765
violation: 0.0017204657491196847
violation: 0.00167316926869993
violation: 0.0016274950351469035
violation: 0.00158391733297012
violation: 0.0015418960309273053
violation: 0.001501438543131411
violation: 0.0014629272012159427
violation: 0.0014262081321618188
violation: 0.0013907597658089188
violation: 0.0013601582805155283
violation: 0.0013328464824005552
violation: 0.0013065923988230912
violation: 0.0012813357494807773
violation: 0.0012569657401122337
violation: 0.001236365872739831
violation: 0.0012190114699547922
violation: 0.0011992116544502509
violation: 0.0011775622624511037
violation: 0.0011582609085415384
violation: 0.0011389415923630912
violation: 0.0011199124929359005
violation: 0.0011006754884537373
violation: 0.001083277704027705
violation: 0.001066136369230612
violation: 0.0010491933694702262
violation: 0.001031824410260655
violation: 0.0010150792321238352
violation: 0.000998820180930106
violation: 0.000984131852881827
violation: 0.0009699922960877735
violation: 0.0009545966012008903
violation: 0.0009396363331385329
violation: 0.0009266599168146527
violation: 0.0009140262172604135
violation: 0.0009015875006375858
violation: 0.0008902182357103724
violation: 0.0008780499311868005
violation: 0.0008660457470918349
violation: 0.0008543517499941724
violation: 0.0008428706003290188
violation: 0.0008315536804369288
violation: 0.0008208847158805946
violation: 0.000810426980776662
violation: 0.0007997522484734597
violation: 0.0007893350738953644
violation: 0.0007791326607915379
violation: 0.0007691414390018713
violation: 0.0007597179067850992
violation: 0.0007504652538896055
violation: 0.000741245685697043
violation: 0.0007322966170540815
violation: 0.0007235915691686876
violation: 0.0007151920055396689
violation: 0.0007069372346702987
violation: 0.0006987637535248345
violation: 0.0006907733550826509
violation: 0.0006830298779799212
violation: 0.0006754181243927746
violation: 0.0006679795936491177
violation: 0.0006606893398230271
violation: 0.0006536091296351101
violation: 0.0006466641120996927
violation: 0.0006399762615476718
violation: 0.0006335488650772862
violation: 0.0006273957420687235
violation: 0.0006215236000708196
violation: 0.0006161518203755891
violation: 0.0006113918151776276
violation: 0.0006071251736136324
violation: 0.0006030938520870944
violation: 0.0005992255771889707
violation: 0.0005955122189370665
violation: 0.0005919356405961551
violation: 0.0005884735105283162
violation: 0.0005851626197888847
violation: 0.0005819472966803874
violation: 0.000578862424248042
violation: 0.0005759087479598403
violation: 0.0005730546137309058
violation: 0.0005702968600985256
violation: 0.0005676053787183121
violation: 0.0005650176785172666
violation: 0.0005624480584368048
violation: 0.0005599281471045947
violation: 0.0005574208102719195
violation: 0.0005549930907510315
violation: 0.000552626309068943
violation: 0.0005503237863509924
violation: 0.0005480875748007812
violation: 0.0005458976082890142
violation: 0.00054375708539694
violation: 0.00054167263147277
violation: 0.0005396329582222382
violation: 0.0005376381718608372
violation: 0.0005358628850808602
violation: 0.0005342566446344173
violation: 0.0005327134944355516
violation: 0.0005311700256180313
violation: 0.0005296374901745947
violation: 0.0005281469649352493
violation: 0.0005266549474162769
violation: 0.0005251860718892788
violation: 0.0005237318107591668
violation: 0.0005222955570668051
violation: 0.0005208942964239345
violation: 0.0005195265168844783
violation: 0.0005181813428114292
violation: 0.000516884675273759
violation: 0.0005156608680271807
violation: 0.000514461655431166
violation: 0.0005132891688186827
violation: 0.0005121515266407325
violation: 0.0005110364330891559
violation: 0.0005099447315063012
violation: 0.0005088753613789986
violation: 0.0005078236610582592
violation: 0.0005067909112023624
violation: 0.0005057740763560735
violation: 0.0005047767175615752
violation: 0.0005037958933648785
violation: 0.0005028222129275644
violation: 0.0005018650428481382
violation: 0.0005009224423800111
violation: 0.0004999974962490934
violation: 0.0004990872395199391
violation: 0.0004981962000750223
violation: 0.0004973147318188975
violation: 0.0004964417296737046
violation: 0.0004955753197879898
violation: 0.0004946901218458127
violation: 0.0004938210437303635
violation: 0.0004929673596846081
violation: 0.0004921226355841666
violation: 0.0004912871202793786
violation: 0.0004904596528542884
violation: 0.0004896376456532477
/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.27811881011284956
violation: 0.21103839273441835
violation: 0.16365897573754876
violation: 0.12638124502857265
violation: 0.09689398092858013
violation: 0.0738655391352648
violation: 0.057263048836391495
violation: 0.04639710696895114
violation: 0.03776270101072457
violation: 0.030324671559648703
violation: 0.024000077998570023
violation: 0.018705054318855822
violation: 0.014282427091628394
violation: 0.010676123451468983
violation: 0.008016534827385959
violation: 0.006238616114828476
violation: 0.005124394633030231
violation: 0.004490757479656624
violation: 0.004053115751123473
violation: 0.0037443026036689075
violation: 0.003428962811660919
violation: 0.0030323190347559914
violation: 0.0027272537391468646
violation: 0.002386505694047119
violation: 0.002085162862784137
violation: 0.0017697484695162616
violation: 0.0014925716272858162
violation: 0.0012488601974045255
violation: 0.0010438675111377755
violation: 0.0008573236692762271
violation: 0.0006991377766200688
violation: 0.0005706218431927457
violation: 0.00046362862409556163
violation: 0.00037487235479900343
violation: 0.0003032579084427363
violation: 0.0002463663859384226
violation: 0.00019825804790409712
violation: 0.00015827733519298905
violation: 0.00012439075792818792
violation: 9.611089606616769e-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 0.909 seconds)