宫颈癌的预测和概率分析®
通过使用 Boruta 特征工程和分类预测模型了解导致宫颈癌的因素来庆祝妇女历史月
宫颈癌(图片由 Unsplash 上的国家癌症研究所提供
简介
由于“女性历史月”即将结束,我想借此机会庆祝一下这个至今仍威胁着许多女性的健康问题。在美国,每年发现 11,000 例新的浸润性宫颈癌病例。尽管新病例的数量在过去十年中呈下降趋势,但它仍然在美国杀死了大约 4000 名妇女,在全球杀死了 30 万名妇女。 (Fontham et al .,2020) 越早发现,生存的机会就越大。因此,为了有效地消除这类疾病,我们需要创建一种机器学习算法,能够尽快检测出癌症。因此,对于期末项目,我将分析数据集:来自 UCI 的宫颈癌(风险因素)。(“UCI 机器学习知识库:宫颈癌(风险因素)数据集”,2017) 该数据集是在委内瑞拉加拉加斯的“加拉加斯大学医院”收集的。我计划混合使用 EDA、Boruta 的特性重要性分析和分类预测模型
数据准备
我们将通过加载必要的库和读取数据集来开始我们的项目。我们将使用 8 个库,1 个用于可视化,3 个用于数据操作,1 个用于特征重要性分析,3 个用于预测模型。
(图片由作者提供)
宫颈癌有 858 个输入,36 个变量,从人口统计信息、习惯到历史医疗记录。一些变量有缺失数据,因为患者出于隐私考虑拒绝回答。值得注意的是,许多变量被解释为由“?”引起的因素填充为缺失值的占位符
(图片由作者提供)
因此,在继续之前,我将检查数据的完整性,因为它可以隐藏我们正在寻找的实际汇总统计数据。有许多函数可以指示缺失值,如 NAs、零、负值或空白字符串,因此创建一个专门处理 NAs 的函数,然后绘制数据的完整性(无缺失)会更容易
(图片由作者提供)
数据操作
在我们对数据有了更好的了解之后,更好的做法是处理缺失的值,以便进行更深入的探索性数据分析。首先,我们创建一个函数来标识所有需要修复的列,然后创建一个函数来修复丢失的值。x="-1 "的原因是允许在“?”之后对它们执行数值运算导致它们都成为因素。“-1”也是一个很好的占位符,因为它清楚地表明该输入中存在某些内容。然后,我们将这两个函数应用到列上,稍后我们可以建立一个表示宫颈癌的属性。
此外,我们还创建了一个相关图来剔除不重要的变量。之后,我们需要切断小于 0.7 的任何组合的相关性。最终的结果将会是这样的,表明一般来说,这些创建了高度相关的变量组合。
(图片由作者提供)
最后四栏(“Hinselmann”、“Schiller”、“细胞学”、“活组织检查”)表示子宫颈检查的结果。阳性结果并不意味着患者患有宫颈癌,但患者接受的阳性越多,这种可能性就越大。因此,我将根据以下公式创建一个名为“宫颈癌”的变量:
宫颈癌= Hinselman + Schiller + Citology +活检
(图片由作者提供)
探索性数据分析
在创建“宫颈癌”列后,我们可以看到大约 90%的患者没有任何症状,只有 1%的患者通过显示所有 4 种症状实际上显示了严重的情况。
(图片由作者提供)
在创建“宫颈癌”列后,我们可以看到大约 90%的患者没有任何症状,只有 1%的患者通过显示所有 4 种症状实际上显示了严重的情况。
因此,我们可以说,预测每个人都不会患癌症的基线模型的准确度将有 88%的高准确度
(图片由作者提供)
当我们观察密度图中患者的年龄时,每个密度图中的峰值都明显变得荒凉,表明“年龄”和“子宫颈癌”之间的相关性很强
(图片由作者提供)
此外,当观察“激素避孕年”和“宫颈癌”时,也有峰高度降低,密度图的右偏度也表明有很强的相关性。虽然我们有可能对它们中的每一个都这样做,但更好的办法是采用一种更快的方法来找到对像 Boruta 这样的“宫颈癌”影响最大的特征
用 Boruta 进行特征重要性分析
Boruta 方法通过对预测值进行混洗,并将它们与原始预测值连接起来,并在合并的数据集上构建随机森林,来评估特征的重要性。之后,我们将原始变量与随机化变量进行比较,以衡量它们的重要性,并选择重要性比随机化变量高的变量。。 (Deepanshu Bhalla,2017) 人们通常认为 Robuta 优于 R 中其他特征选择包,这要归功于它的各种优势:
适用于分类和回归分析,因为它考虑了多变量关系
对随机森林变量重要性度量的增强,可以处理变量之间的相互作用以及改变随机森林重要性度量的性质
在本练习中,Boruto 流程从创建原始数据集的副本开始,但是删除了医疗结果列。然后我们设置种子,使用 Boruta()函数。情节如下
(图片由作者提供)
我们确认了 15 个,排除了 7 个,还有 10 个是暂定的。
(图片由作者提供)
这是被证实对因变量有影响的变量
(图片由作者提供)
从 Boruta 导出的最终结果的数据帧可以在 R 文件中找到
预测模型
我们将创建一个新变量“C _ 宫颈癌”,包含所有上述“已确认”变量和“宫颈癌”。对于癌症的可能性,我们将这些值指定为是或否。由于这是一种非常关键的癌症类型,并且是针对一小部分潜在癌症患者的,因此我们最好认真对待所有症状(1-4 ),而不是遗漏任何症状,并给它们分配 1,其余的为 0。然后,我们将目标特征编码为因子,并将数据集分成 0.75/0.25 比率的训练集和测试集进行预测。
支持向量机
支持向量机(SVM)的目标是在 N 维空间中找到一个超平面(N-明确分类数据点的特征的数量。有许多可能的超平面来对它们进行分类,但是我们想要找到一个具有最大余量(两个类的数据点之间的距离)的平面。一旦实现,未来的数据点可以更有把握地执行强化和分类,如下图所示。(罗希特·甘地,2018) 。在这个项目中,我们选择类型为“C-分类”,内核为“线性”
(来源:https://towards data science . com/support-vector-machine-vs-logistic-regression-94cc 2975433 f)
决策树
决策树模型通过将输入分解成更小的决策来做出判断。决策树的优势在于它的过程具有可理解的规则,并执行分类任务,而不管计算能力如何。它对连续变量和分类变量都很有效,为研究者提供了一个清晰的指示,表明哪些自变量是必不可少的。无论如何,不建议过于频繁地使用连续属性,这可能会产生错误,有时甚至在少量的训练样本上也会耗费精力。决策树用于动物图片分类等任务。
随机森林
这是决策树的高级版本,除了提出的问题,包括一些随机性。该算法通过“装袋法”创建了一个“森林”,即迷你决策树的集合。然后将所有的树合并在一起,以获得更准确和稳定的预测。不幸的是,随机森林在处理有噪声的数据时经常会过拟合。(基里尔·富克斯,2017) 。在这个项目中,我们选择的树木数量是 500 棵
车型对比与精度对比与召回权衡
运行完所有模型后,我们可以构建如下混淆矩阵表。
(图片由作者提供)
我们将使用精确度和召回率作为模型性能评估的指标。精度(特异性)是关于确保模型的准确性,指示在检索的例子中相关例子的分数。另一方面,回忆(敏感度)是关于模型获得正确实例的能力。精确度和召回率的范围从 0 到 1,越高越好。值得注意的是,这里有一个权衡,意味着当精度上升时,召回失败,反之亦然。研究人员经常使用像 F1 分数这样的抽象指标来做出决定,F1 分数是两者的结合。然而,在识别宫颈癌患者这样的危险情况下,回忆比精确更重要,因为错误治疗的成本可能很高,但没有错误错过潜在癌症患者的机会成本高。幸运的是,我会选择随机森林方法,因为与其他方法相比,它具有最高的召回率(0.8826)和精确率(0.5)。(塞缪尔·希利斯&莎拉·霍曼,2016) 。最后但同样重要的是,虽然我很想通过 GridSearch 和 K Folds 交叉验证来提高这个模型的准确性,但我不认为这是一个好主意,因为它是一个非常小的数据集,我们可能会过度拟合。
结论
总之,宫颈癌是最威胁生命的疾病之一,每年导致数千人死亡。但是实现上面这样的随机森林方法,相信以后可以拯救很多人。
— — —
Github:https://Github . com/lukastuong 123/R-Studio/tree/master/Project-% 20 宫颈% 20 癌% 20 检测
参考资料和资源:
Deepanshu Bhalla。 (2017 年 8 月 5 日)。特征选择:用 Boruta 包选择重要变量。2021 年 2 月 22 日检索,来自https://www . listen data . com/2017/05/feature-selection-boruta-package . html
丰瑟姆,E. T. H .,沃尔夫,A. M. D .,丘奇,T. R .,埃齐奥尼,r .,弗劳尔斯,C. R .,赫齐格,a .,…史密斯,R. A. (2020)。平均风险个体宫颈癌筛查:美国癌症协会 2020 年指南更新。 CA:临床医生的癌症杂志, 70 (5),321–346。https://doi.org/10.3322/caac.21628
基里尔·富克斯。 (2017)。机器学习:分类模型。2021 年 2 月 22 日检索,来自https://medium . com/fuzz/machine-learning-classification-models-3040 f71e 2529
甘地。 (2018 年 6 月 7 日)。支持向量机-机器学习算法介绍。检索于 2021 年 2 月 22 日,来自https://towardsdatascience . com/support-vector-machine-introduction-to-machine-learning-algorithms-934 a 444 FCA 47
塞缪尔·希利斯,莎拉·霍曼。 (2016 年 1 月 16 日)。理解权衡。检索于 2021 年 2 月 22 日,来自https://medium . com/OPEX-analytics/why-you-need-to-understand-the trade-off-of-precision-and-recall-525 a 33919942
— — —
数据集:UCI 机器学习知识库:宫颈癌(风险因素)数据集。 (2017)。检索于 2021 年 2 月 22 日,来自https://archive . ics . UCI . edu/ml/datasets/子宫颈+癌症+% 28 风险+因素%29
灵感来源:https://www . ka ggle . com/divyabongouni/key-宫颈癌-预测-与-boruta
Wav2Vec2 和变压器的“链式链接”NLP 任务
从音频直接进入一系列基于文本的自然语言处理任务,如翻译、摘要和情感分析
图表:蔡钦汉
拥抱脸的变形金刚库中增加了 Wav2Vec2 模型,这是近几个月来 NLP 中更令人兴奋的发展之一。在那之前,如果你只有一个很长的音频片段,执行机器翻译或情感分析等任务并不容易。
但现在你可以一气呵成地将 NLP 任务的有趣组合联系起来:用 Wav2Vec2 转录音频片段,然后使用各种 transformer 模型来总结或翻译转录本。你能联系起来的 NLP 任务的可能排列和组合是相当令人难以置信的。
当然,结果可能是不完整的。一些 NLP 任务,比如总结,本质上是很难解决的。
这篇文章是我之前的关于 Wav2Vec2 试验的后续,将概述 2 个试验:
- #1:语音转文本转翻译&情感分析
- #2:语音转文本转摘要
回购、要求和参考
试用所需的笔记本和音频文件在我的 repo 里。此外,您还需要这些来运行笔记本电脑:
通过 Github 上拥抱脸的机器学习工程师弗拉达利·吉克的帖子,大多数笔记本中的代码已经更新,以使用更好的方法来转录长音频文件。
在我早期的工作中,我使用 Audacity 手动将长音频剪辑分割成更小、更易管理的片段(长度超过 90 秒的音频剪辑往往会导致本地机器和 Colab 崩溃)。弗拉达利的代码通过使用 Librosa 将长音频剪辑转换成较短的固定“块”来消除这一步骤。
在 Hugging Face 的 model hub 上有几个版本的 Wav2Vec2 模型。在这篇文章中,我将使用wav2 vec 2-large-960h-lv60-self型号。
试验#1:转录+翻译+情感分析
通过美国消费者新闻与商业频道电视台的 YouTube 频道在右边截屏
对于这次试验,我选择了美国总统乔·拜登在 2021 年 3 月 11/12 日(取决于你在哪个时区)的第一次黄金时间演讲。
他的演讲大约有 24 分钟长,我通过 25 秒的组块将它传输到 Wav2Vec2。你可以选择更长或更短的块。我发现 25 可以给出不错的结果。详细情况在我的回购中的 notebook3.0 里,这里不再赘述。
演讲很复杂,众所周知,拜登一直在与口吃作斗争。剧本(直接下载这里)的某些部分相当粗糙,尤其是接近结尾的部分:
点击此处下载原始 Wav2Vec2 抄本
公平地说,在我看来,拜登说得非常清楚,这是 Wav2Vec2 模式陷入困境的一个例子。但是,在我 2015 年末的 iMac 上,这个模型只花了 12 分钟左右就生成了副本,这比我手动完成要快得多。
接下来,我想把拜登的演讲文本输入机器翻译模型,看看中文翻译的质量如何。我用了拥抱脸的 MarianMT 的实现来做这个,因为我已经在之前的几次演讲中试过了。
不幸的是,结果几乎无法使用。点击此处下载完整的中文翻译:
从技术角度来看,“链式链接”过程工作得很好,在 Wav2Vec2 过程之后,您只需要大约 10 行额外的代码。
但是,当原始抄本中有问题的部分在没有彻底清理丢失或错误的单词以及正确的标点符号的情况下被输入到 MarianMT 模型中时,翻译的质量明显受到影响。我添加了句号(“.”)出现在 Wav2Vec2 中每段 25 秒的文字记录的末尾,但这显然没有捕捉到原始演讲中每个句子的正确开头和结尾。
因此,虽然看起来“链式链接”NLP 任务可以节省大量时间,但一个领域中的问题可能会复合,导致更下游的任务的质量更低。
显然,清理原始的英文文本需要额外的时间。但我相信这样做会大大提高中文翻译的质量。至于准确的标点,目前在 Wav2Vec2 内还没有快捷的方法。但我怀疑这种模式的未来版本会解决这个问题,因为市场上的一些自动语音识别服务已经具备了“添加标点符号”的功能。
接下来,我想尝试将情感分析应用到拜登的演讲中。语音到文本与情感分析的结合在政治或商业环境中非常有用,在这些环境中,快速了解说话者的情感可以影响某些决策。
原始文字被转换成一个简单的数据框架,然后我使用拥抱脸的变形金刚管道和 Plotly 生成一个“情绪结构”图,如下图所示。我已经试验这些情绪图表有一段时间了。我早期的实验可以在这里找到。
这比尝试中文翻译要好得多,尽管我确信情感分析也将受益于彻底的清理和在原始英文抄本中包含适当的标点符号。
从技术上来说,没有理由为什么一个人会只完成三项任务。您可以很容易地再编写几行代码,并将汇总作为连续的第四个 NLP 任务。
但是,包括演讲在内的长文本文档的自动摘要仍然是一项极具挑战性的任务,即使对于 transformer 模型来说也是如此。在我看来,这一结果还不成熟。让我们在下一次试验中仔细观察一下。
试验#2:转录+总结
通过新加坡总理办公室的 YouTube 频道截图。
为此,我选择了一个较短的音频剪辑,一个 4 分钟的视频,内容是新加坡总理李显龙在 2019 年的一次商业会议上回答一个关于民粹主义的问题。该剪辑集中在一个单一的问题,但有足够的复杂性,它是任何自动总结模型的挑战。
详见我的回购中的记事本 3.1 。
Wav2Vec2 输出非常出色,如下图所示(或者在这里下载)。这里和那里有一些小失误,但没有什么是你不能很快清理干净的。
我运行了两个变压器模型的原始抄本,FB 的“ bart-large-cnn ”和谷歌的“ pegasus-large ”。
这是来自 Bart 的结果:
这是飞马座的总结:
两个模型都很好地捕捉到了演讲者对民粹主义的宽泛定义,随后加入了他对新加坡如何试图避免这一问题的阐述。
但 FB-Bart 模型没有捕捉到李先生评论第二部分的任何细节。与此同时,飞马模型从他评论的第一部分抓住了太多,而对后半部分抓得不够。在我看来,这两个版本都算不上一个好的总结,尽管公平地说,这两个模型都没有受过政治演讲的训练。
因此,我们再次看到,通过 Wav2Vec2 和 transformers 链接 NLP 任务在技术上是可行的,但结果并不总是令人满意。
结论
对于在 NLP 工作的人来说,这是令人兴奋的时刻,Wav2Vec2 看起来将开辟一个全新的可能性范围。随着拥抱脸发起冲刺,将 Wav2Vec2 扩展到其他语言(英语之外),NLP 任务的“链式链接”范围只会越来越大。
但是考虑到 Wav2Vec2 现有的限制和许多 NLP 任务(如总结)中固有的困难,在这个过程中添加一个“暂停”按钮可能更明智。
我的意思是,如果原始的 Wav2Vec2 转录物在被送到下游的其他 NLP 任务之前被清除,结果会更好。否则,成绩单上有问题的地方会变得复杂,导致其他地方的成绩低于标准。
和往常一样,如果你在这篇文章或我之前的文章中发现了错误,请联系我:
- 推特:蔡锦鸿
- 领英:【www.linkedin.com/in/chuachinhon
这个帖子的回购,包含图表的数据和笔记本,可以在这里找到。
线性回归:pythons sklearn 与‘从头开始写’的比较
曾经想知道 python 的 sklearn 中多元线性回归/梯度下降的幕后发生了什么吗?你会惊讶它是多么容易。让我们从头开始写,并对两者应用相同的评估方法,看看我们做得如何。
作者 Sani2C 线性回归能让我骑得更快吗?
介绍
所以,从理解的角度来看,理解线性回归中发生的事情是很好的。这里是一个没有使用 python 库的的的深度探索。这里有一个链接指向 github 中这篇文章的源代码。如果你确实需要梯度下降的介绍,先看看我的 5 集 YouTube 系列。
在第一步中,我们将从头开始编写梯度下降,而在第二步中,我们将使用 sklearn 的线性回归。
我们的数据集
让我们从 kaggle 下载我们的数据集。世界卫生组织(世卫组织)下属的全球卫生观察站(GHO)数据库记录所有国家的健康状况以及许多其他相关因素。这些数据集向公众开放,用于卫生数据分析。与 193 个国家的预期寿命、健康因素相关的数据集从同一个世卫组织数据库网站收集,其相应的经济数据从联合国网站收集。
图 kaggle 的屏幕截图
步骤 1:线性回归/梯度下降从零开始
让我们从导入我们的库开始,看看前几行。
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
from sklearn.preprocessing import LabelEncoder
from sklearn import metricsdf = pd.read_csv(‘Life Expectancy Data.csv’)
df.head()
您将看到一个很好的数据视图,可以看到我们有国家和状态文本字段,而“预期寿命”是我们想要预测的字段。
图 jupyter 的屏幕截图
为了获得更多的洞察力,让我们运行一个 info,我们将在图 3 中得到下面的 info。
- 我们有 2 个文本字段,即。国家和地位
- 酒精、乙肝等领域。有我们需要解决的空值
- 列名需要一些工作
df.info()
图 jupyter 的屏幕截图
准备数据
这些名称不适合使用,所以让我们重命名一些列。然后将对象字段转换为数字,因为我们不能处理文本。最后,让我们将 Y 移动到它自己的数组中,并将其从“df”中删除。这种陡峭的结果是,‘df’是我们的特征集并且只包含数字,而‘y’是我们的结果集。
df.rename(columns = {“ BMI “ :”BMI”,
“Life expectancy “: “Life_expectancy”,
“Adult Mortality”:”Adult_mortality”,
“infant deaths”:”Infant_deaths”,
“percentage expenditure”:”Percentage_expenditure”,
“Hepatitis B”:”HepatitisB”,
“Measles “:”Measles”,
“under-five deaths “: “Under_five_deaths”,
“Total expenditure”:”Total_expenditure”,
“Diphtheria “: “Diphtheria”,
“ thinness 1–19 years”:”Thinness_1–19_years”,
“ thinness 5–9 years”:”Thinness_5–9_years”,
“ HIV/AIDS”:”HIV/AIDS”,
“Income composition of resources”:
”Income_composition_of_resources”}, inplace = True)# convert labels to numbers
columns = [“Status”,”Country”]
for feature in columns:
le = LabelEncoder()
df[feature] = le.fit_transform(df[feature])# extract Y and drop from data frame
Y = df[“Life_expectancy”]
df = df.drop([“Life_expectancy”], axis=1)
绘图相关矩阵
如果我们有一个包含许多列的数据集,快速检查列间相关性的一个好方法是将相关性矩阵可视化为热图。查看该矩阵,您可以看到 9 列具有高于 0.38 的最高相关性。我们只对“预期寿命”感兴趣,所以请看最下面一行的结果。
plt.figure(figsize = (24,16))
sns.heatmap(pd.concat([df,Y], axis=1).corr(), annot=True, cmap=”coolwarm”)
为了获得更好的结果,我们可以选择在相关矩阵中仅使用高于 0.3 的特征。
图 jupyter 的屏幕截图
为我们缺失的特征填入数值
回归的一个重要部分是理解哪些特征缺失了。我们可以选择忽略所有缺少值的行,或者用 mode、median 或 mode 填充它们。下面是一个手动函数,它基于以下三种方法之一来填充缺失值:
- 模式=最常见的值
- 中位数=中间值
- 平均值=平均
def fillmissing(df, feature, method):
if method == “mode”:
df[feature] = df[feature].fillna(df[feature].mode()[0])
elif method == “median”:
df[feature] = df[feature].fillna(df[feature].median())
else:
df[feature] = df[feature].fillna(df[feature].mean())
现在,查找缺少值的列,并使用我们方便的函数填充它们。让我们也填写 y 中任何缺失的值。
features_missing= df.columns[df.isna().any()]
for feature in features_missing:
fillmissing(df, feature= feature, method= “mean”)Y.fillna(Y.median(), inplace=True)
获取 X/Y 数组
让我们将数据帧放入易于操作的数组中。
X = df.to_numpy()
y = Y.to_numpy().transpose()
m,n = X.shape
标准化 X
现在,让我们将 X 归一化,使其值介于-1 和 1 之间。我们这样做是为了让所有的特征都在一个相似的范围内。如果我们需要绘制数据,这很有帮助,但也能给出更好的线性回归结果。我们使用下面的等式,你应该看到你的特征现在归一化为类似于图 5 的值。
mu = X.mean(0)
sigma = X.std(0) # standard deviation: max(x)-min(x)
xn = (X — mu) / sigma
图 jupyter 的屏幕截图
添加一列 1
现在在 X 上增加一列 1,以便稍后对我们的假设和成本函数进行更简单的矩阵操作。您的数据现在应该如图 6 所示,带有一列 1。
xo = np.hstack((np.ones((m, 1)), xn))
图 jupyter 的屏幕截图
梯度下降
创建梯度下降所需的变量。我们需要以下变量:
- 重复=重复梯度下降的次数
- θ=对于 X 的每个特征,增加一列θ0
- 成本历史=保持梯度下降的每次迭代的成本
repeat = 1000
lrate = 0.01
theta = np.zeros((n+1))
让我们定义一个成本函数,梯度下降将使用它来确定每个θ的成本。成本函数将实现以下成本等式。
def computeCost(X, y, theta):
m = len(y) # number of training examples
diff = np.matmul(X, theta) — y
J = 1 / (2 * m) * np.matmul(diff, diff) return J
我们现在进入梯度下降循环,在这里我们在每个循环上计算一个新的θ,并跟踪它的成本。参见下面的等式:
现在我们看到了这个方程,让我们把它放入一个方便的函数中
def gradientDescent(X, y, theta, alpha, num_iters):
# Initialize some useful values
m = len(y) # number of training examples
J_history = [] # repeat until convergance
for i in range(num_iters):
hc = np.matmul(X, theta) — y
theta -= alpha / m * np.matmul(X.transpose(), hc)
# Save the cost J in every iteration
J_history.append(computeCost(X, y, theta)) return theta, J_history
让我们运行梯度下降并打印结果
theta, J_history = gradientDescent(xo, y, theta, lrate, repeat)# Display gradient descent's result
print('Best theta computed from gradient descent: ')
print(f' {theta} ')
绘制梯度下降的成本
绘制成本历史以确保成本随着迭代次数的增加而减少。在绘制之后,您应该看到成本随着每次迭代而降低,如图 7 所示。
# Plot the convergence graph
plt.plot(np.arange(repeat), J_history, ‘-b’, LineWidth=2)
plt.xlabel(‘Number of iterations’)
plt.ylabel(‘Cost J’)
plt.show()
图 jupyter 的屏幕截图
预言;预测;预告
让我们用下面的等式来进行预测。
注意将一列 1 加到 X 上,然后使用矩阵乘法,一步就可以完成上面的等式。
y_pred = np.matmul(xo, theta)
评估预测
让我们使用均方根误差(RMSE ),它是平方误差平均值的平方根。下面是应用的等式,其结果将在以后用于比较。
让我们也算出每个预测占真实结果的百分比。然后用它来找出实际年龄的 90%到 110%之间的预测年龄。我们认为这对于计算最终精度是可以接受的。
# get RMSE error rate
print('RMSE: ',np.sqrt(metrics.mean_squared_error(y, y_pred)))# calculate our own accuracy where prediction within 10% is o
diff = (y_pred / y * 100)print('Mean of results: ',diff.mean())
print('Deviation of results: ',diff.std())
print('Results within 10% support/resistance: ', len(np.where(np.logical_and(diff>=90, diff<=110))[0]) / m * 100)
您现在将看到如下结果。如果我们对每一行的预测都在实际年龄的 10%以内,那么我们决定称之为成功。因此,我们最终达到了 90%的准确率。
图 jupyter 的屏幕截图
最后,让我们想象一下每个预测的准确性。自然, 100%是完美的预测。
plt.plot(np.arange(m), diff, '-b', LineWidth=1)
plt.xlabel('Number')
plt.ylabel('Accuracy %')
plt.show()
图 jupyter 的屏幕截图
所以,现在我们已经看到了使用矩阵操作的线性回归,让我们看看结果如何与使用 sklearn 进行比较。
第二步:使用 sklearn 的线性回归
让我们使用 sklearn 来执行线性回归。这次你可以看到它的代码少了很多。一旦我们有了一个预测,我们将使用 RMSE 和我们的支持/阻力计算来看看我们的手动计算如何与一个经过验证的 sklearn 函数进行比较。
from sklearn import metrics
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split# Split data
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=1)# Instantiate model
lm2 = LinearRegression()# Fit Model
lm2.fit(X_train, y_train)# Predict
y_pred2 = lm2.predict(X_test)# RMSE
print('RMSE: ',np.sqrt(metrics.mean_squared_error(y_test, y_pred2)))# calculate our own accuracy where prediction within 10% is ok
diff2 = (y_pred2 / y_test * 100)print('Mean of results: ',diff2.mean())
print('Deviation of results: ',diff2.std())
print('Results within 10% support/resistance: ', len(np.where(np.logical_and(diff2>=90, diff2<=110))[0]) / len(y_pred2) * 100)
图 jupyter 的屏幕截图
结论
你可以看到我们的 RMSE 和支持/抵制百分比在两种方法中是相似的。很自然,你可能会使用 sklearn,因为它的代码少得多,但是希望这个例子向你展示了这些等式是如何工作的。
自然语言处理在情感分类中的挑战
高等级不平衡的影响
克里斯·j·戴维斯在 Unsplash 上的照片
It 毫无疑问,对于任何数据科学和/或机器学习相关的任务来说,文本数据可能是我们可用的最大数据源。因此,许多复杂的和高性能的算法已经被发明来分析文本数据和预测它的情感。但是应用更先进的算法并不一定意味着我们的预测是高精度的。我们仍然需要回到基础,了解数据的本质,这对任何进一步的处理都是挑战。
我最近在自然语言处理领域进行了一项案例研究(这可能是我有史以来的第一个 NLP 项目),以分析推文及其对两大品牌的情绪:苹果和谷歌。这个项目的主要目的是将推文分为正面和负面或中性。这些数据集是由 Crowdflower 通过“data.world”提供的。数据集由大约 9000 条推文组成,分为四类:“正面”、“负面”、“中性”和“无法辨别”,我将它们重新组织成三类,如下所示:
从这里,人们可以很容易地看到,这是高度不平衡的阶级状况。尽管如此,我还是决定继续为快速脏分类任务准备数据。当然,我们必须至少做一些分类器可以接受的基本文本预处理。我应用的一些基本预处理包括:
- 扩展缩略词,如“不是”:“不是”、“不会”、“不会”、“不会”等。
- 小写所有文本,删除非字母字符串,@,超链接,停用词,少于 3 个字母的单词等。
下面是文本预处理代码片段的一个示例:
一些研究建议保留’ # ',在这种情况下没有任何区别
干净的推文示例:
在对预处理感觉良好之后,我开始使用简单的分类器,比如传统的朴素贝叶斯和随机森林。出于矢量化的目的,我使用了 TFIDF 矢量器。下面是分类的快速结果:
朴素贝叶斯分类报告
随机森林分类报告
很明显,如果我们研究“回忆”值,我们可以看到两个模型都存在不平衡数据。此外,随机森林高度过度适合训练数据。所以,在这一点上,我满怀希望地转向了神经网络。显然,首先想到的是 LSTM 和 GRU. *但是在实现这些模型之前,我改变了文本预处理策略,以避免删除一些上下文中的停用词。*像 LSTM 和 GRU 这样的网络需要令牌形式的文本 dat,可按如下示例创建:
使用新的预处理文本,我执行了三种类型的 LSTM:简单的单向 LSTM、双向 LSTM 和带有手套嵌入的双向 LSTM。此外,我还在类似配置的 GRU 网络上进行了培训。在我几乎所有的测试中,LSTM 和 GRU 都产生了相同的结果。因此,为了简洁起见,我将只显示 LSTM 的结果。对于预训练的手套模型,在模型中引入了一个*‘手套. 6b . 100d’*嵌入。包含 GLOVE 的代码随处可见,不过我还是提供下面的代码片段:
下图显示了上述三种 LSTMs 架构的培训结果。请注意,启用了提前停止,因此不同的模型在不同的时间停止。还要注意,我训练的最大历元是 20,这是因为在早期历元的验证数据中出现了大量训练过度。
那么我们在这里得到了什么?从一开始,更先进的模型就不能推广这个模型。戴着预训练手套模型的 LSTM 似乎表现稍好,但仍然差得很远!
还要记住,一开始的班级失衡,是不是影响了我们的模型表现?模型拟合参数中还包括类别权重字典。这对于提高模型性能没有任何帮助。还尝试了其他方法,如 SMOTE、随机过采样器/欠采样器。然而,这些方法对这个数据集都没有帮助。最后,我决定通过增加物理数据来解决班级不平衡的问题。
数据扩充
在这种情况下,我找到了推文文本,但是推文与苹果相关产品相关。然而,文本的情感可以与任何特定品牌无关,只要它有与情感相关的关键词。怀着这个希望,我将 只添加了负面分类的 到我当前的数据集中,并重新运行上述算法。
扩充后的类别分布
朴素贝叶斯分类报告
随机森林分类报告
虽然整体准确率只是略有提高,但我很高兴负面类的*【回忆】*有所增加。因为,在任何市场情绪分析中,尽可能准确地预测人们的负面观点是很重要的。那么,神经网络在新的扩充数据集中表现如何。
增强前后嵌入手套的双向 LSTMs
我们可以看到模型性能有一些轻微的改进。训练过度仍然是一个大问题。在这一点上,我应该把更多的注意力放在优化模型架构上。在测试不同模型架构组合时,先测试多个 LSTMs 层,然后测试密集层,最大的影响来自于 dropout 参数的调整。
注意:最大纪元被设置为 20,但是模型停止得更早
我们可以看到,在 LSTM 层之前包含漏失参数似乎表现得更好。我通常对一次下降超过 20%持谨慎态度,但在这个特定的案例中,高达 30-40%的下降似乎没问题。我的最终模型(LSTM 和 GRU)只能以大约 70%的准确率预测一条给定的推文。对于 NLP 任务来说,这并不是一个很好的结果,然而,考虑到具有挑战性的数据集,预处理 a 模型优化显示了有希望的结果。
最终模型对比:LSTM vs GRU
推文预测示例
最后的想法
该数据集需要做大量工作,尤其是数据扩充结果所支持的平衡类标签的收集。然而我的问题是:一个大约 9000 条推文的文本数据集,对于像 LSTM 和 GRU 这样的建筑来说足够好吗?
在下一步中,我将尝试对这个数据集使用 transformer 模型。
完整的笔记本和必要的文档可以在我的 github 网站上找到:https://github . com/sgautam 666/Brand _ 情操 _ 分析 _with_NLP
参考
https://data.world/crowdflower/brands-and-product-emotions
https://data.world/crowdflower/apple-twitter-sentiment
挑战 cy thon——高性能计算的 Python 模块。
现代的替代方案看起来很有希望,Python 可以以闪电般的速度运行。
来自 Pexels 的 Andrea Piacquadio 的照片
在最近的一篇文章中,我们讨论了如何运行 Python,比通常速度快 91 倍。在这篇文章中,我的目的是讨论上一篇文章中没有回答的问题。
与 Python 的传统性能修复技术——cy thon 相比,所提供的解决方案性能如何?
虽然 Python 是一种很棒的编程语言,但是它的性能是它的主要缺点。这种语法简单的优雅语言并不是为更快的计算而设计的。
多年来,Cython 一直在通过将 Python 代码转换为编译后的 C 程序来弥合这一差距。一系列科学计算包依靠 Cython 来加速计算。
让我们将它的性能与它的现代替代品进行比较。
我们将从使用普通 Python 计算质数开始。然后,我们再和它的 Cython 版本进行对比。我们将使用 Python 的多处理模块重复它们,以找出它的好处。
最后,我们将比较现代方法加速 Python 程序的性能。
Cython。vs Python 进行简单计算。
理解 Cython 优势的最直接方式是在基本计算中使用它。在这里,我们使用我在之前的基准测试中使用的相同的方法——计算一个数以下的质数的数量。
我们使用 cProfile 模块来测量每个计算的性能。cProfile 是众多测量代码运行时间的标准 Python 模块之一。
使用 Python 进行计算。
下面的代码将计算 35,000 以下的质数,并打印一份详细的性能报告。
代码片段由作者提供。
运行上面的 Python 代码片段时,输出可能如下所示。根据您的电脑规格,这些数字可能会有所不同。
作者截图。
因为可能有许多因素影响性能,所以明智的做法是多次进行实验,并使用平均值进行比较。在我的个人电脑上执行上述操作的平均时间是 18.721 秒。
使用 Cython 进行计算。
使用 Cython 不同于使用 Python。首先,我们需要将 Python 脚本转换成 c。
- 如果尚未安装 Cython,请安装它。
pip3 install --upgrade cython
2.用以下内容创建一个文件count_prime.pyx
。和以前一样。
代码片段由作者提供。
3.在同一个目录下创建另一个文件setup.py
,内容如下。它会把你的代码编译成 C 程序。
代码片段由作者提供。
4.现在,在终端窗口中运行下面的命令将创建我们的质数计数器函数的 C 版本。
python setup.py build_ext --inplace
5.另外,重命名(或移动)pyx 文件,否则可能会导致导入冲突。
mv count_prime.pyx count_prime_dep.pyx
6.最后,将函数导入到我们的主应用程序中,并像调用任何其他 python 函数一样运行它。
代码片段由作者提供。
运行这个程序的平均时间是 11.210 秒。这是我做的十个试验中的一个的样本报告。
作者截图。
从 18 秒减少到 11 秒是一个显著的进步。Cython 按照预期完成了工作。让我们重复多重处理场景的步骤。
Cython。多处理 vs Python。
Python 中的多处理模块是启动许多子流程的一种极好的方式。每个进程将运行您的代码的一个实例。如果处理器有空闲内核,它们也可以并行运行。
Python 多重处理。
下面的代码将在多个进程中计算 20K、25K、30K、35K 和 40K 以下的质数(如果可能的话,并行计算。)
代码片段由作者提供。
运行上述代码的平均时间为 29.7 秒。输出可能如下所示。
作者截图。
Cython 多重处理。
下面的代码将对我们之前编译的 C 版本重复同样的过程。
代码片段由作者提供。
这一过程的平均时间约为 18 秒,输出可能如下所示。
作者截图。
事实再次证明,Cython 在显著加快 python 处理时间方面是有效的。它将运行整个循环所需的时间减少了 37.9%。
使用 Tuplex 的高性能计算。
我们已经看到使用 Cython 取得了惊人的成功。在简单的质数计数和多重处理应用中,它大大减少了执行时间。
这能更快吗?我们在上一篇文章中讨论的 Tuplex 库比 Cython 版本的性能更好吗?
如果你在 Tuplex 上寻找一个详细的帖子,这里有一个。
单一进程的多路复用器。
Tuplex 将 Python 脚本转换成 LLVM bitecodes,并并行运行它们。结果是性能显著提高。这个新的库专注于数据管道,但它的应用不仅限于数据科学。
下面的代码将使用 Tuplex 运行一次计算。因为我们在并行化方法的 list 参数中只传递一个数字,所以 Tuplex 将在单线程中运行它。
由作者编写的代码片段。
tuplex 方法的平均结果为 9 秒。请注意,我们没有考虑 Tuplex 设置上下文所需的时间。
作者截图。
与 Cython 的 11 秒相比,这令人印象深刻。根据计算机的架构,结果也可能有所不同。但这个数字足够体面,足以表明 Cython 有一个值得尊敬的对手。
并行计算中的多路复用器。
最后一个比较还没有完成,这可能是 Tuplex 的核心目的——并行化。让我们用 Tuplex 计算同样的多重处理练习。调整 Tuplex 单进程示例的最后一行就可以达到这个目的。它应该是这样的。
代码片段由作者提供。
并行运行 Tuplex 代码的结果是惊人的平均 10 秒。完成同样的任务,Cython 用了 18 秒,plain Python 用了 29 秒。
作者截图。
结论
Cython 一直是 Python 程序员可用的主要(也是唯一的)性能补丁。图书馆经常做得很好;因此,许多其他科学计算软件包在内部使用 Cython。
然而,一个相对较新的图书馆 Tuplex 表现良好。在本文中,我们做了一个素数计数实验来比较 Tuplex 和 Cython 版本。执行时间似乎也大大减少了。
但是结果可能会因您的硬件、操作系统和系统状态而异。此外,由于 Tuplex 还不能用于生产,所以必须小心使用。另一方面,Cython 是稳定的,许多生产中的应用程序已经在使用它。
这种比较的全部意义不在于得出一个比另一个更好的结论。图普莱克斯要走到这一步还有很长的路要走。然而,如果 Cython 不适合你的项目,它不是一个死胡同。不再是了。
感谢阅读,朋友!看来你和我有许多共同的兴趣。我很乐意通过 LinkedIn、T2、Twitter 和 Medium 与你联系。
还不是中等会员?请使用此链接 成为 会员。你可以享受成千上万的有见地的文章,并支持我,因为我赚了一点佣金介绍你。
在 Pandas 中更改列数据类型
使用 PYTHON 进行动手数据分析
举例说明-。astype(),。convert_dtypes()和. to_numeric()
克里斯·劳顿在 Unsplash 上的照片
处理数据很少是直截了当的。大多数情况下,需要对导入的数据集执行各种转换,以便于分析。
在我的所有项目中,pandas 从来没有为导入的数据集的所有列检测到正确的数据类型。但同时,Pandas 提供了一系列方法来轻松转换列数据类型。
在这里,您将获得在 Pandas 中改变一个或多个列的数据类型的所有方法,当然还有它们之间的比较。
在整个阅读过程中,资源用📚,快捷方式用⚡️表示, 外卖 用表示📌。不要忘记查看一个有趣的💡在这篇文章的结尾。
您可以快速跟随本 笔记本 📌。
为了让您更容易理解,让我们创建一个简单的数据框架。
熊猫数据框|作者图片
使用这个例子,将更容易理解——如何在 Pandas 中更改列的数据类型。
熊猫。DataFrame.astype()
此方法用于将特定的数据类型分配给 DataFrame 列。
让我们将**int64**
指定为列Year
的数据类型。使用命令**.head()**
和**.info()**
,可以快速查看生成的数据帧。
df1 = df.copy()
df1["Year"] = df1["Year"].astype("int64")
df1.head()
df1.info()
按作者更改单列|图像的数据类型
类似地,可以将该列更改为 Python 中任何可用的数据类型。但是,如果数据类型不适合该列的值,默认情况下该方法会抛出一个**ValueError**
。
憎恨价值观错误???
熊猫有解决办法。此方法中的第二个可选参数μ. e .**errors**
让您可以自由处理错误。此选项默认为 raise,这意味着引发错误并且不返回任何输出。简单地说,将**‘ignore’**
赋给这个参数,忽略错误并返回原始值。
df1["Car"] = df1["Car"].astype("int64", errors='ignore')
❓ 想一次改变所有列的数据类型 ❓
⚡️只是将列名和数据类型对的字典传递给这个方法,问题就解决了。
df1 = df1.astype({"Year": "complex", "Rating": "float64",\
"Car": 'int32'}, errors='ignore')
更简单的是,通过在**astype()**
中直接传递数据类型,为所有列分配一个数据类型,就像下面的例子。
df1 = df1.astype("int64", errors='ignore')
df1.head()
df1.info()
一次更改所有列的数据类型|按作者排序的图像
如上图所示,Year
和Rating
列的**Dtype**
被修改为**int64**
,而其他非数字列的原始数据类型被返回而不抛出错误。
pandas.to_DataType()
好吧好吧,没有这样的方法叫做 pandas.to_DataType(),但是,如果把 DataType 这个词换成想要的数据类型,就可以得到下面 2 个方法。
pandas.to_numeric()
此方法用于将列的数据类型转换为数值类型。因此,根据列中的值,**float64**
或**int64**
将作为列的新数据类型返回。
df2 = df.copy()
df2["Rating"]=pd.to_numeric(df2["Rating"])
df2.info()
pandas.to_datetime()
在这里,列被转换为 DateTime 数据类型。该方法接受 10 个可选参数来帮助您决定如何解析日期。
df2 = df.copy()
df2["RealDate"] = pd.to_datetime(df2["Service"])
df2.info()
pandas.to_numeric()和 pandas.to_datetime() |作者图片
❓ 需要一次改变多列的数据类型 ❓
⚡ ️Use 的方法**.apply()**
df2[["Rating", "Year"]] = df2[["Rating",\
"Year"]].apply(pd.to_numeric)
类似于**pandas.DataFrame.astype()**
,方法**pandas.to_numeric()**
也给你处理错误的灵活性。
📚pandas . to _ numeric()
📚pandas . to _ datetime()
熊猫。DataFrame.convert_dtypes()
该方法将自动检测最适合给定列的数据类型。默认情况下,**Dtypes**
为**object**
的所有列都将被转换为字符串。
df3 = df.copy()
dfn = df3.convert_dtypes()
dfn.info()
熊猫。DataFrame.convert_dtypes() |作者图片
根据我的观察,这种方法对数据类型转换的控制很差
📚 **熊猫。data frame . convert _ dtypes()T22
总结一下,
在这篇快速阅读中,我演示了如何快速更改单个或多个列的数据类型。我经常使用**pandas.DataFrame.astype()**
方法,因为它对不同的数据类型提供了更好的控制,并且具有最少的可选参数。当然,基于分析需求,可以使用不同的方法,比如将数据类型转换为**datetime64(ns)**
方法**pandas.to_datetime()**
要简单得多。
如何看完所有的中篇文章?
今天就成为媒体会员&获得⚡ 无限制 ⚡访问所有媒体故事的权利。
当你在这里注册并选择成为付费媒介会员,我会从你的会员费中获得一部分作为奖励。
💡项目创意!!
从一个新的 数据集 开始,通过实践 数据争论 技术来评估和清理它,并将其存储在 SQL 数据库 中,以最终在Power BI中可视化它,这可能是一个好主意。
此外,这个项目想法可以用其中给出的资源来实现。正如我常说的,我乐于接受建设性的反馈和通过 LinkedIn 分享知识。
感谢您的阅读和宝贵时间!
如何更改 PySpark 数据框架中的列类型
讨论如何转换 PySpark 数据帧中列的数据类型
Javier Allegue Barros 在 Unsplash 上拍摄的照片
介绍
PySpark 中一个相当常见的操作是类型转换,当我们需要更改数据帧中特定列的数据类型时,通常需要进行类型转换。例如,这很常见(而且是一种不好的做法!)将日期时间存储为字符串,甚至将整数和双精度数存储为StringType
。
在今天的简短指南中,我们将探讨如何在 PySpark 中更改某些 DataFrame 列的列类型。具体来说,我们将讨论如何使用
cast()
功能selectExpr()
功能- Spark SQL
首先,让我们创建一个示例数据框架,我们将在本文中引用它来演示一些概念。
from pyspark.sql import SparkSession# Create an instance of spark session
spark_session = SparkSession.builder \
.master('local[1]') \
.appName('Example') \
.getOrCreate()df = spark_session.createDataFrame(
[
(1, '10-01-2020', '1.0', '100'),
(2, '14-02-2021', '2.0', '200'),
(3, '15-06-2019', '3.0', '300'),
(4, '12-12-2020', '4.0', '400'),
(5, '01-09-2019', '5.0', '500'),
],
['colA', 'colB', 'colC', 'colD']
)
df.show()
*+----+----------+----+----+
|colA| colB|colC|colD|
+----+----------+----+----+
| 1|10-01-2020| 1.0| 100|
| 2|14-02-2021| 2.0| 200|
| 3|15-06-2019| 3.0| 300|
| 4|12-12-2020| 4.0| 400|
| 5|01-09-2019| 5.0| 500|
+----+----------+----+----+*df.printSchema()
*root
|-- colA: long (nullable = true)
|-- colB: string (nullable = true)
|-- colC: string (nullable = true)
|-- colD: string (nullable = true)*
在接下来的章节中,我们将展示如何将colB
、colC
和colD
列的类型分别更改为DateType
、DoubleType
和IntegerType
。
使用 cast()函数
转换数据类型的第一个选项是将输入列转换为指定数据类型的[pyspark.sql.Column.cast()](https://spark.apache.org/docs/3.1.1/api/python/reference/api/pyspark.sql.Column.cast.html)
函数。
from datetime import datetime
from pyspark.sql.functions import col, udf
from pyspark.sql.types import DoubleType, IntegerType, DateType # UDF to process the date column
func = udf(lambda x: datetime.strptime(x, '%d-%m-%Y'), DateType())**df = df \
.withColumn('colB', func(col('colB'))) \
.withColumn('colC', col('colC').cast(DoubleType())) \
.withColumn('colD', col('colD').cast(IntegerType()))** df.show()
*+----+----------+----+----+
|colA| colB|colC|colD|
+----+----------+----+----+
| 1|2020-01-10| 1.0| 100|
| 2|2021-02-14| 2.0| 200|
| 3|2019-06-15| 3.0| 300|
| 4|2020-12-12| 4.0| 400|
| 5|2019-09-01| 5.0| 500|
+----+----------+----+----+*df.printSchema()
*root
|-- colA: long (nullable = true)
* ***|-- colB: date (nullable = true)
|-- colC: double (nullable = true)
|-- colD: integer (nullable = true)***
注意,为了将字符串转换成DateType
,我们需要指定一个 UDF 来处理字符串日期的确切格式。
使用 selectExpr()函数
或者,您可以通过指定相应的 SQL 表达式来使用[pyspark.sql.DataFrame.selectExpr](https://spark.apache.org/docs/3.1.1/api/python/reference/api/pyspark.sql.DataFrame.selectExpr.html)
函数,该表达式可以转换所需列的数据类型,如下所示。
**df = df.selectExpr(
'colA',
'to_date(colB, \'dd-MM-yyyy\') colB',
'cast(colC as double) colC',
'cast(colD as int) colD',
)**df.show()
*+----+----------+----+----+
|colA| colB|colC|colD|
+----+----------+----+----+
| 1|2020-01-10| 1.0| 100|
| 2|2021-02-14| 2.0| 200|
| 3|2019-06-15| 3.0| 300|
| 4|2020-12-12| 4.0| 400|
| 5|2019-09-01| 5.0| 500|
+----+----------+----+----+*df.printSchema()
*root
|-- colA: long (nullable = true)
* ***|-- colB: date (nullable = true)
|-- colC: double (nullable = true)
|-- colD: integer (nullable = true)***
使用 Spark SQL
最后,您甚至可以使用 Spark SQL,以类似于我们使用selectExpr
函数的方式来转换所需的列。
# First we need to register the DF as a global temporary view
df.createGlobalTempView("df")**df = spark_session.sql(
"""
SELECT
colA,
to_date(colB, 'dd-MM-yyyy') colB,
cast(colC as double) colC,
cast(colD as int) colD
FROM global_temp.df
"""
)**df.show()
*+----+----------+----+----+
|colA| colB|colC|colD|
+----+----------+----+----+
| 1|2020-01-10| 1.0| 100|
| 2|2021-02-14| 2.0| 200|
| 3|2019-06-15| 3.0| 300|
| 4|2020-12-12| 4.0| 400|
| 5|2019-09-01| 5.0| 500|
+----+----------+----+----+*df.printSchema()
*root
|-- colA: long (nullable = true)
* ***|-- colB: date (nullable = true)
|-- colC: double (nullable = true)
|-- colD: integer (nullable = true)***
最后的想法
在今天的简短指南中,我们讨论了在 PySpark 中更改 DataFrame 列类型的几种不同方法。具体来说,我们探索了如何将withColumn()
函数与cast()
结合使用,以及如何使用更多类似 SQL 的方法,如selectExpr()
或 Spark SQL。
成为会员 阅读媒体上的每一个故事。你的会员费直接支持我和你看的其他作家。你也可以在媒体上看到所有的故事。
你可能也会喜欢
用于数据湖数据接收的变更数据捕获(CDC)
意见
随着数据量持续爆炸式增长,业务用户越来越要求持续访问洞察,实时提取所有底层数据不再可行。相反,必须部署解决方案来识别和复制更改日志,以支持接近实时的分析应用程序。
适当的数据接收策略对于任何数据湖的成功都至关重要。这篇博文将提出一个案例,像 Oracle Golden Gate 、 Qlik Replicate 和 HVR 这样的变更数据捕获(CDC)工具最适合从频繁刷新的 RDBMS 数据源中提取数据。
图 1:数据湖的典型数据接收情况。作者图片
大量的数据传输时间限制了数据湖的采用
网络上的大量数据传输时间是限制数据湖采用的一个关键因素。如今,在典型的大型企业中,许多事务性数据源继续驻留在内部数据中心。同时,大多数分析平台已经迁移到云,以利用效用计算能力和云提供商的按需规模。对于大多数大型企业来说,连接到云提供商的冗余、专用 10 Gbps 网络链路非常常见,每月花费数万美元。虽然听起来不错,但在处理超过几 TB 的大型数据集时,10 Gbps 连接有很大的局限性。
图 2:大型数据集传输时间。图片由作者使用谷歌数据(参考下文)
上图描述的数据传输时间是乐观的估计。网络延迟、拥塞、跳数和服务器响应时间等其他因素可能会使真实世界的数据传输速度降低许多数量级。底线是满负荷复制对于大型数据集是不实际的。
自主开发的变更数据捕获(CDC)解决方案的局限性
许多数据工程团队开发自主开发的 CDC 解决方案。自主开发的 CDC 解决方案有两种主要模式:
- 使用时间戳的 CDC 计算 : 这种模式需要在源表上创建、更新和终止时间戳。任何插入、更新或删除行的进程也必须更新相应的时间戳列。不允许硬删除。一旦满足这些条件,计算变更日志就变得很简单了。然而,实施前面讨论的约束并不是一件小事。因此,实际上来说,典型数据库中很少一部分表具有这些时间戳或遵循这种模式。它还创建了源表和提取、转换&加载(ETL)代码之间的紧密耦合。
图 3:使用时间戳列的 CDC 计算。作者图片
- 使用减查询的 CDC 计算 : 这与其说是模式,不如说是反模式。然而,这似乎并没有阻止这种模式在许多生产系统的 CDC 计算中的扩散。在源数据库和目标数据库之间创建一个 DB 链接,并执行一个负 SQL 查询来计算 changelog。这种模式导致大量数据在源数据库和目标数据库之间流动。此外,这种模式只有在源数据库和目标数据库是同一类型的情况下才能工作,例如 Oracle 到 Oracle。
图 4:使用 minis 查询的 CDC 计算。作者图片
上面讨论的两种 CDC 方法都会给源数据库带来很大的负载。此外,减号查询模式也会导致显著的网络负载。
图 5:本土 CDC 计算对网络、CPU 和磁盘的不利影响。作者图片
CDC 工具如何计算 changelog?
CDC 工具通过为 changelog 计算挖掘数据库日志来最小化网络负载和源数据库。
每个支持事务的数据库在将任何更改(插入、更新和删除)写入数据库之前,都会先将其写入数据库日志。这样做是为了确保交易的完整性,避免意外事件,如电源故障等。,而交易仍在进行中。
数据库日志根据文件大小或时间间隔事件在活动日志(重做日志)和归档日志之间循环。根据目标数据库的数据延迟要求,CDC 工具可以访问源数据库的活动日志或归档日志。
图 6:典型 CDC 工具的基本架构。图片由作者提供,灵感来自 Qlik 博客。(参考下文)
由于 CDC 工具只从源数据库日志中读取数据,因此不会增加源数据库的负载。此外,变更日志通常比源表小很多数量级。这种更改日志在网络上的这种流动不会导致任何网络负载问题。
图 7: CDC 工具最小化源数据库和网络上的负载。作者图片
由于数据库日志只包含关于最近的插入、更新和删除的信息,所以 changelog 计算变得很简单。然而,由于有许多数据库供应商,每个供应商都有自己的(有时是专有的)日志格式,所以这种任务最好留给商业 CDC 工具供应商。
CDC 工具 ike Oracle Golden Gate 、 Qlik Replicate 和 HVR 允许以网络高效的方式将事务性数据源与分析数据库近乎实时地同步,同时最大限度地减少对源系统的影响,因此最适合从频繁刷新的 RDBMS 数据源获取数据。
商业 CDC 工具的其他优势
除了最大限度地减少对源系统和网络的影响,大多数商业 CDC 工具还提供其他优势,如:
- 企业级弹性
- 减少 ETL 计算占用空间
- 简化的 ETL 代码库
- 动态轻量级转换
- 失去源数据库和数据接收代码之间的耦合
那么为什么 CDC 工具没有更受欢迎呢?
CDC 工具未被更广泛采用的首要原因是成本。CDC 工具供应商在理解许多数据库的日志格式方面投入了大量资金,这些数据库本身可能会继续发展。这种对持续投资的要求将真正的 CDC 工具前景限制在少数几个关键参与者手中,允许他们为自己的产品收取溢价。
CDC 工具没有被广泛采用的第二个原因是,出于安全原因,源系统 DBA 不愿意向第三方 CDC 工具授予数据库日志级别的访问权限(特权访问)。
以上两种担忧都是有根据的,但是可以通过耐心和努力克服。您需要让 CDC 供应商参与价格谈判,以获得有利的定价条款。如果您还与您的 DBA 进行了详细的讨论,告知他们价值并解决他们的安全问题,那将会很有帮助。
通过实施 CDC 工具将数据吸收到数据湖中,可以释放出巨大的企业价值。我会鼓励你踏上那段旅程。CDC 工具是最好的解决方案之一,可以帮助管理爆炸式增长的数据量和业务用户对接近实时访问洞察的需求,至少在 RDBMS 源频繁刷新数据的情况下是如此。
免责声明:这是个人博文。此处表达的观点仅代表我个人的观点,并不代表我现任或前任雇主的观点。所有内容仅用于教育目的,不保证适用性。
如何在 Matplotlib 中改变图形的大小
讨论如何在 Python 中调整用 matplotlib 创建的图形的大小
由 Deon Black 在 Unsplash 上拍照
介绍
在可视化数据时,调整通过 Python 中的matplotlib
生成的图形的大小是一项常见的任务。在今天的简短指南中,我们将讨论几种调整生成图大小的可能方法。
具体来说,我们将讨论如何做到这一点:
- 使用
matplotlib.pyplot.figure()
- 使用
set_size_inches()
- 通过修改
rcParams['figure.figsize']
此外,我们将讨论如何使用现有(默认)大小的因子/比率来调整图形的大小。
首先,让我们使用一些虚拟数据创建一个图表,我们将在本文中使用这些数据来演示几个概念。
import matplotlib.pyplot as pltx = y = range(1, 10)plt.plot(x, y)
plt.show()
下图是使用默认尺寸生成的,如rcParams['figure.figsize']
中所定义。
使用图形
您的第一个选择是调用[matplotlib.pyplot.figure](https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.figure.html)
,它用于创建一个新图形或激活一个现有图形。该方法接受一个名为figsize
的参数,用于指定图形的宽度和高度(以英寸为单位)。此外,您甚至可以指定dpi
,它对应于以每英寸点数为单位的图形分辨率。
import matplotlib.pyplot as plt
**from matplotlib.pyplot import figure****figure(figsize=(3, 2), dpi=80)**x = y = range(1, 10)plt.plot(x, y)
plt.show()
使用set_size_inches
第二个选项是[matplotlib.figure.set_size_inches()](https://matplotlib.org/stable/api/figure_api.html?highlight=figure#matplotlib.figure.Figure.set_size_inches)
,用于设置图形的尺寸,单位为英寸。
import matplotlib.pyplot as pltx = y = range(1, 10)plt.plot(x, y)
**plt.gcf().set_size_inches(3, 2)** plt.show()
修改rcParams
如果您想在不使用图形环境的情况下修改图形的大小,那么您也可以更新matplotlib.rcParams
,它是用于处理默认 Matplotlib 值的[RcParams](https://matplotlib.org/stable/api/matplotlib_configuration_api.html#matplotlib.RcParams)
的一个实例。
import matplotlib.pyplot as plt**plt.rcParams['figure.figsize'] = (3, 2)**x = y = range(1, 10)plt.plot(x, y)
plt.show()
请注意,上述内容将对生成的每个图形产生影响,除非您为特定图形指定不同的大小。如果出于任何原因,您想要恢复该参数的默认值,您可以简单地使用如下所示的rcParamsDefault
plt.rcParams['figure.figsize']=plt.rcParamsDefault['figure.figsize']
使用系数调整图形大小
现在,如果您希望使用与另一个图形相关的硬编码因子或比率来调整图形的大小,那么您可以使用以下命令:
figure_size = plt.gcf().**get_size_inches**()
factor = 0.8plt.gcf().**set_size_inches**(factor * figure_size)
最后的想法
在今天的简短指南中,我们讨论了如何调整使用matplotlib
库生成的图形的大小。我们探讨了一些可能的选项,但您应该确保使用符合您需求的选项(例如,取决于您是想要指定所有图形和绘图的大小,还是仅指定一个特定的)。
成为会员 阅读介质上的每一个故事。你的会员费直接支持我和你看的其他作家。
你可能也会喜欢
[## 如何将 Python 包上传到 PyPI
towardsdatascience.com](/how-to-upload-your-python-package-to-pypi-de1b363a1b3)
如何更改 Matplotlib 图中的字体大小
数据可视化
了解如何在 matplotlib 图形标题、轴标签和图例中更改字体大小
介绍
通常,你可能需要调整用matplotlib
创建的图形的默认字体大小,以确保所有的元素都被恰当地可视化并易于阅读。在今天的简短指南中,我们将讨论如何更改使用matplotlib
库生成的图中的字体大小。具体来说,我们将探索如何
- 全局更改字体大小(这意味着它将适用于所有生成的图)
- 更改单个组件的尺寸,如轴、图形标题、刻度标签等。
- 以及如何改变已经生成的特定绘图的字体大小
首先,让我们使用一些虚拟数据创建一个示例图,我们将在本文中使用它作为参考,以演示一些概念。
import matplotlib.pyplot as pltplt.plot([1, 3, 5, 7], color='red', label='1st Line')
plt.plot([2, 4, 6, 8], color='blue', label='2nd Line')plt.suptitle('Example Figure')
plt.xlabel('This is x-axis')
plt.ylabel('This is y-axis')plt.legend()
plt.show()
输出图如下所示:
这是我们的示例图—来源:作者
更改所有图和组件的字体大小
如果您想改变所有创建的图形的字体大小以及每个单独图形中显示的所有组件,包括标题、图例、轴标签等,那么您需要更新[rcParams](https://matplotlib.org/stable/api/matplotlib_configuration_api.html#matplotlib.RcParams)
中的相应参数,它是一个包含许多可定制属性的字典。
import matplotlib.pyplot as plt# Option 1
**plt.rcParams['font.size'] = 18**# Option 2
**plt.rcParams.update({'font.size': 18})**
更新font.size
参数后的输出图如下所示:
来源:作者
如前所述,这将产生全局影响,并且会影响图中所示的几乎所有组件,在大多数情况下,这可能不是您真正想要的。
更改单个组件的字体大小
有时候,你可能希望一些组件的字体大小不同于其他组件。例如,您可能需要不同地调整图形标题和图例的字体大小。在这种情况下,您必须通过修改相应的参数来指定每个组件的字体大小,如下所示。
import matplotlib.pyplot as plt# Set the default text font size
**plt.rc('font', size=16)**# Set the axes title font size
**plt.rc('axes', titlesize=16)**# Set the axes labels font size
**plt.rc('axes', labelsize=16)**# Set the font size for x tick labels
**plt.rc('xtick', labelsize=16)**# Set the font size for y tick labels
**plt.rc('ytick', labelsize=16)**# Set the legend font size
**plt.rc('legend', fontsize=18)**# Set the font size of the figure title
**plt.rc('figure', titlesize=20)**
更改特定绘图的字体大小
前面介绍的解决方案将适用于生成的每个图形。如果要调整已创建的单个图的字体大小,则可能需要为每个单独的组件指定字体大小。假设你已经创建了一个支线剧情,那么下面的代码应该可以完成这个任务:
import matplotlib.pyplot as pltax1 = plt.subplot(
111,
xlabel='This is x-axis',
ylabel='This is y-axis',
title='Example subplot'
)**ax1.title.set_fontsize(18)
ax1.xaxis.label.set_fontsize(18)
ax1.yaxis.label.set_fontsize(18)
map(lambda p: p.set_fontsize(18), ax1.get_xticklabels())
map(lambda p: p.set_fontsize(18), ax1.get_yticklabels())**plt.show()
最后的想法
在今天的简短指南中,我们讨论了几种改变用matplotlib
库生成的 Python 图中字体大小的方法。我们探讨了如何为创建的每个组件和绘图更改字体大小,以及如何仅为特定图形更改字体大小。
最后,我们还讨论了如何调整特定组件的字体大小。这通常在您希望图形标题和图例具有不同字体大小时很有用。
成为会员 阅读媒体上的每一个故事。你的会员费直接支持我和你看的其他作家。你也可以在媒体上看到所有的故事。
https://gmyrianthous.medium.com/membership
你可能也会喜欢
https://codecrunch.org/what-does-if-name-main-do-e357dd61be1a
改变您在 Power BI 中处理大型数据集的方法
由于内存的限制,当您试图在 Power BI Desktop 中加载具有数亿行的大型数据集时,您可能会遇到问题。让我们探索数据流来实现这一点。
出发点
我的一个客户的表有 1.26 亿行,并且还在增长。
他的问题是如何在只有 8gb RAM 的 Power BI 桌面中加载这些数据。
而且,他对数据源没有控制权。这种缺乏控制的情况意味着他不能创建带有过滤器的数据库视图,以减少 Power BI Desktop 初始加载的数据集。
至少可以说,这个挑战是有问题的。也许你在过去已经经历过这些。
我有了用 Power BI 数据流来解决这个问题的想法。
为此,我使用了放大的 Contoso 数据集:
图 1 —原始数据集(图片由作者提供)
首先,我将解释解决方案的外观。
然后,我向您展示设置解决方案的步骤。
解决办法
下图显示了该解决方案的体系结构:
图 2 —解决方案的架构(作者提供的图表)
如您所见,我设置了两个数据加载:
- 用数据流直接加载 Power BI 服务中的事实表
- 将所有维度表加载到 Power BI 桌面
这样做的目的是避免 Power BI Desktop 加载数百万行。
我在 Power BI Desktop 中使用了一个预览功能(在撰写本文时预览),它允许我将 Power BI 数据集的实时连接与来自另一个数据源的其他(导入的)表结合起来。
构建解决方案
第一步是分析源数据,并找出如何过滤数据。
目标是将数据量减少到最小,因为我必须将数据加载到 Power BI Desktop 一次。
在我的例子中,我可以简化两个事实表中的数据,以一种简单的方式只加载一年的数据:
图 3 —每个表格一年数据的行数(图片由作者提供)
接下来,我在 Power BI 服务上创建一个数据流。
在我的例子中,我使用了高级的每用户工作空间,以便能够使用大型数据集存储格式:
图 4 —在 Power BI 服务中创建一个新的数据流(图片由作者提供)
下一步是为数据流选择操作:
图 5 —为新数据流选择动作(图片由作者提供)
在我的例子中,我想添加新的表。
为了添加新表,我需要配置源服务器和数据库:
图 6 —新表的数据源(图片由作者提供)
我在我的 Azure 虚拟机上安装了本地数据网关。为了存储我的示例数据库,我在同一个虚拟机上安装了 SQL Server。首先,我必须在网关中配置服务器和数据库。其次,我必须在数据源连接中选择网关。
当您希望使用存储在网关连接中的凭据时,可以保留用户名和密码,也可以为数据源输入其他凭据。
现在,您可以使用一个看起来非常类似于 Power BI 中的 Power Query 编辑器的界面来选择所需的表,并根据需要向数据添加转换:
图 7 —数据流中的查询编辑器(图片由作者提供)
我可以添加一个过滤步骤来过滤数据,如上所述:
图 8 —在 Power Query 中过滤数据(图片由作者提供)
这种可能性是数据流的美妙之处:我可以像在 Power Query 中一样添加过滤器,而无需将数据下载到 Power BI Desktop。数据留在云中。
只要您按下保存并关闭,您就可以开始数据加载。这个过程花费的时间很少,因为我只加载了一小部分数据。
现在,数据集在我的工作区中可见:
图 9 —我的工作空间中的数据流(图片由作者提供)
前缀 DF_ stand 代表数据流,我需要一个惟一的名称,因为我将创建一个同名的数据集。但是我不能有两个同名的对象。
不幸的是,不可能在线创建数据集。
你可以在 idea.powerbi.com 上找到一个关于这个问题的条目:基于数据流的数据集服务
为此,我必须在 Power BI Desktop 中创建一个数据集。
我可以选择 Power BI 数据流作为源:
图 10—Power BI 桌面中作为源的数据流(图片由作者提供)
我将两个表都添加到数据集中,并将报表作为 ContosoRetailDW_Big_BigFacts 发布到服务。
但是这种方法有一个缺陷,正如我在构建结束时发现的那样。请读完,因为我留下它是为了说明这种特定方法的一个缺点。
下一步是编辑数据流,删除两个表上的过滤器并刷新数据。我需要刷新数据流和 Power BI 数据集中的数据。这意味着您必须将相同的数据存储两次。
目前,我不知道这个问题的解决方案。
但是您可以配置数据流和数据集的增量刷新,以减少刷新次数:Power BI 中数据集的增量刷新— Power BI | Microsoft Docs
为了创建最终的 Power BI 报告,我必须将带有两个事实表的数据集添加到新的 Power BI 报告中:
图 11 —从云中获取 Power BI 数据集(图片由作者提供)—名称错误
在右下角的状态栏中,我可以看到我正在使用实时连接:
图 12 —带有实时连接的状态栏(作者提供的图片)
我需要为下一步启用预览功能:
图 13-支持 PBI 数据集的直接查询(图片由作者提供)
单击“了解更多”链接,转到文档页面。在那里你可以找到关于这个特性的有价值的信息。
启用此功能并重启 Power BI Desktop 后,状态栏看起来如上图所示。
我一单击“转换数据”按钮,就会收到一条消息,提示实时连接将被更改为直接查询连接。这一更改允许我向数据模型添加额外的表。
现在,状态栏看起来像这样:
图 14 —直接查询模式下的数据模型(图片由作者提供)
下一步是将所有需要的维度表和表之间的所有关系添加到数据模型中。
当我试图将第二个事实表连接到日期表时,我得到了下面的错误消息:
图 15 —多重关系的错误消息(作者提供的图片)
似乎我必须创建两个数据集:每个事实表
一个,然后在直接查询模式下将两个数据集都添加到报告中。无论如何,我仍然能够使用一个数据流来准备我的数据。
这样,我的模型并不完美,但我可以用它作为原型展示给我的客户。
这个问题就是我在将两个事实表加载到一个数据集中时提到的小故障。
结论
当您开始比较两个 Power BI 文件时,这种方法最显著的效果是显而易见的。一个包含整个数据集,另一个包含复合模型,如本文所述:
图 16 —完整数据集和复合模型之间的大小比较(图片由作者提供)
复合模型的尺寸略大于原尺寸的 1/1000。
而且打开这个模型只需要几秒钟。维度表的数据刷新也需要很短的时间。
缺点是对数据流和带有事实表的数据集执行完全加载需要一个多小时。
但是在使用复合数据模型时,您需要理解所有可能的含义。
SQLBI 在 YouTube 上发布了一个关于这个主题的视频:
数据流和复合模型的结合为管理大型数据集打开了一个全新的世界。您可以在不同的报告中多次重用数据流或数据集的数据,而无需多次重新加载数据。
我希望你能从我的方法中得到新的想法。
市场危机的动态变化:对过去二十年国家、部门和股票行为的回顾
演化金融市场行为的数学研究
在本文中,我们研究了过去 20 年中国家金融指数、行业金融指数和股票的行为和相似性。首先,我们引入了一种新的方法来确定 20 个国家和 11 个部门在时间序列结构突变方面的相似性。我们引入了一个新的度量,可以量化任何两个候选集之间的距离,其中概率分布决定了各种元素位置周围的不确定性。接下来,我们转向美国股市,在这里我们进行了三个独立的实验。首先,我们分析了股票危机相关性随时间的演变,强调了近年来在市场恐慌时期股票相似性的增加。接下来,我们研究股票轨迹随时间变化的集体相似性,并证明在危机时期轨迹之间的距离更大。最后,我们通过时变主成分分析来探索我们的股票市场集合的动态。我们强调了在表现出同质行为的资产之间分散投资的当前困难领域,并提出了可能改善投资者多样化的方法。
本次研究的动机:
2020 年 3 月至 6 月,由于新冠肺炎危机,全球市场表现出极端行为。投资者在资产价格下跌和波动中挣扎,因为许多“传统的”多样化战略似乎并不有效。事实上,资产内部的相关性似乎特别高——即使相对于以前的市场危机。这引发了我们的好奇心,我们认为有必要进行彻底的调查。
尽管金融市场参与者可以获得大量数据,但许多投资者倾向于关注最近的过去。这是明智的。市场动态在不断变化,尽管历史可能会押韵,但它肯定不会重演,2020 年的金融市场行为不太可能与 2000 年的完全相同;因为在过去的二十年里,金融市场的许多方面都发生了巨大的变化。这篇论文是带着不同的目的写的。我们希望研究国家、行业和股票行为在过去 20 年中是如何演变的——尤其是在危机时期。我们引入新的方法来检查异常行为、轨迹和时变动态的变化。
我们将分析分为两部分。首先,我们研究国家和部门之间结构突变的相似性。这种分析对于任何希望根据国家或行业风险分散投资的资产配置者或投资者都是有用的。其次,我们研究标准普尔 500 股票,探索相关性、轨迹和时变动态的演变。这项工作的见解可以被任何对股票在过去 20 年中表现出的动态现象感兴趣的全球股票投资者所利用。
数据:
我们的国家和行业数据分别涵盖 2002 年 4 月 1 日至 2020 年 8 月 10 日和 2000 年 4 月 1 日至 2020 年 8 月 10 日,并且每天都进行测量。我们分析的国家包括:澳大利亚、巴西、加拿大、中国、法国、德国、印度、印度尼西亚、意大利、日本、韩国、荷兰、俄罗斯、沙特阿拉伯、西班牙、瑞士、土耳其、英国和美国。我们分析的行业包括:通信、非必需消费品、消费品、能源、金融、医疗保健、工业、信息技术、材料、房地产和公用事业。我们的股票数据涵盖 2000 年 3 月 1 日至 2020 年 8 月 10 日。我们研究了从开始到分析窗口结束的所有标准普尔 500 股票。我们还剩 347 只股票。我们所有的数据都来自彭博。
古怪行为建模:
在本节中,我们研究了 20 个国家指数和 11 个金融市场部门的异常行为的相似性。为了确定相似性,我们将变化点检测方法应用于每个时间序列,并生成变化点集。重要的是,我们使用一种基于功率谱变化检测变化点的方法。这缓解了许多变化点检测方法在面对相关数据时所面临的问题。先前的工作已经证明,本文中应用的方法能够恰当地检测分段自回归过程中的变化点,突出了该算法划分相关数据的能力。对于对所应用的方法感兴趣的人,请参见以下论文之一:
https://www . tandfonline . com/doi/ABS/10.1080/01621459 . 2012 . 716340
https://arxiv.org/pdf/2003.02367.pdf
由于相关性在金融时间序列中是常见的,我们使用上述技术。这种方法是在贝叶斯框架中实现的,并捕获候选变更点周围的不确定性。当测量集合之间的距离时,我们调整先前引入的半度量以考虑候选变化点周围的不确定性。
国家相似度:
国家金融指数的不规则行为集群结构表明,存在一个主要的国家集群,以及其他几个分散的集群。主要集群包括美国、韩国、土耳其、英国、法国、意大利、瑞士、荷兰、加拿大、澳大利亚、德国和沙特阿拉伯。离群国家包括:俄罗斯、巴西、西班牙和中国。这些集群成员和相关的变化点可能是由于这些国家的地理位置和政治关联非常相似,导致在英国退出欧盟等事件期间出现类似的市场行为。值得注意的是,西班牙决心要明显不如欧洲同行相似。集合中最不正常的国家是中国。这并不奇怪,因为许多与当地股票市场相关的特殊限制可能会提供与其他金融市场不同的动力。
扇区相似度:
扇区异常行为树状图由两个明显分开的簇组成。除了原材料和主要消费品之外,主要类别包括所有库存。有趣的是,公用事业、通信和 IT 行业在 2012 年至 2019 年期间没有出现结构性断裂。相比之下,在这个时间窗口期间,在材料部门时间序列中检测到几个变化点。在 2012 年至 2019 年期间,在主要集群(金融、非必需消费品等)的行业时间序列中也发现了变化点。).图 4 显示了通信、公用事业和材料行业的日志回报和检测到的变化点。人们可以看到 2012 年至 2019 年期间结构断裂传播的明显差异。
对比:
为了比较国家和部门之间的相似程度,我们计算了异常行为矩阵的矩阵规范,并根据矩阵中元素的数量对其进行归一化(因为在我们之前的实验中,国家/部门的数量不同)。国家异常距离矩阵标准高于部门异常距离矩阵标准。部门规范中的较小值表明,部门之间的异常行为比国家之间的异常行为更加相似。这可能表明,就国家而言(相对于部门而言),多样化对投资者的好处更大。
权益分析:
在本节中,我们研究了 347 只美国股票,时间跨度约为 20 年。我们将分析分为三个独立的部分。首先,我们检查在不同的离散(和不同的)时间周期内相关系数的行为。接下来,我们研究滚动股票轨迹的集体相似性。最后,我们探讨时变特征谱——作为突出“市场效应”最明显的时间段的一种手段(由领先特征值的大小表示)。
相关性:
在本节中,我们将分析窗口划分为 5 个时段:GFC、峰值 GFC、中期(GFC 和 COVID 之间的时段)、COVID 和峰值 COVID。每个时间分区的日期窗口如下:
- GFC:2007 年 1 月 1 日至 2010 年 5 月 31 日
- GFC 峰:2008 年 9 月 2 日至 2009 年 6 月 1 日
- 临时日期:2010 年 6 月 1 日至 2020 年 2 月 28 日
- COVID:2020 年 3 月 2 日–2020 年 8 月 31 日
- COVID 峰值:2020 年 3 月 2 日–2020 年 5 月 29 日。
在每个周期内,我们计算集合中所有股票的相关矩阵,并绘制相关系数的分布。
图 5 显示了两个发现。首先,在危机时期,股票的相关性明显增强。这在 GFC 和新冠肺炎市场的崩盘中都有所反映,但这种相关性的峰值在这两次崩盘的高峰期更加明显。也就是说,峰值 GFC 和峰值 COVID 分布分别比 GFC 和 COVID 分布更向右集中。其次,这种相关性的增加在最近变得更加明显。图 5 表明,在危机时期,股票行为变得更加相似。这一发现的含义令人震惊,并表明传统的马克维茨启发的投资组合多样化框架必须改变,至少在纯股票投资组合的背景下。
滚动轨迹分析:
在这一节中,我们研究股票轨迹的滚动相似性。为此,我们通过 L1 范数归一化所有轨迹,并在 45 天滚动的基础上计算所有候选轨迹之间的距离。图 6 表明,危机时期提供了最大的轨迹异质性。特别是,网络泡沫、GFC 和新冠肺炎市场危机都在滚动标准计算中显示峰值。
虽然在危机期间,轨迹距离矩阵规范有所增加,但轨迹的方向仍然基本一致。在危机期间,股市的主要方向是下跌。一致性在我们的相关分析中得到证实,其中相关系数更强地为正。这很有意思。
时变主元分析:
最后,我们实现了时变主成分分析,其中我们绘制了每个特征向量所表现出的解释方差的百分比。假设第一个特征向量代表市场的集体力量,当特征谱的第一个元素出现尖峰时,它表示集体市场行为的力量增加。
图 7 显示了互联网泡沫、GFC 和新冠肺炎市场危机期间特征谱第一元素的峰值。这证实了我们在相关性研究中的早期发现,表明在危机时期市场动态明显更加同质。
讨论和限制:
我们的异常行为模型突出了行为最相似和最不相似的部门和国家。在所分析的 20 个国家中,有一个主要由欧洲国家组成的集群。部门异常行为分析在分析的 11 个部门中发现 1 个主要集群。人们发现,原材料和主要消费品的反常行为与其他部门最不一样。我们的(标准化)矩阵规范分析表明,跨部门多元化可能比跨国家多元化更困难。国家不稳定距离矩阵标准的较大值突出了这一点。我们的相关性分析提供了两个见解。首先,股票相关性随着时间的推移而增加。其次,在市场危机期间,股票相关性飙升。我们的轨迹分析和滚动 PCA 表明,尽管在危机期间轨迹显示出最大的异质性,但在这些时期集体市场动态是最强的。这些发现可能会引起全球股票和国际投资者的兴趣,他们关心的是了解市场动态和分散投资组合。
为了便于理解,我将数学讨论/符号减到最少。对于那些对数学细节感兴趣的人,请随时给我发电子邮件,地址是 nickj@arowanaco.com
改变 Power BI 中的数据粒度
有时,您需要以与数据不同的粒度创建报告。让我们看看如何在 Power BI 中解决这一挑战
问题是
我使用 Contoso 样本数据集,就像我以前的文章一样。你可以从微软这里免费下载 ContosoRetailDW 数据集。
Contoso 数据可以在 MIT 许可下自由使用,如这里的所述。
现在,让我们看看在线销售事实表(FactOnlineSales)。
当您查看下图时,可以看到每个订单都有一行或多行。每一行都有一个 SalesOrderLineNumber,每一行都有一个 ProductID。
图 1 —样本数据(图片由作者提供)
现在,我有以下问题之一:
- 数据太多—我的数据太多,我想减少数据量以节省空间和内存来提高性能
- 报告需求—我需要根据订单和产品类别创建报告。
- 我不需要最高的粒度,我想从我的数据中删除不必要的细节
因此,我希望将粒度从产品减少到产品子类别,从 OrderLineNumber 减少到 OrderNumber。由于这种减少,我必须连接 Product 表来映射 Product 子类别。
此聚合将数据集从 12’627’608 行减少到 3’432’947 行,同时保留 SalesOrderNumber、CustomerKey 和其他维度引用。
您可以使用三种方法之一来降低数据的粒度:
- 从源系统检索数据时更改它
- 在 Power Query 中的导入过程中更改它
- 在 Power BI 中加载数据后,在 DAX 中更改它
从这三个变体中,我最喜欢第一个。
我的口头禅是:“如果你需要改变你的数据,尽早去做”。
但是,让我们来详细看看这些变体中的每一个:
在源系统中
如果您的源系统是一个关系数据库,编写一个 SQL 查询来聚集您的数据。
聚合查询将如下所示:
SELECT [FOS].[DateKey], [FOS].[StoreKey], [FOS].[PromotionKey], [FOS].[CurrencyKey]
,[FOS].[CustomerKey], [P].[ProductSubcategoryKey], [FOS].[SalesOrderNumber]
,SUM([FOS].[SalesQuantity]) AS [SalesQuantity]
,SUM([FOS].[SalesAmount]) AS [SalesAmount]
,SUM([FOS].[ReturnQuantity]) AS [ReturnQuantity]
,SUM([FOS].[ReturnAmount]) AS [ReturnAmount]
,SUM([FOS].[DiscountQuantity]) AS [DiscountQuantity]
,SUM([FOS].[DiscountAmount]) AS [DiscountAmount]
,SUM([FOS].[TotalCost]) AS [TotalCost]
,SUM([FOS].[UnitCost]) AS [UnitCost]
,SUM([FOS].[UnitPrice]) AS [UnitPrice]
,[FOS].[UpdateDate], [FOS].[DueDate], [FOS].[ShipDate]
FROM [dbo].[FactOnlineSales] AS [FOS]
LEFT OUTER JOIN [dbo].[DimProduct] AS [P]
ON [P].[ProductKey] = [FOS].[ProductKey]
GROUP BY [FOS].[DateKey], [FOS].[StoreKey], [FOS].[PromotionKey], [FOS].[CurrencyKey]
, [FOS].[CustomerKey], [P].[ProductSubcategoryKey], [FOS].[SalesOrderNumber]
,[FOS].[UpdateDate], [FOS].[DueDate], [FOS].[ShipDate];
在分析数据后,我将所有的测量值相加。您需要仔细选择正确的聚合函数,因为简单的求和并不总是正确的选择。
有时,你不能简单地汇总你的数据。您可能需要对汇总的数据进行计算,以获得正确的结果。
如果源不是关系数据库,尽量在源系统中提前准备好数据,以减少 Power BI 中的转换工作。
一些应用程序允许您创建数据的聚合或报告视图,您可以在 Power BI 中使用这些视图。
如果这些都不可能,下一步就是 Power Query。
电源查询
您可以在 Power Query 中使用 Group By 函数来降低数据的粒度。
图 2 —强大查询中的分组依据(作者提供的图)
该特性计算 Power Query 中的分组和聚合,并将数据加载到 Power BI 中。
但是,这种方法的缺点是 Group By 函数不能将查询返回给 SQL Server。这意味着它必须在超级查询引擎中加载整个数据集。只有在所有数据都被加载后,它才能执行分组和聚合。
从 Power BI 的角度来看,在 Datasource 或 Power Query 中使用查询/视图没有区别。Power BI 仍然只能获得包含聚合数据的精简数据集。
当您需要两种粒度时该怎么办?
有时,您需要在更高和更低的粒度级别上进行计算。
在这种情况下,您需要两个表,并且您必须更改您的数据模型以适应所有需求。
在我的例子中,在为产品分类添加了聚合表和新表之后,我的 PBIX 文件需要大约 15%的额外空间。
但是,有时,这不是一个选项,因为您的事实表中可能有更多的数据,并且由于各种原因,您不能简单地向您的模型添加一个更大的表。
当你有大量数据集时,你可以阅读我上一篇关于这个主题的文章:
另一方面,如果您只有少量的数据,您可能希望只有一个事实表,并且您希望动态地更改度量中的粒度。
让我们来研究一下这种方法。
在一定程度上做这件事,让我们看看结果
不幸的是,在改变数据粒度的同时创建一个度量并不容易。有很多变数需要考虑。
我们来看下面这个问题:整体订单的平均销售金额是多少?
我想考虑整个订单,而不是每个订单行的销售额。因此,我必须合计每个订单号的销售总额。然后计算结果的平均值。
这项措施本身并不困难:
AvgSalesOverOrders =VAR SalesPerOrder = SUMMARIZE(‘Online Sales’
,’Online Sales’[Sales Order Number]
,”SalesAmountPerOrder”, SUMX(‘Online Sales’,
[SalesAmount])
)RETURN
AVERAGEX(SalesPerOrder
,[SalesAmountPerOrder])
我的第一种方法是对表变量 SalesPerOrder 使用 AVERAGE()。
不幸的是,AVERAGE 只能处理物化表,也可以是 DAX 表。
但是,我不想创建一个计算 DAX 表来解决这一挑战。我的目标是创建一个 DAX 度量,而不需要向我的数据模型添加更多的表。
在这种情况下,AVERAGEX()是解决方案。
但是结果正确吗?
嗯,看情况。
你可能在我的上一篇文章中读到过,有多种方法可以计算平均值:
在这种情况下,结果是否正确取决于数据的粒度。
我导入了聚合数据,这些数据是用上面描述的 Power 查询方法准备的,作为我的数据模型中一个名为“Online Sales Aggr”的新表。
请看下面的查询:
DEFINE
MEASURE ‘Online Sales’[AvgSalesOverOrders] =
VAR SalesPerOrder = SUMMARIZE(‘Online Sales’
,’Online Sales’[Sales Order Number]
,”SalesAmountPerOrder”
,SUMX(‘Online Sales’, [SalesAmount])
)
RETURN
AVERAGEX(SalesPerOrder
,[SalesAmountPerOrder])
MEASURE ‘Online Sales Aggr’[AvgSalesOverOrders_Aggr] =
AVERAGE(‘Online Sales Aggr’[SalesAmount])
EVALUATE
ROW( “AvgSalesOverOrders”, [AvgSalesOverOrders],
“AvgSalesOverOrders_Aggr”, [AvgSalesOverOrders_Aggr] )
这是结果:
图 3 —两个平均值的结果(图片由作者提供)
为什么会不一样?
第一个度量从最高粒度聚合数据,包括所有细节,直到每个订单号。
第二种使用预汇总数据。但是该表包含每个客户、商店、促销等的详细信息。因此,该表包含的详细信息比测量中生成的表多得多。
因此,预聚合数据在销售额列中的数字较小。这就是平均值较低的原因。
当我将第二个度量的粒度更改为相同的级别时,结果更加相似。
以下是完整的查询:
DEFINE
MEASURE ‘Online Sales’[AvgSalesOverOrders] =
VAR SalesPerOrder = SUMMARIZE(‘Online Sales’
,’Online Sales’[Sales Order Number]
,”SalesAmountPerOrder”
,SUMX(‘Online Sales’, [SalesAmount])
)
RETURN
AVERAGEX(SalesPerOrder
,[SalesAmountPerOrder])
MEASURE ‘Online Sales Aggr’[AvgSalesOverOrders_Aggr] =
AVERAGE(‘Online Sales Aggr’[SalesAmount])
MEASURE ‘Online Sales’[AvgSalesOverOrders_Aggr_2] =
VAR SalesPerOrder = SUMMARIZE(‘Online Sales Aggr’
,’Online Sales Aggr’[Sales Order Number]
,”SalesAmountPerOrder”
,SUMX(‘Online Sales Aggr’
[SalesAmount])
)
RETURN
AVERAGEX(SalesPerOrder
,[SalesAmountPerOrder])
EVALUATE
ROW( “AvgSalesOverOrders”, [AvgSalesOverOrders],
“AvgSalesOverOrders_Aggr”, [AvgSalesOverOrders_Aggr],
“AvgSalesOverOrders_Aggr_2”, [AvgSalesOverOrders_Aggr_2] )
这是结果:
图 4 —相似粒度的结果(图片由作者提供)
无论如何,由于基值不同,结果不可能相等。
每行的值如何影响结果只是众多变量中的一个。您需要验证结果,并相应地改变方法,以从计算中获得正确的结果。
结论
我已经向您展示了三种不同的方法:
- 准备源中的数据
- 在超级查询中操作数据
- 创建一个度量并在那里更改粒度
我更喜欢第一种选择,因为在大多数情况下,这是最有效的方法。
如果您的源是一个数据库,您可以向源传递一个查询,并用它来计算聚合。
第二种选择有一些限制。如上所述,Power Query 无法通过查询折叠将数据的分组和聚合传递给 SQL Server。
因此,Power Query 将始终读取整个数据集,并在 Power Query 中执行聚合,这需要时间和资源。
当您希望将数据保持在最低粒度时,您必须编写一个度量。
但要谨慎。这种方法可能是性能最低的解决方案。
上面显示的第一个度量用了将近两秒钟来计算结果,在查询中只显示结果的总数:
图 5 —对基础数据进行测量的时间(图片由作者提供)
但是在矩阵中使用它需要 15 秒钟以上:
图 6 —矩阵测量的时间(图片由作者提供)
在 Power BI 中,对聚合数据的简单测量需要 65 ms 才能完成:
图 7——对聚合数据进行简单测量的时间(图片由作者提供)
但是,最后一种方法与第一种方法一样计算平均值,只比第一种方法少花了大约 25%的时间:
这里来自查询:
图 8——聚合数据的测量时间(图片由作者提供)
在 Power BI 中,使用与上述相同的矩阵视觉效果:
图 9 —矩阵中聚合数据的测量时间(图片由作者提供)
正确的解决方案取决于用户的需求。如果这些不清楚,你需要向他们展示不同之处,并要求一个简洁的答案,哪个版本是正确的。
平均值只是计算的一个例子。但是您需要澄清基于聚合数据的所有计算的需求。
这同样适用于首先聚合数据的方法。
您可以加载数据两次。一次是所有细节,一次是汇总形式,以便于一些计算。
但是,要注意如何执行聚合。错误的方法会导致不好的结果。
Sascha Bosshard 在 Unsplash 上的照片
我希望我能够给你一些如何处理这种情况的启发。
更改笔记本电池的默认输出 Jupyter 笔记本生产力快速提示
我打赌那是你会发现有用的东西
Jupyter Notebook 是一个友好的 Python 编辑器,适用于所有级别——初学者和有经验的 Python 用户会时不时或几乎每天都想使用它。对我来说,当我为实用程序模块编写脚本时,我喜欢使用 PyCharm。但是,当我处理数据时,我喜欢使用 Jupyter 笔记本。
Jupyter Notebook 对数据科学家的吸引力来自于它的交互性——你总是可以一步一步地检查数据是什么样子的。这是一些初级数据科学家没有意识到的事情——他们可能非常相信自己的编码技能,并认为一切都会很好。然而,如果不密切、持续地关注数据,您可能会得到一个完全错误的数据集。
默认输出行为
至此,我希望你已经养成了坚持检查数据的好习惯。您可能会做如下事情:
检查数据头(图片由作者提供)
在您读取数据集之后,您要做的是使用head
方法检查它的前五行。除了数据导入,有时您可能需要自己创建数据框架:
创建数据框架(图片由作者提供)
但是,正如您可能注意到的那样,DataFrame 在默认情况下没有输出。同样,您必须在数据帧上使用head
方法,或者简单地在另一个单元格中输入数据帧来检查数据。
检查数据帧(图片由作者提供)
当您一致地操作数据时,比如创建新列、设置数据框架的子集、与其他数据框架对象合并,通过调用单元格中的df.head
或df
来检查新的数据框架对象会变得很乏味。显示数据是因为单元格的默认输出行为是显示最后一个表达式的求值结果。
当单元格的最后一个操作是一个计算结果为 None 的语句或表达式时,您不会得到任何输出。例如,当我们创建 DataFrame another_df = pd.DataFrame(data_records)
时,我们没有任何输出,因为它是一个赋值语句,不输出任何东西。
有什么方法可以不用显式调用df.head
就能显示新创建的 DataFrame?
更改默认输出行为
如你所知,Jupyter Notebook 是建立在 IPython 库之上的,它提供了笔记本单元的基本功能。因此,通过快速的 Google 搜索,我意识到我可以通过运行下面的代码来改变默认的输出行为:
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "last_expr_or_assign"
本质上,您改变了交互式 shell 在 IPython 中的工作方式,Jupyter Notebook 依赖于 IPython。代码所做的是显示最后一个表达式的计算结果或赋值语句中使用的值。运行上述代码后,让我们看看细胞现在的行为:
更新的输出行为(图片由作者提供)
如您所见,我们不再需要运行df.head
,所有创建的 DataFrame 对象都会自动显示,以便我们检查数据。
太方便了!
除了“last_expr_or_assign”
选项,你还可以尝试其他选项,如下图。对我来说,我觉得这个“last_expr_or_assign”
正是我想要的。
互动选项
“永久地”改变行为
当您使用完当前笔记本并创建另一个笔记本时,您可能会注意到您必须再次运行以下代码。否则,新笔记本的行为将和以前一样,只显示最后一个表达式的计算结果。
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "last_expr_or_assign"
在每一个笔记本里做是不是很繁琐?我不知道你的反应,但我发现它很乏味。
幸运的是,有一个解决方案—我们可以通过将此设置应用到配置文件来更改任何笔记本的默认行为。如果您使用的是 Mac (Windows 有类似的解决方案),您应该能够找到一个隐藏的目录(要显示隐藏的文件/文件夹,在 Finder 中,按下Shift + Cmd + .
)来进行 IPython 相关的设置:
/Users/your_username/.ipython/profile_default
在这个文件夹中,你创建一个名为ipython_config.py
的文件。在该文件中,添加以下代码。代码所做的是获取配置文件,并为任何新创建的笔记本将节点的交互性设置为“last_expr_or_assign”
。
c = get_config()c.InteractiveShell.ast_node_interactivity = "last_expr_or_assign"
创建这个文件后,您会看到它改变了新笔记本的默认单元格输出行为。超级酷吧?
抑制输出
就检查数据而言,更改默认显示行为很方便。但是,您的笔记本可能会变得很长,因为所有的 DataFrame 对象都会显示出来。当然,您可以在检查后删除单元的输出。另一个有用的方法是利用分号符号。请观察下面的截图。
抑制输出
如您所见,如果我们用分号结束我们的赋值,就不会显示更多的输出。如果没有分号,单元格将显示赋值中使用的值。
因此,通过使用分号,我们能够操纵单元格的输出行为,同时享受显示最后一个表达式或赋值的交互的笔记本级设置。
结论
在这篇文章中,我与你分享了一个简单的技巧,可以提高你的生产力与 Jupyter 笔记本。在许多情况下,我们希望在处理过程中不断检查我们的数据,为此,我们可能必须不断使用df.head
或df
,这很繁琐。
通过改变 IPython 中节点的交互模式,我们能够让单元格输出最后一个表达式或赋值,从而避免我们调用这些数据检查方法。此外,我们讨论了如何在不改变每个笔记本设置的情况下,在所有笔记本上一致地实施这种行为。我们还学习了如何在需要时使用分号来隐藏输出。
感谢阅读这篇文章。通过注册我的简讯保持联系。还不是中等会员?通过使用我的会员链接支持我的写作(对你没有额外的费用,但是你的一部分会费作为奖励由 Medium 重新分配给我)。
基因序列的混沌博弈表示
为基因组序列的混沌游戏表示建立 GUI,为度量接近度和聚类算法的应用对 C.G.R 进行矢量化。
在这篇文章中,我们将详细讨论 C.G.R 在生物信息学中的应用。然后,混沌矩阵将被转换成一个 N 维向量,用于测量接近度和聚类算法的应用。还将构建一个 GUI 来表示一系列序列的 C.G.R 图。
haos 游戏表示法是由 H J Jeffery 于 1990 年提出的一种新方法。这是一种将一维文本序列转换成可视二维矩阵的迭代方法,本质上是非随机输入在迭代函数系统中的应用。最初是为基因组序列引入的,现在它被用于任何包含从代码 32 到 126 的 ASCII 字符的任意符号或字母,这些字符由大写和小写字母以及标点符号组成。
基因组序列通常是通过 **A、T、G、**和 **C 表示的数千兆字节的文本排列。**多年来,已经开发了许多方法来比较序列,这对人眼来说是复杂的。C.G.R 提供了一个可视化的 2D 图,可以立即识别并与其他序列的 C.G.R 图进行比较。C.G.R 显示出基因组的显著模式特征。由于模式对基因组来说是独特的,这可以用来识别基因组片段或检测水平基因转移。此外,C.G.R 模式的定量分析可用于序列比较,用 C.G.R 进行无比对和基于比对的序列比较都是可能的
算法实现
在本节中,我们将深入探讨如何在 MATLAB 和 Python 中为任何给定的序列从头开始创建 C.G.R 图。我遇到了两种不同的迭代算法方法,这两种方法都可以用其中一种语言来实现。这两种算法的基础是相同的,
- 从二维坐标系的原点开始,通常为(0,0)
- 每个核苷酸都有其预定的位置:
A: (-1,1) — T: (1,-1) — G: (1,1) — C: (-1,-1)
- 对于每个核苷酸(以相反的顺序匹配 k-mer 表;即匹配正向马尔可夫链),移动并标记位于当前位置和核苷酸中间的新位置。例如,如果最后一个字母是 T,则位置从(0,0)移动到(1,-1)和(0,0)之间的中点,即(0.5,-0.5)
- 对所有核苷酸重复此程序
上述实现取决于所生成的 k-mers,并且将随着所选择的 k-mers 的长度而变化。
混沌游戏表征
用 k 值为 9 (k 值描述每个 k-mer 的长度)的人类β冠状病毒 fasta 文件测试的上述代码产生了这些图。
C.贝塔冠状病毒的 G.R 图
在 MATLAB 中完成的第二个实现不依赖于 k-mers,仅依赖于每个核苷酸。
黄泰荣、尹正昌、邱淑诗(2016)。DNA 序列的混沌游戏数字编码及其在相似性比较中的应用。基因组学,第 107 卷,2016 年,爱思唯尔公司理论生物学杂志
用人类贝塔冠状病毒 ’ fasta’ 文件测试的上述代码产生了这些图。
两个冠状病毒序列的混沌博弈图
GUI 实现
实现的 python 文件将是 GUI 的框架。 Streamlit 是面向机器学习和数据科学团队的开源 app 框架。在数小时内而不是数周内创建漂亮的数据应用。全是纯 Python。
所用数据集的链接可在这里找到。
给定数据集由’ xlsx’ 格式的多个序列家族组成,每个家族由属于各自家族的多个序列组成。
窥视其中一个数据集。
GUI 允许用户从数据集中选择任意两个家族,并在这些家族中选择一个序列,该序列将被转换为 C.G.R 图。
两种不同的方法被用来寻找两个序列之间的相似性,向量相关和图像相似性方法。对于矢量相关,给定的 2D 混沌矩阵通过行的线性组合转换成 1D 矢量。这些载体通过 Spearman、Kendal 和 Pearson 的方法进行关联。
SSIM 和 PSNR 指数用于计算图像之间的相似性。计算出的 C . g . r . 2D 图将输入到这些方法中。SSIM 值的范围从 0 到 1,图像相似的分数越高。PSNR 值描述了信噪比,因此图像越近,该值越小。这些方法是进行的一系列实验的一部分,但是从观察来看,这些方法没有产生非常有用的结果。
python 中用于 SSIM 的包有:sc kit-ssim&SSIM-PIL****
实现的源代码可以在 这里找到 。
链接到 GUI:https://share . streamlit . io/rohith-2/chaos-game-representation _ BIOS eq/stream . py
建议的图形用户界面的最终结果
将 C.G.R 矩阵向量化成 N 维元组
在将 C.G.R 的应用扩展到尖端 ML 和深度学习模型的尝试中,可以利用在中公开的通过混沌游戏表示的 DNA 序列的数字编码以及在相似性比较中的应用 中的方法。目的是对属于同一家族的 N 维元组进行聚类,以找出任意两个序列之间的“距离”,并识别未知基因组序列的家族。
矢量器. m
通过选取 3 个基因组家族和这些家族中每个家族的 20 个序列来尝试所提出的想法。出于可视化的目的,元组维度被选择为 3。
********
3D 图的不同视图
未来工作:
这是 C.G.R 的一个基本实现,它没有针对速度或更高 k 值的更好描述进行优化。可以在更高维度更好的特征中使用矢量描述,这可以改进许多 ML 模型分类和基因组序列的模式匹配。
github:https://github . com/Rohith-2/Chaos-Game-Representation _ bio seq
本文使用的数据集来自 NCBI 。
参考资料:
- 黄泰荣、尹正昌、邱淑诗(2016)。DNA 序列的混沌游戏数值编码及其在相似性比较中的应用。基因组学,2016 年第 107 卷,爱思唯尔公司理论生物学杂志。
- H.Joel Jeffrey,“基因结构的混沌游戏表示”,收录于核酸研究,第 18 卷,第 8 期,1990 年,第 2163–2170 页。**
混沌理论,侏罗纪公园,为混沌系统做机器学习
受《侏罗纪公园》启发,分析混沌理论、机器学习和可预测性
作者图片
来自《侏罗纪公园》的灵感:
我第一次读 1990 年的《侏罗纪公园》小说时,看到了这一段有趣的内容,伊恩·马尔科姆博士解释了混沌理论,并声称通过计算机预测混沌系统是不可能的,同时谈到了预测天气的愿望,一个混沌系统,如何导致冯·诺依曼创造了现代(存储程序)计算机。混乱是侏罗纪世界系列的一个中心主题,也是对事情如何出错的解释。马尔科姆博士不断警告《侏罗纪公园》的创作者约翰·哈蒙德,由于混乱,这样的系统是无法控制和管理的。小说之前随机买了一本混沌理论的书。我不知道这是一本 1987 年的书,马尔科姆博士的角色实际上是受《混乱》的作者詹姆斯·格雷克的启发。意识到这一点后,我更感兴趣地读了那本书。
作为一名数据科学家和 JP fan,我决定做更多的研究和分析,评估在机器学习和计算领域取得最新进展后,这一说法现在如何成立,并分析混沌理论在过去几十年中如何应用和影响科学,特别是计算机科学和数据科学。混沌理论被认为是 20 世纪科学中发现的最重要的概念之一。这是一个有趣且有用的概念,但它很少在数据科学和人工智能领域被谈论,所以我写了这篇关于它的文章。
什么是混沌理论:
混沌理论是对复杂的,通常是非线性系统的研究,这些系统对初始条件和状态的改变高度敏感,并具有复杂的相互作用、混合、非周期性和反馈回路,从而导致快速演化的不规则和经常意外的行为,这是不可预测的。然而,在这种无序之下有潜在的秩序和模式,但据说是不可预测的。当你试图预测更远的未来时,预测会迅速变得更加困难。有时表面上简单的系统也会表现出混乱。
混沌理论创始人 Edward Lorenz 用一种有趣的方式总结:“当现在决定未来,但近似的现在并不近似地决定未来。”,意味着系统是确定性的,但初始条件的微小变化会导致非常不同的不可预测行为的演化。确定性行为似乎是随机的。
混沌理论是著名的蝴蝶效应的基础,这种效应在流行文化和电影中经常被提及。根据洛伦兹的说法:“今天在香港飞舞的蝴蝶可以改变下个月纽约的风暴系统。”
混沌理论的用途:
混沌是世界上普遍存在的现象,混沌理论的概念有着广泛的应用。它们不仅用于促进不同混沌系统的分析,断言考虑和限制,以及检测混沌。它们还被用于设计、生产和改进许多东西,有时是通过利用初始条件和混沌地图来制造混沌。除了物理学、化学和生物学等自然科学的核心领域,一些有趣的应用领域包括密码学、经济学、生态学、农业、天文学、政治学、人类学、生理学、心理学、气象学、地质学、最优化、机器人与控制、计算机科学、电气与电信工程、生殖艺术和纺织品设计。
伪随机数生成用于编程任何随机的东西,这在 AI 和 ML 中很常见。混沌过程及其对初始条件的敏感性被用来产生安全的伪随机数。它们也用于图像加密、制作密码和创建水印。
一些通信系统和电路使用混沌信号来实现安全通信。混沌过程也用于家用电器和消费电子产品。
在机器人学中,混沌动力学以混沌分析或混沌合成的形式使用。混沌合成就是产生混沌来完成任务。混沌分析是对混沌行为的观察和分析。混沌理论被用于群体智能&多智能体系统、双足机器人运动和移动机器人与环境交互的行为分析。它也用于一些运动规划算法。分形也被用于模块化机器人。
分形是复杂的,往往是美丽的视觉图案,源于混沌,在从细胞膜到太阳系的整个宇宙中普遍存在,使事物美丽而独特。它们也用于生成数字艺术和设计纺织品图案等。
混沌理论还用于基于元启发式的优化和进化计算,用于人工智能和机器人,以及许多工程和工业问题,如聚合物制造和电信。混沌被加入到粒子群优化和遗传算法的混沌版本中,以避免局部最优。基于主体的建模和仿真在某些情况下也利用混沌理论。
机器学习中有一些混沌启发的模型训练和优化方法。也有受混沌启发的神经网络架构,在实验中发现混沌神经网络处理信息快速高效。随机梯度下降(SGD)和神经网络训练的收敛性具有混沌行为,最近混沌理论被用来改善当前对神经网络优化的理解并解释为什么 SGD 工作良好。
混沌系统、预测分析和机器学习:
有很多混沌系统的例子,包括流行病、道路交通、密码和股票市场、经济、体育、人群、多智能体系统、自动驾驶、消费者行为、销售和社会,其中许多我也曾参与预测分析。
我相信,对于这样的系统,应该考虑并承认混沌的影响以及由此导致的预测中的限制和挑战,以避免在做出预测时不切实际的期望,特别是如果您没有仔细使用领域知识和专门方法的话。
现代计算能力、数据可用性和机器学习的进步,确实给了我们一种希望,可以在某种程度上预测混沌系统中的不可预测性,如果它们以某种方式了解了无序中的潜在秩序和模式。有预测分析做得很好的例子。这取决于数据和方法以及问题的复杂性和性质。
混沌系统对初始条件和测量精度很敏感,它们需要关于完整系统的详细信息。通常我们没有所需的或足够的数据,特征值是嘈杂的和不准确的。我们还没有在混沌系统中创造复杂的相互作用和变化的所有特征和状态表示。另一个挑战是,由于*“维数灾难”*,拥有更多功能会成倍增加所需的数据和计算。对反馈循环和突发行为的解释也使这个问题变得更加困难。
以下是一些方法和想法,它们被证明在减轻混沌的影响和在这样的混沌系统中进行适当的预测方面是很好的:
一个在机器学习中也很重要的简单想法是对模型和系统进行持续的训练、评估和监控。复杂进化系统的预测分析应该是一个迭代过程。混沌理论特别强调混沌系统在长期范围内的不可预测性,即在未来,因此在未来训练一个新系统是有帮助的。
在一些成功的尝试中,系综方法的使用已经被强调,这些成功的尝试是在具有混沌动力学的系统中进行良好的长期预测。在集成方法中,基于*【群体智慧】*,来自多个模型的预测被组合以获得更好的预测。总体而言,集成也是提高机器学习预测的一种有用和常见的方式。在具有混沌动力学的系统中,它们尤其有用,因为多个模型解决了系统对初始条件、状态变化和噪声测量的敏感性。
像卡尔曼滤波器集成这样的数据同化方法将新的观测结果与模型预报结合起来进行改进。当在混沌系统中进行数值模拟时,它们也用于改进预测,并且有时用于 ML 模型的输入。
反馈回路、序列动力学和跟踪状态是混沌理论和混沌动力学的固有部分。因此,递归神经网络(RNNs)似乎是处理这些问题的自然选择。长短期记忆是一种 RNNs。通过处理像消失梯度这样的问题,它们优于 RNNs。类似 LSTMs 的 rnn 在使用 ML 预测混沌的一些研究和实验中被有效地使用[1]。他们可以利用对过去状态的记忆和序列对未来进行连续的时间序列预测。一些解决方案使用简单的深度神经网络,有时将它们与自回归模型相结合。
相空间是在所有可能状态的 n 维空间中表示的系统状态。该系统遵循该空间中的轨迹,该轨迹是描述该系统的微分方程的解。混沌系统通常无法解决,但它们在相空间中运动的定性行为和风味可以估计。在相空间中有一个被称为吸引子的区域,它被所有的轨迹勾勒出来,它们似乎被吸引了。在奇异吸引子中,由于缺乏关于初始条件的完美信息,我们不知道系统在吸引子上的位置。洛伦兹吸引子是一种奇怪的吸引子,是洛伦兹在对流实验中发现的。它看起来像一个不断螺旋上升的蝴蝶形状,轨迹没有交叉,因为没有任何状态是重复的,显示出非周期性和混沌性。它革新了混沌理论,它的情节成为它的标志。
自动编码器以无人监督的方式学习数据的压缩表示。它们也用于混沌系统中的状态表示,有时与 RNNs 结合使用。他们也可以学习有效地表示混沌系统的吸引子。在实验[2]中,使用具有伪最近邻正则化的 LSTM-自动编码器通过无监督学习来编码和估计洛伦兹吸引子,并从该信息重建状态空间。这类似于使用非线性动力学中使用的延迟坐标编码进行状态估计,同时避免了其局限性。
卷积神经网络(CNN)也可以以时间 CNN 的形式用于顺序建模,时间 CNN 使用 1D 卷积。卷积从时间序列中执行复杂的特征提取。对于一些时间序列问题,它们被证明是 RNNs 的一个很好的替代品,有时也与 RNNs 结合使用。时间细胞神经网络也被应用于混沌系统的预测。一位研究人员[3]将自动编码器与 CNN 结合起来,使用 AE-CNN 对混沌的逐时气象数据进行中长期预测,并使用迁移学习对其进行进一步改进
也有机器学习的应用来控制和减少系统中的混沌,特别是使用强化学习。有时像小波这样的信号处理技术也用于此。
用于混沌系统预测的机器学习的一些最令人印象深刻和最新的应用利用了水库计算(RC)。RC 是基于 RNNs 背后的思想。这个框架对系统状态的演变进行数据驱动的预测。储层是随机连接的非线性单元的复杂网络,使用循环回路存储信息。贮存器通过使用那些递归连接来学习和表示系统的动态。输入是低维时间序列数据,使用储层输入(I/R)模块映射到储层中的高维时间相关向量。动态系统的演变输出状态由油藏-输出(R/O)模块[4]映射和预测。通过学习有限的输出参数来训练 RC 系统。在 RC 系统中,机器学习有助于填补状态信息缺失的空白。
在一些研究工作中,RC 已经被有效地应用于混沌系统预测,并且添加了不同的模块和改进以使它们更好地用于混沌系统。RC 系统[5,6]用于预测复杂和混沌的 Kuramoto-Sivashinsky 火焰传播系统。该系统在没有系统先验知识的情况下,对混沌时空系统进行了高度精确和非常长时间的预测。
在科学和工程中,使用基于模型的方法进行系统分析和预测是很常见的。如果一个好的系统模型是已知的,那么在许多情况下它会比使用 ML 做得更好。领域知识的使用非常有助于数据科学的直接利用,也有助于特征工程和 ML 的结合。所以它不应该总是被忽视。混沌系统中预测分析的几种方法是机器学习和系统模型的混合,或者将领域知识与 ML 算法相结合。
现代天气预报仍然使用气象系统模型和方程进行预报。他们通常使用来自不同模型的预测集合,以减轻信息和初始条件不完善的影响。天气的长期预测仍然不太好,研究表明,在 8 天后,这比使用该日期的历史平均值更糟糕[7]。然而,在使用最大似然法进行长期天气预测方面,一些很好的工作正在进行中,从事这项工作的专家声称非常乐观[8]。改进和大规模部署需要时间。有趣的是,尽管计算能力在过去几十年里有了惊人的增长,但制造现代计算机的主要目标仍未完全实现。
回到马尔科姆博士在《侏罗纪公园》中的主张,我想说,应该记住,在混沌系统中进行预测是具有挑战性的,也是不可靠的。然而,通过使用现代计算以及机器学习和深度学习的进步,在对混沌系统进行体面的预测分析方面取得了一些良好的进展。
参考文献:
[1] M. Modondo,T. Gibbons,“使用 LSTM 循环神经网络学习和模拟混沌”。2018 年多指标类集调查。
[2] Sigrid Keydana,《深度吸引子:深度学习遇到混沌的地方》,RStudio AI 博客,2020 年。
[3]辛,“基于混沌时间序列的 AE-CNN 与迁移学习的预测”,印度复杂性科学,2020 .
[4] H. Fan,J. Jiang,等,“用机器学习实现混沌系统的长期预测”,APS 物理评论研究,2020。
[5] Natalie Wolchover,“机器学习预测混沌的‘惊人’能力”,《量子》杂志,2018 年。
[6] J. Pathak,B. Hunt 等,“从数据中对大型时空混沌系统进行无模型预测:一种水库计算方法”,APS Physics,2018。
[7]马修·卡普奇,“研究表明’特定’天气预报不能提前 10 天以上做出”,华盛顿邮报,2019 年
[8]弗雷德·施穆德,“机器学习会让我们重新思考混沌理论吗?”,风暴地理,2021。
良好特性的特征
提示和技巧
为什么在选择模型特征时,预测能力不是一切
来源: flaticon , shutterstock
在保险业,过去的索赔行为对未来的索赔行为有很强的预测性。这可能是用于确定客户是否会提出索赔的唯一最具预测性的信息来源。然而,如果我们只使用索赔历史来构建模型,效果不会很好。通常,模型特征应该来自各种不同的信息源。您的特征选择方法应该旨在从每个不同的信息源中创建一个最具预测性的特征列表。
在本文中,我们将解释如何结合使用可变聚类和特性重要性来创建这样一个候选列表。我们还讨论了可能导致添加或删除功能的其他注意事项。这些包括数据质量和可用性、特征稳定性、可解释性和法律/道德。最后,我们将讨论所有这些因素是如何在一个特性选择框架中结合起来的。让我们从定义我们所说的特征选择的确切含义开始。
什么是特征选择?
在模型开发过程中,特征选择发生在特征工程之后和我们开始拟合模型之前。在特征工程中,我们将原始数据转换成模型特征列表。根据您的问题,此列表可能会很大(即超过 1000 个功能)。功能选择包括缩小到一个候选名单(即 20-40 个功能)。根据您的模型,可能会有另一个特征选择阶段,您可以在其中选择模型特征的最终列表(即 8-10 个特征)。在本文中,我们关注第一个阶段——创建候选名单。
图 1:特征工程和选择概述
我们创建入围名单有几个原因。在模型训练阶段,使用特征的完整列表在计算上是昂贵的。甚至在我们开始训练模型之前,我们将想要探索特征以理解它们与目标变量的关系。还有大量的工作要投入到特性的测试中。没有必要为他们都做这项工作。这是因为完整的列表将包含冗余/不相关的特征。
冗余功能
为了更好地理解这一点,假设您想要创建一个模型来预测某人是否会拖欠汽车贷款。让我们假设,对于每个客户,我们都可以访问月收入、违约和欠款历史、现有债务和一些个人信息。在要素工程过程中,您将在不同的时间段使用不同的聚合从每个来源创建许多要素。在图 2 中,您可以看到一些这样的例子。
图 2:特征工程示例
对于收入,我们预计上述 3 个特征非常相似。我们还可以预期它们会预测违约。然而,它们都捕捉到了收入和违约之间相同的潜在关系。这意味着,一旦我们的模型中有了收入特征,再增加一个也不会提高模型的准确性。我们说剩下的收入特征是多余的。我们希望从候选列表中排除多余的特征,即使它们是可预测的。
无关的特征
我们还希望删除任何不可预测的或由于其他原因不应考虑的特征(例如,在模型中使用该特征是非法的)。这些被称为不相关特征。例如,假设我们使用客户 20 年前的收入创建了一个特性。这些信息已经过时,不能告诉我们任何关于他们当前财务状况的信息。换句话说,这个特性不能帮助我们预测客户是否会拖欠汽车贷款。
图 3:冗余和不相关特性的总结
特征选择的目标是通过移除尽可能多的冗余和不相关的特征来缩小列表。为此,我们需要考虑单个特征的预测能力以及这些特征之间的差异(即预测变量)。这些是主要的考虑因素,我们将在下面深入讨论。
预测能力
我们可以粗略地将预测能力定义为一个特征预测目标变量的能力。实际上,我们需要使用一些度量/统计来估计这一点。一个常见的衡量标准是特征和目标变量之间的相关性。较大的正相关或负相关表明存在很强的关系,或者换句话说,该特征是预测性的。其他度量包括信息值、互信息和特征重要性分数。
不同的措施有各自的优缺点。重要的是,它们让我们能够比较特征,并优先考虑最具预测性的特征。然而,如果这是我们唯一考虑的事情,我们可能不会有一个很好的候选名单。继续我们的汽车贷款例子,假设我们已经创建了表 1 中的特性列表。这是我们所有的特性列表,我们已经根据特性的重要性对它们进行了排序。
表 1:潜在模型特征的完整列表
一般来说,我们可以看到基于违约历史的特征是最具预测性的。这是因为客户过去的违约历史会告诉我们很多关于他们未来是否会违约的信息。所以,假设我们只取了 20 个最有预测性的特征作为我们最终的候选名单。我们最终会得到许多默认的特性。换句话说,候选列表中会有许多多余的特征。
预测变量
这个问题把我们带到了我们应该考虑的第二个因素——预测变量。为了避免有很多冗余的特性,我们需要考虑这些特性彼此之间有多大的不同。为此,我们应该首先从完整列表中创建特征组。组的构建应使一个组中的要素彼此相似,而与其他组中的要素不同。现在,如果我们从每个组/子列表中选取最具预测性的特征,我们最终会得到更少的冗余特征。
可变聚类
问题是我们如何创建这些特征组。我们可以使用领域知识手工完成,或者可能已经有了一个固有的分组。对于我们的汽车贷款示例,我们可以创建 6 个组(5 个主要数据源和 1 个收入和债务组合)。例如,您可以在图 4 中看到默认组和收入组。在这两个组中,这些特征已经按照特征的重要性进行了排序。然后,我们可以从每组中选取 3/4 个最具预测性的特征,从而得到 18 到 24 个特征的候选列表。
图 4:默认和收入特性组
对于许多问题,可能很难手动对特征进行分组。您可能有太多的要素需要手动分组。底层数据源也可能更加复杂。即使以我们的汽车贷款为例,也不清楚这 6 个组是否是最佳分组。例如,个人组中的一个功能是“当前职业”。将这一点包括在收入特征中可能更好。
为了解决这些问题,我们需要一种统计方法来创建相似的组。这些被称为变量聚类方法。例如,您可以使用 Python 中的 VarClusHi 包。这种方法旨在对高度相关的变量进行分组。一个组内的变量应该高度相关,同时不与其他组中的变量相关。你也可以修改聚类方法,比如 K-means,这样它们就可以对变量而不是观察值进行聚类。
其他特征和考虑
使用可变聚类将帮助我们去除冗余特征。使用特征重要性将帮助我们去除不相关的特征,因为它们不具有预测性。在我们使用这些方法之前,我们可能首先想要移除由于其他原因而不相关的特征。同样,我们也有理由想要包含一些特征,即使它们不是可预测的。这些额外的原因总结在图 5 中,我们将在下面进行更详细的讨论。
图 5:一个好特性的特征
数据质量
如果某个特征的数据质量很差,则该特征可能被认为是不相关的。每当我们预期数据集中的记录值与真实值不同时,我们都应该小心。例如,数据可能丢失或输入不正确。通常,较差的数据质量意味着某个特征不具有预测性,并且无论如何都会被排除在外。情况并非总是如此,尤其是当错误是系统性的或者数据不是随机丢失的时候。
在某些情况下,数据可能会被用户或第三方公开处理。以我们的汽车贷款模型为例,用户可能会被要求提供自己的个人信息(例如,原籍国、职业)。用户可能会被诱惑提供给他们获得贷款的更好机会的信息。例如,他们可以谎称自己有一份高薪工作,比如医生或软件开发员。我们需要独立验证这些类型的特征是否正确。
数据可用性
模型通常是在开发环境中创建的。为了实际使用该模型,他们需要转移到生产环境中。由于各种技术问题和成本,某些功能可能在生产环境中不可用。换句话说,这些数据可用于训练模型,但不能用于模型的实时预测。为了有一个工作模型,我们需要排除这些特性。
即使这些特性被排除在最终的模型之外,我们仍然希望将它们包含在我们的候选列表中。这将允许我们继续探索这些特性。如果我们能证明它们是可预测的,这将有助于证明生产这些特征所涉及的工作和成本是合理的。它们可以用于未来的模型中。
稳定性(过去和未来的表现)
仅仅因为你的特征现在是可预测的,并不意味着它们将来也是可预测的。随着时间的推移,特征和目标变量之间的关系可能会发生变化,模型中捕获的关系可能会过时。这些变化是由各种内部和外部力量推动的。例如,COVID 疫情导致了客户行为的突然变化,影响了试图预测该行为的模型。
为了更好地理解这一点,让我们回到汽车贷款的例子。假设,在疫情之前,我们用过去 12 个月中 PERS7 - 的物理分行访问量建立一个模型。当时,倾向于更频繁去银行的客户不太可能拖欠汽车贷款。换句话说,较高的 PERS7 值与较低的违约概率相关。到了疫情,封锁意味着许多互动转移到了网上。这意味着更少的分支机构访问,我们将看到所有客户的 PERS7 值减少。
从我们模型的角度来看,个人债务的下降表明违约风险更高。尽管这些客户的违约风险不会改变,但该模型现在预测了更高的违约概率。组织内外还有许多其他潜在的变化会以这种方式影响你的模型。您需要尽最大努力考虑所有这些因素,并选择对这些变化具有鲁棒性的特性。
可解释性
到目前为止,我们已经讨论了使用平均值和最小值等简单聚合来创建要素。还有更复杂的特征工程技术,如主成分分析(PCA)。例如,从图 4 中,我们可以获得收入组中的所有特征,并计算 PCs。不严格地说,你可以把 PCs 看作是收入特征的总结。我们可以考虑将第一台电脑纳入我们的候选名单。
第一个 PC 可能比任何个人收入特征更具预测性。然而,我们可能仍然只包括收入的简单汇总。这是因为违约和总收入之间的关系比个人电脑更容易理解和解释。最终,我们可以优先考虑一些特性来提高模型的可解释性。如果你想了解为什么可解释性很重要,你可以阅读这篇文章:
法律与伦理
使用某些类型的信息构建模型可能是非法的。例如,为了避免借贷中的性别歧视,使用 PERS65 (客户性别)可能是非法的。即使法律目前没有涵盖这些类型的信息,你可能还是想避免它们。它们可能会导致不道德的后果和公众的反弹。
与直觉相反,你可能仍然想在你的候选名单中包含这些特征。这样就可以进行算法公平性评估。如果不将性别作为一个特征,您就无法确定您的模型是否偏向某一性别。这些类型的要素称为受保护的要素,不应用于构建模型。
具体问题
最后要考虑的是,模型通常会有很多分析。有时这种分析与模型构建没有直接关系,相反,我们想要回答特定的问题。比如,某些地区的客户违约率是否不同?还是倾向于网上互动的客户违约率比去分行的高?在你的候选名单中包含回答这类问题所需的任何特征会很方便。
特征选择框架
最终,以上所有的考虑都需要以某种方式形式化。这就是特性选择框架的用武之地。它将概述选择特征方法的技术细节,包括特征重要性的度量和可变聚类方法。它还可以定义您处理其他考虑事项的方法(例如,需要什么分析来确定一个特性是否稳定)。您可以在图 6 中看到这样一个框架的轮廓。
图 6:特性选择框架的概要
这个框架可能会成为一个更大的建模框架的一部分。与特征选择一起,这将定义特征工程的方法和使用的模型类型。建模框架可以再次成为更大的治理框架的一部分。这就是负责任的人工智能框架。我们将在下面的文章中讨论负责任的人工智能及其目标。
[## 什么是负责任的 AI?
towardsdatascience.com](/what-is-responsible-ai-548743369729)
成为推荐会员
如果你觉得这篇文章很有帮助并且想看更多,你可以成为我的 推荐会员 来支持我
图像来源
所有图片都是我自己的或从www.flaticon.com获得。在后者的情况下,我拥有他们的保费计划中定义的“完全许可”。
参考
名词(noun 的缩写)Siddiqi,信用风险记分卡:开发和实施智能信用评分 (2006)
J.Brownlee ,如何选择机器学习的特征选择方法(2020)https://machinelingmastery . com/Feature-Selection-with-real-and-category-data/
R Doucmentation,变量聚类(2021)http://math . Furman . edu/~ DCS/courses/math 47/R/library/Hmisc/html/var clus . html
打开风险手册,模型衰变(2021)https://www.openriskmanual.org/wiki/Model_Decay