摘要让我从一个非常基本的问题开始。什么是机器学习?机器学习是指教授计算机系统某些算法的过程,这些算法可以通过经验自我改进。 关于机器学习的定义,Tom Michael Mitchell的这段话被广泛引用: “对于某类任务T和性能度量P,如果一个计算机程序在T上其性能P随着经验E而自我完善,那么我们称这个计算机程序从经验E中学习。” 就像人类一样,系统将能够执行简单的分类任务和复杂的数学计算,如回归。它涉及建立用于分类或回归的数学模型。 要“训练”这些数学模型,您需要一组训练数据。这是系统在其上构建模型的数据集。本文将涵盖机器学习分类的所有需求,从最基本的开始。 文章目录在这里,我们将讨论:
摘要这些数学模型根据其训练数据分为两类——监督模型和非监督式学习模型。 监督式学习在建立监督式学习模型时,所使用的训练数据包含所需的答案。这些必需的答案被称为标签。例如,您显示一张狗的图片,并将其标记为狗。 因此,如果有足够多的狗的图片,该算法将能够正确地对狗的图像进行分类。监督式学习模型也可以用来预测连续的数值,例如某公司的股票价格。这些模型被称为回归模型。 在这种情况下,标签就是过去股票的价格。所以算法会跟随这个趋势。很少有流行的算法包括
非监督式学习顾名思义,在非监督式学习中,用于培训的数据集并不包含所需的答案。相反,该算法使用聚类和降维等技术进行训练。 非监督式学习的一个主要应用是异常检测。这种方法使用聚类算法来发现图中的主要离群点。它们用于信用卡欺诈检测。 受监管模型的种类监督模型在标记数据集上进行训练,既可以是连续标记,也可以是分类标记。 回归模型回归是用来处理连续的价值,如房子的成本,当你被给予的功能,如位置,覆盖面积,历史价格等。流行的回归模型有:
分类模型分类用于将数据分成类别,每个类别由一个标签表示。训练数据必须包含标签,并且必须对每个标签有足够的观察,以便模型的准确性是可敬的。一些流行的分类模型包括:
评价这些模型的准确性的方法也是多种多样的。我们将更详细地讨论这些模型、评估方法和改进这些模型的技术,称为超参数调优。 分类类别根据数据集中存在的类的数量和级别,有三种类型的分类。 二进制分类这种类型的分类只有两类。通常,它们是布尔值-1或0,真或假,高或低。这种分类可用于癌症检测或电子邮件垃圾邮件检测的一些例子,其中的标签对于癌症和垃圾邮件可能为阳性或阴性,对于垃圾邮件检测可能不为阳性。 让我们举个例子,我们正在使用一个乳腺癌检测数据集,可以从这里下载。 import pandas as pdimport numpy as npimport matplotlib.pyplot as pltimport seaborn as snsdata= pd.read_csv('data.csv')data.head()
散点图-纹理平均值与半径平均值 这里你可以看到两个“类”——“ M”代表恶性,“ B”代表良性。正如您所看到的,类被很好地划分,并且对于这两个特性很容易用肉眼进行区分。然而,这并不适用于所有的特性对。 可用于这种分类的模型有:
你也可以使用决策树、随机森林和其他算法,但是逻辑回归和支持向量分类专门用于二进制分类。 多层次分类多类分类器或多项式分类器可以区分两个以上的类。众所周知的多元分类数据集是企鹅数据集。可以从海运库加载企鹅数据集。 import seaborn as snspenguins = sns.load_dataset('penguins')penguins.head()
我们可以生成一个 bill _ length _ mm 与 flpper _ length _ mm 参数的散点图,以查看这三类参数的明显变化。
图3散点图-鳍状体长度与比尔长度 诸如随机森林和朴素贝叶斯之类的算法可以轻松构建多类分类器模型。其他算法(例如支持向量分类器和逻辑回归)仅用于二进制分类。 多标签分类当一个观察包含多个标签时,就会出现这种类型的分类。例如,一个图像可能包含一辆汽车、一辆卡车和一个人。该算法必须能够分别对它们进行分类。因此,它必须为许多标签训练,并应报告真为一辆汽车,卡车和人类和假为任何其他标签,它已经训练。 分类器模型在我们深入研究任何分类模型之前,我们需要准备数据来训练算法。第一步是预处理和清理数据。有关数据清理的详细理解,请参阅一文教你如何正确地清理数据。 对于这个数据集,我们需要清理的是将花的字符串名称改为整数值,这样算法就可以正确地对它们进行分类。我们还需要删除具有 NaN 值的观测值。 d = {'Adelie':1, 'Chinstrap':2, 'Gentoo':3}penguins['species'] = penguins['species'].map(d, na_action='ignore')penguins = penguins.dropna(axis=0)penguins.head()
清洁数据后,您需要将功能变量与标签变量分开。特征变量是包含用于构建模型的可测量数据的列。
之后,您需要将数据分割成训练和测试数据集。顾名思义,训练数据集是用来训练算法,而我们检查模型的准确性的测试数据集。我们可以使用 skearn.model _ select 进行这种分割。Train _ test _ split ()函数。通常,我们对数据集进行75-25分割。75% 的主要数据是训练数据,其余的是测试数据。 from sklearn.model_selection import train_test_splitX_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0) 我们将随机状态参数传递给函数,因为它将导致可重复的训练集测试集拆分。 K-最近邻(KNN)K 最近邻是一种基于实例或基于内存的算法。这意味着算法在训练期间记忆数据集,并在以后使用它来预测类。这使得预测更快,但训练模型需要时间。K-NN 中的“ k”代表最近邻的数量,它将研究这些数量来做出预测。 为了简单起见,我们首先看一个示例,其中 k = 1。这意味着在进行预测时,算法将在训练数据中寻找离测试点最近的点,并分配该训练点的类。 图4散点图-鳍状体长度与比尔长度 在这里,我已经绘制了我们的训练数据的所有点,并建立了模型来接收分配给每个班级的区域。我将' k’的值用作1。为了分配这些区域,该算法搜索与图上每个点最接近的训练点,并分配训练点的类别。分隔这些区域的边界称为决策边界。 对于 k 的较高值,比如 k = 2,它搜索两个最接近的点,然后选出结果的多数票。如果最接近的两个点属于类1和2,它们将随机分配给任何类。这就是打破联系的方式。 但是,如果 k 的值为3,并且最近的3个点属于类1、2和1,它将选择多数类并将类1分配给测试点。更高的 k 值将导致更平滑的决策边界。 现在让我们看看如何训练数据集。从 sklearn 中导入 K 邻居分类器,创建分类器并训练模型。
我们使用了传递给 K-最近邻分类器的参数来改进模型,稍后我们将详细讨论这些参数。 现在是测试该模型的时候了。 knn.score(X_test, y_test)
97% 的准确率正是我们想要的。我们可以通过改变模型参数来提高精度。我们将在稍后的超参数优化中讨论这个问题。 N- 邻居参数是 k 的值-算法所考虑的最近邻居的个数。较高的值可能会提高精度。 权重参数是指将不同的权重分配给 k 个最近的邻居。我们已经选择了统一的参数。另一个可以分配的是“距离”。它使得离测试点更近的邻居获得更高的权重。 度量参数用于选择距离的类型。我们已经选好了欧几里得度量。其他值可能是“ Manhattan”或“ minkowski”。 支持向量分类器SVC 使用支持向量机(SVM)算法进行二进制分类。支持向量机最简单的形式是线性支持向量机,它使用线性决策边界进行分类。 线性支持向量机利用符号函数对数据点进行分类。如果函数内部的值是正的,它就给它赋值 + 1。如果值为负,则分配的值为 -1。 f(x,w,b)=sign(wx+b) 这里 x 是一组特征变量,w 是赋予这些变量的权重,b 是加入的偏差项或常数项。 决策边界的选择使得到两个类的最近点的垂直距离相等且最大。 决策边界的方程式是 y=wx+b 图5线性决策边界 上面的图显示了两个特征的乳腺癌数据集的决策边界和分类:“ RADIUS_MEAN”和“ TEXTURE_MEAN”。 让我们看看如何使用Scikit学习来实施此功能。 # Read the data and perform the necessary cleaningcancer_data=pd.read_csv('data.csv')d={'M':1,'B':2}cancer_data['diagnosis']=cancer_data.diagnosis.map(d)# Separate the feature and label variablesXc=cancer_data[['radius_mean','texture_mean']]yc=cancer_data[['diagnosis']]Xc_train,Xc_test,yc_train,yc_test=train_test_split(Xc,yc,random_state=0)# Import the SVM library and fit the modelfrom sklearn.svm import SVClsvm=SVC(C=1,kernel='linear')lsvm.fit(Xc_train,yc_train)
参数C称为正则化参数。C的值决定了该模型对训练数据的符合程度。C较高的C值意味着更少的正则化,并以尽可能准确的方式适合训练数据。这有时可能导致过度拟合,这是不足的。 C较小的C值意味着更正规化,并为模型提供了一些摆动空间,以找到更好的决策边界,并可能导致较低的训练精度,但测试精度较高。 下面的图显示了改变C值的效果。 图6. C = 0.0005的决策边界 图7. C = 100的决策边界 您可以看到决策边界如何改变C的不同值。 内核参数决定模型使用的函数。您还可以使用“ RBF”等非线性内核来创建非线性决策边界。本质上,内核更改数据的维度。内核具有当前的功能空间,并将其转换为不同的特征空间。 “ RBF”或径向基函数内核使用此表达式来转换特征空间: f(x1,x2)=exp(−||x1−x2||2) 这里 f (x1,x2)是新的特征空间,x1和 x2是特征变量。Γ 是一个调节内核的超参数。 ksvm = SVC(C=1, kernel='rbf', gamma=0.01)ksvm.fit(Xc_train, yc_train)
图8非线性决策边界 让我们在测试数据上测试这个模型。 ksvm.score(Xc_test, yc_test)
|
Actually Positive | Actually Negative | |
Predicted Positive | True Positives (TPs) | False Positives (FPs) |
Predicted Negative | False Negatives (FNs) | True Negatives (TNs) |
这是混乱矩阵。真实值在矩阵的对角线上。它用于计算精度和召回分数。
精确告诉我们我们算法的积极预测的准确性。
召回率是我们的模型正确检测到的阳性的比率。它也被称为真正的阳性率(TPR)。
from sklearn.metrics import confusion_matrixfrom sklearn.model_selection import cross_val_predicty_train_pred = cross_val_predict(gbclf, Xc_train, yc_train, cv=5)confusion_matrix(yc_train, y_train_pred)
array([[119, 40], [ 15, 252]])
这是使用梯度增强分类器的癌症数据集上的混淆矩阵。
在这里,我们可以看到真正正面和真正负面的数量,并计算出准确率召回率。
让我们看看准确率召回率是如何影响模型性能的。
from sklearn.metrics import precision_score, recall_scoreprint('Precision: ', precision_score(yc_train, y_train_pred))print('Recall: ', recall_score(yc_train, y_train_pred))
Precision: 0.8880597014925373Recall: 0.7484276729559748
我们也可以把我们的准确率召回率成绩合并到一个实体中,这个实体被称为 f1成绩。这是准确率召回率分数的调和平均值。
from sklearn.metrics import f1_scoref1_score(yc_train, y_train_pred)
0.8122866894197952
高精度和召回分数将导致更高的F1分数。但是,我们不能同时获得高精度和高回忆。
但是,在某些情况下,您更喜欢更高的精度或更高的召回率。在我们的癌症数据集中,我们希望误报比假否定性更多。因此,我们需要更高的召回。我们需要相应地构建算法。
我们还可以绘制Precision-Recall曲线。
from sklearn.metrics import precision_recall_curveprecision, recall, threshold = precision_recall_curve(yc_train, y_train_pred, pos_label=1)plt.plot(threshold, precision[:-1], 'b--', label='Precision')plt.plot(threshold, recall[:-1], 'g-', label='Recall')plt.xlabel('Threshold')plt.legend(loc='upper left')plt.ylim([0, 1])plt.show()
图10 精度与召回率
现在我们可以选择准确率召回率的最佳组合这样我们就有了最高的阈值。或者,我们可以绘制精度与直接召回,并得到我们需要的权衡。
ROC-AUC是评估二进制分类器的好方法。ROC 是一个真正正利率(召回率)与虚假正利率的图表。FPR 是被错误地预测为正面的负面类别的比率。
我们可以用 roc _ Curve ()函数计算 TPR 和 FPR。
import sklearn.metrics as metrics# Calculate the fpr and tpr for all thresholds of the classificationfpr, tpr, threshold = metrics.roc_curve(yc_train, y_train_pred, pos_label=1)roc_auc = metrics.auc(fpr, tpr)plt.plot(fpr, tpr, linewidth=2)plt.plot([0, 1], [0, 1], 'k--')plt.axis([0, 1, 0, 1])plt.xlabel('False Positive Rate')plt.ylabel('True Positive Rate')plt.show()
图11:ROC曲线
虚线表示随机分类器的 ROC。一个好的分类器的曲线下面积(AUC)接近于一。
from sklearn.metrics import roc_auc_scoreroc_auc_score(yc_train, y_train_pred)
0.846123948837538
我们将使用支持向量机在Python中实施简单的交易策略。目标变量是根据特征变量购买或出售股票。
我们将使用Google Finance S&P 500数据集训练和测试模型。我们可以使用Yfinance库下载数据。您可以使用命令“ pip install yfinance”安装库。安装后,加载库并下载数据集。
import yfinance as yfs_data = yf.download('SPY', start='2015-01-01', end='2020-12-31')# Drop the missing values from the dataset and then plot the closing price for each day s_data = s_data.dropna(axis=0)sns.lineplot(x=s_data.index, y='Close', data=s_data)
图12标准普尔500指数收盘价
现在我们必须确定目标变量并相应地拆分数据集。对于我们的情况,我们将使用股票的收盘价来决定是否购买或出售股票。如果下一个交易日的收盘价大于今天的收盘价,那么我们将买入标准普尔500指数,否则我们将卖出标准普尔500指数。我们将为买入信号存储 + 1,为卖出信号存储 -1。
y = np.where(s_data['Close'].shift(-1) > s_data['Close'], 1, -1)
X 是一个数据集,包含预测变量,用于预测目标变量“ y”。X 由诸如“ Open-Close”和“ High-Low”之类的变量组成。这些可以理解为指标的基础上,该算法将预测期权价格。
s_data['Open-Close'] = s_data.Open - s_data.Closes_data['High-Low'] = s_data.High - s_data.LowX = s_data[['Open-Close','High-Low']]
现在我们可以分开训练集和测试集数据,并在这些数据上训练一个简单的 SVC。
Xs_train, Xs_test, ys_train, ys_test = train_test_split(X, y, random_state=0) clf = SVC().fit(Xs_train, ys_train)clf.score(Xs_test, ys_test)
0.5026455026455027
机器学习可以根据目标变量的存在分为监督和无监督的模型。它们还可以根据目标变量的类型将它们分类为回归和分类模型。
各种类型的分类模型包括K-最近邻,支持向量机,决策树,可以通过使用集成学习来改进。这导致了随机森林分类器,它由一组决策树组成,这些决策树相互学习以提高模型的准确性。
你也可以通过使用超参调整技术(如 GridSearchCV 和 k 倍交叉验证)来提高模型的准确性。我们可以使用诸如混淆矩阵等评估方法,找到一个良好的精度-召回率权衡,并使用 ROC 曲线下的面积来测试模型的准确性。我们还研究了如何在交易策略中使用 SVC
|