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.14017421024502066
violation: 0.061581950654932806
violation: 0.03477774452872539
violation: 0.02315591268977705
violation: 0.01628956483660768
violation: 0.011732197722809996
violation: 0.009261179153190129
violation: 0.0077705025299145926
violation: 0.006957471610158985
violation: 0.0064574143703548924
violation: 0.006191115125282179
violation: 0.006057238974457705
violation: 0.006000777806339348
violation: 0.005868357891308995
violation: 0.00580291802853392
violation: 0.0057723676588301845
violation: 0.005756947971778033
violation: 0.005733332889919009
violation: 0.005700606624645025
violation: 0.005667827078790747
violation: 0.0055877366300484295
violation: 0.0055291351831670155
violation: 0.005460760674075937
violation: 0.005375194673451703
violation: 0.005288054442075132
violation: 0.005203284939611481
violation: 0.005110269931845382
violation: 0.005004969613317581
violation: 0.004889401944567229
violation: 0.004778610916794783
violation: 0.004657040705272458
violation: 0.00452764230838304
violation: 0.004393717477174756
violation: 0.004267124138925712
violation: 0.00413392813301637
violation: 0.0040127559281387054
violation: 0.00389146535192683
violation: 0.003765260270042635
violation: 0.00363751482186278
violation: 0.003514710166154283
violation: 0.0033965138303582183
violation: 0.0032925205579804177
violation: 0.00319416481327226
violation: 0.003104947029333612
violation: 0.0030221674035500186
violation: 0.002938964639034165
violation: 0.002856115850045574
violation: 0.0027738912186805074
violation: 0.002692711668736988
violation: 0.0026129548289076147
violation: 0.0025351644702120315
violation: 0.002458740363437871
violation: 0.0023842026907912963
violation: 0.0023133039094786357
violation: 0.0022437367434809015
violation: 0.0021751169925788797
violation: 0.0021084094490923964
violation: 0.0020436678052480656
violation: 0.0019806643593504474
violation: 0.0019243270194362226
violation: 0.0018713261632058358
violation: 0.0018195678200698315
violation: 0.0017692749012867164
violation: 0.0017204657491193133
violation: 0.0016731692686998657
violation: 0.0016274950351468159
violation: 0.0015839173329702059
violation: 0.0015418960309271522
violation: 0.001501438543131509
violation: 0.0014629272012160912
violation: 0.0014262081321619027
violation: 0.001390759765808768
violation: 0.0013601582805156383
violation: 0.00133284648240035
violation: 0.0013065923988233132
violation: 0.0012813357494811
violation: 0.0012569657401119952
violation: 0.001236365872739909
violation: 0.0012190114699549652
violation: 0.0011992116544500074
violation: 0.0011775622624511093
violation: 0.0011582609085414254
violation: 0.001138941592363195
violation: 0.0011199124929359974
violation: 0.001100675488453943
violation: 0.0010832777040278897
violation: 0.0010661363692305481
violation: 0.0010491933694700341
violation: 0.0010318244102607982
violation: 0.0010150792321237036
violation: 0.000998820180929816
violation: 0.0009841318528818884
violation: 0.0009699922960875752
violation: 0.0009545966012010874
violation: 0.0009396363331388106
violation: 0.0009266599168144428
violation: 0.0009140262172599809
violation: 0.0009015875006378716
violation: 0.0008902182357106995
violation: 0.0008780499311872211
violation: 0.000866045747092065
violation: 0.0008543517499938854
violation: 0.000842870600328982
violation: 0.0008315536804370776
violation: 0.0008208847158803019
violation: 0.0008104269807765804
violation: 0.0007997522484735479
violation: 0.0007893350738953648
violation: 0.0007791326607913974
violation: 0.0007691414390019201
violation: 0.0007597179067853006
violation: 0.0007504652538892073
violation: 0.0007412456856969909
violation: 0.000732296617053843
violation: 0.000723591569168482
violation: 0.0007151920055395156
violation: 0.000706937234670464
violation: 0.0006987637535247349
violation: 0.0006907733550823536
violation: 0.0006830298779799352
violation: 0.0006754181243926791
violation: 0.000667979593649312
violation: 0.0006606893398227812
violation: 0.0006536091296352826
violation: 0.0006466641120995271
violation: 0.0006399762615476285
violation: 0.000633548865077372
violation: 0.0006273957420690709
violation: 0.0006215236000710717
violation: 0.0006161518203754259
violation: 0.000611391815177258
violation: 0.0006071251736133542
violation: 0.0006030938520872328
violation: 0.0005992255771889872
violation: 0.0005955122189364474
violation: 0.0005919356405965006
violation: 0.0005884735105283929
violation: 0.0005851626197891066
violation: 0.0005819472966806153
violation: 0.0005788624242478919
violation: 0.0005759087479599636
violation: 0.0005730546137306858
violation: 0.0005702968600985546
violation: 0.0005676053787176446
violation: 0.0005650176785172028
violation: 0.0005624480584368465
violation: 0.0005599281471047759
violation: 0.000557420810271954
violation: 0.0005549930907513085
violation: 0.0005526263090690785
violation: 0.0005503237863508872
violation: 0.0005480875748009304
violation: 0.00054589760828919
violation: 0.0005437570853967617
violation: 0.0005416726314728746
violation: 0.0005396329582220509
violation: 0.0005376381718607333
violation: 0.0005358628850809582
violation: 0.0005342566446342803
violation: 0.0005327134944355888
violation: 0.0005311700256181597
violation: 0.0005296374901748048
violation: 0.0005281469649347856
violation: 0.0005266549474162036
violation: 0.0005251860718895401
violation: 0.0005237318107590422
violation: 0.0005222955570663309
violation: 0.0005208942964238551
violation: 0.000519526516884404
violation: 0.0005181813428112989
violation: 0.0005168846752737163
violation: 0.0005156608680270252
violation: 0.0005144616554313836
violation: 0.0005132891688190271
violation: 0.000512151526640438
violation: 0.0005110364330892081
violation: 0.0005099447315066083
violation: 0.0005088753613789309
violation: 0.0005078236610580663
violation: 0.0005067909112024853
violation: 0.0005057740763559452
violation: 0.0005047767175614351
violation: 0.000503795893365122
violation: 0.0005028222129273644
violation: 0.000501865042847809
violation: 0.0005009224423798533
violation: 0.0004999974962487809
violation: 0.0004990872395200449
violation: 0.000498196200074986
violation: 0.0004973147318194866
violation: 0.000496441729674069
violation: 0.0004955753197881697
violation: 0.0004946901218458008
violation: 0.0004938210437305531
violation: 0.0004929673596844663
violation: 0.0004921226355847404
violation: 0.0004912871202795684
violation: 0.0004904596528538222
violation: 0.0004896376456529446
/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.27811881011285294
violation: 0.21103839273442068
violation: 0.1636589757375498
violation: 0.12638124502857262
violation: 0.09689398092857957
violation: 0.07386553913526409
violation: 0.057263048836390835
violation: 0.04639710696895035
violation: 0.037762701010723494
violation: 0.030324671559647638
violation: 0.024000077998568965
violation: 0.018705054318854733
violation: 0.014282427091627426
violation: 0.010676123451468036
violation: 0.008016534827385334
violation: 0.006238616114828023
violation: 0.005124394633029932
violation: 0.004490757479656394
violation: 0.004053115751123289
violation: 0.003744302603668765
violation: 0.003428962811660837
violation: 0.0030323190347558513
violation: 0.002727253739146734
violation: 0.002386505694046926
violation: 0.0020851628627839703
violation: 0.0017697484695160606
violation: 0.0014925716272855608
violation: 0.0012488601974043122
violation: 0.0010438675111376318
violation: 0.0008573236692761033
violation: 0.000699137776619971
violation: 0.0005706218431926346
violation: 0.00046362862409548433
violation: 0.0003748723547989193
violation: 0.0003032579084426959
violation: 0.00024636638593838355
violation: 0.000198258047904046
violation: 0.00015827733519296173
violation: 0.00012439075792814155
violation: 9.611089606616562e-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.941 seconds)