原文:TowardsDataScience Blog
协议:CC BY-NC-SA 4.0
探索锁定对移动数据速度的影响
原文:https://towardsdatascience.com/exploring-the-impact-of-lockdown-on-mobile-data-speeds-664beb7ef685?source=collection_archive---------56-----------------------
保罗·史密斯在 Unsplash上的照片
印度新冠肺炎疫情封锁期间不同服务提供商的移动互联网速度的数据可视化。
前言
第五天(还是第六天?我失去了联系新冠肺炎一级防范禁闭在我的城市孟买,突然停电了,我的无线网络也断开了。我正在看《网飞王国》的一集,我真的很想看完最后几分钟。
所以我打开了我的移动数据,希望获得和一分钟前一样的无缝高清质量。相反,我得到的是颗粒状,高度像素化的垃圾,需要 15 分钟来缓冲。
这个。插曲。有过。只有。5.分钟。向左。
这让我想到了一般的移动数据速度,尤其是我的下载速度。我真的不记得上一次我遇到如此糟糕的低速数据是什么时候了。
动机
我很想知道全国移动数据使用的封锁和突然激增是否对平均数据速度产生了负面影响。我的假设是,我的服务提供商,Airtel,比其他公司更难处理高速数据。!为了测试这一点,我进行了这个小项目。
数据源
通过谷歌快速搜索,我找到了 TRAI 电信管理局的网站和他们的 MySpeed 门户网站。MySpeed 是 TRAI 开发的一款应用程序,允许用户监控其服务提供商(又称电信服务提供商或 TSP)的下载和上传速度。
该网站拥有 2018 年 3 月以来的州级和技术级(3G/4G)历史数据,并涵盖了该国所有主要的 tsp。他们也有一份写得很好的关于无线数据速度测量的白皮书,这是一份有趣的读物(只要你不像我一样在午餐后阅读)。
我下载了三年(2018 年至 2020 年)3 月、4 月、5 月和 6 月的数据,因为这几个月是今年全国封锁的关键月份(至今!)。
整个项目可以在我的 GitHub repo 上找到。
PC: memegenerator
数据预处理
数据分布在不同的。csv 文件,我将它们聚合成一个数据帧。有趣的特征是—
month_year
—数据的月份和年份tsp
—服务提供商的名称tech
— 3G 或 4Gtest_type
—下载或上传速度测试data_speed
—以 Mbps(兆比特每秒)为单位的数据速度lsa
—特许服务区,基本上是地区或州或市。
然后,我继续清理每个特征中的虚假值数据,并重新格式化数字特征中的数据类型。如你所见,数据集非常大,占用了将近 550 MB 的内存!
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 8985844 entries, 0 to 8985843
Data columns (total 8 columns):
# Column Dtype
--- ------ -----
0 tsp object
1 tech object
2 test_type object
3 data_speed float64
4 signal_strength float64
5 lsa object
6 year int64
7 month object
dtypes: float64(2), int64(1), object(5)
memory usage: 548.5+ MB
需要记住的几件事…
- 数据集中的每一个数据本质上都是用户通过 MySpeed 应用程序进行速度测试的记录,并被自愿发送到 TRAI 进行质量控制和分析。
- 速度测试代表短时间上传和下载速度。
- 这些数据是众包的,反映了在给定的一个月内使用 MySpeed 应用程序测试数据速度的次数。
探索性数据分析
速度测试次数
Q1:一段时间内进行了多少次速度测试?
速度测试的数量在 2018 年比 2020 年最多。月环比显示,除了从 4 月到 6 月的速度测试下降之外,这三年没有明显的趋势。
整个印度和所有 tsp 的速度测试总数(图片来源:作者)
Q2:在哪里进行的速度测试最多?
纵观各邦,很明显,在所有三年中,北方邦在速度测试的数量上领先全国,其次是马哈拉施特拉邦。这种反差在疫情期间尤为突出,尽管人数少于前几年。
描绘 2018 年至 2020 年印度各地速度测试数量变化的 Choropleth 地图
Q3:谁做的速度测试最多?
在封锁期间(3 月-20206 月),超过 50%的速度测试是由Jio(Reliance Jio Infocomm)的用户完成的,而Airtel(Bharati Airtel Limited)远远落后于第二名。这种巨大的差距是由于国内更多的用户造成的。( Jio 无线用户市场份额为 33.47%,其次是Airtel为 28.31% )
封锁期间 tsp 之间的速度测试份额(2020 年)(图片来源:作者)
Q4:做了哪些速度测试?
在封锁的几个月里,在所有的 tsp 中,速度测试在上传和下载速度测试之间几乎平分秋色,但这是意料之中的,因为应用程序会自动执行双速度测试。
两种测试中锁定期间总速度测试的份额(图片来源:作者)
数据速度的变化
问题 5:参赛选手的平均速度有什么不同?
查看三年来的平均数据速度(以 Mbps 为单位),可以发现 Jio 用户一直享受着极高的数据速度,几乎是其他 tsp 的两倍。
数据速度的绝对值表明,与竞争对手相比, Jio 和 Airtel 用户在 2020 年的最初几个月面临着速度的大幅下降。这可能是由于它们的用户基数大,因此负载较高。
平均数据速度随时间和 tsp 的变化(图片来源:作者)
Q6:锁定期间数据速度真的下降了吗?
月平均数据速度的同比变化(*将某一年的值与其前一年的值进行比较)*绘制为条形图。显而易见,在封锁的前四个月,所有主要 tsp 的平均速度都下降了。2019 年 4 月数据速度增幅最大的 Cellone ,2020 年 4 月数据速度降幅最大。
对于大多数 tsp,在 2020 年 4 月观察到最低的数据速度,之后似乎有一些小的缓解。令人惊讶的是, Idea 和沃达丰是仅有的两家在封锁的后两个月数据速度有所提升的公司。
不同 tsp 的月平均数据速度的同比趋势(图片来源:作者)
问题 7:各服务提供商的数据传输速度有何不同?
对数据速度分布的观察显示, Jio 、 Airtel 和沃达丰在锁定期间提供了超过 10 Gbps 的速度,尽管不一致。大多数 tsp 最常观察到的数据速度约为 2 Gbps,而 Jio 用户一直享受着更高的速度(从其分布的双峰特性来看*)。*
锁定期间 tsp 之间的数据速度分布(图片来源:作者)
Q8:全国各地的平均数据速度如何变化?
为了回答这个问题,我只查看了前两个 tsp—Jio和 Airtel 。中央邦的用户在封锁期间享受了最高的平均数据速度,其次是马哈拉施特拉邦。在马哈拉施特拉邦(孟买是其首都),平均下载速度在 6-7 Gbps 之间。
锁定期间 Jio 用户的州平均下载速度(图片来源:作者)
泰米尔纳德邦和安得拉邦的 Airtel 用户享有最高的下载速度,其次是中央邦和哈里亚纳邦。在封锁期间,马哈拉施特拉邦的用户体验到了 7 到 8 Gbps 的速度。
锁定期间 Airtel 用户的州平均下载速度(图片来源:作者)
结论
在这个项目结束时,我明白了—
- 在印度封锁的最初几个月,所有服务提供商的下载和上传数据速度都大幅下降。
- Jio 用户远多于全国 Airtel 用户。
- 尽管存在这种差异,Jio 和 Airtel 在封锁期间提供了相当的平均下载速度。
- 在封锁的几个月里,中央邦的人们享受着两大服务提供商的高平均下载速度
我想我最初的假设是正确的!
一些有趣的链接
注意:您可能找不到 TSP/ State 中提到的速度,这是因为您选择的样本不足。TSPs
myspeed.trai.gov.in](https://myspeed.trai.gov.in/) [## 什么是 dBm,它如何影响您的手机信号?
想知道如何获得手机信号强度的最佳测量结果吗?那些我们梦寐以求的信号棒…
www.wilsonamplifiers.com](https://www.wilsonamplifiers.com/blog/what-is-dbm-and-how-does-it-affect-your-cell-signal/)
希望你喜欢这篇文章。
再见!
使用 PageRank 探索印度超级联赛
原文:https://towardsdatascience.com/exploring-the-indian-premier-league-using-pagerank-9569e971ceb7?source=collection_archive---------26-----------------------
奇拉尤·特里韦迪在 Unsplash 上的照片
体育分析
关于 PageRank 算法的简短教程
这项工作的总体目标是探索面向板球分析的网络科学算法。本文涵盖了这个目标的一部分。IPL 数据用于此目的,特别关注 PageRank 算法。介绍了几种建立图形网络的方法,以及提取一些有趣见解的方法。更重要的是,还包括一个关于 PageRank 算法的简短教程。使用 PageRank 对 IPL 中最突出的两支队伍和米进行比较。
印度超级联赛是世界上最受欢迎的体育联赛之一;它的第十三版正在进行中。这是收视率最高的板球联赛。随着疫情给世界上所有体育活动蒙上阴影,特别是在印度,这被吹捧为获得前所未有的收视率。
八支队伍参加了这项一年一度的赛事,每支队伍都要面对对方两次,一次在各自的主场。在 cricsheet.org 可以免费获得 IPL 历史上每场比赛的数据。他们的网站不仅提供了 IPL 的数据,还提供了所有主要的男女板球比赛的数据。
这项工作主要处理图表,并使用它们进行可视化以及分析。让我们先湿湿我们的嘴,获得一些基本的直觉,为板球分析建立一些图表。然后我们就可以进入代码了。
构建图表
图 A. 这是投球手-击球手网络的一幅图,带有太阳升起者海德拉巴和德里夜魔侠之间的比赛的投球手和击球手之间的边缘。Rishabh Pant 是野蛮的,因为他击中了一吨,但他们的团队仍然由于 Dhawan 的攻击而失败。两个玩家都有连接到高重量保龄球手的边缘——适当的颜色。来源:作者图片
探索 IPL 数据的一种有趣方式是通过生成节点和边,其中节点可以是玩家,而边表示游戏中的特定活动。
例如,上图 A 所示的击球手-投球手网络由击球手和投球手组成,作为节点,他们之间的有向加权边代表击球手从投球手得分的回合。权重较高的边用橙色和红色着色。
例如,Rishabh Pant 在 Bhuvaneshwar Kumar 上得了 44 分,由从节点 B Kumar 到 RR Pant 的边表示,权重为 44 。特别是这场比赛,在太阳升起者海得拉巴和德里夜魔侠之间,里沙布·潘特打进了一个世纪,然而他的球队输掉了比赛。
下面的图 B 显示了一个大得多但不太有用并且有点压倒性的击球手-投球手网络,它覆盖了 IPL(直到 IPL-12)中的每一个投球。这个情节确实展示了大卫·华纳的爆炸性。
图 B. 该图以投球手和击球手为节点,以投球手到击球手的有向边为边权重,以总失球数为边权重。几乎 IPL 历史上的每一个投球都被计算在内。边缘根据重量着色。更多产的击球手有黄色到红色的彩色边缘。东南部的大卫·华纳就是这样一个脱颖而出的击球手。来源:图片由作者生成
类似地,另一种可以利用这些数据建立的网络是投球手的解雇或 T21。另一个经常被研究的网络是 batsmen 伙伴关系网络,它已经被证明在较长的格式中特别有用。
此外,请注意,在高层次上,这种分析属于网络科学的范畴。
网络科学 是研究电信网络、计算机网络、生物网络、认知和语义网络、社交网络等复杂网络的学术领域,将由节点(或顶点)表示的不同元素或行动者以及元素或行动者之间的连接视为链接(或边)。—维基百科
在深入研究网络科学算法,尤其是 PageRank 之前,让我们先接触一些编码。第一个任务是准备数据。
数据准备
第一步是准备数据,这些数据以 YAML 文件的形式提供。每个 YAML 文件对应一个匹配项。并且对于每一场比赛,数据都以一个球的描述的形式给出。所以我们需要准备这些数据来形成节点和边。
以下方法用于准备使用 networkx 生成图形所需的数据。
该方法将输入作为比赛和回合,并返回一个格式为:**(投球手、击球手、跑垒者)的元组列表。**每个投球的数据汇总在31–37行中。然后在第41–44 行中生成元组。
下面的方法将元组转换为图的边。
第 16–17 行聚集击球手和投球手对元组的运行,以创建边权重,而击球手和投球手形成节点。defaultdict在这里挺合适的。
现在,让我们看看图 A 中的网络及其图形是如何产生的。使用的主库是 networkx 和 matplotlib 。这相当简单。
图形生成
下面给出了生成图 A 中图形的代码。
第 5 行分配绘图参数,第14–22行根据运行次数给边缘分配颜色(如注释中所述)。线24–28决定图形的布局以及节点和边的位置。第 30–37 行给出了标签。
第 38 行,最后画出图形。
当我写这篇文章的时候,钦奈超级国王队和孟买印度人队的首场比赛已经结束了,作为一名 CSK 球迷,我迫不及待地想为这场比赛创建一个网络,以获得想要的结果。
图 c .2020 年 9 月 19 日,击球手-投球手-运行 CSK 和密歇根州之间的首场比赛网络。Rayudu 为爆破 bum rah 22是养眼!!再次证明印度通过掉 Rayudu 掉了 WC-2019。来源:图片由作者生成
既然我们已经能够使用一个或一组匹配的数据来生成网络并将其可视化,我们就可以考虑分析图表的算法了。
PageRank 是网络科学中流行的算法之一,也是本文研究的重点。下面是一个关于 PageRank 的简短教程。
PageRank 算法教程
著名的谷歌搜索引擎下的同名 PageRank 算法,在它的基本框架上出奇的简单。大多数算法,当它们在实践中工作时,都要经历无数微小的改变才能有效,这些对 PageRank 的修改超出了本文的范围。
说句题外话,去年(即 2019 年)这个时候左右,所有与 PageRank 相关的专利都到期了。
另外,请注意,我使用了参考文献 更深入的 PageRank 作者 *Langville 等人。艾尔。*对于本教程以及其他一些教程。还参考了伦敦帝国理工学院的线性代数课程。
现在让我们来看看 PageRank 算法。PageRank 的目标是对网站进行排名,并决定它们在搜索结果中的显示顺序。潜在的假设是,一个网站的重要性取决于它与其他网站的链接。
下面是一个互联网的迷你模型,四个网页相互链接,如箭头所示。
互联网的迷你模型。在本课程中使用了类似的表述。网页 X 有 Y 、 Z 和 W 的链接。 Y 与 X 和 W 连接。 Z 和 W 相互链接,同时 W 也指向 Y 。来源:图片由作者生成
这 4 个网页中哪一个最相关?
为了确定这一点,每个页面都由基于它们之间的链接的链接向量来表示,通过链接的总数来标准化。例如,对于网页 X,向量将如下:
X 连接到 Y 、 W 和 Z ,连接总数为 3 。这导致概率矩阵 P 的生成,通过组合所有网页的向量,如下所示(注意转置)。
互联网上的用户最终到达 X 的概率取决于 Y 。在 Y 上着陆的概率取决于 X 和 W 。诸如此类。这个问题显然是自我参照的。
现在为了计算页面 X 的排名,我们需要 X 所连接的每个网页的排名以及链接概率向量。
这体现在下面的总结中。网页的排名 X 是 X 与其他具有该排名的页面的链接概率的乘积。
这对于整个互联网来说将采取如下形式:
计算上述等式中的 r 的有效方法是使用迭代法。一种是从初始猜测的 r 开始,并将其乘以 P 以获得更新的**r。**这再次乘以 r ,等等,直到 r 停止变化。
雅可比法 就是这种迭代方法的一个正式例子。
我从维基百科上复制了一个例子来看看 Jacobi 方法的应用。
假设给我们下列线性系统:
如果我们选择(0,0,0,0)作为初始近似值,则第一个近似解由下式给出
使用获得的近似值,重复迭代过程,直到达到期望的精度。以下是五次迭代后的近似解。
该系统的精确解为(1,2,1,1)。
正如您可以推断的那样,同样的方法可以应用于求解上面描述的秩方程。在十次迭代之后,在我们的情况下获得的秩向量是,
雅可比法本质上是矩阵对角化的算法。那么对角化和这个问题有什么关系呢?矩阵的对角化为我们提供了它的特征向量。让我试着更清楚地把这些点联系起来。
矩阵通过旋转、缩放、剪切或正交投影中的一种线性变换矢量(还有更多!).特征向量是那些向量的集合,对应于一个变换矩阵,在变换下它们的方向不变。尽管这些向量的方向保持不变,但它们确实会按照由特征值决定的因子进行缩放。
用数学形式写出这个定义如下。
这里 A 是矩阵 v 是特征向量 λ 是特征值。 I 是与 A 维数相同的单位矩阵。左手边的矩阵 A 对矢量 v 进行变换,矢量v等于右手边的项,由矢量 v 以因子 λ缩放表示。
这个等式类似于我们为确定上面的等级而写的等式。如果特征值等于 1,这将是完全相同的。
换句话说,确定秩实质上是在特征值等于 1 时确定特征向量。
现在,矩阵的对角化无非是求其特征向量。这就是雅可比方法的基本原理。所以 PageRank 从根本上来说是一种计算概率矩阵特征向量的方法。请注意,有许多更有效的方法可以做到这一点。例如更适合互联网规模的幂法。
总之,反过来,本教程简要解释了特征向量的概念,并指出矩阵对角化可以用来确定它们。显示了迭代方法的应用,如 Jacobi 方法,其本质上是矩阵对角化的工具。这就导致了网页的排名确定从根本上来说就是特征向量的计算。
你有希望了解整个情况。现在让我们将 PageRank 应用于 IPL 数据。
板球分析 PageRank
让我们从 PageRank 的一个非常简单的应用开始,确定比赛的玩家。从下面的代码可以看出,使用 networkx 计算 PageRank 算法非常简单。
确定“最佳球员”
考虑图 A 和 c 中所示的两个匹配的示例。对于德里和海德拉巴之间的高得分匹配,PageRank 算法的输出如下:
('**S Dhawan**', 0.16706747134453998),
('RR Pant', 0.12847147719416976),
('KS Williamson', 0.11339938336161924),
('HV Patel', 0.054508466219623325),
('AD Hales', 0.04907687103359096),
('JJ Roy', 0.043984250939231515),
('PP Shaw', 0.04121692739936753),
('GJ Maxwell', 0.039109987886062),
('SS Iyer', 0.036112054051209354),
('B Kumar', 0.032705311057058616),
('Sandeep Sharma', 0.032705311057058616),
('Shakib Al Hasan', 0.032705311057058616),
('S Kaul', 0.032705311057058616),
('Rashid Khan', 0.032705311057058616),
('TA Boult', 0.032705311057058616),
('S Nadeem', 0.032705311057058616),
('LE Plunkett', 0.032705311057058616),
('A Mishra', 0.032705311057058616),
('V Shankar', 0.032705311057058616)
达万的确是这场比赛的选手,同时也被的* PageRank *排在首位。紧跟喘气。在最近和米的比赛中,Rayudu 被评为最佳击球手。但这其实微不足道,不足为奇。更有用的是比较整个 IPL 中两个队的击球手。
让我们来分析一下锦标赛历史上最突出的两支队伍: CSK 和米。
来源:维基百科
钦奈超级国王 — vs — 孟买印度人(击球手)
两队在印度超级联赛中已经交锋 29 次,孟买赢得了其中的 17 次,最近的一次交锋属于金奈。
在图 D 中,该网络涵盖了 IPL 历史上迄今为止(2020 年 9 月 21 日)两支球队之间的每一场比赛。这确实是一个密集的情节,不是很清楚。
图 D 。击球手-投球手-运行 IPL 历史上所有 CSK vs MI 比赛的网络,直到 2021 年 9 月 21 日。来源:图片由作者生成
更有趣的是 PageRank 算法的输出。有趣的是,顶级击球手的名单被 CSK 占据了。更有趣的是,排在第一位的是巴德里纳特,他在 2013 年(或大约在那个时候)被 CSK 放弃。
('**S Badrinath**', 0.05421395478976649),
('**SK Raina**', 0.053135571284977624),
('**RG Sharma**', 0.041368536612979664),
('**MS Dhoni**', 0.04038317373144958),
('**AT Rayudu**', 0.03464112279515003),
('**ML Hayden**', 0.0330266349697345),
('**SR Tendulkar**', 0.02418058298782965),
('**DJ Bravo**', 0.021503060692972184),
('**F du Plessis**', 0.021390681834730786),
('**KA Pollard**', 0.021321303236989133),
('**MEK Hussey**', 0.021042740963540033),
('**DR Smith**', 0.01890655407121474),
为了让事情变得更有趣,也为了让剧情看起来更有意义,让我们将分析限制在金奈从禁令中回来后的几年——对其热情的粉丝来说,这是一个令人沮丧的时期。
在下面的图 E 中,显示了最近几个版本的匹配网络。让我们注意一些观察。
- Suryakumar Yadav 和 Rohit Sharma 爱打击 **Imran Tahir,**看着他们之间突出的红色边缘。
- 无论是多尼还是刘冰这几年都相对沉寂。而 Rayudu 做得非常出色,即使是面对像 bum rah 这样的顶级保龄球手。
- 沃森惩罚了马林加很多次。而杜普莱西则掠夺了克鲁纳尔潘迪亚。而且 Q de Kock 喜欢打击迪帕克查哈尔。
图 E 。CSK 禁令结束后,CSK 的击球手-投球手网络 vs . MI 进行 IPL 比赛。来源:图片由作者生成
应用 PageRank 算法的结果如下。Rayudu 近年来在 IPL 中表现出色,是最好的击球手(在两队之间的决斗中),而许多 MI 球员也名列前茅。
('**AT Rayudu**', 0.0583995180647374),**CSK**
('**SA Yadav**', 0.05791406258909479),**MI**
('**RG Sharma**', 0.05623336818791069),**MI**
('**SK Raina**', 0.04320529341604707),**CSK**
('**HH Pandya**', 0.038683990832774545),**MI**
('**KH Pandya**', 0.03657684830688639),**MI**
('**SR Watson**', 0.034829476630529085),**CSK**
('**F du Plessis**', 0.03473325010829539),**CSK**
('**KA Pollard**', 0.03220709886860807),**MI**
('**MS Dhoni**', 0.031817576009506396),**CSK**
考虑到 CSK 在过去 5 场比赛中只赢过一次,这个结果很有意义。多尼女士刚刚进入前 10 名。
总的来说,毫无疑问,这两支球队相互之间竞争激烈,作为一名 CSK 球迷,我希望多尼在下一届 IPL 结束时进入前五名,这可能是他的最后一次。
接下来呢?
目前的焦点(为了防止文章变得太大)只集中在击球手身上。有许多网络可以用来进行分析。例如,投球手-击球手-解雇网络或击球手伙伴关系网络,如前所述。
此外,本文中考虑的 PageRank 是最基本的。多年来,它经历了许多变化,这些变化可以应用于这种分析,以获得有趣的见解。
然后,整个工作可以扩展到测试比赛和 ODI,这可以提供许多用于分析和更好地理解的指标,而不是保龄球和击球率等当前数据。去吧。
一旦用类似的网络科学算法获得了更多有趣的见解,我希望能发表一篇后续文章。
🔵在 Linkedin 或 Twitter 找到我🔵
另外,看看我的其他文章。
[## 我的数据科学文章列表
2020 年 9 月 1 日更新
medium.com](https://medium.com/@dyaus/list-of-my-data-science-articles-edd8866029e8)
探索 ConvNet 图像分类器的潜在空间
原文:https://towardsdatascience.com/exploring-the-latent-space-of-your-convnet-classifier-b6eb862e9e55?source=collection_archive---------45-----------------------
隐藏层的潜在空间中的线性!
阿里雷扎在 Unsplash 上的照片
神经网络,尤其是卷积神经网络的一个迷人之处在于,在网络的最后几层中,各层是完全连接的,每一层都可以被视为一个向量空间。ConvNet 从图像中提取的所有有用的和需要的信息都以特征向量的形式存储在最终层的压缩版本中。当这最后一层被当作一个向量空间并服从向量代数时,它开始产生一些非常有趣和有用的性质。
我在 Kaggle 的imate rialist Challenge(Fashion)数据集上训练了一个 Resnet50 分类器。这里的挑战是将每一幅服装图像分类成合适的属性,如图案、领口、袖长、款式等。我使用了预训练的 Resnet 模型,并在这个数据集上应用了迁移学习,为每个标签添加了层。一旦模型得到训练,我希望看看最后一层的向量空间,并搜索模式。
潜在空间方向
Resnet50 的最后一个 FC 层的长度为 1000。在对时尚数据集进行迁移学习后,我在这一层应用主成分分析,将维度减少到 50,保留了 98%以上的方差。
潜在空间方向的概念在 GANs 和变分自动编码器中很流行,其中输入是矢量,输出是图像,观察到通过在某个方向上平移输入矢量,输出图像的某个属性改变。下面的例子来自 NVIDIA 训练的 StyleGAN,你可以看看这个网站,在这里,每当你刷新页面时,一个假脸就会从一个随机向量中生成。
图片来自界面 GAN Github |姿势、年龄、表情和眼镜等属性可以通过在各自的潜在方向上平移输入向量来调整。
这太令人兴奋了!对输入向量的简单线性运算会在输出图像中产生如此复杂的变换。这些潜在的方向就像旋钮,你可以调整以获得输出图像所需的效果。难以置信!
在我们的图像分类器中,我们做的正好与 GAN 相反。在分类器中,我们获取一个图像,并在 FC 层中获得一个长度为 1000 的向量,通过 PCA 变换,我们将其维数降低到 50。我们想要探索的想法是,我们为其训练模型的图像属性是否在 FC 层和 PCA 之后的层的向量空间中以线性方式排列。答案确实是肯定的!
iMaterialist 挑战赛的任务之一是确定袖子长度,分为五种类型:长袖、短袖、泡泡袖、无袖和露肩。这五种中,三种占多数:长袖、短袖和无袖。现在我们想看看是否存在一个潜在的方向,沿着这个方向,这三个袖长等级被分离。如果是二元分类,我们可以使用逻辑回归,系数向量会给出潜在方向,但在我们的情况下,我们有多个类别。
在多类问题中获得潜在方向的一种方法是建立一个神经网络,其中我们迫使输入层通过单个单元中间层,输入层的权重向量为我们提供潜在方向。下面给出了这个分类器的代码片段,其中我的输入是长度为 50 的 PCA 层,它通过一个单元层,经过几层后,我得到了我的最后 5 个类。迫使它通过单个单元层背后的想法是约束网络学习线性潜在方向。这个单一单位层的值本质上给了我输入到学习的潜在方向上的投影。
**class latent_model(nn.Module):**
**def __init__(self):**
super(latent_model, self).__init__()
self.layer1 = nn.Sequential(nn.Linear(50, 1), nn.Linear(1,10), nn.ReLU(),nn.Linear(10,10), nn.ReLU(), nn.Linear(10,5) , nn.Softmax()) **def forward(self, ip):**
x = self.layer1(ip)
return x
lm=latent_model()
*#####Train the Classifier#####
#######################
##The latent direction##*
latent_direction=lm.layer1[0].weight[0].cpu().detach().numpy()
iMaterialist ConvNet 模型的结果
让我们看看训练完这个小分类器后得到了什么!
下图显示了不同袖型沿潜在方向的分布,我们可以看到三大类:短款、长款和无袖款沿潜在方向分离。
作者的图表:袖长沿潜在方向的分布。
神经网络是复杂的非线性模型,但隐藏层中隐藏着线性!
现在,我拍摄一幅裙子的图像,从该图像的 PCA 向量空间中的点开始,沿着袖子长度的潜在方向画一条线,并从训练数据集中检索最接近这条线的图像。下面是一些这样的例子。值得注意的一件有趣的事情是,虽然袖子长度沿着从长袖到短袖再到无袖的方向变化,但裙子的其他特征,如领口、裙子长度和整体风格往往保持不变。
来自 Kaggle 数据集 的图像|示例 1: 从#3 开始,检索在不同点最接近该线的其他图像。
来自 Kaggle 数据集|示例 2: 从#1 开始,检索在不同点最接近该线的其他图像。
来自 Kaggle 数据集 的图像|示例 3: 从#4 开始,检索在不同点最接近直线的其他图像。
在第二个示例中,所有检索到的图像都是长裙,并且在一个图像中有两个姿势,而在第三个示例中,大多数图像都没有模特。唯一显著的变化是袖长。
从上面的结果来看,看起来训练数据集图像已经在 PCA 层的潜在空间中以原始的顺序排列了!
对模式进行类似的分析会得到以下结果
不同模式类型沿已发现模式潜在方向的分布。(作者配图)
从上面的图表中,我们看到花型连衣裙从更坚实的类型沿着潜在的方向分离。看几个例子证实了这一观察。
来自 Kaggle 数据集 的图像|示例 5: 从#6 开始,检索在不同点最接近直线的其他图像。
来自 Kaggle 数据集|示例 5: 从#2 开始,检索在不同点上最接近该线的其他图像。
来自 Kaggle 数据集 的图像|示例 6: 从#4 开始,检索在不同点最接近该线的其他图像。
在上面的例子中,图案沿着发现的方向慢慢地从纯色到条纹到花卉到格子,并且检索到的图像在整体风格方面倾向于类似于初始图像。
结论
着眼于特征向量的潜在空间是我们对神经网络工作的理解向前迈进了一步。从上面的分析中,我们可以得出一个结论:卷积神经网络以图像的形式接收复杂数据,随着输入通过后续层,从这些图像中提取的信息变得越来越有组织。我们发现,在网络最后一层的潜在空间中,我们的训练数据集图像以有序的方式进行排序和分离,以至于我们可以发现感兴趣的某个属性变化的线性方向。
阅读更多博客此处。
用神经网络探索新冠肺炎和抑郁症之间的联系
原文:https://towardsdatascience.com/exploring-the-link-between-covid-19-and-depression-using-neural-networks-469030112d3d?source=collection_archive---------30-----------------------
变更数据
对新冠肺炎相关推文进行情感分析,研究抑郁症和疫情之间的相关性。
代表形象。鸣谢:伊斯托克照片
我们生活方式的巨大变化,加上为抗击冠状病毒爆发而引入的限制、隔离和社会距离措施,导致世界各地精神健康问题的惊人增加。社交媒体是人们在特定地点和时间的精神状态的有力指示器。为了研究冠状病毒疫情和普通人群中抑郁和焦虑加速之间的联系,我决定探索与冠状病毒相关的推文。
这个博客是如何组织的?
在这篇博文中,我将首先使用 keras 训练一个神经网络来识别抑郁的推文。为此,我将使用 10,314 条推文的数据集,分为抑郁推文(标记为 1)和非抑郁推文(标记为 0)。这个数据集是由维里戴安娜·罗梅罗·马丁内斯制作的。以下是她的 github 个人资料的链接:【https://github.com/viritaromero
一旦我训练好了网络,我会用它来测试从 twitter 上抓取的推文。为了建立新冠肺炎和抑郁症之间的联系,我将获得两组不同的数据。第一个数据集将由与冠状病毒相关的关键词组成,如“新冠肺炎”、“隔离”、“疫情”和“病毒”。第二个数据集将由使用中性关键字搜索的随机推文组成,如“and”、“I”、“The”等。第二个数据集将作为对照,检查随机样本推文中抑郁推文的百分比。这将使我们能够测量随机样本和新冠肺炎特定推文中抑郁推文百分比的差异。
预处理数据
图片来源:【https://xaltius.tech/why-is-data-cleaning-important/
在我们开始训练神经网络之前,我们需要收集和清理数据。
导入库
为了开始这个项目,我们首先需要导入所有必要的库和模块。
一旦我们准备好了所有的库,我们就需要获取数据并对其进行预处理。你可以从这个链接下载数据集:https://github . com/viritaro Mero/Detecting-Depression-in-Tweets/blob/master/情操 _tweets3.csv
数据的快速检查
我们可以通过将数据集读入 pandas 数据框来快速检查数据集的结构。
现在,我们将把推文的文本存储到一个名为 text 的数组中。tweets 的相应标签将被存储到一个名为 labels 的单独数组中。代码如下:
很抱歉打印出一个相当大的数据集,但我这样做是为了让我们可以快速检查整体结构。我注意到的第一件事是,在标签数组中,0 比 1 多得多。这意味着在数据集中,我们的非抑郁推文大约是抑郁推文的 3.5 倍。在理想情况下,我希望在抑郁和非抑郁推特数量相等的数据集上训练我的神经网络。然而,为了获得同等数量的抑郁和非抑郁推文,我将不得不大幅删减我的数据。我认为较大且不平衡的数据集比非常小且平衡的数据集要好,因此,我将继续使用原始状态的数据集。
清理数据
你会注意到的第二件事是,推文中包含了很多所谓的“停用词”,如“a”、“The”、“and”等。这些词对于将一条推文归类为抑郁或非抑郁并不重要,因此我们将删除这些词。我们还需要删除标点符号,因为这也是不必要的,只会降低我们的神经网络的性能。
我决定使用令人惊叹的 wordCloud 库对清理后的数据进行快速可视化,结果如下。毫不奇怪,抑郁推文中最常见的词是抑郁。
使用 WordCloud 可视化推文
数据的符号化
标记化到底是什么?
基本上,神经网络不像我们人类那样理解原始文本。因此,为了使文本更容易被我们的神经网络接受,我们将它转换成一系列的 1 和 0。
图片来源:inboundhow.com
为了在 keras 中标记文本,我们导入了 tokenizer 类。这个类基本上是在字典中查找整个文本中一定数量的独特单词。然后使用字典查找,keras 允许我们创建向量,用字典查找中的索引值替换单词。
我们还继续填充较短的 tweetss 并截断较大的 tweet,使每个向量的最大长度等于 100。
你可能会想,“嗯,我们只把单词转换成数字,而不是 1 和 0!”你是对的。有两种方法可以做到这一点:要么我们可以将数字转换成一个热编码向量,要么创建一个嵌入矩阵。一位热编码向量通常是非常高维和稀疏的,而矩阵是较低维和密集的。如果你感兴趣,你可以在 Francois Chollet 的《用 Python 进行深度学习》一书中了解更多。在这篇博客中,我将使用矩阵,但是在我们初始化它们之前,我们需要先处理一些其他的事情。
打乱数据
图片由 Sergi Viladesau 在 unsplah 上提供
数据的另一个问题,你可能早就发现了,文本数组首先包含所有非抑郁的推文,然后是所有抑郁的推文。因此,我们需要重组数据,让随机的推文样本进入训练、验证和测试集。
拆分数据
现在我们需要将数据分成训练集、验证集和测试集。
唷!终于完成了所有的数据管理!
制造一个神经网络
图片来源:extremetech.com
现在我们可以开始制作模型架构了。
我将尝试两种不同的模型:一种是预训练单词嵌入层,另一种是可训练单词嵌入层。
为了定义神经网络架构,您需要了解单词嵌入是如何工作的。网上有大量关于单词嵌入的信息。这篇博文是我的最爱之一:
https://towards data science . com/introduction-to-word-embedding-and-word 2 vec-652 d0c 2060 fa
既然您已经对嵌入层的功能有所了解,我将继续用代码创建它。
第一个模型
对于第一个模型,该架构由预训练的单词嵌入层和两个密集层组成。为模型定型的代码如下:
图:模型 1 中训练集和验证集的准确性和损失
这里我们可以看到,该模型在测试集上表现非常好,准确率为 98 %。过度拟合可能不是问题,因为验证精度和损失几乎与训练精度和损失相同。
第二种模式
对于第二个模型,我决定排除预先训练的嵌入层。代码如下。
图:模型 2 中训练集和验证集的准确性和损失
在测试集上,两个模型的精度都一样好。然而,由于第二个模型不太复杂,我将用它来预测一条推文是否抑郁。
从 twitter 获取新冠肺炎相关推文的数据
为了获得我的推文数据集,我使用了 twint,这是一个了不起的 twitter 网络抓取工具。我准备了两组不同的数据集,每组 1000 条推文。第一个由包含 corona 相关关键词的推文组成,如“新冠肺炎”、“隔离”和“疫情”。
现在,为了获得一个对照样本进行比较,我搜索了包含中性关键词的推文,如“the”、“a”、“and”等。利用这个样本中的 1000 条推文,我组成了第二个控制数据集。
COVID 相关推文的 WordCloud
我使用与清理训练集相似的过程来清理数据集。在清理数据后,我将其输入我的神经网络,以预测抑郁推特的百分比。我得到的结果令人惊讶。
下面显示了代码的一次运行,我用不同批次的数据重复了一次运行,这些数据是使用与上述相同的过程获得的,并计算了平均结果。
我的模型预测,平均而言,在使用中性关键词获得的一组推文中,35 %是抑郁推文,65 %是非抑郁推文。在随机获得的样本中,35%的抑郁推文是一个惊人的高数字。然而,带有 COVID 相关关键词的抑郁推文数量甚至更高:55 %抑郁对 45 %非抑郁。抑郁推特增加了 57 %!
这导致了一个结论,即新冠肺炎和推特上的抑郁情绪之间确实存在相关性。
结论
我希望这篇文章能帮助你学习更多关于使用机器学习进行情感分析的知识,我希望你也能尝试类似的项目。
编码快乐!
演职员表:吉菲的斯莱特
使用 Tableau 探索墨尔本房地产市场
原文:https://towardsdatascience.com/exploring-the-melbourne-real-estate-market-using-tableau-914d63659f8e?source=collection_archive---------17-----------------------
Tableau 中的数据可视化介绍
介绍
墨尔本作为世界上最适宜居住的城市之一,吸引了全球各地的许多人。他们中的许多人梦想把这个美丽的地方作为他们的家。我在数据科学领域的旅程始于我搬到墨尔本,因此我决定对该市的房地产市场进行全面分析。我一直对这个行业很着迷。因此,在这篇文章中,我将采取一种全面的方法来识别驱动因素,并帮助潜在买家进行数据驱动的决策。因为这个分析是使用 Tableau 完成的,所以我也将为您提供一些仪表板技巧。
有趣的事实——我在出租房子的时候确实使用了这个分析。因此,如果你刚到墨尔本或者打算在这里买房,这可能会很有用。”
由丹尼斯·简斯在 Unsplash 上拍摄的照片
关于 Tableau
Tableau 是一个功能强大且发展迅速的数据可视化工具,被大多数精通数据的组织所使用。自我智能和将数据转化为令人惊讶的商业洞察力的众多功能使 Tableau 成为最佳的 BI 工具之一。
数据描述
本项目使用的数据集是托尼·皮诺(Tony Pino)在 Kaggle 上发布的 2016 年 1 月至 2018 年 10 月期间墨尔本出售的房屋数据,这些数据来自 Domain.com.au 每周发布的公开结果。一些数据字段包括日期、价格、郊区、地区名称、土地大小、建筑大小、与中央商务区的距离等。(卡格尔)
假设和关键问题
1.随着我们越来越靠近 CBD 区域,建筑规模与土地规模的比率会产生什么影响?这个比例会影响房价吗?
2.2018 年第二季度墨尔本不同大都市地区的房屋均价会是多少?
3.墨尔本哪个月卖的房子多?
4.墨尔本房价和最大卖房数排名前 10 的郊区有哪些?
数据处理
为了分析建筑与土地的比例及其与城市距离的关系,在数据中添加了一个虚拟列(比例)。我们的探索围绕着价格、与 CBD 的距离、郊区、区域类型以及建筑与土地的比例。区域列中的空值是使用郊区信息估算的。使用 Excel 中合适的过滤器删除了剩余的空值记录。对显示建筑面积与土地面积之比大于 1 的房产数据进行质量检查。此类记录已从分析中剔除。
探索性分析
为了开始分析,我首先绘制了一张 choropleth 地图,显示了墨尔本不同地区房屋的平均价格。
Choropleth 地图:
地图是一种专题地图,其中地图中的不同区域按照代表地理特征汇总的统计变量的比例进行着色或图案化。(维基百科)
图一。不同地区住房平均价格的变化。快照取自作者开发的 Tableau 仪表板。
上面的可视化显示,位于中央商务区和东部沿海地区的房价比其他地区的房价要高。
我感兴趣的是分析房子的位置对建筑面积与土地面积比率的影响。房子离 CBD 的距离被用作位置的维度。我绘制了一个二元组合图,它由“距 CBD 的距离”和“平均比率”之间的条形图和线图组成。线形图显示了比率的移动平均值,以平滑结果。为了更好的理解,这个距离被形象化为 5 公里的范围。
图二。与城市的距离相对于建筑与土地面积比率的变化。快照取自作者开发的 Tableau 仪表板。
为了清楚地了解比率随位置的变化,我还绘制了墨尔本的 choropleth 地图,显示了不同郊区的平均比率,如下图所示。
图 3。不同地区平均建筑面积与土地面积之比的变化。快照取自作者开发的 Tableau 仪表板。
以上形象化的描述让我们了解到,随着我们越来越靠近 CBD 和沿海地区,建筑面积与土地面积的比例也在增加。可以推断,与位于城市和靠近沿海地区的房屋相比,位于远离城市的房屋在前院和后院有更多未被占用的土地空间。造成这种情况的主要原因可以认为是 CBD 地区缺乏空间和房价高。
现在让我们来看看墨尔本房屋销售的月度趋势。我绘制了房屋销售的年度饼状图来观察月度趋势,如下图所示。由于 2018 年的完整数据不可用,我们将可视化 2016 年和 2017 年的结果。
图 4。2011 年和 2017 年的月度销售分布。快照取自作者开发的 Tableau 仪表板。
可以观察到,2016 年的最大销售额在 11 月,而 2017 年的最大销售额在 7 月。在这两年中,据观察,大多数房屋都是在 5 月至 11 月期间出售的。由此可以推断,房子在冬季卖得更多。
为了找出平均价格最高和售出房屋数量最多的前 10 个郊区,我绘制了两个条形图,如下图所示。
图 5。最高均价和最高销售量的十大郊区。快照取自作者开发的 Tableau 仪表板。
上面的图像显示,库永是最昂贵的郊区,水库是最受欢迎的郊区。
使用 Tableau 的预测模型预测未来平均价格:
绘制了一个显示一年中不同月份平均价格的条形图。该图已针对不同区域进行了过滤。我已经用 Tableau 的预测模型预测了 2018 年第二季度的房价。该模型根据季度和月份的价格变化趋势来确定预测价格。
图 6。东部大都市地区的预测。快照取自作者开发的 Tableau 仪表板。
根据上述可视化,东部地区 2018 年 4 月、5 月和 6 月的预测平均价格分别为 122 万美元、123 万美元和 124 万美元。随着我们从 2018 年第一季度跳到第二季度,预测遵循价格下降的趋势。此外,模型平均出 2016 年和 2017 年从 4 月到 5 月和 5 月到 6 月的变化,并提供 5 月和 6 月的价格向上增长。
图 7。西部和北部大都市地区的预测。快照取自作者开发的 Tableau 仪表板。
在西部大都市和北部大都市地区,随着我们从 2017 年第 1 季度进入第 2 季度,该模型再次遵循价格下降的趋势。从四月到五月和五月到六月的价格变化被平均化,并且预测第二季度的所有三个月对于两个区域具有相似的趋势。
图 8。南部大都市地区的预测。快照取自作者开发的 Tableau 仪表板。
对于南部大都市地区,2016 年和 2017 年第一季度的数据都缺失。因此,系统无法跟踪季度变化趋势,并预测 2018 年 4 月的平均价格与 2018 年 3 月相同。此外,根据上一年 4 月至 5 月和 5 月至 6 月的平均变化,2018 年 5 月和 6 月有所上升。
图 9。南部大都市地区的预测。快照取自作者开发的 Tableau 仪表板。
在东南大都市地区,2016 年和 2017 年第一季度的数据都缺失。此外,2016 年第二季度的数据也缺失。因此,该模型无法提供准确的预测,并显示 2018 年第二季度所有三个月的固定值为 92 万美元。
结论
这种数据探索和可视化帮助我们为有抱负的买家收集了一些关于墨尔本房地产市场的有用见解。
据观察,随着我们越来越靠近城市地区,建筑面积与土地面积的比率变化很大。城市的高价格和更少的空间鼓励人们利用全部土地来建造房屋。
除了南部大都市地区,预测模型显示,随着我们从 2018 年第一季度到第二季度,房价将会下降。此外,冬季被认为是买家购买房屋的最佳季节。
参考
- t .皮诺(2018 年)。墨尔本住房市场。从https://www.kaggle.com/anthonypino/data取回
- Choropleth 地图。从 https://en.wikipedia.org/wiki/Choropleth_map取回
包装
感谢阅读👍。希望你觉得这篇文章很有见地。如果是,请在您最喜欢的社交媒体平台上分享。我希望提出一些更高级的数据可视化。
我目前正在墨尔本莫纳什大学攻读数据科学硕士学位。要提供任何反馈或建议,请发电子邮件至 rishabharora268@gmail.com。你也可以在 Linkedin 或脸书上联系我。
继续摆桌子!
使用 Python 查找要阅读的新书
原文:https://towardsdatascience.com/exploring-the-most-recommended-books-using-python-e5bf7291fe59?source=collection_archive---------28-----------------------
搜罗探索最值得推荐的书籍
保罗·斯查费在 Unsplash 上的照片
有成千上万的书,但并不是所有的都值得一读。引用华氏 451 度中老费伯的话,最好的书是那些“展示生活面孔上的毛孔”的书
那么,面对铺天盖地的书籍,你如何找到最好的呢?
一种方法是去专门的图书网站(比如亚马逊或者 Goodreads)。它们提供过滤工具来优化搜索结果,并显示用户的评论和平均评级,以帮助缩小选择范围。
或者,你可以向他们的朋友或熟人寻求推荐。
这两种方法无疑是有效的。
但是还有第三种方法可以获得很好的结果:看看那些知名人士的推荐,他们说他们读过的书对他们的成就起了很大的作用。
这就是这个神奇的网站Mostrecommendedbooks.com发挥作用的地方。
MostRecommendedBooks.com
这个网站几乎展示了*“世界级人物”*推荐的所有书籍。与同行相比,它真的是遥遥领先。
- 把所有这些书放在一个数据框架里,给我的书友们
- 使用 Python 可视化库深入了解这一宝贵财富。
我还使用了 Google Books API 来获取页数、出版日期和类别。我选择 Google Books API 是因为:
(我的Github上有抓取数据和构建数据集的代码)。数据集也可以在 中找到【卡格尔】)
在开始之前,让我们导入将要使用的 Python 库。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sb
import textwrap%matplotlib inline
加载数据集
books_df = pd.read_csv('books_clean.csv')
books_df.head(10)
这是我们的数据集的样子。让我们看看这里有多少本书:
books_df.shape
(3003, 8)
如你所见,我们有 3003 个书名。
我们还有其他功能,如推荐数量、类别、出版日期和页数。
对于任何可能感兴趣的人,我还确保包括 Google books IDs,以方便相同书籍的数据抓取。
探索数据集
让我们从绘制推荐/书籍数量的分布图开始:
***#Histogram:***
plt.figure(figsize=[10,5])
plt.hist(data=books_df, x='num_recommendations')
plt.title('Distribution of the number of recommendations per book', size=18, fontweight='bold')
plt.xlabel('Recommendations', size=15)
plt.ylabel('Frequency', size=15)
这种分布是右偏的,许多书的推荐数量少于 2 本。
那么,这份榜单内最值得推荐的书有哪些呢?
要回答这个问题,我们不能按降序排列所有 3003 本书,因为这将产生一个不美观的图表,不能简明地传达信息。
因此,我将(任意地)将“num_recommendations”唯一值的中值作为最受推荐书籍的最小阈值:
***#Fixing the threshold:***
threshold=np.median(books_df['num_recommendations'].value_counts().index)***#Subset of the dataset based on the threshold:***
data=books_df.loc[books_df.num_recommendations >= threshold] ***#Combining titles and authors:***
data['title_y']=[','.join(i) for i in list(zip(data['title'],data['author']))]***#Barplot:***
plt.figure(figsize = [5,10])
color_base = sb.color_palette()[0]sb.barplot(data = data.sort_values(by = 'num_recommendations', ascending = False), x = 'recommender_count', y = 'title_y', color = color_base)plt.title('The Most Recommended Books', size = 18)
plt.xlabel('Recommendations', fontweight = 'bold', size = 15)
plt.ylabel('Titles', size = 15);
在这里,我们有 22 本书在我们的数据框架的绝对顶点。
正如你所看到的,《人类对意义的探索》( Victor Frankl)在 20 多条建议中名列榜首,其次是《智人》(尤瓦尔·赫拉利),然后是雷伊·达里奥的《原则》( T31)。
然而,似乎这个情节包含许多商业和自助书籍。我们几乎看不到一本小说,更别说哲学或其他特定类别的书了。
深入挖掘数据框架中的类别肯定会完善我们的发现,并带来有意义的信息,帮助我们选择最好的书籍。
但是首先,我们需要知道在我们的数据集中最常出现的类别。
为了简单起见,我将只列出前 20 名:
***#Plotting the 20 most frequently occurring categories:***plt.figure(figsize = [10,5])
color_base = sb.color_palette()[0]sb.barplot(books_df.category.value_counts().head(20).index, books_df.category.value_counts().head(20).values, color=color_base)plt.xticks(rotation = 'vertical')
plt.title('The Most Frequently Occurring Categories', fontweight = 'bold', size = 18)
plt.xlabel('Categories', size = 15)
plt.ylabel('Count', size = 15)
不出所料,小说和商业书籍最受欢迎,各有超过 400 本。传记书籍排在第三位,接下来是历史和科学。
在一个给定的类别中有很多书并不意味着这个类别是最值得推荐的,也不意味着这个类别中的书是所有书中最值得推荐的。品味是无法解释的。有些人喜欢小说,而有些人对经济学更感兴趣。
出于这个原因,查看建议在每个类别中的分布是合理的。
这将让我们了解异常值,并帮助我们发现每个类别中最值得推荐的书籍:
cat = books_df.category.value_counts().head(20).indexfig, ax = plt.subplots(figsize = [10,5])sb.swarmplot(data = books_df[books_df.category.isin(cat)], x = 'category', y = 'num_recommendations', palette = 'tab20')ax.set_xticklabels(ax.get_xticklabels(), rotation = 90)
ax.set_title('Distribution of Recommendations by Category', fontweight = 'bold', size = 18)
ax.set_xlabel('Categories', size = 15)
ax.set_ylabel('Recommendations', fontsize = 15)
我们看到大多数类别都有 1-5 本推荐范围内的书籍。
同时,一些类别有超过 5 人推荐的书籍,而另一些类别有超过 10 人推荐的书籍。传记、商业和经济、小说、心理学和自助都有许多书籍,有许多推荐。
现在,让我们找出每一类中的必读书籍。
我将只考虑 9 个类别,并根据推荐数量绘制前 5 个类别。但是请注意,使用以下代码可以添加更多类别或扩大图书列表:
***#Defining the categories:***
categories = books_df.category.value_counts().head(9).index.tolist()***#Defining a function to select a subset of data:*
def** selection(cat):
data = books_df[books_df['category'] == cat].sort_values(by = 'num_recommendations', ascending = False).head()
**return** datafig, ax = plt.subplots(nrows = 3, ncols = 3,figsize = [20,15])
plt.suptitle('Top 5 Recommended Books in each Category', size = 30, y = 1.05, fontweight = 'bold')
fig.tight_layout(h_pad = 8)
fig.text(-0.02, 0.5, 'Recommendations', va = 'center', rotation='vertical', fontweight='bold', fontsize=25)
fig.text(0.5, -0.06, 'Titles', va = 'center', ha = 'center', fontweight = 'bold', fontsize=25)
ax = ax.flatten()
color_base = sb.color_palette()[0]y = sorted(books_df['num_recommendations'].unique())
i=0
**for** cat **in** categories:
sb.barplot(data = selection(cat), x='title', y = 'num_recommendations', ax = ax[i], color = color_base)
ax[i].set_title(cat, fontweight = 'bold', fontsize = 18, color = 'crimson')
ax[i].set_ylabel('')
ax[i].set_xlabel('')
ax[i].set_xticklabels((textwrap.fill(x.get_text(), width=11) **for** x **in** ax[i].get_xticklabels()), fontsize = 14)
ax[i].set_yticks(np.arange(0, max(y)+1, 5))
ax[i].set_yticklabels(labels = ax[i].get_yticks(), fontsize =14)
i += 1
现在我们有各种各样的书,我们可以根据自己喜欢的类型从中选择。
当然,如前所述,有可能情节超过五本书。这只是一个说明,展示它是如何呈现的。
最后,我们可以更进一步,从另一个角度来看我们的数据集。
一个作者可以有多本书,如果一些书获得了很多喜欢,一些作者可能同样比其他人拥有更多的粉丝。
换句话说,我们来看看**“谁是** 最值得推荐的作者”:
***#Grouping by 'recommender' and 'author' to get the unique values of #authors per each recommender:***
data = recommended_books.groupby(['recommender', 'author']).count().reset_index(level=1)***#Plotting the 20 most recommended authors:***
plt.figure(figsize=[10,5])
color_base = sb.color_palette()[0]sb.barplot(data['author'].value_counts().head(20).index, data['author'].value_counts().head(20).values, color=color_base)plt.xticks(rotation = 'vertical')
plt.title('The Most Recommended Authors', fontweight = 'bold', size = 18)
plt.xlabel('Authors', size = 15)
plt.ylabel('Count', size = 15)
这是一个很棒的条形图,有很多名字出现在第一个图的中。
不过顺序不太一样,有些名字是新的。
换句话说,即使一些书被高度推荐,我们也不要忽视作者,因为他们同样重要。
最终想法:
说名人的推荐是“有史以来最好的”,不是我的目的。当然还有许多其他令人惊讶的书没有被注意到(或者没有被翻译成英文)。
简单的建议创造推动我们选择的社会证据。一本书的评论或推荐数量越多,想要阅读它的人就越多。当这些评论或建议来自我们当中最成功的人时,社会证明往往会增加。推荐就像一个指南针,在我们迷失的时候给我们指明正确的方向。
我要感谢mostrecommendedbooks.com的联合创始人理查德·赖斯和阿努拉格·拉姆达桑,他们允许我使用他们的网站作为主要的信息来源。
通过 Google books API 访问公共数据甚至可以在没有 API 键的情况下完成。我试过带钥匙和不带钥匙,两种情况下都有效。
探索下一个单词预测器!
原文:https://towardsdatascience.com/exploring-the-next-word-predictor-5e22aeb85d8f?source=collection_archive---------5-----------------------
深度学习|自然语言处理
构建下一个单词预测器的不同方法
自由股票在 Unsplash 上的照片
语言预测导论
你手机上的键盘怎么知道你下一步想输入什么?语言预测是一个自然语言处理 NLP 应用程序,涉及预测前面文本中给出的文本。自动完成或建议的回答是语言预测的流行类型。语言预测的第一步是选择语言模型。本文展示了在 Whatsapp 或任何其他消息应用程序中构建下一个单词预测器可以采用的不同方法。
通常有两种模型可以用来开发下一个单词的建议者/预测者:1) N-grams 模型或 2)长短期记忆(LSTM)。我们将仔细检查每种型号,并得出哪个型号更好的结论。
n 元语法方法
如果你沿着 n-grams 这条路走下去,你需要关注“马尔可夫链”来根据训练语料库预测每个后续单词或字符的可能性。下面是这种方法的代码片段。在这种方法中,一的序列长度被用来预测下一个字。这意味着我们将预测前一个单词中给出的下一个单词。
导入必要的模块:word _ tokenize,default dict, 计数器
import re
from nltk.tokenize import word_tokenize
from collections import defaultdict, Counter
创建包含方法的类 MarkovChain :
class MarkovChain:
def __init__(self):
self.lookup_dict = defaultdict(list)def _preprocess(self, string):
cleaned = re.sub(r’\W+’, ' ', string).lower()
tokenized = word_tokenize(cleaned)
return tokenizeddef add_document(self, string):
preprocessed_list = self._preprocess(string)
pairs = self.__generate_tuple_keys(preprocessed_list)
for pair in pairs:
self.lookup_dict[pair[0]].append(pair[1])def __generate_tuple_keys(self, data):
if len(data) < 1:
return
for i in range(len(data) - 1):
yield [ data[i], data[i + 1] ]
def generate_text(self, string):
if len(self.lookup_dict) > 0:
print("Next word suggestions:", Counter(self.lookup_dict[string]).most_common()[:3])
return
当我们创建上述类的一个实例时,一个默认的字典被初始化。有一种方法可以对我们通过添加的训练语料进行预处理。add_document() 方法。当我们在的帮助下添加文档时。add_document() 方法,为每个唯一的单词创建对。让我们用一个例子来理解这一点:如果我们的训练语料库是“你好吗?从我们上次见面到现在有多少天了?你父母好吗?”在预处理和添加文档之后,我们的查找字典应该是:
{ 'how': ['are', 'many', 'are'], 'are': ['you', 'your'],
'you': ['how'], 'many': ['days'], 'days': ['since'],
'since': ['we'], 'we': ['last'], 'last': ['met'], 'met': ['how'],
'your': ['parents']}
每一个唯一的单词作为一个键和它后面的单词列表作为一个值被添加到我们的查找字典 lookup_dict 中。
当我们输入一个单词时,它会在字典中查找,并在下面的单词列表中给出最常用的单词。这里,单词建议的最大数量是三个,就像我们在键盘上一样。下面是序列长度为 1 的这种方法的运行示例。输出包含建议的单词及其在列表中各自的出现频率。当我们输入单词“how”时,会在字典中查找它,并从下面的单词列表中选择最常用的三个单词。这里,“许多”单词出现了 1531 次,这意味着单词序列“多少”在训练语料库中出现了 1531 次。
n 元模型的输出(序列长度为 1)
在 n 元语法方法中:
此外,在上述方法中,我们可以具有 2 或 3 或更长的序列长度。为此,我们将不得不改变上面的一些代码。
class MarkovChain:
"""
Previous code continued
"""
def add_document(self, string):
preprocessed_list = self._preprocess(string)
pairs = self.__generate_tuple_keys(preprocessed_list)
for pair in pairs:
self.lookup_dict[pair[0]].append(pair[1])
pairs2 = self.__generate_2tuple_keys(preprocessed_list)
for pair in pairs2:
self.lookup_dict[tuple([pair[0], pair[1]])].append(pair[2])
pairs3 = self.__generate_3tuple_keys(preprocessed_list)
for pair in pairs3:
self.lookup_dict[tuple([pair[0], pair[1], pair[2]])].append(pair[3])
def __generate_tuple_keys(self, data):
if len(data) < 1:
return
for i in range(len(data) - 1):
yield [ data[i], data[i + 1] ]
#to add two words tuple as key and the next word as value
def __generate_2tuple_keys(self, data):
if len(data) < 2:
return
for i in range(len(data) - 2):
yield [ data[i], data[i + 1], data[i+2] ]
#to add three words tuple as key and the next word as value
def __generate_3tuple_keys(self, data):
if len(data) < 3:
return
for i in range(len(data) - 3):
yield [ data[i], data[i + 1], data[i+2], data[i+3] ]
def oneword(self, string):
return Counter(self.lookup_dict[string]).most_common()[:3]def twowords(self, string):
suggest = Counter(self.lookup_dict[tuple(string)]).most_common()[:3]
if len(suggest)==0:
return self.oneword(string[-1])
return suggestdef threewords(self, string):
suggest = Counter(self.lookup_dict[tuple(string)]).most_common()[:3]
if len(suggest)==0:
return self.twowords(string[-2:])
return suggest
def morewords(self, string):
return self.threewords(string[-3:])def generate_text(self, string):
if len(self.lookup_dict) > 0:
tokens = string.split(" ")
if len(tokens)==1:
print("Next word suggestions:", self.oneword(string))
elif len(tokens)==2:
print("Next word suggestions:", self.twowords(string.split(" ")))
elif len(tokens)==3:
print("Next word suggestions:", self.threewords(string.split(" ")))
elif len(tokens)>3:
print("Next word suggestions:", self.morewords(string.split(" ")))
return
我们来破解密码。方法*。__generate_2tuple_keys()* 和*。__generate_3tuple_keys()* 用于分别存储长度为 2 和 3 的序列及其后续单词列表。现在,我们的代码有能力根据之前的三个单词来预测单词。让我们看看我们新的查找字典 lookup_dict 的例子:“你好吗?从我们上次见面到现在有多少天了?你父母好吗?”
{
"""
Same as before
"""
('how', 'are'): ['you', 'your'],
...
('how', 'many'): ['days'],
('many', 'days'): ['since'],
...
('how', 'are', 'you'): ['how'],
...
('how', 'many', 'days'): ['since'],
...
}
与前一对相比,新对被添加到字典中。我们上面创建的类 MarkovChain 处理我们输入的任意长度的序列。如果我们输入一个单词,那么方法’ oneword’ ‘将被调用,这将与前一个相同。对于长度为 2 或 3 的输入,将分别调用方法’两个字和’三个字’。这些方法的作用是在给定输入单词的情况下,从查找字典中查找最常见的三个单词。当输入单词多于四个时,将处理最后三个。当遇到未知单词时,该单词将被忽略,字符串的其余部分将被处理。看看下面的图来澄清任何疑问。这个数字是基于不同的训练语料库。左侧显示输入,右侧显示输出。
我们的 n-grams 模型的各种输入情况
下面是这种方法的运行输出:
n 元模型的输出(序列长度超过 1)
上面的输出是基于用于这种方法的一个不同的更大的数据集。GitHub 对于这种方式的链接是 this 。你可以在那里找到上面的代码。
局限性:
马尔可夫链没有记忆。采用这种方法有许多限制。举个例子,“我吃了这么多烤……”下一个单词“三明治”将基于“烤三明治”在训练数据中一起出现的次数来预测。因为我们得到的建议只是基于频率,所以在很多情况下这种方法可能会失败。
长短期记忆(LSTM)方法:
使用神经语言模型的更高级的方法是使用长短期记忆(LSTM)。LSTM 模型使用深度学习和管理记忆的人工“细胞”网络,使它们比传统的神经网络和其他模型更适合文本预测。
“草总是…”
下一个词是简单的“绿色”,可以被大多数模型和网络预测。
但是对于句子“现在是冬天,阳光很少,草总是……”,我们需要知道句子更后面的上下文来预测下一个单词“棕色”。
当上下文和要预测的单词之间的差距增大时,标准 RNNs 和其他语言模型变得不太准确。这就是 LSTM 被用来解决长期依赖问题的时候,因为它有记忆细胞来记住以前的上下文。你可以在这里了解更多关于 LSTM 网络的信息。
让我们开始编码并定义我们的 LSTM 模型。在构建我们的模型时,首先,使用一个嵌入层,两个各有 50 个单位的堆叠 LSTM 层。
Keras 提供了一个嵌入层,可用于文本数据上的神经网络。嵌入层用随机权重初始化,并学习训练数据集中所有单词的嵌入。它需要整数编码形式的输入数据。这个数据准备步骤可以在同样由 Keras 提供的 Tokenizer API 的帮助下执行。点击了解更多关于嵌入层的信息。
两个 LSTM 层之后是两个完全连接的或密集的层。第一层有 50 个单元,第二个密集层是我们的输出(softmax)层,其单元数量等于词汇表大小。对于每个输入,模型将根据概率从我们的词汇中预测下一个单词。分类交叉熵被用作损失函数。
数据预处理:
对于嵌入层的输入,我们首先必须使用来自 keras.processing.text 的 Tokenizer 来编码我们的输入字符串。我们在预处理中所做的很简单:我们首先创建特征字典的序列。然后我们在记号赋予器的帮助下把它编码成整数形式。
from keras.preprocessing.text import Tokenizer
import nltk
from nltk.tokenize import word_tokenize
import numpy as np
import re
from keras.utils import to_categorical
from doc3 import training_doc3cleaned = re.sub(r'\W+', ' ', training_doc3).lower()
tokens = word_tokenize(cleaned)
train_len = 4
text_sequences = []for i in range(train_len,len(tokens)):
seq = tokens[i-train_len:i]
text_sequences.append(seq)sequences = {}
count = 1for i in range(len(tokens)):
if tokens[i] not in sequences:
sequences[tokens[i]] = count
count += 1tokenizer = Tokenizer()
tokenizer.fit_on_texts(text_sequences)
sequences = tokenizer.texts_to_sequences(text_sequences)#vocabulary size increased by 1 for the cause of padding
vocabulary_size = len(tokenizer.word_counts)+1
n_sequences = np.empty([len(sequences),train_len], dtype='int32')for i in range(len(sequences)):
n_sequences[i] = sequences[i]train_inputs = n_sequences[:,:-1]
train_targets = n_sequences[:,-1]
train_targets = to_categorical(train_targets, num_classes=vocabulary_size)
seq_len = train_inputs.shape[1]
让我们用一个例子来理解上面的代码中发生了什么:“你好吗?从我们上次见面到现在有多少天了?你父母好吗?”。我们首先清理我们的语料库,并借助 nltk 库中的*正则表达式、和 word_tokenize 对其进行标记。【序列】字典是做什么的?下面是使用记号赋予器之前的‘sequences’*字典。
{'how': 1, 'are': 2, 'you': 3, 'many': 4, 'days': 5, 'since': 6, 'we': 7, 'last': 8, 'met': 9, 'your': 10, 'parents': 11}
我们的*‘text _ sequences’*列表保存了我们训练语料库中的所有序列,它将是:
[['how', 'are', 'you', 'how'], ['are', 'you', 'how', 'many'], ['you', 'how', 'many', 'days'], ['how', 'many', 'days', 'since'], ['many', 'days', 'since', 'we'], ['days', 'since', 'we', 'last'], ['since', 'we', 'last', 'met'], ['we', 'last', 'met', 'how'], ['last', 'met', 'how', 'are'], ['met', 'how', 'are', 'your']]
使用 tokenizer 后,我们得到了编码形式的上述序列。这些数字只不过是重新分配前’*序列’*字典中相应单词的索引。
[[1, 2, 9, 1], [2, 9, 1, 3], [9, 1, 3, 4], [1, 3, 4, 5], [3, 4, 5, 6], [4, 5, 6, 7], [5, 6, 7, 8], [6, 7, 8, 1], [7, 8, 1, 2], [8, 1, 2, 10]]
一旦我们有了编码形式的序列,通过将序列分成输入和输出标签来定义训练数据和目标数据。对于此示例,我们将基于前三个单词预测下一个单词,因此在训练中,我们使用前三个单词作为输入,最后一个单词作为将由模型预测的标签。我们的’T12 培训 _ 输入’T13 现在应该是:
[[1 2 9] [2 9 1] [9 1 3] [1 3 4] [3 4 5] [4 5 6] [5 6 7] [6 7 8] [7 8 1] [8 1 2]]
然后,我们将输出标签转换成一个热点向量,即 0 和 1 的组合。’ train_targets’ 中的单热点向量看起来像:
[[0\. 1\. 0\. 0\. 0\. 0\. 0\. 0\. 0\. 0\. 0.]
...
[0\. 0\. 0\. 0\. 0\. 0\. 0\. 0\. 0\. 0\. 1.]]
对于第一个目标标签“how ”,序列字典中的索引是“1 ”,因此在编码形式中,您会在’ train_targets’ 的第一个独热向量中的索引 1 处看到“1”。
注意:以上代码是针对文本“你好吗?从我们上次见面到现在有多少天了?你父母好吗?”为了更简单的解释。但实际上,使用了更大的数据集。
构建模型:
现在我们训练我们的序列模型,它有 5 层:一个嵌入层、两个 LSTM 层和两个密集层。在我们的模型的输入层,即嵌入层中,输入长度被设置为序列的大小,在这个例子中是 3。(注意:我们将训练输入和训练目标的数据分割为 3 比 1,因此当我们为预测模型提供输入时,我们必须提供 3 个长度向量。)
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from keras.layers import Embedding
model = Sequential()
model.add(Embedding(vocabulary_size, seq_len, input_length=seq_len))
model.add(LSTM(50,return_sequences=True))
model.add(LSTM(50))
model.add(Dense(50,activation='relu'))
model.add(Dense(vocabulary_size, activation='softmax'))# compiling the network
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(train_inputs,train_targets,epochs=500,verbose=1)
预测单词:
在我们的模型被训练后,我们可以以编码的形式给出输入,并从 softmax 函数中得到三个最可能的单词,如下所示。
from keras.preprocessing.sequence import pad_sequencesinput_text = input().strip().lower()
encoded_text = tokenizer.texts_to_sequences([input_text])[0]
pad_encoded = pad_sequences([encoded_text], maxlen=seq_len, truncating='pre')
print(encoded_text, pad_encoded)for i in (model.predict(pad_encoded)[0]).argsort()[-3:][::-1]:
pred_word = tokenizer.index_word[i]
print("Next word suggestion:",pred_word)
在上面的代码中,我们使用填充,因为我们在长度为 3 的序列上训练我们的模型,所以当我们输入 5 个单词时,填充将确保最后三个单词作为我们模型的输入。当我们输入少于 3 个单词时会发生什么?我们不会得到最好的结果!当我们输入一个未知的单词时,也会发生同样的情况,因为在这个单词的索引中,一键向量将包含 0。我们将来可以做的是,将长度为 2(输入)的序列添加到 1(目标标签)中,将长度为 1(输入)的序列添加到 1(目标标签)中,就像我们在这里将长度为 3(输入)的序列添加到 1(目标标签)中一样,以获得最佳结果。
下面是我们的模型根据前面的单词预测接下来的 3 个单词的最终输出。
LSTM 模型的输出
上面的输出显示了输入的向量形式以及建议的单词。[6,4,3]是*‘编码 _ 文本’*,[[6,4,3]]是’填充 _ 编码’。
注意:这里我们将数据分为 3(输入)比 1(目标标签)。所以,一定要输入三个字。
GitHub 上面代码的链接是这个。你可以在那里找到 LSTM 方法的代码。
结论:
上面,我们看到 n-grams 方法不如 LSTM 方法,因为 lstm 具有从文本语料库中更远的地方记住上下文的记忆。在开始一个新项目时,您可能希望通过在互联网上寻找开源实现来考虑一个现有的预训练框架。这样,您就不必从头开始,也不需要担心训练过程或超参数。
乔希·里默尔在 Unsplash 上拍摄的照片
自然语言处理领域的许多最新工作包括开发和训练神经模型,以模拟人类大脑对语言的作用方式。这种深度学习方法使计算机能够以更有效的方式模仿人类语言。
探索 Python 熊猫图书馆
原文:https://towardsdatascience.com/exploring-the-python-pandas-library-67243960271e?source=collection_archive---------40-----------------------
Python 熊猫图书馆
来源
Pandas 是一个 python 库,用于从数据中分析、转换和生成统计数据。在本帖中,我们将讨论 Pandas 中用于数据争论和探索的几种有用的方法。出于我们的目的,我们将使用来自 Kaggle 的医疗费用个人数据集数据。
我们开始吧!
读取数据
首先,让我们导入 pandas 库:
import pandas as pd
接下来,让我们读入熊猫数据框。Pandas 数据框基本上是一个由行和列组成的类似于表格数组的数据结构。为了读入数据,我们可以使用。read_csv()'方法:
df = pd.read_csv("insurance.csv")
接下来,我们可以使用。head()‘和’。tail()'方法分别查看第一行和最后五行数据:
print(df.head())
print(df.tail())
我们还可以查看列名:
print(df.columns)
这对于包含大量列的数据集尤其有用。
清洗数据
很多时候,当使用真实数据时,我们必须处理数据列中缺失的值。使用 pandas,我们可以很快了解数据有多稀疏。isnull()”方法:
print(df.isnull().sum())
我们看到该数据不包含任何缺失值。让我们人为地为“儿童”和“地区”列添加缺失的值,以演示我们如何删除这些值:
df.loc[df.region == 'southwest', 'region'] = np.nan
df.loc[df.children == 1, 'children'] = np.nan
现在让我们计算一下我们添加的缺失值的数量:
print(df.isnull().sum())
我们可以使用。“dropna()”方法来移除这些缺少的值。这既可以就地完成,也可以返回一个值,存储在一个新的变量中。为了适当地删除丢失的值,我们执行以下操作:
df.dropna(inplace=True)
print(df.isnull().sum())
这里,df 变量已经被修改。或者,我们可以执行以下操作:
df = df.dropna()
让我们再次打印缺失的值:
print(df.isnull().sum())
我们可以在丢失值之前和之后检查数据帧的长度:
print("Length Before:", len(df))
df.dropna(inplace=True)
print("Length After:", len(df))
此外,如果想要填充数据框中缺失的值,可以使用。fillna()”方法。要做到这一点:
df.fillna(0, inplace=True)
或者:
df = df.fillna(0)
由于我们输入的是缺失值,因此数据帧的长度不应改变:
print("Length Before:", len(df))
df.fillna(0, inplace=True)
print("Length After:", len(df))
过滤数据
我们可以根据列值轻松过滤数据帧。例如,如果我们想要对应于 30 岁以下患者的记录,我们可以写:
df = df[df['age'] < 30]
print(df.head())
如果我们想要与超过 10,000 美元的费用相对应的记录,我们可以写:
df = df[df['charges'] > 10000]
print(df.head())
我们还可以过滤数据框,仅包含吸烟者:
df = df[df['smoker'] == 'yes']
让我们打印前五行:
print(df.head())
请注意,在删除数据后,索引已经被修改。我们可以通过使用“reset_index”方法来解决这个问题:
df.reset_index(inplace=True)
del df['index']
print(df.head())
我们也可以使用多个条件进行过滤。假设我们想要提取与女性吸烟者相对应的数据。我们可以使用。loc[]'方法如下:
df = df.loc[(df.sex == 'female') & (df.smoker == 'yes')]
df.reset_index(inplace=True)
del df['index']
print(df.head())
我们甚至可以添加两个以上的条件。让我们过滤 50 岁以上的女性吸烟者:
df = df.loc[(df.sex == 'female') & (df.smoker == 'yes') & (df.age >= 50)]
df.reset_index(inplace=True)
del df['index']
print(df.head())
选择行和列
现在我们将讨论如何使用。iloc[]'方法来选择索引。为了选择数据集中的第一个、第二个和最后一个索引,我们执行以下操作:
print(df.head())
print("---------------------First---------------------")
print(df.iloc[0])
print("---------------------Second---------------------")
print(df.iloc[1])
print("---------------------Last---------------------")
print(df.iloc[-1])
你可以用’做类似的事情。特定列的 loc[]。要选择第一行和第二行,我们执行以下操作:
print("---------------------First---------------------")
print(df.loc[0, 'sex'])
print("---------------------Second---------------------")
print(df.loc[1, 'sex'])
我们也可以在一列中选择多行:
print("---------------------First---------------------")
print(df.loc[0:3, 'sex'])
print("---------------------Second---------------------")
print(df.loc[3:6, 'sex'])
汇总数据&生成统计数据
现在,我们将讨论如何从数据框中的数据生成统计数据。我们可以为特定类别创建单独的数据框,并从结果数据框中生成统计数据。让我们为男性和女性记录创建单独的数据框:
df_female = df[df['sex'] == 'female']
df_male = df[df['sex'] == 'male']
让我们看看女性的平均费用:
print("Female charges: ", df_female['charges'].mean())
让我们看看男性的平均费用:
print("Male charges: ", df_male['charges'].mean())
我们还可以使用’找到任何数字列的最大值。max()”方法。让我们对完整的数据集这样做:
print("Maximum Value: ", df['charges'].max())
我们还可以找到最小值:
print("Minimum Value: ", df['charges'].min())
我们可以将这些方法应用于其他数值列。让我们对“年龄”列也这样做:
print("Maximum Value: ", df['age'].max())
print("Minimum Value: ", df['age'].min())
让我们对“bmi”列进行同样的操作:
print("Maximum Value: ", df['bmi'].max())
print("Minimum Value: ", df['bmi'].min())
另一个有用的方法是。可用于聚合数据的“groupby()”方法。假设我们想知道男性和女性吸烟者的数量:
df_yes = df[df['smoker'] == 'yes']
df_yes = df_yes.groupby(['sex'])['smoker'].count()
print(df_yes.head())
我们看到男性吸烟者的数量大于女性吸烟者的数量。我们也可以看看非吸烟者的分组统计数据:
df_no = df[df['smoker'] == 'no']
df_no = df_no.groupby(['sex'])['smoker'].count()
print(df_no.head())
我们也可以使用。“groupby()”方法来获取不同类别类型的平均医疗费用。之前我们看了男性和女性的平均医疗费用。我们可以用’再次生成那些统计数据。groupby()':
df = df.groupby(['sex'])['charges'].mean()
print(df.head())
我们还可以为每个区域组生成这些统计数据:
df = df.groupby(['region'])['charges'].mean()
print(df.head())
看看每个吸烟者群体的平均医疗费用也是很有趣的:
df = df.groupby(['smoker'])['charges'].mean()
print(df.head())
正如我们所料,吸烟者的医疗费用明显高于不吸烟者。我们也可以按吸烟者和性别分组:
df = df.groupby(['smoker', 'sex'])['charges'].mean()
print(df.head())
我们还可以查看其他统计数据,如跨类别收费的标准偏差。标准差衡量一组值的离差量。在这种情况下,我们将考虑电荷的标准偏差,它对应于电荷数据的分散。让我们来看看不同性别间电荷的标准差:
df = df.groupby(['sex'])['charges'].std()
print(df.head())
我们还可以查看不同地区的收费标准偏差:
df = df.groupby(['region'])['charges'].std()
print(df.head())
或者我们可以应用。跨多列的“groupby()”。让我们计算跨地区/性别组的费用标准偏差:
df = df.groupby(['region', 'sex'])['charges'].std()
print(df.head())
接下来,让我们计算不同吸烟者/性别群体的标准偏差:
df = df.groupby(['smoker', 'sex'])['charges'].std()
print(df.head())
迭代数据帧
接下来,我们将讨论如何迭代数据框行。我们可以使用一种叫做。iterrows()',这将允许我们对行和索引值进行迭代:
for index, rows in df.iterrows():
print(index, rows)
下面是一些输出值的屏幕截图:
我们还可以为我们的迭代选择特定的行。让我们对“性别”、“费用”和“吸烟者”栏也这样做:
for index, rows in df.iterrows():
print('sex:', rows['sex'], 'charges:', rows['charges'], 'smoker:', rows['smoker'])
我们还可以根据其他列的值创建新列。假设我们想要创建一个新列来指定一个记录是否对应于一个女性吸烟者。我们可以使用。iterrows()‘和’。用布尔值标记女性吸烟者的 at[]'方法:
for index, rows in df.iterrows():
if (rows.sex == 'female') and (rows.smoker == 'yes'):
df.at[index, 'female_smoker'] = True
else:
df.at[index, 'female_smoker'] = False
让我们打印修改后的数据框的前五行:
print(df.head())
我们可以用’执行更复杂的标记。iterrows()‘和’。位于[]'。假设我们要创建一列布尔值,对应于 50 岁以上有孩子的男性吸烟者:
for index, rows in df.iterrows():
if (rows.sex == 'male') and (rows.smoker == 'yes') and (rows.age > 50) and (rows.children > 0):
df.at[index, 'male_smoker_with_children'] = True
else:
df.at[index, 'male_smoker_with_children'] = False
让我们打印结果数据框的前五行:
print(df.head())
我们可以做的另一件事是使用 collections 模块中的“Counter”方法来了解新列的布尔值分布。让我们将“计数器”方法应用于“女性吸烟者”列:
from collections import Counter
print(Counter(df['female_smoker']))
这对应于 115 个女性吸烟者的记录。让我们将“计数器”应用于 50 岁以上有孩子的男性吸烟者一栏:
print(Counter(df['male_smoker_with_children']))
这相当于 21 个 50 岁以上有孩子的男性吸烟者的记录。
写入文件
最后,如果我们对数据框进行了足够的修改,以至于我们希望将其保存到一个单独的文件中,那么我们可以使用。“to_csv()”方法:
df.to_csv("insurance_edit.csv")
结论
总之,在这篇文章中,我们讨论了熊猫的几种方法。我们讨论了如何使用 Pandas 方法读取、清理和过滤数据。我们还讨论了如何生成聚合统计数据、迭代数据帧以及将数据写入新文件。我希望这有所帮助。这篇文章中的代码可以在 GitHub 上找到。感谢您的阅读!
探索数据科学的真实世界
原文:https://towardsdatascience.com/exploring-the-real-world-of-data-science-57dc1f3fec3d?source=collection_archive---------34-----------------------
我在现实世界中学到的关于数据科学的东西
图片提供:阿蒂卡·马安
近年来,数据科学、机器学习和人工智能一直是热门领域。许多人希望成为数据科学家,并投入巨大努力通过大学、在线课程或自学来提升他们的技能。然而,就工作和解决业务问题而言,在现实世界中有很多挑战。作为一名数据科学家,非技术技能同样重要。在这篇博客中,我分享了我作为一名数据科学家在工作中的亲身经历。
理解业务问题
现实世界的问题中有很多挑战,学生在大学里不一定会遇到。在学校,他们曾经得到一个结构化的问题和一个流行的数据集,并最终得到精确的解决方案。然而,行业中的问题通常是非结构化的和复杂的。任何关于这个问题的假设在现实世界中都会适得其反。在深入分析之前,最好完全了解业务问题。理解业务问题包括对问题及其领域做更多的研究、计划、向客户提出正确的问题以及与团队成员进行讨论。
协力
数据科学是关于逻辑思维,在解决问题时产生更多的想法和创造力。因此,团队合作在数据科学中扮演着重要的角色。也有必要多维思考,而不是一维思考。团队成员可能来自不同的背景,拥有不同种类的技能。发挥每个团队成员的力量,并相应地分配工作。这帮助我用不同的方式解决问题,并学习新的东西。
好听众
另一个关键技能是成为一个好的倾听者。数据科学是关于共享和协作的。基本上,这个人需要理解团队中其他人的观点。很多时候,其他团队成员提出了好的想法,这些想法可能是独一无二的,为了在项目中成功实施,倾听和理解它们是必要的。正如我上面所说的,数据科学不是一个人的表演,它总是一个团队的努力。
证明文件
数据科学或人工智能是一个快速发展的领域,因此,总会有一些新的和至关重要的东西需要学习。很难记住所有的事情,文档帮助我克服了这个挑战。此外,它还帮助我明确了自己的思维过程。我过去常常记录我的学习、分析、建模过程、实验和代码。此外,我会详细地写下我失败的实验及其原因,从长远来看,这有助于我强化我的想法。除此之外,它还帮助我提高了我的沟通和理解概念的细节。你可以记录下你学到的或遇到的小事情,这些小事情从长远来看会产生很大的影响。使用你自己方便的工具来记录。
敏捷环境
在敏捷环境中工作让我在每个冲刺阶段的开始都有清晰的计划、优先级和方向。拥有敏捷的思维有助于应对变化和处理不确定性。如果你遇到不确定性,尝试各种选择,收集反馈,反复改进。这也给了我与不同团队合作的机会。在每个 sprint 结束时,以机器学习模型的形式向利益相关者提交一个最小可行产品(MVP)帮助我以更好的形式塑造我的项目。此外,每个 sprint 结束时的反馈帮助我纠正错误,高效地交付项目。
讲故事
讲故事是数据科学的重要组成部分。我们正在处理数据,创建模型,并寻找洞见。但是,从商业角度来看,这个模型说明了什么呢?换句话说,这种模式如何为公司赚钱或解决问题?利益相关者和管理层对 p 值或任何其他统计数据都不感兴趣。这里的主要挑战是以吸引人的方式用更简单的术语向非技术观众解释模型。一种方法是通过一个小故事来解释这个模型。这是我去年最大的收获之一。始终包括良好的视觉效果,这有助于以故事的形式传达信息。讲故事是一门艺术,需要时间和大量的练习。
展示输出的创造性
我们总是使用传统的 PPT 向客户或利益相关者展示我们的工作。我们为什么不创建一个 web 应用程序或仪表板来解释我们的模型输出,而不是 PPT 呢?创建一个 web 应用程序或仪表板显示了对项目的承诺,也与利益相关者和客户建立了联系。
始终使用版本控制
版本控制是每个人都包括在工作流中的一件重要的事情。它有助于集中管理您的代码,而不是将其保存到 PC/笔记本电脑或外部驱动器中。这样,当你在任何地方进行新项目时,你都可以参考代码或文档。
编码
在过去的 8 个月里,我显著提高了我的编码技能。我在工作和比赛中学到的一件事是编写函数式或面向对象的代码,以获得最大的代码可重用性。这将有助于在未来的项目中使用代码,并减少当前项目的时间。每当我提到 stackoverflow 或 google 时,我都会记录代码函数,这帮助我学习了新的编码知识。始终遵循最佳实践,让您的代码对读者友好。
请求帮助
数据科学融合了计算机科学、统计学、机器学习和领域专业知识。因此,从处理不同的步骤,从清理数据到解释最终的模型并部署它,都需要 it 人员的技能。不要被**、**吓倒,你不可能一天就掌握数据科学。因此,如果你陷入困境,请随时寻求帮助,通过这种方式你将获得更多的知识,并最终使你对自己的方法充满信心。
继续学习!
人工智能是 IT 行业的新热点,让我们直面这样一个事实,所有这些都不可能在短时间内被任何人所同化。决定战略性地利用它,每天投资一两个小时来学习新概念和解决新问题,包括学习新算法、编码、阅读博客、做个人项目等。除此之外,我强烈推荐阅读对心流和讲故事技巧有很大帮助的非技术性书籍,这将是我们继续前进的有用特征。
热情
在我最初的日子里,我的印象是,在这个分析的世界里,每个人都是一切的主人。但是后来我意识到我的假设是错误的。我知道这对这里的每个人来说都是一个不断学习的过程。在这个游戏中保持流行的核心是 激情、好奇心和渴望 了解更多。无论是机器学习还是深度学习或 NLP,解决复杂问题的永远是激情。
免责声明—本博客包含我的个人经历。如果这些信息对你有所帮助,我很乐意倾听。
感谢阅读!
你也可以在 KDnuggets 上阅读这篇文章。
探索 CDI 数据集中糖尿病、高血压和高胆固醇之间的关系
原文:https://towardsdatascience.com/exploring-the-relationship-between-diabetes-high-blood-pressure-and-high-cholesterol-in-the-cdi-16f15fc80b73?source=collection_archive---------62-----------------------
使用数据分析和统计
我的上一篇文章讨论了糖尿病带各州糖尿病患病率和糖尿病相关死亡率的性别和种族差异。这些数据来自 CDC 的慢性病指标(CDI):糖尿病数据集,它提供了 2010 年至 2018 年所有州和地区的糖尿病相关信息的汇编。
在本文中,我想使用 CDI 糖尿病数据集的数据来探讨糖尿病与其共病(高血压和高胆固醇)之间的关系。就像糖尿病一样,这两种共病是心脏病的已知风险因素。我想看看在糖尿病带诊断为糖尿病的成人中,一种共病是否比另一种更普遍。我还想了解在糖尿病带中诊断为糖尿病的成年人中,高血压患病率和高胆固醇患病率是否存在性别偏见。
这种探索性数据分析是在 Jupyter Notebook/Python 中完成的。用于生成本文中使用的这些可视化和统计测试的代码已经发布到 GitHub 这里。
巴克等人在 2011 年描述的糖尿病带包括“阿拉巴马州、阿肯色州、佛罗里达州、佐治亚州、肯塔基州、路易斯安那州、北卡罗来纳州、俄亥俄州、宾夕法尼亚州、南卡罗来纳州、田纳西州、德克萨斯州、弗吉尼亚州和西弗吉尼亚州……密西西比州。”在我的上一篇文章中,我关注的是这些州的子集,因为这些州比美国其他州受糖尿病的影响更大,因此可以进行更有针对性的分析。在本文中,我将继续分析这些数据,并仅针对构成糖尿病带的州得出结论。
在开始之前,我想提供一些关于这个主题的技术背景。高血压、高胆固醇和糖尿病都是心脏病的危险因素。高血压意味着血管中的血流量增加,使心脏工作更多,心脏变弱(美国心脏协会,2016)。高水平的胆固醇(体内发现的一种脂肪)会阻塞血液流动。如果血管被胆固醇堵塞,它们就会变得狭窄,需要更高的血压来保持血液流动,最终削弱心脏,增加心脏病的可能性。因此,研究这些共病的患病率对人群健康研究很重要。
与上一篇文章类似,我将继续分析 2017 年的数据,因为这是可用数据中最近的一年。
首先,我想看看糖尿病共病的总体患病率:高血压和高胆固醇。
2017 年糖尿病共病患病率。来源:我自己的数据分析。
从上图可以看出,在诊断为糖尿病的成年人中,高血压的患病率高于高胆固醇的患病率。统计测试证实两者之间存在显著差异:
- 使用独立的 t 检验来确定在诊断为糖尿病的成人中高血压患病率和高胆固醇患病率之间是否存在统计学显著差异。使用 Levene 方差相等性检验(p > 0.05),满足正态性(p > 0.05)和方差齐性假设。对于确诊为糖尿病的成年人,高血压患病率 (M = 65.81,SD = 4.81),明显高于高胆固醇患病率 (M = 56.31,SD = 4.37),p = 0.00 < 0.05。
这一观察结果与 CDC 的《2020 年国家糖尿病统计报告》的数据相吻合,该报告指出,2013 年至 2016 年,68.4%的诊断为糖尿病的成年人患有高血压(血压> 140/90),或目前正在接受高血压药物治疗,43.5%的人胆固醇水平高(LDL 胆固醇> 130 mg/dl)。糖尿病带和美国的高血压患病率相似。然而,糖尿病带的高胆固醇患病率高于美国。与美国其他地区相比,高胆固醇患病率的增加可归因于糖尿病带中诊断为糖尿病的成年人密度的增加。
接下来,我想看看被诊断为糖尿病的成年人中高血压患病率和高胆固醇患病率之间的性别差异。
2017 年诊断为糖尿病的成年人中高血压的患病率
从诊断为糖尿病的成年人中高血压的患病率开始,我可以看到男性和女性成年人的患病率相似。两组之间没有显著差异,这一点通过统计检验是显而易见的:
- 使用独立的 t 检验来确定男性和女性成人高血压患病率之间是否存在统计学显著差异。使用 Levene 方差相等性检验(p > 0.05),满足正态性(p > 0.05)和方差齐性假设。男性 (M = 67.64,SD = 4.90) 和女性 (M = 64.24,SD = 7.15),高血压患病率无显著差异,p = 0.15 > 0.05。
2017 年诊断为糖尿病的成年人中高胆固醇的患病率
上述诊断为糖尿病的成年人中高胆固醇患病率的图表显示,男性和女性成年人具有相似的高胆固醇患病率。统计测试证实了这一点:
- 使用独立的 t 检验来确定男性和女性成年人的高胆固醇患病率之间是否存在统计学显著差异。使用 Levene 方差相等性检验(p > 0.05),满足正态性(p > 0.05)和方差齐性假设。男性 (M = 58.41,SD = 9.00) 和女性 (M = 56.13,SD = 5.36),高胆固醇患病率无显著差异,p = 0.42 > 0.05。
CDI 糖尿病数据集还包括种族数据;然而,由于缺少大量数据,我没有考虑种族在共病患病率中的作用。黑人(非西班牙裔)和西班牙裔人口的数据缺失太多,我无法做出有意义的见解。尽管如此,我还是很想知道在糖尿病共病的种族差异方面做了哪些研究。根据 Walker 等人(2016)的研究,与其他族裔群体相比,黑人(非西班牙裔)个体“始终表现出最低的血压控制率”。在黑人(非西班牙裔)的血脂控制中也发现了类似的趋势(Walker 等人,2016)。在我之前的文章中,一项种族差异分析显示,黑人(非西班牙裔)在整个糖尿病带中具有最高的糖尿病患病率和糖尿病相关死亡率。黑人(非西班牙人)受糖尿病的影响很大;由此可见,他们也会受到糖尿病共病的严重影响。
在我的上一篇文章中,我讨论了数据的局限性。同样的限制也适用于此。这些数据的来源是行为风险因素监测系统(BRFFS),该系统通过调查收集数据,并为诊断为糖尿病的成年人提供数据。因此,没有通过 BRFFS 的调查收集方法接触到的任何人都不包括在内,未确诊的糖尿病患者也不包括在内。此外,1 型和二型糖尿病之间没有区别。
另一个限制是 CDI 糖尿病数据集中这两个特定问题的种族数据缺失。性别、种族、环境因素和社会文化因素都有助于糖尿病的发展;因此,没有所有的碎片,很难拼凑出一幅画。
总之,糖尿病是一种复杂的疾病,有许多危险因素和并发症。我对 CDI 糖尿病数据集的分析着眼于高血压、高胆固醇和糖尿病之间的相互联系。在这个数据集中,在诊断为糖尿病的成年人中,高血压或高胆固醇没有性别偏见,但在 2017 年糖尿病带诊断为糖尿病的成年人中,高血压的患病率明显高于高胆固醇。
引用:
美国心脏协会。"血压多高会导致心力衰竭."2016,https://www . heart . org/en/health-topics/高血压/高血压对健康的威胁/高血压会导致心脏衰竭
美国已诊断糖尿病的地理分布:糖尿病带。美国预防医学杂志第 40 卷,4(2011):434–9。doi:10.1016/j . amepre . 2010 . 12 . 019
疾病控制和预防中心,2020 年全国糖尿病统计报告。第 9 页。“糖尿病相关并发症的风险因素”。https://www . CDC . gov/diabetes/pdf/data/statistics/national-diabetes-statistics-report . pdf
种族、民族和健康的社会决定因素对糖尿病结果的影响。美国医学科学杂志第 351 卷,4(2016):366–73。doi:10.1016/j . amjms . 2016 . 01 . 008
探索正则化背后简单而令人满意的数学
原文:https://towardsdatascience.com/exploring-the-simple-satisfying-math-behind-regularization-2c947755d19f?source=collection_archive---------20-----------------------
来源: Unsplash
对过度拟合的迷人防御
正则化常用于机器学习,从简单的回归算法到复杂的神经网络,以防止算法过拟合。让我们通过简单数学的透镜来探索正则化控制模型的令人难以置信的令人满意和美丽的方式。
考虑一个非常简单的回归任务。有六个参数(系数)表示为β和,五个输入表示为 x 。模型的输出只是每个系数乘以输入(加上一个截距项β-0)。
为了使这个问题人性化,我们假设我们正试图基于五个因素来预测学生在一次测试中的分数(*f*(*x*)
的输出):1)他们花了多少时间做作业(hw
);2)他们睡了多少小时(sleep
);3)他们上次测试的分数(score
);4)他们当前班级的 GPA(gpa
);以及 5)他们在测试前是否吃了食物(food
)。
回归模型的目标是最小化“损失”,试图量化误差。这通常通过均方误差来实现。例如,如果我们有一个输入 x 和目标 y 的数据集,对于每个数据点,我们将评估预测目标和实际目标的差异,对其求平方,并在所有项目中取平均值。为了简洁起见,可以用这样的简写来表达( E 表示“期望值”或平均值)。
因此,线性回归被训练成沿着这个损失函数 l 优化其参数。然而,请注意,我们的模型有许多特点,这通常与更高的复杂性相关,类似于增加多项式的次数。所有的特征都相关吗?如果不是,它们可能只是为模型过度拟合提供了另一个自由度。
假设一个学生当前的 GPA 和他们那天早上是否吃了食物,结果提供了最小的好处,同时导致模型过度拟合。如果这些系数被设置为 0,那么这些特征将从模型中完全消除。
这导致了一个更简单的模型,该模型对数据过度拟合的能力较弱。在某种意义上,这种将系数降低到零的行为类似于特征选择。
正则化基于这样的想法,即较大的参数通常会导致过拟合,因为它们 a)不为零,所以它向生态系统中添加了另一个变量/自由度 b)会导致预测中的大波动和不自然的波动。这种高方差是过度拟合的警示信号。
让我们探讨两种类型的正则化:L1 正则化和 L2 正则化。
L1 正则化通过添加“正则化项”略微改变了线性回归中使用的损失函数,在这种情况下是“ λE [| β| ]”。我们来分解一下: E [| β| 的意思是‘参数绝对值的平均值’,而 λ 是一个比例因子,它决定了参数的平均值应该在总损失上招致多少损失。
总的来说,这鼓励更小的参数。当模型基于损失调整其系数以达到降低其值的总体目标时,它必须确定某个特征是否有足够的价值来保留,因为它比正则化项更多地增加了预测能力*。从根本上来说,保留这些特性更有利可图。*
然后,丢弃不太有用的特征,模型变得更简单。
L2 正则化本质上是相同的,但是参数在被平均之前被平方。因此,正则化是参数平方的平均值。这试图完成同样的任务,即鼓励模型降低系数的整体值,但结果不同。
值得注意的是,常规线性回归是 L1/L2 归一化的特例,其中λ参数等于 0,正则项基本上被抵消。
为了探究 L1 和 L2 归一化的不同效果,我们需要看看它们的导数,或者它们的函数在某一点的斜率。为了简化,我们可以表示为:
- L1 正则化为
y = x
。导数是 1。 - L2 正规化为
y = x²
。导数是 2 x 。
这意味着:
- 在 L1 正则化中,如果参数从 5 减少到 4,相应的正则化减少 5–4 = 1。
- 在 L2 正则化中,如果参数从 5 减少到 4,相应的正则化减少 25–16 = 9。
在 L1 正则化中,减少参数的回报是恒定的,而在 L2 正则化中,随着参数接近零,回报变得越来越小。从参数值 5 到 4 会产生 9 的下降,但是从 1 到 0 只会产生 1 的提高。
注意,记住模型只关心相对回报。奖励的绝对值与我们无关,因为 lambda 参数总是可以放大或缩小。重要的是模型将从参数的某个变化中获得多少减少或增加。
因此,在使用 L2 时,模型可能决定值得“保留一个特征”(不丢弃,或将参数减少到 0),因为:
- 它提供了大量的预测能力(减少损失中的第一项,
*E*[(*f*(*x*)−*y*)²]
)。 - 降低参数值不会有太大的好处,因为它已经接近 0 了。
- 减小参数将消除损失函数第一项中的增益,而第二项中的增益要小得多(
*λE*[*β²*]
)。
所以,总的来说:
- L1 正则化将产生具有更少特征的更简单的模型,因为它为减少参数值提供了一致的回报。它可以被认为是一种变量选择的“自然”方法,例如,它可以去除多重共线性变量。
- L2 正则化将产生参数接近但很可能不在零点的更复杂的模型,因为它提供递减的奖励来减少参数值。它能够学习更复杂的数据模式。
两种正则化方法都通过防止每个参数对最终结果产生太大影响来降低模型过度拟合的能力,但会导致两种不同的结果。
如果你正在寻找一个简单和轻量级的模型,L1 正则化是一个不错的选择。它采取了一种严肃的方法来消除对输出没有深刻影响的变量。在回归中,这被称为“套索回归”,可以在像sci-kit learn
这样的标准库中找到。
另一方面,如果您的任务更复杂,例如神经网络中的正则化,使用 L1 可能是一个坏主意,它可以通过将大量超参数设置为零来杀死它们。L2 正则化通常在神经网络中被推荐,因为它充当护栏,但不会过多地干扰神经元的复杂工作。
L2 回归被称为“岭回归”,可以在标准库中实现。在神经网络中,丢弃比 L2 正则化更“自然”,但在许多用例中,应该使用后者或两者都使用。
要点
- 正则化通过减少任何特征对结果的整体影响来防止机器学习模型中的过度拟合。
- L1 正则化和 L2 正则化都不断地给模型施加压力以减少它们的参数。前者给出恒定的奖励,但是后者根据参数接近 0 的程度给出递减的奖励。
- 正则化迫使模型反复比较某个特征带来的预测能力与其增加正则化项的程度,这导致模型选择保留更重要的特征。
- L1 将导致许多不太相关的变量被一起消除(系数设置为 0),而 L2 将导致不太相关的变量仍然存在,但系数较小。
感谢阅读!
探索 Softmax 函数
原文:https://towardsdatascience.com/exploring-the-softmax-function-578c8b0fb15?source=collection_archive---------52-----------------------
用 Wolfram 语言发展直觉
卡伦·艾姆斯利在 Unsplash 上的照片
在机器学习中,分类问题通常用神经网络来解决,神经网络给出它被训练识别的每个类别或类型的概率。一个典型的例子是图像分类,其中神经网络的输入是图像,输出是图像用概率表示的可能事物的列表。
Wolfram 语言(WL)带有一个大型的预训练神经网络库,包括解决分类问题的网络。例如,内置的系统功能 ImageIdentify 使用了一个预训练的网络,它可以识别图像中的 4000 多个对象。
作者在 Unsplash 上使用了詹姆斯·萨顿的照片
边注:由于 Wolfram notebook 界面独特的排版功能(例如将代码与图像混合),所有代码都用屏幕截图显示。在这个故事的结尾有一个笔记本,里面有完整的代码。
您可以直接使用底层神经网络来访问 4000 多个可能对象中每一个的概率。显然,“家猫”在这种情况下以几乎 1 的概率轻松获胜。其他类型的猫以较低的概率紧随其后。“浴帘”的结果可能是因为图像的背景。将所有 4,000+个概率相加得出数字 1.0。
作者在 Unsplash 上使用了詹姆斯·萨顿的照片
当你详细检查神经网络并查看它的组成层时,你会注意到最后一层是一种叫做 SoftmaxLayer 的东西。这一层在神经网络中非常常用,用于将一系列概率分配给一系列对象。
(图片由作者提供)
SoftmaxLayer 使用 softmax 函数,该函数将一个数字列表作为输入,并将一个规范化的数字列表作为输出。更具体地说,输入列表中的每个元素都被取幂并除以或归一化为所有取幂元素的总和。
(图片由作者提供)
从函数定义中可以清楚地看出,输出元素的总和总是 1。原因是输出中的每个元素都是一个分数,其中分母是所有分子的总和。不太清楚的是任意输入列表如何与输出列表相关,因为 softmax 函数是非线性的。
为了对此有所帮助并获得直觉,我编写了一个 WL 函数来理解 softmax 函数的输入和输出。它简单地创建了两个条形图,一个绘制输入列表,一个绘制输出列表。
understand[list_List] := Row[{
BarChart[list],
Style[" \[Rule] ", 32],
BarChart[SoftmaxLayer[][list]]
}]
让我们从三个零的简单输入开始。在这种情况下,输出也有三个相等的元素,因为它们的总和是 1,所以它们都是 0.333…
(图片由作者提供)
这适用于所有元素都相同的任何列表。例如,7 的四元素列表将产生所有元素都为 0.25 的结果:
(图片由作者提供)
当输入元素不完全相等时,事情变得更加有趣。让我们从线性增加的元素列表开始。输出是指数函数的缩小版本。
(图片由作者提供)
类似地,线性递减元素的列表产生递减的指数函数:
(图片由作者提供)
一个向下开口的抛物线会产生一条看起来像正态分布的输出“曲线”(可能正是如此?).
(图片由作者提供)
向上开口的抛物线给出更极端的输出,端点值占主导地位。
(图片由作者提供)
最后,主要是为了好玩,周期函数以某种重新调整的形式保持其周期性:
(图片由作者提供)
在笔记本中探索这一点和更多内容是非常有教育意义的。理解 softmax 函数如何工作有助于理解神经网络如何计算它们的最终分类概率分配。如果你想亲自体验更多,请从 Wolfram Cloud 下载这款笔记本。如果你对 WL 完全陌生,我推荐你阅读我最近的一篇名为“学习 Wolfram:从零到英雄”的文章。
用 NLTK 探索 Trump Twitter 档案
原文:https://towardsdatascience.com/exploring-the-trump-twitter-archive-6242e5100a74?source=collection_archive---------39-----------------------
探索特朗普
适合喜欢冒险的 NLP 初学者。
由尼古拉斯·托马斯在 Unsplash 上拍摄的照片
在本帖中,我们将探索由 特朗普推特档案 提供的数据集。这是 探索王牌 系列的一部分。
对于这个项目,我们将使用 pandas 和 numpy 进行数据操作,使用 matplotlib 进行可视化,使用 datetime 处理时间戳,使用 unicodedata 和 regex 处理字符串,最后使用 nltk 进行自然语言处理。
让我们从启动 Jupyter 笔记本开始吧!
环境
我们将导入 pandas 和 matplotlib,并为 Jupyter 设置显示选项,以便行和列不会被截断。
# for manipulating data
import pandas as pd
import numpy as np# for visualizations
%matplotlib inline
import matplotlib.pyplot as plt# to print out all the outputs
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"# set display options
pd.set_option('display.max_columns', None)
pd.set_option('display.max_rows', None)
pd.set_option('display.max_colwidth', -1)
获取数据
让我们把数据读入数据帧。如果你想跟进,你可以在这里下载数据集。这个数据集包含特朗普总统从 2017 年 1 月 20 日上任到 2020 年 5 月 30 日的推文。
df = pd.read_csv('trump_20200530.csv')
让我们看看前五行,看看记录(行)和字段(列)的数量。
df.head()
df.shape
让我们对这些列进行一个快速的重命名,以便于以后使用。
df.columns=['source', 'tweet', 'date_time', 'retweets', 'favorites', 'is_retweet', 'id']
让我们删除 id 列,因为它现在并不真正相关。
df = df.drop(columns=['id'])
让我们做一个快速的健全性检查,这次我们还要检查列的 dtypes。
df.head()
df.info()
使用时间戳
我们可以从前面的截图中看到,’ date_time '列是一个字符串。让我们把它解析成一个时间戳。
# for working with timestamps
from datetime import datetime
from dateutil.parser import parsedt = []
for ts in df.date_time:
dt.append(parse(ts))
dt[:5]
让我们添加一个包含时间戳信息的“datetime”列。
df['datetime'] = df.apply(lambda row: parse(row.date_time), axis=1)
让我们仔细检查数据集的数据范围。
df.datetime.min()
df.datetime.max()
修整数据
让我们看看这些推文有多少来源。
df.source.value_counts()
让我们只保留那些使用“iPhone 版 Twitter”应用程序制作的。
df = df.loc[df.source == 'Twitter for iPhone']
我们应该删除旧的“date_time”列和“source”列。
df = df.drop(columns=['date_time', 'source'])
分离转发
看看有多少是转发。
df.is_retweet.value_counts()
让我们创建另一个只包含 retweets 的 dataframe,并删除“is_retweet”列。
df_retweets = df.loc[df.is_retweet == True]
df_retweets = df_retweets.drop(columns=['is_retweet'])
健全性检查:
df_retweets.head()
df_retweets.shape
回到原始数据帧,让我们从数据集中删除 retweets,并完全删除“is_retweet”列。
df = df.loc[df.is_retweet == False]
df = df.drop(columns=['is_retweet'])
另一个健全性检查:
df.head()
df.shape
探索数据
让我们探索这两个数据框架,并回答几个问题。
总统什么时候发微博最多?他什么时候发微博最少?
下图显示,总统在下午 12 点左右最常发推文。他也最少在早上 8 点左右发微博。
title = 'Number of Tweets by Hour'
df.tweet.groupby(df.datetime.dt.hour).count().plot(figsize=(12,8), fontsize=14, kind='bar', rot=0, title=title)
plt.xlabel('Hour')
plt.ylabel('Number of Tweets')
总统哪一天发推特最多?他哪天发的微博最少?
下图显示了总统在周三最常发推文。他周四发的微博也最少。
title = 'Number of Tweets by Day of the Week'
df.tweet.groupby(df.datetime.dt.dayofweek).count().plot(figsize=(12,8), fontsize=14, kind='bar', rot=0, title=title)
plt.xlabel('Day of the Week')
plt.ylabel('Number of Tweets')
plt.xticks(np.arange(7),['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'])
从转发中分离 Twitter 句柄
让我们导入正则表达式,这样我们就可以用它来解析文本并分离出原始推文的 Twitter 句柄。在下面的代码中,我们添加了另一个包含 Twitter 句柄的列。
import repattern = re.compile('(?<=RT @).*?(?=:)')
df_retweets['original'] = [re.search(pattern, tweet).group(0) for tweet in df_retweets.tweet]
让我们创建另一个数据帧,它将只包含最初的 Twitter 句柄及其相关的转发次数。
df_originals = df_retweets.groupby(['original']).sum().sort_values('retweets').reset_index().sort_values('retweets', ascending=False)
让我们快速检查一下数据:
df_originals.head()
df_originals.shape
让我们快速地将结果可视化,这样我们就可以知道数据是否不成比例。
df_originals = df_retweets.groupby(['original']).sum().sort_values('retweets').reset_index().sort_values('retweets', ascending=False)[:10].sort_values('retweets')
df_originals.plot.barh(x='original', y='retweets', figsize=(16,10), fontsize=16)
plt.xlabel("Originating Tweet's Username")
plt.xticks([])
总统最喜欢转推哪个推特用户?
下图显示总统喜欢转发来自“@realDonaldTrump”的推文。
转发量前 5 名
让我们来看看根据最初的 Twitter 句柄被其他人转发最多的前 5 条推文。
先说带“@realDonaldTrump”的。
df_retweets.loc[df_retweets.original == 'realDonaldTrump'].sort_values('retweets', ascending=False)[:5]
还有一个是“@charliekirk11”。
df_retweets.loc[df_retweets.original == 'charliekirk11'].sort_values('retweets', ascending=False)[:5]
检查转发的收藏夹数
让我们看看有多少转发被其他人喜欢。
df_retweets.favorites.value_counts()
令人惊讶的是,没有一条转发似乎受到了任何人的喜爱。奇怪。
我们应该放弃它。
计算 N-Grams
要做一些 n 元排序,我们需要导入 unicodedata 和 nltk。我们还需要指定可能需要从分析中排除的附加停用词。
# for cleaning and natural language processing
import unicodedata
import nltk# add appropriate words that will be ignored in the analysis
ADDITIONAL_STOPWORDS = ['rt']
以下是我最喜欢的几个自然语言处理函数:
让我们使用“tweet”栏来看看df
数据框架中的前 10 个二元模型。
get_bigrams(df, 'tweet')
现在,对于前 10 个三元模型:
让我们使用viz_bigrams()
函数并可视化二元模型。
viz_bigrams(df, ‘tweet’)
类似地,让我们使用viz_trigrams()
函数并可视化三元模型。
viz_trigrams(df, 'tweet')
我们做到了!
结论
使用基本的 Python 和 nltk 库,我们探索了来自 Trump Twitter 存档的数据集,并对其进行了一些 n 元排序。
感谢您的阅读!探索性数据分析使用了很多技术,我们在这篇文章中只探讨了其中的一些。我鼓励你坚持练习,并使用其他技术从数据中获得洞察力。
在下一篇中,我们将继续我们的旅程,进入 Trump Twitter 存档,并 使用 spaCy 从同一数据集中提取命名实体 。
如果你想了解更多关于我从懒鬼到数据科学家的旅程,请查看下面的文章:
我的无学位数据科学之旅。
towardsdatascience.com](/from-slacker-to-data-scientist-b4f34aa10ea1)
敬请期待!
你可以在推特或 LinkedIn 上找到我。*
用 PyCaret 探索 Trump Twitter 档案
原文:https://towardsdatascience.com/exploring-the-trump-twitter-archive-with-pycaret-5c9e065acd6f?source=collection_archive---------52-----------------------
探索川普
适合喜欢冒险的 NLP 初学者。
洛伦佐·瑞在 Unsplash 上拍照
在之前的帖子中,我们开始探索由 特朗普推特档案 提供的数据集。这是 探索王牌 系列的第三部。
在这篇文章中,我们将继续我们的旅程,但这次我们将使用 PyCaret。
对于这个项目,我们将使用 PyCaret :
PyCaret 是一个开源的,Python 中的低代码机器学习库,允许您在几秒钟内从准备数据到在您选择的笔记本环境中部署您的模型。
PyCaret 做的比 NLP 多得多。它还进行一系列有监督和无监督的 ML,包括分类、回归、聚类、异常检测和关联规则挖掘。
要了解更多信息,请查看 Moez Ali 的公告:
[## 宣布 PyCaret:一个用 Python 编写的开源低代码机器学习库
Python 中的开源低代码机器学习库。
towardsdatascience.com](/announcing-pycaret-an-open-source-low-code-machine-learning-library-in-python-4a1f1aad8d46)
家政
让我们从安装 PyCaret 开始。只要做pip install pycaret
我们就可以出发了!注意:PyCaret 是一个很大的库,所以你可能想在等待它安装的时候喝杯咖啡。
此外,我们需要下载英语语言模型,因为它不是用 PyCaret 自动下载的:
python -m spacy download en_core_web_sm
python -m textblob.download_corpora
获取数据
让我们把数据读入数据帧。如果你想跟进,你可以在这里下载数据集。这个数据集包含了特朗普从 2017 年 1 月 20 日上任那一刻到 2020 年 5 月 30 日的推文。
import pandas as pd
from pycaret.nlp import *df = pd.read_csv('trump_20200530.csv')
让我们先检查一下数据的形状:
df.shape
让我们快速看一下:
df.head()
为了方便起见,我们只对 1000 条推文进行采样。
# sampling the data to select only 1000 tweets
df = df.sample(1000, random_state=493).reset_index(drop=True)
df.shape
主题建模
有趣的部分!
nlp = setup(data = df, target = 'text', session_id = 493,
customI _stopwords = [ 'rt', 'https', 'http', 'co', 'amp'])
PyCaret 的setup()
函数执行以下文本处理步骤:
- 移除数字字符
- 删除特殊字符
- 单词标记化
- 停用词删除
- 二元模型提取
- 三元模型提取
- 词汇化
- 自定义停用词
所有这些都在一行代码中!
它接受两个参数:在data
中的 dataframe 和我们想要在target
中传递的文本列的名称。在我们的例子中,我们还使用可选参数session_id
来获得再现性,使用custom_stopwords
来减少来自 tweets 的噪音。
说了这么多,做了这么多,我们会得到类似这样的结果:
下一步,我们将创建模型,并使用‘lda’
:
lda = create_model('lda', num_topics = 6, multi_core = True)
上面,我们创建了一个‘lda’
模型,并将主题数量作为6
传入,并对其进行设置,以便 LDA 将使用所有可用的 CPU 内核来并行化和加速训练。
最后,我们将使用assign_model()
为数据集的其余部分分配主题比例。
lda_results = assign_model(lda)
lda_results.head()
可视化结果
让我们绘制整个语料库的总体频率分布图:
plot_model()
现在让我们提取整个语料库的二元模型和三元模型:
plot_model(plot = 'bigram')
plot_model(plot = 'trigram')
但是如果我们只想从特定主题中提取 n 元语法呢?简单,我们只要传入topic_num
参数。
plot_model(lda, plot = 'trigram', topic_num = 'Topic 1')
如果我们想要主题的分布,我们将简单地改变它并在plot
参数中指定它。
plot_model(lda, plot = 'topic_distribution')
就是这样!
自上任以来,我们已经成功地对特朗普总统的推文进行了主题建模。
奖金回合
Moez Ali 写了一篇关于在 Power BI 中使用 PyCaret 的很棒的教程。看看这个:
[## 基于 PyCaret 的 Power BI 主题建模
在 Power BI 中实现主题模型的分步指南
towardsdatascience.com](/topic-modeling-in-power-bi-using-pycaret-54422b4e36d6)
感谢您的阅读!探索性数据分析使用了很多技术,我们在这篇文章中只探讨了其中的一些。我鼓励你坚持练习,并使用其他技术从数据中获得洞察力。
在下一篇文章中,我将为 pycaret 的自然语言处理模块做一个初学者指南。
感谢您的阅读。如果你想了解更多关于我从懒鬼到数据科学家的旅程,请查看下面的文章:
我的无学位数据科学之旅。
towardsdatascience.com](/from-slacker-to-data-scientist-b4f34aa10ea1)
如果你正在考虑改变方向,进入数据科学领域,现在就开始考虑重塑品牌:
给我们其他人的固执己见的建议。热爱数学,选修。
towardsdatascience.com](/the-slackers-guide-to-rebranding-yourself-as-a-data-scientist-b34424d45540)
敬请期待!
你可以通过推特或 LinkedIn 联系我。
[1] PyCaret。(2020 年 6 月 4 日)。为什么是 PyCaret 。https://pycaret.org/
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ji-chu/105200.html