Python进行分类预测并进行参数优化

在进行机器学习分类时,总是很难找到准确率最高的那一次,这时候需要我们手动进行调参,然而这样往往就会耗费我们很大的时间(炼丹),而利用sklearn中的GridSearchCV的方法进行参数优化会方便很多,能够快速找到最优参数(即准确率最高的那次)。

GridSearchCV的方法如同字面意思,是进行网格搜索,需要遍历所有可能的参数组合,因此在大数据集下也很耗时,但我认为在小数据集上比手动调参来的快得多。

下面将展现一个具体的例子,来完成机器学习分类并进行参数优化,这里的任务是利用一些特征来对机器是否故障进行分类,故障为1,不故障为0,数据来自于一次数据比赛。

这一部分都是数据的处理:由于原始数据的机器质量等级中存在HML这三个字母,因此将其转化为数字编码,这里利用独热编码。

import time
T1 = time.process_time()

import pandas as pd
data = pd.read_excel("train data.xlsx")
# 检查数据是否有缺失
null = data.isnull().sum()
# 观察数据的特征/指标
features = data.columns
# 去除无用指标
features = features.drop(['机器编号', '统一规范代码', '具体故障类别'])
newdata = data.drop(['机器编号', '统一规范代码', '具体故障类别'], axis=1)
data1 = newdata

# # 编码, 一对一编码
# mapping = {
#            'H': 1,
#            'M': 2,
#            'L': 3}
# data1['机器质量等级'] = data1['机器质量等级'].map(mapping)


# 独热编码
newdata = pd.get_dummies(newdata, columns=['机器质量等级'])
new_features = newdata.columns

 下面进行最大最小值归一化:

# 归一化
from sklearn import preprocessing
from pandas import DataFrame
min_max_scaler = preprocessing.MinMaxScaler()
newdata = min_max_scaler.fit_transform(newdata)
newdata = DataFrame(newdata, index=None, columns=new_features)

观察一下处理好后的数据:

 

 我们的目的就是对第六列数据,即"是否发生故障"这一列进行预测分类。

首先将数据划分为训练集与测试集:

# 数据划分
x = newdata.drop('是否发生故障', axis=1)# 特征
y = newdata['是否发生故障']# 目标变量
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.3, random_state=63)

 这里将特征(x)和类别(y)划分出来,利用train_test_split按照7:3划分训练集和测试集,random_state这个是随机状态,因为划分是一种伪随机,这里是为了保证每次分割结果是一样的,便于不同分类方法之间比较。

下面就可以进行分类了:

这里利用决策树进行分类,只设置一个树的深度为3,随机状态与上面保持一致,利用fit, predict进行训练预测并进行精度验证。

# 决策树
from sklearn.tree import DecisionTreeClassifier # 导入决策树
# 基尼系数,深度为3
tree = DecisionTreeClassifier(criterion='gini', max_depth=3, random_state=63)
# 训练
tree.fit(X_train, y_train)
# 预测
y_pre_tree = tree.predict(X_test)
# 评估
from sklearn.metrics import classification_report
print('\n', '决策树预测结果:', '\n',classification_report(y_test, y_pre_tree), '\n')

我们观察一下结果,可以发现虽然总体精确率达到了94%,但是样本不平衡,故障的机器太少了且预测准确率仅为0.9,效果很差,就算是不故障的机器准确率也只是在97%。

 因此接下来我们来通过GridSearchCV来进行参数优化,看一下效果如何:

# 决策树参数优化
import numpy as np
from sklearn.model_selection import GridSearchCV
# 设置参数范围
parameters = {
    'max_depth': np.arange(1, 10), # 树最大深度
    'min_samples_leaf': np.arange(1, 10), # 最小节点
    'min_samples_split': np.arange(1, 10)} # 最小分离点数
youhua_tree = DecisionTreeClassifier(random_state=63) # 设置随机状态
para_tree = GridSearchCV(youhua_tree,parameters, cv=10)
para_tree.fit(X_train, y_train) # 独热编码数据
print('决策树的最优参数:',para_tree.best_params_)

我们在1~10的范围内对决策树的三个参数进行优化,并设置10折交叉验证(cv=10),结果如下:

 可以看到,最大深度为9,最小节点为8,最小分离点数为2,我们利用调整后的参数再进行一次预测,观测一下优化后的结果:

