面向直接营销的 Python 机器学习分类
你如何提高业务的时间效率、削减成本并提高销售额?这个问题是永恒的,但不是修辞性的。在接下来的几分钟阅读时间里,我将应用一些分类算法来演示数据分析方法的使用如何有助于实现这一目标。我们将一起创建一个预测模型,帮助我们定制交给电话营销团队的客户数据集,以便他们可以首先将资源集中在更有前景的客户上。
在此过程中,我们将对数据集执行一些操作。首先,我们将对数据进行清理、编码、标准化和重新采样。一旦数据准备就绪,我们将在训练子集上尝试四种不同的分类器,进行预测并用混淆矩阵可视化它们,并计算 F1 分数以选出最佳模型。这些步骤已经放在模式中:
Project’s schema
我们将在这里使用的数据集对这个城镇来说并不陌生,您可能以前就遇到过。41,118 条记录的数据样本由一家葡萄牙银行在 2008 年至 2013 年间收集,包含电话营销活动的结果,包括客户对银行提供的存款合同的回应(二元目标变量“y”)。这种反应正是我们要用模型预测的。数据集可从加州大学欧文分校的机器学习仓库获得。所以让我们开始吧!
结果:
数据清理、特征选择、特征转换
“我喜欢把事情一笔勾销”,弗里德里希·尼采说。这是数据清理部分!
使用df.isnull().sum()
查询,我们确保数据集中没有丢失的值(如果有的话,df.dropna(subset = ['feature_name'], inplace=True)
会将它们从相关的列中删除)。
在本例中,我使用 Tableau Prep Builder 数据清理工具来跟踪和删除异常值,以确保数字特征中的值不是字符串,重命名一些列并删除一些不相关的列,例如'contact', 'month', 'day_of_week', 'duration', 'campaign', 'pdays', 'previous' and 'poutcome'
(这些列描述了一个已经发生的电话呼叫,因此不应在我们的预测模型中使用)。
接下来,我们将把分类变量的非数字标签转换成数字标签,并把它们转换成整数。我们这样做:
运行df.dtypes
查询只是为了确保标签已经变成整数,这是有意义的。然后,我们应用sklearn.preprocessing
工具箱中的StandardScaler
来标准化我们期望在模型中使用的其他特征的数值。该方法通过移除平均值并缩放至单位方差来标准化特征:
现在,让我们使用递归特征消除(RFE)方法和随机森林分类器算法作为估计器对数据集的特征进行排序:
输出:
Num Features: 6
Selected Features: [ True True False True False False True False True True]
Feature Ranking: [1 1 3 1 2 5 1 4 1 1]
在稍后的阶段,当我们将建立一个预测模型时,我们将利用这个特性排名。我们将使用该模型,试图找到排名最高的特征的最佳组合,该组合将做出具有令人满意的 F1 分数的预测。展望未来,最佳组合将是:
例如,随着欺诈性信用卡交易或在线活动的结果等分类案例的出现,往往会出现类别失衡的问题。在执行df['y'].value_counts()
查询后,我们看到变量‘y’的两个类在我们的数据集中也没有被平等地表示。数据清理后,目标变量“y”中有 35584 条属于类“0”的记录,只有 4517 条属于类“1”的记录。在将数据分成训练样本和测试样本之前,我们应该考虑对数据进行过采样或欠采样。
为了对数据进行重新采样,让我们从imblearn.over_sampling
工具箱中应用SMOTE
方法进行过采样(对于此步骤,您可能需要先安装带有 Pip 或 Conda 的imblearn
包):
就这么简单。现在,数据与每个类中的 35584 个条目保持平衡:
输出:
[35584] [35584]
构建预测模型
既然数据已经准备好了,我们就可以训练我们的模型并进行预测了。让我们首先将数据分成训练集和测试集:
我们将尝试四种分类算法,即逻辑回归、支持向量机、决策树和随机森林,然后使用用户定义的scorer
函数计算它们的 F1 得分,以选择得分最高的分类器:
输出:
LogisticRegression F1 score = 0.71245481432799659
SVC F1 score = 0.753674137005029
DecisionTreeClassifier F1 score = 0.7013983920155255
RandomForestClassifier F1 score = 0.923286257213907
F1 得分是准确率和召回率的加权平均值。你可以在我的帖子这里阅读如何解读精度和召回分数。
现在,让我们打印一份完整的分类报告,其中包含随机森林算法的精确度和召回率,该算法已经证明了最高的 F1 分数:
输出:
precision recall f1-score support
0 0.91 0.93 0.92 10594
1 0.93 0.91 0.92 10757
micro avg 0.92 0.92 0.92 21351
macro avg 0.92 0.92 0.92 21351
weighted avg 0.92 0.92 0.92 21351
最后,我们可以用混淆矩阵将结果可视化:
结果:
太好了!我们已经清理并转换了数据,选择了最相关的特征,选出了最佳模型,并做出了一个得分不错的预测。现在,我们有了一个模型,可以帮助我们定制交给电话营销团队的客户数据库,这样他们就可以将精力集中在那些更有条件首先对活动做出肯定反应的人身上。
感谢您的阅读!!
使用 ROC 和 CAP 曲线的机器学习分类器评估
Photo by Isaac Smith on Unsplash
虽然有几个度量标准,如准确性和召回率,来衡量机器学习模型的性能,但 ROC 曲线和 CAP 曲线非常适合分类问题。在本文中,我将探讨什么是 ROC 和 CAP,以及我们如何使用 Python 和虚拟数据集来创建这些曲线。
即使在探索了许多关于 CAP Curve 的文章后,我也找不到一篇详细解释如何创建它们的文章,这就是我写这篇文章的原因。
完整的代码被上传到下面的 GitHub 库。
在这个知识库中,我讨论了各种机器学习模型的性能评估指标。…
github.com](https://github.com/kb22/ML-Performance-Evaluation)
资料组
我创建了自己的数据集。有两个特性,age
和experience
。基于这两个特征,输出标签为0.0
表示工资低于 20 万美元,而1.0
表示工资高于或等于 20 万美元。
Complete dataset
GREEN
点数代表超过或等于 20 万美元的薪资,而RED
点数代表低于 20 万美元的薪资。我还确保了这两个类之间有一些重叠,所以数据更真实一些,不容易分离。
分类
首先,我将数据分成两组,70%的训练数据和 30%的测试数据。我用Support Vector Classifier
和linear kernel
对训练数据进行训练,然后在测试数据上测试模型。该模型取得了 95% 的评分。
Classification on Test data
性能赋值
受试者工作特性曲线
接收器操作特性曲线,更好地称为 ROC 曲线,是测量分类模型性能的极好方法。针对分类器预测的概率,将真阳性率(TPR) 与假阳性率(FPR) 作图。然后,计算地块下的面积。
曲线下的面积越大,模型区分类别的能力就越强。
导入文件并创建基线 首先,我从sklearn.metrics
导入roc_curve
和auc
,这样我可以创建 ROC 曲线并计算曲线下的面积。我还将图形大小定义为 20x12,并创建一条从(0,0)
到(1,1)
的基线。
值r--
表示线条颜色为红色,是一条虚线(— — — — — — — — — — — — —
)。
计算概率并确定 TPR 和 FPR 接下来,使用predict_proba
我计算预测的概率并将其存储在probs
中。它由两列组成,第一列包括第一类的概率(薪金< $20 万),第二列包括第二类的概率(薪金≥ $20 万)。所以,我用probs[:, 1]
选择第二类的概率。
roc_curve
生成 roc 曲线并返回fpr
、tpr
和thresholds
。最后,使用fpr
和tpr
作为auc
中的输入,我计算出该模型曲线下的面积,并将其保存在roc_auc
中。roc_auc
现在有了我们的支持向量分类器生成的曲线下的面积。
绘制 ROC 曲线 我使用fpr
作为 x 值和tpr
作为 y 值绘制曲线,颜色为绿色,线宽为 4。这条曲线的标签包括曲线下的区域。x 轴标签设置为False Positive Rate
,y 轴标签设置为True Positive Rate
。标题为Receiver Operating Characteristic
,图例出现在图的右下角。文本大小设置为 16。
ROC Curve
曲线下面积为 0.98,这真是令人惊讶,提供了我们的模型表现良好的信息。
累积精度曲线
CAP 曲线试图分析如何使用最少的尝试次数有效地识别给定类别的所有数据点。在这个数据集中,我试图确定Support Vector Classifier
能够多快地识别出所有工资高于或等于 20 万美元的个人。
计算每个类的计数 首先,我在测试数据(60)中找到总的数据点,并保存在变量total
中。测试标签要么是0.0
要么是1.0
,所以如果我把所有的值加起来,我将得到类1.0
(31)的计数,我可以把它保存在class_1_count
中。从total
中减去这个数将得到class_0_count
(29)。
我还将图形尺寸设置为 20x12,使其比正常尺寸大。
随机模型 首先,我们绘制一个随机模型,该随机模型基于类别1.0
的正确检测将线性增长的事实。
颜色为red
,样式为使用--
定义的dashed
。我已经将标签设置为Random Model
。
Random Model
完美模型
接下来,我绘制完美模型。一个完美的模型将在与类别1.0
数据点相同的尝试次数中检测所有类别1.0
数据点。完美模型需要 31 次尝试来识别 31 类1.0
数据点。
我把这块地涂成灰色。标签设置为Perfect Model
。
Perfect Model
经过训练的模型(支持向量分类器)
最后,我绘制出Support Vector Classifier
的结果。首先,像在 ROC 曲线中一样,我提取变量probs
中类1.0
的概率。
我把probs
和y_test
拉上拉链。然后,我按照概率的逆序对这个 zip 文件进行排序,最大概率排在最前面,然后是较小的概率。我只提取数组中的y_test
值,并将其存储在model_y
中。
np.cumsum()
创建一个值数组,同时将数组中所有以前的值累加到当前值中。例如,如果我们有一个数组[1, 1, 1, 1, 1]
。应用cumsum
将导致[1, 2, 3, 4, 5]
。我用它来计算 y 值。此外,我们需要在数组前面追加0
作为起始点(0,0)
。x 值的范围从0
到total + 1
。我添加一个,因为np.arange()
不包括终点,我希望终点是total
。
然后我用蓝色标出结果,并标上Support Vector Classifier
。我还将另外两个模型包含在情节中。
Support Vector Classifier
使用曲线下面积
的 CAP 分析分析 CAP 曲线的第一种方法是使用曲线下面积。让我们考虑随机模型下的面积为a
。我们使用以下步骤计算准确率:
- 计算完美模型(
aP
)到随机模型(a
)下的面积 - 计算预测模型(
aR
)到随机模型(a
)下的面积 - 计算准确率(
AR
) = aR / aP
准确率越接近 1,模型越好。
使用auc
,我计算了所有面积,然后使用这些值计算了准确率。该比率约为 0.97,非常接近于 1,表明我们的模型非常有效。
使用图进行 CAP 分析 另一种分析 CAP 曲线的方法是读取我们上面生成的图。相同的步骤如下:
- 从 x 轴的 50%处画一条垂直线,直到它穿过
Support Vector Classifier
图。 - 在垂直线与训练模型相交的点上,画一条水平线,使其与 y 轴相交。
- 计算 1 类标签占 1 类标签总数的百分比。
一旦我们知道了百分比,我们就可以用下面的括号来分析它。低于 60%:垃圾型号
2。60% — 70%:差模
3。70% — 80%:好型号
4。80% — 90%:非常好的型号
5。超过 90%:好得难以置信
请注意,如果该值超过 90%,测试过度拟合是一个很好的做法。
首先,我通过计算总测试数据的 50%的 int 值来找到索引。我用它来画一条从这个点到训练好的模型的垂直虚线(— — —
)。接下来,我画出从这个交点到 y 轴的直线。我通过将目前观察到的类1.0
值除以总的类1.0
数据点并乘以 100 来确定百分比。我得到的值为 93.55% 。
CAP Curve Analysis
尽管百分比是 93.55%,大于 90%,但结果是预期的。正如我们在开始时看到的数据集和分类,该模型在拆分数据方面非常有效。虽然我对测试数据使用了 CAP 分析,但我们也可以对训练数据使用同样的方法,并分析我们的模型对训练数据的了解程度。
结论
本文总结了如何用 Python 计算 ROC 曲线和 CAP 曲线,以及如何对它们进行分析。
请随时分享你的想法和想法。与 ROC 和 CAP 一起工作对我来说也是全新的,所以请分享我可能错过的任何信息。感谢阅读!
DBSCAN Python 示例:Epsilon (EPS)的最佳值
https://www.pexels.com/photo/a-boy-holding-a-chalk-5212334/
DBSCAN,即基于密度的带噪声应用空间聚类,是一种无监督的机器学习算法。无监督的机器学习算法用于分类未标记的数据。换句话说,用于训练我们的模型的样本没有预定义的类别。与其他聚类算法相比,DBSCAN 特别适用于需要以下条件的问题:
- 确定输入参数的最少领域知识(即 k-means 中的 K 和层次聚类中的 Dmin
- 发现任意形状的团簇
- 大型数据库的良好效率
如果你对阅读 DBSCAN 感兴趣,可以在这里找到原文。
算法
与大多数机器学习算法一样,模型的行为由几个参数决定。在接下来的文章中,我们将触及三个问题。
- eps :如果两点之间的距离低于阈值ε,则认为这两点是相邻的。
- min_samples :一个给定点为了被分类为核心点而应该拥有的最小邻居数量。需要注意的是,点本身包含在最小样本数中。
- 度量:计算特征数组中实例间距离时使用的度量(即欧几里德距离)。
该算法通过计算每个点和所有其他点之间的距离来工作。然后,我们将这些点分为三类。
核心点:至少有 个 min_samples 个点的点,这些点相对于该点的距离低于由ε定义的阈值。
边界点:至少与 min_samples 点不接近,但与一个或多个核心点足够接近的点。边界点包含在最近核心点的群集中。
噪声点:离核心点不够近的点被认为是边界点。噪声点被忽略。也就是说,它们不属于任何集群。
密码
让我们看看如何用 python 实现 DBSCAN。若要开始,请导入以下库。
import numpy as np
from sklearn.datasets.samples_generator import make_blobs
from sklearn.neighbors import NearestNeighbors
from sklearn.cluster import DBSCAN
from matplotlib import pyplot as plt
import seaborn as sns
sns.set()
与导入数据相反,我们可以使用scikit-learn
来生成定义良好的集群。
X, y = make_blobs(n_samples=300, centers=4, cluster_std=0.60, random_state=0)
plt.scatter(X[:,0], X[:,1])
如前所述,我们必须为ε提供一个值,它定义了两点之间的最大距离。下面的文章描述了一种自动确定 Eps 最佳值的方法。
https://IOP science . IOP . org/article/10.1088/1755-1315/31/1/012012/pdf
通俗地说,我们通过计算每个点到最近的 n 点的距离,对结果进行排序和作图,从而为ε找到一个合适的值。然后我们观察变化最明显的地方(想想你的手臂和前臂之间的角度),并选择它作为ε。
我们可以使用NearestNeighbors
来计算每个点到最近邻点的距离。点本身包含在n_neighbors
中。kneighbors
方法返回两个数组,一个包含到最近的n_neighbors
点的距离,另一个包含这些点的索引。
neigh = NearestNeighbors(n_neighbors=2)nbrs = neigh.fit(X)distances, indices = nbrs.kneighbors(X)
接下来,我们对结果进行排序和绘图。
distances = np.sort(distances, axis=0)distances = distances[:,1]plt.plot(distances)
ε的最佳值将在最大曲率点找到。
我们训练我们的模型,选择0.3
为eps
,设置min_samples
为5.
m = DBSCAN(eps=0.3, min_samples=5)m.fit(X)
labels_
属性包含集群列表和它们各自的点。
clusters = m.labels_
然后,我们将每个单独的聚类映射到一种颜色。
colors = ['royalblue', 'maroon', 'forestgreen', 'mediumorchid', 'tan', 'deeppink', 'olive', 'goldenrod', 'lightcyan', 'navy']vectorizer = np.vectorize(lambda x: colors[x % len(colors)])
该模型对人口密集区进行了分类。正如我们所见,所有深蓝色的点都被归类为噪声。
plt.scatter(X[:,0], X[:,1], c=vectorizer(clusters))
最后的想法
与 k-means 不同,DBSCAN 会计算出聚类数。DBSCAN 的工作原理是确定最小数量的点是否彼此足够接近以被视为单个聚类的一部分。DBSCAN 对比例非常敏感,因为ε是两点之间最大距离的固定值。
机器学习速成班
你现在如何在你的问题中使用机器学习?
机器学习是发展最快的技术领域之一。它能够自动化大量当前流程,这些流程是当今工作的一部分。机器学习有两种主要的一般方法:监督和非监督。两者都可以用来解决许多分类或回归问题。
Machine Learning is great for classifying, predicting and analysing data.
例如,假设我们想要预测“黄邦贤在美国吗”。然后你会使用监督学习。在监督学习中,学习者有一个特征数据集,对于每个标签,都有一组训练实例。关键是选择理想的分类器,使其在给定训练示例的情况下学习数据应该预测什么。
示例:生成准确的未来警察追捕历史
想象一个犯罪侦查系统。我们想比较一个高调犯罪和一个类似的低调犯罪在未来的描述与他们的预期结果。这是监督机器学习的一个例子。这里有一篇信息丰富的博客文章,可以了解更多关于 NLP 和机器学习的知识,并查看用于帮助生成未来搜索历史的代码。
当使用无监督的机器学习时,我们没有任何类似标记数据集的东西(还没有)。相反,我们有一个未标记的“源”数据集。为了预测犯罪,我们需要了解一些犯罪的历史原因。我们使用数据挖掘方法来识别与犯罪密切相关的因素。
但是机器学习也包括从未标记的数据中创建数据集的过程。我们应用一些机器学习方法来创建一组未标记的数据点。这些点作为我们分类任务的标签。这个过程叫做训练。
现在我们有了一个未标记的数据集和一组训练示例,我们可以运行分类任务了。此时,分类器不知道预测的标签是什么(它应该将数据点分配给哪个类)。它只是知道如何预测它。但是一些分类器可能需要运行更多的训练样本以便收敛。这叫学习率。
基于决策树的回归
我们可以使用基于分类器的方法,该方法依赖于一些输入特征和我们的输出标签之间的成对链接结构。决策树就是一个例子。该树只包含一个树形目录,该目录是每个所需特征链接的特征(分类标签)。
例如,我们可能希望预测每个感兴趣类别的帖子中的消息长度。但是用户只是想要标题。因此,对于每个类别,树目录可能只有一个条目。每个条目将描述一类消息,每个树条目将给出一些树链接,这些树链接的左轴和右轴的值之和大于我们选择的一个数字。这些值是从一些随机抽样中计算出来的。
这将适用于某些类别标签。然而,通过额外的训练例子,它变得几乎无用。我们最终会有很多错误类别的树条目,这将导致没有一个条目会收敛。
机器学习和视觉
现在,考虑一个世界,我们生活在一个有 WiFi 的城市。为了检测城市环境中的活动和移动,有大量的数据和许多传递这些数据的方式。例如,我们也许可以使用摄像机,而不仅仅是在电视机上发出警告。图像传感器上的每对标记可以指示该邻域中的活动。使用这些特征,系统可以对活动进行分类,并且可以准确地检测活动。要做到这一点,系统必须学习背景上的活动模式,并预测用户的位置。这将需要大量的例子来收敛。
机器学习和训练
对于每个数据点,可以训练机器学习模型,以便该模型能够预测数据点的“未来类别”。训练可以通过反向传播来完成。通常,回归问题还涉及某种对象检测问题。因此,需要结合物体检测和机器学习。
应用基于分类器的机器学习
在某些情况下,模型学习问题过于复杂,无法用有监督的机器学习技术来解决。在其他情况下,人类的机器学习专家必须实现和实施模型。但是,为了训练模型,我们可以使用一些机器学习算法,如梯度提升、支持向量机、AdaBoost、剩余秩学习和某种程度上的随机森林。
结论
机器学习是一个很好的工具,可以对数据进行分类、预测和生成洞察,不管是有标签的还是无标签的。
作为一名机器学习工程师(或数据科学家,这里没有通用的职称标准),你将基于数据解决现实世界的问题。您的数据可能包括图像、音频文件或文本文档。第一步总是清理你的数据,使它更容易使用和实现机器学习算法。接下来是探索数据和思考你可能想要用来成功的算法的时候了。
Data Science Job
最后,如果你想了解成为一名数据科学家意味着什么,那么看看我的书数据科学工作:如何成为一名数据科学家,它将指导你完成这个过程。
如果你想了解更多关于机器学习和数据科学的内容,可以看看我的其他文章:
机器学习、骑自行车和 300W FTP(第一部分)
寻找更好的体育锻炼方法
Credit: Coen Van Den Broek
我不时地骑自行车。我说的是公路自行车。我不是职业选手,我也不想成为——但是我喜欢竞争,我喜欢比赛,我喜欢挑战。
原来骑自行车是一项与数据纠缠不清的运动。从功率计到心率监测器,追踪这项运动变得很容易。
A Wattbike Trainer
使用我自己的 106 次 Wattbike(室内教练)旋转训练的数据集,这一系列文章的目的是了解我的表现的重要特征。我希望能够利用这些信息来实现我的目标:300 瓦的 FTP。
我会尽可能多的把工作喂给 野兽 (ML)。
所有代码都在 GitHub 上。
F警察?!*
不,不完全是。功能阈值功率(FTP) 代表骑手可以维持一小时的功率,以瓦特为单位,通常计算为 20 分钟全力测试平均功率的 95%。
基于 20 分钟会话的计算似乎是任意的,但这是为了易于复制和方便起见。 FTP 与大多数骑自行车的人相关,是评估你短期和长期努力的基础。
如果你想了解更多,请点击这里查看 BikeRadar 的文章。
从 255 瓦开始
Figure 1: Session Average Distribution of Power over a Revolution
截至 2019 年 8 月 20 日,我记录了一个 255 瓦的 FTP,重 87 公斤。也就是说,我在 Wattbike 上 20 分钟内平均输出 268 瓦(其中 95%是我的 FTP 读数)。鉴于我的体重,我猜这可能是平均水平。
我以为这是关于权力的,你为什么要谈论花生?
你可能想知道如何推动踏板转化为权力。在任何物理系统中,功率都表示为力和速度的乘积。在自行车运动中,这个等式告诉我们:
力量=蹬力 x 腿速
步频,以每分钟转数(rpm)衡量,代表腿部速度,对于单次 360 度腿部旋转,上面的花生状极坐标图显示了在会话中每次旋转平均的每个角度的切向力。
Zwatt 团队和 Wattbike 团队都有关于主题这里和这里的作品(分别)。
好吧,那有什么变化呢?
Figure 2: Polar plots for 4 different 20 Minute Tests
每条线代表完成的 20 分钟最大努力测试,首先在 2017 年,然后在 2019 年再进行三次测试。虽然极坐标图确实显示了变化,但现在,我对 FTP 的变化感兴趣。
1)+2W2017 年 11 月 9 日至 2019 年 3 月 25 日改进。
2)+16W2019 年 3 月 25 日至 2019 年 5 月 28 日改进。
3)+7W2019 . 5 . 28-2019 . 8 . 20 改善。
2019 年 3 月至 8 月是行动的开始。
反思期,没有一个训练目标。然而,我确实试图坚持训练,并且每次都或多或少地使用预定义的 Wattbike 应用程序会话。该应用程序跟踪一系列变量,包括训练过程中的距离、节奏和力量。数据集说明了什么?
2019,低强度训练年
Figure 3: Distribution of Time Spent in Bucketed Power Zones
嗯,今年我确实找到了更多的时间去骑车。
根据图 3 中的分布图,相对于其他类别,我已经在100–150 w类别中花费了更多的时间。尽管骑自行车的时间更多,但与 2018 年相比,今年到目前为止,我花在测试我的功率极限( 300W+ 类别)上的时间更少。我没想到会这样。
Figure 4: Proportion of Ride Duration in each Power Zone.
添加一个日期维度,只观察今年记录的时段,上面的堆积条形图显示了每个动力区类别花费的每次乘坐时间比例。红色大竖条与之前在花生地里进行的 20 分钟 FTP 测试相吻合。
+16W vs+7W——我做了哪些不同的事情?
通过 3 个 FTP 测试分离情节,我们剩下两个时期,创造性地,我将它们称为时期 1 和时期 2 。
**第一阶段:**9 周内 19 次会议(3 月 25 日-5 月 28 日)。
**第二阶段:**12 周内 20 次会议(5 月 28 日—8 月 20 日)。
该图说明了在周期 1 中的会话的特点是花费在200-250 w和100-150 w区域中的时间比例较大,并且几乎没有时间测试我的功率极限的上限。
换句话说,黄色的多,深红色的 少。
Figure 5: Absolute Ride Duration split by Power Zone.
在绝对时间而不是相对时间中绘制图 4 揭示了更多好东西。看看上面,有什么让你印象深刻的?
a) 更长的乘坐持续时间在周期 1 中展现。****
b)在周期 1** 中,计时超过 200 w15 分钟的更多会话**。****
c)在100-150 w区域内,大多数周期 1** 时段计时 25 分钟以上。**
持续时间、工作量&节奏
Figure 6: Max Power, Average Power, Session Duration, Workload, Power Standard Dev & Cadence Scatterplots (top left to bottom right, period 1 = blue, period 2 = orange).
在图 6 中,我们绘制了周期之间的六个进一步的指标(周期 1 =蓝色,周期 2 =橙色),并揭示了以下内容:
1)
2) 平均功率 —没有明显差异,但是在周期 2 会话中可能维持稍高的平均功率。
3) 会话持续时间 — 获胜者 —在周期 1 中会话长度的变化更大,更短和更长的会话都是如此。
4) 工作量 — 赢家 —第 1 期利用了更多的工作量变化。我将工作负载定义为平均功率乘以会话持续时间,代表会话的总强度。
5) 功率标准差 —这是为了区分持续努力(低标准 dev)和间歇会话(高标准 dev)。两个时期都显示混合会议。嗯,没有明显的区别。
6) 节奏 — 优胜者 —第一期以更大范围的节奏训练。
对 Wattbike 课程的一些探索性数据分析已经突出显示了(获胜者)一些有趣的途径,可以探索有关训练强度、节奏和持续时间的内容。
要达到 300 瓦的 FTP,我至少要接受多少专业训练?
我们还没喂 野兽 (do ML) 但是回到目标,还是有那么多要回答的。
什么时候训练时间变得无关紧要了?我的饮食是什么样的?睡眠模式如何影响训练?精神状态和压力起什么作用?
还有很多生活方式的因素在起作用——我认识到,我仅凭权力得出的结论是不确定的。
接下来呢?
在把数据扔给 ML 之前,我想深入挖掘一下我的心率和睡眠数据集。如果我能够将这些数据集以菊花链的方式连接在一起,并与我已经拥有的电力数据保持一致,那就更好了。
我不知道他们会透露什么,但我迫不及待地想知道——我将在第 2 部分记录我的发现。请随意提出任何建议或您自己的结果。
问题不在于我训练了多少时间,而在于我在这段时间里做了什么。
这部作品的驱动者是 个性化 。
我们每个人对身体压力的反应不同,需要不同的恢复程度,有自己的伤害,活动水平,饮食和生活方式——所以我们真的应该期待关注甚至不了解我们的网站会有好的结果吗?
个性化结果怎么样?
研究对于分享知识来说是很棒的,但是我不想要一个 100 人的样本的结果,他们不是我的年龄,不是我的种族,不分享我的生活方式,也没有我的伤害。
最初纯粹是一个物理目标,现在变成了一个练习,学习是什么让一个人成功,了解优势和针对弱点。在此过程中利用尽可能多的数据。
更重要的是,这个原理是运动不可知的。对我来说是骑自行车,但对你来说可能是抱石,对他来说可能是减肥,对她来说可能是橄榄球。
欢迎来到自我意识的时代。
导出并可视化代码: github
机器学习数据集
为数据科学项目寻找第一批数据的最佳资源
简介
你读过几篇关于数据分析的文章,然后你跟随了几个教程,看着人们应用基本的机器学习算法。现在您已经准备好自己尝试一些这种技术,但是您从哪里开始呢?您的笔记本电脑上没有数百万行数据等待分析。
在本文中,将向您介绍五种不同的数据源,您可以通过搜索来找到最适合数据科学项目的第一个数据集。
卡格尔
下载数千个项目的开放数据集+在一个平台上共享项目。探索热门话题,如政府…
www.kaggle.com](https://www.kaggle.com/)
Kaggle 可能是最受欢迎的资源,鼓舞人心的或现有的数据科学家可以在这里找到边项目的数据集。目前,这个网站上有近 25000 个公开的数据集,它们涵盖了各种各样的主题。您可以使用关键字搜索数据集,如果其他数据科学家决定通过创建一个公开可用的内核来共享他们的工作,则可以查看他们在数据集上的工作。
此外,该网站举办机器学习竞赛,以防你想与全球其他数据科学家竞争奖项,一旦你学到足够的知识,你还可以搜索他们的工作板以找到与数据科学相关的工作。
驱动数据
DrivenData 致力于数据科学和社会影响交叉领域的项目,如国际…
www.drivendata.org](https://www.drivendata.org/)
DrivenData 是一个类似 Kaggle competition 的网站,因为数据集是以有奖竞赛的形式发布的。他们没有这么大的数据库,但他们的主题是对世界和社会产生影响。因此,许多人发现他们的数据集鼓舞人心,绝对值得研究。
UCI 机器学习知识库
UCI 机器学习知识库 目前已经有近 500 个数据集可供你下载并开始使用。搜索他们的数据集是绝对值得的,因为他们大多是干净的,组织良好的。
美国政府数据
美国海岸警卫队保存着历史船只位置变动的档案,通过全国范围的…
www.data.gov](https://www.data.gov/)
美国 Gov 数据 是另一个拥有大量数据集的地方。你现在可以浏览超过 25 万个不同的政府数据集。分为农业,气候,消费者,生态系统,教育,能源,金融,卫生,地方政府,制造业,海事,海洋
结论
我已经介绍了我最喜欢的寻找机器学习和数据科学数据集的资源。现在是你的时间了,所以在你的 jupyter 笔记本上浏览、下载和加载数据吧。
原发表于 aboutdatablog.com: 机器学习数据集,2019 年 11 月 11 日。
PS:我正在 Medium 和上撰写深入浅出地解释基本数据科学概念的文章。你可以订阅我的 邮件列表 每次我写新文章都会收到通知。如果你还不是中等会员,你可以在这里加入。**
下面还有一些你可能喜欢的帖子
** [## python 中的 lambda 函数是什么,为什么你现在就应该开始使用它们
初学者在 python 和 pandas 中开始使用 lambda 函数的快速指南。
towardsdatascience.com](/what-are-lambda-functions-in-python-and-why-you-should-start-using-them-right-now-75ab85655dc6) [## Jupyter 笔记本自动完成
数据科学家的最佳生产力工具,如果您还没有使用它,您应该使用它…
towardsdatascience.com](/jupyter-notebook-autocompletion-f291008c66c) [## 当你开始与图书馆合作时,7 个实用的熊猫提示
解释一些乍一看不那么明显的东西…
towardsdatascience.com](/7-practical-pandas-tips-when-you-start-working-with-the-library-e4a9205eb443)**
机器学习——诊断车队跟踪器的故障
本文提出了一种数据驱动的解决方案来诊断车队跟踪模块的故障。
Figure 1: https://www.shortlandinsurance.com/module_resources/page_management/36/Fotolia_37500680_L.jpg
介绍
许多运输和物流公司使用模块来跟踪他们的车辆,一些模块不能按预期工作并不罕见。例如,可能需要丢弃追踪器,可能会收集到车辆的错误数据,或者可能会将技术支持人员派到很远的地方去分析问题。因此,有必要对这些模块进行远程故障诊断,因为当它们出现故障时,可能会造成经济损失。
由于这些模块不断地向数据库发送数据,本研究的目的是使用这些数据来诊断模块上的故障。有必要开发一种方法来预处理由车辆模块发送的收集数据。在此之后,机器学习技术被应用于创建模型,模型被分析和比较。但是,错在哪里呢?
故障是系统的至少一个属性或特征参数的不允许的偏差[1]。诊断故障有三个步骤,即:
- 故障检测:是故障诊断最基本的任务,用于检查系统中的故障或失效,并确定故障发生的时间;
- 故障隔离:隔离的作用是检测故障的位置或者是哪个部件有缺陷;
- 故障标识:该标识用于确定故障的类型、形式和大小。
通常,故障识别过程只包括故障检测和隔离(FDI)。这并没有否定故障识别的效用。然而,如果不涉及重新配置动作,这个过程可能不是必需的[2]。
发展
首先,要执行任何机器学习解决方案,都需要数据。在本案例研究中,一家巴西物流公司提供了许多追踪器发送的一些数据,因此所有使用的数据都是真实的。
问题描述
安装在车辆中的模块在整个运行期间发送数据。该公司提供了 12586 个注册表。该公司提供了 12586 个注册表。注册表由一个模块在一天内传输的所有数据组成。平均每个模块每天发 1116.67 分。每个点有八个属性:
- 电池电压:车载电池电压的浮动值;
- 经度:车辆经度的浮点值;
- 纬度:车辆纬度的浮点值;
- 点火:表示点火
是否打开的布尔值; - 里程表:车辆里程表的浮点值;
- GPS 信号:表示 GPS 信号
是否有效的布尔值; - 速度:车速的浮点值;
- 内存索引:模块中
点保存的内存位置的整数值。
因为模块根据每个模块以不同的频率定期发送数据,所以每个注册表具有不同的大小。这样,每个注册表的大小就是发送的点数乘以 8(属性的数量)。
目的是识别注册中心可能存在的错误或其是否正常工作。这样,这是一个多类分类问题,这里有八类;一类为无故障的注册表,七种可能的故障,如下所列:
- 故障 1 :脉冲设置错误;
- 故障二:里程表锁定;
- 故障三 : GPS 锁定;
- 故障 4 :点火线释放;
- 故障 5 :加速计故障;
- 故障 6 :模块缓冲有问题;
- 故障 7 : GPS 出现位置跳变;
这些故障中的一些有几次出现得太低。不足 3%的瑕疵都被贴上了“其他”的标签。每个故障的数据量可以在左边看到。
数据预处理
因为特征提取过程是一项大规模的工作,会显著影响最终结果[3]。这种方法使用来自系统的知识来执行数据转换,以显著降低数据维度。
初始属性是时间序列(电池电压、纬度等。),从它们中,我创建了 21 个新属性,如下表所示。此后,数据转换将原始数据从二维转换为一维。这些新属性中的大多数都可以很容易地计算出来,因此没有复杂的公式或算法。
New Attributes description table.
大多数属性都是二进制的,所以不需要规范化。然而,诸如点数、关于电池电压的数据和存储器索引中的跳跃之类的属性可以被标准化。由于没有对异常值进行分析,传统的归一化会导致数据被一些高值所抑制,因此使用 RobustScaler。此缩放器使用第一个和第三个四分位数作为约束,而不是最大值和最小值,因此这种归一化更健壮,并保留了异常值。
由于某些属性可能与其他属性高度相关,因此计算了所有可能的相关性。经度和纬度变化具有 0.996315 的皮尔逊相关性,这在大多数 ML 项目中建议我们应该丢弃这些属性中的一个。然而,由于模型的目标是诊断模块的 GPS 中的故障,尽管相关性很高,但这两个属性都是有用的。
而且,点数和 GPS 无效的点数有很高的相关性,0.962769。这是因为点数是有效 GPS 点数与无效 GPS 点数之和。因此,由于这种线性组合,属性“点数”被丢弃。最后,日期和序列字段也被丢弃,因为它们用于识别车辆和模块,并且不提供关于模块操作的任何信息。
训练 ML 模型
为了运行算法,数据集被分成训练集和测试集。对于每个实验,20%的注册表用于测试,80%用于训练。
我想找出哪种传统算法更适合这种数据,所以我测试了过采样和欠采样的每种算法。
考虑到最大似然技术,所有的随机森林都使用 100 个估计器,所有的最大似然都使用架构(5,10,5),lr = 0:001 和 200 次最大迭代。
获得的指标可以在下表中看到:
通过过采样,随机森林的归一化混淆矩阵如下所示:
除了最大似然技术的评价指标,还计算了模型的训练和评价时间。在最坏的情况下,这个时间是 0.37 ms ,在这个案例研究中,这个时间可以被认为是应用程序
的实时响应。
结论
正如所提出的,这些模型可以检测和识别具有高性能指标的车队跟踪模块上的故障。然而,有广泛的功能工程,可以由 LSTM 或 CNN 自动执行。我也,做了一些 CNN 的模型来做这个故障诊断,也许我会在下一篇文章中详细介绍。
所采用的方法的局限性包括模型不能发现未被映射的故障,因此任何未被学习的故障将被错误地分类为已知故障之一。
和文章中一样,这里没有任何代码,你可以在我的 GitHub 库中随意查看。
故障诊断模型检测和识别车队跟踪模块上的故障。…
github.com](https://github.com/lmeazzini/Tracker-fault-diagnosis)
参考
[1] D. van Schrick,“关于
监督、故障检测和诊断领域术语的说明”,IFAC 会议录
卷,第 30 卷,第 18 期,第 959-964 页,1997 年。
[2] D. Wang 和 W. T. Peter,“基于移动平均磨损退化指数
和一般
顺序蒙特卡罗方法的泥浆泵预测”,机械系统和
信号处理,第 56 卷,第 213–229 页,2015 年。
[3] L. Wen,X. Li,L. Gao,Y. Zhang,“一种新的基于卷积
神经网络的数据驱动故障诊断方法”,
IEEE Transactions on Industrial Electronics,vol. 65,no. 7,
PP . 5990–5998,2018,
机器学习——用 CNN 诊断车辆追踪器故障
Photo by Omer Rana on Unsplash
初步考虑
几周前,我发表了另一篇标题几乎相同的文章:
一种数据驱动的跟踪模块故障诊断方案。
towardsdatascience.com](/machine-learning-diagnosing-faults-on-vehicle-fleet-trackers-56b123d77cf5)
在这个故事中,我使用了跟踪模块操作的一些特定知识来手动提取特征;现在,在这个故事中,我的目标是在没有任何特征提取的情况下,在同一个数据集上诊断故障。对于没有阅读第一篇文章的人来说,介绍和问题描述将是相同的。然而,所有的发展都不会。
介绍
许多运输和物流公司使用模块来跟踪他们的车辆,一些模块不能按预期工作并不罕见。例如,可能需要丢弃追踪器,可能会收集到车辆的错误数据,或者可能会将技术支持人员派到很远的地方去分析问题。因此,有必要对这些模块进行远程故障诊断,因为当它们出现故障时,可能会造成经济损失。
由于这些模块不断地向数据库发送数据,本研究的目的是使用这些数据来诊断模块上的故障。有必要开发一种方法来预处理由车辆模块发送的收集数据。在此之后,机器学习技术被应用于创建模型,模型被分析和比较。但是,错在哪里呢?
故障是系统的至少一个属性或特定参数的不允许的偏差[1]。此外,诊断故障有三个步骤,即:
- 故障检测:是故障诊断最基本的任务,用于检查系统中的故障或失效,并确定故障发生的时间;
- 故障隔离:隔离的作用是检测故障的位置或者哪个是有缺陷的部件;
- 故障标识:该标识用于确定故障的类型、形式和大小。
通常,故障识别过程只包括故障检测和隔离(FDI)。这并没有否定故障识别的效用。然而,如果不涉及重新配置动作,这个过程可能不是必需的[2]。
问题描述
首先,要执行任何机器学习解决方案,都需要数据。在本案例研究中,一家巴西物流公司提供了许多追踪器发送的一些数据,因此所有使用的数据都是真实的。
安装在车辆中的模块在整个运行期间发送数据。该公司提供了 12586 个注册表。该公司提供了 12586 个注册表。注册表由一个模块在一天内传输的所有数据组成。平均每个模块每天发 1116.67 分。每个点有八个属性:
- 电池电压:车载电池电压的浮动值;
- 经度:车辆经度的浮点值;
- 纬度:车辆纬度的浮点值;
- 点火:表示点火
是否开启的布尔值; - 里程表:车辆里程表的浮点值;
- GPS 信号:表示 GPS 信号
是否有效的布尔值; - 速度:车速的浮点值;
- 内存索引:模块中
点保存的内存位置的整数值。
因为模块根据每个模块以不同的频率定期发送数据,所以每个注册表具有不同的大小。这样,每个注册表的大小就是发送的点数乘以 8(属性的数量)。
目的是识别注册中心可能存在的错误或其是否正常工作。这样,这是一个多类分类问题,这里有八类;一类为无故障的注册表,七种可能的故障,如下所列:
- 故障 1 :脉冲设置错误;
- 故障二:里程表锁定;
- 故障三 : GPS 锁定;
- 故障 4 :点火线释放;
- 故障 5 :加速计故障;
- 故障 6 :模块缓冲器有问题;
- 故障 7 : GPS 出现位置跳变;
这些故障中的一些有几次出现得太低。不足 3%的瑕疵都被贴上了“其他”的标签。每次故障的数据量见下表。
发展
我的目标是检测和隔离故障;然而,虽然仅仅检测故障是一个二元问题,但是检测和隔离是一个多类问题。检测故障可能容易得多。从公司方面来看,几乎总是,当一个模块出现故障时,他们需要更换它。所以不管是什么故障,我们都需要更换模块。
我们在这里提出模型,一个用于检测故障,另一个用于检测和隔离故障。
数据预处理
由于我们的目标是在不使用任何关于系统操作的特定知识的情况下对数据集进行微小的更改,因此数据预处理相当简单。
我们选择保留所有数据,不执行任何异常值分析。大多数离群值强烈表明存在错误,如果我们丢弃所有离群值,许多有问题的注册中心将会消失。这样,我们唯一要做的就是使用鲁棒定标器进行归一化。传统的归一化会导致数据被某个高值抑制,因此使用 RobustScaler。此缩放器使用第一个和第三个四分位数作为约束,而不是最大值和最小值,因此这种归一化更健壮,并保留了异常值。
考虑到注册表具有可变长度,不可能用该数据集直接构建 ML 模型。这样,有必要为所有重试设置一个默认大小。已知注册表中存在的最大点数是 6410,点数的平均值是 1116.67,标准偏差是 1155.75,具有较小数据量的注册表以“0”完成,直到它们具有与最大注册表相同的数据量。
可以执行不同的方法来设置注册表的默认大小,例如从高于平均值的注册表中截断数据量,并且用“0”来填充低于平均值的注册表,或者从比较小的注册表具有更多数据的所有注册表中截断数据量。然而,由于 CNN 的分歧,这些方法被测试并被认为是不可行的。
CNN 架构
我根据 VGG 16 号做了一个模型。
使用 4 个卷积块。每个像 Conv->Conv->统筹。然后是两个完全连接的层。
卷积的思想是让过滤器选择和修改属性。为此,我们使用(8,6410,1)形状来处理每个注册表。这样,CNN 就像威胁图像一样威胁数据。要更深入地检查架构,请检查我的 GitHub(链接在介绍和结论中)。
使用的批量大小为 1,学习率为 0.0001,he_uniform 初始化器。batch_size 可以更大。然而,由于硬件限制,三个对我来说更高。
模特培训
训练两个模型,一个用于故障检测,另一个用于故障检测和隔离。因此,定义了同一数据集的两种结构。这些结构描述如下:
- 结构 1 :用于实验检测系统是否有故障。它包含 12586 条记录,其中 7480 条有缺陷,5106 条无缺陷;
- 结构 2 :在实验中用于检测和隔离故障。它包含 5106 条无缺陷记录、2170 条失败 2 记录、1573 条失败 3 记录、1702 条失败 4 记录和 2035 条“其他”失败记录,总共 12586 条记录。
所有模型都是用 Python 3.6 和 Sk-learn 0.20.2 编写的,在 Ubuntu 18.04 上运行,采用英特尔 i7–7700 HQ、16Gb 内存、GTX 1050Ti。
为了运行算法,数据集被分成训练集和测试集。对于每个实验,20%的注册表用于测试,80%用于训练。
模型评估
度量标准需要充分的解释。在所讨论的案例研究中,最大限度地减少误报的数量至关重要,因为这将涉及派遣技术人员执行不必要的维护。而假阳性意味着接收到对某个故障模块的投诉。那么,从财务角度来看,召回的相关性大于精确度。
对于 88.42 的精度和 87.96 的召回,故障检测的混淆矩阵可以如下所示:
对于 54.98 的精度和 52.57 的召回,用于故障检测和隔离的混淆矩阵可以如下所示:
对于这两个模型,都存在高方差和高偏差。如果架构更深入或者改变一些超参数,模型会有更好的结果。或者,甚至执行更广泛的数据预处理。
结论
正如所提出的,这些模型可以检测和隔离车队跟踪模块上的故障。然而,评价性指标不适合使用模型。在我的另一篇文章中,使用来自系统的知识,可以在公司实现更高的指标来远程诊断他们模块上的故障。
所采用的方法的局限性包括模型不能发现未被映射的故障,因此任何未被学习的故障将被错误地分类为已知故障之一。
和文章中一样,这里没有任何代码,你可以在我的 GitHub 库中随意查看。
故障诊断模型检测和隔离车队跟踪模块上的故障。…
github.com](https://github.com/lmeazzini/Tracker-fault-diagnosis)
参考
[1] D. van Schrick,“对
监督、故障检测和诊断领域术语的评论”,IFAC 会议录
卷,第 30 卷,第 18 期,第 959-964 页,1997 年。
[2] D. Wang 和 W. T. Peter,“基于移动平均磨损退化指数和一般
序贯蒙特卡罗方法的
泥浆泵预测”,机械系统和
信号处理,第 56 卷,第 213–229 页,2015 年。
机器学习——不要仅仅依赖你的大学
正式课程和网络课程之间的巨大差异
Photo by Andrew Neel on Unsplash
在大学学习的问题是
将机器学习整合到预测分析中一直是高需求的,这为企业提供了竞争优势。这个热门话题受到了全世界大学生的高度关注。然而,在大学中正式介绍机器学习的概念和技术可能会证明对普通本科生来说极其令人生畏。
在麦吉尔大学的本科冬季交流期间,我报名参加了他们的 应用机器学习 课程。是的,我报名参加研究生水平的课程是愚蠢的!它始于线性回归的引入,因为它是最基本的机器学习算法。导师做了很好的工作,试图解释算法背后的直觉。
但在介绍了算法背后的大量数学之后,最后一击是“哦,顺便说一下,作业 1 已经完成了,10 天后到期,鼓励你用 Python 来完成它,下节课见。”
我怎么可能在 10 天内学会 L2 正则化和用随机梯度下降拟合回归模型的概念!我甚至不知道如何用 Python 编码!
我已经被第二次演讲淹没了,我立即退出。在那门课程中,需要扎实的统计学、微积分、线性代数和编程背景知识。果然,在第一次介绍性讲座中,这四个要素立即被引入。
我是许多学生中的一员,通过寒暑假学习并忘记了大部分的数学概念,这一点也没有帮助。
在线课程的发现
我不允许一点小挫折摧毁我对数据科学的兴趣,我开始在网上搜索对“足够感兴趣”的公众足够友好的教授机器学习的资源。有很多很棒的在线课程,有些是免费的,有些是付费的,有些是正式认证的。我选择付费课程是因为我从提供付费课程的老师那里找到了真正的激情。
我报名参加的在线课程是基里尔·叶列缅科的 机器学习 A-Z:数据科学中的动手 Python&R。
Kirill 在课程中介绍的所有算法中提供了易于理解的直觉,即使是高中生也能理解,这方面做得非常出色。所有介绍的算法都辅以实际操作的编码会话,使用接近真实生活的数据,帮助我可视化并理解其意义。
受到激励,我重新注册了我家乡大学的另一门机器学习课程,并发现随着我直觉基础的建立,这门课程变得容易多了。
在接下来的部分中,我想提供一些我在大学里所学和所学之间的对比。我希望这篇文章能够激励那些正在考虑将他们的学习延伸到大学之外的人,或者在机器学习领域寻求进一步知识的工作专业人员。
**免责声明:**以下比较仅限于 2 个来源提供的学习资料:我的大学和 Kirill 的机器学习课程。从今以后,我为下面这篇文章中的偏颇观点道歉,这不应该被视为所有正式学习和在线学习中的普遍现象。
那么有什么不同呢?
为了说明正式学习和在线课程之间的区别,让我们看看几个常见的机器学习概念,并看看它在我的大学中是如何解释的,与 Kirill 的课程是如何处理的。以下列表是我在大学时发现很难理解的东西的快照,但在我观看 Kirill 的视频时完全被揭穿了。
线性回归
这就是我的大学试图在他们的演讲幻灯片中解释线性回归的方式:
Throwing in mathematical notations as a general introduction to linear regression makes it difficult to understand (Credits: Pun Chi Seng Patrick)
对有经验的人来说,这是小事一桩。但是对于任何一个刚刚开始学习统计学和微积分的人来说,消化这些信息需要相当长的时间,尤其是在缺乏好的视觉效果的情况下。
另一方面,在线课程通过一步一步的动画解释直接切入业务问题:
Explaining the relationship of working experience and salary makes the intuitive understanding of simple linear regression so much easier (Credits: Kirill Eremenko)
一个简单的 3 分钟视频解释了普通最小二乘法背后的直觉,足以让任何人明白它的意义。
使用 R 平方统计评估线性回归模型
R 平方统计,也称为拟合优度,广泛用于评估线性回归模型。下面红色的句子完美地总结了 R 平方统计的使用:
Explaining the use of R-squared statistics to evaluate generalized linear regression models ((Credits: Pun Chi Seng Patrick)
然而,我发现从 Kirill 的课程中呈现的视觉效果来理解要容易得多:
A visual representation of R-squared statistics presented by Kirill (Credits: Kirill Eremenko)
通俗地说,R 平方统计就是将最佳拟合线与“最差拟合线”进行比较,后者是数据的恒定平均值。残差平方和越低,R 平方值越高。调整后的 R 平方增加了与模型无关的额外预测因子的惩罚,适用于多元线性回归模型。
支持向量最大间隔分类器
在我大学的机器学习课程中,理解支持向量机的概念显然是最难的任务。沉重的数学的轰炸,让我们似乎不可能耐着性子一口气理解概念。请看下面关于最大间隔分类器的摘录信息:
The heavy math behind the computation of a maximal margin classifier (Credits: Pun Chi Seng Patrick)
现在,相比之下,我们看到了基里尔的一个简单插图是如何抓住最大间隔分类器的直觉的妙处:
Credits: Kirill Eremenko
好吧,你明白了,我还可以做很多比较,但是我会让你不无聊的!到现在为止,你可能认为你从网上学习中会比在大学里接受正规教育受益更多。但就个人而言,我觉得完成大学的机器学习课程比仅仅完成 Kirill 的课程更有就业价值。
但是正规学习也没那么差吧?
没有最终项目,机器学习课程是不完整的。Kirill 的课程用 Python 和 R 语言提供了易于理解的直觉和示例代码,供学习和遵循。完成他的教程让我很满意,我可以用一系列机器学习算法进行预测。
但这还不够。
期末专题评分的重要性
正式学习和网上学习的区别在于一个分等级的期末项目。我们的任务是从公开可用的数据集设计一个机器学习问题。下面的流程图强调了处理与真实世界应用非常相似的良好机器学习项目的过程:
我们在公共数据集建模方面的实践经验得到了来自教授和助教的项目咨询和支持的补充,以个性化的方式丰富了我们的学习。在项目期间,我很高兴我有一个来自 Kirill 课程的机器学习脚本集,可以用于数据预处理和建模。
习惯重数学的重要性
从统计推断到超参数调优,高性能模型的神奇之处在于对背后复杂数学的深刻理解。
诸如:“我的 ANN 模型的最佳学习速率和权重衰减是多少?”以及“一个好的随机森林回归模型在不过度拟合的情况下所需的最优树数是多少?“只有具备足够的数学知识才能回答。
简单地
The demand of data scientist to provide business and product intelligence is on the rise (Source: PredictiveAnalyticsWorld)
无论是建立推荐系统,还是在人工智能产品和服务中实现计算机视觉,机器学习算法的实施都在不断增加。有利可图的人工智能行业激起了大学的兴趣,提供数据科学专业学位的大学开始涌现。以我大学的 最近提供的数据科学学位 为例。
随着人们越来越意识到它的需求,他们开始冒险进入未知领域。没有意识到数学和计算机科学完美融合背后的技术细节,普通大学生很自然地会在这门课程中苦苦挣扎。
机器学习技术应用的简单性可以被许多可用的在线课程所揭穿。不幸的是,严酷的事实是,几乎没有雇主在乎你是否有一个勉强被认可的在线课程认证。你的正式资格永远是人力资源主管优先考虑的。尤其是如果人力资源主管没有技术倾向的话。
另一个严峻的事实是,大多数数据科学职位要求高等教育才能被考虑。对许多人来说,完成一门涉及机器学习的本科课程已经被证明是一个挑战。但是我希望这篇文章可以激励读者减少对正规教育的依赖,并知道有大量非常有用的资源可以补充你在数据科学和机器学习方面的学习。
如果你有兴趣了解如何成为一名优秀的数据分析师,我认为大学需要更加重视这一点,你可以看看我在这里写的另一篇文章:
从数据收集、预处理、转换到非技术交流,这些都是非常重要的…
towardsdatascience.com](/4-important-things-universities-need-to-teach-about-data-science-analytics-6ab5988639ca)
感谢您的时间,我希望这篇文章在某种程度上让读者受益,如果您有任何问题,请随时联系我!
机器学习工程师、数据科学家以及他们各自的角色。
在过去的十年里,诸如“数据科学”、“大数据”、“数据湖”、“机器学习”、“人工智能”等术语已经上升到日常词汇的最前沿(有时又回落),用于最广泛的各种行业。然而,不管它们的广泛使用(或者正因为如此!)对于其中许多术语的含义,似乎没有什么共识。我不希望在一致的术语上进行长时间的争论,但是有两个经常使用的术语让我特别感兴趣:“数据科学家”和“机器学习工程师”。
在最广泛的意义上,这两个术语都可以理解为指“构建机器学习解决方案的技术熟练的人”。“数据科学家”是一个术语,多年来,它已经成为一种多面手数学家或统计学家,他们也可以编写一些代码,并知道如何解释和可视化数据。最近,“机器学习工程师”这个术语已经和软件开发人员联系在一起了,他们已经学会了一些数学。
虽然这些解释确实有些道理,但我觉得它们都不是特别有用。因此,冒着增加困惑的风险,我想通过两个勇敢的冒险故事来说明我对这些角色的理解——一个是科学家,另一个是工程师——他们前往一个未知的、可能是无尽的沙漠,寻找石油…
根据他们的任务,工程师和科学家有不同的装备。
这位科学家轻装旅行。他有一个背包、一个指南针、一把铲子和一些简单但精确的测量设备。他对沙漠进行了几次突袭,虽然不是很深入,但是足够深入到可以评估哪个方向看起来最有希望。在进行测量并用铁锹挖了几个洞后的几天内,他想到了可能有石油的地方。
另一方面,工程师带着笨重而精密的机器。目前,他并不关心哪里能找到石油。然而,一旦找到了,他将不得不运输它,所以他花了几天时间设计管道的蓝图。
合作让两个探索者结合他们的优势,变得更有效率。
几天后,探险者们进行了商议,科学家宣布他将在接下来的几天里进行更深入的探索,因为他现在更加确定在哪里可以找到石油。当科学家出发时,工程师启动他的机器,跟随科学家的脚步,开始建造第一段管道。最终他追上了科学家,他发现了一口小井!
他们一起在该位置安装了一个钻机,并将其与管道连接起来。这条管道使科学家的工作更加高效,尽管他们还没有找到真正的主井,但这口小井已经可以带来一些利润,工程师可以用它来测试他的管道。
经过几个月的顺利合作,两位探索者都准备好了第一次重大突破。
为了准备下一阶段的探险,工程师建造了一个轻型石油钻机,并指导科学家如何使用。有了这种专门的钻头,科学家现在可以在没有工程师在场的情况下开井了。有一段时间,科学家继续寻找新井,而工程师继续将它们连接到管道上。
接下来,工程师现在还设计了轻型管道,科学家可以在没有工程师帮助的情况下将其连接到管道上。这使得科学家大大加快了他的探索速度,同时也让工程师有时间重新设计管道的大部件,从而使管道更加稳定和高效,
同样,科学家为工程师设计了一套新的标准化测量方法,并将其嵌入到主轮毂的测量协议中,这样科学家就不再需要前往钻井现场监控其性能。
经过几个月的艰苦工作,他们到达了寻找的大油井。他们一起将油井连接到管道上,并安装复杂的测量设备。到现在为止,例行公事已经很好地解决了。测量,钻孔,连接,泵送,测量。完成了。很快,大油井开始喷涌。
过了一段时间,他们分道扬镳——工程师留在现场,而科学家在场外为项目做贡献。
不久之后,科学家打包回家。现场不再需要他,但他仍然可以分析油井产生的测量结果。
工程师多呆一会儿。他对整个系统运行良好还不满意。一组操作员来了,他们一起解决了所有剩余的问题。然后,工程师将系统交给操作员,然后回家,并承诺如果出现问题会回来。
科学家和工程师的重聚。
我们的两个探险者很快又见面了。他们回忆起他们小小的沙漠冒险,并开始为他们的下一次冒险制定计划——显然,北极可能有石油,他们准备去发现!
数据科学家和机器学习工程师的角色不同。
也许你能够从上面的故事中认识到成功的机器学习项目的一些要素。
我选择了两个探险家的这个小寓言,因为我相信机器学习——尽管它在过去的五到十年里取得了巨大的进步——仍然是一个很大程度上需要探索未知领域的领域。我相信探索精神(快速原型)和五年前一样重要,但是在项目开始时就开始为生产系统(快速扩展)打基础也变得越来越重要。
对于我的两个探索者,我选择了一名(数据)科学家和一名(机器学习)工程师来说明他们合作实现快速有效的价值交付的重要性。
毫无疑问,这两个角色有许多不同的定义,但对我来说,关键的定义特征是,数据科学家会问:“解决这个问题的最佳算法是什么?”并试图通过快速测试各种假设(寻找油井)来回答这个问题。另一方面,机器学习工程师会问:“帮助我们解决问题的最佳系统是什么?”并试图通过构建一个自动化的过程(构建一条输油管道)来回答这个问题,这个过程可以用来加速假设的测试。
尽管数据科学家和机器学习工程师的角色不同,但他们的合作对机器学习项目至关重要。
无论这两个定义是否 100%准确,重要的是当两个有才华的专业人士以这种心态走到一起时,随之而来的合作。在我的例子中,数据科学家寻找新的模型架构来尝试;衡量业绩的新方法;要包括的新数据源等。,而机器学习工程师则在寻找将数据科学家的工作整合到可扩展系统中的方法。随着系统的扩展,数据科学家变得更加高效,因为他有更好的工具可以使用。机器学习工程师变得更加有效,因为他构建的工具被用来交付越来越多有价值的结果。
机器学习工程师写软件,数据科学家写脚本。
这两种职业之间的差异也可以从他们写的代码中看出。当然,两个演员都得是优秀的程序员。不仅仅是机器学习工程师必须能够编写高质量的代码。当然,数据科学家不一定要能够构建复杂的软件系统,但他或她必须能够构建结构清晰、文档完善且易于维护的代码!
也就是说,对于数据科学家来说,重点将是看到快速的结果,而不是构建可持续的软件。因此,数据科学家的首选工具——因为整个事情通常在 Python 世界中进行——将是广泛使用 Jupyter 笔记本,它积极支持探索性的工作方式;这种工作的最终产品通常是原型脚本。
然而,机器学习工程师编写了软件。我怎么强调这一点都不为过。(如果你在机器学习方面非常优秀,并且正在构建结构清晰、文档完善且易于维护的脚本,那么你就是我们在 Alexander Thamm 的项目中能够找到的最好的数据科学家——而不是机器学习工程师!).机器学习工程师专注于构建可以快速扩展的软件。Python 世界中也会出现很多这种情况,这意味着作为首选工具,通常会使用像 PyCharm 这样的 ide。(然而,它确实超越了 Python,因为伸缩还意味着知道如何使用工具来编排用于模型训练的资源,以及将训练好的模型提供给最终用户系统,但这是另一个时间的讨论)。
项目的不同阶段需要机器学习工程师和数据科学家的不同参与。
最后要谈的是项目的阶段和谁在什么时候参与。如果我们考虑一个经历“假设”阶段的项目进展;“概念证明”;“原型”;“生产”——那么很容易说前两个是数据科学家的领域,而后两个是机器学习工程师的领域。我只是部分同意。
科学家和工程师站在沙漠边缘,凝视着远方,想知道那里是否有石油:这是“假设”阶段。科学家在沙漠中跑来跑去,用铁锹挖许多小洞,以观察石油的最初迹象,而工程师则为他的管道绘制蓝图,这就是我所说的“概念证明”。一条成熟的管道正在建设,第一口正在开采的小井就是我所说的“原型”。以及由一个我认为是“生产”的操作员团队维护的大规模、完全精炼和高效的系统。
机器学习工程师和数据科学家在整个项目中至关重要。
因此,也许看待这个问题的正确方式是认识到每个阶段都需要来自两个角色的输入,但是这些输入看起来会发生变化。特别是在开始时,机器学习工程师将非常依赖于数据科学家所做的探索,后来数据科学家将非常依赖于机器学习工程师构建的工具。但是每一个都将始终保持相关性——事实上至关重要。
在最后,两人都将继续下一件事,这可能是又一次探索之旅——这次是去北极?
机器学习可解释性
kaggle.com 微课综述
最近,我在 kaggle.com 上做了微课机器学习可解释性。我强烈推荐这门课程,因为我学到了很多有用的方法来分析一个训练过的 ML 模型。为了对所涉及的主题有一个简要的概述,这篇博文将总结我的学习。
以下段落将解释排列重要性、部分相关图和 SHAP 值等方法。我将使用著名的泰坦尼克号数据集来说明这些方法。
Photo by Maximilian Weisbecker on Unsplash
开始之前
我将要描述的方法可以用于任何模型,并且在模型适合数据集之后应用。以下回答的问题分别涉及上述在线课程中的一个部分。泰坦尼克号数据集可以用来训练一个分类模型,该模型预测泰坦尼克号上的乘客是幸存还是死亡。我在这个任务中使用了一个简单的决策树,没有优化它,也没有平衡数据,等等。它只是为了说明方法而被训练。分析代码可以在这个 GitHub 库上找到。
哪些变量对存活率影响最大?
对于这个问题,本课程建议采用排列重要性法。这种方法只是简单地取一列数据,并改变它的值,而保持其他列不变。利用改变的数据,该方法计算模型的性能。与原始数据相比,性能下降得越多,混洗列中的特征对于模型就越重要。为了找到所有特性的重要性,对所有列逐一进行这种操作。使用 eli5 python 包,我为我们的数据集找出了以下数字。
Importance of each feature for the survival on the Titanic
正如我们所见,泰坦尼克号幸存的最重要特征是性别,其次是年龄和票价。
这些数字只告诉我们哪些特征是重要的,而不是它们如何影响预测,例如,我们不知道是女性还是男性更好。为了找出特征是如何影响结果的,本课程建议使用部分相关图。
这些变量是如何影响存活率的?
找出变量如何影响结果的一个方法是在线课程建议的部分相关图。此方法获取数据集的一行,并重复更改一个要素的值。对不同的行执行多次,然后进行汇总,以找出该特性如何在很大范围内影响目标。python 包 pdpbox 可用于创建一个图表,显示使用不同值时的结果。对于我们的数据集,绘制“年龄”对目标的部分依赖关系如下所示。
Partial dependence plot for age on survival on Titanic
这个情节以一种非常好的方式表明,随着年龄的增长,在泰坦尼克号上幸存的概率会降低。尤其是 20 岁到 30 岁之间,在泰坦尼克号上可不是个好年龄。线周围的蓝色区域是线的置信度。这表明其他因素也对某人是否幸存起着很大的作用。幸运的是 pdpbox 库提供了二维图来显示两个特征对结果的相互作用。让我们看看年龄是如何与乘客乘坐的舱位相互作用的。
Partial dependence plot for age-class interaction on survival on Titanic
交互图显示,具有特定年龄的班级确实会对存活率产生影响,例如,20 至 30 岁之间的三等生的存活率低于 0.3,而拥有一等票的同龄人的存活率约为 0.5。
让我们看看三等舱的那个 30 岁的乘客,看看她的情况如何影响她的生存。为了分析特定的数据样本,本课程建议使用 SHAP 值。
变量如何影响特定乘客的生存?
SHAP 值用于显示单个用户的特征的效果。这里,该方法也采用一个特征并将该值与该特征的基线值进行比较,而不改变其他特征。所有特征都是如此。最后,该方法返回总和为 1 的所有 SHAP 值。有些价值观对结果有正面影响,有些价值观对结果有负面影响。我们特定的 30 岁乘客具有以下 SHAP 值。
Showing parameters of a specific passenger influencing the output
影响最大的有她是女性的事实,票价价格等等。蓝色值显示她乘坐的是三等舱,对结果有负面影响。
概要剧情
为了显示所有乘客的 SHAP 值汇总,我使用了如下所示的汇总图。
Summary plot of features importance towards the survival on the Titanic
该图按颜色显示特征值,红色为最大值,蓝色为最小值。因此,分类特征“性”只有两种颜色。水平位置是对样本结果的特定影响,垂直位置显示特征重要性。可以看出,就生存而言,女性大多具有积极影响,而男性大多具有消极影响。然而,例如,“费用”特征就不太明显。它的大部分值分布在 x 轴上。
依赖贡献图
为了说明在给定乘客性别的情况下,年龄对实际结果的影响,依赖贡献图就派上了用场。下面的图显示了这种贡献。
Interaction of Age and Sex towards contribution to survivals on the Titanic
随着女性乘客年龄的增加,我们看到了一个小的下降趋势(红点)。不过,这些点主要出现在正值 0 以上。如前所述,男性乘客大多低于 0,尤其是 20 到 30 之间的值。
结论
出于多种原因,我真的很喜欢上这门课。然而,对于每个数据分析师和科学家来说,分析数据或模型本身也是非常重要的。特别是,当考虑深度神经网络或其他难以遵循决策的黑盒方法时,引入的方法肯定会增加价值。
12 分钟解释机器学习
在过去的两年里,我接触了许多不同行业的客户,包括医疗保健、政府、金融、制造、电信、非营利等。,我被问到的第一个问题仍然是:我如何开始机器学习和人工智能?
这是我将制作的机器学习基础系列的第一集。不需要技术/数学/统计背景。
视频中提到的一些问题包括:
- 什么是机器学习?
- 为什么机器学习对企业如此重要?
- 机器学习是如何工作的?
- 在机器学习算法的引擎盖下会发生什么?
关于作者
scar D. Lara Yejas 是高级数据科学家,也是 IBM 机器学习中心的创始成员之一。他与世界上一些最大的企业密切合作,将 ML 应用于他们的特定用例,包括医疗保健、金融、制造、政府和零售。他还为 IBM 大数据产品组合做出了贡献,特别是在大规模机器学习领域,是 Apache Spark 和 Apache SystemML 的贡献者。
scar 拥有南佛罗里达大学的计算机科学和工程博士学位。他是《人类活动识别:使用可穿戴传感器和智能手机》一书的作者,并发表了大量关于大数据、机器学习、以人为中心的传感和组合优化的研究/技术论文。
机器学习!= .适合()
像所有初学者一样,当我开始机器学习之旅时,我犯了太多的错误。这是同样的故事。要学的东西很多。大肆宣传。大量的技术术语。涵盖了大量的先决条件等等。
似曾相识?我知道。
Photo by David Paschke on Unsplash
对我来说,当时机器学习只涉及复杂的数学,没有别的。都是关于越来越复杂的模型。我在学习所有的数学细节,并欺骗自己我正在学习,但事实上,情况并非如此。
当时我脑海中有一个事实上的规则,如果你想提高性能或减少误差指标,就切换到更复杂的模型。并且一直做下去,直到性能提升或者损耗降低。
说说结果?挫败感!
事情没有按照我的期望进行。在从线性回归切换到具有 RBF 核的支持向量机回归机之后,我一直在等待性能大幅提升。
但现实世界中事情并不是这样的。
这样做了很多次后,我意识到这里有什么地方出了问题,我需要找出原因。
我了解到:
垃圾进= >机器= >垃圾出
机器学习!= .fit()
不要犯同样的错误。
机器学习还有很多东西。
不仅仅是复杂的模型。不仅仅如此。
以下是机器学习流程中你也应该关注的三个主要步骤:
数据清理
在现实世界的项目中,你不会每次都得到那个干净的.csv
文件。更常见的情况是,您必须从多个来源收集数据,清理它们,然后连接它们,并进一步检查一致性和重复。
数据清理不仅仅涉及填充缺失值。除此之外还有很多事情。下面列出了其中的一些:
- 检查整个数据的一致性
- 选择与您的问题相关的数据子集。
- 异常值处理
剔除离群值不是解决办法。有时,您需要深入挖掘,找出这个记录值行为不同的原因。根据你的问题陈述,在真实案例中可能吗?然后,进行相应的处理。
- 重命名列名以提高可解释性
- 删除重复记录
- 处理缺失值
- 以正确的格式存储抓取的数据
还有更多…
数据分析和可视化
如果你不了解你的数据,你就不能用它做任何事情。当然
询问与业务问题相关的问题,并通过代码了解解决方案。有时,在现实世界中,任务不是建立一个最先进的模型来预测一些事情。而是分析数据,找出隐藏的可以让业务受益的洞察,用简单的语言把洞察呈现出来。
例句:假设你在亚马逊工作,你知道客户在平台上进行的每笔交易的大部分细节。
你可以问的问题:
- 一天中大多数交易发生的高峰时间是什么时候?
- 亚马逊上卖得最多的是什么类型的产品?
- 收视率多少对购买有影响吗?
还有更多…
明白了吗?你的目标是找出可以帮助亚马逊获得更多销售的见解。
你的问题随着你的问题陈述的改变而改变。
即使你的目标是预测某事,如果不知道你的数据,你也不能做得很好。
不仅如此,数据分析和可视化还有助于您进行下一步工作,即特征工程
为什么大家都说:认识你自己,背后是有原因的。
特征工程
它是从原始特征集中提取新特征或转换现有特征集以使其适用于机器学习模型的过程。
为什么选择特色工程?
你需要明白:具有良好特性集的简单模型比具有不良特性集的复杂模型表现更好。
不理解数据和你的问题陈述,你就不能进行特征工程。
领域知识在特征工程中起着非常重要的作用。你需要找出以前在这个空间里做过的工作。阅读文献,然后结合你的发现构建新的特征。如果你有这个闲心,最好和领域专家谈谈。
特征选择:从原始集合中选择重要特征的子集。它也属于特征工程,sklearn 有关于它的大量文档。在这里 看完 。
创建一个简单的基线模型,这样你就可以在加入新特性后比较你的结果,看看它们是否有帮助。记住:这是一个迭代的过程。
投入时间构建新特性远比等待一个复杂的模型开始工作要好。
关键教训:不要爱上复杂的模型,而要爱上数据。各有侧重。都是有联系的。
希望你喜欢这篇文章,并学到一些新东西。将这些知识融入到你的新项目中,并与刚刚起步的人分享这篇文章!
关注我更多这样的文章。和平与力量。
用于异常检测和状态监控的机器学习
从数据导入到模型输出的分步教程
我上一篇关于异常检测和条件监控的文章收到了很多反馈。我收到的许多问题涉及技术方面以及如何建立模型等。由于这个原因,我决定写一篇后续文章,详细介绍所有必要的步骤,从预处理数据到构建模型和可视化结果。
对于异常检测和状态监控的介绍,我建议首先阅读我关于这个主题的原始文章。这为如何利用机器学习和数据驱动分析从传感器数据中提取有价值的信息提供了必要的背景信息。
当前的文章主要集中在技术方面,包括建立基于多元统计分析和自动编码器神经网络的异常检测模型所需的所有代码。
下载数据集:
为了复制原始文章中的结果,首先需要从 NASA 声学和振动数据库下载数据集。有关实验和可用数据的更多信息,请参见下载的 IMS 轴承数据自述文件。
每个数据集由单独的文件组成,这些文件是以特定间隔记录的 1 秒振动信号快照。每个文件由 20.480 个点组成,采样率设置为 20 kHz。文件名表示收集数据的时间。数据文件中的每条记录(行)都是一个数据点。较大的时间戳间隔(显示在文件名中)表示在下一个工作日恢复实验。
导入包和库:
第一步是为分析导入一些有用的包和库:
*# Common imports*
**import** **os**
**import** **pandas** **as** **pd**
**import** **numpy** **as** **np**
**from** **sklearn** **import** preprocessing
**import** **seaborn** **as** **sns**
sns.set(color_codes=**True**)
**import** **matplotlib.pyplot** **as** **plt**
%**matplotlib** inline
**from** **numpy.random** **import** seed
**from** **tensorflow** **import** set_random_seed
**from** **keras.layers** **import** Input, Dropout
**from** **keras.layers.core** **import** Dense
**from** **keras.models** **import** Model, Sequential, load_model
**from** **keras** **import** regularizers
**from** **keras.models** **import** model_from_json
数据加载和预处理:
假设随着时间推移,齿轮逐渐退化,所以在下面的分析中,我们每 10 分钟使用一个数据点。通过使用每个文件中 20.480 个数据点的振动记录的平均绝对值,汇总每个 10 分钟的数据点。然后,我们将所有内容合并到一个数据帧中。
在下面的例子中,我使用了来自第二档齿轮故障测试的数据(参见 readme 文档以获得关于该实验的更多信息)。
data_dir = '2nd_test'
merged_data = pd.DataFrame()
**for** filename **in** os.listdir(data_dir):
print(filename)
dataset=pd.read_csv(os.path.join(data_dir, filename), sep='**\t**')
dataset_mean_abs = np.array(dataset.abs().mean())
dataset_mean_abs = pd.DataFrame(dataset_mean_abs.reshape(1,4))
dataset_mean_abs.index = [filename]
merged_data = merged_data.append(dataset_mean_abs)
merged_data.columns = ['Bearing 1','Bearing 2','Bearing 3','Bearing 4']
加载振动数据后,我们将索引转换为日期时间格式(使用遵循惯例的,然后在将合并的数据集保存为. csv 文件之前,按时间顺序按索引对数据进行排序
merged_data.index = pd.to_datetime(merged_data.index, format='%Y.%m.**%d**.%H.%M.%S')merged_data = merged_data.sort_index()
merged_data.to_csv('merged_dataset_BearingTest_2.csv')
merged_data.head()
Resulting dataframe: “merged_data”
定义训练/测试数据:
在建立模型之前,我们需要定义训练/测试数据。为此,我们执行一个简单的分割,在数据集的第一部分(应该代表正常运行条件)上进行训练,并在导致轴承故障的数据集的其余部分上进行测试。
dataset_train = merged_data['2004-02-12 11:02:39':'2004-02-13 23:52:39']
dataset_test = merged_data['2004-02-13 23:52:39':]dataset_train.plot(figsize = (12,6))
Training data: Normal operating conditions
标准化数据:
然后我使用 Scikit-learn 的预处理工具来缩放模型的输入变量。“最小最大缩放器”只是将数据重新缩放到范围[0,1]内。
scaler = preprocessing.MinMaxScaler()
X_train = pd.DataFrame(scaler.fit_transform(dataset_train),
columns=dataset_train.columns,
index=dataset_train.index)*# Random shuffle training data*
X_train.sample(frac=1)
X_test = pd.DataFrame(scaler.transform(dataset_test),
columns=dataset_test.columns,
index=dataset_test.index)
异常检测的 PCA 型模型;
由于处理高维传感器数据通常具有挑战性,因此有几种技术可以减少变量的数量(降维)。主要技术之一是主成分分析 (PCA)。关于更详细的介绍,我参考了我关于这个主题的原始文章。
作为初步尝试,让我们将传感器读数压缩到两个主要分量。
**from** **sklearn.decomposition** **import** PCApca = PCA(n_components=2, svd_solver= 'full')X_train_PCA = pca.fit_transform(X_train)
X_train_PCA = pd.DataFrame(X_train_PCA)
X_train_PCA.index = X_train.index
X_test_PCA = pca.transform(X_test)
X_test_PCA = pd.DataFrame(X_test_PCA)
X_test_PCA.index = X_test.index
马哈拉诺比斯距离度量:
马氏距离广泛用于聚类分析和分类技术。为了使用 Mahalanobis 距离将测试点分类为属于 N 个类别之一,首先估计每个类别的协方差矩阵,通常基于已知属于每个类别的样本。在我们的例子中,由于我们只对“正常”与“异常”的分类感兴趣,我们使用只包含正常操作条件的训练数据来计算协方差矩阵。然后,给定一个测试样本,我们计算到“正常”类的 Mahalanobis 距离,如果距离超过某个阈值,则将测试点分类为“异常”。
关于这些技术方面的更详细的介绍,你可以看看我以前的文章,它更详细地涵盖了这些主题。
定义 PCA 模型中使用的函数:
计算协方差矩阵:
**def** cov_matrix(data, verbose=**False**):
covariance_matrix = np.cov(data, rowvar=**False**)
**if** is_pos_def(covariance_matrix):
inv_covariance_matrix = np.linalg.inv(covariance_matrix)
**if** is_pos_def(inv_covariance_matrix):
**return** covariance_matrix, inv_covariance_matrix
**else**:
print("Error: Inverse of Covariance Matrix is not positive definite!")
**else**:
print("Error: Covariance Matrix is not positive definite!")
计算马哈拉诺比斯距离:
**def** MahalanobisDist(inv_cov_matrix, mean_distr, data, verbose=**False**):
inv_covariance_matrix = inv_cov_matrix
vars_mean = mean_distr
diff = data - vars_mean
md = []
**for** i **in** range(len(diff)):
md.append(np.sqrt(diff[i].dot(inv_covariance_matrix).dot(diff[i])))
**return** md
检测异常值:
**def** MD_detectOutliers(dist, extreme=**False**, verbose=**False**):
k = 3\. **if** extreme **else** 2.
threshold = np.mean(dist) * k
outliers = []
**for** i **in** range(len(dist)):
**if** dist[i] >= threshold:
outliers.append(i) *# index of the outlier*
**return** np.array(outliers)
计算将数据点分类为异常的阈值:
**def** MD_threshold(dist, extreme=**False**, verbose=**False**):
k = 3\. **if** extreme **else** 2.
threshold = np.mean(dist) * k
**return** threshold
检查矩阵是否正定:
**def** is_pos_def(A):
**if** np.allclose(A, A.T):
**try**:
np.linalg.cholesky(A)
**return** **True**
**except** np.linalg.LinAlgError:
**return** **False**
**else**:
**return** **False**
设置 PCA 模型:
从两个主要部分定义训练/测试集:
data_train = np.array(X_train_PCA.values)
data_test = np.array(X_test_PCA.values)
根据训练集中的数据计算协方差矩阵及其逆矩阵:
cov_matrix, inv_cov_matrix = cov_matrix(data_train)
我们还计算训练集中输入变量的平均值,因为这在以后用于计算测试集中数据点的 Mahalanobis 距离
mean_distr = data_train.mean(axis=0)
使用协方差矩阵及其逆矩阵,我们可以计算定义“正常条件”的训练数据的 Mahalanobis 距离,并找到阈值以将数据点标记为异常。然后可以计算测试集中数据点的 Mahalanobis 距离,并将其与异常阈值进行比较。
dist_test = MahalanobisDist(inv_cov_matrix, mean_distr, data_test, verbose=**False**)
dist_train = MahalanobisDist(inv_cov_matrix, mean_distr, data_train, verbose=**False**)
threshold = MD_threshold(dist_train, extreme = **True**)
标记异常的阈值:
如果满足正态分布输入变量的假设,到分布质心的马氏距离的平方应遵循χ2 分布。这也是上述用于标记异常的“阈值”计算背后的假设。由于这种假设在我们的情况下不一定成立,因此可视化 Mahalanobis 距离的分布以设置标记异常的良好阈值是有益的。再次,我参考我的前一篇文章,获得关于这些技术方面的更详细的介绍。
我们首先想象马哈拉诺比斯距离的平方,它应该理想地遵循χ2 分布。
plt.figure()
sns.distplot(np.square(dist_train),
bins = 10,
kde= **False**);
plt.xlim([0.0,15])
Square of the Mahalanobis distance
然后想象马哈拉诺比斯距离本身:
plt.figure()
sns.distplot(dist_train,
bins = 10,
kde= **True**,
color = 'green');
plt.xlim([0.0,5])
plt.xlabel('Mahalanobis dist')
从上述分布来看,计算出的用于标记异常的阈值 3.8 似乎是合理的(定义为距分布中心的 3 个标准偏差)
然后,我们可以保存 Mahalanobis 距离,以及数据帧中训练和测试数据的阈值和“异常标志”变量:
anomaly_train = pd.DataFrame()
anomaly_train['Mob dist']= dist_train
anomaly_train['Thresh'] = threshold
*# If Mob dist above threshold: Flag as anomaly*
anomaly_train['Anomaly'] = anomaly_train['Mob dist'] > anomaly_train['Thresh']
anomaly_train.index = X_train_PCA.indexanomaly = pd.DataFrame()
anomaly['Mob dist']= dist_test
anomaly['Thresh'] = threshold
*# If Mob dist above threshold: Flag as anomaly*
anomaly['Anomaly'] = anomaly['Mob dist'] > anomaly['Thresh']
anomaly.index = X_test_PCA.index
anomaly.head()
Resulting dataframe for the test data
基于计算的统计数据,任何高于阈值的距离都将被标记为异常。
我们现在可以将数据合并到单个数据帧中,并将其保存为. csv 文件:
anomaly_alldata = pd.concat([anomaly_train, anomaly])
anomaly_alldata.to_csv('Anomaly_distance.csv')
在测试数据上验证 PCA 模型:
我们现在可以绘制计算的异常度量(Mob dist),并检查它何时超过异常阈值(注意对数 y 轴)。
anomaly_alldata.plot(logy=**True**, figsize = (10,6), ylim = [1e-1,1e3], color = ['green','red'])
从上图中,我们看到模型能够在实际轴承故障前大约 3 天检测到异常。
其他方法:用于异常检测的自动编码器模型
这里的基本思想是使用自动编码器神经网络将传感器读数“压缩”为低维表示,这捕捉了各种变量之间的相关性和相互作用。(基本上与 PCA 模型的原理相同,但是这里我们也允许输入变量之间的非线性)。
关于自动编码器的更详细的介绍,你可以看看我以前的文章,它更详细地涵盖了这个主题。
定义自动编码器网络:
我们使用一个 3 层神经网络:第一层有 10 个节点,中间层有 2 个节点,第三层有 10 个节点。我们使用均方误差作为损失函数,并使用“Adam”优化器训练模型。
seed(10)
set_random_seed(10)
act_func = 'elu'
*# Input layer:*
model=Sequential()
*# First hidden layer, connected to input vector X.*
model.add(Dense(10,activation=act_func,
kernel_initializer='glorot_uniform',
kernel_regularizer=regularizers.l2(0.0),
input_shape=(X_train.shape[1],)
)
)
model.add(Dense(2,activation=act_func,
kernel_initializer='glorot_uniform'))
model.add(Dense(10,activation=act_func,
kernel_initializer='glorot_uniform'))
model.add(Dense(X_train.shape[1],
kernel_initializer='glorot_uniform'))
model.compile(loss='mse',optimizer='adam')
*# Train model for 100 epochs, batch size of 10:*
NUM_EPOCHS=100
BATCH_SIZE=10
拟合模型:
为了跟踪训练期间的准确性,我们在每个时期后使用 5%的训练数据进行验证(validation_split = 0.05)
history=model.fit(np.array(X_train),np.array(X_train),
batch_size=BATCH_SIZE,
epochs=NUM_EPOCHS,
validation_split=0.05,
verbose = 1)
Training process
可视化培训/验证损失:
plt.plot(history.history['loss'],
'b',
label='Training loss')
plt.plot(history.history['val_loss'],
'r',
label='Validation loss')
plt.legend(loc='upper right')
plt.xlabel('Epochs')
plt.ylabel('Loss, [mse]')
plt.ylim([0,.1])
plt.show()
Train/validation loss
训练集中损失函数的分布:
通过在训练集中绘制计算损失的分布,可以使用它来识别用于识别异常的合适阈值。在这样做时,可以确保该阈值被设置在“噪声水平”之上,并且任何被标记的异常应该在噪声背景之上具有统计显著性。
X_pred = model.predict(np.array(X_train))
X_pred = pd.DataFrame(X_pred,
columns=X_train.columns)
X_pred.index = X_train.index
scored = pd.DataFrame(index=X_train.index)
scored['Loss_mae'] = np.mean(np.abs(X_pred-X_train), axis = 1)plt.figure()
sns.distplot(scored['Loss_mae'],
bins = 10,
kde= **True**,
color = 'blue');
plt.xlim([0.0,.5])
Loss distribution, training set
根据上面的损失分布,让我们尝试使用阈值 0.3 来标记异常。然后,我们可以计算测试集中的损失,以检查输出何时超过异常阈值。
X_pred = model.predict(np.array(X_test))
X_pred = pd.DataFrame(X_pred,
columns=X_test.columns)
X_pred.index = X_test.index
scored = pd.DataFrame(index=X_test.index)
scored['Loss_mae'] = np.mean(np.abs(X_pred-X_test), axis = 1)
scored['Threshold'] = 0.3
scored['Anomaly'] = scored['Loss_mae'] > scored['Threshold']
scored.head()
然后,我们也为训练集计算相同的指标,并将所有数据合并到单个数据帧中:
X_pred_train = model.predict(np.array(X_train))
X_pred_train = pd.DataFrame(X_pred_train,
columns=X_train.columns)
X_pred_train.index = X_train.index
scored_train = pd.DataFrame(index=X_train.index)
scored_train['Loss_mae'] = np.mean(np.abs(X_pred_train-X_train), axis = 1)
scored_train['Threshold'] = 0.3
scored_train['Anomaly'] = scored_train['Loss_mae'] > scored_train['Threshold']scored = pd.concat([scored_train, scored])
自动编码器模型的结果:
计算了损耗分布和异常阈值后,我们可以将轴承故障前的模型输出可视化:
scored.plot(logy=**True**, figsize = (10,6), ylim = [1e-2,1e2], color = ['blue','red'])
总结:
两种建模方法给出了相似的结果,它们能够在实际故障之前很好地标记即将发生的轴承故障。主要的区别本质上是如何为标记异常定义合适的阈值,以避免在正常操作条件下出现许多假阳性。
我希望这篇教程能给你启发,让你自己尝试这些异常检测模型。一旦你成功地建立了模型,是时候开始试验模型参数了。并在新的数据集上测试同样的方法。如果你遇到一些有趣的用例,请在下面的评论中告诉我。
玩得开心!
如果你有兴趣了解更多与人工智能/机器学习和数据科学相关的主题,你也可以看看我写的其他一些文章。你会发现他们都列在我的中型作者简介,,你可以在这里找到。
而且,如果你想成为一个媒体会员,免费访问平台上的所有资料,你也可以使用下面我的推荐链接。(注意:如果您使用此链接注册,我也会收到一部分会员费)
[## 通过我的推荐链接加入媒体- Vegard Flovik
作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…
medium.com](https://medium.com/@vflovik/membership)
更多来自 Vegard Flovik 媒体:
- 蒙特卡洛方法简介
- 从物理学到数据科学的转变
- 什么是图论,你为什么要关心它?
- 用于图像分类的深度迁移学习
- 建造一个能读懂你思想的人工智能
- 机器学习:从炒作到现实应用
- 人工智能和大数据隐藏的风险
- 如何使用机器学习进行异常检测和状态监控
- 用于供应链管理的人工智能:预测分析和需求预测
- 如何(不)使用机器学习进行时间序列预测:避免陷阱
- 如何利用机器学习进行生产优化:利用数据提高绩效
- 你如何向人工智能系统教授物理学?
- 我们能使用纳米级磁铁建立人工大脑网络吗?
人工智能研讨会——从宣传到现实应用
面向八年级学过数学的人的机器学习
抛开所有的复杂性,剩下的就是一个简单的代数公式
Credit: OstapenkoOlena/iStock/Getty Images Plus
我通常看到以两种方式解释人工智能:通过媒体日益煽情的视角,或者通过充斥着多余语言和特定领域术语的密集科学文献。
初学者的机器学习:神经网络导论
简单解释它们如何工作,以及如何用 Python 从头实现一个。
这里有些东西可能会让你吃惊:**神经网络并没有那么复杂!**术语“神经网络”经常被用作时髦词汇,但实际上它们往往比人们想象的要简单得多。
这篇文章是为完全的初学者而写的,假设你没有机器学习的知识。我们将理解神经网络是如何工作的,同时用 Python 从头实现一个神经网络。
我们开始吧!
注意:我推荐阅读 victorzhou.com的这篇文章——这篇文章的大部分格式在那里看起来更好。
1.构建模块:神经元
首先,我们必须谈谈神经元,它是神经网络的基本单位。一个神经元接受输入,用它们做一些数学运算,然后产生一个输出。这是一个双输入神经元的样子:
这里发生了三件事。首先,每个输入乘以一个权重:
接下来,所有加权输入与偏差 b 相加:
最后,总和通过一个激活函数传递:
激活函数用于将一个无界的输入转换成一个具有良好的、可预测的形式的输出。一个常用的激活功能是 sigmoid 功能:
sigmoid 函数只输出(0,1)范围内的数字。你可以把它想成是把(∞,+∞)压缩到(0,1)——大负数变成0,大正数变成1。
简单的例子
提醒:这篇文章的大部分格式在 victorzhou.com上的原帖中看起来更好。
假设我们有一个 2 输入神经元,它使用 sigmoid 激活函数并具有以下参数:
w =[0,1]只是向量形式的 w 1 =0, w 2 =1 的一种写法。现在,让我们给神经元一个x=【2,3】的输入。我们将使用点积来更简洁地写东西:
给定输入x=【2,3】,神经元输出 0.999。就是这样!这个向前传递输入以获得输出的过程被称为前馈。
编码一个神经元
是时候实现一个神经元了!我们将使用 NumPy ,一个流行且强大的 Python 计算库,来帮助我们做数学:
认得这些号码吗?这就是我们刚才做的例子!我们得到同样的答案 0.999。
2.将神经元组合成神经网络
神经网络只不过是一堆连接在一起的神经元。下面是一个简单的神经网络可能的样子:
这个网络有两个输入,一个隐层有两个神经元( h 1 和 h 2),一个输出层有一个神经元( o 1)。请注意, 1 的输入是来自 h 1 和 h 2 的输出——这就是网络的构成。
隐藏层是输入(第一个)层和输出(最后一个)层之间的任何层。可以有多个隐藏层!
一个例子:前馈
让我们使用上图所示的网络,并假设所有神经元都具有相同的权重 w =[0,1】,相同的偏差 b =0,以及相同的 sigmoid 激活函数。设 h 1、 h 2、 o 1 表示它们所代表的神经元的输出。
如果我们传入输入 x =[2,3]会发生什么?
输入 x =[2,3]的神经网络输出为 0.7216。很简单,对吧?
一个神经网络可以有任意数量的层,在这些层中有任意数量的神经元。基本思想保持不变:通过网络中的神经元将输入前馈,最终得到输出。为了简单起见,我们将在本文的剩余部分继续使用上图所示的网络。
神经网络编码:前馈
让我们为我们的神经网络实现前馈。这里的网络形象再次供参考:
我们又得了 0.7216!看起来很有效。
3.训练神经网络,第 1 部分
假设我们有以下测量值:
让我们训练我们的网络,根据某人的体重和身高来预测他们的性别:
我们将用 0 表示男性,用 1 表示女性,我们还将移动数据以使其更易于使用:
失败
在我们训练我们的网络之前,我们首先需要一种方法来量化它做得有多“好”,以便它可以尝试做得“更好”。这就是损失的原因。
我们将使用均方误差 (MSE)损失:
让我们来分解一下:
- n 为样本数,为 4(爱丽丝、鲍勃、查理、戴安娜)。
- y 代表被预测的变量,是性别。
- y_true 是变量的 true 值(“正确答案”)。例如,爱丽丝的 y_true 将为 1(女性)。
- y_pred 是变量的预测值。它是我们网络输出的任何东西。
(y _ true-y _ pred)被称为平方误差。我们的损失函数只是取所有平方误差的平均值(因此名字表示平方误差)。我们的预测越准确,我们的损失就越低!
更好的预测=更低的损失。
训练一个网络=尽量减少它的损失。
损失计算示例
假设我们的网络总是输出 00——换句话说,它确信所有人类都是男性🤔。我们会有什么损失?
代码:MSE 损失
下面是一些为我们计算损失的代码:
If you don’t understand why this code works, read the NumPy quickstart on array operations.
很好。向前!
喜欢这个帖子吗?我写了很多初学者友好的 ML 文章。订阅我的简讯让它们进入你的收件箱!
4.训练神经网络,第 2 部分
我们现在有一个明确的目标:最小化神经网络的损失。我们知道我们可以改变网络的权重和偏差来影响它的预测,但是我们怎样才能减少损失呢?
本节使用了一点多变量微积分。如果你对微积分感到不舒服,可以跳过数学部分。
为了简单起见,让我们假设我们的数据集中只有 Alice:
那么均方误差损失就是爱丽丝的平方误差:
另一种思考损失的方式是作为权重和偏差的函数。让我们给网络中的每个权重和偏差贴上标签:
然后,我们可以将损失写成一个多变量函数:
假设我们想要调整 w 1。如果我们改变 w 1,损失 L 会如何变化?这个问题偏导数可以回答。我们怎么算?
这就是数学开始变得更加复杂的地方。不要气馁!我建议带上纸和笔——这会帮助你理解。
如果你读这个有困难:下面的数学格式在 victorzhou.com 的原始帖子里看起来更好。
首先,让我们用∂y _ pred/∂w1 来重写偏导数:
This works because of the Chain Rule.
我们可以计算∂ L/ ∂ y_pred ,因为我们在上面计算了 l =(1-t34)y _ pred:
现在,让我们弄清楚如何处理∂y _ pred/∂w1。就像之前一样,设 h 1、 h 2、 o 1 为它们所代表的神经元的输出。然后
f is the sigmoid activation function, remember?
由于 w 1 只影响 h 1(而不是 h 2),我们可以写
More Chain Rule.
我们为∂做同样的事情:
You guessed it, Chain Rule.
x 1 这里是体重, x 2 是身高。这是我们现在第二次看到f’(x)(sigmoid 函数的导数)了!我们来推导一下:
稍后我们将使用这个漂亮的形式来表示f’(x)。
我们完了!我们已经设法将∂1 分解成我们可以计算的几个部分:
这种通过逆向计算偏导数的系统被称为反向传播,或“反向传播”。
唷。这是一大堆符号——如果你还是有点困惑,没关系。让我们做一个例子来看看这是怎么回事!
示例:计算偏导数
我们将继续假设只有 Alice 在我们的数据集中:
让我们将所有权重初始化为 1,将所有偏差初始化为 0。如果我们通过网络进行前馈,我们得到:
网络输出 y_pred =0.524,不强烈偏向男性(0)或女性(1)。我们来计算一下∂ L/ ∂ w 1:
提醒:我们在前面为我们的乙状结肠激活函数推导了 f*'(x)=f(x)∫(1-f*(x)。
我们做到了!这告诉我们,如果我们要增加 w 1, L 结果会增加一个t iiny位。
训练:随机梯度下降
我们现在已经拥有了训练神经网络所需的所有工具!我们将使用一种叫做随机梯度下降 (SGD)的优化算法,告诉我们如何改变我们的权重和偏差,以最小化损失。基本上就是这个更新方程式:
η 是一个叫做学习率的常数,它控制着我们训练的速度。我们所做的就是从 w 1 中减去η∂w1/∂l:
- 如果∂ L/ ∂ w 1 为正, w 1 将减少,这使得 L 减少。
- 如果∂ L/ ∂ w 1 为负, w 1 将增加,这使得 L 减少。
如果我们对网络中的每一个权重和偏差都这样做,那么损耗会慢慢减少,我们的网络也会改善。
我们的培训过程将是这样的:
- 从我们的数据集中选择一个样本。这就是随机梯度下降的原因——我们一次只对一个样本进行操作。
- 计算损失相对于权重或偏差的所有偏导数(例如∂ L/ ∂ w 1,∂ L /∂ w 2 等)。
- 使用更新等式来更新每个权重和偏差。
- 回到步骤 1。
让我们看看它的实际效果吧!
代码:一个完整的神经网络
终于到了实现完整神经网络的时刻:
你可以自己运行/玩这个代码。在 Github 上也有。
我们的损失稳步下降,因为网络了解到:
我们现在可以利用网络来预测性别:
现在怎么办?
你成功了!快速回顾一下我们的工作:
- 介绍了神经元,神经网络的构建模块。
- 在我们的神经元中使用了乙状窦激活功能。
- 我发现神经网络只是连接在一起的神经元。
- 创建了一个数据集,将体重和身高作为输入(或特征),将性别作为输出(或标签)。
- 了解了损失函数和均方误差 (MSE)损失。
- 意识到训练一个网络只是最小化它的损失。
- 使用反向传播计算偏导数。
- 使用随机梯度下降 (SGD)来训练我们的网络。
还有很多事情要做:
- 使用适当的机器学习库,如 Tensorflow 、 Keras 和 PyTorch ,尝试更大/更好的神经网络。
- 用 Keras 建立你的第一个神经网络。
- 在你的浏览器中修补神经网络。
- 发现除了 sigmoid 之外的其他激活功能,如 Softmax 。
- 发现除了 SGD 之外的其他优化器。
- 看我的卷积神经网络介绍(CNN)。CNN 彻底改变了计算机视觉的领域,并且非常强大。
- 看我的介绍递归神经网络 (RNNs),经常用于自然语言处理 (NLP)。
我将来可能会写这些话题或类似的话题,所以如果你想得到新帖子的通知,请订阅。
感谢阅读!
原贴于victorzhou.com。
一个或多个变量的线性回归
生物医学数据的机器学习
如何在医学中使用线性回归进行结果预测
简介
线性回归是一种用于机器学习的统计模型,属于“监督学习”类算法,适用于生物医学数据的分析。我们使用它来预测连续值输出,这与逻辑回归不同,逻辑回归用于预测离散值输出(即分类)。
在开始之前,我建议读者先去 Coursera 上学习 Andrew NG 教授的有趣的机器学习课程。本课程对这篇文章中讨论的所有论点提供了一个很好的解释。
让我们从我们的例子开始:我们有一个检查收缩压(SBP)并监测年龄和体重的患者数据集,我们想预测一个新患者的 SBP。我们假设体重和年龄等因素会影响 SBP。对于我们的数据集,我们将从[2]中获取一个表的值
Table 1: Dataset
要说明的变量(SBP)称为 因变量 ,或 响应变量 ,它与我们的 输出 变量或 目标向量 相匹配。而是将解释 输入 (年龄和体重)的变量称为 自变量 或 预测变量 ,或 特征 。如果因变量和自变量是连续的,如 SBP、和体重的情况,那么可以计算出一个相关系数作为它们之间关系强度的度量。[3]
我们说线性回归代表了相关性的进化。两者的区别在于:相关性是指两个或多个变量之间关系的强弱。相反,回归指的是描述两个或多个变量之间关系的统计技术和算法的集合[2]。
线性回归假设一个或多个输入要素与相对目标矢量(输出)之间的关系近似呈线性。[4],它能够识别和表征这种关系。这种假设的结果是,在线性回归模型中,输入特征对目标向量(输出)有“影响”,并且这种影响是恒定的。
“影响”通常被确定为“系数”、“权重”或“参数”,更简单地说,我们说线性回归计算输入特征的加权和,加上一个称为“偏差项”或截距的常数[5]。
为了简化,让我们从应用一个变量的线性回归开始。
一元线性回归
如果我们想彻底理解线性回归是如何工作的,从一个变量开始是一个基本步骤。我们将使用表 1 中的数据集,只外推特征“年龄”并使用“SBP”列作为输出。
本文中的所有代码都是用 Python 2.7 编写的,对于移植到许多其他语言来说,它也是不言自明的。对于实现环境,我建议使用 Jupyter 笔记本。
将主要使用线性代数计算,因为它在尽可能避免“while”和“for”循环方面具有内在优势。为了实现这个目标,我们将使用 NumPy ,这是一个强大的数学函数库,用于使用 Python 进行科学计算。
在开始描述线性回归模型之前,有必要看一下我们的数据,并尝试了解线性回归是否适用于这些数据。目标是基于患者年龄预测例如收缩压值。
第一步:导入 Python 库
首先,我们导入本帖将要讨论的 Python 代码所需的所有包: NumPy 、 Pandas 和 matplot 。这些软件包属于 SciPy.org,这是一个基于 Python 的数学、科学和工程开源软件生态系统。
Numpy 对于线性代数计算是必要的。
Pandas 是一个开源库,为 Python 提供高性能、数据结构和数据分析工具。pandas 数据帧是一个二维大小可变的、潜在异构的表格数据结构。它由三个主要部分组成,数据、行和列,带有标记的轴(行和列)。点击这个链接到 GeeksForGeeks 门户网站,获取关于熊猫数据框架使用的详细信息。
Matplotlib 是创建所有绘图的基础。
Code 1: import Python libraries
第二步:创建数据集
在这一步中,我们将使用我们的值创建一个数据集。带有标题的逗号分隔值格式的示例如下:
年龄体重 SBP
60,58,117
61,90,120
74,96,145
57,72,129
63,62,132
68,79,130
66,69,110
77,96,163
63,96,136
50
复制并粘贴文件中的值,并将其保存为“SBP.csv”
第三步:打开数据集
一旦我们创建了 SBP.csv 数据集,上传它并使用 Pandas pd 对象创建一个 DataFrame。数据集上传的 Python 代码如下:
Code 2: upload data and create a pandas DataFrame
在 Jupyter 单元格中键入“df ”,将显示如下数据帧内容:
Table 2: Visualizing a pandas DataFrame
步骤 4:上传数据集
SBP 数据集由 3 列组成(年龄、体重和 SBP),但我们将上传第一列和最后一列(年龄和 SBP);我们的模型将决定年龄和 SBP 之间关系的强度。Pandas 使访问 DataFrame 变量变得容易,这些变量将被复制到一个包含输入的 X 向量和一个用于输出的 y 向量中。
Code 3: Uploading the dataset
第五步:特征缩放和归一化
在继续之前,此处报告的 SBP 数据集必须进行重新缩放和归一化。在机器学习中,需要缩放和归一化,尤其是当特征和输出之间出现数量级差异时。如简介中所述,我们将在矩阵上使用线性代数,以尽可能避免而和 for 在变量上循环。此外,编程线性代数将导致代码的良好可读性。
为此,在 Python 中,我们可以利用 NumPy。如前所述,NumPy 是一个用于科学计算和线性代数的数学函数库。所有的操作都可以简化,创建一个 NumPy 对象,并使用一些相关的方法。我们之所以要使用 NumPy,是因为尽管矩阵上的许多操作可以使用常规操作符(+、-、*、/)来完成,但 NumPy 保证了对操作的更好控制,尤其是在矩阵很大的情况下。例如,使用 NumPy,我们可以逐元素地乘以参数,如特征矩阵 X 和输出向量 y :
Code 4: Multiply arguments element-wise
关于 NumPy 使用的深入讨论超出了本文的范围。为了实现特性的缩放和规范化,我们需要以下代码:
Code 5: The FeatureScalingNormalization() function.
代码 5 实现了一个名为 *FeatureScalingNormalization()的 Python 函数。*该函数将特征向量 X 作为参数,返回 3 个参数:1)同一个 X 向量,但经过缩放和归一化( X_norm ),2) mu ,即训练集中 X 的平均值,3) sigma ,即标准差。此外,我们将存储 mu 和 sigma ,因为这些参数在后面会很重要。复制以下代码并将其粘贴到新的 Jupyter 笔记本单元格中:
Code 6: Run the FeatureScalingNormalization function.
在笔记本单元格中键入“X”将显示新的 X 值:
array([-0.73189052, -0.59728997, 1.15251726, -1.13569219, -0.32808885, 0.34491392, 0.07571281, 1.55631892, -0.32808885, -1.53949386, -0.32808885, 1.42171837, -0.73189052, -0.59728997, -0.05888774, 1.82552004])
包含年龄值的 X 向量现在被归一化。
第六步:给 X 向量添加一列 1
现在我们将把一列 1 添加到向量 X 中。
Code 7: Add a column of ones to the X vector.
这是 X 的新结构:
array([[ 1\. , -0.73189052],
[ 1\. , -0.59728997],
[ 1\. , 1.15251726],
[ 1\. , -1.13569219],
[ 1\. , -0.32808885],
[ 1\. , 0.34491392],
[ 1\. , 0.07571281],
[ 1\. , 1.55631892],
[ 1\. , -0.32808885],
[ 1\. , -1.53949386],
[ 1\. , -0.32808885],
[ 1\. , 1.42171837],
[ 1\. , -0.73189052],
[ 1\. , -0.59728997],
[ 1\. , -0.05888774],
[ 1\. , 1.82552004]])
第七步:绘制数据集
当我们想知道数据是如何分布的时候,绘制数据图是一种有用的做法。使用 matplotlib 散点图方法绘制数据:
Code 8: Plot data
Figure 1: Plot Age-SBP
将数据可视化一目了然,我们可以注意到年龄和 SBP 之间增加关系的模式。这是我们所期望的,因为收缩压在生理上与年龄增长有关。
第八步:假设(线性回归模型)
线性回归的基本思想由基于输入特征 X 预测输出 y 的函数来表示。
Equation 1: Linear Regression Model
预测输出是 h = θ * X 项,它等于一个称为“偏差项”或“截距项”或 θ_0 的常数加上输入特征 X **、**的加权和,其中 θ_1 代表X的权重。我们将这个函数称为“假设”,我们将使用它从 X (年龄)到 y (SBP)进行“映射”。
由于我们使用线性代数,对于所有计算,我们可以将假设模型写成矢量化形式:
Equation 2: Linear Regression Model in vectorized form
其中θ*_0和 θ _ 1 表示为向量θ=【θ_ 0,θ_1】***,假设等于 θX 。
预测 y 的最佳性能包括找到预测的 y 值和实际的 y 值之间的距离更接近最小值的θ 值。
让我们试试随机选择的两个参数,对于向量θ,例如:θ = [140.0,5.0],看看会发生什么:
Code 9: Plot the Hypothesis with θ = [140.0, 5.0]
Figure 2: θ = [140.0; 5.0]
图 2 中用红线表示的假设模型应该预测y(SBP)。对于θ=【140.0,5.0】的值,它表示我们在预测 y 时的 h=θX 向量。但是这个模型显然不符合我们的数据。正如用红线连接圆点的蓝线所突出显示的,假设“触及”了一些 y 值,但是剩余的 h 向量远不是最小值。所以我们很想猜测当设置不同的值时,哪个 θ 可以预测 y 。我们可以“通过试错法”选择 θ 来最小化假设和y之间的所有距离。为了实现这个目标,我们可以为我们的模型计算 成本函数 。
第九步:计算成本函数
**成本函数 可以记录我们离假设模型的最小值有多远,并可以帮助我们找到最佳θ 。描述成本函数的等式如下:
Equation 3: Linear Regression Cost Function
其中 m 是 X 向量的长度(在我们的例子中= 16),而 i 是分配给数据集中每一项的索引。该等式由三部分组成:
- 假设( h=θX )
- 平方误差即= ( h-y ) ^2
- 成本函数 J 计算如下:J = 1/2m * Sum(平方误差)
由于我们使用线性代数,等式 3 的矢量化实现如下:
Equation 4: Linear Regression Cost Function (vectorized form)
直觉一.
为了简化解释,让我们尝试手动计算仅由 SBP 数据集的前 3 个值组成的较小数据集的成本函数,以及θ = [120.0,10.0]的。目前,这些参数是随机选择的,因为我们现在不需要设置最佳的θ*。我们将分割 X 和 y ,产生数组 X_1 和 y_1 :*
Code 10: Make a vector X_1 and y_1 with the first 3 values of X, and y.
同样,我们必须设置 m=3 ,因为我们现在有三个样本。让我们将数据和假设绘制如下:
Code 11: Plot data and Hypothesis
Figure 4: Plot of the first 3 values of the dataset; θ = [120.0; 10.0]
SBP 前三个值(蓝点)对应的矢量 y 为:
y = [117.0,120.0,145.0]
由于我们的 θ 为=【120,10.0】, h = θ X_1 的乘积将由以下向量表示,(红线上的点高亮显示):*
h = θX_1 = [112.7,114.0,131.5]*
蓝色虚线突出显示了实际 y_1 值和预测值之间的距离。现在,我们有了所有我们需要的,来计算成本函数 J 。我们将应用解决方案 1 中描述的成本函数:
Solution I: Calculating the Cost Function
…成本函数(J)是= 39.3
Python 中的代价函数。
以下 Python 代码实现了成本函数:
Code 12: The code for calculating the Cost Function
*该代码逐步实现*等式 4 中描述的成本函数(矢量化)。让我们再重复一遍:
- 假设( h=θX )
- 平方误差即= (h-y) ^2)
- 成本函数 J 即= 1/2m * Sum(平方误差)
*既然我们已经理解了成本函数计算的机制,让我们回到完整的 SBP 数据集(16 名患者)。如果我们想计算整个 SBP 数据集的成本函数,使用*θ=【140.0;5.0],我们将键入:
Code 13: Running calcCostFunction
该函数将返回 J = 138.04,这是为θ=【140.0】计算的代价函数;5.0] 。这个 J 不是我们能找到的最小 J ,因为我们已经手动设置了 θ,不知道如何最小化它。下面的直觉 II 可以帮助我们更好地理解我们手工方法的局限性。
直觉二。
以下代码随机生成 10 个 θ 向量,并将它们传递给 calcCostFunction ,生成一个相对成本函数表( J ):
Code 14: Try random θ and calculate the Cost Function
产生的输出是:
***[Th0 Th1] J**
[38\. 55.] 5100.4688623710845
[71\. 47.] 2352.6631642080174
[28\. 76.] 7148.466632549135
[73\. 75.] 3579.826857778751
[79\. 47.] 1925.1631642080174
[12\. 42.] 7320.026790356101
[68\. 25.] 1992.2131192595837
[25\. 92.] 8565.015528875269
[51\. 46.] 3667.1483894376343
[13\. 62.] 7992.509785763768*
*“带回家的信息”是试图手工最小化 J 不是正确的方法。在随机选择的 θ的上运行 10 次之后, J 的行为是不可预测的。而且,没有办法根据 *θ来猜测 J 。*那么问题来了:我们如何选择 *θ,求最小 J?我们需要一个能为我们最小化 J 的算法,这个算法就是下一步的论证。
步骤 10:梯度下降
我们感兴趣的是使用 【梯度下降】*****找到成本函数的最小值,这是一种可以使这种搜索自动化的算法。梯度下降计算代价函数的导数,通过参数 α、更新向量 θ ,即学习率。从现在开始,我们将把 SBP 数据集称为**训练集。**这种澄清是必要的,因为梯度下降将使用数据集的实际矢量 y 和 h 矢量预测之间的差异来“学习”如何找到最小值 J 。该算法将重复,直到它将收敛。 θ 更新必须同时进行。***
Equation 4: Gradient Descent implementation
由于我们使用线性代数,矢量化实现如下:
Equation 5: Gradient Descent (vectorized form)
注意,这里我们必须转置 X ,因为 X 是一个[16,2]矩阵,而错误是一个[16,1]向量。
梯度下降实现。
以下 Python 代码实现了梯度下降。我们将使用方程 5 的矢量化形式:
Code 15: The Gradient Descent function
要运行梯度下降,我们必须初始化 θ 、迭代、和 α、,它们与 X 和 y 一起是梯度下降函数的参数:
Code 16: Running the Gradient Descent
结果收集在“结果”列表中。该列表由找到的 θ、加上包含 θ 和 J 历史的两个列表组成。经过 2000 次迭代后,梯度下降找到了θ=【128.4,9.9】和 J = 59.7 ,这是 J 的最小值。我们将使用这两个列表来绘制梯度下降活动。以下代码将绘制训练集和 h 。
Code 17: Plot dataset and h for θ = [128.4, 9.9]. J = 59.7 is the minimum
Figure 5: Plot of dataset and h; θ = [128.4; 9.9]; J = 59.7
假设 h 现在符合我们的数据!
我们来绘制一下 θ历史:
Code 18: Plot the θ history
θ 历史曲线如图图 6 所示。红色曲线代表 θ _0,绿色曲线代表 θ _1。2000 次迭代后, θ 为*=【128.4;9.9]***
Figure 6: The θ history plot. The red curve represents θ0; the green curve represents θ1
现在我们来绘制一下 J 的历史:
Code 19: Plot the J history
Figure 7: The J history plot
在大约 200 次迭代之后,成本函数下降,在 1500 次迭代之后稳定在 59.7 左右。 J 曲线取决于我们设置为 0.01 的 α、。
第 11 步:预测
现在我们已经找到了最佳的 θ,我们可以预测一个 75 岁老人的收缩压。该查询是一个向量,由两个数字[1,75]组成。第一个数字对应于特征 x_0 。为了运行预测,我们必须使用我们在步骤 5:特征缩放和归一化中计算的μ和σ参数来缩放和归一化查询向量。查询向量将是[1,1.29]。然后,我们要将查询乘以 θ 向量(θ=【128.4,9.95】)。下面的代码实现了预测。
Code 20: Predicting SBP
75 岁老人的 SBP 是:141.2
步骤 12:关于学习常数 α 的直觉
让我们用学习率 α 做一些实验。改变 α 会影响 J 的动态。如果 α 过小,梯度下降会收敛缓慢,我们需要用更多的迭代来训练它,以找到 J 的最小值。相反,如果 α 太大,则梯度下降有永不收敛的风险。有趣的是,对于大约 1.9 的 α 值,梯度下降收敛,但是对于最初的 40 次迭代, θ 的行为是紊乱的,以便连续达到稳定。(图 8)
Figure 8: Experiments with α. Panel A shows h, J and θ, with α = 0.001. If α is too little, 2000 iterations are not sufficient; Gradient Descent will be slow in converging, and it will require ~ 10000 iterations for finding the minimum J (data not shown). Panel B shows the opposite situation. With α = 1.9, Gradient Descent converges, but initially,the searching of θ shows turbulence. After 40 iterations θ reaches stability, and finally, the algorithm converges.
步骤 13:J 和 θ 的等高线图
我们可以创建一个等高线图,它是一个包含许多同心轨迹的图形。对于每条轨道,有多对与恒定值 J 相关联的 θ 。最小值 J 对应的 θ 位于中心(红点)。其他同心线对应 J 的所有不同值。距离中心越远,成本函数值 J 越高。
Code 21: Drawing a Contout Plot of J and θ
代码 20 产生以下图形:
Figure 9: The contour plot of J and theta
注意*θ=【128.4;9.9]* 对应的最小值 J (59.7),就是图形中心的红点。蓝点跟踪梯度下降收敛到最小值的路径。**
步骤 14:如何修改多变量代码
我们已经解释了具有一个变量的线性回归的统计机制:SBP 数据集中的特征年龄。这里提出的代码的主要部分也适用于多个变量。SBP 数据集由两个特征(年龄和体重)和一个输出: SBP 。在这一步中,我们将更新代码,使其能够适应多个变量。唯一需要调整的是:
- 数据集上传
- 特征缩放和归一化功能
- 向向量 X 添加一列“1”的代码
- 预测查询。
数据集上传
必须修改上传数据集的代码,以生成新的 X 向量,其中包含每位患者的年龄和体重:
Code 22: The code for uploading the dataset for multiple variables
用于产生新 X 向量的 numpy 方法是。因为我们现在想要一个具有两组不同特征的 X 向量。**
特征缩放和归一化功能
在矢量 mu 和 sigma 中修改关于特征缩放和归一化的代码。现在这两个向量将各接受两个参数。
Code 23: The FeatureScalingNormalization function for Linear Regression with Multiple Variables.
向向量 X 添加一列“1”
向 X 向量添加“1”的行修改如下:
Code 24: Adding a column of “ones” to the vector X.
预测查询
预测的查询和归一化的代码修改如下:
Code 25: The Query in Linear Regression with Multiple Variables
在这种情况下,预测结果是 SBP =143.47
有了这些变化,Python 代码就可以进行多变量线性回归了。每次从训练集中添加新功能时,您都必须更新代码!
希望这篇帖子对你有用!
参考文献
- Andrew NG,机器学习| Coursera。
- 约翰·佩祖罗,假人生物统计学,威利,ISBN-13:9781185585
- 施耐德,A;Hommel,G;Blettner,m .科学出版物评价系列的线性回归分析第 14 部分,Dtsch Arztebl Int 2010107(44): 776–82;DOI: 10.3238
- Chris Albon,《Python 机器学习指南》, O’Really,ISBN-13:978–1491989388。
- Aurélien Géron,使用 Scikit-Learn 和 TensorFlow 进行机器学习:构建智能系统的概念、工具和技术,O’Reilly,ISBN-13:978–1491962299。