项目:矿物分类(训练模型)

根据上一篇博客我们对数据清洗得到了分别使用平均值,众数,中位数,只获取完整行,线性回归,逻辑森林这六种填充方法,获得了完整数据,可以用来训练模型。

就是我们比较熟悉的环节,会分别用,逻辑回归,随机森林,svm,adaboost,高斯贝叶斯,xgboost,全连接神经网络,卷积神经网络进行训练

一、读取数据,这里result_all={}是用来存储最终结果的,每一种填充方法对应八种模型训练的结果

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

train_data=pd.read_excel(r"D:\learn\temp_data\训练集[方法].xlsx")
x_train_data=train_data.iloc[:,1:]
y_train_data=train_data.iloc[:,0]

test_data=pd.read_excel(r"D:\learn\temp_data\测试集[方法].xlsx")
x_test_data=test_data.iloc[:,1:]
y_test_data=test_data.iloc[:,0]

result_all={}

二、训练方法

在使用算法之前需要介绍一种方法,网格搜索

对于之前的学习中我们通常使用交叉验证进行调参,对一个参数寻找最优值我们就需要使用一次交叉验证,当我们有很多个参数需要调节的时候,交叉验证就显得很笨重,所以我们使用网格搜索。网格搜索本质上也是交叉验证,但是网格搜索能一下筛选多个参数的最优值。

我们拿逻辑回归的参数进行举例:

导入这个模块,然后把每个参数列出来,和可以选择的值,这是一般写法,但是以下参数为逻辑回归的参数,这样写会出错。

python 复制代码
from sklearn.model_selection import GridSearchCV
param_grid={
    'solver':['newton-cg','lbfgs','liblinear','sag','sags'],
    'penalty':['l1','l2','elasticnet','none'],#正则化类型
    'C':[0.01,0.1,1,10],
    'max_iter':[100,200,500],
    'multi_class':['auto','ovr','multinomial'],
}

由于none惩罚的时候,不支持multinomial等,其他参数之间的限制,所以我们要分开写,这里方法改为设置一个列表用来保存得到最优值的结果,最后在对这四组获得的值进行筛选,选出最优的参数值

python 复制代码
#网格搜索方法进行调参
grid_chioce=[]
grid_chioce.append({
    'penalty': ['l1', 'l2'],  # 正则化类型
    'C': [0.01, 0.1, 1, 10],
    'solver': ['liblinear'],#linlinear一般收敛比较快迭代次数可以少些
    'max_iter': [100, 200],
    'multi_class': [ 'ovr'],
    })
grid_chioce.append({
    'solver': ['newton-cg', 'lbfgs'],
    'penalty': ['l2'],  # 正则化类型
    'C': [ 0.01, 0.1, 1, 10],
    'max_iter': [100, 200, 500],
    'multi_class': [ 'ovr', 'multinomial'],
    })
grid_chioce.append({
        'solver': ['saga'],
        'penalty': ['l1','l2'],  # 正则化类型
        'C': [0.01, 0.1, 1, 10],
        'max_iter': [100, 200, 500],
        'multi_class': ['ovr', 'multinomial'],
    })
grid_chioce.append({
        'solver': ['soga'],
        'penalty': ['elasticnet'],  # 正则化类型
        'C': [0.01, 0.1, 1, 10],
        'max_iter': [100, 200, 500],
        'multi_class': ['ovr', 'multinomial'],
        'l1_ratio': [0.1, 0.5, 0.9]  # 仅当penalty='elasticnet'时使用
    }
)
logic=LogisticRegression()
grid_search=GridSearchCV(logic,grid_chioce,cv=5)
grid_search.fit(x_train_data,y_train_data)
print('最佳参数:{}'.format(grid_search.best_params_))

网格搜索过程比较慢,这里我们直接使用已知比较好的参数值来进行训练模型

1.逻辑回归

python 复制代码
from sklearn.linear_model import  LogisticRegression

'''建立最优模型'''
Logic_result={}
Logic=LogisticRegression(C=0.001,max_iter=100,penalty='none',solver='lbfgs')
Logic.fit(x_train_data,y_train_data)

'''测试结果'''
train_pre=Logic.predict(x_train_data)
print('逻辑回归train:\n',metrics.classification_report(y_train_data,train_pre))
test_pre=Logic.predict(x_test_data)
print('逻辑回归test:\n',metrics.classification_report(y_test_data,test_pre))
a=metrics.classification_report(y_test_data,test_pre,digits=6)
b=a.split()