# 使用优化后决策树参数进行预测
from sklearn.tree import DecisionTreeClassifier # 导入决策树
# 基尼系数,优化参数
newtree = DecisionTreeClassifier(criterion='gini', max_depth=9, min_samples_leaf=8, min_samples_split=2,random_state=63)
# 训练
newtree.fit(X_train, y_train)
# 预测
y_pre_newtree = newtree.predict(X_test)
# 评估
print('\n', '参数调整后的决策树预测结果:', '\n',classification_report(y_test, y_pre_newtree), '\n')

 可以看到,总体准确率已经达到98%,精度得到了大幅度提升,并且机器故障率的预测准确度也达到了96%,相比于之前的参数设置提升了6个百分点。

最后,我们来看一下运行时间:

未利用GridSearchCV进行参数优化的时间:

利用GridSearchCV进行参数优化的时间:

 由于我的电脑性能不太好,因此花费时间要长一些,但是同样是可以看出来,利用GridSearchCV进行参数优化的方法耗时还是很长的,仅仅是对3个参数优化,并且样本仅有2700个,就花费了半分钟左右。

不过,总体来说,该方法在小样本数据集上表现还是很好的,能省去很多人工调试的时间,调好的参数也使得精度有很大提升,大家在使用时结合样本与自己的实际情况选择使用。

下面是全部代码,需要数据的话可以私我。

import time
T1 = time.process_time()

import pandas as pd
data = pd.read_excel("train data.xlsx")
# 检查数据是否有缺失
null = data.isnull().sum()
# 观察数据的特征/指标
features = data.columns
# 去除无用指标
features = features.drop(['机器编号', '统一规范代码', '具体故障类别'])
newdata = data.drop(['机器编号', '统一规范代码', '具体故障类别'], axis=1)
data1 = newdata
# # 编码, 一对一编码
# mapping = {
#            'H': 1,
#            'M': 2,
#            'L': 3}
# data1['机器质量等级'] = data1['机器质量等级'].map(mapping)


# 独热编码
newdata = pd.get_dummies(newdata, columns=['机器质量等级'])
new_features = newdata.columns

# 归一化
from sklearn import preprocessing
from pandas import DataFrame
min_max_scaler = preprocessing.MinMaxScaler()
newdata = min_max_scaler.fit_transform(newdata)
newdata = DataFrame(newdata, index=None, columns=new_features)


# 数据划分
x = newdata.drop('是否发生故障', axis=1)# 特征
y = newdata['是否发生故障']# 目标变量
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.3, random_state=63)


# 决策树
from sklearn.tree import DecisionTreeClassifier # 导入决策树
# 基尼系数,深度为3
tree = DecisionTreeClassifier(criterion='gini', max_depth=3, random_state=63)
# 训练
tree.fit(X_train, y_train)
# 预测
y_pre_tree = tree.predict(X_test)
# 评估
from sklearn.metrics import classification_report
print('\n', '决策树预测结果:', '\n',classification_report(y_test, y_pre_tree), '\n')

# 决策树参数优化
import numpy as np
from sklearn.model_selection import GridSearchCV
# 设置参数范围
parameters = {
    'max_depth': np.arange(1, 10), # 树最大深度
    'min_samples_leaf': np.arange(1, 10), # 最小节点
    'min_samples_split': np.arange(1, 10)} # 最小分离点数
youhua_tree = DecisionTreeClassifier(random_state=63) # 设置随机状态
para_tree = GridSearchCV(youhua_tree,parameters, cv=10)
para_tree.fit(X_train, y_train) # 独热编码数据
print('决策树的最优参数:',para_tree.best_params_)

# 使用优化后决策树参数进行预测
from sklearn.tree import DecisionTreeClassifier # 导入决策树
# 基尼系数,优化参数
newtree = DecisionTreeClassifier(criterion='gini', max_depth=9, min_samples_leaf=8, min_samples_split=2,random_state=63)
# 训练
newtree.fit(X_train, y_train)
# 预测
y_pre_newtree = newtree.predict(X_test)
# 评估
print('\n', '参数调整后的决策树预测结果:', '\n',classification_report(y_test, y_pre_newtree), '\n')


T2 =time.process_time()
print('程序运行时间:%s秒' % ((T2 - T1)))

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值