Python 中的逻辑回归 - 快速指南
Python 中的逻辑回归 - 简介
逻辑回归是一种对象分类的统计方法。本章将通过一些示例介绍逻辑回归。
分类
要理解逻辑回归,您应该知道分类的含义。让我们考虑以下示例以更好地理解这一点 -
- 医生将肿瘤分类为恶性或良性。
- 银行交易可能是欺诈性的,也可能是真实的。
多年来,人类一直在执行此类任务——尽管它们很容易出错。问题是我们能否训练机器更准确地为我们完成这些任务?
进行分类的机器的一个例子是您机器上的电子邮件客户端,它将每封传入的邮件分类为“垃圾邮件”或“非垃圾邮件”,并且它的准确度相当高。逻辑回归统计技术已成功应用于电子邮件客户端。在本例中,我们训练了机器来解决分类问题。
逻辑回归只是用于解决此类二元分类问题的机器学习的一部分。还有其他几种机器学习技术已经开发出来并在实践中用于解决其他类型的问题。
如果您已经注意到,在上述所有示例中,谓词的结果只有两个值 - 是或否。我们将它们称为类 - 也就是说,我们的分类器将对象分为两个类。用技术术语来说,我们可以说结果或目标变量本质上是二分的。
还有其他分类问题,其中输出可能被分为两个以上的类。例如,给定一个装满水果的篮子,要求您将不同种类的水果分开。现在,篮子可能包含橙子、苹果、芒果等。因此,当您将水果分开时,您将它们分为两类以上。这是一个多变量分类问题。
Python 中的逻辑回归 - 案例研究
假设一家银行要求您开发一个机器学习应用程序,该应用程序将帮助他们识别将向他们开立定期存款(某些银行也称为定期存款)的潜在客户。银行定期通过电话或网络形式进行调查,收集潜在客户的信息。这项调查本质上是一般性的,是针对大量受众进行的,其中许多人可能对与这家银行本身打交道不感兴趣。在其余的人中,只有少数人可能有兴趣开立定期存款。其他人可能对银行提供的其他设施感兴趣。因此,调查不一定是为了识别开设 TD 的客户。您的任务是从银行将与您分享的海量调查数据中找出所有最有可能开通 TD 的客户。
幸运的是,对于那些渴望开发机器学习模型的人来说,这样一种数据是公开可用的。该数据是由加州大学欧文分校的一些学生在外部资助下准备的。该数据库作为UCI 机器学习存储库的一部分提供,并被世界各地的学生、教育工作者和研究人员广泛使用。数据可以从这里下载。
在接下来的章节中,让我们使用相同的数据执行应用程序开发。
建立项目
在本章中,我们将详细了解建立一个项目以在 Python 中执行逻辑回归的过程。
安装 Jupyter
我们将使用 Jupyter——使用最广泛的机器学习平台之一。如果您的计算机上没有安装 Jupyter,请从此处下载。对于安装,您可以按照其网站上的说明来安装该平台。正如该网站所建议的,您可能更喜欢使用Anaconda Distribution,它附带 Python 和许多用于科学计算和数据科学的常用 Python 包。这将减少单独安装这些软件包的需要。
成功安装 Jupyter 后,启动一个新项目,此阶段的屏幕将如下所示,准备接受您的代码。
现在,通过单击标题名称并进行编辑,将项目名称从Untitled1 更改为“Logistic Regression” 。
首先,我们将导入代码中需要的几个 Python 包。
导入Python包
为此,请在代码编辑器中键入或剪切并粘贴以下代码 -
In [1]: # import statements import pandas as pd import numpy as np import matplotlib.pyplot as plt from sklearn import preprocessing from sklearn.linear_model import LogisticRegression from sklearn.model_selection import train_test_split
在此阶段,您的笔记本应如下所示 -
单击“运行”按钮运行代码。如果没有生成错误,则您已成功安装 Jupyter,现在可以进行其余的开发。
前三个 import 语句导入我们项目中的 pandas、numpy 和 matplotlib.pyplot 包。接下来的三个语句从 sklearn 导入指定的模块。
我们的下一个任务是下载项目所需的数据。我们将在下一章中学习这一点。
Python 中的逻辑回归 - 获取数据
本章详细讨论了获取数据以在 Python 中执行逻辑回归所涉及的步骤。
下载数据集
如果您尚未下载前面提到的 UCI 数据集,请立即从此处下载。单击数据文件夹。您将看到以下屏幕 -
单击给定的链接下载bank.zip 文件。zip 文件包含以下文件 -
我们将使用bank.csv 文件进行模型开发。Bank-names.txt 文件包含您稍后需要的数据库的描述。bank-full.csv 包含一个更大的数据集,您可以将其用于更高级的开发。
这里,我们已将bank.csv 文件包含在可下载的源zip 中。该文件包含逗号分隔的字段。我们还对该文件进行了一些修改。建议您使用项目源 zip 中包含的文件进行学习。
加载数据中
要从刚刚复制的 csv 文件加载数据,请键入以下语句并运行代码。
In [2]: df = pd.read_csv('bank.csv', header=0)
您还可以通过运行以下代码语句来检查加载的数据 -
IN [3]: df.head()
运行命令后,您将看到以下输出 -
基本上,它已经打印了加载数据的前五行。检查存在的 21 列。我们将仅使用其中的几列来进行模型开发。
接下来,我们需要清理数据。数据可能包含一些带有NaN的行。要消除此类行,请使用以下命令 -
IN [4]: df = df.dropna()
幸运的是,bank.csv 不包含任何带有 NaN 的行,因此在我们的示例中并不真正需要此步骤。然而,一般来说,在巨大的数据库中很难发现这样的行。因此,运行上述语句来清理数据总是更安全。
注意- 您可以使用以下语句轻松检查任意时间点的数据大小 -
IN [5]: print (df.shape) (41188, 21)
行数和列数将打印在输出中,如上面第二行所示。
接下来要做的事情是检查每一列对于我们正在尝试构建的模型的适用性。
Python 中的逻辑回归 - 重构数据
每当任何组织进行调查时,他们都会尝试从客户那里收集尽可能多的信息,并认为这些信息在以后的某个时间点无论如何都会对组织有用。为了解决当前的问题,我们必须选取与我们的问题直接相关的信息。
显示所有字段
现在,让我们看看如何选择对我们有用的数据字段。在代码编辑器中运行以下语句。
In [6]: print(list(df.columns))
您将看到以下输出 -
['age', 'job', 'marital', 'education', 'default', 'housing', 'loan', 'contact', 'month', 'day_of_week', 'duration', 'campaign', 'pdays', 'previous', 'poutcome', 'emp_var_rate', 'cons_price_idx', 'cons_conf_idx', 'euribor3m', 'nr_employed', 'y']
输出显示数据库中所有列的名称。最后一列“y”是一个布尔值,指示该客户是否在银行有定期存款。该字段的值为“y”或“n”。您可以在作为数据一部分下载的banks-name.txt 文件中阅读每列的描述和用途。
消除不需要的字段
检查列名,您会知道某些字段对于当前的问题没有任何意义。例如,月份、星期几、活动等字段对我们来说没有用处。我们将从数据库中删除这些字段。要删除列,我们使用 drop 命令,如下所示 -
In [8]: #drop columns which are not needed. df.drop(df.columns[[0, 3, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19]], axis = 1, inplace = True)
该命令表示删除列号 0、3、7、8 等。为了确保正确选择索引,请使用以下语句 -
In [7]: df.columns[9] Out[7]: 'day_of_week'
这将打印给定索引的列名称。
删除不需要的列后,使用 head 语句检查数据。屏幕输出如下所示 -
In [9]: df.head() Out[9]: job marital default housing loan poutcome y 0 blue-collar married unknown yes no nonexistent 0 1 technician married no no no nonexistent 0 2 management single no yes no success 1 3 services married no no no nonexistent 0 4 retired married no yes no success 1
现在,我们只有我们认为对数据分析和预测重要的字段。数据科学家的重要性在这一步就显现出来了。数据科学家必须选择适当的列来构建模型。
例如,工作类型虽然乍一看可能无法说服每个人都将其包含在数据库中,但它将是一个非常有用的字段。并不是所有类型的客户都会开通TD。低收入人群可能不会开设 TD,而高收入人群通常会将多余的资金存入 TD。因此,工作类型在这种情况下变得非常重要。同样,仔细选择您认为与您的分析相关的列。
在下一章中,我们将准备用于构建模型的数据。
Python 中的逻辑回归 - 准备数据
为了创建分类器,我们必须按照分类器构建模块要求的格式准备数据。我们通过进行One Hot Encoding来准备数据。
编码数据
我们将很快讨论数据编码的含义。首先,让我们运行代码。在代码窗口中运行以下命令。
In [10]: # creating one hot encoding of the categorical columns. data = pd.get_dummies(df, columns =['job', 'marital', 'default', 'housing', 'loan', 'poutcome'])
正如评论所说,上述语句将创建数据的唯一热编码。让我们看看它创造了什么?通过打印数据库中的头记录来检查创建的称为“数据”的数据。
In [11]: data.head()
您将看到以下输出 -
为了理解上述数据,我们将通过运行data.columns命令列出列名称,如下所示 -
In [12]: data.columns Out[12]: Index(['y', 'job_admin.', 'job_blue-collar', 'job_entrepreneur', 'job_housemaid', 'job_management', 'job_retired', 'job_self-employed', 'job_services', 'job_student', 'job_technician', 'job_unemployed', 'job_unknown', 'marital_divorced', 'marital_married', 'marital_single', 'marital_unknown', 'default_no', 'default_unknown', 'default_yes', 'housing_no', 'housing_unknown', 'housing_yes', 'loan_no', 'loan_unknown', 'loan_yes', 'poutcome_failure', 'poutcome_nonexistent', 'poutcome_success'], dtype='object')
现在,我们将解释get_dummies命令如何完成单热编码。新生成的数据库中的第一列是“y”字段,指示该客户端是否订阅了TD。现在,让我们看看编码的列。第一个编码列是“job”。在数据库中,你会发现“job”列有很多可能的值,例如“admin”、“blue-collar”、“entrepreneur”等等。对于每个可能的值,我们在数据库中创建一个新列,并附加列名称作为前缀。
因此,我们有名为“job_admin”、“job_blue-collar”等的列。对于原始数据库中的每个编码字段,您将找到在创建的数据库中添加的列列表,其中包含该列在原始数据库中采用的所有可能值。仔细检查列列表以了解数据如何映射到新数据库。
了解数据映射
为了理解生成的数据,让我们使用 data 命令打印出整个数据。运行命令后的部分输出如下所示。
In [13]: data
上面的屏幕显示前十二行。如果进一步向下滚动,您将看到所有行都已完成映射。
此处显示了数据库下方的部分屏幕输出,以供您快速参考。
为了理解映射的数据,让我们检查第一行。
它表示该客户尚未订阅 TD,如“y”字段中的值所示。这也表明该客户是“蓝领”客户。水平向下滚动,会告诉你他有“住房”,没有借过“贷款”。
经过这一热编码后,我们需要进行更多的数据处理,然后才能开始构建模型。
抛开“未知”
如果我们检查映射数据库中的列,您会发现存在少数以“unknown”结尾的列。例如,使用屏幕截图中显示的以下命令检查索引 12 处的列 -
In [14]: data.columns[12] Out[14]: 'job_unknown'
这表明指定客户的工作未知。显然,在我们的分析和模型构建中包含这些列是没有意义的。因此,应删除所有具有“未知”值的列。这是通过以下命令完成的 -
In [15]: data.drop(data.columns[[12, 16, 18, 21, 24]], axis=1, inplace=True)
确保指定正确的列号。如有疑问,您可以随时通过在 columns 命令中指定其索引来检查列名称,如前所述。
删除不需要的列后,您可以检查最终的列列表,如下面的输出所示 -
In [16]: data.columns Out[16]: Index(['y', 'job_admin.', 'job_blue-collar', 'job_entrepreneur', 'job_housemaid', 'job_management', 'job_retired', 'job_self-employed', 'job_services', 'job_student', 'job_technician', 'job_unemployed', 'marital_divorced', 'marital_married', 'marital_single', 'default_no', 'default_yes', 'housing_no', 'housing_yes', 'loan_no', 'loan_yes', 'poutcome_failure', 'poutcome_nonexistent', 'poutcome_success'], dtype='object')
此时,我们的数据已准备好用于模型构建。
Python 中的逻辑回归 - 分割数据
我们大约有四万一千多条记录。如果我们使用全部数据来构建模型,我们将不会留下任何数据用于测试。所以一般来说,我们将整个数据集分成两部分,比如 70/30 的百分比。我们使用 70% 的数据进行模型构建,其余数据用于测试所创建模型的预测准确性。您可以根据您的要求使用不同的分光比。
创建特征数组
在分割数据之前,我们将数据分成两个数组 X 和 Y。X 数组包含我们要分析的所有特征(数据列),Y 数组是布尔值的一维数组,它是的预测。为了理解这一点,让我们运行一些代码。
首先,执行以下 Python 语句来创建 X 数组 -
In [17]: X = data.iloc[:,1:]
要检查X的内容,请使用head打印一些初始记录。以下屏幕显示 X 数组的内容。
In [18]: X.head ()
该阵列有几行和 23 列。
接下来,我们将创建包含“ y ”值的输出数组。
创建输出数组
要为预测值列创建数组,请使用以下 Python 语句 -
In [19]: Y = data.iloc[:,0]
通过调用head检查其内容。下面的屏幕输出显示了结果 -
In [20]: Y.head() Out[20]: 0 0 1 0 2 1 3 0 4 1 Name: y, dtype: int64
现在,使用以下命令分割数据 -
In [21]: X_train, X_test, Y_train, Y_test = train_test_split(X, Y, random_state=0)
这将创建名为X_train、Y_train、X_test 和 Y_test的四个数组。和以前一样,您可以使用 head 命令检查这些数组的内容。我们将使用 X_train 和 Y_train 数组来训练我们的模型,并使用 X_test 和 Y_test 数组来测试和验证。
现在,我们准备构建我们的分类器。我们将在下一章中研究它。
Python 中的逻辑回归 - 构建分类器
您不需要从头开始构建分类器。构建分类器很复杂,需要统计、概率论、优化技术等多个领域的知识。市场上有几个预构建的库,它们对这些分类器进行了充分测试且非常有效的实现。我们将使用sklearn中的一个这样的预构建模型。
sklearn 分类器
从 sklearn 工具包创建逻辑回归分类器很简单,并且在单个程序语句中完成,如下所示 -
In [22]: classifier = LogisticRegression(solver='lbfgs',random_state=0)
创建分类器后,您将把训练数据输入分类器,以便它可以调整其内部参数并为未来数据的预测做好准备。为了调整分类器,我们运行以下语句 -
In [23]: classifier.fit(X_train, Y_train)
分类器现在已准备好进行测试。以下代码是上述两条语句的执行输出 -
Out[23]: LogisticRegression(C = 1.0, class_weight = None, dual = False, fit_intercept=True, intercept_scaling=1, max_iter=100, multi_class='warn', n_jobs=None, penalty='l2', random_state=0, solver='lbfgs', tol=0.0001, verbose=0, warm_start=False))
现在,我们准备测试创建的分类器。我们将在下一章讨论这个问题。
Python 中的逻辑回归 - 测试
在将上面创建的分类器投入生产使用之前,我们需要对其进行测试。如果测试表明模型没有达到所需的精度,我们将不得不返回上述过程,选择另一组特征(数据字段),重新构建模型并进行测试。这将是一个迭代步骤,直到分类器满足您所需的精度要求。那么让我们测试我们的分类器。
预测测试数据
为了测试分类器,我们使用前期生成的测试数据。我们在创建的对象上调用预测方法并传递测试数据的X数组,如以下命令所示 -
In [24]: predicted_y = classifier.predict(X_test)
这会为整个训练数据集生成一个一维数组,给出 X 数组中每一行的预测。您可以使用以下命令检查该数组 -
In [25]: predicted_y
以下是执行上述两个命令时的输出 -
Out[25]: array([0, 0, 0, ..., 0, 0, 0])
输出表明前三个客户不是定期存款的潜在候选者。您可以检查整个阵列来筛选潜在客户。为此,请使用以下 Python 代码片段 -
In [26]: for x in range(len(predicted_y)): if (predicted_y[x] == 1): print(x, end="\t")
运行上述代码的输出如下所示 -
输出显示可能订阅 TD 的所有行的索引。现在,您可以将此输出提供给银行的营销团队,他们将获取所选行中每个客户的联系详细信息并继续他们的工作。
在将该模型投入生产之前,我们需要验证预测的准确性。
验证准确性
为了测试模型的准确性,请在分类器上使用评分方法,如下所示 -
In [27]: print('Accuracy: {:.2f}'.format(classifier.score(X_test, Y_test)))
运行此命令的屏幕输出如下所示 -
Accuracy: 0.90
它表明我们的模型的准确率为 90%,这在大多数应用中都被认为是非常好的。因此,不需要进一步调整。现在,我们的客户已准备好开展下一个活动,获取潜在客户名单并追赶他们开通 TD,成功率可能很高。
Python 中的逻辑回归 - 限制
正如您从上面的示例中看到的,将逻辑回归应用于机器学习并不是一项艰巨的任务。然而,它也有其自身的局限性。逻辑回归将无法处理大量分类特征。在我们到目前为止讨论的示例中,我们很大程度上减少了特征数量。
然而,如果这些特征对我们的预测很重要,我们将被迫将它们包括在内,但逻辑回归将无法为我们提供良好的准确性。逻辑回归也容易出现过度拟合。它不能应用于非线性问题。对于与目标不相关但彼此相关的自变量,它的表现会很差。因此,您必须仔细评估逻辑回归对您要解决的问题的适用性。
机器学习的许多领域都指定了其他技术。仅举几例,我们有 k 最近邻 (kNN)、线性回归、支持向量机 (SVM)、决策树、朴素贝叶斯等算法。在最终确定特定模型之前,您必须评估这些不同技术对我们试图解决的问题的适用性。
Python 中的逻辑回归 - 总结
逻辑回归是一种二元分类的统计技术。在本教程中,您学习了如何训练机器使用逻辑回归。创建机器学习模型,最重要的要求是数据的可用性。如果没有足够的相关数据,你就无法简单地让机器学习。
获得数据后,下一个主要任务是清理数据,消除不需要的行、字段,并为模型开发选择适当的字段。完成此操作后,您需要将数据映射为分类器训练所需的格式。因此,数据准备是任何机器学习应用程序中的一项主要任务。准备好数据后,您可以选择特定类型的分类器。
在本教程中,您学习了如何使用sklearn库中提供的逻辑回归分类器。为了训练分类器,我们使用大约 70% 的数据来训练模型。我们使用其余数据进行测试。我们测试模型的准确性。如果这不在可接受的范围内,我们将返回选择新的功能集。
再次遵循准备数据、训练模型并测试的整个过程,直到您对其准确性感到满意为止。在开始任何机器学习项目之前,您必须学习并接触迄今为止已开发并已在行业中成功应用的各种技术。