dataframe删除含有特定字符的行_创建一个机器学习算法,用不到30行的Python代码预测NCAAB得分...

在Python和一些很棒的库的帮助下,你可以构建自己的机器学习算法,用不到30行代码预测NCAAB比赛的最终得分。本内容旨在解释创建机器学习应用程序所需的所有步骤,包括设置,数据检索和处理,训练模型以及输出最终预测。

建立

先决条件

要学习本教程,强烈建议您对Python有基本的了解,但不是必需的。了解导入模块,获取和设置变量,字典和实例化类的目的是一个很好的基础,而使用Pandas和sklearn的经验是一个巨大的优势。

开发要求

  • Python 3:下面的所有代码也适用于Python 2,但是建议使用Python 3。
  • pandas,sportsreference,sklearn:我们所需的依赖关系,将在下面进一步详细说明。它们可以通过PIP安装,具体如下:
  • pip install pandas sklearn sportsreference
  • 活动网络连接:对于大多数人来说这可能不是问题,但是您最终使用的开发环境必须能够访问外部Web才能从我们的代码下载数据集。

构建应用程序

现在我们已经设置了开发环境,让我们开始构建实际的应用程序。

完整算法

import pandas as pdfrom sportsreference.ncaab.teams import Teamsfrom sklearn.ensemble import RandomForestRegressorfrom sklearn.model_selection import train_test_splitFIELDS_TO_DROP = ['away_points', 'home_points', 'date', 'location', 'losing_abbr', 'losing_name', 'winner', 'winning_abbr', 'winning_name', 'home_ranking', 'away_ranking']dataset = pd.DataFrame()teams = Teams()for team in teams: dataset = pd.concat([dataset, team.schedule.dataframe_extended])X = dataset.drop(FIELDS_TO_DROP, 1).dropna().drop_duplicates()y = dataset[['home_points', 'away_points']].valuesX_train, X_test, y_train, y_test = train_test_split(X, y)parameters = {'bootstrap': False, 'min_samples_leaf': 3, 'n_estimators': 50, 'min_samples_split': 10, 'max_features': 'sqrt', 'max_depth': 6}model = RandomForestRegressor(**parameters)model.fit(X_train, y_train)print(model.predict(X_test).astype(int), y_test)
0cf35f2cafe345bdad9eec1d3dc1bd85

对于那些喜欢直接跳到代码的人来说,上面的要点是我们将要使用的最终程序。如果您已经熟悉pandas和sklearn,可以跳到本内容的底部,了解该程序的运行方式以及如何扩展它以获得更高的精度,更快的运行时间和更高的可用性。对于其他想要进一步解释此代码的人,请继续阅读下面的内容,了解每个步骤的目的。

导入依赖项

import pandas as pdfrom sportsreference.ncaab.teams import Teamsfrom sklearn.ensemble import RandomForestRegressorfrom sklearn.model_selection import train_test_split

几乎每个Python程序都以一个import部分开头,其中包含了必需的依赖项,以便稍后在模块中使用。对于这个项目,我们需要导入我们之前安装的以下包:

  • pandas:一个流行的Python数据科学库,我们将用它来存储和操作我们的数据集。
  • sportsreference:一个免费的Python运动API,我们将用它来从NCAAB比赛中提取统计数据。
  • sklearn:Python最大的机器学习库之一,包括几个预先制定的算法,例如:我们将要使用的算法RandomForestRegressor,以及帮助数据创建传输路径的有用工具,例如train_test_split自动创建训练和测试数据集。

初始化数据集

dataset = pd.DataFrame()teams = Teams()for team in teams: dataset = pd.concat([dataset, team.schedule.dataframe_extended])

没有数据集,任何机器学习应用程序都不完整。为了帮助我们预测NCAAB比赛的最终得分,我们想要创建一个包含所有单个比赛统计数据的数据集(例如投篮命中率,失误数和盖帽次数,篮板百分比等等),然后我们可以使用这些数据来预测这些因素如何与最终得分相关联。

要创建此数据集,我们首先需要初始化一个空Pandas DataFrame,我们将用它来存储我们的最终数据。接下来,我们从sportsreference中初始化Teams类,其中包含当前或最近一个赛季NCAA男子组的每个篮球队的信息,并允许我们轻松地逐个团队获取统计数据。

