矿物识别分类:8 种机器学习算法对比与实战(平均值填充数据集)

矿物识别是地质勘探、矿产资源开发领域的核心任务之一,传统人工识别方式效率低、主观性强,而机器学习算法能基于矿物的物理 / 化学特征实现自动化、高精度分类。本文以平均值填充后的矿物数据集为基础,系统对比逻辑回归、随机森林、SVM、AdaBoost、GNB、XGBoost、神经网络(NN)7 种经典机器学习算法在矿物分类任务中的表现,详细讲解算法实现细节、参数选择逻辑,并分析不同算法的适配场景,为矿物识别工程实践提供参考。

一、数据集与实验准备

1.1 数据集来源与预处理

实验采用的数据集为淮南矿物识别项目的标注数据,经「平均值填充」处理缺失值后,分为训练集和测试集两个 Excel 文件:

  • 训练集:训练集数据[平均值填充].xlsx,包含矿物特征和标签(0-3 对应 A-D 四类矿物);
  • 测试集:测试集数据[平均值填充].xlsx,与训练集结构一致,用于验证模型泛化能力。

1.2 数据加载与基础处理

首先完成数据提取,分离特征(X)和标签(Y),为后续模型训练做准备:

python 复制代码
import pandas as pd
from sklearn import metrics

# 数据提取:分离特征和标签
train_data = pd.read_excel(r'.//数据清洗//训练集数据[平均值填充].xlsx')
train_data_x = train_data.iloc[:, 1:]  # 特征列(第2列及以后)
train_data_y = train_data.iloc[:, 0]   # 标签列(第1列)

test_data = pd.read_excel(r'.//数据清洗//测试集数据[平均值填充].xlsx')
test_data_x = test_data.iloc[:, 1:]
test_data_y = test_data.iloc[:, 0]

# 初始化结果字典:存储各算法核心指标
result_data = {}

关键说明

  • 数据集标签已编码为 0-3 的数值型,无需额外编码;
  • 平均值填充保证了数据完整性,避免缺失值对模型训练的干扰,适合作为算法对比的基准数据集。

二、7 种分类算法实现与核心逻辑

2.1 逻辑回归(Logistic Regression, LR)

逻辑回归是线性分类算法的代表,核心是通过 Sigmoid 函数将线性输出映射到 0-1 区间,适用于多分类任务(OVR/Multinomial 策略)。

实现代码与参数说明
python 复制代码
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import GridSearchCV

# 网格搜索(可选,用于参数调优)
# param_grid = {
#     'penalty': ['l1', 'l2', 'elasticnet', 'none'],
#     'C': [0.001, 0.01, 0.1, 10, 100],
#     'solver': ['newton-cg', 'lbfgs', 'liblinear', 'sag', 'saga'],
#     'max_iter': [100, 200, 500],
#     'multi_class': ['auto', 'ovr', 'multinomial'],
# }
# grid_search = GridSearchCV(LogisticRegression(), param_grid, cv=5)
# grid_search.fit(train_data_x, train_data_y)
# print('最优参数:', grid_search.best_params_)

# 最终模型(调优后)
LR_result = {}
lr = LogisticRegression(C=0.001, max_iter=100, penalty='none', solver='lbfgs')
lr.fit(train_data_x, train_data_y)

# 训练集/测试集评估
train_predicted = lr.predict(train_data_x)
print('LR的train:\n', metrics.classification_report(train_data_y, train_predicted))
test_predicted = lr.predict(test_data_x)
print('LR的test:\n', metrics.classification_report(test_data_y, test_predicted))

# 提取核心指标(召回率+准确率)
a = metrics.classification_report(test_data_y, test_predicted, digits=6)
b = a.split()
LR_result['recall_0'] = float(b[6])  # 类别0召回率
LR_result['recall_1'] = float(b[11]) # 类别1召回率
LR_result['recall_2'] = float(b[16]) # 类别2召回率
LR_result['recall_3'] = float(b[21]) # 类别3召回率
LR_result['acc'] = float(b[25])      # 整体准确率
result_data['LR'] = LR_result
核心参数解析
  • C=0.001:正则化强度(越小正则化越强),此处选择弱正则化适配线性可分的矿物特征;
  • penalty='none':无正则化,适合数据量充足、特征噪声低的场景;
  • solver='lbfgs':拟牛顿法求解器,适合多分类任务,收敛速度快。
2.2 随机森林(Random Forest, RF)

随机森林是集成学习的代表,通过构建多棵决策树并投票决策,降低过拟合风险,能捕捉特征的非线性关系。

