如何选择最佳机器学习算法?

讲完随机森林算法之后,小冰开口问道 :“咖哥,上面的这几种经典算法,你讲得简明扼要,感觉都挺好。不过,现在的问题来了,算法一多,我反而不知道如何选择了。你能不能给我们说说,什么样的算法适合解决什么样的问题?”

咖哥回答 :“这很值得说一说。没有任何一种机器学习算法,能够做到针对任何数据集都是最佳的。通常,拿到一个具体的数据集后,会根据一系列的考量因素进行评估。这些因素包括 :要解决的问题的性质、数据集大小、数据集特征、有无标签等。有了这些信息后,再来寻找适宜的算法。”

让我们从下页这张 Sklearn 的算法“官方小抄”图入手来简单说说机器学习算法的选择。顺着这张图过一遍各种机器学习算法,也是一个令我们将所学知识融会贯通的过程。

在开始选择 Sklearn 算法之前,先额外加一个 IF 语句 :

IF 机器学习问题 = 感知类问题 ( 也就是图像、语言、文本等非结构化问题 )THEN 深度学习算法 ( 例如使用 Keras 深度学习库 )

因为适合深度学习的问题通常不用 Sklearn 库来解决,而对于浅层的机器学习问题,Sklearn就可以大显身手了。Sklearn 库中的算法选择流程如下 :

IF 数据量小于 50 个
数据样本太少了 , 先获取更多数据
ELSE 数据量大于 50 个
 IF 是分类问题
 IF 数据有标签
 IF 数据量小于 10 万个
选择 SGD 分类器
 ELSE 数据量大于 10 万个
先尝试线性 SVM 分类器 , 如果不好用 , 再继续尝试其他算法
 IF 特征为文本数据
选择朴素贝叶斯
 ELSE
先尝试 KNN 分类器 , 如果不好用 , 再尝试 SVM 分类器加集成分类算法 ( 参见第 9 课内容 )
 ELSE 数据没有标签
选择各种聚类算法 ( 参见第 10 课内容 )
 ELSE 不是分类问题
 IF 需要预测数值 , 就是回归问题
 IF 数据量大于 10 万个
选择 SGD 回归
 ELSE 数据量小于 10 万个
根据数据集特征的特点 , 有套索回归和岭回归、集成回归算法、SVM 回归等几种选择
 ELSE 进行可视化 ,
则考虑几种降维算法 ( 参见第 10 课内容 )
 ELSE 预测结构
对不起 , Sklearn 帮不了你

选择机器学习算法的思路大致如此。此外,经验和直觉在机器学习领域的重要性当然是不言而喻。其实,不光机器学习,经验和直觉无论在什么领域也都是关键。当然,选取多种算法去解决同一个问题,然后将各种算法的效率进行比较,也不失为一个好的方案。

刚才,我们已经应用了好几个机器学习算法处理同一个数据集。再加上以前讲过的逻辑回归,现在就可以对各种算法的性能进行一个横向比较。下面是用逻辑回归算法解决心脏病的预测问题的示例代码。

扫描二维码关注公众号,回复: 12664752 查看本文章
from sklearn.linear_model import LogisticRegression # 导入逻辑回归模型
lr = LogisticRegression()
lr.fifit(X_train, y_train)
y_pred = lr.predict(X_test) # 预测心脏病结果
lr_acc = lr.score(X_test, y_test)*100
lr_f1 = f1_score(y_test, y_pred)*100
print(" 逻辑回归预测准确率 :{:.2f}%".format(lr_acc))
print(" 逻辑回归预测 F1 分数 : {:.2f}%".format(lr_f1))
print(' 逻辑回归混淆矩阵 :\n', confusion_matrix(y_test, y_pred))

下面就输出所有这些算法针对心脏病预测的准确率直方图 :

methods = ["Logistic Regression", "KNN", "SVM",
 "Naive Bayes", "Decision Tree", "Random Forest"]
accuracy = [lr_acc, KNN_acc, svm_acc, nb_acc, dtc_acc, rf_acc]
colors = ["orange", "red", "purple", "magenta", "green", "blue"]
sns.set_style("whitegrid")
plt.fifigure(fifigsize=(16, 5))
plt.yticks(np.arange(0, 100, 10))
plt.ylabel("Accuracy %")
plt.xlabel("Algorithms")
sns.barplot(x=methods, y=accuracy, palette=colors)
plt.grid(b=None)
plt.show()

各种算法的准确率比较如下图所示。

从结果上看,KNN 和随机森林等算法对于这个问题来说是较好的算法。

再绘制出各种算法的混淆矩阵 :