Logic_result['recall_0']=float(b[6])
Logic_result['recall_1']=float(b[11])
Logic_result['recall_2']=float(b[16])
Logic_result['recall_3']=float(b[21])
Logic_result['acc']=float(b[25])
result_all['Logic']=Logic_result
print('结束!')

2.随机森林

python 复制代码
from sklearn.ensemble import RandomForestClassifier
forest_result={}
forest=RandomForestClassifier(bootstrap=False,
                          max_depth=20,
                          max_features='log2',
                          min_samples_leaf=1,
                          min_samples_split=2,
                          n_estimators=50,
                          random_state=487)
forest.fit(x_train_data,y_train_data)

train_pre=forest.predict(x_train_data)
print('逻辑回归train:\n',metrics.classification_report(y_train_data,train_pre))
test_pre=forest.predict(x_test_data)
print('逻辑回归test:\n',metrics.classification_report(y_test_data,test_pre))
forest_test_report=metrics.classification_report(y_test_data,test_pre,digits=6)
b=forest_test_report.split()

forest_result['recall_0']=float(b[6])
forest_result['recall_1']=float(b[11])
forest_result['recall_2']=float(b[16])
forest_result['recall_3']=float(b[21])
forest_result['acc']=float(b[25])
result_all['forest']=forest_result
print('结束!')

3.svm

代码都是差不多的,基本上是下面这三点,其他修改一下

python 复制代码
from sklearn.svm import SVC
SVM_result={}
SVM=SVC(C=1,coef0=0.1,degree=4,gamma=1,kernel='poly',probability=True,random_state=100)

4.Adaboost(和上面一样)

python 复制代码
from sklearn.ensemble import AdaBoostClassifier
from sklearn.tree import DecisionTreeClassifier
Adaboost_result={}
Adaboost=AdaBoostClassifier(algorithm='SAMME',
                       base_estimator=DecisionTreeClassifier(max_depth=2),
                       n_estimators=200,
                       learning_rate=1.0,
                       random_state=0)

5.高斯贝叶斯(贝叶斯几乎没什么调节的参数,其他和上面一样,修改一下就可以)

python 复制代码
from sklearn.naive_bayes import GaussianNB
GNB_result={}
GNB=GaussianNB()

6.Xgboost(一样,不过这里有一点需要注意,就是xgboost可能不在sklearn,需要我们自己下载,就相当于下载一个库)

python 复制代码
import xgboost as xgb  #Xgboost库需要下载
xgb_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)

7.全连接神经网络

到神经网络,就跟上面机器学习的算法不一样了

神经网络不能接收表格,数据必须转化为张量数据,其实张量就是矩阵

Float32,表示精度有多高,32就是32位空间,16就是16个空间,从而控制精度

python 复制代码
import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np
from sklearn.model_selection import train_test_split

#转换数据为pytorch张量
x_train=torch.tensor(x_train_data.values,dtype=torch.float32)
y_train=torch.tensor(y_train_data.values)
x_test=torch.tensor(x_test_data.values,dtype=torch.float32)
y_test=torch.tensor(y_test_data.values)

linear全连接,init只是定义了神经网络,forward表示神经网络层搭建好

这里我们设置了三层神经网络,虽然只有三层但不代表只能进行三次变换,实际上可以通过激活函数引入多层复合,实现复杂的特征映射。每一层的输出都可以作为下一层的输入,不断抽象和组合特征,从而拟合高度非线性的决策边界。只要网络足够深或宽,配合合适的训练策略,就能逼近任意连续函数。

python 复制代码
#定义神经网络
class Net(nn.Module):
    def __init__(self):
        super(Net,self).__init__()
        self.fc1=nn.Linear(13,32)
        self.fc2=nn.Linear(32,64)
        self.fc3=nn.Linear(64,4)

    def forward(self,x):
        x=torch.relu(self.fc1(x))
        x=torch.relu(self.fc2(x))
        x=self.fc3(x)
        return x

loss损失函数,损失函数有五种,0-1损失函数用于二分类,回归用均方差损失函数,多分类用交叉熵损失函数。这里就是交叉熵损失函数。

(所有的权重一开始是有个初始值的,随机给值,但不是绝对的随机,是有控制的给值【正态分布】根据损失来改变w的过程就是梯度下降)

python 复制代码
#实例化网络,损失函数和优化器
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():
        predicictions=model(x_data)
        correct=(predicictions.argmax(1)==y_data).type(torch.float).sum().item()
        correct /= size
        loss=criterion(predicictions,y_data).item()
        print(f'{train_or_test}:\t Accuracy:{(100 * correct)}%')
    return  correct