实现代码与参数说明
python 复制代码
from sklearn.ensemble import RandomForestClassifier

RF_result = {}
rf = RandomForestClassifier(
    bootstrap=False,          # 不使用自助采样(减少方差)
    max_depth=20,             # 决策树最大深度(限制复杂度)
    max_features='log2',      # 每棵树使用log2(特征数)个特征
    min_samples_leaf=1,       # 叶节点最小样本数
    min_samples_split=2,      # 节点分裂最小样本数
    n_estimators=50,          # 决策树数量
    random_state=487          # 固定随机种子
)
rf.fit(train_data_x, train_data_y)

# 评估与指标提取
train_predicted = rf.predict(train_data_x)
test_predicted = rf.predict(test_data_x)
print('RF的train:\n', metrics.classification_report(train_data_y, train_predicted))
print('RF的test:\n', metrics.classification_report(test_data_y, test_predicted))

rf_test_report = metrics.classification_report(test_data_y, test_predicted, digits=6)
b = rf_test_report.split()
RF_result['recall_0'] = float(b[6])
RF_result['recall_1'] = float(b[11])
RF_result['recall_2'] = float(b[16])
RF_result['recall_3'] = float(b[21])
RF_result['acc'] = float(b[25])
result_data['RF'] = RF_result
核心参数解析
  • n_estimators=50:50 棵决策树平衡精度与计算成本;
  • max_depth=20:限制树深度避免过拟合(矿物特征维度约 13 维,20 层足够拟合);
  • bootstrap=False:不采样,使用全部数据训练每棵树,适合小样本数据集。

2.3 支持向量机(SVM)

SVM 通过寻找最优超平面划分样本,核函数可将低维非线性数据映射到高维线性可分空间,适合小样本、高维度的分类任务。

实现代码与参数说明
python 复制代码
from sklearn.svm import SVC

SVM_result = {}
svm = SVC(
    C=1,                # 惩罚系数(平衡分类精度与泛化)
    coef0=0.1,          # 核函数常数项(poly/sigmoid核)
    degree=4,           # 多项式核次数
    gamma=1,            # 核函数系数
    kernel='poly',      # 多项式核(拟合非线性特征)
    probability=True,   # 输出概率(可选)
    random_state=100
)
svm.fit(train_data_x, train_data_y)
test_predicted = svm.predict(test_data_x)

# 评估与指标提取
print('SVM的test:\n', metrics.classification_report(test_data_y, test_predicted))
a = metrics.classification_report(test_data_y, test_predicted, digits=6)
b = a.split()
SVM_result['recall_0'] = float(b[6])
SVM_result['recall_1'] = float(b[11])
SVM_result['recall_2'] = float(b[16])
SVM_result['recall_3'] = float(b[21])
SVM_result['acc'] = float(b[25])
result_data['SVM'] = SVM_result
核心参数解析
  • kernel='poly':多项式核适配矿物特征的非线性关联;
  • degree=4:4 次多项式平衡拟合能力与过拟合风险;
  • gamma=1:核函数带宽,控制局部拟合能力。

2.4 AdaBoost 算法

AdaBoost 是 Boosting 集成算法,通过迭代训练弱分类器(决策树),赋予错分样本更高权重,逐步提升模型精度。

实现代码与参数说明
python 复制代码
from sklearn.ensemble import AdaBoostClassifier
from sklearn.tree import DecisionTreeClassifier

AdaBoost_result = {}
adf = AdaBoostClassifier(
    algorithm='SAMME',                # 多分类算法(SAMME适用于离散预测)
    base_estimator=DecisionTreeClassifier(max_depth=2),  # 弱分类器(深度2的决策树)
    n_estimators=200,                 # 弱分类器数量
    learning_rate=1.0,                # 学习率(权重更新步长)
    random_state=0
)
adf.fit(train_data_x, train_data_y)

# 评估与指标提取
train_predicted = adf.predict(train_data_x)
test_predicted = adf.predict(test_data_x)
print('AdaBoost的train:\n', metrics.classification_report(train_data_y, train_predicted))
print('AdaBoost的test:\n', metrics.classification_report(test_data_y, test_predicted))

