机器学习项目分享之实现智能的矿物识别系统(二)
目录
简介
在上一篇博客当中我们对数据集进行处理,使用了6中方法进行数据填充然后经过一系列操作得到可以直接放到模型里面训练的数据集。接下来我们将使用6中机器学习的算法进行训练预测。

我们首先以平均数的填充方法得到的训练集与测试集为例,使用6种模型进行训练。
训练前准备
读取训练数据与测试数据
train_data = pd.read_excel(r"D:\PythonProject\培训\机器学习\矿物分析\shuju\训练集数据(平均数).xlsx")
test_data = pd.read_excel(r"D:\PythonProject\培训\机器学习\矿物分析\shuju\测试集数据(平均数).xlsx")
从指定路径读取训练集 Excel 文件,存储在train_data变量中,从指定路径读取测试集 Excel 文件,存储在test_data变量中
划分训练集与测试集特征和标签
train_data_x = train_data.iloc[:,1:] # 取所有行,从第2列开始的所有列作为特征
train_data_y = train_data.iloc[:,0] # 取所有行,第1列作为标签(目标变量)
test_data_x = test_data.iloc[:,1:] # 测试集特征
test_data_y = test_data.iloc[:,0] # 测试集标签
创建结果存储字典
result_data = {} # 用于后续存储模型训练和评估的结果
一、逻辑回归
网格搜索
网格搜索(Grid Search)进行逻辑回归模型的超参数调优
param_grid = {
'penalty': ['l1', 'l2', 'elasticnet', 'none'],
'C':[0.001, 0.01, 0.1, 1, 10, 100],
'solver':['newton-cg', 'lbfgs', 'liblinear', 'sag', 'saga'],
'max_iter':[100, 200, 500],
'multi_class':[ 'multinomial']
}
logreg=LogisticRegression()
grid_search=GridSearchCV(logreg,param_grid,cv=5)
grid_search.fit(train_data_x,train_data_y)
print("输出最佳参数:")
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_predicted=lr.predict(train_data_x)
print('LR的自测:\n',metrics.classification_report(train_data_y,train_predicted))
# 在测试集上进行预测并评估
test_predicted=lr.predict(test_data_x)
print('LR的测试:\n',metrics.classification_report(test_data_y,test_predicted)):\n',metrics.classification_report(train_data_y,train_predicted))
# 在测试集上进行预测并评估
test_predicted=lr.predict(test_data_x)
print('LR的测试:\n',metrics.classification_report(test_data_y,test_predicted))
结果提取与保存
# 保留6位小数的评估报告
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 # 将逻辑回归结果存入总结果字典
将关键评估指标(各类别召回率和总体准确率)提取出来保存到字典中,方便后续分析或与其他模型比较。

