3D径向基函数(RBF)插值遇奇异矩阵,求QR分解代码插入位置
Fixing Singular Matrix Error in RBF Interpolation (Even After Removing Duplicates)
我明白你在搭建RBF插值代码时碰到了奇异矩阵的报错,哪怕已经移除了重复数据——这种情况其实很常见,问题不一定出在重复点上,更可能是你的输入特征(T Heizstation、T GWK、P Presse)之间存在线性相关性(比如其中一个变量能被另外两个变量近似线性表示),这会导致RBF算法构建的核矩阵不可逆,触发LinAlgError。
快速解决方案:用Scipy RBF内置的正则化参数
Scipy的interpolate.Rbf其实自带了smooth参数,用来添加正则化项,能直接解决奇异矩阵问题,比手动写QR分解简单得多。你只需要修改初始化RBF函数的那一行:
# 添加smooth参数,值可以根据你的数据调整,比如1e-6到1之间 newfunc = interpolate.Rbf(x1np,x2np,x3np,ynp,function='linear', smooth=1e-6)
这个参数会在核矩阵的对角线上加上一个小值,让矩阵变得非奇异,同时不会对插值结果造成太大影响。如果插值结果不够精准,可以尝试微调smooth的数值(比如1e-5、1e-7)。
手动用QR分解解决(如果需要底层控制)
如果你确实想手动用QR分解来处理矩阵求解,那需要自己实现RBF的核矩阵构建和系数求解,而不是直接用Scipy的封装。以下是修改后的完整代码:
import numpy as np from scipy import interpolate import pandas as pd import xlsxwriter #Read the Dataset from Excel File dataset=pd.read_excel(r'C:\Users\Windows 10\.spyder-py3\Messwerte_FIBRE.xlsx') dataset=dataset.drop([0]) dataset=dataset.drop_duplicates(subset=['T Heizstation','T GWK','P Presse','Bauteilverzug']) index1=[1] index2=[4] index3=[5] index4=[9] x1=dataset.iloc[:, index1] x2=dataset.iloc[:, index2] x3=dataset.iloc[:, index3] y=dataset.iloc[:, index4] #converting string into array x1np=np.array(x1,dtype=float) x2np=np.array(x2,dtype=float) x3np=np.array(x3,dtype=float) ynp=np.array(y,dtype=float).flatten() # 转成一维数组方便矩阵运算 # 合并输入特征为N×3的矩阵 X = np.hstack([x1np, x2np, x3np]) N = X.shape[0] # 构建线性RBF的核矩阵 def linear_rbf(x_i, x_j): return np.linalg.norm(x_i - x_j) K = np.zeros((N, N)) for i in range(N): for j in range(N): K[i,j] = linear_rbf(X[i], X[j]) # 可选:添加微小的正则化项,进一步避免矩阵奇异 K += 1e-6 * np.eye(N) # 用QR分解求解系数矩阵 Q, R = np.linalg.qr(K) coeffs = np.linalg.solve(R, Q.T @ ynp) # 自定义插值函数 def custom_rbf_interp(x1, x2, x3): x = np.array([x1, x2, x3]).reshape(1, 3) # 计算输入点与所有样本点的距离 dists = np.linalg.norm(X - x, axis=1) # 计算插值结果 return np.dot(dists, coeffs) # 生成估计值 estimation = np.array([custom_rbf_interp(x1np[i][0], x2np[i][0], x3np[i][0]) for i in range(N)]) # Write the estimation output in Another Excel file workbook = xlsxwriter.Workbook(r'C:\Users\Windows 10\.spyder-py3\RBF_Reg.xlsx') worksheet = workbook.add_worksheet('est_output') row=2 for outputverzug in enumerate(estimation): worksheet.write(row,0,outputverzug[1]) row+=1 # 修复原代码中write_column的错误 row=2 for idx, val in enumerate(ynp): worksheet.write(row,1,val) row+=1 worksheet.write(0,0,"Predicted Angle Values") worksheet.write(1,0,"°") worksheet.write(0,1,"Original Angle Values") worksheet.write(1,1,"°") worksheet.conditional_format('A2:A202', {'type': '3_color_scale', 'min_color': "#FF0000", 'max_color': "#00FF00"}) worksheet.conditional_format('B2:B202', {'type':'3_color_scale', 'min_color': "#00FF00", 'max_color': "#FF0000"}) workbook.close()
这里的核心是手动构建RBF核矩阵,然后用QR分解替代直接求逆来求解线性方程组,这样能避免奇异矩阵的问题。另外我还修复了原代码中write_column的使用错误,确保原始值能正确写入Excel。
额外建议
你可以先检查一下输入特征的相关性,比如用np.corrcoef(X.T)计算相关系数矩阵,如果某两个变量的相关系数接近1或-1,说明存在强共线性,这时候除了正则化,也可以考虑移除其中一个冗余变量,从根源上解决矩阵奇异的问题。
内容的提问来源于stack exchange,提问作者Umair Rehman
相关产品推荐
相关产品推荐