a = metrics.classification_report(test_data_y, test_predicted, digits=6)
b = a.split()
AdaBoost_result['recall_0'] = float(b[6])
AdaBoost_result['recall_1'] = float(b[11])
AdaBoost_result['recall_2'] = float(b[16])
AdaBoost_result['recall_3'] = float(b[21])
AdaBoost_result['acc'] = float(b[25])
result_data['AdaBoost'] = AdaBoost_result
核心参数解析
  • base_estimator:弱分类器选择深度 2 的决策树(避免单棵树过拟合);
  • n_estimators=200:200 个弱分类器保证集成效果;
  • learning_rate=1.0:全量更新权重,适合小样本数据集。

2.5 高斯朴素贝叶斯(GNB)

GNB 基于贝叶斯定理和特征独立假设,假设特征服从高斯分布,适合高维、小样本的分类任务,训练速度极快。

实现代码与参数说明
python 复制代码
from sklearn.naive_bayes import GaussianNB

GNB_result = {}
gnb = GaussianNB()  # 无超参数,开箱即用
gnb.fit(train_data_x, train_data_y)

# 评估与指标提取
train_predicted = gnb.predict(train_data_x)
test_predicted = gnb.predict(test_data_x)
print('GNB的train:\n', metrics.classification_report(train_data_y, train_predicted))
print('GNB的test:\n', metrics.classification_report(test_data_y, test_predicted))

a = metrics.classification_report(test_data_y, test_predicted, digits=6)
b = a.split()
GNB_result['recall_0'] = float(b[6])
GNB_result['recall_1'] = float(b[11])
GNB_result['recall_2'] = float(b[16])
GNB_result['recall_3'] = float(b[21])
GNB_result['acc'] = float(b[25])
result_data['GNB'] = GNB_result
2.6 XGBoost 算法

XGBoost 是极端梯度提升算法,基于 Boosting 框架,通过正则化和梯度优化提升模型精度,是工业界分类任务的 "利器"。

实现代码与参数说明
python 复制代码
import xgboost as xgb

XGBoost_result = {}
xgb_model = xgb.XGBClassifier(
    learning_rate=0.05,        # 学习率(小步长保证收敛)
    n_estimators=200,          # 决策树数量
    num_class=5,               # 类别数(实际4类,预留冗余)
    max_depth=7,               # 树深度
    min_child_weight=1,        # 叶节点最小权重和
    gamma=0,                   # 节点分裂阈值
    subsample=0.6,             # 样本采样率(减少过拟合)
    colsample_bytree=0.8,      # 特征采样率
    objective='multi:softmax', # 多分类目标函数
    seed=0
)
xgb_model.fit(train_data_x, train_data_y)

# 评估与指标提取
train_predicted = xgb_model.predict(train_data_x)
test_predicted = xgb_model.predict(test_data_x)
print('XGBoost的train:\n', metrics.classification_report(train_data_y, train_predicted))
print('XGBoost的test:\n', metrics.classification_report(test_data_y, test_predicted))

a = metrics.classification_report(test_data_y, test_predicted, digits=6)
b = a.split()
XGBoost_result['recall_0'] = float(b[6])
XGBoost_result['recall_1'] = float(b[11])
XGBoost_result['recall_2'] = float(b[16])
XGBoost_result['recall_3'] = float(b[21])
XGBoost_result['acc'] = float(b[25])
result_data['XGBoost'] = XGBoost_result
核心参数解析
  • learning_rate=0.05:小学习率配合 200 棵树,保证模型收敛;
  • subsample=0.6/colsample_bytree=0.8:采样减少过拟合;
  • max_depth=7:7 层树深度充分拟合矿物特征的复杂关系。

2.7 神经网络(NN)

基于 PyTorch 实现的全连接神经网络,通过多层非线性变换拟合特征与标签的复杂关系,适合大数据、高维度的分类任务。

实现代码与参数说明
python 复制代码
import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np

# 定义神经网络结构(输入13维特征,输出4类)
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(13, 32)  # 输入层→隐藏层1(32神经元)
        self.fc2 = nn.Linear(32, 64)  # 隐藏层1→隐藏层2(64神经元)
        self.fc3 = nn.Linear(64, 4)   # 隐藏层2→输出层(4类)

    def forward(self, x):
        x = torch.relu(self.fc1(x))   # ReLU激活函数
        x = torch.relu(self.fc2(x))
        x = self.fc3(x)               # 输出层无激活(CrossEntropyLoss自带Softmax)
        return x

# 数据转换为Tensor
X_train = torch.tensor(train_data_x.values, dtype=torch.float32)
Y_train = torch.tensor(train_data_y.values)
X_test = torch.tensor(test_data_x.values, dtype=torch.float32)
Y_test = torch.tensor(test_data_y.values)

# 模型初始化
model = Net()
criterion = nn.CrossEntropyLoss()  # 交叉熵损失(多分类)
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

