用特征重要性分析用户行为和 UX 性能
如何应用商业策略概念进行特性重要性分析。有例子!
图片来自 pexels.com 的 Kaboompics
当我们在数据科学中考虑特征重要性时,我们可能也会考虑特征选择,然后我们的想法可能会最终出现在 scikit-learn 中可以找到的典型分类器算法中,如决策树、回归、随机森林……你能想到的。
这些算法对于捕获数据集中最重要的特征非常有用,然后可能会根据这些特征的重要性创建一个预测模型。
数据科学目前充斥着来自不同背景的人。在我的案例中,作为一名工业工程师,我想到了一种用工业工程方法进行分析的方法。除了学习大量的数学和微积分,我们还学习了策略和流程优化。
在工业工程中学到的一个经典概念是 BCG 矩阵(也称为增长份额矩阵)。这是波士顿咨询集团在 70 年代开发的一个概念,用于公司识别并将其产品聚集到不同的类别中,然后使它们在市场中发展,使公司的收入最大化。
如果您不了解 BCG 矩阵,不要担心,请继续阅读本文,您将会了解其中的概念。我还会在文末留下说明链接!
商业案例
假设您是一家电子商务公司的数据科学家,您的经理要求您进行分析,目的是确定他们可以在公司网站中改进的关键功能。通过这种方式,公司将获得更多的用户进行转换(在这种情况下转换可以是购买产品,或购买机票等)。所有公司最终想要的是客户转化更多,这样他们就有更多的收入。
他们可能会问你,是什么让人们更容易皈依?
对于这个例子,我从一个虚构的在线销售产品的电子商务公司构建了一个玩具数据集。这家公司的网站具有你可以从这样的网页中期待的典型特征:搜索引擎、搜索后的过滤选项、将产品添加到购物车等。
你得到的数据
你能得到的简化的数据库看起来像这样:
包含用户数据事件的熊猫数据框架
我们还可以将该表视为数据透视表,使用以下代码:
df['one'] = 1df_pivot = (pd.pivot_table(df
,values=['one']
,columns=['event']
,index=['user_id','converted']
,aggfunc = {'one':'sum'}))df_pivot.columns = df_pivot.columns.to_series().str.join('_')df_pivot = df_pivot.reset_index()for col in df_pivot.columns[2:]: df_pivot = df_pivot.rename(columns = {col: col.replace('one_','')})
我们得到了这个数据透视表:
前一个数据帧的透视版本
有很多人做的动作,比如做一个搜索,然而,没有多少人改变。正因为如此,很难建立一个预测模型,因为只有少数人采取行动,最终导致转变。
我们可以构建一个决策树,看看哪些特性是最重要的,看看哪些是阈值,我们已经可以看到明显的转化趋势。主要的问题是:是什么使人皈依?
决策树—使用 Graphviz 包
因此,如果用户应用过滤器超过 5 次,并向购物车中添加超过 3 件商品,那么它有很高的转换机会…但它看起来有点太具体,在这个业务案例中没有用,不是吗?
让我们看看如果构建波士顿矩阵会发生什么
我为此构建了一个包(要安装它,在您的终端中运行这个命令: pip install bcganalysis )。这是您必须使用的代码,使用类似前面的数据透视表作为输入(访问 GitHub repo 了解更多细节!)
!pip install bcganalysis# we import the package first
from bcg_analysis import Generate_BCG# and matplotlib
import matplotlib.pyplot as plt# then we instantiate the object for the analysis
# df is the table with the user and events
features = Generate_BCG(df)
# and we get the pivot table
features.get_pivot(index=['user_id','converted'],columns='event')
# then we generate the chart with penetration and conversion
features.generate_chart(threshold=1)# and then we plot it
features.plot_bcg()
(*)关于如何应用代码的更详细的方法,请看我的 Github 中的自述文件:https://github.com/Mateil04/bcg_analysis。在这里,您可以使用回购中可用的玩具数据集进行示例。
我们得到的情节
在 x 轴上,它显示了有多少用户已经使用了每个功能至少一次,我们称之为渗透。也可以认为是该功能的流行度。
在 y 轴上,我们可以看到转换,这是在所有使用过该功能的用户中,有多少人最终进行了转换。
例如,几乎所有的用户(大约 80%)都在进行搜索操作,但是在所有执行这个操作的用户中,大约 20%的人会转换。这是因为这是一个非常常见的动作,几乎每个用户都会做。它让网站持续滚动,但不能保证转化。
另一方面,如果我们看一下 add_to_cart 动作,我们会看到它是由少数用户(渗透率20%)完成的,但这些用户的转化率非常高(75%)。
这就是 BCG 矩阵的用武之地(它不是严格意义上的矩阵,但它就是这么叫的!)
BCG 矩阵—图片由 Matias Eiletz 提供
波士顿矩阵最初被认为是用来评估一家公司的产品在市场上的成功和市场份额。
例如,你可以考虑麦当劳公司,把巨无霸作为摇钱树,因为它是非常受欢迎的经典产品,总能带来一些收入。纯素汉堡可以在问号象限,因为现在纯素食品非常流行,而且肯定有很大的潜力,但它必须在市场上取得成功,才能成为明星产品并带来最大的收入。一个鱼汉堡可以在狗象限。这可以是这样的情况,一个产品曾经是一个问号,但没有通过测试,最终没有流行起来。
产品的所需运动用虚线箭头表示。
卡介苗矩阵的 x 轴是市场份额,y 轴是增长率。在我们的业务案例中,我们为了渗透(流行)和转换而改变了它们,但是本质是一样的。
卡介苗矩阵-改编-马蒂亚斯·埃列茨拍摄的图像
回到生成的图,我们可以看到:
问号象限中的功能(add_to_cart,apply_filter)是具有很大潜力但尚未被开发的功能。我们希望它们变得更受欢迎,并像那样,成为我们未来的之星特色(高渗透率,高转化率)。为了实现这一点,您可能会建议 UX 团队改变这些功能在网站上的显示方式,例如颜色和大小,以突出显示它们。然后,他们会得到更多的点击,将会有更多的整体转换(这一功能被转换成了星形象限)。
犬类象限中的特征,它们可以被省略并替换为其他特征。这个例子中的“看稀有”按钮似乎没有吸引很多人,也不会触发转换,所以最好考虑另一个不同的功能来代替它。
摇钱树是那些没有太多转换的功能,但是它们非常受欢迎,并且让网站的用户流量很大。在我们的案例中,搜索并点击一篇又一篇的文章,就是明显的例子。
最终,如图表所示,星星将在某个时候传给奶牛,我们将需要找到更多的特征作为问号,比如在主页上一个全新的部分,然后成为我们的新星星。
总结
在本文中,我展示了如何执行与 UX 设计相关的功能重要性分析,评估用户行为。它也可以被认为是一种聚类方法。
如果您想查看包的代码,可以在我的 GitHub 中查看。
如果您想了解更多关于卡介苗基质的信息,您可以查看这篇维基文章或这篇其他帖子。
分析 Fitbit 数据,揭开疫情封锁期间身体模式变化的神秘面纱
健康分析:了解锻炼、睡眠、卡路里燃烧模式,并朝着正确的方向优化
疫情禁闭后在家锻炼
在过去的四年里,我一直定期锻炼。由于疫情的局势,这是我第一次这么长时间不能去健身房或使用任何设备。希望我们大多数人都面临着同样的问题。我们都知道呆在家里拉平疫情曲线有多重要。
然而,我们仍然可以通过呆在家里来尽力保持健康。我一直在我的阳台/露台上锻炼,用楼梯作为引体向上的杠,一根长杆作为我的重量(幸运的是我找到了它),做几个俯卧撑和一个阻力管,这是我过去在旅行中买的。
为了量化家庭锻炼的效果,我下载了我的 Fitbit 数据,做了一些预处理,并将其标记为锁定前后的数据。主要目的是了解:
什么是不同的 Fitbit 度量?他们之间有什么关系吗?
我在禁闭前后消耗的卡路里是怎样的?
我能在家燃烧/达到同样的强度吗?
这两个时期我的睡眠模式有什么变化?
我可以根据这一分析创建智能推荐吗?比如我的身体需要睡几个小时才能恢复?
作为分析的结果,我可以进一步优化什么?
通过这篇博文,我打算对数据进行分析,找到上述问题的答案。这篇文章也是一个很好的例子,告诉我们如何利用分析来变得健康和健美。我们如何从数据中获得洞察力,并创建关于睡眠、锻炼提醒、锻炼赞赏徽章等的智能建议。我已经在这里提供了数据和代码。让我们开始有趣的东西。
在家锻炼时面临的挑战
在跳到代码和找到见解之前,我想指出我在家庭锻炼中面临的挑战,这些挑战使我深入挖掘并进行这一分析。
我一直在尽最大努力用我能找到的任何东西来保持我的健康。我面临的主要挑战是-
1.重量和设备的缺失
在健身房,我做了 110 公斤(242 磅)的深蹲,120 公斤(265 磅)的 T2,硬拉等等。在家里,我不能设法得到这样的重量级人物。所以,我用我得到的更轻的竿增加了重复次数。
我没有合适的引体向上或引体向上杆,所以我只能在楼梯上做。我在大部分练习中使用阻力管。重量/张力变小了,所以我再次增加了重复次数。但是,缺少重量和设备仍然是一个挑战。
我发现了一篇有趣的文章,文章称举重会导致肌肉增长,从而燃烧更多的卡路里。所以,举重是关键。
如果你曾经举过重物,你可能不止一次想知道你应该举多少重量。你是…
www.verywellfit.com](https://www.verywellfit.com/are-you-lifting-enough-weight-1231071)
2.空间不足
我不能出去跑步或散步,因为现在很危险。为此,我在瑜伽垫上做有氧运动。
这里是我在家做的一些锻炼来保持我的健康。下面你可以观察到的一件事是我一直戴着一个 Fitbit。
在家锻炼:俯卧撑
在家锻炼:引体向上和阻力管
在家锻炼:二头肌弯曲和深蹲
需要注意的重要事项
一个人的卡路里摄入量取决于他们的性别、年龄、身高和体重。有在线计算器可以用来计算。人们也可以使用性别、年龄、身高和体重信息来计算身体质量指数(身体质量指数)。
同样,燃烧的卡路里数量取决于性别、年龄、身高和体重因素。在线计算器可用于计算。
这个计算器估计你在运动和日常生活中燃烧的卡路里数量。报告生成了…
nutritiondata.self.com](https://nutritiondata.self.com/tools/calories-burned)
活动数据分析和有趣的见解
Fitbit 提供的两个重要文件是活动数据和睡眠数据。让我们看一看它
活动数据
我将数据分别标记为锁定前(2020 年 3 月 15 日之前)和锁定后(2020 年 3 月 15 日当天和之后)。我还删除了周末的数据,因为我通常不会在周六和周日锻炼,给我的身体休息和恢复时间。
度量分析
锁定前后指标的变化
我们来看看散点图 ( 柱状图)和箱线图。有时,平均值可能是一个有偏差的参数,因此应该查看百分位数分布。
metric = 'Calories Burned'
#Equally dividing Pre-Post Data into 21 Percentile buckets
bins = 21
percentile_bins = np.linspace(0,100,bins)
pre_bins = np.percentile(df_exercise_preLockdown[metric], percentile_bins)
post_bins = np.percentile(df_exercise_postLockdown[metric], percentile_bins)
sns.distplot(pre_bins,kde_kws={ "lw": 2, "label": "Pre Lockdown"},axlabel=metric)
sns.distplot(post_bins,kde_kws={ "lw": 2, "label": "Post Lockdown"})
plt.show()
锁定前和锁定后消耗的卡路里散点图(直方图和 Kde 图的组合)
锁定前和锁定后消耗的卡路里箱线图
在封锁期后,燃烧的平均卡路里从 2475 千卡减少到 2290 千卡。大约下降了 7.5%。
5-Days with Minimum Calories Burned during Pre-Lockdown Period
**2128, 2154, 2203, 2229, 2330**
5-Days with Maximum Calories Burned during Pre-Lockdown Period
**2597, 2755, 2755, 2896, 2969**5-Days with Minimum Calories Burned during Post-Lockdown Period
**1864, 1921, 1935, 1959, 1962**
5-Days with Maximum Calories Burned during Post-Lockdown Period
**2688, 2729, 2777, 2827, 3224****All units in Kcalorie*
另一件有趣的事情是一致性也降低了。与封锁前相比,封锁后燃烧的卡路里有显著的差异。从图和计算的标准偏差可以清楚地看出这一点。我有点知道原因了。在办公室,我经常从办公桌走到会议室,午饭后也会和同事一起散步。在封锁前,我的健身时间是一致的,但现在在家里,我偏离了固定的日程,有时开始得晚,结束得快。 宾果!!我发现了改进的余地。一致性是关键。
度量之间的关系
我还想找出所走的步数、走过的距离和燃烧的卡路里之间的关系。无论从直觉上还是从数据上看,它们似乎都是正相关的。让我们来验证相关性的数量或强度。
度量之间的相关性
所有指标都与相关系数为 1 的完全相关。这基本上意味着,如果我们知道 Fitbit 使用的正确公式,我们就可以使用消耗的卡路里精确地推导出步数和距离。也表示关系/公式为线性。
睡眠数据分析和有趣的见解
我们来看看睡眠数据。我已经标记了封锁前后的数据。
睡眠数据
度量分析
锁定前后睡眠指标的变化
我们来看看距离图 ( 直方图)和箱线图。有时,平均值可能是一个有偏差的参数,因此我们可以查看百分位数分布。
metric = 'MinutesAsleep'
#Equally dividing Pre-Post Data into 21 Percentile buckets
bins = 21
percentile_bins = np.linspace(0,100,bins)
pre_bins = np.percentile(df_sleep_preLockdown[metric], percentile_bins)
post_bins = np.percentile(df_sleep_postLockdown[metric], percentile_bins)
sns.distplot(pre_bins,kde_kws={ "lw": 2, "label": "Pre Lockdown"},axlabel=metric)
sns.distplot(post_bins,kde_kws={ "lw": 2, "label": "Post Lockdown"})
plt.show()
锁定前和锁定后的睡眠分钟数分布图(直方图和 Kde 图的组合)
锁定前和锁定后期间的睡眠分钟数(以分钟为单位)箱线图
这些年来,我的身体一直在训练自己减少睡眠,同时保持活跃。有一些文章围绕着睡眠需求因人而异的主题。这取决于基因和身体多年来的训练方式等因素。这里有一篇有趣的文章。
睡眠解剖学睡眠阶段睡眠机制你需要多少睡眠?梦想基因的作用和…
www.ninds.nih.gov](https://www.ninds.nih.gov/Disorders/Patient-Caregiver-Education/Understanding-Sleep)
在封锁期后,我燃烧的平均卡路里下降了 7.5%。平均睡眠时间也减少了 14 分钟。但是,好的一面是,在锁定后,差异非常小。我的睡眠时间更稳定。 太棒了!!这是我感到高兴的事情,甚至在封锁结束后我也想这么做。
智能推荐
接下来,我想进行智能推荐,根据我燃烧的卡路里数量,根据我的身体需求推荐适量的睡眠。
有些日子我会因为睡眠不足或高强度锻炼而感到懒惰,但大多数时候我会因为充足的睡眠而感到精力充沛、精神焕发。
其次,我晚上锻炼,晚上睡觉大多在 12 点以后。所以,我对第一天燃烧的卡路里数和第二天的睡眠时间感兴趣。我将使用这些信息创建一个数据集,其中我将记录第一天燃烧的卡路里和第二天的睡眠时间。
根据您的锻炼和睡眠模式,您可以创建不同的数据集。
#Find Day2
df_exercise['incremented_date']= df_exercise.Date + datetime.timedelta(days=1)#Joining Activity Dataset with Sleep Dataset
query = """
select
a.*,
b.MinutesAsleep
from
df_exercise a
join
df_sleep_agg b
on
a.incremented_date = b.Date
order by
a.Date
"""
df_join = sqldf(query,globals())
这是最终连接数据集的外观
活动和睡眠数据集的连接
接下来,我会试着找到燃烧的卡路里和一分钟睡眠之间的理想关系。我将使用回归,因为它给出系数值,并且结果是直观的。此外,由于我只是在消耗卡路里方面退步,保持模型简单是明智的。
cols = ['CaloriesBurned']
clf = LinearRegression()
clf.fit(df_join[cols],df_join['MinutesAsleep'])
回归模型的截距和系数为
Intercept = 253.77
Coefficient = 0.0441
让我们看看我的推荐引擎会根据燃烧的卡路里量给出什么建议
Calories Burnt: **2100 Kcalorie**
Amount of Ideal sleep needed for your body-type: **5 hours 47 minutes**Calories Burnt: **2200 Kcalorie**
Amount of Ideal sleep needed for your body-type: **5 hours 51 minutes**Calories Burnt: **2500 Kcalorie**
Amount of Ideal sleep needed for your body-type: **6 hours 5 minutes**Calories Burnt: **2600 Kcalorie**
Amount of Ideal sleep needed for your body-type: **6 hours 9 minutes**Calories Burnt: **2700 Kcalorie**
Amount of Ideal sleep needed for your body-type: **6 hours 13 minutes**Calories Burnt: **2969 Kcalorie**
Amount of Ideal sleep needed for your body-type: **6 hours 25 minutes**Calories Burnt: **3000 Kcalorie**
Amount of Ideal sleep needed for your body-type: **6 hours 27 minutes**
注意事项:
- 该关系仅在消耗的卡路里数在 3000 千卡限制内时有效,因为在训练集中,很少有我消耗超过 3000 千卡的情况。
- 在 3000 千卡之后,这种关系很可能是非线性的。也就是说,如果我燃烧 3000+千卡热量,我做了一些我的身体不习惯的事情,燃烧这么多热量需要我的身体采取适量的饮食和休息来恢复。所以,一旦我们得到更多的数据,我们就能更好地发现这种关系。
- 3000 千卡范围内的关系也可能是非线性的。可以应用非线性算法来进一步微调推荐。我使用回归只是因为它的简单和直观。
结论
通过这篇博文,我分享了我如何使用 Fitbit 数据来了解我在疫情情况下的身体模式变化。主要见解可以总结为:
由于缺乏适当的设备、运动较少以及无法遵循严格的作息时间,在锁定后的时间里,燃烧的卡路里减少了 7.5%。但是,通过家庭锻炼,我已经能够燃烧大量的卡路里。
在锁定后期间,平均睡眠时间减少了 14 分钟,但睡眠时间的一致性增加了,变化很小,对此我很高兴,并希望继续下去。
我们还发现了关于 Fitbit 指标及其相关性的重要见解。
我们还创建了一个智能推荐引擎,根据燃烧的卡路里数和个人的睡眠要求,推荐所需的睡眠时间。
我已经在这里 做好了数据和代码 。
如果你有任何疑问,请联系我。我也很想知道你是否对健康分析有兴趣。
我的 Youtube 频道获取更多内容:
嗨,伙计们,欢迎来到频道。该频道旨在涵盖各种主题,从机器学习,数据科学…
www.youtube.com](https://www.youtube.com/channel/UCg0PxC9ThQrbD9nM_FU1vWA)
关于作者-:
Abhishek Mungoli 是一位经验丰富的数据科学家,拥有 ML 领域的经验和计算机科学背景,跨越多个领域并具有解决问题的思维方式。擅长各种机器学习和零售业特有的优化问题。热衷于大规模实现机器学习模型,并通过博客、讲座、聚会和论文等方式分享知识。
我的动机总是把最困难的事情简化成最简单的版本。我喜欢解决问题、数据科学、产品开发和扩展解决方案。我喜欢在闲暇时间探索新的地方和健身。在 中 、Linkedin或insta gram关注我,查看我以前的帖子。我欢迎反馈和建设性的批评。我的一些博客-****
- 每个数据科学家都应该避免的 5 个错误
- 以简单&直观的方式分解时间序列
- GPU 计算如何在工作中真正拯救了我?
- 信息论& KL 分歧第一部分和第二部分
- 使用 Apache Spark 处理维基百科,创建热点数据集
- 一种基于半监督嵌入的模糊聚类
- 比较哪种机器学习模型表现更好
- 确定您的数据分布
分析巴西的全球识字率数据
数据
我在 data.world 上偶然发现了一些非常有趣的数据集,其中引起我注意的是这个关于 2011 年至 2018 年全球识字率的数据集,按年龄组和性别进行了细分。如果你读过我以前的博客,那么所有的分析都将在 r 中完成。这次我不会解释我的代码,所以如果你想理解代码,最好有一些 r 的工作知识。
设置
**library**(tidyverse)
**library**(lubridate)
**library**(httr)
**library**(readxl)
**library**(extrafont)
**library**(hrbrthemes)
**library**(gghighlight)
**library**(ggtext)
**library**(ggmap)
**library**(scales)
**loadfonts**(device = "win")
**GET**("https://query.data.world/s/ethf3e5hs6lv52vzvegp3g3qeeeloj", **write_disk**(tf <- **tempfile**(fileext = ".xlsx")))literacy_data <- **read_excel**(tf)
分析
2018 年女性平均识字率最高的国家
literacy_data **%>%**
**filter**(Gender**==**"female") **%>%**
**group_by**(Country) **%>%**
**filter**(**max**(Year)**==**2018**&n_distinct**(Year)**>=**5,
**mean**(`Literacy rate`[Year**==**2018],na.rm = T)**>mean**(`Literacy rate`[Year**!=**2018],na.rm = T)) **%>%**
**group_by**(Country,Year) **%>%**
**summarise**(Average_literacy_rate = **mean**(`Literacy rate`,na.rm = T)) **%>%**
**ggplot**(**aes**(**reorder**(Country,Average_literacy_rate,mean),Average_literacy_rate,color=**factor**(Year)))**+**
**geom_point**(size=9,alpha=0.4)**+**
**coord_flip**()**+**
**gghighlight**(Year**==**2018)**+**
**scale_y_percent**()**+**
**scale_color_manual**(values = **c**("2018"="firebrick"))**+**
**theme_minimal**()**+**
**labs**(x=NULL,y=NULL,title = "Countries that had peak average literacy rate in <span style='color:firebrick'>**2018**</span>",
color=NULL)**+**
**theme_ipsum_ps**()**+**
**theme**(plot.title = **element_markdown**(size=20,margin = **margin**(b = 10)))
该图显示了与以往所有年份的平均水平相比,2018 年女性平均识字率最高的国家。南美洲的一些国家和阿根廷保持在 90%左右。其他拉美国家如巴西、墨西哥和哥伦比亚也显示出良好的增长势头。孟加拉国的女性识字率显著提高。这可能是由于政府将教育支出增加了一倍,从 2008 年的 20 亿美元增加到 2016 年的 43 亿美元
各地区识字率的分布
world_avg <- literacy_data **%>%**
**summarise**(avg=**mean**(`Literacy rate`,na.rm = T)) **%>%**
**pull**(avg)
literacy_data **%>%**
**group_by**(Region) **%>%**
**mutate**(region_avg= **mean**(`Literacy rate`,na.rm = T)) **%>%**
**ungroup**() **%>%**
**ggplot**(**aes**(Region,`Literacy rate`,color=Age))**+**
**geom_jitter**(alpha=0.7,size=3,height = 0.2)**+**
**geom_hline**(**aes**(yintercept=world_avg),color="grey40",size=0.9)**+**
**geom_segment**(**aes**(x=Region,xend=Region,y=world_avg,yend=region_avg),color="black")**+**
**coord_flip**()**+**
ggsci**::scale_color_jama**()**+**
**stat_summary**(fun.y = mean, geom = "point", size = 8,color="firebrick")**+**
**geom_text**(**aes**(x=Region,y=region_avg,label=scales**::percent**(region_avg)),color="white",hjust=0.5,nudge_y = 0.01)**+**
**theme_classic**()**+**
**theme**(text = **element_text**(family = "Roboto Condensed"),axis.title = **element_text**(size = 12),
axis.text.y = **element_text**(family = "Roboto Condensed", size = 12),
panel.grid = **element_blank**(),
plot.title = **element_text**(size = 25,hjust = 0.5,family = "Roboto Condensed"))**+**
**annotate**(geom = "text",x=7,y=1,label=**paste0**("Worldwide literacy average of\n",scales**::percent**(world_avg)),color="white")**+**
**scale_y_percent**()**+**
**labs**(x=NULL,title = "Distribution of literacy rate across regions")
灰色垂直线代表全球平均识字率,红色大圆圈突出显示每个地区的平均识字率。与全球平均水平和其他地区相比,撒哈拉以南非洲、北非和西非、中亚和南亚等地区的平均识字率较低。毫不奇怪,年龄较大的人识字率普遍较低。
各年龄组的识字率趋势
avg_year <- literacy_data **%>%**
**group_by**(Year,Age) **%>%**
**summarise**(avg=**mean**(`Literacy rate`,na.rm = T)) **%>%**
**ungroup**()
avg_year **%>%**
**ggplot**(**aes**(Year,avg,color=Age))**+**
**geom_line**(size=1.5)**+**
**geom_point**(size = 2.6, **aes**(color = Age), shape = 15) **+**
**geom_text**(data=avg_year **%>%** **group_by**(Age) **%>%** **filter**(Year**==max**(Year)),**aes**(label=Age),hjust=**-**0.5)**+**
**scale_color_manual**(values = **c**("15-24"="#d20962","15+"="#005670","25-64"="#ce181e","65+"="#8a7967"))**+**
**scale_y_percent**()**+**
**labs**(y=NULL,x=NULL,title = "Literacy rate trend across age groups")**+**
**theme**(
text = **element_text**(family = "Roboto Condensed"),
plot.margin = **unit**(**rep**(1.2, 4), "cm"),
plot.title = **element_text**(size = 20,
color = "#22292F",
face = "bold",
margin = **margin**(b = 5)),
plot.subtitle = **element_text**(size = 15,
margin = **margin**(b = 35)),
plot.caption = **element_text**(size = 10,
margin = **margin**(t = 25),
color = "#606F7B"),
panel.background = **element_blank**(),
axis.text = **element_text**(size = 12, color = "#22292F"),
axis.text.x = **element_text**(margin = **margin**(t = 5)),
axis.text.y = **element_text**(margin = **margin**(r = 5)),
axis.line = **element_line**(color = "#3D4852"),
axis.title = **element_text**(size = 14),
axis.title.y = **element_text**(margin = **margin**(r = 15),
hjust = 0.5),
axis.title.x = **element_text**(margin = **margin**(t = 15),
hjust = 0.5),
panel.grid.major = **element_line**(color = "#DAE1E7"),
panel.grid.major.x = **element_blank**(),
legend.position = "none"
)
除了 2012 年所有年龄组的识字率急剧下降之外,这里没有什么有趣的东西可看
女性平均识字率高于男性平均识字率的国家
countries_female <- literacy_data **%>%**
**group_by**(Country) **%>%**
**filter**(**mean**(`Literacy rate`[Gender**==**"female"],na.rm = T)**>mean**(`Literacy rate`[Gender**==**"male"]))
literacy_data **%>%**
**semi_join**(countries_female) **%>%**
**group_by**(Country) **%>%**
**summarise**(avg_ltrcy_male = **mean**(`Literacy rate`[Gender**==**'male'],na.rm = T),
avg_ltrcy_female=**mean**(`Literacy rate`[Gender**==**'female'],na.rm = T)) **%>%**
**ungroup**() **%>%**
**ggplot**(**aes**(y=**reorder**(Country,avg_ltrcy_female),x=avg_ltrcy_male,xend=avg_ltrcy_female))**+**
ggalt**::geom_dumbbell**( size=5, colour="grey",colour_x = "#005670",colour_xend = "#d20962")**+**
ggrepel**::geom_text_repel**(**aes**(x=avg_ltrcy_female,label=**percent**(avg_ltrcy_female,accuracy = 1)))**+**
ggrepel**::geom_text_repel**(**aes**(x=avg_ltrcy_male,label=**percent**(avg_ltrcy_male,accuracy = 1)))**+**
**labs**(x=NULL,y=NULL,title = "Countries where female literacy rate is higher than male literacy rate")**+**
**scale_x_percent**()**+**
**theme_classic**()**+**
**theme**(
text = **element_text**(family = "Roboto Condensed"),
plot.margin = **unit**(**rep**(1.2, 4), "cm"),
plot.title = **element_text**(size = 20,
color = "#22292F",
face = "bold",
margin = **margin**(b = 5)),
plot.subtitle = **element_text**(size = 15,
margin = **margin**(b = 35)),
plot.caption = **element_text**(size = 10,
margin = **margin**(t = 25),
color = "#606F7B"),
panel.background = **element_blank**(),
axis.text = **element_text**(size = 12, color = "#22292F"),
axis.text.x = **element_text**(margin = **margin**(t = 5)),
axis.text.y = **element_text**(margin = **margin**(r = 5)),
axis.line = **element_line**(color = "#3D4852"),
axis.title = **element_text**(size = 14),
axis.title.y = **element_text**(margin = **margin**(r = 15),
hjust = 0.5),
axis.title.x = **element_text**(margin = **margin**(t = 15),
hjust = 0.5),
panel.grid.major = **element_line**(color = "#DAE1E7"),
panel.grid.major.x = **element_blank**(),
legend.position = "none")
我很好奇哪些国家的女性平均识字率高于或等于男性平均识字率。这张图表上的大多数国家都是南美和非洲地区的小国,这确实令人惊讶。
男女识字率差距最大的国家
countries_male <- literacy_data **%>%**
**group_by**(Country) **%>%**
**filter**(**mean**(`Literacy rate`[Gender**==**"female"],na.rm = T)**<mean**(`Literacy rate`[Gender**==**"male"]))
literacy_data **%>%**
**semi_join**(countries_male) **%>%**
**group_by**(Country) **%>%**
**summarise**(avg_ltrcy_male = **mean**(`Literacy rate`[Gender**==**'male'],na.rm = T),
avg_ltrcy_female=**mean**(`Literacy rate`[Gender**==**'female'],na.rm = T),
diff= avg_ltrcy_male**-**avg_ltrcy_female) **%>%**
**top_n**(20,diff)**%>%**
**ggplot**(**aes**(y=**reorder**(Country,avg_ltrcy_female),x=avg_ltrcy_male,xend=avg_ltrcy_female))**+**
ggalt**::geom_dumbbell**( size=5, colour="grey",colour_x = "#005670",colour_xend = "#d20962")**+**
**geom_text**(**aes**(x=avg_ltrcy_female,label=**percent**(avg_ltrcy_female,accuracy = 1)),vjust=**-**1)**+**
**geom_text**(**aes**(x=avg_ltrcy_male,label=**percent**(avg_ltrcy_male,accuracy = 1)),vjust=**-**1)**+**
**geom_rect**(**aes**(xmin=1,xmax=1.2,ymin=**-**Inf,ymax=Inf),fill="grey")**+**
**geom_text**(**aes**(label=**percent**(diff,accuracy = 1), y=Country, x=1.1), fontface="bold", size=4)**+**
**geom_text**(**aes**(x=1.1,y=20.5,label="Difference"))**+**
**labs**(x=NULL,y=NULL,title = "Top 20 countries with highest discrepency between <span style='color:#005670'>male</span> and <span style='color:#d20962'>female</span> literacy rates")**+**
**scale_y_discrete**()**+**
**scale_x_percent**(breaks = **c**(0.3,0.6,0.9),labels = **c**("30%","60%","90%"))**+**
**theme_classic**()**+**
**theme**(
text = **element_text**(family = "Roboto Condensed"),
plot.margin = **unit**(**rep**(1.2, 4), "cm"),
plot.title = **element_markdown**(size = 20,margin = **margin**(b = 5)),
plot.subtitle = **element_text**(size = 15,
margin = **margin**(b = 35)),
plot.caption = **element_text**(size = 10,
margin = **margin**(t = 25),
color = "#606F7B"),
panel.background = **element_blank**(),
axis.text = **element_text**(size = 12, color = "#22292F"),
axis.text.x = **element_text**(margin = **margin**(t = 5)),
axis.text.y = **element_text**(margin = **margin**(r = 5)),
axis.line = **element_line**(color = "#3D4852"),
axis.title = **element_text**(size = 14),
axis.title.y = **element_text**(margin = **margin**(r = 15),
hjust = 0.5),
axis.title.x = **element_text**(margin = **margin**(t = 15),
hjust = 0.5),
panel.grid.major = **element_line**(color = "#DAE1E7"),
panel.grid.major.x = **element_blank**(),
legend.position = "none")
接下来,我想看看男女识字率差异最大的国家。对于审美,我只是根据两性差异的数值,可视化了前 20 名。同样,我们也可以在这里看到许多非洲国家和一些亚洲国家,比如巴基斯坦——我来自那里。非常有趣的是,在非洲有些国家,女性的平均识字率高于男性,但同时,在非洲有些国家,男性的识字率远远高于女性。
在地图上将其可视化
world <- **map_data**(map = "world") **%>%**
**filter**(region**!=**"Antartica")
long_lat <- literacy_data **%>%**
**group_by**(Country) **%>%**
**summarise**(`Literacy rate`=**mean**(`Literacy rate`,na.rm = T)) **%>%**
**ungroup**() **%>%**
**left_join**(world,by = **c**("Country"="region")) **%>%**
**filter**(**!is.na**(lat))
p <- **ggplot**() **+**
**geom_map**(data = world, map = world,
**aes**(long, lat, group = group, map_id = region),
fill = "#282828", color = "#282828") **+**
**geom_map**(data = long_lat, map = world,
**aes**(fill = `Literacy rate`, map_id = Country),
color = "#282828", size = 0.5, alpha = .8) **+**
**scale_fill_gradient2**(low = "#be0027", high = "#0a8ea0",mid = "#b4a996",midpoint = 0.6) **+**
**scale_y_continuous**(breaks=**c**()) **+**
**scale_x_continuous**(breaks=**c**()) **+**
**labs**(x = "", y = "") **+**
**guides**(
fill = **guide_legend**(title = "Literacy Rate")
) **+**
**coord_map**("gilbert", xlim = **c**(**-**300, 300)) **+**
**labs**(
title = "Global Literacy Rates"
) **+**
**theme**(
text = **element_text**(family = "Roboto Condensed"),
plot.title = **element_text**(color = "#ffffff",
margin = **margin**(t = 30, b = 10),
size = 20),
plot.subtitle = **element_text**(color = "#ababab",
margin = **margin**(b = 10),
size = 15,
hjust = 0.7),
plot.background = **element_rect**(fill = "#323232"),
panel.background = **element_rect**(fill = "#323232",
color = "#323232"),
legend.position = "right",
legend.title = **element_text**(color = "#6d6d6d",
size = 10),
legend.background = **element_rect**(fill = "#323232"),
legend.text = **element_text**(color = "#6d6d6d",
size = 10)
)
cowplot**::ggdraw**(p)**+**
**theme**(plot.background = **element_rect**(fill = "#323232"))
我想尝试可视化地图上的数据,因为我从来没有这样做过。在深入研究细节之前,这有助于从全局层面了解数据
近距离观察巴基斯坦
south_asia <-literacy_data **%>%**
**filter**(Region**==**"Central and Southern Asia") **%>%**
**group_by**(Year,Country) **%>%**
**summarise**(avg_ltrcy=**mean**(`Literacy rate`)) **%>%**
**ungroup**() **%>%**
**group_by**(Country) **%>%**
**filter**(**n**()**>**1)
south_asia **%>%**
**ggplot**(**aes**(Year,avg_ltrcy))**+**
**geom_line**(size=1.5,**aes**(color=Country))**+**
**gghighlight**(Country**==**"Pakistan",use_direct_label = F,use_group_by = F)**+**
**scale_color_manual**(values = **c**("Pakistan"="#11862f"))**+**
**geom_text**(data = south_asia **%>%** **group_by**(Country) **%>%**
**filter**(Year**==max**(Year)) **%>%** **ungroup**(),**aes**(label=**paste0**(Country,"-",**percent**(avg_ltrcy,accuracy = 1))),size=4,hjust=0,fontface="bold")**+**
**scale_x_continuous**(breaks = **seq**(2010,2019,by = 1),limits = **c**(2010,2021))**+**
**annotate**(geom = "text",x=2020,y=0.8,label="Between 75% and 100%",color="black",fontface="bold")**+**
**geom_rect**(**aes**(xmin=2019,xmax=2021,ymin=0.75,ymax=1),fill="#3be8b0",alpha=0.05)**+**
**geom_rect**(**aes**(xmin=2019,xmax=2021,ymin=0.5,ymax=0.75),fill="#56a0d3",alpha=0.05)**+**
**annotate**(geom = "text",x=2020,y=0.6,label="Between 50% and 75%",color="black",fontface="bold")**+**
**geom_rect**(**aes**(xmin=2019,xmax=2021,ymin=0,ymax=0.5),fill="#c90f23",alpha=0.05)**+**
**annotate**(geom = "text",x=2020,y=0.4,label="Less than 50%",color="black",fontface="bold")**+**
**scale_y_percent**()**+**
**labs**(color=NULL,title = "Pakistan vs the rest of the region",x=NULL,y=NULL)**+**
**theme**(legend.position = "none")**+**
bbplot**::bbc_style**()**+**
**theme**(text = **element_text**(family = "Roboto Condensed"))
因为我来自巴基斯坦,我想看看我的国家与同一地区的其他国家相比如何。虽然总体趋势略有上升,但令人失望的是,巴基斯坦仅好于阿富汗,落后于其邻国,如印度、孟加拉国和伊朗。
结论
在这篇文章中,我试图让我的可视化更有创造性,而不是依赖于典型的条形图。我很惊讶地发现,有很多“较穷”的国家拥有很高的识字率。我希望有更多的数据可以帮助我们了解哪些因素影响一个国家的识字率,我们可以根据这些数据建立一个基于某种回归分析的模型。
分析健康保险市场数据
健康保险数据的探索性数据分析
Healthcare.gov 向公众提供合格健康计划(QHP)景观数据。这些数据集包括联邦政府运营市场的各州的个人和家庭健康计划。对医疗保险计划以及其他一般医疗保健服务的可用数据进行定量分析,可能有助于在定价和基于价值的护理方面使我们的医疗保健系统更加透明。
在本帖中,我们将对 QHP 景观数据进行探索性数据分析。数据可在这里获得。它也可以作为一个。我的 GitHub 上的‘CSV’文件。
我们开始吧!
首先,让我们将数据存储在 pandas 数据框中,并打印列的列表:
import pandas as pd
df = pd.read_csv("QHP_landscape_2020.csv")
print(df.columns)
我们还可以打印完整的列列表:
print(list(df.columns))
如你所见,有 128 列。我们将把我们的分析限制在以下几列:
- 发行人名称
- 县名
- 计划营销名称
- 医疗最高自付费用-个人-标准
- 医疗免赔额—个人—标准
- 初级保健医生—标准
- 急诊室—标准
- 专家—标准
df = df[['Issuer Name', 'County Name', 'Plan Marketing Name',
'Medical Maximum Out Of Pocket - Individual - Standard',
'Medical Deductible - Individual - Standard', 'Primary Care Physician - Standard', 'Specialist - Standard', 'Emergency Room - Standard']]
print(df.head())
我们可以看到有几个分类列。让我们定义一个将数据框、列名和限制作为输入的函数。当被调用时,它打印分类值的字典以及它们出现的频率:
def return_counter(data_frame, column_name, limit):
from collections import Counter print(dict(Counter(data_frame[column_name].values).most_common(limit)))
让我们将函数应用于“发行人名称”列,并将结果限制为五个最常见的值:
return_counter(df, 'Issuer Name', 5)
我们可以看到发行者名称“Medica”的记录最多。
让我们将函数应用于“County Name”列:
return_counter(df, 'County Name', 5)
正如您所看到的,这是一个有用的快速测试,可以查看数据中是否有任何明显的不平衡,这通常是建模时需要处理的一个关键问题。
接下来,从数字列(如“医疗最高自付费用-个人-标准”)中生成汇总统计数据会很有用。首先,我们需要将字符串值的美元金额转换成浮点类型。
OOP_INDV = []
for i in list(df['Medical Maximum Out Of Pocket - Individual - Standard'].values):
try:
OOP_INDV.append(float((str(i)[1] + str(i)[3:])))
except(ValueError):
OOP_INDV.append(np.nan)
df['OOP_INDV'] = OOP_INDV
让我们确保转换成功:
print(df[['Medical Maximum Out Of Pocket - Individual - Standard', 'OOP_INDV']].head())
看起来不错!
现在,让我们定义一个采用数据框、分类列和数值列的函数。每个类别的数字列的平均值和标准偏差存储在数据框中,并且数据框根据平均值以降序排序。如果您想要快速查看特定类别对于特定数字列是否具有更高或更低的平均值和/或标准偏差值,这将非常有用。
def return_statistics(data_frame, categorical_column, numerical_column):
mean = []
std = []
field = []
for i in set(list(data_frame[categorical_column].values)):
new_data = data_frame[data_frame[categorical_column] == i]
field.append(i)
mean.append(new_data[numerical_column].mean())
std.append(new_data[numerical_column].std())
df = pd.DataFrame({'{}'.format(categorical_column): field, 'mean {}'.format(numerical_column): mean, 'std in {}'.format(numerical_column): std})
df.sort_values('mean {}'.format(numerical_column), inplace = True, ascending = False)
df.dropna(inplace = True)
return df
我们可以查看“开证人姓名”和“医疗最高自付费用-个人”的汇总统计数据:
stats = return_statistics(df, 'Issuer Name', 'OOP_INDV')
print(stats.head(15))
“德州蓝十字和蓝盾”的个人最高自付费用和跨计划类型的零标准差。
接下来,我们将使用箱线图来显示基于最小值、最大值、中值、第一个四分位数和第三个四分位数的数值分布。如果您对它们不熟悉,可以看看文章了解 Boxplots 。
与汇总统计函数类似,此函数采用数据框、分类列和数值列,并根据限制显示最常见类别的箱线图:
def get_boxplot_of_categories(data_frame, categorical_column, numerical_column, limit):
import seaborn as sns
import matplotlib.pyplot as plt
keys = []
for i in dict(Counter(df[categorical_column].values).most_common(limit)):
keys.append(i)
print(keys)
df_new = df[df[categorical_column].isin(keys)]
sns.boxplot(x = df_new[categorical_column], y = df_new[numerical_column])
让我们在 5 个最常见的发行者名称中为 OOP_INDV 生成箱线图:
get_boxplot_of_categories(df, 'Issuer Name', 'OOP_INDV', 5)
我们可以对“医疗免赔额—个人—标准”进行类似的分析。让我们将字符串值的美元金额转换为浮点类型:
DEDUCT_INDV = []
for i in list(df['Medical Deductible — Individual — Standard'].values):
try:
DEDUCT_INDV.append(float((str(i)[1] + str(i)[3:])))
except(ValueError):
DEDUCT_INDV.append(np.nan)
df['DEDUCT_INDV'] = DEDUCT_IND
让我们确保转换成功:
print(df[['Medical Deductible - Individual - Standard', 'DEDUCT_INDV']].head())
我们可以查看“发行人名称”和“医疗免赔额—个人—标准”的汇总统计数据:
stats = return_statistics(df, 'Issuer Name', 'DEDUCT_INDV')
print(stats.head(15))
“Wellmark Value Health Plan,Inc .”和“Wellmark Health Plan of Iowa,Inc .”的平均“医疗免赔额—个人—标准”最高。
让我们为 5 个最常出现的发行人名称中的 DEDUCT_INDV 生成箱线图:
get_boxplot_of_categories(df, 'Issuer Name', 'DEDUCT_INDV', 5)
最后,让我们定义一个函数,它将一个数据框、分类列、分类值和两个数值列作为输入,并显示一个散点图:
def get_scatter_plot_category(data_frame, categorical_column, categorical_value, numerical_column_one, numerical_column_two):
import matplotlib.pyplot as plt
import seaborn as sns
df_new = data_frame[data_frame[categorical_column] == categorical_value]
sns.set()
plt.scatter(x= df_new[numerical_column_one], y = df_new[numerical_column_two])
plt.xlabel(numerical_column_one)
plt.ylabel(numerical_column_two)
让我们为 Medica 生成一个 OOP_INDV 与 DEDUCT_INDV 的散点图:
get_scatter_plot_category(df, ‘Issuer Name’, ‘Medica’, ‘DEDUCT_INDV’, ‘OOP_INDV’)
我就讲到这里,但是请随意处理数据并自己编码。我鼓励你对急诊室、专科医生和初级保健列进行类似的分析。例如,了解初级保健的共同保险百分比在不同的发行人名称之间的差异是很有趣的。
概括地说,我回顾了几种分析健康保险市场数据的方法。这包括用箱线图和散点图显示数据。我们还定义了用于生成汇总统计数据的函数,比如平均值、标准差和分类值的计数。我希望这篇文章有趣。这篇文章的代码可以在 GitHub 上找到。感谢您的阅读!
分析 StyleGAN 如何工作:高质量图像生成中的样式合并
入门
在之前的帖子中,我们讨论了 2K 图像到图像的翻译、视频到视频的合成以及大规模的类条件图像生成。即 pix2pixHD、vid-to-vid 和 BigGAN。
但是我们离生成基于真实风格的图像还有多远呢?快速浏览一下真实照片的时尚程度:
照片由 anabelle carite 在 Unsplash 拍摄
为此,在这一部分中,我们将关注通过自适应实例规范化的风格合并。为此,我们将重温层内规范化的概念,这将被证明对我们理解 GANs 非常有用。
没有风格,就没有派对!
StyleGAN (基于风格的生成对抗网络生成器架构 2018)
基于我们对甘的理解,我们现在将能够控制他们的风格,而不仅仅是生成图像!多酷啊。但是,等一下。我们已经看到, InfoGAN 可以控制依赖于去纠缠表示的图像生成。
这项工作严重依赖于渐进式 GANs、自适应实例规范化( AdaIN )和风格转移。我们已经在前面的部分中介绍了渐进式 gan,所以在我们专注于理解这项工作之前,让我们深入了解它们的其余部分。
1.了解特征空间规范化和样式转换
人类视觉系统对图像统计非常敏感。众所周知,空间不变的统计,如通道方式的均值和方差可靠地编码图像的风格。同时,空间变化特征编码具体实例。
批量标准化
图片由作者提供,最初用 Latex 编写
在所描绘的等式中, N 是图像批次的数量 H 高度和 W 宽度。希腊字母 μ ()表示平均值,希腊字母 σ ()表示标准差。类似地, γ 和 β 对应于导致线性/仿射变换的可训练参数,对于所有通道来说是不同的。具体来说 γ 、 β 是具有通道维度的向量。批次特征是形状为[N,C,H,W]的 x ,其中索引 c 表示每个通道的平均值。值得注意的是,空间维度以及图像批次被平均。这样,我们将我们的特征集中在一个紧凑的空间,这通常是有益的。
但是,就风格和全局特征而言,所有个体通道都共享羞耻学习特征,即γ、β。因此,BN 可以直观地理解为将一批图像归一化为以单一样式为中心。尽管如此,卷积层能够了解一些批内风格的差异。因此,每个样品可能仍然有不同的风格。例如,如果您想将所有图像转换为相同的共享风格(即梵高风格),这是不可取的。
但是如果我们不混合特性批次特性呢?
实例规范化
与 BN 层不同,实例归一化(IN)仅在特征空间维度上计算**,但对于每个通道**(和每个样本)再次独立计算**。从字面上看,我们只是在前面的等式中去掉了对 N 的求和。令人惊讶的是,实验验证了 IN 中的仿射参数可以完全改变输出图像的风格。与 BN 相反,IN 中的可以将每个单独样本的样式标准化为目标样式(由γ和β建模)。由于这个原因,训练一个模型转换到一个特定的风格是比较容易的。因为网络的其余部分可以将其学习能力集中在内容操作和局部细节上,同时丢弃原始的全局细节(即风格信息)。**
以这种方式,通过引入由多个γ组成的集合,可以设计一个网络来模拟过多的有限样式,这正是条件实例规范化的情况。
自适应实例规范化(AdaIN)
另一个图像的风格转移的想法开始变得自然。如果γ,β是从另一幅图像的特征统计中注入的呢?通过这种方式,我们将能够通过给定我们期望的特征图像均值为β,方差为γ来对任意风格建模。 AdaIN 正是这样做的:它接收输入 x(内容)和样式输入 y,并简单地调整 x 的通道均值和方差以匹配 y 的均值和方差。数学上:
图片由作者提供,最初用 Latex 编写
仅此而已!那么,我们可以做些什么呢?只需一个小改动的单层?让我们看看!
来源:https://arxiv.org/abs/1703.06868
在上半部分,您可以看到一个简单的编码器-解码器网络架构,其中有一个额外的 AdaIN 层用于样式对齐。在下半部分,你会看到这个惊人想法的一些结果!总之,AdaIN 通过对齐一阶统计量(μ和σ)来执行风格转移(在特征空间中),在复杂性方面没有额外的成本。如果你想玩这个想法,代码可以在这里找到(官方)和(非官方)
2.基于样式的生成器
让我们回到我们最初理解风格的目标——甘。基本上,NVIDIA 在这项工作中完全抓住了我们对 GANs 中大多数发电机的理解和设计。让我们看看怎么做。
在一个普通的 GAN 发生器中,采样的输入潜在空间向量 z 被投影和整形,因此它将通过转置卷积或上采样进行进一步处理,有或没有卷积。在这里,潜在向量由一系列完全连接的层进行变换,即所谓的映射网络 f !这导致了另一个学习向量 w ,叫做中间潜在空间 w。但是为什么有人会这样做呢?
图片由 StyleGAN paper 提供,来源:https://arxiv.org/abs/1812.04948
映射网络 f
这种选择的主要原因是中间潜在空间 W 不必支持根据任何固定分布的采样。通过连续映射,导出其采样密度。这种映射 f“打开”了 W 的空间,因此它隐含地实施了一种解开的表示。这意味着变异因素变得更加线性。作者认为与纠缠的图像相比,基于非纠缠的图像更容易生成真实的图像。有了这个完全无人监管的把戏,我们至少期望 W 比 Z 空间纠缠度小。让我们看一下图中所示的 A。
街区:风格特征
b 区:噪音
此外,作者为 G 提供了明确的噪声输入,作为建模随机细节的直接方法。 B 块是由不相关的高斯噪声组成的单通道图像。它们作为附加噪声图像被馈送到合成网络的每一层。单一噪声图像被广播到所有特征地图。
合成网络 g
除了初始块之外,每一层都从上采样层开始,以使空间分辨率加倍。然后,添加卷积块。在每次卷积之后,2D 每像素噪声被添加到模型随机性中。最后用魔法 AdaIN 层注入与风格对应的已学中间潜空间。
风格混合和截断技巧
不是像 BigGAN 那样截断潜在向量 z,而是在中间潜在空间 W 中使用它。这实现为:w ’ = E(w)—ψ*(w—E(w)),其中 E(w)= E(f(z))。ε表示预期值。控制样品质量的重要参数是ψ。当它接近 0 时,我们粗略地得到收敛到数据集的平均图像的采样面。如下图所示,在 W 空间中截断似乎效果很好:
图片由 StyleGAN paper 提供,来源:https://arxiv.org/abs/1812.04948
正如原论文所完美描述的:
“有趣的是,各种高级属性经常在对立面之间翻转,包括观点、眼镜、年龄、颜色、头发长度,通常还有性别。 " ~泰罗·卡拉斯等人
引入的另一个技巧是风格混合。从潜在空间 Z 采样 2 个样本,它们生成对应于两种风格的两个中间潜在向量 w1、w2。w1 应用于交叉点之前,w2 应用于交叉点之后。这可能是在块内部执行的。这种正则化技巧防止网络假设相邻的样式是相关的。一定比例的生成图像(通常为 90%)使用了这种技巧,并且每次都随机应用于网络中的不同位置。
3.浏览基于样式的生成器的设计选择
每个注入的风格和噪声**(块 A 和 B)** 被定位在网络中。这意味着当修改样式/噪声的特定子集时,预计只会影响图像的某些方面。
风格:我们来看看这种本土化的原因,从风格说起。我们广泛地看到,AdaIN 操作首先将每个通道归一化为零均值和单位方差。然后,它应用基于风格的尺度和偏差。以这种方式,用于后续卷积运算的特征统计被改变。更确切地说,先前的统计/样式在下一个 AdaIN 层中被丢弃。因此,在被下一个 AdaIN 操作覆盖之前,每个样式只控制一个卷积。
噪声:在传统的发生器中,潜在向量 z 被馈入网络的输入端。这被认为是次优的,因为它消耗了发电机的学习能力。这是合理的,因为网络需要发明一种方法来从早期激活生成空间变化的数字。
通过在每次卷积后添加每像素噪声,实验验证了噪声的影响出现在网络的局部。与 BigGAN 类似,每个层都有新的噪声,因此没有动力从先前的激活中产生随机效果。
以上都可以举例说明如下:
图片由 StyleGAN paper 提供,来源:【https://arxiv.org/abs/1812.04948
在左边,我们有生成的图像。在中间,4 种不同的噪声应用于所选的子区域。右边可以观察到一大组不同噪声的样本的标准差。
4.量化空间的解开
令人惊叹的是,他们第一次能够量化空间的解缠。因为如果你数不过来,它就不存在!为此,他们引入了两种新的方法来量化空间的混乱。
感知路径长度
如果你对纠缠和不纠缠的表示感到不舒服,你可以重新访问 InfoGAN 。用非常简单的术语来说,纠缠是混合的,解纠缠与编码相关,但在某种程度上是可分离的。我喜欢把解开的表征称为一种低维度数据的解码信息。
假设我们有两个潜在的空间向量,我们想在它们之间进行插值?我们怎么可能确定“潜在空间的行走”对应于一个纠缠或不纠缠的表象?直观上,不太清晰的潜在空间应该导致在图像中观察到的感觉上平滑的过渡。
潜在空间向量的插值可以告诉我们很多。例如,图像中可能出现非线性、不平滑和急剧的变化。你怎么称呼这样的代表?例如,在任一端点都不存在的要素可能会出现在线性插值路径的中间。这是一个混乱世界的标志,即纠缠表象。
量化是根据潜在空间中的小步长ε来进行的。如果我们把一个潜在的空间插值路径细分成小段,我们就可以测量距离。后者在两个步骤之间测量,具体为 t,其中 t 在[0,1]中,t+ε。然而,基于生成的图像来测量距离是有意义的。因此,人们可以将所有步骤的距离相加,以穿过两个随机的潜在空间样本 z1 和 z2 。注意,距离是在图像空间中测量的。实际上,在这项工作中,他们测量了两个 VGG 网络嵌入之间的成对距离。数学上这可以描述为(slerp 表示球面插值):
图片由作者提供,最初用 Latex 编写
有趣的是,他们发现通过添加噪声,路径长度(平均距离)大约减半,而混合风格略有增加(+10%)。此外,这一测量证明,8 层全连接架构显然产生了一个中间潜在空间 W,它比 z 更不纠缠。
线性可分性
让我们看看这是如何工作的。抓紧了!
- 我们首先用z∾P(z)生成 200K 幅图像,并使用标签为 Y 的辅助分类网络对它们进行分类。
- 我们保留 50%具有最高置信度得分的样本。这导致 100k 高分自动标记( Y )潜在空间向量 z 用于渐进 GAN,w 用于风格 GAN。
- 我们拟合一个线性的 SVM 来预测标签 X 仅基于潜在空间点( z 和 w 用于样式-GAN)并且通过这个平面分类这些点。
- 我们计算条件熵 H( Y | X ),其中 X 表示由 SVM 预测的类别, Y 是由分类器确定的类别。
- 我们按照 exp(σ(H(Y | X))计算可分性得分,对数据集的所有给定属性求和。我们基本上为每个属性拟合一个模型。请注意,CelebA 数据集包含 40 个属性,如性别信息。
定量结果可在下表中观察到:
图片由 StyleGAN paper 提供,来源:https://arxiv.org/abs/1812.04948
本质上,给定 SVM 标签 X ,条件熵 H 告诉我们需要多少额外信息来确定样本的真实类别。理想的线性 SVM 将导致完全确定地知道 Y ,导致熵为 0。高熵值意味着高不确定性,因此基于线性 SVM 模型的标签根本不能提供信息。不夸张的说,熵 H 越低越好。
结论
GANs 上提出的工程解决方案一直让我惊叹不已。在本文中,我们看到了一个令人兴奋的设计,它通过自适应实例规范化来注入参考图像的样式。风格-甘绝对是该领域最具革命性的作品之一。最后,我们强调了所提出的线性可分性的度量,这使得我们在本系列中深入到越来越多的高级概念。
一如既往,我们专注于直觉,我们相信你不会气馁,开始尝试甘。如果你想开始用一堆模型进行实验以重现最先进的结果,你绝对应该检查 Tensorflow 中的这个开源库或者 Pytorch 中的这个 one 。
下一部AI Summer 上有!
参考
[1]t .卡拉斯、s .莱恩和 t .艾拉(2019 年)。一种基于风格的生成对抗网络生成器体系结构。在IEEE 计算机视觉和模式识别会议论文集(第 4401–4410 页)中。
[2]伊奥费和塞格迪(2015 年)。批量标准化:通过减少内部协变量转移加速深度网络训练。 arXiv 预印本 arXiv:1502.03167 。
[3]乌里扬诺夫博士、韦达尔迪博士和莱姆皮茨基博士(2016 年)。实例规范化:快速风格化缺少的要素。 arXiv 预印本 arXiv:1607.08022 。
[4]t .宫户,t .片冈,Koyama,m .,& Yoshida,Y. (2018)。生成对抗网络的谱归一化。arXiv 预印本 arXiv:1802.05957 。
原载于 2020 年 5 月 9 日 https://theaisummer.com**的 。
使用机器学习分析韩国流行音乐|第 1 部分—数据收集和清理
K-Pop 机器学习教程系列
这是教程的第 1 部分,我在这里收集 K-Pop 数据并清理数据。
视频版附解说:https://youtu.be/lkhorCY5tFA
我的整个代码:https://github . com/import Data/kpop-analysis/blob/master/K _ pop _ Data _ cleaning . ipynb
介绍
作为一个在韩国出生和长大的人,我是听着 K-pop 长大的。这些年来,韩国流行音乐成为了一种全球现象,它的流行程度至今仍让我难以置信。
所以,我认为使用机器学习来分析 K-pop 以探索有趣的见解会很酷。谢谢查宁(又名。数据教授为理念!
在这篇文章中,我将向您展示数据科学周期中的数据收集和数据清理阶段。
数据收集
我不得不做一些谷歌搜索来找到数据集。经过一番搜索,我发现这个网站有一个 excel 文件。这是一项关于社交媒体和韩国流行音乐的调查,我觉得很有趣。我喜欢他们问的问题,也喜欢最近进行的调查。
该数据集包含来自世界各地的 240 名 K-pop 粉丝,共有 22 个调查问题。
数据集链接:Rraman,Saanjanaa (2020): KPOP 数据. xlsx. figshare。数据集。https://doi.org/10.6084/m9.figshare.12093648.v2
数据清理
数据清理是一个重要的步骤,因为您需要用于 EDA 和模型构建的最干净的数据。如果你把垃圾放进去,那么你会从模型中得到垃圾。
数据集可能有前导空格和尾随空格。所以,我决定用这个函数去掉那些空白。然后我删除了第一列“时间戳”,因为它没有用。
函数来删除数据帧中的前导和尾随空格
因为列名就是问题,而且它们太长,所以我决定给它们取代码名来简化列。
重命名列
接下来,检查数据集是否有空值。
检查空值
有三列包含空值。首先,让我们检查只有一个空值的列。
我发现 life_chg 和 money_src 中的空值都是“n/a”,于是干脆用字符串“none”代替。
对于“daily_MV_hr”列,我决定用平均值替换空值。有多种方法可以处理空值(删除行,分配唯一的类别,或者可以运行回归模型来预测丢失的值,等等),但是我认为用平均值替换它们是最好的选择。
我取 1 和 4 的平均值,即 2.5 小时,去掉了“小时”这个词。我注意到有些类别在范围内,所以为了简单起见,我取了这些范围的平均值。我创建了一个特殊的函数来处理这个问题。
函数在一些有范围而另一些没有范围时寻找平均值
清洁“每日 MV 小时”色谱柱之前和之后
我意识到这个数据集有点乱。所以我重复了类似的步骤来清洁每根柱子。
- “yr_listened”栏
清理“yrs _ listened”列的过程
我将只向您展示每一列之前和之后的图片。
- “每日新闻人力资源”栏目
《每日 _ 音乐 _hr》前后
- “年度支出”栏
“yr _ merch _ spent”之前和之后
- “年龄”栏
前后“年龄”
- “收藏组”栏
原始列值
制作一个单独的列来查找每个人喜欢的组的数量
BTS 与其他的单独列
- “nes_medium”列
原始列值
简化的列值
- “追求”栏目
原始列值
简化的列值
- “时间常数”栏
原始列值
简化的列值
- “生活 _ 变化”栏
原始列值
简化的列值
- “pos_eff”列
原始列值
简化的列值
- “money_src”列
原始列值
简化的列值
- “疯狂 _ev”专栏
原始列值
简化的列值
- “国家”栏
原始列值
简化的列值
终于清理完数据了!
我将清理后的数据框保存到一个 CSV 文件中,以供教程的下一部分使用。
将清理后的数据帧保存到 CSV
在第 2 部分,我将讨论本教程的探索性数据分析部分。敬请期待!
使用机器学习分析韩国流行音乐|第 2 部分—探索性数据分析(EDA)
K-POP 机器学习教程系列
这是教程的第二部分,我从变量中发现了有趣的见解。
在 Unsplash 上 Saveliy Bobov 拍摄的照片
带解释的视频版本
第一部分—本教程的数据收集和数据清理可以在 这里找到 。
现在让我们做一些探索性的数据分析这个项目的一部分!
我的完整代码可以在 这里 找到。
正在完成数据清理
在上一个教程中,我意识到我忘记了清理三个列(变量)-“性别 _ 偏好”,“原因”和“工作”,所以我很快先清理了它们。
- 对于“gender_pref”,我把它们重新贴上“男性”、“女性”、“两者皆有”、“是关于音乐”的标签,以简化它们。
- 对于“原因”,我按照“独特的音乐风格”、“独特的编舞”、“有魅力的偶像”、“很多原因”、“其他原因”来分类。
- 对于“工作”,我把他们分为“学生”、“全职工人”和“失业者”
分析连续变量
首先,我检查连续变量的描述——“yr _ listened”、“daily_music_hr”、“daily_MV_hr”、“yr _ merch _ spent”、“age”、“num_gr_like”。
检查连续变量的描述
连续变量的描述
我们可以看到,粉丝平均年龄为 18 岁,他们听 k-pop 的时间大约为 3 年。他们每天花 4.3 小时听 k-pop,花 1.95 小时看 k-pop 音乐视频。他们平均在韩国流行商品上花费 85 美元。
检查连续变量的直方图
- 您可以看到由于一些异常值,“yr_listened”变量的分布有点向右倾斜。
“yr_listened”直方图
- “每日 _ 音乐 _hr”正态分布
“每日 _ 音乐 _ 小时”直方图
- 《daily_MV_hr》有点右倾
“每日 MV 小时”直方图
- “年销售额”接近正态分布
“年销售额”直方图
- “年龄”呈正态分布
“年龄”直方图
- “num_gr_like”是右偏的
“数量类”直方图
检查箱线图以检测异常值
绘制箱线图可以帮助您检测异常值。
- 我们看到“yr_listened”和“yr _ merch _ spent”中有一些异常值。
“每日音乐小时”、“每日音乐小时”、“年听音乐小时”和“年消费”的方框图
- “num_gr_like”有很多离群值
“数量 _ 类别”的箱线图
移除异常值并再次检查分布
让我们从“yr_listened”和“num_gr_like”中删除异常值,并检查直方图,看看分布中是否有任何变化。
“yr_listened”和“num_gr_like”的直方图
我们可以明确的看到“yr_listened”现在是正态分布,而“num_gr_like”不是。太多的人只喜欢 1 或 2 组,所以去除离群值不会对分布产生太大影响。
检查连续变量之间的相关性
检查相关性很重要,因为我们想知道哪些变量是相关的。在模型构建过程中,我们不希望出现多重共线性——当自变量高度线性相关时。这可能会在拟合回归模型时导致问题。
修复多重共线性的方法有哪些?欢迎在下方的评论区回答这个问题!
检查关联矩阵和关联热图
根据相关矩阵,我们看到连续变量之间不存在多重共线性——没有相关性接近于 0。
我们可以看到这些关系:
- 他们听 k-pop 的年数与他们听 k-pop 的小时数、他们在商品上的花费和年龄正相关。
- k-pop 粉丝看 k-pop youtube 音乐视频的小时数与听 k-pop 的小时数呈正相关。
- 他们花在听 k-pop 上的时间越多,他们花在购买 k-pop 商品上的钱就越多。
- 他们看的 k-pop youtube 视频越多,听的 k-pop 越多,他们喜欢的组合就越多。
- 年龄越小,花在听 k-pop 和看 k-pop 视频上的时间越多。
- 年龄与他们每年花多少钱购买 k-pop 商品无关。
分析分类变量
现在,让我们分析分类变量。
制作分类变量的数据框架
条形图
让我们绘制柱状图来展示分类变量。以下是一些发现。
- BTS 显然是最著名的团体
收藏夹组的条形图
- 韩国流行音乐在许多国家越来越受欢迎
k-pop 流行度条形图
- 很多粉丝喜欢 K-pop 是多重原因,其次是“独特的音乐风格”。不是很多人听 K-pop 只是因为偶像的外表。
原因条形图
- 很多粉丝既喜欢男团也喜欢女团,其次是重男轻女和“是关于音乐的”。没有多少人只喜欢女团。
性别偏好条形图
- 240 人中大约有 90 人因为喜欢韩国流行音乐而被取笑。大约 70 人说他们的睡眠时间减少了。
生活变化条形图
- 超过 120 人说他们通过听 k-pop 减轻了压力/焦虑/抑郁。这对我来说非常有趣,因为我认为鉴于很多人被取笑,不会有很多积极的影响。大约 80 人通过韩国流行音乐交了朋友。
正面效果条形图
- 有很多美国 k-pop 粉丝,其次是英国、其他欧洲国家和加拿大。
国家条形图
使用数据透视表查找关系
让我们也用数据透视表找出变量之间的一些关系。
- 听 k-pop 和看 k-pop YouTube 视频有助于粉丝减轻压力,并帮助他们结交更多朋友
听/看 kpop 与积极效果的关系
- 大部分钱都花在了购买音乐会门票上
去听音乐会和他们花在韩国流行商品上的钱之间的关系
- 年长的 K-pop 粉丝(24 岁左右)因为喜欢 K-pop 而被取笑。年轻的 K-pop 粉丝通过 K-pop 交朋友。
年龄与积极效果和生活变化的关系
就是这样!当然,在数据科学周期的探索性数据分析部分,您总是可以更深入地找到更多见解。一旦你很好地理解了你想在模型构建过程中做什么,那么你就可以在那里停下来。
我在我的代码中有更多的发现,所以如果你想检查一下,请到我的 GitHub 链接。
感谢您的阅读!
使用机器学习分析韩国流行音乐|第 3 部分—建模
K-POP 机器学习教程系列
这是本教程的第 3 部分,我构建了不同的预测模型并比较了结果。
可以在这里 找到之前的教程 。
注意:你可以在这篇文章的底部找到我的全部代码的链接。
现在让我们做一些模型建设!
对数据框进行子集划分,并将分类变量转换为虚拟变量
对于模型构建,我删除了“fav_grp”列,因为我们在探索性数据分析中看到有太多的组,而 BTS 是主导组。
df_model = df[['popl_by_co_yn', 'reason', 'yr_listened', 'gender_pref','daily_music_hr', 'watch_MV_yn', 'daily_MV_hr', 'obsessed_yn','news_medium', 'pursuit', 'time_cons_yn', 'life_chg', 'pos_eff','yr_merch_spent', 'money_src', 'concert_yn', 'crazy_ev', 'age','country', 'job', 'gender', 'num_gr_like', 'bts_vs_others']]
然后,我得到虚拟数据,将分类变量转换为回归模型的虚拟/指示变量。
获取虚拟数据以转换分类变量
训练和测试分割
主要目标是使用其他独立变量预测“每日音乐小时数”——K-pop 粉丝听 K-pop 的小时数。
设 X 为除“每日 _ 音乐 _hr”之外的所有其他变量,设 Y 为“每日 _ 音乐 _hr”。然后我们用 80%作为训练集,剩下的 20%作为测试集。
多元线性回归
由于我们有一个小数据集(只有 240 行),我们希望避免使用复杂的模型。所以我们从多元线性回归开始。
from sklearn.linear_model import LinearRegressionfrom sklearn.metrics import mean_absolute_error# initialize the linear regression modellm = LinearRegression()# train the modellm.fit(X_train, y_train)# perform predicion on the test datay_pred = lm.predict(X_test)# performance metricsprint('Coefficients:', lm.coef_)print('Intercept:', lm.intercept_)print('Mean absolute error (MAE): %.2f' % mean_absolute_error(y_test, y_pred))
对于指标,我们将使用 MAE(平均绝对误差)来检查模型的准确性。
多元线性回归的系数和平均误差
多元线性回归(MLR)模型的 MAE 为 2.17。这意味着平均来说,我们的预测有 2.17 小时的误差。由于 K-pop 粉丝听 K-pop 的小时数从 0 到 10 不等,这是相当合理的。但是让我们看看我们是否能做得更好。
在同一个多元线性回归模型上,我们将应用 10 重交叉验证来概括数据。10 折交叉验证的工作原理是这样的——它在数据中创建了 10 个组,留下 1 个组进行验证,并使用剩余的 9 个组进行训练。最终,它创造了 10 种不同的 Mae。
然后我们取它们的平均值,得到一个单一的 MAE-1.98。
我们可以看到比上面的稍微好一点。
使用 10 重交叉验证的 MLR 的 MAE
套索回归
构建模型时处理小数据的另一种方法是使用正则化模型。Lasso ( L 东Ab soluteShrinkage 和SelectionOoperator)使用收缩(alpha)。收缩是指数据值向中心点收缩,如平均值。
它应用 L1 正则化,这增加了等于系数幅度绝对值的惩罚。
套索的 MAE 是 1.58。
拉索回归的 MAE
我们也可以尝试寻找最优的 alpha 来找到最佳的套索模型。
我们看到最佳 alpha 值是 0.09,MAE 现在稍微好一点,为 1.57。
寻找套索回归的最佳α
里脊回归
与 Lasso 类似,岭回归也增加了惩罚。它使用 L2 正则化。与 Lasso 回归的唯一区别是,它使用系数的平方大小,而不是绝对值。
岭回归的 MAE 为 1.85,与 lasso 相比并不算大。
岭回归的 MAE
我们也可以尝试找到最佳收缩参数,但根据图,看起来我们已经有了最佳收缩参数。
看我们是否能找到最佳收缩率
随机森林回归量
基于树的模型可以是好的模型,只要它们不太深。
我们可以看到 RF 的 MAE 为 1.61。
随机森林回归的 MAE
我们还可以尝试调整随机森林模型的超参数。使用 GridsearchCV 是调优参数的好方法。
下面是调整随机回归参数的一种方法。
from sklearn.model_selection import GridSearchCVparams = {'n_estimators':range(10,100,10),
'criterion':('mse','mae'),
'max_features':('auto','sqrt','log2')}gs_rf = GridSearchCV(rf, params,
scoring = 'neg_mean_absolute_error', cv = 10)gs_rf.fit(X_train, y_train)
使用最佳估计量,最佳 MAE 为 1.51。
调谐随机森林
XGBoost
另一个基于树的模型是 XGBoost。
XGBoost 的 MAE 为 1.54。
XGBoost 的 MAE
我们还可以尝试调整超参数,就像我们对随机森林模型所做的那样。
params = {'min_child_weight': [3, 5, ],
'gamma': [0.5, 1],
'subsample': [0.8, 1.0],
'colsample_bytree': [0.6, 0.8],
'max_depth': [1,2]}gs_xgb = GridSearchCV(xgb, params,
scoring = 'neg_mean_absolute_error', cv = 10)gs_xgb.fit(X_train, y_train)
调优后的 XGBoost 的 MAE 为 1.33。
调优的 XGBoost
比较所有型号的性能
作为本教程的总结,我们将比较我们构建的所有模型的性能。
lm_pred = lm.predict(X_test)lm_las_pred = lm_las.predict(X_test)lm_rid_pred = lm_rid.predict(X_test)rf_pred = gs_rf.best_estimator_.predict(X_test)xgb_pred = gs_xgb.best_estimator_.predict(X_test)
比较模型性能
我们看到 XGBoost 是最好的模型!平均而言,预测误差为 1.23 小时。
当然,你可以花几天时间去寻找“最好”的模型,但同时,我们也希望有效率。
感谢您的阅读!接下来的教程,我要讲的是模型制作!
使用机器学习分析 K-Pop |第 4 部分—生产模型(模型部署)
K-POP 机器学习教程系列
这是教程的第 4 部分,我使用 FLASK 将预测模型投入生产。
可以在这里 找到之前的教程 。
视频版本
注意:你可以在这篇文章的底部找到整个 GitHub 库的链接。
在本教程中,我将向您展示如何将一个模型投入生产(又名。模型部署)。
什么是模型部署?模型部署是将机器学习模型集成到现有的生产环境中,以根据数据做出实际的业务决策。
我们将使用 Python web API 和 FLASK 来部署模型。因此,我们的最终目标是创建一个网站,一旦用户输入了输入值,它就会向您提供预测结果。
从 GitHub 下载我的文件
首先,去我的 GitHub 页面上的 K-Pop 库下载模型部署文件夹。
我们将使用名为 GitZip 的网站,该网站允许您下载回购中的特定文件夹。您所需要做的就是将链接复制并粘贴到我的模型部署文件夹中。
在这里复制并粘贴我的文件夹链接
您可以随意命名文件夹。我将把我的命名为“K-Pop 模型部署”
使用 Spyder IDE
在本教程中,我们将使用 Spyder IDE。
如果你还没有安装,你可以从这里下载(你需要从 Anaconda 网站下载)。请务必下载 3.7 版本,因为这是最新版本。
安装 Anaconda (Python 3.7)
安装后,打开 Spyder IDE,导航到“文件资源管理器”并选择您刚刚下载的文件夹。
打开模板文件夹下的 app.py、k_pop_model_building.py 和 index.html。
Spyder 的文件浏览器
仅选择连续变量
在上一篇教程中,我们使用. pd.get_dummies(df_model)将分类变量转换为虚拟/指示变量。我意识到这产生了太多额外的变量,我认为这不是很用户友好(我们不想让用户输入 73 个答案)。因此,我们将只选择连续变量—这样用户只需输入五个变量(“yr_listened”、“daily_MV_hr”、“yr _ merch _ spent”、“age”、“num_gr_like”)来预测“daily _ music _ HR”—他们每天听 K-pop 的小时数。
df_real = df[[“yr_listened”, “daily_music_hr”, “daily_MV_hr”,
“yr_merch_spent”, “age”, “num_gr_like”]]
然后,运行列车并再次测试分离。
from sklearn.model_selection import train_test_splitX = df_real.drop('daily_music_hr', axis = 1)
y = df_real.daily_music_hr.valuesX_train, X_test, y_train, y_test = train_test_split(X, y,
test_size = 0.2,
random_state = 1)
运行 XGBoost 模型
从上一个教程中,我们看到 XGBoost 模型是最好的一个。因此,我们将部署这种模式。
import xgboost as xgb# initialize the linear regression model
xgb_clf = xgb.sklearn.XGBClassifier(nthread = -1, seed = 1)# train the model
xgb_clf.fit(X_train, y_train)# Tune XGBoost using GridSearchCVfrom sklearn.model_selection import GridSearchCVparams = {'min_child_weight': [5], 'gamma': [1],
'subsample': [0.8, 1.0],
'colsample_bytree': [0.6, 0.8],
'max_depth': [1,2]}gs_xgb = GridSearchCV(xgb_clf, params ,
scoring = 'neg_mean_absolute_error',
cv = 10)gs_xgb.fit(X_train, y_train)gs_xgb.best_score_xgb_best = gs_xgb.best_estimator_
xgb_bestxgb_best.fit(X_train, y_train)
保存已训练的模型
我们可以使用 pickle 将训练好的模型保存到磁盘上。它可以在以后重新加载,就像我们训练过的一样使用。
# save the model to disk
with open('model.pkl', 'wb') as file:
pickle.dump(xgb_best, file)
使用 FLASK 创建 Web 应用程序
首先,我们需要这两样东西来创建一个 web 应用程序。
- Python 脚本将加载训练好的模型,要求用户将输入值放在网站上,执行预测,并返回结果。
- HTML 模板是网站的格式。这将允许用户输入他们的数据,并将呈现结果。
其结构如下所示:
web app/
index.html├──model/
│└──model . pkl—训练好的模型
├──模板/
│└──—网站格式
└── app.py —托管模型
创建 app.py 来托管模型
app.py 将成为网络应用的主干。它会发送网页,从用户那里获取数据来进行预测。
# use flask to host the modelimport flask
import pickle
import pandas as pd# Use pickle to load in the pre-trained model
with open(f'model.pkl', 'rb') as f:
model = pickle.load(f)# initialize the flask app
app = flask.Flask(__name__, template_folder='templates')# set up the main route
[@app](http://twitter.com/app).route('/', methods=['GET', 'POST'])
def main():
if flask.request.method == 'GET':
# rendering the initial form, to get input
return(flask.render_template('index.html'))
if flask.request.method == 'POST':
# extracting the input values
yr_listened = flask.request.form['yr_listened']
daily_MV_hr = flask.request.form['daily_MV_hr']
yr_merch_spent = flask.request.form['yr_merch_spent']
age = flask.request.form['age']
num_gr_like = flask.request.form['num_gr_like']
# making dataframe for model
input_variables = pd.DataFrame([[yr_listened, daily_MV_hr, yr_merch_spent, age, num_gr_like]],
columns=['yr_listened', 'daily_MV_hr', 'yr_merch_spent', 'age', 'num_gr_like'],
dtype=float,
index=['input'])
# get the model's prediction
prediction = model.predict(input_variables)[0]
output = float(round(prediction, 2))
# render the form again, but add in the prediction and remind user of the values they input before
return flask.render_template('index.html',
original_input={'yr_listened':yr_listened,
'daily_MV_hr':daily_MV_hr,
'yr_merch_spent':yr_merch_spent,
'age':age,
'num_gr_like':num_gr_like},
result=float(output)
)
if __name__ == "__main__":
app.run(debug=True)
创建 index.html 来格式化我们的网站
这是这个项目的前端部分。它将要求用户输入值,执行预测,并给我们输出。这是很基础的风格。我试着玩 CSS,但无法真正让它工作。如果你了解 CSS 或者想尝试一下样式,请随意!
<!doctype html>
<html>
<style>
form {
margin: auto;
width: 35%;
}.result {
margin: auto;
width: 35%;
border: 1px solid #ccc;
}
</style><head>
<title>Predicting Daily K-Pop Listening Hours</title>
</head>
<form action="{{ url_for('main') }}" method="POST">
<fieldset>
<legend>Input values:</legend>
Number of years you listened to K-Pop:
<input name="yr_listened" type="number" step=".01" required>
<br>
<br> Number of hours you watch K-Pop MV per day:
<input name="daily_MV_hr" type="number" step=".01" required>
<br>
<br> How much money you spend on K-Pop merchandise a year:
<input name="yr_merch_spent" type="number" step=".01" required>
<br>
<br> Your age:
<input name="age" type="number" step=".01" required>
<br>
<br> Number of groups you like:
<input name="num_gr_like" type="number" step=".01" required>
<button type="submit" class="btn btn-primary btn-block btn-large">Predict!</button>
</fieldset>
</form>
<br>
<div class="result" align="center">
{% if result %}
{% for variable, value in original_input.items() %}
<b>{{ variable }}</b> : {{ value }}
{% endfor %}
<br>
<br> Predicted Daily K-Pop Listening Hours:
<p style="font-size:50px" step=".01">{{ result }}</p>
{% endif %}
</div></html>
运行 Web 应用程序
现在我们终于可以测试看看是否一切都按照我们想要的方式工作了!
- 转到 Anaconda 提示符
- 将目录更改为您的工作文件夹(即 cd 桌面-> cd K-Pop 模型部署)
- 运行 app.py(即 python app.py)
- 将你得到的链接复制并粘贴到浏览器上
- 输入值,检查它是否给出了预测
Anaconda 提示符命令示例
cd Desktop
cd K-Pop Model Deployment
python app.py
工作 Web 应用程序
我们完了。希望你觉得这个教程有用!
在下一个教程中,我将向你展示如何通过创建一个作品集网站来记录这个项目!敬请关注。
使用机器学习分析 K-Pop |第 5 部分— GitHub 文档和作品集网站
K-POP 机器学习教程系列
这是本教程的最后一部分,我将展示如何在 GitHub 上记录您的工作,以及如何使用 GitHub 托管一个简单的作品集网站。
可以在这里 找到之前的教程 。
视频版本
注意:你可以在这篇文章的底部找到整个 GitHub 库的链接。
我想通过在 GitHub 上记录它并使用 GitHub 创建一个简单的作品集网站来结束这篇教程。特别感谢 Ken Jee 提供的关于如何创建简单投资组合网站的视频。
在 K-Pop 回购中增加概述部分
Overview
- Created a web application that returns the predicted number of hours one listens to K-Pop on a daily basis (MAE ~ 1.2 hours).
- Engineered features from the text of each column.
- Explored the data to analyze the relationships among the features.
- Built five different regression models — linear, lasso, ridge, random forest, and XGBoost.
- Optimized the random forest and the XGBoost models using GridSearchCV to find the optimal parameters.
为投资组合网站创建回购
创建新的存储库
存储库->新建->用 README.md 初始化
我把我的命名为“ds-简单-投资组合”。
在 README.md 文件中添加内容
我将为 K-Pop 分析项目添加如下描述。
我还将在这里添加一些图像——一个用于 web 应用程序的图像和一些用于探索性数据分析的图像。
在 README.md 文件中添加完内容后,请转到“设置”。
向下滚动到“GitHub Pages”,打开“Source”下的“Master Branch”。
一旦你点击它,它会给你一个网址,这是你的工作组合网站!
你也可以选择你喜欢的主题。
最终作品集网站
感谢您在本教程中调谐!向所有晋级到最后一轮的人致敬。我个人很享受这个旅程,因为我学到了以前没有用过的技术。我学会了如何使用 GridSearchCV 寻找最佳参数,还学会了如何部署模型和创建 web 应用程序。
分析 MacBook GPU 性能;使用 MLflow 和弹性 Kibana 进行可视化
使用 AMD GPU、英特尔 UHD 和英特尔 CPU 加速深度学习的各种 MacBook PlaidML 配置的比较;用 Databricks MLflow 和 Elastic Kibana 可视化。
首先,我们要感谢您选择 PlaidML。无论您是新用户还是多年的老用户,我们都非常…
github.com](https://github.com/plaidml/plaidml)
一名观众对我的 YouTube 视频发表了评论,该视频展示了如何在 MacBook 上为 Keras 启用 AMD GPU 加速。
非常正确
评论指出我选择的 OpenCL 库不如 Metal 库性能好。这激起了我的好奇心。金属永远比 OpenCL 快吗?快了多少?AMD GPU 比英特尔 UHD 和英特尔 CPU 快多少?我 MacBook 中的三个计算设备是:
- 镭龙 Pro 560X 4 GB
- 英特尔 UHD 显卡 630 1536 MB
- 2.3 GHz 英特尔酷睿 i9,16 个线程,32 GB 主内存
TL;速度三角形定位法(dead reckoning)
DavidVilla147BVB 懂他的东西!在 MacBook 上加速深度学习,Metal 库绝对比 OpenCL 库快。在下图中,Y 轴是网络架构,从下到上依次为:IMDB_LSTM、MobileNet、NasNet Mobile、VGG16、VGG19。X 轴从左到右是以下计算配置:英特尔 CPU、OpenCL-UHD、金属 UHD、OpenCL-GPU、金属 GPU。
Y =网络架构;X =设备/库
一位同事最近提出了 MFflow,这个小实验似乎是检验它的完美借口。在这个实验中,我发现 PlaidML 有自己的一套称为 Plaidbench 的性能测试。Plaidbench 将其结果写成 JSON。拥有一堆需要分析的 JSON 文档引发了我对 Elastic 和 Kibana 的思考。以下是对 MFLow 和 Elastic 的 Kibana 的分析和可视化。我的设置如下。
PlaidML 与 Python 虚拟环境(venv)
我的第一步是用 pip 安装 PlaidML。最近,我一直在为新项目创建 python 虚拟环境,并将它们全部放在 NFS 的一个位置,以便在任何计算机上使用。以前,我只是在我的 Conda 环境或默认环境中运行。如果我感觉像青蛙,我会用 Docker 容器…我想这是我应该一直做的。
PlaidML venv & pip(与 asciinema.org 一起录制)
PlaidML 安装脚本
PlaidML 有一个简单的设置脚本,可以创建一个 JSON 文件,~/.plaidml。
要尝试所有可能的配置,而不仅仅是 AMD 的 Metal,您必须复制~/。plaidml 文件到另一个位置。否则,您只会覆盖之前的~/。plaidml 文件。我选择将该文件复制到一个更具描述性的文件名中,以指示其内容,然后为我想要测试的每个配置重新运行‘plaidml-setup’脚本。这看起来是这样的:
然后,对于每个试验,我将所需的测试配置文件复制到~/.plaidml 中。例如,要使用 OpenCL 测试英特尔 UHD,我会将“opencl_uhd.json”复制到“~/”。因为这是 Plaidbench 期望这个配置文件所在的位置。我可以修改代码,但我发现交换文件很容易。
数据块 MLflow
机器学习生命周期的开源平台 MLflow 是一个管理机器学习生命周期的开源平台
mlflow.org](https://mlflow.org/)
mlflow
我一直在寻找一个借口来测试 MLflow,这似乎是一个完美的用例。我运行了许多 ML 试验,这个开源软件很容易安装、使用和探索它的 web UI。
MLflow 安装和 UI 启动
UI 运行后,可以通过本地主机上的浏览器在端口 5000 上访问它:http://locah host:5000
运行我的试验
现在,我已经准备好开始开发和运行我的基准代码了。由于 PlaidML 库附带了一个基准测试系统,所以只需要用正确的计算机硬件和库调用基准测试系统。使用的五种硬件和软件加速器配置是:
- 带 AMD 的金属
- 带 AMD 的 OpenCL
- 金属带英特尔 UHD
- OpenCL 与英特尔 UHD 合作
- 英特尔 CPU
我选择了五种网络架构进行测试,以便在合理的时间内完成测试。这些网络是:
- MobileNet
- 纳斯特移动
- IMDB
- VGG16
- VGG19
由于每个基准测试都调用 PlaidML 中的’ exit()',所以我创建了一个 bash 脚本来重复调用我的 Python 脚本。Python 脚本验证试验尚未运行,然后运行试验。对于这样一个简单的项目,在 MLflow 中调用这三个基本函数。
- mlflow.start_run() #表示单次试验的开始
- ml flow . log _ param(’ param _ name ',value) #零到多个您希望跟踪的参数,~个独立值
- ml flow . log _ metric(’ metric _ name ',value) #要分析的结果,~相关值
trial.py(已创建 w/ carbon.now.sh )
trial_driver.sh
MLflow 中的结果
我检查了 MLflow 中的原始数据,然后深入研究了网络架构。我发现用简单的查询语法深入数据很容易,但是我发现绘图系统有点初级。为了深入研究 IMDB LSTM 网络的结果,我简单地用*params . network = ’ IMDB _ lstm '*进行了查询,然后进行了基本的绘图。这里是一个快速查看一对夫妇的图表明,AMD 的金属库 GPU 确实是最快的设置。
情节 1
情节 2
这里有一个动画 GIF 演示如何创建前两个情节。
mlflow 演示
MLflow 摘要
MLflow 是一个不错的工具。我喜欢它入门的简单性,简单的 API,以及漂亮而简单的 web UI。我认为 Databricks 最终会把它建成更有价值的东西。最重要的是,我喜欢它是开源的,而不是像 Spark 一样绑定(或锁定)在一个单一的技术上。我也喜欢它有一个 Python API。
基巴纳的结果
刚到基巴纳?这是你开始工作所需要的一切。观看视频,了解使用 Kibana 进行数据分析的核心概念…
www.elastic.co](https://www.elastic.co/kibana)
这里是我的 Kibana 仪表板的一个演示,展示了 plaidbench 设置的各种总执行时间。
基巴纳设置
要让 Kibana 快速运行,您可以运行一个 ElasticSearch Docker 映像,然后运行一个 Kibana Docker 映像。一旦您的容器运行,几行 Python 代码将索引所有基准 JSON 文件。
在 Docker 中创建 ElasticSearch + Kibana“集群”
用 Python 索引原始数据
要将数据输入 ElasticSearch,你需要一个“索引”然后这个索引需要一个“映射”我认为映射是索引数据的模式。Elastic 的一个很好的特性是你可以简单地开始索引数据,Elastic 会为你创建一个默认的索引和映射。这就是你搜索所需要的一切。除了搜索,还需要做更多的工作。在我的例子中,我想用 Kibana 进行可视化分析,所以我为我的数据创建了一个自定义映射。
Elastic 在所有主要语言中都实现了一个干净的 API,或者你可以使用他们各种*Stash 应用程序中的一个来代替编码。我用 Python 做了我的自定义映射。我的代码根据值是否可以转换为数字来自动创建我的映射(即模式)。如果没有,我将字段类型设置为“keyword”而不是“text ”,这样我就可以在 Kibana 中执行聚合。
我的自动映射 Python 代码
Python 中的自动弹性映射
我的弹性索引代码
Python 弹性索引
基巴纳可视化
在我索引我的代码之后,我构建了我的 Kibana 仪表板。
这一部分总是令人愉快的。我还没有从 Kibana 的“镜头”功能中得到任何东西,但公平地说,它仍处于测试阶段。各个可视化效果是同步的,这样,如果您深入查看一个小部件,整个仪表板都会更新。您还可以添加一个客户小部件,让查看者能够执行深入分析。选择您的各种范围和过滤器并单击“应用更改”按钮将更新整个仪表板。
自定义深入小部件
自定义小部件的演示
摘要
MLflow 有潜力,但我认为需要以简单性为代价增加一点功能。在我的下一篇文章中,我将分享如何在 Kibana 中创建一个仪表板。不难,但和大多数事情一样,细节的微调也不简单。但大多数情况下,如果你试图在 Mac 或 MacBook 上加速你的深度学习,请始终使用金属库。谢谢 DavidVilla147BVB。
用 Python 分析医疗保险数据
使用 BigQuery 在 Python 中提取和分析医疗保险数据
医疗保险是为 65 岁及以上的美国人提供的单一付款人国家社会健康保险计划。它还包括一些有残疾状况的年轻人、ALS 患者和终末期肾病患者。医疗保险和医疗补助服务中心向公众提供医疗保险数据。可以通过 Google BigQuery 访问数据。
您可以使用数据集来回答以下问题:
- 每个州开出的药物总数是多少?
- 每个州最常开的药物是什么?
- 每个城市和州的住院和门诊治疗的平均费用是多少?
- 在美国,哪些是最常见的住院诊断疾病?
- 对于每种诊断条件,哪些城市的病例数最多?
- 这些城市在这些条件下的平均费用是多少,与全国平均水平相比如何?
在本帖中,我们将对医疗保险数据库中的数据进行一些简单的探索性数据分析。虽然我们不会回答上面所有的问题,但这篇文章将为感兴趣的读者提供一个良好的开端。
首先,要访问数据,你需要创建一个谷歌云账户。接下来,您需要安装 Google BigQuery 并生成认证凭证。你可以在这里找到操作说明。
我们开始吧!
首先,让我们导入必要的 google 身份验证和 BigQuery 包:
from google.oauth2 import service_account
from google.cloud import bigquery
接下来,我们需要导入熊猫并将列设置定义为“None”。我们这样做是为了显示所有的列,因为 pandas 默认情况下会截断它们。
import pandas as pd
pd.set_option("display.max_columns", None)
接下来,我们定义密钥路径、客户端凭证和客户端对象:
key_path = "key_path/key.json"credentials = service_account.Credentials.from_service_account_file(
key_path,
scopes=["[https://www.googleapis.com/auth/cloud-platform](https://www.googleapis.com/auth/cloud-platform)"],
)client = bigquery.Client(
credentials=credentials,
project=credentials.project_id,
)
接下来,我们定义数据集引用,其中我们传入数据库的名称“medicare”和项目的名称“bigquery-public-data”:
dataset_ref = client.dataset("medicare", project="bigquery-public-data")
我们可以看看 12 个可用的表:
columns = [x.table_id for x in client.list_tables(dataset_ref)]
print(columns)
让我们来看看列表中的第一个元素,“住院 _ 费用 _2011”:
table_ref = dataset_ref.table('inpatient_charges_2011')
table = client.get_table(table_ref)
我们可以将结果存储在数据帧中,并打印列名:
df = client.list_rows(table).to_dataframe()
print(df.columns)
我们还可以查看数据帧的长度:
print(len(df))
我们还可以打印数据帧的前五行:
print(df.head())
我们可以从 python 中的 collections 模块导入 counter 方法来分析一些分类变量的分布。让我们看看“提供商名称”列:
from collections import Counter
print(dict(Counter(df['provider_name'].values).most_common(20)))
我们也可以将这些输出可视化。让我们定义一个函数,它将类别字符串作为输入,并显示四个最常见值的条形图:
import matplotlib.pyplot as plt
import seaborn as sns
def plot_most_common(category):
sns.set()
bar_plot = dict(Counter(df[category].values).most_common(4))
plt.bar(*zip(*bar_plot.items()))
plt.show()
现在让我们用“provider_name”调用函数:
plot_most_common('provider_name')
我们还可以看看“drg_description”的四个最常见的值:
plot_most_common('drg_description')
我们还可以定义一个函数来生成跨分类值的箱线图。我们使用箱线图来显示基于最小值、最大值、中值、第一个四分位数和第三个四分位数的数值分布。如果你对它们不熟悉,可以看看文章了解盒子情节。
该函数采用数据框、分类列和数值列,并根据限制显示最常见类别的箱线图:
def get_boxplot_of_categories(data_frame, categorical_column, numerical_column, limit):
keys = []
for i in dict(Counter(df[categorical_column].values).most_common(limit)):
keys.append(i)
print(keys)
df_new = df[df[categorical_column].isin(keys)]
sns.boxplot(x = df_new[categorical_column], y = df_new[numerical_column])
让我们为 5 个最常出现的提供者名称中的平均 medicare 付款生成箱线图:
get_boxplot_of_categories(df, 'provider_name', 'average_medicare_payments', 5)
我们可以为“总排放量”生成一个类似的曲线图:
get_boxplot_of_categories(df, 'provider_name', 'total_discharges', 5)
我们还可以构建一个散点图函数。此函数将一个数据框、分类列、分类值和两个数字列作为输入,并显示一个散点图:
def get_scatter_plot_category(data_frame, categorical_column, categorical_value, numerical_column_one, numerical_column_two):
import matplotlib.pyplot as plt
import seaborn as snsdf_new = data_frame[data_frame[categorical_column] == categorical_value]
sns.set()
plt.scatter(x= df_new[numerical_column_one], y = df_new[numerical_column_two])
plt.xlabel(numerical_column_one)
plt.ylabel(numerical_column_two)
让我们为“好撒马利亚人医院”生成一个平均医疗保险付款与总出院人数的散点图:
get_scatter_plot_category(df, 'provider_name', 'GOOD SAMARITAN HOSPITAL', 'average_medicare_payments', 'total_discharges')
我们也可以看看“北岸医疗中心”的同一个图:
get_scatter_plot_category(df, 'provider_name', 'NORTH SHORE MEDICAL CENTER', 'average_medicare_payments', 'total_discharges')
概括地说,在这篇文章中,我对医疗保险数据集进行了简单的探索性数据分析。我分析了提供者名称的分类值的分布。我还生成了条形图,用于可视化数据集中提供者名称的出现频率。最后,我定义了用于生成跨类别值的箱线图和可视化数值散点图的函数。我希望这篇文章有趣。
这篇文章的代码可以在 GitHub 上找到。感谢您的阅读!
分析微生物组数据
来源: DNA 壁纸洞穴
第 1 部分—基因组数据科学系列
本文是将机器学习应用于生物信息学数据的系列教程的一部分:
第 1 部分—数据采集和预处理
为了跟进,你可以下载我们的 Jupyter 笔记本,或者继续阅读并输入下面的代码。
介绍
我们许多人大部分时间都在室内度过,但很少有人意识到我们接触的每一个表面都是寄居在这些空间的特殊有机体的家园——门把手、厨房柜台、桌子、椅子、浴室、冰箱等。当我们想到不同的生态系统,如沙漠、雨林、草原或珊瑚礁时,我们知道不同的生物群落专门生活在世界上的这些地区。同样,我们可以推断不同组成或不同类群的微生物和真菌可能专门生活在我们周围的不同位置或表面。我们称这些特殊的微生物群落为 微生物群 。
如果我们只知道这些生物群落之间的基因差异会怎么样?我们也许可以逆向工程这些生物体的来源?在接下来的系列教程中,我们将向您展示我们如何从简单表面拭子的基因序列数据出发,在事先不知道拭子来源位置的情况下,使用一些数据科学检测工作,找出如何区分这些拭子的来源位置。
为了研究微生物组之间的遗传差异,我们能够使用 Qiita 找到一个数据集。
来源:qi ta 文档
Qiita(发音为“ cheetah ”)是一个多组学软件包和数据库,包含微生物生态学数据集,并提供一个良好的界面来搜索不同类型的组学数据,从论文中找到参考数据,甚至提供关于文件类型和相关元数据的信息。它基于qime生物信息学管道,将原始测序数据转换和处理为有利于数据分析的通用格式。其他常见的生物信息学管道有方法、数据 2 、使用原型等。不同管道的比较,见此处。
获取我们的数据
要访问这些数据,您需要创建一个帐户,然后点击左侧的所有 QIIME 地图和 BIOMs 下载北亚利桑那大学病原体&微生物研究所 Caporaso 实验室收集的数据。
资料来源: Qiita,Caporaso 实验室项目
一旦完成,你需要解压文件,把它放在一个名为 data 的文件夹中,然后把数据转换成我们可以处理的格式。为此,我们首先需要安装一个名为 biom-format 的软件包,方法是在您的终端上键入:
pip install biom-format
完成后,我们可以在终端中运行以下命令:
biom convert -i data/BIOM/60899/all.biom -o data/BIOM/60899/feature_table.tsv — to-tsv
此命令将转换我们的。biom 文件到更熟悉的。tsv 格式,这样我们就可以进入我们的 Jupyter 笔记本,并通过以下方式读入 Pandas 数据帧:
BIOM 文件格式常见于*-组学*数据集中,用于表示 OTU 表格。OTUs 代表 可操作的分类单位 ,可认为是由基因组特定区域的遗传序列相似性分组的生物集群。本质上,当生物集群未知时,它们在不同的分类水平上充当“物种”的代理。该表中的观察值或行是 OTU,相应的矩阵记录了在每个样品中观察到每个 OTU 的次数。
由于最初收集这些数据的科学家最有可能在不同的表面和位置采集拭子,然后对拭子采集的微生物和真菌的 DNA 进行测序,我们不一定事先知道实际物种的组成。我们所拥有的是不同组的 DNA 串(由 A,T,C,Gs 组成),然后我们可以通过对其运行 BLAST 局部比对搜索算法来与参考数据库进行比较。
来源:爆炸词汇
这样的工具可以在这里找到。在我们的例子中,这一步已经为我们完成了。
数据预处理
幸运的是,我们的数据集已经带有相应的元数据文件,其中包含有关样本 id、测序执行位置、数据来自的实验类型、使用的测序机器、拭子收集的时间戳、地理位置等信息。我们可以通过以下操作在 pandas 中打开我们的元数据文件:
来源:作者图片
然后,我们可以创建一个助手函数,它从我们的。biom 文件,并将其转换为更容易处理的格式,我们称之为特征表:
然后,我们可以在之前的原始表上运行上面的 helper 函数,并重命名我们的索引:
我们可以看到,我们从一个有 1,497 行和 25,756 列的表开始。因为每一列代表一个特定的基因序列或 OTU(对应于我们的特征或维度),所以我们可以看到我们正在处理难以置信的高维数据。这在处理宏基因组数据集时很常见,并提出了传统数据科学技术可能无法应对的新挑战。
为了帮助我们处理这种高维度,我们使用我们的助手函数将每个最初标记有基因序列的列重命名为相应的整数,这样我们就没有真正长的基因序列字符串作为列名。这些列中的每一列包含每行的特定 OTU 的频率或计数。每一行代表一个样本 id,其可以识别例如特定的拭子。
从这里,我们可以经历一些用于清理生物信息学数据的常见实践。通过确保每个序列有 20,000 个以上的相关读数,并且在至少 3 个不同的样本中出现过(本质上,应用一系列阈值),我们可以对数据进行子集化,这样我们现在有 301 行和 1,894 列。
请注意,这一步还有很多可以改进的地方,许多科学论文都是关于这一点的。我们正从快速和肮脏的角度来处理这个问题。
来源:作者图片
因为我们应用了阈值来减少我们的要素表,所以我们也将从元数据表中删除那些对应的条目:
从这里,我们现在可以使用我们的元数据来仔细检查,看看我们有来自 3 个不同城市的样本:
来源:作者图片
后续步骤…
我们已经完成了解释微生物组宏基因组数据的性质的步骤,如何获得它,如何加载它,以及如何预处理它并将其转换成我们现在可以进行分析的格式。在我们的下一篇文章中,我们将向您展示如何应用各种机器学习算法和降维技术来帮助可视化和解释高维数据,以便我们可以从数据中推断出潜在的地理结构,而不必求助于通过元数据提供的标签。
本教程系列的两位合著者是尼古拉斯·帕克 & 蒙迪·雷默,他们都是旧金山大学数据科学硕士项目的毕业生。
如果您想联系我们,请联系我们: