说明:这是一个机器学习实战项目(附带数据+代码),如需数据+完整代码可以直接到文章最后获取。
1.需求分析
在国家一系列政策密集出台的环境下,在国内市场强劲需求的推动下,我国家用燃气灶具产业整体保持平稳较快增长。随着产业投入加大、技术突破与规模积累,在可以预见的未来,开始迎来发展的加速期。某电器公司的燃气灶产品销售额一直在国内处于领先地位,把产品质量视为重中之重,每年都要对其产品质量数据进行分析研究,以期不断完善,精益求精。本模型也是基于一些历史数据进行维修方式的建模、预测。
2.数据采集
本数据是模拟数据,分为两部分数据:
数据集:data.xlsx
在实际应用中,根据自己的数据进行替换即可。
特征数据:故障模式、故障模式细分、故障名称、单据类型
标签数据:维修方式
3.数据预处理
1)原始数据描述:
2)原始数据文本转换为数值:
2)数据完整性、数据类型查看:
print(data_.dtypes) # 打印数据类型
3)数据缺失值个数:
print(data_.isnull().any()) # 查看是否有NULL值
可以看到数据不存在缺失值。
4)哑特征处理
特征变量故障模式、故障模式细分、故障名称中的数值为文本类型,不符合机器学习数据要求,需要进行哑特征处理,变为0 1数值。
关键代码如下:
处理后,数据如下:
4.探索性数据分析
1)特征变量故障分析:
故障分析:在维修记录中不同部件维修数量不同,其中“电极针坏”的数量占比最多,占全部维修记录的64.12%。“热电偶坏”和“电磁阀坏”的占比次之,分别为14.87%和11.29%。
explodes = [0.1 if i == "sales" else 0 for i in lbs] matplotlib.rcParams['font.sans-serif'] = ['SimHei'] plt.figure(figsize=(5, 5)) # 创建子图,大小为5*5 patches, l_text, p_text = plt.pie(data["故障模式"].value_counts(normalize=True), explode=explodes, labels=lbs, autopct='%.2f%%', radius=0.8) for t in p_text: t.set_size(12) for t in l_text: t.set_size(12) plt.show()
2)特征变量故障模式分析:
故障模式又分别细分为5项:“开裂”、“变形”、“老化”、“调整电极针位置”、“热电偶与电磁阀接触不良”。
def pie_pic(data, color=None, radius=None): lbs = data.value_counts().index if color: matplotlib.rcParams['font.sans-serif'] = ['SimHei'] plt.pie(data.value_counts(normalize=True), labels=lbs, colors=sns.color_palette(color, 4), autopct='%.2f%%', radius=radius, startangle=120)
3)相关性分析
df_tmp1 = df_data[ ['故障模式_1', '故障模式_2', '故障模式_3', '故障模式_4', '故障模式_5', '故障模式细分_1', '故障模式细分_2', '故障模式细分_3', '故障模式细分_4', '故障模式细分_5', '故障名称_1', '故障名称_2', '维修方式']] plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = False sns.heatmap(df_tmp1.corr(), cmap="YlGnBu", annot=True) plt.show()
说明:正值是正相关、负值时负相关,值越大变量之间的相关性越强。
5.特征工程
1)特征数据和标签数据拆分,y为标签数据,除y之外的为特征数据;
2)数据集拆分,分为训练集和尝试集,80%训练集和20%验证集;
3)数据归一化
6.机器建模
1)遗传算法简单介绍:
遗传算法,也叫Genetic Algorithm,简称 GA 算法他既然叫遗传算法,那么遗传之中必然有基因,那么基因染色体(Chromosome)就是它的需要调节的参数。我们在生物中了解到,大自然的法则是“物竞天择,适者生存”,我觉得遗传算法更适用于“优胜劣汰”。
- 优:最优解,
- 劣:非最优解。
遗传算法的实现流程:
涉及到还是适应度函数、选择、交叉、变异这几个模块。下面就这几个模块展开说明。具体的流程图解释如下:
(1)需要先对初始种群进行一次适应度函数进行计算,这样方便我们对个体进行选择,适应度值越大的越容易被保留;
(2)对群体进行选择,选择出适应度值较大的一部分优势群体;
(3)对优势种群进行 “交配”,更容易产生优秀的个体;
(4)模拟大自然变异操作,对染色体个体进行变异操作;
2)本次机器学习工作流程:
(1)种群数量NIND = 50代表第一代种群先进行50次的模型训练作为50个初始个体,每次训练的[C,G](当然每次训练的C和G还是随机初始化的)就是这个个体的的染色体;
(2)目标函数就是训练集上的分类准确度(当然下面代码用的交叉验证分数,含义其实是一样的);
(3)选择、交叉、变异、进化
(4)最后末代种群中的最优个体得到我们想要的C和Gamma,把这两个参数代入到测试集上计算测试集结果
3)应用遗传算法GA得到最优的调参结果
编号
名称
1
评价次数:750
2
时间已过 2950.9299054145813 秒
3
最优的目标函数值为:0.9611955168119551
4
最优的控制变量值为:
5
C的值:149.7418557703495
6
G的值:0.00390625
最优的空值变量C、G的值,大家在实际数据集过程种可以慢慢尝试。
4)建立支持向量机分类模型,模型参数如下:
编号
参数
1
C=C
2
kernel='rbf'
3
gamma=G
其它参数根据具体数据,具体设置。
7.模型评估
1)评估指标主要采用准确率分值、查准率、查全率、F1
编号
评估指标名称
评估指标值
1
准确率分值
0.96
2
查准率
95.02%
3
查全率
99.73%
4
F1
97.32%
通过上述表格可以看出,此模型效果良好。
class MyProblem(ea.Problem): # 继承Problem父类 def __init__(self, PoolType): # PoolType是取值为'Process'或'Thread'的字符串 name = 'MyProblem' # 初始化name(函数名称,可以随意设置) M = 1 # 初始化M(目标维数) maxormins = [-1] # 初始化maxormins(目标最小最大化标记列表,1:最小化该目标;-1:最大化该目标) Dim = 2 # 初始化Dim(决策变量维数) varTypes = [0, 0] # 初始化varTypes(决策变量的类型,元素为0表示对应的变量是连续的;1表示是离散的) lb = [2 ** (-8)] * Dim # 决策变量下界 ub = [2 ** 8] * Dim # 决策变量上界 lbin = [1] * Dim # 决策变量下边界(0表示不包含该变量的下边界,1表示包含) ubin = [1] * Dim # 决策变量上边界(0表示不包含该变量的上边界,1表示包含) # 调用父类构造方法完成实例化 ea.Problem.__init__(self, name, M, maxormins, Dim, varTypes, lb, ub, lbin, ubin) # 目标函数计算中用到的一些数据 ori_data = pd.read_excel("data.xlsx", header=1) print(ori_data.head()) # 读取预处理后的数据 self.data = preprocessing.scale(np.array(X_train)) # 训练集的特征数据(归一化) self.dataTarget = np.array(Y_train) # 设置用多线程还是多进程 self.PoolType = PoolType if self.PoolType == 'Thread': self.pool = ThreadPool(2) # 设置池的大小 elif self.PoolType == 'Process': num_cores = int(mp.cpu_count()) # 获得计算机的核心数 self.pool = ProcessPool(num_cores) # 设置池的大小 def aimFunc(self, pop): # 目标函数,采用多线程加速计算 Vars = pop.Phen # 得到决策变量矩阵 args = list( zip(list(range(pop.sizes)), [Vars] * pop.sizes, [self.data] * pop.sizes, [self.dataTarget] * pop.sizes)) if self.PoolType == 'Thread': pop.ObjV = np.array(list(self.pool.map(subAimFunc, args))) elif self.PoolType == 'Process': result = self.pool.map_async(subAimFunc, args) result.wait() pop.ObjV = np.array(result.get()) def test(self, C, G): # 代入优化后的C、Gamma对测试集进行检验 data_test = pd.read_excel("data_test.xlsx") X_test = data_test.drop(columns=['维修方式']) Y_test = data_test['维修方式'] data_test = preprocessing.scale(np.array(X_test)) # 测试集的特征数据(归一化) dataTarget_test = np.array(Y_test) # 测试集的标签数据 svc = svm.SVC(C=C, kernel='rbf', gamma=G).fit(self.data, self.dataTarget) # 创建分类器对象并用训练集的数据拟合分类器模型 dataTarget_predict = svc.predict(X_test) # 采用训练好的分类器对象对测试集数据进行预测 print("测试集数据分类正确率 = %s%%" % ( len(np.where(dataTarget_predict == dataTarget_test)[0]) / len(dataTarget_test) * 100)) print("验证集查准率: {:.2f}%".format(precision_score(Y_test, dataTarget_predict) * 100)) # 打印验证集查准率 print("验证集查全率: {:.2f}%".format(recall_score(Y_test, dataTarget_predict) * 100)) # 打印验证集查全率 print("验证集F1值: {:.2f}%".format(f1_score(Y_test, dataTarget_predict) * 100)) # 打印验证集F1值 def subAimFunc(args): i = args[0] Vars = args[1] data = args[2] dataTarget = args[3] C = Vars[i, 0] G = Vars[i, 1] svc = svm.SVC(C=C, kernel='rbf', gamma=G).fit(data, dataTarget) # 创建分类器对象并用训练集的数据拟合分类器模型 scores = cross_val_score(svc, data, dataTarget, cv=30) # 计算交叉验证的得分 ObjV_i = [scores.mean()] # 把交叉验证的平均得分作为目标函数值 return ObjV_i import geatpy as ea # import geatpy if __name__ == '__main__': """===============================实例化问题对象===========================""" PoolType = 'Thread' # 设置采用多线程,若修改为: PoolType = 'Process',则表示用多进程 problem = MyProblem(PoolType) # 生成问题对象 """=================================种群设置==============================""" Encoding = 'RI' # 编码方式 NIND = 50 # 种群规模 Field = ea.crtfld(Encoding, problem.varTypes, problem.ranges, problem.borders) # 创建区域描述器 population = ea.Population(Encoding, Field, NIND) # 实例化种群对象(此时种群还没被初始化,仅仅是完成种群对象的实例化) """===============================算法参数设置=============================""" myAlgorithm = ea.soea_SGA_templet(problem, population) myAlgorithm.MAXGEN = 30 # 最大代数 myAlgorithm.trappedValue = 1e-6 # “进化停滞”判断阈值 myAlgorithm.maxTrappedCount = 10 # 进化停滞计数器最大上限值,如果连续maxTrappedCount代被判定进化陷入停滞,则终止进化 myAlgorithm.logTras = 1 # 设置每隔多少代记录日志,若设置成0则表示不记录日志 myAlgorithm.verbose = True # 设置是否打印输出日志信息 myAlgorithm.drawing = 1 # 设置绘图方式(0:不绘图;1:绘制结果图;2:绘制目标空间过程动画;3:绘制决策空间过程动画) """==========================调用算法模板进行种群进化========================""" [BestIndi, population] = myAlgorithm.run() # 执行算法模板,得到最优个体以及最后一代种群 BestIndi.save() # 把最优个体的信息保存到文件中 """=================================输出结果==============================""" print('评价次数:%s' % myAlgorithm.evalsNum) print('时间已过 %s 秒' % myAlgorithm.passTime) if BestIndi.sizes != 0: print('最优的目标函数值为:%s' % (BestIndi.ObjV[0][0])) print('最优的控制变量值为:') for i in range(BestIndi.Phen.shape[1]): print(BestIndi.Phen[0, i]) """=================================检验结果===============================""" problem.test(C=BestIndi.Phen[0, 0], G=BestIndi.Phen[0, 1]) else: print('没找到可行解。')
8.实际应用
根据测试集的特征数据,来预测这些产品的维修方式。可以根据预测的维修方式类型,进行产品的优化和人员工作的安排。具体预测结果此处不粘贴图片了。
本次机器学习项目实战所需的资料,项目资源如下:https://download.csdn.net/download/weixin_42163563/21110938