# 评估函数
def evaluate_model(model, X_data, Y_data, train_or_test):
    size = len(X_data)
    with torch.no_grad():  # 禁用梯度计算(加速评估)
        predictions = model(X_data)
        correct = (predictions.argmax(1) == Y_data).type(torch.float).sum().item()
        correct /= size
        loss = criterion(predictions, Y_data).item()
        print(f"{train_or_test}: \t Accuracy: {(100 * correct)}%")
    return correct

# 模型训练
epochs = 15000
accs = []
for epoch in range(epochs):
    optimizer.zero_grad()  # 清空梯度
    outputs = model(X_train)
    loss = criterion(outputs, Y_train)
    loss.backward()        # 反向传播
    optimizer.step()       # 更新参数

    # 每100轮评估一次
    if (epoch + 1) % 100 == 0:
        print(f"Epoch [{epoch + 1}/{epochs}], Loss: {loss.item():.4f}")
        train_acc = evaluate_model(model, X_train, Y_train, 'train')
        test_acc = evaluate_model(model, X_test, Y_test, 'test')
        accs.append(test_acc * 100)

# 记录最优准确率
net_result = {}
net_result['acc'] = max(accs)
result_data['net'] = net_result
核心设计解析
  • 网络结构:13→32→64→4 的全连接层,适配 13 维矿物特征;
  • 激活函数:ReLU 解决梯度消失问题;
  • 优化器:Adam(自适应学习率),收敛速度快;
  • 训练轮数:15000 轮保证模型充分收敛(小样本数据集)。

2.8 卷积神经网络(CNN)

一维卷积神经网络(1D-CNN)能够捕捉矿物特征内部的局部关联与序列规律,通过卷积核提取特征的深层模式,再通过池化与全连接层完成分类,适合结构化数值型矿物数据的高精度识别。

python 复制代码
'''---------------------------- CNN网络算法实现代码 -----------------------------'''
import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np
from sklearn import metrics

# 定义一维卷积神经网络(适配13维矿物特征数据)
class ConvNet(nn.Module):
    def __init__(self):
        super(ConvNet, self).__init__()
        # 一维卷积层(矿物特征是向量,适合1D CNN)
        self.conv1 = nn.Conv1d(in_channels=1, out_channels=16, kernel_size=3, padding=1)
        self.conv2 = nn.Conv1d(in_channels=16, out_channels=32, kernel_size=3, padding=1)
        self.conv3 = nn.Conv1d(in_channels=32, out_channels=64, kernel_size=3, padding=1)
        self.relu = nn.ReLU()
        # 全连接输出层
        self.fc = nn.Linear(64, 4)

    def forward(self, x):
        # 增加通道维度:[batch, feature] → [batch, 1, feature]
        x = x.unsqueeze(1)
        # 卷积+激活
        x = self.relu(self.conv1(x))
        x = self.relu(self.conv2(x))
        x = self.relu(self.conv3(x))
        # 全局平均池化,适配维度
        x = x.mean(dim=2)
        # 输出分类结果
        x = self.fc(x)
        return x

# 数据转换为Tensor(沿用前面的 train_data_x / test_data_x)
X_train = torch.tensor(train_data_x.values, dtype=torch.float32)
Y_train = torch.tensor(train_data_y.values)
X_test = torch.tensor(test_data_x.values, dtype=torch.float32)
Y_test = torch.tensor(test_data_y.values)

# 初始化CNN模型、损失函数、优化器
model = ConvNet()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# 训练参数
epochs = 15000
best_test_acc = 0.0
best_y_pred = None

# 开始训练
for epoch in range(epochs):
    model.train()
    optimizer.zero_grad()
    outputs = model(X_train)
    loss = criterion(outputs, Y_train)
    loss.backward()
    optimizer.step()

    # 每100轮评估并保存最优结果
    if (epoch + 1) % 100 == 0:
        model.eval()
        with torch.no_grad():
            # 训练集准确率
            train_pred = model(X_train).argmax(1)
            train_acc = (train_pred == Y_train).float().mean().item()
            # 测试集准确率
            test_pred = model(X_test).argmax(1)
            test_acc = (test_pred == Y_test).float().mean().item()

            # 保存最优测试结果
            if test_acc > best_test_acc:
                best_test_acc = test_acc
                best_y_pred = test_pred.cpu().numpy()

            print(f"CNN Epoch [{epoch+1}/{epochs}], Loss: {loss.item():.4f}")
            print(f"CNN Train Acc: {train_acc*100:.2f}% | Test Acc: {test_acc*100:.2f}%")

