大俠幸會,在下全網同名「演算法金」 0 基礎轉 AI 上岸,多個演算法賽 Top 「日更萬日,讓更多人享受智慧樂趣」
在光譜學領域,資料預處理是不可或缺的一環。
本文將基於 NIR soil 近紅外光譜資料,運用 Python 語言進行資料處理,並透過圖表直觀反映預處理帶來的變化。(資料集:後臺回覆 [ NIR soil ] 獲取 )
常用的光譜資料預處理技術包括:
- MSC(多元散射校正)
- SNV(標準正規化變換)
- 光譜微分
- 基線校正
- 去趨勢
一、MSC(多元散射校正)
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
# 讀取資料
nirsoil_df = pd.read_csv(path)
# 提取光譜資料
spectra = nirsoil_df.filter(like='spc.')
# 進行MSC預處理
def msc(input_data):
# 計算參考光譜(均值光譜)
ref_spectrum = np.mean(input_data, axis=0)
# 初始化校正後的光譜資料矩陣
corrected_spectra = np.zeros_like(input_data)
for i in range(input_data.shape[0]):
fit = np.polyfit(ref_spectrum, input_data[i, :], 1, full=True)
corrected_spectra[i, :] = (input_data[i, :] - fit[0][1]) / fit[0][0]
return corrected_spectra
# 應用MSC
msc_spectra = msc(spectra.values)
# 視覺化對比
plt.figure(figsize=(12, 6))
# 原始光譜
plt.subplot(1, 2, 1)
plt.plot(spectra.values.T, color='blue', alpha=0.1)
plt.title('Original Spectra')
plt.xlabel('Wavelength Index')
plt.ylabel('Reflectance')
# MSC校正後的光譜
plt.subplot(1, 2, 2)
plt.plot(msc_spectra.T, color='red', alpha=0.1)
plt.title('MSC Corrected Spectra')
plt.xlabel('Wavelength Index')
plt.ylabel('Reflectance')
plt.tight_layout()
在輸出的圖片中,左側顯示的是原始光譜資料,右側顯示的是經過MSC(多元散射校正)處理後的光譜資料。
原始光譜(左側圖)
- 顏色和形狀:每條藍色的線代表一個樣本的光譜資料,顏色淺且分佈較散。
- 特點:可以觀察到光譜資料在某些波長處的反射率(Reflectance)存在一定的波動,這可能是由於散射效應和基線漂移引起的。
MSC校正後的光譜(右側圖)
- 顏色和形狀:每條紅色的線代表一個樣本的校正後的光譜資料,顏色淺且分佈較集中。
- 特點:校正後的光譜資料在各個波長處的反射率(Reflectance)更加一致,減少了由散射效應和基線漂移引起的變化。整體曲線更加平滑,差異性減少。
總結
- 變化:經過MSC處理後,光譜資料在整體上變得更加一致和平滑,減少了不必要的噪音和變動,使得資料更適合後續的分析和建模。
- 意義:MSC處理透過消除光譜資料中的散射效應和基線漂移,提高了資料的質量,增強了不同樣本之間的可比性。
防失聯,進免費知識星球交流。演算法知識直達星球:https://t.zsxq.com/ckSu3
更多內容,見免費知識星球
二、SNV(標準正規化變換)
# 提取光譜資料
spectra = nirsoil_df.filter(like='spc.')
# 進行SNV預處理
def snv(input_data):
# 每個樣本減去其均值,然後除以其標準差
corrected_spectra = (input_data - np.mean(input_data, axis=1, keepdims=True)) / np.std(input_data, axis=1, keepdims=True)
return corrected_spectra
# 應用SNV
snv_spectra = snv(spectra.values)
# 視覺化對比
plt.figure(figsize=(12, 6))
# 原始光譜
plt.subplot(1, 2, 1)
plt.plot(spectra.values.T, color='blue', alpha=0.1)
plt.title('Original Spectra')
plt.xlabel('Wavelength Index')
plt.ylabel('Reflectance')
# SNV校正後的光譜
plt.subplot(1, 2, 2)
plt.plot(snv_spectra.T, color='green', alpha=0.1)
plt.title('SNV Corrected Spectra')
plt.xlabel('Wavelength Index')
plt.ylabel('Reflectance')
plt.tight_layout()
plt.show()
在輸出的圖片中,左側顯示的是原始光譜資料,右側顯示的是經過SNV(標準正規化變換)處理後的光譜資料。
原始光譜(左側圖)
- 顏色和形狀:每條藍色的線代表一個樣本的光譜資料,顏色淺且分佈較散。
- 特點:可以觀察到光譜資料在某些波長處的反射率(Reflectance)存在一定的波動,這可能是由於樣本間的差異和噪聲引起的。
SNV校正後的光譜(右側圖)
- 顏色和形狀:每條綠色的線代表一個樣本的校正後的光譜資料,顏色淺且分佈較集中。
- 特點:校正後的光譜資料在各個波長處的反射率(Reflectance)變得更加一致,樣本間的差異和噪聲顯著減少。每條曲線的均值為零,標準差為一,使得所有光譜都在同一個尺度上。
總結
- 變化:經過SNV處理後,光譜資料的均值被中心化為零,標準差被標準化為一,減少了由於不同樣本間的散射效應和噪聲帶來的影響。
- 意義:SNV處理透過對每個樣本的光譜資料進行均值中心化和標準化,消除了樣本間的散射效應,提高了資料的一致性和可比性,使得資料更適合後續的分析和建模。
三、光譜微分
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 讀取資料
# nirsoil_df = pd.read_csv('path_to_your_csv.csv')
# 提取光譜資料
spectra = nirsoil_df.filter(like='spc.')
# 進行光譜微分處理
def spectral_derivative(input_data, order=1):
if order == 1:
derivative_spectra = np.diff(input_data, n=1, axis=1)
elif order == 2:
derivative_spectra = np.diff(input_data, n=2, axis=1)
else:
raise ValueError("Only first and second order derivatives are supported.")
return derivative_spectra
# 一階微分
first_derivative = spectral_derivative(spectra.values, order=1)
# 二階微分
second_derivative = spectral_derivative(spectra.values, order=2)
# 視覺化對比
plt.figure(figsize=(12, 6))
# 一階和二階微分
plt.plot(first_derivative[0, :], label='1st Derivative', color='black')
plt.plot(second_derivative[0, :], label='2nd Derivative', color='red')
plt.title('Spectral Derivatives')
plt.xlabel('Wavelength Index')
plt.ylabel('Reflectance')
plt.legend()
plt.grid(True)
plt.show()
在輸出的圖片中,我們同時展示了一階微分和二階微分處理後的光譜資料。
一階微分(黑色線)
- 特點:一階微分曲線展示了光譜資料在各個波長處的變化率。它突出了光譜曲線的斜率變化,強調了光譜資料中快速變化的區域。
- 用途:一階微分處理可以減少基線漂移的影響,並增強光譜中微弱的特徵和變化。這對於區分類似的光譜樣本非常有用。
二階微分(紅色線)
- 特點:二階微分曲線展示了光譜資料的曲率變化率。它進一步強調了光譜曲線的區域性最大值和最小值,突出了更細微的變化。
- 用途:二階微分處理可以進一步減少基線漂移和噪聲的影響,並提供更多關於光譜中細節特徵的資訊。這對於精細分析光譜資料中的細節特徵非常有用。
總結
- 變化:一階和二階微分處理後,光譜資料的變化率和曲率變化率被突出展示,增強了光譜中細節特徵的可見性,減少了基線漂移和噪聲的影響。
- 意義:導數處理透過強調光譜資料的變化率和曲率變化率,提供了更清晰的特徵和模式,有助於後續的分析和建模。
抱個拳,送個禮
點選 ↑ 領取
四、基線校正
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.sparse import diags
from scipy.sparse.linalg import spsolve
# 讀取資料
# nirsoil_df = pd.read_csv('path_to_your_csv.csv')
# 提取光譜資料
spectra = nirsoil_df.filter(like='spc.')
# 進行AsLS基線校正
def baseline_als(y, lam=1e5, p=0.01, niter=10):
L = len(y)
D = diags([1, -2, 1], [0, -1, -2], shape=(L, L-2))
D = lam * D.dot(D.T)
w = np.ones(L)
for i in range(niter):
W = diags(w, 0, shape=(L, L))
Z = W + D
z = spsolve(Z, w*y)
w = p * (y > z) + (1-p) * (y < z)
return z
def baseline_correction(input_data):
corrected_spectra = np.zeros_like(input_data)
for i in range(input_data.shape[0]):
baseline_values = baseline_als(input_data[i, :])
corrected_spectra[i, :] = input_data[i, :] - baseline_values
return corrected_spectra
# 應用基線校正
corrected_spectra = baseline_correction(spectra.values)
# 視覺化對比
plt.figure(figsize=(12, 6))
# 原始光譜
plt.subplot(1, 2, 1)
plt.plot(spectra.values.T, color='blue', alpha=0.1)
plt.title('Original Spectra')
plt.xlabel('Wavelength Index')
plt.ylabel('Reflectance')
# 基線校正後的光譜
plt.subplot(1, 2, 2)
plt.plot(corrected_spectra.T, color='green', alpha=0.1)
plt.title('Baseline Corrected Spectra')
plt.xlabel('Wavelength Index')
plt.ylabel('Reflectance')
plt.tight_layout()
plt.show()
在輸出的圖片中,左側顯示的是原始光譜資料,右側顯示的是經過基線校正處理後的光譜資料。
原始光譜(左側圖)
- 顏色和形狀:每條藍色的線代表一個樣本的光譜資料,顏色淺且分佈較散。
- 特點:可以觀察到光譜資料在各個波長處的反射率(Reflectance)存在一定的基線漂移和噪聲,這可能是由測量誤差和環境因素引起的。
基線校正後的光譜(右側圖)
- 顏色和形狀:每條綠色的線代表一個樣本的校正後的光譜資料,顏色淺且分佈較集中。
- 特點:校正後的光譜資料在各個波長處的反射率(Reflectance)變得更加一致,基線漂移被去除,噪聲顯著減少。曲線的整體趨勢更加平滑和穩定。
總結
- 變化:經過基線校正處理後,光譜資料的基線漂移被有效去除,減少了由測量誤差和環境因素帶來的影響,使得光譜資料更加清晰和穩定。
- 意義:基線校正處理透過去除光譜資料中的基線漂移,提高了資料的質量和一致性,便於後續的分析和建模。
防失聯,進免費知識星球交流。演算法知識直達星球:https://t.zsxq.com/ckSu3
免費知識星球,歡迎加入交流
五、去趨勢
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import detrend
# # 讀取資料
# nirsoil_df = pd.read_csv('path_to_your_csv.csv')
# 提取光譜資料
spectra = nirsoil_df.filter(like='spc.')
# 進行去趨勢處理
def detrending(input_data):
detrended_spectra = detrend(input_data, axis=1)
return detrended_spectra
# 應用去趨勢處理
detrended_spectra = detrending(spectra.values)
# 視覺化對比
plt.figure(figsize=(12, 6))
# 原始光譜
plt.subplot(1, 2, 1)
plt.plot(spectra.values.T, color='blue', alpha=0.1)
plt.title('Original Spectra')
plt.xlabel('Wavelength Index')
plt.ylabel('Reflectance')
# 去趨勢後的光譜
plt.subplot(1, 2, 2)
plt.plot(detrended_spectra.T, color='brown', alpha=0.1)
plt.title('Detrended Spectra')
plt.xlabel('Wavelength Index')
plt.ylabel('Reflectance')
plt.tight_layout()
plt.show()
在輸出的圖片中,左側顯示的是原始光譜資料,右側顯示的是經過去趨勢處理後的光譜資料。
原始光譜(左側圖)
- 顏色和形狀:每條藍色的線代表一個樣本的光譜資料,顏色淺且分佈較散。
- 特點:光譜資料在各個波長處的反射率(Reflectance)存在一定的趨勢,這些趨勢可能是由實驗條件、測量誤差等因素引起的。
去趨勢後的光譜(右側圖)
- 顏色和形狀:每條棕色的線代表一個樣本的去趨勢處理後的光譜資料,顏色淺且分佈較集中。
- 特點:去趨勢處理後,光譜資料中各個波長處的趨勢被去除,資料更加平穩和一致,減少了由實驗條件、測量誤差等因素帶來的系統性偏差。
總結
- 變化:經過去趨勢處理後,光譜資料中的系統性趨勢被去除,光譜曲線更加平穩和一致,減少了外部因素帶來的系統性偏差。
- 意義:去趨勢處理透過去除光譜資料中的系統性趨勢,提高了資料的質量和一致性,使得光譜資料更適合後續的分析和建模。
更多內容,見微*公號往期文章: 審稿人:拜託,請把模型時間序列去趨勢!!
[ 抱個拳,總個結 ]
- 科研為國分憂,創新與民造福 -
日更時間緊任務急,難免有疏漏之處,還請大俠海涵 內容僅供學習交流之用,部分素材來自網路,侵聯刪
[ 演算法金,碎碎念 ]
全網同名,日更萬日,讓更多人享受智慧樂趣
如果覺得內容有價值,煩請大俠多多 分享、在看、點贊,助力演算法金又猛又持久、很黃很 BL 的日更下去;
同時邀請大俠 關注、星標 演算法金,圍觀日更萬日,助你功力大增、笑傲江湖