在提取数据之前,我们需要通过运行for team in teams:每个迭代对应于联盟中一个独特的团队。sportsreference公开每个团队的日程安排和技术统计信息,使我们能够编写类似于team.schedule.dataframe_extended的代码,它可以收集每支球队在当前赛季参加的每场比赛的统计信息。该dataframe_extended属性返回一个pandas DataFrame,其中每个索引对应不同比赛的位置。

在收集每个比赛的技术统计信息后,我们希望将其添加到我们的整个数据集中,以便我们拥有一个单一的数据源。这可以通过将我们现有的数据集与DataFrame包含当前团队完整的技术统计信息的本地数据连接起来来完成。通过用结果连接覆盖我们现有的数据集,我们确保数据集不仅包括最近团队的信息,还包括之前查询过的所有团队的信息。

预处理数据集

FIELDS_TO_DROP = ['away_points', 'home_points', 'date', 'location', 'losing_abbr', 'losing_name', 'winner', 'winning_abbr', 'winning_name', 'home_ranking', 'away_ranking']...X = dataset.drop(FIELDS_TO_DROP, 1).dropna().drop_duplicates()y = dataset[['home_points', 'away_points']].valuesX_train, X_test, y_train, y_test = train_test_split(X, y)

在我们的数据集完成构建之后,我们需要从我们不想使用的数据集中过滤掉一些类别(或者通常在机器学习中调用的特征) - 即那些string类型(或分类)类似的:球队名称或日期和地点。有时,基于字符串的特征可能是有用的,例如在预测房屋价值的情况下,并且确定列为“海滨”的房产具有比分类为“内陆”的房产更高的价值。虽然此特征对房价预测很有用,但大多数机器学习算法无法处理基于字符串的数据。替换这些类型的特征的一种方法称为独热编码它使用唯一的特征列自动替换类似的分类值,其中属于该特征的每个索引的值都为1,否则为0。通过将类别更改为1和0,机器学习算法能够更有效地处理这些特征。

对于我们的目的,我们会简单地删除这些特征,因为他们要么数量太多,要么是无意义的,或者会引入偏差。因此,我们将删除所有这些类别。

在这一点上,有些人可能会奇怪,为什么要在要删除的字段列表中包含home_points以及away_points。这两个字段是我们想要预测的最终输出(通常称为标签),因此我们不希望它们包含在我们的主要特征中,而应该专门为我们的输出标签保留它们。

执行上面的代码,我们首先从数据集中删除所有不需要的特征,并将修剪后的输出保存为X。删除不需要的特征后,我们接下来删除所有不完整数据的行。如果sports-reference.com上的数据没有正确填充,或者球队没有执行特定的统计操作,例如没有封盖投篮或罚球,有时会发生这种情况。我们可以通过两种方法处理这些不完整的数据,方法是设置缺失值和设置数(例如类别的平均值或默认为零)或删除任何无效的行。因为无效单元格的数量对于我们的数据集来说非常少,所以我们将删除任何具有不完整数据的行,因为它不会影响我们的最终结果。

因为一场比赛需要两个参赛队伍,所以每个比赛都会有另一个版本,因为在这种比赛中参赛队伍一次是主队,一次是客队 。这只是污染我们的数据集,并没有提供任何值,因为行完全相同,所以我们想要删除任何其他版本并保留每场比赛的一个实例。为此,我们只需添加drop_duplicates()到数据集中以确保每个索引都是唯一的。

接下来,我们需要创建输出标签,用于在训练时确定模型权重的准确性,并测试最终算法的精度。我们可以通过创建一个仅包含home和away点的两列向量来生成我们的标签,并将结果设置为y。

最后,通常的做法是将数据集拆分为训练和测试子集,以确保训练后的模型是准确的。理想情况下,我们希望使用大约75%的数据集进行训练,并保留剩余的25%进行测试。应随机采用这些子集以防止模型偏向于特定的信息集。在使用训练数据集训练模型之后,应该针对测试数据集运行模型以确定模型的预测性能并查看其是否过度拟合。

幸运的是,sklearn有一个内置函数,可以为我们创建这些子集。通过将我们的X和y输入train_test_split,我们能够检索具有预期拆分的训练和测试子集。