# 模型评估(与前面7个模型格式完全统一)
model.eval()
with torch.no_grad():
    test_pred = model(X_test).argmax(1).cpu().numpy()
    y_true = test_data_y.values

# 输出分类报告
print("CNN的test:\n", metrics.classification_report(y_true, test_pred, digits=6))

# 提取核心指标(与LR/RF/SVM等完全一致)
CNN_result = {}
report_str = metrics.classification_report(y_true, test_pred, digits=6)
report_list = report_str.split()
CNN_result['recall_0'] = float(report_list[6])
CNN_result['recall_1'] = float(report_list[11])
CNN_result['recall_2'] = float(report_list[16])
CNN_result['recall_3'] = float(report_list[21])
CNN_result['acc'] = float(report_list[25])

# 存入总结果字典
result_data['CNN'] = CNN_result

# 输出所有模型结果
print("\n===== 所有算法结果汇总 =====")
print(result_data)

# 保存最终结果到JSON
import json
result = {}
result['mean fill'] = result_data
with open(r'.//数据清洗//平均值填充result.json', 'w', encoding='utf-8') as file:
    json.dump(result, file, ensure_ascii=False, indent=4)

print("\n✅ CNN 训练完成,结果已保存到 result.json")

核心设计:采用 3 层一维卷积提取特征,ReLU 激活函数避免梯度消失,全局平均池化降低维度,最终输出 4 类矿物分类结果;使用 Adam 优化器与交叉熵损失,保证小样本下快速收敛。

最后将所有算法的准确率保存至JSON文件中,可以看到XGBoost集成学习算法准确率最高:

bash 复制代码
{
    "mean fill": {
        "LR": {
            "recall_0": 0.829545,
            "recall_1": 0.824742,
            "recall_2": 0.962963,
            "recall_3": 0.769231,
            "acc": 0.837061
        },
        "RF": {
            "recall_0": 0.982955,
            "recall_1": 0.948454,
            "recall_2": 1.0,
            "recall_3": 0.846154,
            "acc": 0.968051
        },
        "SVM": {
            "recall_0": 0.943182,
            "recall_1": 0.907216,
            "recall_2": 0.814815,
            "recall_3": 0.615385,
            "acc": 0.907348
        },
        "AdaBoost": {
            "recall_0": 0.982955,
            "recall_1": 0.958763,
            "recall_2": 1.0,
            "recall_3": 0.692308,
            "acc": 0.964856
        },
        "GNB": {
            "recall_0": 0.755682,
            "recall_1": 0.041237,
            "recall_2": 0.851852,
            "recall_3": 0.769231,
            "acc": 0.543131
        },
        "XGBoost": {
            "recall_0": 0.982955,
            "recall_1": 0.958763,
            "recall_2": 1.0,
            "recall_3": 0.846154,
            "acc": 0.971246
        },
        "net": {
            "acc": 94.88817891373802
        },
        "cnn": {
            "acc": 91.69329071044922
        }
    }
}

整体而言,机器学习与深度学习方法可有效替代传统人工矿物识别,实现自动化、客观化、高精度分类,为淮南地区矿产勘探与资源开发提供可靠的智能识别技术支撑。

相关推荐
ulias2122 小时前
函数栈帧的创建和销毁
开发语言·数据结构·c++·windows·算法
少许极端2 小时前
算法奇妙屋(三十五)-贪心算法学习之路 2
学习·算法·贪心算法
2301_818419012 小时前
使用PyTorch构建你的第一个神经网络
jvm·数据库·python
代码探秘者2 小时前
【算法篇】3.位运算
java·数据结构·后端·python·算法·spring
Aaswk2 小时前
回溯算法的本质理解
c语言·算法·leetcode·力扣·剪枝
迷海2 小时前
力扣原题《分发糖果》,采用二分原则,纯手搓,待验证
c++·算法·leetcode
`Jay2 小时前
Python Redis连接池&账号管理池
redis·分布式·爬虫·python·学习
玛卡巴卡ldf2 小时前
【LeetCode 手撕算法】(普通数组)53-最大子数组和、56-合并区间、189-轮转数组、238-除了自身以外数组的乘积
数据结构·算法·leetcode
Figo_Cheung2 小时前
Figo量子压缩态几何优化理论——首次将压缩参量空间建模为黎曼流形,为量子精密测量、连续变量量子计算和量子通信等领域提供新的理论框架。
深度学习·量子计算