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.1401742102450194
violation: 0.06158195065493211
violation: 0.03477774452872498
violation: 0.023155912689776657
violation: 0.016289564836607155
violation: 0.011732197722809678
violation: 0.009261179153189992
violation: 0.007770502529914376
violation: 0.006957471610159133
violation: 0.006457414370354927
violation: 0.006191115125282051
violation: 0.006057238974457531
violation: 0.006000777806339454
violation: 0.005868357891308839
violation: 0.005802918028533955
violation: 0.00577236765882993
violation: 0.005756947971777763
violation: 0.005733332889918891
violation: 0.005700606624644991
violation: 0.005667827078790848
violation: 0.0055877366300482924
violation: 0.005529135183167032
violation: 0.005460760674075866
violation: 0.005375194673451729
violation: 0.005288054442074971
violation: 0.00520328493961172
violation: 0.005110269931845302
violation: 0.005004969613317408
violation: 0.004889401944567166
violation: 0.004778610916794522
violation: 0.004657040705272624
violation: 0.004527642308383188
violation: 0.00439371747717508
violation: 0.004267124138925838
violation: 0.004133928133016217
violation: 0.004012755928138884
violation: 0.0038914653519267033
violation: 0.0037652602700427485
violation: 0.003637514821862944
violation: 0.0035147101661546086
violation: 0.0033965138303584086
violation: 0.003292520557980575
violation: 0.0031941648132722406
violation: 0.0031049470293336013
violation: 0.003022167403549936
violation: 0.0029389646390340397
violation: 0.0028561158500457454
violation: 0.0027738912186803136
violation: 0.002692711668736687
violation: 0.0026129548289077916
violation: 0.0025351644702122254
violation: 0.002458740363438354
violation: 0.002384202690791116
violation: 0.0023133039094784605
violation: 0.0022437367434813534
violation: 0.0021751169925786113
violation: 0.0021084094490923756
violation: 0.0020436678052479203
violation: 0.0019806643593506235
violation: 0.0019243270194359483
violation: 0.001871326163205833
violation: 0.0018195678200697174
violation: 0.0017692749012868422
violation: 0.0017204657491192068
violation: 0.0016731692686996831
violation: 0.0016274950351468876
violation: 0.0015839173329701992
violation: 0.0015418960309270628
violation: 0.0015014385431316695
violation: 0.0014629272012161886
violation: 0.0014262081321621263
violation: 0.0013907597658088403
violation: 0.0013601582805156654
violation: 0.0013328464824005637
violation: 0.001306592398823308
violation: 0.0012813357494810527
violation: 0.001256965740112001
violation: 0.0012363658727397298
violation: 0.0012190114699551528
violation: 0.0011992116544500267
violation: 0.0011775622624514183
violation: 0.0011582609085414224
violation: 0.0011389415923630875
violation: 0.0011199124929361947
violation: 0.0011006754884538405
violation: 0.001083277704027835
violation: 0.001066136369230526
violation: 0.0010491933694702557
violation: 0.0010318244102607002
violation: 0.0010150792321233404
violation: 0.0009988201809299417
violation: 0.0009841318528817544
violation: 0.000969992296087644
violation: 0.0009545966012007913
violation: 0.000939636333138458
violation: 0.000926659916814543
violation: 0.0009140262172602567
violation: 0.0009015875006380721
violation: 0.000890218235710648
violation: 0.0008780499311870562
violation: 0.0008660457470919083
violation: 0.0008543517499939792
violation: 0.0008428706003288381
violation: 0.0008315536804371624
violation: 0.000820884715880059
violation: 0.0008104269807766458
violation: 0.00079975224847327
violation: 0.0007893350738951736
violation: 0.0007791326607914142
violation: 0.0007691414390018356
violation: 0.0007597179067853338
violation: 0.0007504652538892254
violation: 0.0007412456856971551
violation: 0.0007322966170538622
violation: 0.0007235915691683486
violation: 0.000715192005539442
violation: 0.0007069372346705272
violation: 0.0006987637535246869
violation: 0.0006907733550824022
violation: 0.0006830298779800716
violation: 0.0006754181243925671
violation: 0.0006679795936494891
violation: 0.000660689339823002
violation: 0.0006536091296353141
violation: 0.0006466641120996234
violation: 0.0006399762615472939
violation: 0.0006335488650772223
violation: 0.0006273957420690501
violation: 0.0006215236000712345
violation: 0.000616151820375539
violation: 0.0006113918151771293
violation: 0.0006071251736134216
violation: 0.0006030938520872545
violation: 0.0005992255771888921
violation: 0.0005955122189366886
violation: 0.0005919356405962433
violation: 0.0005884735105285635
violation: 0.0005851626197894036
violation: 0.00058194729668085
violation: 0.0005788624242480129
violation: 0.0005759087479600045
violation: 0.0005730546137310419
violation: 0.0005702968600984021
violation: 0.0005676053787179068
violation: 0.0005650176785174569
violation: 0.0005624480584371954
violation: 0.0005599281471043016
violation: 0.0005574208102717999
violation: 0.0005549930907513079
violation: 0.0005526263090688303
violation: 0.0005503237863512042
violation: 0.0005480875748008062
violation: 0.0005458976082897912
violation: 0.0005437570853968722
violation: 0.0005416726314726501
violation: 0.0005396329582218867
violation: 0.0005376381718606432
violation: 0.0005358628850811837
violation: 0.0005342566446344795
violation: 0.0005327134944355761
violation: 0.0005311700256183288
violation: 0.000529637490174838
violation: 0.0005281469649349833
violation: 0.0005266549474162144
violation: 0.0005251860718894643
violation: 0.0005237318107590048
violation: 0.0005222955570667071
violation: 0.0005208942964240066
violation: 0.0005195265168842951
violation: 0.0005181813428111927
violation: 0.0005168846752738339
violation: 0.0005156608680268815
violation: 0.0005144616554312383
violation: 0.0005132891688192268
violation: 0.0005121515266404812
violation: 0.0005110364330891477
violation: 0.0005099447315065034
violation: 0.0005088753613790483
violation: 0.0005078236610582817
violation: 0.0005067909112024138
violation: 0.0005057740763558866
violation: 0.0005047767175613037
violation: 0.000503795893364907
violation: 0.000502822212927494
violation: 0.0005018650428477705
violation: 0.0005009224423799823
violation: 0.0004999974962490144
violation: 0.0004990872395199099
violation: 0.00049819620007466
violation: 0.0004973147318194258
violation: 0.0004964417296740971
violation: 0.0004955753197882053
violation: 0.000494690121845731
violation: 0.0004938210437306683
violation: 0.0004929673596843664
violation: 0.0004921226355846887
violation: 0.000491287120279479
violation: 0.000490459652853965
violation: 0.0004896376456532542
/home/runner/work/spectrochempy/spectrochempy/.venv/lib/python3.13/site-packages/sklearn/decomposition/_nmf.py:1728: ConvergenceWarning: Maximum number of iterations 200 reached. Increase it to improve convergence.
  warnings.warn(
violation: 1.0
violation: 0.27811881011285616
violation: 0.21103839273442287
violation: 0.16365897573755073
violation: 0.12638124502857256
violation: 0.09689398092857912
violation: 0.07386553913526335
violation: 0.057263048836390856
violation: 0.046397106968950615
violation: 0.03776270101072386
violation: 0.03032467155964793
violation: 0.0240000779985693
violation: 0.018705054318855052
violation: 0.01428242709162765
violation: 0.010676123451468372
violation: 0.00801653482738569
violation: 0.006238616114828288
violation: 0.005124394633030186
violation: 0.004490757479656553
violation: 0.004053115751123429
violation: 0.003744302603668943
violation: 0.003428962811660923
violation: 0.003032319034755955
violation: 0.0027272537391468113
violation: 0.002386505694047024
violation: 0.0020851628627840675
violation: 0.0017697484695162007
violation: 0.0014925716272857132
violation: 0.0012488601974044817
violation: 0.0010438675111377384
violation: 0.0008573236692762021
violation: 0.0006991377766200663
violation: 0.0005706218431926893
violation: 0.000463628624095521
violation: 0.0003748723547989922
violation: 0.00030325790844271474
violation: 0.00024636638593840047
violation: 0.00019825804790410122
violation: 0.000158277335192966
violation: 0.00012439075792814792
violation: 9.611089606618191e-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.196 seconds)