创建和训练模型

parameters = {'bootstrap': False, 'min_samples_leaf': 3, 'n_estimators': 50, 'min_samples_split': 10, 'max_features': 'sqrt', 'max_depth': 6}model = RandomForestRegressor(**parameters)model.fit(X_train, y_train)

现在我们的数据集已经处理完毕,是时候创建和训练我们的模型了。我决定在这个例子中使用一个随机森林回归器,因为与标准决策树相比,该算法的易用性和相对准确性,以及它在减少过度拟合方面的良好处理,使其易于使用。随机森林算法创建多个决策树,并将随机性注入到特征权重中。然后,这些决策树被组合以创建森林(因此是决策树的随机森林) ,该森林用于训练、验证或推断时的最终分析。该算法同时支持分类和回归,使其对各种应用程序非常灵活。

分类确定属于固定数量类别的输出标签,例如学生在测试中收到的字母等级(“A”,“B”,“C”,“D”或“F”)。只能有五个类别(或分类),因此模型只会尝试将输出放入这五个类别中的一个。另一方面,回归决定了输出标签可能具有不确定范围的值,例如房价。虽然房价往往会有一系列标准房价,但房价没有限制,任何正数都是有效的。由于篮球比赛的最终得分在技术上可以是任何正数(或零!),我们希望使用回归。

在我们构建和训练模型之前,我们首先需要设置一些超参数。超参数是在训练之前输入到模型的参数,并且影响它的构建和优化方式。对于机器和深度学习领域的大多数初学者来说,这些参数往往是最大的障碍,因为这些设置通常没有“完美”的价值,如果有的话,它可能会让人难以确定应该放什么。

一般的经验法则是坚持使用这些超参数的默认值,然后一旦模型被训练并完成,并且您能够测试它,就开始使用反复试验方法调整值,直到您满意为止。对于我们的模型,我选择了六个不同的超参数,并找到了这组特定的值,以提供性能和准确性之间的最佳平衡。

在选择超参数之后,终于可以创建我们的模型了。首先,我们需要实例化之前导入的RandomForestRegressor类并包含我们的超参数。通过使用(**parameters),我们将字典的键值对扩展为类的命名参数,该参数在功能上与以下内容相同:

model = RandomForestRegressor(bootstrap=False, min_samples_leaf=3, ... max_depth=6)

现在我们的模型已经实例化了,剩下的就是训练它。通过包含RandomForestRegressor的fit方法,sklearn使这一点变得非常简单,因此我们只需要用输入特征和相应的输出标签运行它。这个方法运行在适当的位置,所以我们的模型变量现在将自动指向一个经过训练的模型,我们可以使用它进行预测!

输出结果

print(model.predict(X_test).astype(int), y_test)

我们的应用程序的最后一步是针对我们的测试子集运行预测,并将它们与我们的预期结果进行比较。

运行应用程序

最后,我们一直在等待的那一刻!我们的应用程序现已完成,我们剩下的就是运行算法。

请注意,该程序可能需要很长时间才能完成,因为大部分处理时间用于为Division-I College Basketball中的所有350多个团队构建数据集。如果您只是希望看到一个有效的算法,您可以通过在数据连接行之后的第一个循环中添加break语句来尽早停止数据创建。

一旦程序完成,它将输出类似于以下内容的东西(我减少了行数以节省空间):

(array([[86, 86], [71, 71], [78, 77], [74, 72], [90, 81], ... [52, 66], [68, 65]]),array([[ 83, 89], [ 71, 73], [ 80, 76], [ 77, 72], [ 92, 84], ... [ 46, 73], [ 66, 65]]))
ead5ff99cb394dc4b5cf3997e578d945

此输出包含两个部分:预测输出和预期输出。从array([[86, 86]到[68, 65]])是预测的输出,同时array([[83, 89]到[66, 65]])为实际的数据。如前所述,第一列指的是主队的的预期得分,第二列是主队的预计得分。

预测输出中的行也与预期输出中的行匹配,因此[86, 86]与[83, 89]相关等等。如果我们比较列表,我们会发现我们的预测并不太糟糕!在大多数情况下,预计得分仅与实际结果相差几分。

fbc3aaaa-a527-429e-b117-82f8325de5cb
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值