二、随机森林
网格搜索
网格搜索(Grid Search)进行逻辑回归模型的超参数调优
param_grid = {
'n_estimators': [50, 100, 200, 300], # 树的数量
'max_depth': [None, 10, 20, 30, 40], # 树的最大深度
'min_samples_split': [2, 5, 10], # 分裂内部节点所需的最小样本数
'min_samples_leaf': [1, 2, 4], # 叶节点所需的最小样本数
'max_features': ['sqrt', 'log2', None], # 寻找最佳分裂时考虑的特征数量
'bootstrap': [True, False], # 是否使用bootstrap抽样
'criterion': ['gini', 'entropy'] # 不纯度的衡量标准
}
logreg=RandomForestClassifier()
grid_search=GridSearchCV(logreg,param_grid,cv=5)
grid_search.fit(train_data_x,train_data_y)
print("输出最佳参数:")
print(grid_search.best_params_)
模型训练
RF_result = {} # 用于存储随机森林的评估结果
# 使用网格搜索找到的最佳参数初始化模型(这里固定了random_state确保结果可复现)
rf = RandomForestClassifier(bootstrap=False, max_depth=20, max_features='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)
print('RF的自测:\n', metrics.classification_report(train_data_y, train_predicted))
# 在测试集上预测并评估
test_predicted = rf.predict(test_data_x)
print('RF的测试:\n', metrics.classification_report(test_data_y, test_predicted))
结果提取与保存
# 提取评估指标
a = metrics.classification_report(test_data_y, test_predicted, digits=6)
b = a.split() # 将报告字符串按空格分割成列表
# 提取各类别的召回率和整体准确率
RF_result['recall_0'] = float(b[6]) # 类别0的召回率
RF_result['recall_1'] = float(b[11]) # 类别1的召回率
RF_result['recall_2'] = float(b[16]) # 类别2的召回率
RF_result['recall_3'] = float(b[21]) # 类别3的召回率
RF_result['acc'] = float(b[25]) # 整体准确率
result_data['RF'] = RF_result # 将随机森林结果存入总结果字典
将关键评估指标(各类别召回率和总体准确率)提取出来保存到字典中,方便后续分析或与其他模型比较。随机森林是一种集成学习方法,通过构建多棵决策树并综合其结果来提高预测性能和稳定性。

三、SVM
网格搜索
网格搜索(Grid Search)进行逻辑回归模型的超参数调优
from sklearn.svm import SVC
param_grid = {
'C': [0.001, 0.01, 0.1, 1, 2], # 正则化参数,控制惩罚项强度
'kernel': ['linear', 'poly', 'rbf', 'sigmoid'], # 核函数类型
'gamma': ['scale', 'auto', 0.001, 0.01, 0.1, 1], # 核系数,用于rbf, poly和sigmoid
'degree': [2, 3, 4], # 多项式核函数的阶数(仅对poly有效)
'coef0': [0.0, 0.1, 1.0], # 核函数中的独立项(对poly和sigmoid有效)
'shrinking': [True, False], # 是否使用收缩启发式方法
'probability': [False, True], # 是否启用概率估计
'class_weight': [None, 'balanced'] # 类别权重
}
logreg=SVC()
grid_search=GridSearchCV(logreg,param_grid,cv=5)
grid_search.fit(train_data_x,train_data_y)
print("输出最佳参数:")
print(grid_search.best_params_)
模型训练
svm_result = {} # 用于存储SVM的评估结果
# 使用网格搜索得到的最佳参数初始化SVM模型
svm = SVC(C=1, coef0=0.1, degree=4, gamma=1, kernel='poly',
probability=True, random_state=100)
svm.fit(train_data_x, train_data_y) # 用训练数据拟合模型
模型评估与结果提取:
# 在训练集上预测并评估
train_predicted = svm.predict(train_data_x)
print('SVM的自测:\n', metrics.classification_report(train_data_y, train_predicted))
# 在测试集上预测并评估
test_predicted = svm.predict(test_data_x)
print('SVM的测试:\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]) # 类别0的召回率
svm_result['recall_1'] = float(b[11]) # 类别1的召回率
svm_result['recall_2'] = float(b[16]) # 类别2的召回率
svm_result['recall_3'] = float(b[21]) # 类别3的召回率
svm_result['acc'] = float(b[25]) # 整体准确率
result_data['SVM'] = svm_result # 将SVM结果存入总结果字典

四、AdaBoost
网格搜索
网格搜索(Grid Search)进行逻辑回归模型的超参数调优
from sklearn.ensemble import AdaBoostClassifier
from sklearn.tree import DecisionTreeClassifier
# AdaBoost分类器的网格搜索参数
param_grid = {
'n_estimators': [50, 100, 200, 300], # 弱学习器的数量
'learning_rate': [0.01, 0.1, 0.5, 1.0, 1.5], # 学习率,控制每个弱学习器的权重缩减
'algorithm': ['SAMME', 'SAMME.R'], # 提升算法,SAMME.R使用预测概率
# 基分类器的参数(这里使用决策树作为基分类器)
'base_estimator__max_depth': [1, 2, 3, 4], # 基分类器的最大深度
'base_estimator__min_samples_split': [2, 5], # 基分类器的最小分裂样本数
'base_estimator__min_samples_leaf': [1, 2] # 基分类器的最小叶节点样本数
}
logreg=AdaBoostClassifier()
grid_search=GridSearchCV(logreg,param_grid,cv=5)
grid_search.fit(train_data_x,train_data_y)
print("输出最佳参数:")
print(grid_search.best_params_)
模型训练
AdaBoost_result = {} # 用于存储AdaBoost的评估结果
# 用网格搜索得到的最佳参数初始化模型(指定基分类器为决策树,max_depth=2)
AdaBoost = AdaBoostClassifier(algorithm='SAMME',
base_estimator=DecisionTreeClassifier(max_depth=2),
n_estimators=200,
learning_rate=1.0,
random_state=0) # random_state确保结果可复现
AdaBoost.fit(train_data_x, train_data_y) # 用训练集拟合模型
模型评估与结果提取
# 在训练集上预测并评估(自测,查看是否过拟合)
train_predicted = AdaBoost.predict(train_data_x)
print('AdaBoost的自测:\n', metrics.classification_report(train_data_y, train_predicted))
# 在测试集上预测并评估(验证泛化能力)
test_predicted = AdaBoost.predict(test_data_x)
print('AdaBoost的测试:\n', metrics.classification_report(test_data_y, test_predicted))
# 提取测试集评估指标(保留6位小数)
a = metrics.classification_report(test_data_y, test_predicted, digits=6)
b = a.split() # 将评估报告字符串按空格分割为列表,便于提取数值
# 提取4个类别的召回率(recall)和整体准确率(acc)
AdaBoost_result['recall_0'] = float(b[6]) # 类别0的召回率
AdaBoost_result['recall_1'] = float(b[11]) # 类别1的召回率
AdaBoost_result['recall_2'] = float(b[16]) # 类别2的召回率
AdaBoost_result['recall_3'] = float(b[21]) # 类别3的召回率
AdaBoost_result['acc'] = float(b[25]) # 整体准确率
# 将AdaBoost结果存入总结果字典,便于后续与其他模型对比
result_data['AdaBoost'] = AdaBoost_result
AdaBoost 的优势是能有效降低偏差(通过聚焦错分样本),但对噪声数据较敏感,参数调优(尤其是学习率和弱学习器数量)对性能影响较大。

五、 XGBoost
网格搜索
网格搜索(Grid Search)进行逻辑回归模型的超参数调优
XGBoost_result = {} # 存储XGBoost的评估结果
# 用指定参数初始化XGBoost分类器
xgb = xgb.XGBClassifier(
learning_rate=0.05, # 学习率
n_estimators=200, # 树的数量
num_class=5, # 多分类的类别数(这里指定为5类)
max_depth=7, # 树的最大深度
min_child_weight=1, # 子节点最小权重和
gamma=0, # 分裂所需最小损失减少量
subsample=0.6, # 样本采样比例
colsample_bytree=0.8, # 特征采样比例
objective='multi:softmax', # 多分类目标函数(输出类别)
seed=0 # 随机种子,确保结果可复现
)
logreg=()
grid_search=xgb.XGBClassifier(logreg,param_grid,cv=5)
grid_search.fit(train_data_x,train_data_y)
print("输出最佳参数:")
print(grid_search.best_params_)
模型训练
XGBoost_result={}
xgb=xgb.XGBClassifier(learning_rate=0.05,n_estimators=200,
num_class=5,max_depth=7,min_child_weight=1,gamma=0,subsample=0.6,
colsample_bytree=0.8,objective='multi:softmax',seed=0
)
xgb.fit(train_data_x,train_data_y)
模型评估与结果提取
# 在训练集上预测并评估(自测,检查是否过拟合)
train_predicted = xgb.predict(train_data_x)
print('XGBoost的自测:\n', metrics.classification_report(train_data_y, train_predicted))
# 在测试集上预测并评估(验证泛化能力)
test_predicted = xgb.predict(test_data_x)
print('XGBoost的测试:\n', metrics.classification_report(test_data_y, test_predicted))
# 提取测试集评估指标(保留6位小数)
a = metrics.classification_report(test_data_y, test_predicted, digits=6)
b = a.split() # 将评估报告按空格分割为列表,便于提取数值
# 提取4个类别的召回率(recall)和整体准确率(acc)
XGBoost_result['recall_0'] = float(b[6]) # 类别0的召回率
XGBoost_result['recall_1'] = float(b[11]) # 类别1的召回率
XGBoost_result['recall_2'] = float(b[16]) # 类别2的召回率
XGBoost_result['recall_3'] = float(b[21]) # 类别3的召回率
XGBoost_result['acc'] = float(b[25]) # 整体准确率
# 将XGBoost结果存入总结果字典,用于后续模型对比
result_data['XGBoost'] = XGBoost_result

六、GaussianNB
导入高斯朴素贝叶斯模型
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)
print('GNB的自测:\n', metrics.classification_report(train_data_y, train_predicted))
# 在测试集上预测并评估(验证泛化能力)
test_predicted = GNB.predict(test_data_x)
print('GNB的测试:\n', metrics.classification_report(test_data_y, test_predicted))
提取关键评估指标
# 保留6位小数的评估报告,转换为字符串后按空格分割为列表
a = metrics.classification_report(test_data_y, test_predicted, digits=6)
b = a.split()
# 提取4个类别的召回率和整体准确率(索引对应报告中的位置)
GNB_result['recall_0'] = float(b[6]) # 类别0的召回率
GNB_result['recall_1'] = float(b[11]) # 类别1的召回率
GNB_result['recall_2'] = float(b[16]) # 类别2的召回率
GNB_result['recall_3'] = float(b[21]) # 类别3的召回率
GNB_result['acc'] = float(b[25]) # 整体准确率
# 将高斯朴素贝叶斯的结果存入总结果字典
result_data['GNB'] = GNB_result

七、保存所有模型结果
import json # 导入JSON处理库
result = {} # 最终要保存的总结果字典
result['mean fill'] = result_data # 用"mean fill"作为键,存储所有模型的结果(可能表示数据用平均值填充的场景)
# 将结果写入JSON文件
with open(r'D:\PythonProject\培训\机器学习\矿物分析\temp_data\平均值填充result.json', 'w', encoding='utf-8') as file:
json.dump(
result,
file,
ensure_ascii=False, # 确保中文等非ASCII字符正常显示
indent=4 # 缩进4格,使JSON文件格式更易读
)


总结
最终我们发现XGBoost在所有模型中的准确率与召回率最高,我们还要继续使用不同的填充数据方法进行再训练测试。即在中位数下6种模型的效果,最终选取出最佳的数据填充方式和最佳的模型
更多推荐
所有评论(0)