什么是数据科学?简单来说,数据科学可以定义为从数据中提取意义和洞察力的过程。通常,这些是我们在数据科学项目中需要问的问题:
需要注意的重要一点是,也可以从数据开始,在处理数据时提出问题或见解,但在大多数情况下,我们都是从问题开始的。考虑到这一点,让我们开始吧。
在这个项目中,我们将尝试分析刚果足球俱乐部的表现并进行比较。
第一部分:制定问题。
刚果当地足球俱乐部在过去几年的表现如何,哪些因素会影响他们的表现?法国、德国、巴西等伟大的足球国家拥有许多伟大的足球俱乐部,全球数百万人在电视上观看排名靠前的比赛,这当然有助于他们国家队的表现。如果我们知道这些俱乐部在过去几年的表现,我们大概可以了解刚果国家足球队的表现。分析足球队表现的一种方法是使用**胜率**,即赢得的游戏数除以玩过的游戏总数**.**
第二部分:获取数据。
抓取过程的一个重要步骤是检查我们的网页,以了解我们需要操作的数据和所有html元素的位置。我不会在这里详细介绍如何做到这一点,但请记住,这就是**html标签'**类名和**身份证**将在本文的这一部分中使用的那个被发现。
步骤1:从网页中检索数据
让我们做所有的导入:
Importingallthecomponentswewillneed.
当我们使用我们导入的组件时,将解释这些行。
让我们将我们将抓取的页面的URL存储在一个列表中,因为我们需要所有感兴趣的俱乐部的数据,而且它们并不都在一个地方:
Thefunctiontoopenthebrowserandgoawebpage.
当我们打开网页时,我们可能必须单击横幅才能将其移开。我们定义了一个函数,它将获取一个浏览器对象(当前打开的网页)并单击带有id的任何横幅(它是一个html元素)**'onetrust-accept-btn-handler'**:
Thefunctiontoclickonanybanneronthepage.
注意使用**WebDriverWait**和预期的条件(**欧共体**)我们之前导入的方法。上面它们的使用只是意味着当我们启动浏览器并打开我们的页面时,我们等到具有id的元素**'onetrust-accept-btn-handler'**出现。一旦元素出现,我们**点击**在上面。但是我们不会永远等待,并且元素实际上可能永远不会出现,所以我们使用**最大暂停**我们之前定义的变量(请记住,我们将其设置为60秒,但您可以更改它以适应您的情况)。60秒后,如果没有出现横幅,我们的函数会打印“**没有出现横幅**”并且什么也不返回。
现在让我们假设我们的网页没有显示横幅,我们可以向下滚动并查看我们想要的所有内容。所以我们定义了一个函数来做这个,加载整个网页,向下滚动直到到达我们页面的底部,当没有更多内容可以加载时停止,就像人类会做的那样:
Thefunctiontoleadthepageinitsfullheight.
我试图使该功能尽可能不言自明。
现在定义另一个函数,它将按照所需的顺序调用上述函数,以加载传递URL的页面的数据:
Thefunctiontoretrievethehtmldata.
Ascreenshotoftheoutputforoneteam.Alltheotherslooksimilar
第2步:现在我们为抓取的每个站点解析html内容
ThefunctiontocreateDataFrameswithDataforeachteam.
然后可以使用和重用该功能。我们将为每个俱乐部调用它,然后将我们抓取的数据保存在csv文件中以供将来使用(当我们需要相同的数据时,我们不需要再次抓取)。
Callthefunctiononeachsoupobjectforeachclub,andsavethedatatocsvfiles.
现在我们有了数据。下一阶段是探索性数据分析(EDA),我们需要确定数据是否需要一些清理,以及它是否可以帮助我们回答问题。我们将该阶段分为两部分,第一部分用于清洁,第二部分用于分析和可视化。
第三部分:清理数据
这部分很大程度上取决于您的领域知识和您对所拥有数据的理解。我们检查了数据,发现一些名称包含括号、斜杠等,我们不需要这些。因此,我们清理了名称,但我们确保保留带有横杠(-)和圆点(.)的名称。我们编写了一个函数来做到这一点:
Thefunctiontocleanclubsnames
首先,我们定义一个正则表达式模式来匹配包含一个或多个单词的任何名称,该单词可选地后跟或由任意数量的空格、点或条分隔。这意味着如果文本中还有其他内容,例如括号,我们的模式将只匹配没有该内容的部分。
括号**(……)**在正则表达式模式中意味着我们将模式匹配的任何内容作为一个组,并且**P**意味着我们将捕获的组命名为**姓名**.我们将捕获的组写在方括号内。我们将通过断言测试我们的函数是否如我们所愿:
Assertionstotestournamecleaningfunction
我们还发现今年的比赛有不同寻常的格式。我们还需要清理日期:
Thefunctiontocleanthedates.
我们为3种不同的格式定义了3种模式。第一个是带有数字的日期,如“**dd.dd。dd:dd**”我们只需要“**dd.dd**“部分。所以我们的正则表达式使用**积极前瞻(=)**得到“一个或多个数字后跟一个点,然后是一个或多个数字”(我们将采用)后跟一个空格(我们不会采用)。
第二种模式适用于带有数字的日期,例如“**dd.dd.dddd**别的东西”,我们只需要“**dd.dd.dddd**“部分。此正则表达式还使用**正前瞻(=\w+)**只参加我们想要的部分。
第三种模式适用于带有“”之类数字的日期**dd.dd.dddd**“独自的。
对于每个匹配模式,我们更改为**日月年**格式。
我们测试我们的功能:
Assertionstotestourdatecleaningfunction.
现在我们可以一次清除所有名称和日期。首先我们连接所有团队的所有数据,然后我们清理名称和日期,将EventDate列更改为datetime类型,最后更改名称**刚果共和国**和**非洲**一个。我们还负责保存新的数据框以备将来需要:
Actualcleaningoftheclubsnamesandmatchdates,andafewmoremanipulations.
为了查看所有这些清理的结果,我们将数据框的前10行显示为**all_df.head(10)**:
Thefirst10rowsofourDataFrame.
第四部分:分析和可视化数据
我们注意到团队在2017年之前不存在,所以如果我们要比较我们的团队,我们需要使用他们都有数据的时期。
Selectingonlythegamesplayedafter2016forallteams.
我们可能还想知道打主场还是客场比赛对比赛结果有任何影响。我们不会在这里详细介绍这些细节,但让我们看看如何为此拆分数据:
SplittingHomeandAwaygames.
我们将保留这两个数据框以备不时之需。但是现在让我们创建另一个数据框,通过连接我们的**家**和**离开**数据帧。注意我们改变了列**客队**和**团队之家**至**团队。**
现在让我们按团队、年份和结果对比赛进行分组,并计算每组:
这意味着对于每支球队,我们将计算每年的每场比赛结果。我们还将计数列命名为'**游戏计数**'。
接下来,我们通过将赢得的比赛总数除以每支球队每年的比赛总数来计算每年的获胜百分比:
我们打印新数据框的前10行**wins_summary.head(10)**:
从该表中,我们已经可以开始得出一些结论,但我们可能无法清楚地看到数据告诉我们什么。所以是时候可视化数据了。我们将首先添加一列来存储每个团队的颜色。
现在我们可以绘制我们的数据:
运行该代码会得到以下结果:
第五部分:我们回答了什么问题?
这是我们报告分析结果的地方。我们可以将其放入报告中,其结构将根据项目的目的而有所不同。这里必须具备的技能是讲故事。大多数人不需要或不想了解我们使用的所有方法和工具,但他们肯定想了解所有这些的含义是什么?为什么我们在编写长代码和进行大量思考时让自己如此痛苦?我们需要解释结果,并可能根据我们的分析给出一些建议。
我将把这个留给你来谈谈你认为数据告诉我们我们团队的表现以及表现不佳的可能原因。
这就是这个项目。如您所见,没有涉及机器学习,并非所有问题都需要机器学习,因为这完全取决于我们的目标。