# 绘制出各种算法的混淆矩阵
from sklearn.metrics import confusion_matrix
y_pred_lr = lr.predict(X_test)
KNN3 = KNeighborsClassififier(n_neighbors = 3)
KNN3.fifit(X_train, y_train)
y_pred_KNN = KNN3.predict(X_test)
y_pred_svm = svm.predict(X_test)
y_pred_nb = nb.predict(X_test)
y_pred_dtc = dtc.predict(X_test)
y_pred_rf = rf.predict(X_test)
cm_lr = confusion_matrix(y_test, y_pred_lr)
cm_KNN = confusion_matrix(y_test, y_pred_KNN)
cm_svm = confusion_matrix(y_test, y_pred_svm)
cm_nb = confusion_matrix(y_test, y_pred_nb)
cm_dtc = confusion_matrix(y_test, y_pred_dtc)
cm_rf = confusion_matrix(y_test, y_pred_rf)
plt.figure(figsize=(24, 12))
plt.suptitle("Confusion Matrixes", fontsize=24) # 混淆矩阵
plt.subplots_adjust(wspace = 0.4, hspace= 0.4)
plt.subplot(2, 3, 1)
plt.title("Logistic Regression Confusion Matrix") # 逻辑回归混淆矩阵
sns.heatmap(cm_lr, annot=True, cmap="Blues", fmt="d", cbar=False)
plt.subplot(2, 3, 2)
plt.title("K Nearest Neighbors Confusion Matrix") #KNN 混淆矩阵
sns.heatmap(cm_KNN, annot=True, cmap="Blues", fmt="d", cbar=False)
plt.subplot(2, 3, 3)
plt.title("Support Vector Machine Confusion Matrix") #SVM 混淆矩阵
sns.heatmap(cm_svm, annot=True, cmap="Blues", fmt="d", cbar=False)
plt.subplot(2, 3, 4)
plt.title("Naive Bayes Confusion Matrix") # 朴素贝叶斯混淆矩阵
sns.heatmap(cm_nb, annot=True, cmap="Blues", fmt="d", cbar=False)
plt.subplot(2, 3, 5)
plt.title("Decision Tree Classifier Confusion Matrix") # 决策树混淆矩阵
sns.heatmap(cm_dtc, annot=True, cmap="Blues", fmt="d", cbar=False)
plt.subplot(2, 3, 6)
plt.title("Random Forest Confusion Matrix") # 随机森林混淆矩阵
sns.heatmap(cm_rf, annot=True, cmap="Blues", fmt="d", cbar=False)
plt.show()

各种算法的混淆矩阵如下图所示。

从图中可以看出,KNN 和随机森林这两种算法中“假负”的数目为 3,也就是说本来没有心脏病,却判定为有心脏病的客户有 3 人 ;而“假正”的数目为 4,也就是说本来有心脏病,判定为没有心脏病的客户有 4 人。

本文摘自《零基础学机器学习》


机器学习,就是在已知数据集的基础上,通过反复的计算,选择最贴切的函数(function)去描述数据集中自变量x1, x 2, x 3, …, xn 和因变量y 之间的关系。如果机器通过所谓的训练(training)找到了一个函数,对于已有的 1000 组钻石数据,它都能够根据钻石的各种特征,大致推断出其价格。那么,再给另一批同类钻石的大小、重量、颜色、密度等数据,就很有希望用同样的函数(模型)推断出这另一批钻石的价格。此时,已有的 1000 组有价格的钻石数据,就叫作训练数据集(trainingdataset)。另一批钻石数据,就叫作测试数据集(test dataset)。

因此,正如下图所示,通过机器学习模型不仅可以推测孩子身高和钻石价格,还可以实现影片票房预测、人脸识别、根据当前场景控制游戏角色的动作等诸多功能。

机器学习就是从数据中发现关系,归纳成函数,以实现从 A 到 B 的推断

其实所谓机器学习,的确是一个统计建模的过程。但是当特征数目和数据量大到百万、千万,甚至上亿时,原本属于数学家的工作当然只能通过机器来完成喽。而且,机器学习没有抽样的习惯,对于机器来说,数据是多多益善,有多少就用多少。

下面的图展示了机器从数据中训练模型的过程,而人类的学习,是从经验中归纳规律,两者何其相似!越是与人类学习方式相似的 AI,才是越高级的 AI !这种从已知到未知的学习能力是机器学习和以前的符号式 AI 最本质的区别。

机器 :从数据中学习 ;人类 :从经验中学习。两者何其相似

机器学习的另外一个特质是从错误中学习,这一点也与人类的学习方式非常相似。你们看一个婴儿,他总想吞掉他能够拿到的任何东西,包括硬币和纽扣,但是真的吃到嘴里,会发生不好的结果。慢慢地,他就从这些错误经验中学习到什么能吃,什么不能吃。这是通过试错来积累经验。机器学习的训练、建模的过程和人类的这个试错式学习过程有些相似。机器找到一个函数去拟合(fit)它要解决的问题,如果错误比较严重,它就放弃,再找到一个函数,

如果错误还是比较严重,就再找,一直到找到相对最为合适的函数为止,此时犯错误的概率最小。这个寻找的过程,绝大多数情况不是在人类的“指导”下进行的,而是机器通过机器学习算法自己摸索出来的。

因此,机器学习是突破传统的学习范式,它与专家系统(属于符号式 AI)中的规则定义不同。如下图所示,它不是由人类把已知的规则定义好之后输入给机器的,而是机器从已知数据中不断试错之后,归纳出来规则。

机器学习是突破传统的学习范式,是从数据中发现规则,而不是接受人类为它设定的规则

如果你想学习机器学习,以上内容您很感兴趣。那么推荐您阅读《零基础学机器学习

本书的目标,是让非机器学习领域甚至非计算机专业出身但有学习需求的人,轻松地掌握机器学习的基本知识,从而拥有相关的实战能力。

本书通过AI“小白”小冰拜师程序员咖哥学习机器学习的对话展开,内容轻松,实战性强,主要包括机器学习快速上手路径、数学和Python 基础知识、机器学习基础算法(线性回归和逻辑回归)、深度神经网络、卷积神经网络、循环神经网络、经典算法、集成学习、无监督和半监督等非监督学习类型、强化学习实战等内容,以及相关实战案例。本书所有案例均通过Python及Scikit-learn 机器学习库和Keras 深度学习框架实现,同时还包含丰富的数据分析和数据可视化内容。

本书适合对AI 感兴趣的程序员、项目经理、在校大学生以及任何想以零基础学机器学习的人,用以入门机器学习领域,建立从理论到实战的知识通道。

猜你喜欢

转载自blog.csdn.net/epubit17/article/details/112969806