Zero_gard梯度的初始化

outputs=model......model后面有个forward是省略的,覆盖父类的方法,所以这里能直接把x_train传进

python 复制代码
epochs1=10000
accs=[]
for epoch in range(epochs1):
    optimizer.zero_grad()
    outputs=model(x_train)

    loss=criterion(outputs,y_train)
    loss.backward()
    optimizer.step()
    if(epoch+1)% 100 ==0:
        print(f'Epoch [{epoch +1}/{epochs1},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_all['linear-net']=net_result

8.卷积神经网络

和全连接不同的地方就在于神经网络构建

conv2d和1d的区别,2d是用来识别图片,卷积核是二维的,最小单元是一张图

1d的最小单元是一行数据,卷积核是一维的,同样3d就是用来处理视屏的,卷积核是三维的。

out_channels和size代表的就是16个卷积核,卷积核是3

python 复制代码
import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np

#转换数据为pytorch张量
x_train=torch.tensor(x_train_data.values,dtype=torch.float32)
y_train=torch.tensor(y_train_data.values)
x_test=torch.tensor(x_test_data.values,dtype=torch.float32)
y_test=torch.tensor(y_test_data.values)

class CNN(nn.Module):
    def __init__(self,num_features,hidden_size,num_classes):
        super(CNN,self).__init__()
        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,num_classes)

    def forward(self,x):
        x=x.unsqueeze(1)
        x=self.conv1(x)
        x=self.relu(x)
        x=self.conv2(x)
        x=self.relu(x)
        x=self.conv3(x)
        x=self.relu(x)
        x=x.mean(dim=2)
        x=self.fc(x)
        return x

hidden_size=10
num_classes=4
model=CNN(13,hidden_size,num_classes)
criterion=nn.CrossEntropyLoss()
optimizer=optim.Adam(model.parameters(),lr=0.001)

epochs2=10000
accs=[]
for epoch in range(epochs2):
    outputs=model(x_train)
    loss=criterion(outputs,y_train)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    if(epoch+1)% 100 ==0:
        print(f'Epoch [{epoch +1}/{epochs2},Loss:{loss.item():.4f}')

        with torch.no_grad():
            predictions=model(x_train)
            predicted_classes=predictions.argmax(dim=1)
            accuracy=(predicted_classes == y_train).float().mean()
            print(f'train accuracy:{accuracy.item() * 100:.2f}%')

            predictions=model(x_test)
            predicted_classes=predictions.argmax(dim=1)
            accuracy=(predicted_classes == y_test).float().mean()
            print(f'test accuracy:{accuracy.item() * 100:.2f}%')
            accs.append(accuracy*100)

cnn_result={}
cnn_result['acc']=max(accs).item()
result_all['cnn']=cnn_result

三、保存结果

上面就是我们八种训练方法,最后我们需要对六个填充方法,八个训练方法的48个结果进行保存

python 复制代码
print(result_all)
import json
result={}
result['方法 fill']=result_all
with open(r'temp_data/result[方法].json','w',encoding='utf-8')as file:
    json.dump(result,file,ensure_ascii=False,indent=4)

接着开头对文件的读取,读取什么填充方法的数据,最后这里就写上对应的方法,我们能得到六个文件

一个文件是一种填充方法的八个训练方法的结果

eg:

最后对比,中位数填充,随机森林训练的准确率最高

相关推荐
AAD555888992 小时前
伊蚊种类识别与分类——基于VFNet的蚊虫识别模型训练与实现
人工智能·数据挖掘
沃达德软件2 小时前
模糊图像处理系统功能解析
图像处理·人工智能·深度学习·目标检测·计算机视觉·目标跟踪·超分辨率重建
姜太小白2 小时前
【前端】JavaScript字符串执行方法总结
开发语言·前端·javascript
被星1砸昏头2 小时前
C++与Node.js集成
开发语言·c++·算法
xixi09242 小时前
selenium的安装配置
开发语言·python
2501_942191772 小时前
微生物图像识别与分类:基于YOLO11-C3k2-SFHF的六类微生物自动检测方法详解
人工智能·分类·数据挖掘
暗之星瞳2 小时前
OPENCV进阶1
人工智能·opencv·计算机视觉
HAREWORK_FFF2 小时前
近三年高认可度AI证书|按需求选对不选难
人工智能
程序员zgh2 小时前
C++ 纯虚函数 — 抽象接口
c语言·开发语言·c++·经验分享·笔记·接口隔离原则