numpy Scipy线性分类?

huwehgph  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(118)

我尝试使用x,y,z值和岩性分类创建岩性值的3d模型。我得到的最接近的解决方案是使用线性插值方法,然而,我想根据未知值是否线性地位于两个已知点之间来分类,而不是插值。有没有办法在python中做到这一点?我尝试过逻辑回归模型,但问题是数据集相对稀疏,每个站点都不同,所以模型不能很好地泛化。
我的数据是经纬度和NAVD 88表面高程。我知道投影问题,我可能会在以后投影我的数据,以使其在空间上更准确,但现在我试图看看是否有一种相对简单的方法来在两个已知的x,y,z点之间进行分类,而不必编写自己的线性表达式算法。
提前感谢!
这是我现在插值的方法:

#query is my dataset queried from my database
# Dimensions
latitude_vals = query['Y']
longitude_vals = query['X']
z_vals = query['lith_elev_start']
lith_vals = query['SoilID']

#numpy array conversion
x = np.asarray(longitude_vals, dtype=np.float64)
y = np.asarray(latitude_vals, dtype=np.float64)
z = np.asarray(z_vals, dtype=np.float64)

# Map text values to numerical codes
lith_mapping = {lith: code for code, lith in enumerate(lith_vals.unique())}  #encode lithology classifications to integers
w = np.array([lith_mapping[lith] for lith in lith_vals], dtype=np.float64)  #np array of lith classification values

# Create a grid of coordinates for the output NetCDF
output_x = np.linspace(min(x), max(x), 100)
output_y = np.linspace(min(y), max(y), 100)
output_z = np.linspace(min(z), max(z), 100)

# Use meshgrid to create 3D arrays of coordinates
output_x, output_y, output_z = np.meshgrid(output_x, output_y, output_z, indexing='ij')

# Interpolate on the grid
grid_points = np.array([output_x.flatten(), output_y.flatten(), output_z.flatten()]).T

output_w_linear = griddata((x, y, z), w, grid_points, method='linear', fill_value=-9999)

output_w_linear =output_w_linear.reshape(output_x.shape)

字符串

okxuctiv

okxuctiv1#

如果我正确理解你的问题:

  • 你有三维坐标Map到类(岩性);
  • 你想在新的坐标上预测类

scipy库可以为多维函数执行插值,但它们不是分类器。Decompression类在这种情况下没有意义。
另一方面,sklearn有很多内置的机制来做到这一点。

MCVE

让我们创建一些3D数据集与3个不同的类:

import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import confusion_matrix

s = np.linspace(0, 1, 10)
X, Y, Z = np.meshgrid(s, s, s)
T = np.zeros_like(X)
T[X+Y+Z>2] = 1
T[X+Y-Z>1] = 2

data = np.array([X.ravel(), Y.ravel(), Z.ravel()]).T
target = T.ravel()

字符串
现在我们可以训练classifier并检查测试数据,它的性能符合预期。

X_train, X_test, y_train, y_test = train_test_split(data, target, test_size=0.2, stratify=target, random_state=123)

model = KNeighborsClassifier(n_neighbors=10, weights="distance")
model.fit(X_train, y_train)


我们选择KNeighborsClassifier,因为它似乎更适合您的要求,但您有很多选择。
一旦模型被拟合,我们就可以预测测试折叠的新位置类:

y_pred = model.predict(X_test)


并衡量这个预测的准确性:

model.score(X_test, y_test)  # 0.975
confusion_matrix(y_test, y_pred)
# array([[142,   0,   0],
#        [  2,  23,   0],
#        [  3,   0,  30]]


对于这个玩具例子来说,这是相当不错的。

相关问题