Machine-Learning-Mastery-Sklearn-教程-九-

72 阅读1小时+

Machine Learning Mastery Sklearn 教程(九)

原文:Machine Learning Mastery

协议:CC BY-NC-SA 4.0

Python 中机器学习的稳健回归

原文:machinelearningmastery.com/robust-regr…

回归是一项建模任务,包括预测给定输入的数值。

用于回归任务的算法也被称为“回归”算法,其中最广为人知且可能最成功的是线性回归。

线性回归适合最能描述输入和目标数值之间线性关系的直线或超平面。如果数据包含异常值,该线可能会出现偏差,从而导致更差的预测表现。稳健回归是指在训练数据中存在异常值时稳健的一套算法。

在本教程中,您将发现用于机器学习的稳健回归算法。

完成本教程后,您将知道:

  • 稳健回归算法可用于输入值或目标值中有异常值的数据。
  • 如何评估回归预测建模任务的稳健回归算法?
  • 如何使用数据集上的最佳拟合线比较稳健回归算法?

我们开始吧。

Robust Regression for Machine Learning in Python

Python 中机器学习的稳健回归 图片由 Lenny K 摄影提供,保留部分权利。

教程概述

本教程分为四个部分;它们是:

  1. 异常值回归
  2. 具有异常值的回归数据集
  3. 稳健回归算法
  4. 比较稳健回归算法

异常值回归

回归预测建模包括预测给定一些输入的数值变量,通常是数值输入。

用于回归预测建模任务的机器学习算法也称为“回归”或“回归算法”最常用的方法是线性回归

许多回归算法是线性的,因为它们假设输入变量和目标变量之间的关系是线性的,例如二维的直线、三维的平面和高维的超平面。对于许多预测任务来说,这是一个合理的假设。

线性回归假设每个变量的概率分布表现良好,如具有高斯分布。数据集中某个特征的概率分布表现越差,线性回归找到良好拟合的可能性就越小。

使用线性回归时变量概率分布的一个具体问题是异常值。这些观测值远远超出了预期分布。例如,如果一个变量具有高斯分布,那么与平均值有 3 或 4(或更多)个标准差的观测值被认为是异常值。

数据集可能在输入变量或目标变量上有异常值,这两者都会给线性回归算法带来问题。

数据集中的异常值会扭曲为变量计算的汇总统计数据,例如平均值和标准偏差,这反过来会使模型偏离观测值的中心。这导致模型试图平衡在异常值和正常数据上表现良好,而在整体上表现较差。

相反,解决方案是使用线性回归的修改版本,专门解决数据集中异常值的预期。这些方法被称为稳健回归算法

具有异常值的回归数据集

我们可以使用make _ revolution()函数定义一个合成回归数据集。

在这种情况下,我们需要一个易于绘制和理解的数据集。这可以通过使用单个输入变量和单个输出变量来实现。我们不希望任务太容易,所以我们会添加大量的统计噪声。

...
X, y = make_regression(n_samples=100, n_features=1, tail_strength=0.9, effective_rank=1, n_informative=1, noise=3, bias=50, random_state=1)

一旦我们有了数据集,我们就可以通过增加异常值来扩充它。具体来说,我们将向输入变量添加异常值。

这可以通过改变一些输入变量的值来实现,该值是偏离平均值的标准偏差数的因子,例如 2 到 4。我们将向数据集中添加 10 个异常值。

# add some artificial outliers
seed(1)
for i in range(10):
	factor = randint(2, 4)
	if random() > 0.5:
		X[i] += factor * X.std()
	else:
		X[i] -= factor * X.std()

我们可以将它绑定到一个准备数据集的函数中。然后可以调用这个函数,我们可以用 x 轴上的输入值和 y 轴上的目标或结果绘制数据集。

下面列出了准备和绘制数据集的完整示例。

# create a regression dataset with outliers
from random import random
from random import randint
from random import seed
from sklearn.datasets import make_regression
from matplotlib import pyplot

# prepare the dataset
def get_dataset():
	X, y = make_regression(n_samples=100, n_features=1, tail_strength=0.9, effective_rank=1, n_informative=1, noise=3, bias=50, random_state=1)
	# add some artificial outliers
	seed(1)
	for i in range(10):
		factor = randint(2, 4)
		if random() > 0.5:
			X[i] += factor * X.std()
		else:
			X[i] -= factor * X.std()
	return X, y

# load dataset
X, y = get_dataset()
# summarize shape
print(X.shape, y.shape)
# scatter plot of input vs output
pyplot.scatter(X, y)
pyplot.show()

运行该示例会创建合成回归数据集并添加异常值。

然后绘制数据集,我们可以清楚地看到数据中的线性关系,带有统计噪声,少量异常值作为远离主要数据的点。

Scatter Plot of Regression Dataset With Outliers

具有异常值的回归数据集的散点图

现在我们有了数据集,让我们在上面拟合不同的回归模型。

稳健回归算法

在本节中,我们将考虑数据集的不同稳健回归算法。

线性回归(不稳健)

在深入研究稳健回归算法之前,让我们从线性回归开始。

我们可以在有异常值的回归数据集上使用重复 k 倍交叉验证来评估线性回归。我们将测量平均绝对误差,这将提供一个模型表现的下限,在这个任务中,我们可能会期望一些稳健的回归算法表现出色。

# evaluate a model
def evaluate_model(X, y, model):
	# define model evaluation method
	cv = RepeatedKFold(n_splits=10, n_repeats=3, random_state=1)
	# evaluate model
	scores = cross_val_score(model, X, y, scoring='neg_mean_absolute_error', cv=cv, n_jobs=-1)
	# force scores to be positive
	return absolute(scores)

我们还可以在数据集上绘制模型的最佳拟合线。为此,我们首先在整个训练数据集上拟合模型,然后创建一个跨整个输入域的网格输入数据集,对每个输入域进行预测,然后为输入和预测输出绘制一条线。

该图显示了模型“”如何看待”问题,特别是输入和输出变量之间的关系。这个想法是,当使用线性回归时,线会被异常值扭曲。

# plot the dataset and the model's line of best fit
def plot_best_fit(X, y, model):
	# fut the model on all data
	model.fit(X, y)
	# plot the dataset
	pyplot.scatter(X, y)
	# plot the line of best fit
	xaxis = arange(X.min(), X.max(), 0.01)
	yaxis = model.predict(xaxis.reshape((len(xaxis), 1)))
	pyplot.plot(xaxis, yaxis, color='r')
	# show the plot
	pyplot.title(type(model).__name__)
	pyplot.show()

将这些联系在一起,下面列出了线性回归的完整示例。

# linear regression on a dataset with outliers
from random import random
from random import randint
from random import seed
from numpy import arange
from numpy import mean
from numpy import std
from numpy import absolute
from sklearn.datasets import make_regression
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import RepeatedKFold
from matplotlib import pyplot

# prepare the dataset
def get_dataset():
	X, y = make_regression(n_samples=100, n_features=1, tail_strength=0.9, effective_rank=1, n_informative=1, noise=3, bias=50, random_state=1)
	# add some artificial outliers
	seed(1)
	for i in range(10):
		factor = randint(2, 4)
		if random() > 0.5:
			X[i] += factor * X.std()
		else:
			X[i] -= factor * X.std()
	return X, y

# evaluate a model
def evaluate_model(X, y, model):
	# define model evaluation method
	cv = RepeatedKFold(n_splits=10, n_repeats=3, random_state=1)
	# evaluate model
	scores = cross_val_score(model, X, y, scoring='neg_mean_absolute_error', cv=cv, n_jobs=-1)
	# force scores to be positive
	return absolute(scores)

# plot the dataset and the model's line of best fit
def plot_best_fit(X, y, model):
	# fut the model on all data
	model.fit(X, y)
	# plot the dataset
	pyplot.scatter(X, y)
	# plot the line of best fit
	xaxis = arange(X.min(), X.max(), 0.01)
	yaxis = model.predict(xaxis.reshape((len(xaxis), 1)))
	pyplot.plot(xaxis, yaxis, color='r')
	# show the plot
	pyplot.title(type(model).__name__)
	pyplot.show()

# load dataset
X, y = get_dataset()
# define the model
model = LinearRegression()
# evaluate model
results = evaluate_model(X, y, model)
print('Mean MAE: %.3f (%.3f)' % (mean(results), std(results)))
# plot the line of best fit
plot_best_fit(X, y, model)

运行该示例首先报告数据集上模型的平均 MAE。

我们可以看到,线性回归在这个数据集上实现了大约 5.2 的 MAE,提供了误差的上限。

Mean MAE: 5.260 (1.149)

接下来,数据集被绘制为显示异常值的散点图,并用线性回归算法的最佳拟合线覆盖。

在这种情况下,我们可以看到最佳拟合线没有与数据对齐,并且被异常值扭曲。反过来,我们预计这将导致模型在数据集上的表现比预期的要差。

Line of Best Fit for Linear Regression on a Dataset with Outliers

异常数据集中线性回归的最佳拟合线

胡伯回归

Huber 回归是一种稳健回归,它知道数据集中出现异常值的可能性,并赋予它们比数据集中其他示例更小的权重。

我们可以通过 Sklearn 中的【Huber 回归器类使用 Huber 回归。“ε参数控制什么被认为是异常值,其中较小的值考虑更多的数据异常值,反过来,使模型对异常值更加稳健。默认值为 1.35。

下面的示例评估具有异常值的回归数据集上的 Huber 回归,首先使用重复交叉验证评估模型,然后绘制最佳拟合线。

# huber regression on a dataset with outliers
from random import random
from random import randint
from random import seed
from numpy import arange
from numpy import mean
from numpy import std
from numpy import absolute
from sklearn.datasets import make_regression
from sklearn.linear_model import HuberRegressor
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import RepeatedKFold
from matplotlib import pyplot

# prepare the dataset
def get_dataset():
	X, y = make_regression(n_samples=100, n_features=1, tail_strength=0.9, effective_rank=1, n_informative=1, noise=3, bias=50, random_state=1)
	# add some artificial outliers
	seed(1)
	for i in range(10):
		factor = randint(2, 4)
		if random() > 0.5:
			X[i] += factor * X.std()
		else:
			X[i] -= factor * X.std()
	return X, y

# evaluate a model
def evaluate_model(X, y, model):
	# define model evaluation method
	cv = RepeatedKFold(n_splits=10, n_repeats=3, random_state=1)
	# evaluate model
	scores = cross_val_score(model, X, y, scoring='neg_mean_absolute_error', cv=cv, n_jobs=-1)
	# force scores to be positive
	return absolute(scores)

# plot the dataset and the model's line of best fit
def plot_best_fit(X, y, model):
	# fut the model on all data
	model.fit(X, y)
	# plot the dataset
	pyplot.scatter(X, y)
	# plot the line of best fit
	xaxis = arange(X.min(), X.max(), 0.01)
	yaxis = model.predict(xaxis.reshape((len(xaxis), 1)))
	pyplot.plot(xaxis, yaxis, color='r')
	# show the plot
	pyplot.title(type(model).__name__)
	pyplot.show()

# load dataset
X, y = get_dataset()
# define the model
model = HuberRegressor()
# evaluate model
results = evaluate_model(X, y, model)
print('Mean MAE: %.3f (%.3f)' % (mean(results), std(results)))
# plot the line of best fit
plot_best_fit(X, y, model)

运行该示例首先报告数据集上模型的平均 MAE。

我们可以看到 Huber 回归在这个数据集上实现了大约 4.435 的 MAE,优于上一节中的线性回归模型。

Mean MAE: 4.435 (1.868)

接下来,数据集被绘制为显示异常值的散点图,并覆盖算法的最佳拟合线。

在这种情况下,我们可以看到最佳拟合线更好地与数据的主体对齐,并且似乎不受存在的异常值的明显影响。

Line of Best Fit for Huber Regression on a Dataset with Outliers

异常数据集上 Huber 回归的最佳拟合线

RANSAC 回归

随机样本一致性,简称 RANSAC,是另一种稳健的回归算法。

RANSAC 试图将数据分为离群值和内联值,并在内联值上拟合模型。

Sklearn 库通过transacruler类提供了一个实现。

下面的示例在具有异常值的回归数据集上评估 RANSAC 回归,首先通过重复交叉验证评估模型,然后绘制最佳拟合线。

# ransac regression on a dataset with outliers
from random import random
from random import randint
from random import seed
from numpy import arange
from numpy import mean
from numpy import std
from numpy import absolute
from sklearn.datasets import make_regression
from sklearn.linear_model import RANSACRegressor
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import RepeatedKFold
from matplotlib import pyplot

# prepare the dataset
def get_dataset():
	X, y = make_regression(n_samples=100, n_features=1, tail_strength=0.9, effective_rank=1, n_informative=1, noise=3, bias=50, random_state=1)
	# add some artificial outliers
	seed(1)
	for i in range(10):
		factor = randint(2, 4)
		if random() > 0.5:
			X[i] += factor * X.std()
		else:
			X[i] -= factor * X.std()
	return X, y

# evaluate a model
def evaluate_model(X, y, model):
	# define model evaluation method
	cv = RepeatedKFold(n_splits=10, n_repeats=3, random_state=1)
	# evaluate model
	scores = cross_val_score(model, X, y, scoring='neg_mean_absolute_error', cv=cv, n_jobs=-1)
	# force scores to be positive
	return absolute(scores)

# plot the dataset and the model's line of best fit
def plot_best_fit(X, y, model):
	# fut the model on all data
	model.fit(X, y)
	# plot the dataset
	pyplot.scatter(X, y)
	# plot the line of best fit
	xaxis = arange(X.min(), X.max(), 0.01)
	yaxis = model.predict(xaxis.reshape((len(xaxis), 1)))
	pyplot.plot(xaxis, yaxis, color='r')
	# show the plot
	pyplot.title(type(model).__name__)
	pyplot.show()

# load dataset
X, y = get_dataset()
# define the model
model = RANSACRegressor()
# evaluate model
results = evaluate_model(X, y, model)
print('Mean MAE: %.3f (%.3f)' % (mean(results), std(results)))
# plot the line of best fit
plot_best_fit(X, y, model)

运行该示例首先报告数据集上模型的平均 MAE。

我们可以看到,RANSAC 回归在这个数据集上实现了大约 4.454 的 MAE,优于线性回归模型,但可能不是 Huber 回归。

Mean MAE: 4.454 (2.165)

接下来,数据集被绘制为显示异常值的散点图,并覆盖算法的最佳拟合线。

在这种情况下,我们可以看到最佳拟合线与数据主体对齐,甚至可能比 Huber 回归的图更好。

Line of Best Fit for RANSAC Regression on a Dataset with Outliers

异常数据集上 RANSAC 回归的最佳拟合线

泰尔森回归

泰尔森回归包括在训练数据的子集上拟合多个回归模型,最后将系数组合在一起。

Sklearn 通过类提供了一个实现。

下面的示例在具有异常值的回归数据集上评估泰尔森回归,首先通过重复交叉验证评估模型,然后绘制最佳拟合线。

# theilsen regression on a dataset with outliers
from random import random
from random import randint
from random import seed
from numpy import arange
from numpy import mean
from numpy import std
from numpy import absolute
from sklearn.datasets import make_regression
from sklearn.linear_model import TheilSenRegressor
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import RepeatedKFold
from matplotlib import pyplot

# prepare the dataset
def get_dataset():
	X, y = make_regression(n_samples=100, n_features=1, tail_strength=0.9, effective_rank=1, n_informative=1, noise=3, bias=50, random_state=1)
	# add some artificial outliers
	seed(1)
	for i in range(10):
		factor = randint(2, 4)
		if random() > 0.5:
			X[i] += factor * X.std()
		else:
			X[i] -= factor * X.std()
	return X, y

# evaluate a model
def evaluate_model(X, y, model):
	# define model evaluation method
	cv = RepeatedKFold(n_splits=10, n_repeats=3, random_state=1)
	# evaluate model
	scores = cross_val_score(model, X, y, scoring='neg_mean_absolute_error', cv=cv, n_jobs=-1)
	# force scores to be positive
	return absolute(scores)

# plot the dataset and the model's line of best fit
def plot_best_fit(X, y, model):
	# fut the model on all data
	model.fit(X, y)
	# plot the dataset
	pyplot.scatter(X, y)
	# plot the line of best fit
	xaxis = arange(X.min(), X.max(), 0.01)
	yaxis = model.predict(xaxis.reshape((len(xaxis), 1)))
	pyplot.plot(xaxis, yaxis, color='r')
	# show the plot
	pyplot.title(type(model).__name__)
	pyplot.show()

# load dataset
X, y = get_dataset()
# define the model
model = TheilSenRegressor()
# evaluate model
results = evaluate_model(X, y, model)
print('Mean MAE: %.3f (%.3f)' % (mean(results), std(results)))
# plot the line of best fit
plot_best_fit(X, y, model)

运行该示例首先报告数据集上模型的平均 MAE。

我们可以看到,泰尔森回归在这个数据集上实现了大约 4.371 的 MAE,优于线性回归模型以及 RANSAC 和 Huber 回归。

Mean MAE: 4.371 (1.961)

接下来,数据集被绘制为显示异常值的散点图,并覆盖算法的最佳拟合线。

在这种情况下,我们可以看到最佳拟合线与数据主体对齐。

Line of Best Fit for Theil Sen Regression on a Dataset with Outliers

异常数据集上泰尔森回归的最佳拟合线

比较稳健回归算法

现在我们已经熟悉了一些流行的稳健回归算法以及如何使用它们,我们可以看看如何直接比较它们。

运行一个实验来直接比较同一数据集上的稳健回归算法可能是有用的。我们可以比较每种方法的平均表现,更有用的是,使用像方框图和触须图这样的工具来比较重复交叉验证折叠中的分数分布。

下面列出了完整的示例。

# compare robust regression algorithms on a regression dataset with outliers
from random import random
from random import randint
from random import seed
from numpy import mean
from numpy import std
from numpy import absolute
from sklearn.datasets import make_regression
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import RepeatedKFold
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import HuberRegressor
from sklearn.linear_model import RANSACRegressor
from sklearn.linear_model import TheilSenRegressor
from matplotlib import pyplot

# prepare the dataset
def get_dataset():
	X, y = make_regression(n_samples=100, n_features=1, tail_strength=0.9, effective_rank=1, n_informative=1, noise=3, bias=50, random_state=1)
	# add some artificial outliers
	seed(1)
	for i in range(10):
		factor = randint(2, 4)
		if random() > 0.5:
			X[i] += factor * X.std()
		else:
			X[i] -= factor * X.std()
	return X, y

# dictionary of model names and model objects
def get_models():
	models = dict()
	models['Linear'] = LinearRegression()
	models['Huber'] = HuberRegressor()
	models['RANSAC'] = RANSACRegressor()
	models['TheilSen'] = TheilSenRegressor()
	return models

# evaluate a model
def evalute_model(X, y, model, name):
	# define model evaluation method
	cv = RepeatedKFold(n_splits=10, n_repeats=3, random_state=1)
	# evaluate model
	scores = cross_val_score(model, X, y, scoring='neg_mean_absolute_error', cv=cv, n_jobs=-1)
	# force scores to be positive
	scores = absolute(scores)
	return scores

# load the dataset
X, y = get_dataset()
# retrieve models
models = get_models()
results = dict()
for name, model in models.items():
	# evaluate the model
	results[name] = evalute_model(X, y, model, name)
	# summarize progress
	print('>%s %.3f (%.3f)' % (name, mean(results[name]), std(results[name])))
# plot model performance for comparison
pyplot.boxplot(results.values(), labels=results.keys(), showmeans=True)
pyplot.show()

运行该示例依次评估每个模型,报告平均和标准偏差 MAE 分数。

注意:鉴于学习算法和评估程序的随机性,您的具体结果会有所不同。试着运行这个例子几次。

我们可以看到这些分数与上一节中报告的分数之间的一些微小差异,尽管这些差异可能具有统计学意义,也可能不具有统计学意义。稳健回归方法比线性回归表现更好的一般模式成立,lSen 比其他方法获得更好的表现。

>Linear 5.260 (1.149)
>Huber 4.435 (1.868)
>RANSAC 4.405 (2.206)
>TheilSen 4.371 (1.961)

创建了一个图表,显示了一个方框和触须图,总结了每个评估算法的结果分布。

我们可以清楚地看到稳健回归算法的分布低于线性回归算法。

Box and Whisker Plot of MAE Scores for Robust Regression Algorithms

稳健回归算法 MAE 分数的盒须图

比较基于最佳拟合线的稳健回归算法可能也很有趣。

下面的示例适合每种稳健回归算法,并在整个训练数据集散点图的上下文中,在同一图上绘制它们的最佳拟合线。

# plot line of best for multiple robust regression algorithms
from random import random
from random import randint
from random import seed
from numpy import arange
from sklearn.datasets import make_regression
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import HuberRegressor
from sklearn.linear_model import RANSACRegressor
from sklearn.linear_model import TheilSenRegressor
from matplotlib import pyplot

# prepare the dataset
def get_dataset():
	X, y = make_regression(n_samples=100, n_features=1, tail_strength=0.9, effective_rank=1, n_informative=1, noise=3, bias=50, random_state=1)
	# add some artificial outliers
	seed(1)
	for i in range(10):
		factor = randint(2, 4)
		if random() > 0.5:
			X[i] += factor * X.std()
		else:
			X[i] -= factor * X.std()
	return X, y

# dictionary of model names and model objects
def get_models():
	models = list()
	models.append(LinearRegression())
	models.append(HuberRegressor())
	models.append(RANSACRegressor())
	models.append(TheilSenRegressor())
	return models

# plot the dataset and the model's line of best fit
def plot_best_fit(X, y, xaxis, model):
	# fit the model on all data
	model.fit(X, y)
	# calculate outputs for grid across the domain
	yaxis = model.predict(xaxis.reshape((len(xaxis), 1)))
	# plot the line of best fit
	pyplot.plot(xaxis, yaxis, label=type(model).__name__)

# load the dataset
X, y = get_dataset()
# define a uniform grid across the input domain
xaxis = arange(X.min(), X.max(), 0.01)
for model in get_models():
	# plot the line of best fit
	plot_best_fit(X, y, xaxis, model)
# plot the dataset
pyplot.scatter(X, y)
# show the plot
pyplot.title('Robust Regression')
pyplot.legend()
pyplot.show()

运行该示例会创建一个图,将数据集显示为散点图以及每种算法的最佳拟合线。

我们可以清楚地看到线性回归算法的离轴线,以及遵循数据主体的稳健回归算法的更好的线。

Comparison of Robust Regression Algorithms Line of Best Fit

最佳拟合线稳健回归算法的比较

进一步阅读

如果您想更深入地了解这个主题,本节将提供更多资源。

蜜蜂

文章

摘要

在本教程中,您发现了机器学习的稳健回归算法。

具体来说,您了解到:

  • 稳健回归算法可用于输入值或目标值中有异常值的数据。
  • 如何评估回归预测建模任务的稳健回归算法?
  • 如何使用数据集上的最佳拟合线比较稳健回归算法?

你有什么问题吗? 在下面的评论中提问,我会尽力回答。

如何以及何时在 Python 中对分类使用 ROC 曲线和精确召回曲线

原文: machinelearningmastery.com/roc-curves-and-precision-recall-curves-for-classification-in-python/

可以更灵活地预测属于分类问题中每个类的观察的概率,而不是直接预测类。

这种灵活性来自于可以使用不同阈值来解释概率的方式,该阈值允许模型的操作者在模型所做的错误中权衡关注,例如与假阴性的数量相比的假阳性的数量。当使用一个错误的成本超过其他类型错误的成本的模型时,这是必需的。

有助于解释二元(两类)分类预测性建模问题的概率预测的两种诊断工具是 ROC 曲线和精确回忆曲线。

在本教程中,您将发现 ROC 曲线,精确回忆曲线以及何时使用每个曲线来解释二分类问题的概率预测。

完成本教程后,您将了解:

  • ROC 曲线总结了使用不同概率阈值的预测模型的真阳性率和假阳性率之间的权衡。
  • 精确回忆曲线总结了使用不同概率阈值的预测模型的真阳性率和阳性预测值之间的权衡。
  • 当观察值在每个类别之间平衡时,ROC 曲线是合适的,而精确回忆曲线适用于不平衡的数据集。

让我们开始吧。

  • 更新 Aug / 2018 :修正了精确召回图的无技能线表示中的错误。还修正了错误,我将 ROC 称为相对而不是接收器(感谢拼写检查)。
  • 更新 Nov / 2018 :修正了关于解释每个轴上的值大小的描述,感谢 Karl Humphries。

How and When to Use ROC Curves and Precision-Recall Curves for Classification in Python

如何以及何时使用 ROC 曲线和精确回忆曲线进行分类 照片由 Giuseppe Milo 拍摄,保留一些权利。

教程概述

本教程分为 6 个部分;他们是:

  1. 预测概率
  2. 什么是 ROC 曲线?
  3. Python 中的 ROC 曲线和 AUC
  4. 什么是精确回忆曲线?
  5. Python 中的精确召回曲线和 AUC
  6. 何时使用 ROC 与精确回忆曲线?

预测概率

在分类问题中,我们可能决定直接预测类值。

或者,可以更灵活地预测每个类的概率。其原因是提供选择甚至校准如何解释预测概率的阈值的能力。

例如,默认值可能是使用 0.5 的阈值,这意味着[0.0,0.49]中的概率是负结果(0),[0.5,1.0]中的概率是正结果(1)。

可以调整此阈值以针对特定问题调整模型的行为。一个例子是减少一种或另一种类型的错误。

在对二进制或两类分类问题做出预测时,我们可以做出两种类型的错误。

  • 误报。预测没有事件时的事件。
  • 假阴性。实际上有一个事件,预测没有事件。

通过预测概率和校准阈值,可以由模型的操作者选择这两个问题的平衡。

例如,在烟雾预测系统中,我们可能更关心低假阴性而不是低假阳性。假阴性意味着不会警告雾霾日,事实上它是一个高雾日,导致公众健康问题无法采取预防措施。误报意味着公众会在不需要时采取预防措施。

比较预测两类问题概率的模型的常用方法是使用 ROC 曲线。

什么是 ROC 曲线?

预测二元结果概率时的一个有用工具是接收器工作特性曲线或 ROC 曲线。

它是假阳性率(x 轴)对真实阳性率(y 轴)的曲线图,其中许多不同的候选阈值在 0.0 和 1.0 之间。换句话说,它描绘了误报率与命中率的关系。

真阳性率计算为真阳性数除以真阳性数和假阴性数之和。它描述了当实际结果为正时,模型在预测正类时有多好。

True Positive Rate = True Positives / (True Positives + False Negatives)

真阳性率也称为敏感性。

Sensitivity = True Positives / (True Positives + False Negatives)

假阳性率计算为假阳性的数量除以假阳性的数量和真阴性的数量之和。

它也被称为误报率,因为它总结了当实际结果为负时预测正类的频率。

False Positive Rate = False Positives / (False Positives + True Negatives)

假阳性率也称为反转特异性,其中特异性是真阴性的总数除以真阴性和假阳性的总和。

Specificity = True Negatives / (True Negatives + False Positives)

哪里:

False Positive Rate = 1 - Specificity

ROC 曲线是一个有用的工具,原因如下:

  • 不同模型的曲线可以直接比较或针对不同的阈值进行比较。
  • 曲线下面积(AUC)可用作模型技能的摘要。

曲线的形状包含大量信息,包括我们可能最关心的问题,预期的假阳性率和假阴性率。

为了明确这一点:

  • 图的 x 轴上的较小值表示较低的假阳性和较高的真阴性。
  • 图的 y 轴上的较大值表示较高的真阳性和较低的假阴性。

如果您感到困惑,请记住,当我们预测二元结果时,它是正确的预测(真阳性)或不是(假阳性)。这些选择之间存在紧张关系,同样存在真正的消极和误报。

熟练的模型将为随机选择的实际正面事件分配比平均负面事件更高的概率。当我们说模型具有技巧时,这就是我们的意思。通常,熟练的模型由曲线向左上方的曲线表示。

没有技能的模型在[0.5,0.5]处表示。在每个阈值处没有技能的模型由从图的左下角到右上角的对角线表示,并且具有 0.5 的 AUC。

具有完美技能的模型表示为[0.0,1.0]点。具有完美技能的模型由从绘图的左下角到左上角然后跨越顶部到右上角的线表示。

操作员可以绘制最终模型的 ROC 曲线,并选择在假阳性和假阴性之间给出理想平衡的阈值。

Python 中的 ROC 曲线和 AUC

我们可以使用roc_curve()scikit-learn 函数在 Python 中绘制模型的 ROC 曲线。

该函数获取测试集的真实结果(0,1)和 1 类的预测概率。该函数返回每个阈值的误报率,每个阈值的真正正率和阈值。

# calculate roc curve
fpr, tpr, thresholds = roc_curve(y, probs)

可以使用roc_auc_score()函数计算 ROC 的 AUC。

roc_curve()函数一样,AUC 函数同时获取测试集中的真实结果(0,1)和 1 类的预测概率。它返回的 AUC 分数在 0.0 和 1.0 之间,分别对于没有技能和完美技能。

# calculate AUC
auc = roc_auc_score(y, probs)
print('AUC: %.3f' % auc)

下面列出了计算小测试问题的逻辑回归模型的 ROC 曲线和 AUC 的完整示例。

# roc curve and auc
from sklearn.datasets import make_classification
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_curve
from sklearn.metrics import roc_auc_score
from matplotlib import pyplot
# generate 2 class dataset
X, y = make_classification(n_samples=1000, n_classes=2, weights=[1,1], random_state=1)
# split into train/test sets
trainX, testX, trainy, testy = train_test_split(X, y, test_size=0.5, random_state=2)
# fit a model
model = KNeighborsClassifier(n_neighbors=3)
model.fit(trainX, trainy)
# predict probabilities
probs = model.predict_proba(testX)
# keep probabilities for the positive outcome only
probs = probs[:, 1]
# calculate AUC
auc = roc_auc_score(testy, probs)
print('AUC: %.3f' % auc)
# calculate roc curve
fpr, tpr, thresholds = roc_curve(testy, probs)
# plot no skill
pyplot.plot([0, 1], [0, 1], linestyle='--')
# plot the roc curve for the model
pyplot.plot(fpr, tpr, marker='.')
# show the plot
pyplot.show()

运行该示例将打印 ROC 曲线下的区域。

AUC: 0.895

还创建了模型的 ROC 曲线图,表明模型具有技能。

Line Plot of ROC Curve

ROC 曲线的线图

什么是精确回忆曲线?

有许多方法可以评估预测模型的技能。

信息检索(基于查询查找文档)的相关领域中的方法测量精度和召回

这些度量在用于评估二分类模型的应用机器学习中也是有用的。

精确度是真阳性数除以真阳性和假阳性之和的比率。它描述了模型在预测积极阶级方面有多好。精度被称为阳性预测值。

Positive Predictive Power = True Positives / (True Positives + False Positives)

要么

Precision = True Positives / (True Positives + False Positives)

召回计算为真阳性数除以真阳性和假阴性之和的比率。召回与敏感度相同。

Recall = True Positives / (True Positives + False Negatives)

or

Sensitivity = True Positives / (True Positives + False Negatives)
Recall == Sensitivity

在两个类别之间的观察不平衡的情况下,检查精度和召回都很有用。具体来说,有许多没有事件的例子(0 级)和只有一些事件的例子(1 级)。

其原因在于,通常大量的 0 级示例意味着我们对正确预测 0 级的模型技能不太感兴趣,例如高真阴性。

计算精度和召回的关键是计算不使用真正的否定。它只关注少数民族阶级 1 的正确预测。

精确回忆曲线是不同阈值的精度(y 轴)和回忆(x 轴)的图,非常类似于 ROC 曲线。

无技能线由阳性病例总数除以阳性和阴性病例总数来定义。对于具有相同数量的正面和负面情况的数据集,这是 0.5 的直线。此线以上的点显示技巧。

具有完美技能的模型被描绘为[1.0,1.0]处的点。一个熟练的模型用一条曲线表示,该曲线比无技能的扁平线高出[1.0,1.0]。

还有综合分数,试图总结精确度和召回率;三个例子包括:

  • F 得分F1 得分:计算精度和召回的调和平均值(调和平均值,因为精度和召回率是比率)。
  • 平均精度:总结了精确召回曲线中阈值的每次调用变化的加权精度增加。
  • 曲线下面积:与 AUC 一样,总结了精确回忆曲线下面积的积分或近似值。

在模型选择方面,F1 总结了特定概率阈值的模型技能,而平均精度和曲线下面积总结了模型跨越阈值的技能,如 ROC AUC。

这使得精确回忆和精确度与召回和汇总测量的图表成为二分类问题的有用工具,这些问题在每个类别的观察中具有不平衡。

Python 中的 Precision-Recall 曲线

可以通过precision_score()recall_score()函数以 scikit-learn 计算精度和召回率。

可以使用precision_recall_curve()函数计算阈值的精度和调用,该函数将真实输出值和正类的概率作为输出,并返回精度,调用和阈值。

# calculate precision-recall curve
precision, recall, thresholds = precision_recall_curve(testy, probs)

可以通过调用f1_score()函数来计算 F1 得分,该函数将真实的类值和预测的类值作为参数。

# calculate F1 score
f1 = f1_score(testy, yhat)

精确召回曲线下的面积可以通过调用auc()函数并将其传递给每个阈值计算的调用和精度值来近似。

# calculate precision-recall AUC
auc = auc(recall, precision)

最后,可以通过调用average_precision_score()函数并将其传递给真实的类值和预测的类值来计算平均精度。

下面列出了完整的示例。

# precision-recall curve and f1
from sklearn.datasets import make_classification
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import precision_recall_curve
from sklearn.metrics import f1_score
from sklearn.metrics import auc
from sklearn.metrics import average_precision_score
from matplotlib import pyplot
# generate 2 class dataset
X, y = make_classification(n_samples=1000, n_classes=2, weights=[1,1], random_state=1)
# split into train/test sets
trainX, testX, trainy, testy = train_test_split(X, y, test_size=0.5, random_state=2)
# fit a model
model = KNeighborsClassifier(n_neighbors=3)
model.fit(trainX, trainy)
# predict probabilities
probs = model.predict_proba(testX)
# keep probabilities for the positive outcome only
probs = probs[:, 1]
# predict class values
yhat = model.predict(testX)
# calculate precision-recall curve
precision, recall, thresholds = precision_recall_curve(testy, probs)
# calculate F1 score
f1 = f1_score(testy, yhat)
# calculate precision-recall AUC
auc = auc(recall, precision)
# calculate average precision score
ap = average_precision_score(testy, probs)
print('f1=%.3f auc=%.3f ap=%.3f' % (f1, auc, ap))
# plot no skill
pyplot.plot([0, 1], [0.5, 0.5], linestyle='--')
# plot the precision-recall curve for the model
pyplot.plot(recall, precision, marker='.')
# show the plot
pyplot.show()

首先运行该示例打印 F1,曲线下面积(AUC)和平均精度(AP)分数。

f1=0.836 auc=0.892 ap=0.840

然后创建精确回忆曲线图,显示与无技能模型相比的每个阈值的精度/召回率。

Line Plot of Precision-Recall Curve

精确回忆曲线的线图

何时使用 ROC 与精确回忆曲线?

通常,ROC 曲线和精确回忆曲线的使用如下:

  • 当每个类的观察数量大致相等时,应使用 ROC 曲线。
  • 当存在中等到大的不平衡时,应使用精确召回曲线。

这个建议的原因是 ROC 曲线在具有类不平衡的数据集上呈现模型的乐观图像。

但是,如果类分布中存在较大的偏差,则 ROC 曲线可能会对算法的表现提供过于乐观的视图。 [...]精确回忆(PR)曲线(通常用于信息检索)被引用作为类别分布中具有大偏差的任务的 ROC 曲线的替代。

有些人进一步指出,使用带有不平衡数据集的 ROC 曲线可能具有欺骗性,并导致对模型技能的错误解释。

[...]由于对特异性的直观但错误的解释,在不平衡数据集的背景下 ROC 图的视觉可解释性对于关于分类表现可靠性的结论可能具有欺骗性。另一方面,[精确回忆曲线]图可以为观察者提供对未来分类表现的准确预测,因为他们评估了正面预测中真阳性的分数。

这种乐观情况的主要原因是由于在 ROC 曲线中使用了假阳性率并且在精确回忆曲线中小心避免了这种速率。

如果测试集中正负实例的比例发生变化,则 ROC 曲线不会改变。精度,精度,升力和 F 分数等指标使用混淆矩阵的两列值。随着阶级分布的变化,即使基本分类器表现不变,这些度量也会发生变化。 ROC 图基于 TP 速率和 FP 速率,其中每个维度是严格的柱状比率,因此不依赖于类别分布。

我们可以用一个简短的例子来具体化。

下面是具有修改问题的相同 ROC 曲线示例,其中 class = 0 与 class = 1 观察值之比为 10:1。

# roc curve and auc on imbalanced dataset
from sklearn.datasets import make_classification
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_curve
from sklearn.metrics import roc_auc_score
from matplotlib import pyplot
# generate 2 class dataset
X, y = make_classification(n_samples=1000, n_classes=2, weights=[0.9,0.09], random_state=1)
# split into train/test sets
trainX, testX, trainy, testy = train_test_split(X, y, test_size=0.5, random_state=2)
# fit a model
model = KNeighborsClassifier(n_neighbors=3)
model.fit(trainX, trainy)
# predict probabilities
probs = model.predict_proba(testX)
# keep probabilities for the positive outcome only
probs = probs[:, 1]
# calculate AUC
auc = roc_auc_score(testy, probs)
print('AUC: %.3f' % auc)
# calculate roc curve
fpr, tpr, thresholds = roc_curve(testy, probs)
# plot no skill
pyplot.plot([0, 1], [0, 1], linestyle='--')
# plot the precision-recall curve for the model
pyplot.plot(fpr, tpr, marker='.')
# show the plot
pyplot.show()

运行该示例表明该模型具有技能。

AUC: 0.713

事实上,它具有技巧,但大部分技能被衡量为做出正确的假阴性预测,并且有很多假阴性预测要做。

ROC 曲线图确认了 AUC 对大多数概率阈值的熟练模型的解释。

Line Plot of ROC Curve Imbalanced Dataset

ROC 曲线不平衡数据集的线图

我们还可以在同一数据集上重复对同一模型的测试,并计算精确回忆曲线和统计量。

The complete example is listed below.

# precision-recall curve and auc
from sklearn.datasets import make_classification
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import precision_recall_curve
from sklearn.metrics import f1_score
from sklearn.metrics import auc
from sklearn.metrics import average_precision_score
from matplotlib import pyplot
# generate 2 class dataset
X, y = make_classification(n_samples=1000, n_classes=2, weights=[0.9,0.09], random_state=1)
# split into train/test sets
trainX, testX, trainy, testy = train_test_split(X, y, test_size=0.5, random_state=2)
# fit a model
model = KNeighborsClassifier(n_neighbors=3)
model.fit(trainX, trainy)
# predict probabilities
probs = model.predict_proba(testX)
# keep probabilities for the positive outcome only
probs = probs[:, 1]
# predict class values
yhat = model.predict(testX)
# calculate precision-recall curve
precision, recall, thresholds = precision_recall_curve(testy, probs)
# calculate F1 score
f1 = f1_score(testy, yhat)
# calculate precision-recall AUC
auc = auc(recall, precision)
# calculate average precision score
ap = average_precision_score(testy, probs)
print('f1=%.3f auc=%.3f ap=%.3f' % (f1, auc, ap))
# plot no skill
pyplot.plot([0, 1], [0.1, 0.1], linestyle='--')
# plot the precision-recall curve for the model
pyplot.plot(recall, precision, marker='.')
# show the plot
pyplot.show()

首先运行该示例打印 F1,AUC 和 AP 分数。

鉴于熟练的模型通常高于 0.5,分数看起来并不令人鼓舞。

f1=0.278 auc=0.302 ap=0.236

从情节来看,我们可以看到精确度和召回后快速崩溃。

Line Plot of Precision-Recall Curve Imbalanced Dataset

精确回忆曲线不平衡数据集的线图

进一步阅读

如果您希望深入了解,本节将提供有关该主题的更多资源。

文件

API

用品

摘要

在本教程中,您发现了 ROC 曲线,精确回忆曲线,以及何时使用每个曲线来解释二分类问题的概率预测。

具体来说,你学到了:

  • ROC 曲线总结了使用不同概率阈值的预测模型的真阳性率和假阳性率之间的权衡。
  • 精确回忆曲线总结了使用不同概率阈值的预测模型的真阳性率和阳性预测值之间的权衡。
  • 当观察值在每个类别之间平衡时,ROC 曲线是合适的,而精确回忆曲线适用于不平衡的数据集。

你有任何问题吗? 在下面的评论中提出您的问题,我会尽力回答。

使用 Python 和 scikit-learn 保存和加载机器学习模型

原文: machinelearningmastery.com/save-load-machine-learning-models-python-scikit-learn/

找到准确的机器学习模型并不是项目的终点。

在这篇文章中,您将了解如何使用 scikit-learn 在 Python 中保存和加载机器学习模型。

这允许您将模型保存到文件并稍后加载以做出预测。

让我们开始吧。

  • 2017 年 1 月更新:已更新,以反映版本 0.18 中 scikit-learn API 的更改。
  • 更新 March / 2018 :添加了备用链接以下载数据集,因为原始图像已被删除。

Save and Load Machine Learning Models in Python with scikit-learn

使用 scikit-learn 照片保存并加载机器学习模型 Christine ,保留一些权利。

用泡菜完成你的模型

Pickle 是在 Python 中序列化对象的标准方法。

您可以使用 pickle 操作来序列化您的机器学习算法并将序列化格式保存到文件中。

稍后您可以加载此文件以反序列化您的模型并使用它来进行新的预测。

下面的例子演示了如何训练 Pima 印第安人糖尿病数据集的逻辑回归模型,将模型保存到文件并加载它以对未见的测试集做出预测(更新:下载从这里)。

# Save Model Using Pickle
import pandas
from sklearn import model_selection
from sklearn.linear_model import LogisticRegression
import pickle
url = "https://raw.githubusercontent.com/jbrownlee/Datasets/master/pima-indians-diabetes.data.csv"
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
dataframe = pandas.read_csv(url, names=names)
array = dataframe.values
X = array[:,0:8]
Y = array[:,8]
test_size = 0.33
seed = 7
X_train, X_test, Y_train, Y_test = model_selection.train_test_split(X, Y, test_size=test_size, random_state=seed)
# Fit the model on 33%
model = LogisticRegression()
model.fit(X_train, Y_train)
# save the model to disk
filename = 'finalized_model.sav'
pickle.dump(model, open(filename, 'wb'))

# some time later...

# load the model from disk
loaded_model = pickle.load(open(filename, 'rb'))
result = loaded_model.score(X_test, Y_test)
print(result)

运行该示例将模型保存到本地工作目录中的 finalized_model.sav 。加载已保存的模型并对其进行评估可以估算模型对未见数据的准确率。

0.755905511811

使用 joblib 完成模型

Joblib 是 SciPy 生态系统的一部分,提供用于管道化 Python 作业的实用程序。

它提供了实用程序,用于保存和加载有效利用 NumPy 数据结构的 Python 对象

这对于需要大量参数或存储整个数据集的某些机器学习算法(如 K 最近邻)非常有用。

下面的示例演示了如何在 Pima Indians 糖尿病数据集开始时训练逻辑回归模型,使用 joblib 将模型保存到文件并加载它以对看不见的测试集做出预测。

# Save Model Using joblib
import pandas
from sklearn import model_selection
from sklearn.linear_model import LogisticRegression
from sklearn.externals import joblib
url = "https://raw.githubusercontent.com/jbrownlee/Datasets/master/pima-indians-diabetes.data.csv"
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
dataframe = pandas.read_csv(url, names=names)
array = dataframe.values
X = array[:,0:8]
Y = array[:,8]
test_size = 0.33
seed = 7
X_train, X_test, Y_train, Y_test = model_selection.train_test_split(X, Y, test_size=test_size, random_state=seed)
# Fit the model on 33%
model = LogisticRegression()
model.fit(X_train, Y_train)
# save the model to disk
filename = 'finalized_model.sav'
joblib.dump(model, filename)

# some time later...

# load the model from disk
loaded_model = joblib.load(filename)
result = loaded_model.score(X_test, Y_test)
print(result)

运行该示例将模型保存为文件 finalized_model.sav ,并为模型中的每个 NumPy 数组创建一个文件(另外四个文件)。加载模型后,将报告模型对未见数据的准确率估计值。

0.755905511811

完成模型的提示

本节列出了最终确定机器学习模型时的一些重要注意事项。

  • Python 版。记下 python 版本。几乎可以肯定,当您稍后加载并反序列化时,您需要使用相同的主要(可能是次要)版本的 Python 来序列化模型。
  • 库版本。在反序列化已保存的模型时,机器学习项目中使用的所有主要库的版本几乎肯定需要相同。这不仅限于 NumPy 的版本和 scikit-learn 的版本。
  • 手动序列化。您可能希望手动输出学习模型的参数,以便将来可以直接在 scikit-learn 或其他平台中使用它们。通常,机器学习算法用于做出预测的算法比用于学习参数的算法简单得多,可以很容易地在您可以控制的自定义代码中实现。

请注意该版本,以便您可以在以后因某种原因无法在其他计算机或其他平台上重新加载模型时重新创建环境。

摘要

在这篇文章中,您发现了如何使用 scikit-learn 在 Python 中持久保存机器学习算法。

您学习了两种可以使用的技术:

  • 用于序列化标准 Python 对象的 pickle API。
  • joblib API 用于使用 NumPy 数组有效地序列化 Python 对象。

您对保存和加载机器学习算法或此帖子有任何疑问吗?在评论中提出您的问题,我会尽力回答。

scikit-learn 秘籍的书评

原文: machinelearningmastery.com/scikit-learn-cookbook-book-review/

scikit-learn 库是 Python 中机器学习的首选库。

在线文档非常好,但有时可能会感到支离破碎或受到狭隘范例的限制。

在这篇文章中,您将发现 Trent Hauck 的书 Scikit-Learn Cookbook ,它提供了一个桌面参考,以补充在线文档并帮助您快速学习 scikit-learn。

我们进入吧。

Amazon Image

图书概述

Scikit-Learn Cookbook 是由 Trent Hauck 撰写并由 Packt Publishing 出版的重点书。

这本书的副标题是:

超过 50 个将 scikit-learn 纳入数据科学管道的每一步的秘籍,从特征提取到模型构建和模型评估。

它于 2014 年底出版,长度不到 200 页。我喜欢这个外形。厚厚的参考文本真的让我离开这些日子(想想数字秘籍,它自豪地坐在我的架子上)。我宁愿有 10 个较小的焦点参考文本,如迷你百科全书系列。

我喜欢它是关于 scikit-learn 秘籍的小型尖锐文本。

预订观众

这本书不适合机器学习初学者。做记录。

它假定:

  • 熟悉 Python。
  • 熟悉 SciPy 栈。
  • 熟悉机器学习。

对于已经在项目中使用 scikit-learn 的人来说,这些是合理的假设,在这种情况下,本书成为桌面参考,用于咨询特定的 ad hoc 机器学习任务。

书籍内容

这本书由 50 个秘籍组成? (如果我相信目录和我自己的计数,可能有 57 个秘籍)分为 5 章。

  • 第一章:预编程工作流程
  • 第二章:使用线性模型
  • 第三章:使用距离度量建立模型
  • 第四章:使用 scikit-learn 对数据进行分类
  • 第五章:Postmodel 工作流程

这些章节通常映射到标准数据科学项目的工作流程:

  1. 获取并准备数据。
  2. 尝试一些线性模型
  3. 尝试一些非线性模型
  4. 尝试一些更多的非线性模型。
  5. 完成模型

对于一本书来说,这是一个好的结构,问题是仅靠 scikit-learn 并不能很好地服务于所有这些步骤。它擅长于建模部分,并且在数据预处理方面做得很好,但在数据加载和数据分析步骤中却很难被忽略。

接下来我们将依次逐步介绍每一章。

章节演练

在本节中,我们将详细介绍五章中的每个章节。

第一章:预编程工作流程

本章重点介绍数据准备。这是重新格式化数据以最好地将问题的结构暴露给我们可能选择稍后使用的机器学习算法。

本章共有 17 个秘籍,我将它们分组如下:

  • 数据加载:加载您自己的数据并使用内置数据集。
  • 数据清理:诸如输入缺失值之类的任务。
  • 数据预处理:缩放和特征工程。
  • 降维:SVD,PCA 和因子分析。
  • 其他:管道,高斯过程和梯度下降。

我很伤心,我必须在这里设计自己的结构。我也很遗憾有一个“_ 其他 _”类别。这表明章节中的秘籍组织可以更清洁。

我想更多和单独的缩放方法的秘籍。我发现自己在使用它们之前会对数据集进行大量扩展。这可能是获得良好结果所需的最常见的预处理步骤。

第二章:使用线性模型

本章的重点是线性模型。这个较短的章节包含 9 个秘籍。

通常,本章的秘籍包括:

  • 线性回归
  • 规范化回归
  • 逻辑回归
  • 回归的更多奇特变化,如提升。

这又是另一个奇怪的秘籍组合。

我想我觉得线性模型的重点可以进一步扩展到 LDA,Perceptron 和平台支持的其他模型,而不仅限于回归。

第三章:使用距离度量建立模型

许多算法确实在其核心使用距离测量。

可能会想到的第一个是 KNN,但实际上你可以更广泛地解释它并引入支持向量机和使用内核的相关技术等技术。

本章重点介绍使用距离测量的技术,并且几乎专注于 K-Means(本章 9 个秘籍中的 8 个)。本章末尾有一个 KNN 秘籍。

该章应该被称为聚类或 K-Means。

此外,我最好注意我的偏见,因为我根本不使用聚类方法,我发现它们对于预测性建模完全没用。

第四章:使用 scikit-learn 对数据进行分类

从标题来看,本章是关于分类算法的。

我将在本章中组织 11 个秘籍如下:

  • 决策树(CART 和随机森林)
  • 支持向量机
  • 判别分析(LDA 和 QDA)
  • 朴素贝叶斯
  • 其他(半监督学习,梯度下降等)

我会把 LDA 和 QDA 放在线性模型章节(第二章)中,我会添加更多的算法。 scikit-learn 的一大好处是它提供了许多开箱即用的算法。

本章涉及的那些算法很好,我所说的是我会将数字增加一倍或三倍,并使算法的秘籍成为本书的重点。

第五章:Postmodel 工作流程

本章包含 11 个关于一般岗位建模任务的方法。

这是技术上不准确的,因为您将这些任务作为建模的一部分来执行,但是,我看到了作者的目的。

我将总结本章的秘籍如下:

  • 重采样方法(交叉验证和变化)。
  • 算法调整(网格搜索,随机搜索,手动搜索等)。
  • 特征选择。
  • 其他(模型持久性,模型评估和基线)。

一个涵盖重要主题的好章节。非常重要的主题。

通常,我会在 k-fold 交叉验证的上下文中介绍每种算法,因为对于大多数用例,以任何其他方式评估算法可能不是一个好主意。

我也很惊讶地看到这本书的特色选择如此晚。我原本预计会出现在第一章中。它属于数据准备工作。

对书的思考

这本书很好。我建议那些寻找好桌面参考的人来支持 scikit-learn 的在线文档。

我通常喜欢每种秘籍的呈现方式。事实上,它的冗长程度很好,而在其他书籍中,秘籍可能过于简短。结构如下:

  • 秘籍名称和描述。
  • 做好准备(例如前提条件或要求)。
  • 怎么做(实际代码和实现结果所需的步骤)。
  • 工作原理(API 或流程的附加说明)。
  • 还有更多(秘籍的可选附加变体是有用的)。

鉴于上述软推荐,我在阅读时注意到了一些事情。

我对许多秘籍的内容感到沮丧。这么多,以至于我永远不会使用它们在我自己的 scikit - 学习秘籍库中使用它们从项目到项目。

我使用 scikit - 学习了一点点,我花时间阅读并尝试了大部分 API。书中的许多秘籍都是手工制作的功能,实际上已经存在于 scikit-learn API 中。也许 API 自发布以来已经更新,但是这确实困扰了我。更少的代码是更少的维护,如果你使用像 scikit-learn 这样的库,那么你应该使用它,并且很好。

此外,通常在解释中有一些方程式。它们主要是提供技术的快捷描述并避免说明。它很好,但它们也可能被排除在外并指向一个好的参考文本,并将激光专注于 scikit-learn API。

有些秘籍太长了。我轻盈,专注,自足。我可以复制和粘贴的东西,用于在我自己的项目中启动流程。

你不能涵盖整个 scikit-learn API,本书的内容非常好。它涵盖了库的关键部分。我希望看到它涵盖了区分库的一些方面,例如更详细的管道,学习线图和模型校准。

摘要

在这篇文章中,你发现了 Trent Hauck 的书 Scikit-Learn Cookbook

Amazon Image

您了解到这是一本包含 50 多种使用 scikit-learn 主题的秘籍的书,例如:

  • 数据准备。
  • 线性和非线性算法。
  • 模型评估和算法调整。

这是一本合理的秘籍,可用作桌面参考,以补充 scikit-learn 库的在线文档。

你对这本书有什么问题吗?你读过这本书吗?发表评论,让我知道你对它的看法。

用于机器学习中的超参数调整的 SkOpt

原文:machinelearningmastery.com/scikit-opti…

最后更新于 2020 年 11 月 6 日

超参数优化指的是执行搜索,以便发现一组特定的模型配置参数,从而在特定数据集上获得模型的最佳表现。

有许多方法可以执行超参数优化,尽管现代方法,如贝叶斯优化,是快速有效的。 Scikit-Optimize 库是一个开源 Python 库,它提供了贝叶斯优化的实现,可用于调整 Sklearn Python 库中机器学习模型的超参数。

您可以很容易地使用 Scikit-Optimize 库在下一个机器学习项目中调整模型。

在本教程中,您将发现如何使用 Scikit-Optimize 库来使用贝叶斯优化进行超参数调整。

完成本教程后,您将知道:

  • Scikit-Optimize 为贝叶斯优化提供了一个通用工具包,可用于超参数调整。
  • 如何手动使用 Scikit-Optimize 库来调整机器学习模型的超参数。
  • 如何使用内置的 BayesSearchCV 类执行模型超参数调优。

我们开始吧。

  • 2020 年 11 月更新:更新了中断的 API 链接,因为 skopt 网站发生了变化。

Scikit-Optimize for Hyperparameter Tuning in Machine Learning

scikit-优化机器学习中的超参数调整 图片由丹·内维尔提供,保留部分权利。

教程概述

本教程分为四个部分;它们是:

  1. sci kit-优化
  2. 机器学习数据集和模型
  3. 手动调整算法超参数
  4. 自动调整算法超参数

sci kit-优化

Scikit-Optimize,简称 skopt,是一个用于执行优化任务的开源 Python 库。

它提供了有效的优化算法,如贝叶斯优化,并可用于寻找任意成本函数的最小值或最大值。

贝叶斯优化提供了一种基于贝叶斯定理的有原则的技术,用于指导高效且有效的全局优化问题的搜索。它的工作原理是建立一个目标函数的概率模型,称为替代函数,然后在选择候选样本对真实目标函数进行评估之前,使用获取函数对其进行有效搜索。

有关贝叶斯优化主题的更多信息,请参见教程:

重要的是,该库为调整 Sklearn 库提供的机器学习算法的超参数提供了支持,即所谓的超参数优化。因此,它为效率较低的超参数优化过程(如网格搜索和随机搜索)提供了一种有效的替代方案。

scikit-optimize 库可以使用 pip 安装,如下所示:

sudo pip install scikit-optimize

安装后,我们可以导入库并打印版本号,以确认库安装成功并可以访问。

下面列出了完整的示例。

# report scikit-optimize version number
import skopt
print('skopt %s' % skopt.__version__)

运行该示例会报告 scikit-optimize 的当前安装版本号。

您的版本号应该相同或更高。

skopt 0.7.2

有关更多安装说明,请参见文档:

现在我们已经熟悉了什么是 Scikit-Optimize 以及如何安装它,让我们来探索如何使用它来调整机器学习模型的超参数。

机器学习数据集和模型

首先,让我们选择一个标准数据集和一个模型来处理它。

我们将使用电离层机器学习数据集。这是一个标准的机器学习数据集,包括 351 行数据,其中有三个数字输入变量和一个目标变量,目标变量有两个类值,例如二进制分类。

使用带有三次重复的重复分层 10 倍交叉验证的测试工具,一个简单的模型可以达到大约 64%的准确率。一个表现最好的模型可以在同样的测试设备上达到大约 94%的精确度。这提供了此数据集的预期表现范围。

该数据集包括预测电离层测量值是否表明特定结构。

您可以在此了解有关数据集的更多信息:

不需要下载数据集;我们将自动下载它作为我们工作示例的一部分。

下面的示例下载数据集并总结其形状。

# summarize the ionosphere dataset
from pandas import read_csv
# load dataset
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/ionosphere.csv'
dataframe = read_csv(url, header=None)
# split into input and output elements
data = dataframe.values
X, y = data[:, :-1], data[:, -1]
print(X.shape, y.shape)

运行该示例会下载数据集,并将其拆分为输入和输出元素。不出所料,我们可以看到有 351 行数据,34 个输入变量。

(351, 34) (351,)

我们可以使用重复的分层交叉验证在这个数据集上评估支持向量机 (SVM)模型。

我们可以报告数据集上所有折叠和重复的平均模型表现,这将为后面章节中执行的模型超参数调整提供参考。

下面列出了完整的示例。

# evaluate an svm for the ionosphere dataset
from numpy import mean
from numpy import std
from pandas import read_csv
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.svm import SVC
# load dataset
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/ionosphere.csv'
dataframe = read_csv(url, header=None)
# split into input and output elements
data = dataframe.values
X, y = data[:, :-1], data[:, -1]
print(X.shape, y.shape)
# define model model
model = SVC()
# define test harness
cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
# evaluate model
m_scores = cross_val_score(model, X, y, scoring='accuracy', cv=cv, n_jobs=-1, error_score='raise')
print('Accuracy: %.3f (%.3f)' % (mean(m_scores), std(m_scores)))

运行该示例首先加载和准备数据集,然后对数据集评估 SVM 模型。

:考虑到算法或评估程序的随机性,或数值精确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。

在这种情况下,我们可以看到具有默认超参数的 SVM 实现了大约 93.7%的平均分类准确率,这是熟练的,并且接近 94%的问题上的最高表现。

(351, 34) (351,)
Accuracy: 0.937 (0.038)

接下来,让我们看看是否可以通过使用 scikit-optimize 库调整模型超参数来提高表现。

手动调整算法超参数

Scikit-Optimize 库可用于调整机器学习模型的超参数。

我们可以通过使用库的贝叶斯优化功能来手动实现这一点。

这要求我们首先定义一个搜索空间。在这种情况下,这将是我们希望调整的模型的超参数,以及每个超参数的范围。

我们将调整 SVM 模型的以下超参数:

  • C ,正则化参数。
  • 内核,模型中使用的内核类型。
  • ,用于多项式核。
  • γ,用于大多数其他内核。

对于数值超参数 Cγ,我们将定义一个对数标度,在 1e-6 和 100 的小值之间进行搜索。是一个整数,我们将搜索 1 到 5 之间的值。最后,内核是一个具有特定命名值的类别变量。

我们可以为这四个超参数定义搜索空间,它们是来自 skopt 库的数据类型列表,如下所示:

...
# define the space of hyperparameters to search
search_space = list()
search_space.append(Real(1e-6, 100.0, 'log-uniform', name='C'))
search_space.append(Categorical(['linear', 'poly', 'rbf', 'sigmoid'], name='kernel'))
search_space.append(Integer(1, 5, name='degree'))
search_space.append(Real(1e-6, 100.0, 'log-uniform', name='gamma'))

请注意为每个参数指定的数据类型、范围和超参数名称。

然后,我们可以定义一个将由搜索过程调用的函数。这是优化过程稍后期望的函数,它获取模型和模型的特定超参数集,对其进行评估,并返回超参数集的分数。

在我们的案例中,我们希望在电离层数据集上使用重复的分层 10 倍交叉验证来评估模型。我们希望最大化分类精确率,例如,找到给出最佳精确率的模型超参数集。默认情况下,该过程最小化从该函数返回的分数,因此,我们将返回 1 减去准确性,例如,完美技能将是(1–准确性)或 0.0,最差技能将是 1.0。

下面的 evaluate_model() 函数实现了这一点,并获取了一组特定的超参数。

# define the function used to evaluate a given configuration
@use_named_args(search_space)
def evaluate_model(**params):
	# configure the model with specific hyperparameters
	model = SVC()
	model.set_params(**params)
	# define test harness
	cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
	# calculate 5-fold cross validation
	result = cross_val_score(model, X, y, cv=cv, n_jobs=-1, scoring='accuracy')
	# calculate the mean of the scores
	estimate = mean(result)
	# convert from a maximizing score to a minimizing score
	return 1.0 - estimate

接下来,我们可以通过调用*gp _ minimum()*函数来执行搜索,并传递要调用的函数的名称来评估每个模型和要优化的搜索空间。

...
# perform optimization
result = gp_minimize(evaluate_model, search_space)

该过程将一直运行,直到它收敛并返回结果。

结果对象包含许多细节,但重要的是,我们可以访问最佳表现配置的分数和最佳成形模型使用的超参数。

...
# summarizing finding:
print('Best Accuracy: %.3f' % (1.0 - result.fun))
print('Best Parameters: %s' % (result.x))

下面列出了手动调整电离层数据集上 SVM 超参数的完整示例。

# manually tune svm model hyperparameters using skopt on the ionosphere dataset
from numpy import mean
from pandas import read_csv
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.svm import SVC
from skopt.space import Integer
from skopt.space import Real
from skopt.space import Categorical
from skopt.utils import use_named_args
from skopt import gp_minimize

# define the space of hyperparameters to search
search_space = list()
search_space.append(Real(1e-6, 100.0, 'log-uniform', name='C'))
search_space.append(Categorical(['linear', 'poly', 'rbf', 'sigmoid'], name='kernel'))
search_space.append(Integer(1, 5, name='degree'))
search_space.append(Real(1e-6, 100.0, 'log-uniform', name='gamma'))

# define the function used to evaluate a given configuration
@use_named_args(search_space)
def evaluate_model(**params):
	# configure the model with specific hyperparameters
	model = SVC()
	model.set_params(**params)
	# define test harness
	cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
	# calculate 5-fold cross validation
	result = cross_val_score(model, X, y, cv=cv, n_jobs=-1, scoring='accuracy')
	# calculate the mean of the scores
	estimate = mean(result)
	# convert from a maximizing score to a minimizing score
	return 1.0 - estimate

# load dataset
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/ionosphere.csv'
dataframe = read_csv(url, header=None)
# split into input and output elements
data = dataframe.values
X, y = data[:, :-1], data[:, -1]
print(X.shape, y.shape)
# perform optimization
result = gp_minimize(evaluate_model, search_space)
# summarizing finding:
print('Best Accuracy: %.3f' % (1.0 - result.fun))
print('Best Parameters: %s' % (result.x))

运行该示例可能需要一些时间,具体取决于机器的速度。

您可能会看到一些可以安全忽略的警告消息,例如:

UserWarning: The objective has been evaluated at this point before.

运行结束时,会报告表现最佳的配置。

:考虑到算法或评估程序的随机性,或数值精确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。

在这种情况下,我们可以看到,按照搜索空间列表的顺序报告的配置是适度的 C 值、径向基函数、2 的(被径向基函数核忽略)和适度的γ值。

重要的是,我们可以看到这个模型的技能大约是 94.7%,这是一个表现最好的模型

(351, 34) (351,)
Best Accuracy: 0.948
Best Parameters: [1.2852670137769258, 'rbf', 2, 0.18178016885627174]

这不是使用 Scikit-Optimize 库进行超参数调整的唯一方法。在下一节中,我们可以看到一种更自动化的方法。

自动调整算法超参数

Sklearn 机器学习库提供了调整模型超参数的工具。

具体来说,它提供了 GridSearchCV随机化搜索 CV 类,这些类采用一个模型、一个搜索空间和一个交叉验证配置。

这些类的好处是搜索过程是自动执行的,只需要最少的配置。

类似地,Scikit-Optimize 库提供了一个类似的界面,用于通过Bayesarccv类执行模型超参数的贝叶斯优化。

这个类可以用与 Sklearn 等价类相同的方式使用。

首先,搜索空间必须定义为一个字典,其中超参数名称用作关键字,变量的范围用作值。

...
# define search space
params = dict()
params['C'] = (1e-6, 100.0, 'log-uniform')
params['gamma'] = (1e-6, 100.0, 'log-uniform')
params['degree'] = (1,5)
params['kernel'] = ['linear', 'poly', 'rbf', 'sigmoid']

然后,我们可以定义Bayesarccv配置,采用我们希望评估的模型、超参数搜索空间和交叉验证配置。

...
# define evaluation
cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
# define the search
search = BayesSearchCV(estimator=SVC(), search_spaces=params, n_jobs=-1, cv=cv)

然后,我们可以执行搜索,并在最后报告最佳结果和配置。

...
# perform the search
search.fit(X, y)
# report the best result
print(search.best_score_)
print(search.best_params_)

将这些联系在一起,下面列出了使用电离层数据集上的 BayesSearchCV 类自动调整 SVM 超参数的完整示例。

# automatic svm hyperparameter tuning using skopt for the ionosphere dataset
from pandas import read_csv
from sklearn.model_selection import cross_val_score
from sklearn.svm import SVC
from sklearn.model_selection import RepeatedStratifiedKFold
from skopt import BayesSearchCV
# load dataset
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/ionosphere.csv'
dataframe = read_csv(url, header=None)
# split into input and output elements
data = dataframe.values
X, y = data[:, :-1], data[:, -1]
print(X.shape, y.shape)
# define search space
params = dict()
params['C'] = (1e-6, 100.0, 'log-uniform')
params['gamma'] = (1e-6, 100.0, 'log-uniform')
params['degree'] = (1,5)
params['kernel'] = ['linear', 'poly', 'rbf', 'sigmoid']
# define evaluation
cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
# define the search
search = BayesSearchCV(estimator=SVC(), search_spaces=params, n_jobs=-1, cv=cv)
# perform the search
search.fit(X, y)
# report the best result
print(search.best_score_)
print(search.best_params_)

运行该示例可能需要一些时间,具体取决于机器的速度。

您可能会看到一些可以安全忽略的警告消息,例如:

UserWarning: The objective has been evaluated at this point before.

运行结束时,会报告表现最佳的配置。

:考虑到算法或评估程序的随机性,或数值精确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。

在这种情况下,我们可以看到,该模型的表现高于表现最好的模型,平均分类准确率约为 95.2%。

搜索发现了一个大的 C 值、一个径向基函数和一个小的γ值。

(351, 34) (351,)
0.9525166191832859
OrderedDict([('C', 4.8722263953328735), ('degree', 4), ('gamma', 0.09805881007239009), ('kernel', 'rbf')])

这提供了一个模板,您可以使用它来调整机器学习项目中的超参数。

进一步阅读

如果您想更深入地了解这个主题,本节将提供更多资源。

相关教程

蜜蜂

摘要

在本教程中,您发现了如何使用 Scikit-Optimize 库将贝叶斯优化用于超参数调整。

具体来说,您了解到:

  • Scikit-Optimize 为贝叶斯优化提供了一个通用工具包,可用于超参数调整。
  • 如何手动使用 Scikit-Optimize 库来调整机器学习模型的超参数。
  • 如何使用内置的 BayesSearchCV 类执行模型超参数调优。

你有什么问题吗? 在下面的评论中提问,我会尽力回答。

如何将 Seaborn 数据可视化用于机器学习

原文:machinelearningmastery.com/seaborn-dat…

最后更新于 2020 年 8 月 19 日

数据可视化提供了对数据集中变量之间的分布和关系的洞察。

这种洞察力有助于在建模之前选择要应用的数据准备技术,以及最适合数据的算法类型。

Seaborn 是一个 Python 的数据可视化库,它运行在流行的 Matplotlib 数据可视化库之上,尽管它提供了简单的界面和美学上更好看的图。

在本教程中,您将发现一个关于机器学习的 Seaborn 数据可视化的温和介绍。

完成本教程后,您将知道:

  • 如何使用条形图、直方图、方框图和触须图总结变量的分布。
  • 如何用线图和散点图总结关系?
  • 如何比较同一图上不同类值的变量分布和关系?

用我的新书Python 机器学习精通启动你的项目,包括分步教程和所有示例的 Python 源代码文件。

我们开始吧。

How to use Seaborn Data Visualization for Machine Learning

如何使用 Seaborn 数据可视化进行机器学习 图片由马丁·佩蒂特提供,版权所有。

教程概述

本教程分为六个部分;它们是:

  • 海底数据可视化库
  • 线形图
  • 条形图
  • 直方图
  • 方框图和触须图
  • 散点图

海底数据可视化库

Python 的主要绘图库称为 Matplotlib

Seaborn 是一个绘图库,它提供了更简单的界面,为机器学习所需的绘图提供了合理的默认值,最重要的是,这些绘图在美学上比 Matplotlib 中的那些更好看。

Seaborn 要求先安装 Matplotlib。

可以直接使用 pip 安装 Matplotlib,如下所示:

sudo pip install matplotlib

安装后,您可以通过打印版本号来确认库可以加载和使用,如下所示:

# matplotlib
import matplotlib
print('matplotlib: %s' % matplotlib.__version__)

运行该示例将打印 Matplotlib 库的当前版本。

matplotlib: 3.1.2

接下来,也可以使用 pip 安装 Seaborn 库:

sudo pip install seaborn

安装后,我们还可以通过打印版本号来确认库是否可以加载和使用,如下所示:

# seaborn
import seaborn
print('seaborn: %s' % seaborn.__version__)

运行该示例将打印当前版本的 Seaborn 库。

seaborn: 0.10.0

要创建 Seaborn 地块,必须导入 Seaborn 库并调用函数来创建地块。

重要的是,Seaborn 绘图功能期望数据作为熊猫数据帧提供。这意味着,如果您从 CSV 文件加载数据,您必须使用熊猫函数,如 read_csv() 将数据加载为数据帧。绘图时,可以通过数据框名称或列索引指定列。

要显示剧情,可以调用 Matplotlib 库上的 show()函数

...
# display the plot
pyplot.show()

或者,可以将绘图保存到文件中,例如 PNG 格式的图像文件。 savefig() Matplotlib 功能可用于保存图像。

...
# save the plot
pyplot.savefig('my_image.png')

现在我们已经安装了 Seaborn,让我们看看在处理机器学习数据时可能需要的一些常见图。

线形图

线图通常用于呈现定期收集的观测数据。

x 轴表示规则的时间间隔,如时间。y 轴显示观察值,按 x 轴排序,用一条线连接。

通过调用 lineplot()函数并传递规则间隔的 x 轴数据和观察的 y 轴数据,可以在 Seaborn 中创建线图。

我们可以使用月汽车销量的时间序列数据集来演示线图。

数据集有两列:“”和“销售”月将用作 x 轴,销售额将绘制在 y 轴上。

...
# create line plot
lineplot(x='Month', y='Sales', data=dataset)

将这些联系在一起,完整的示例如下所示。

# line plot of a time series dataset
from pandas import read_csv
from seaborn import lineplot
from matplotlib import pyplot
# load the dataset
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/monthly-car-sales.csv'
dataset = read_csv(url, header=0)
# create line plot
lineplot(x='Month', y='Sales', data=dataset)
# show plot
pyplot.show()

运行该示例首先加载时间序列数据集,并创建数据的折线图,清楚地显示销售数据的趋势和季节性。

Line Plot of a Time Series Dataset

时间序列数据集的线图

有关使用 Seaborn 绘制线图的更多优秀示例,请参见:可视化统计关系

条形图

条形图通常用于表示多个类别的相对数量。

x 轴表示均匀分布的类别。y 轴表示每个类别的数量,并绘制为从基线到 y 轴上适当级别的条形图。

通过调用 countplot()函数并传递数据,可以在 Seaborn 中创建条形图。

我们将展示一个条形图,其中包含由分类输入变量组成的乳腺癌分类数据集中的一个变量。

我们将只绘制一个变量,在这种情况下,第一个变量是年龄段。

...
# create line plot
countplot(x=0, data=dataset)

将这些联系在一起,完整的示例如下所示。

# bar chart plot of a categorical variable
from pandas import read_csv
from seaborn import countplot
from matplotlib import pyplot
# load the dataset
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/breast-cancer.csv'
dataset = read_csv(url, header=None)
# create bar chart plot
countplot(x=0, data=dataset)
# show plot
pyplot.show()

运行该示例首先加载乳腺癌数据集,并创建数据的条形图,显示每个年龄组和属于可及组的个体(样本)数量。

Bar Chart Plot of Age Range Categorical Variable

年龄范围类别变量的条形图

我们可能还想针对类标签绘制一个变量的每个类别的计数,例如第一个变量。

这可以通过使用 countplot() 函数并通过“色调参数指定类变量(列索引 9)来实现,如下所示:

...
# create bar chart plot
countplot(x=0, hue=9, data=dataset)

将这些联系在一起,完整的示例如下所示。

# bar chart plot of a categorical variable against a class variable
from pandas import read_csv
from seaborn import countplot
from matplotlib import pyplot
# load the dataset
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/breast-cancer.csv'
dataset = read_csv(url, header=None)
# create bar chart plot
countplot(x=0, hue=9, data=dataset)
# show plot
pyplot.show()

运行该示例首先加载乳腺癌数据集,并创建数据的条形图,显示每个年龄组和每个组中由数据集的两个类别标签分隔的个人(样本)数量。

Bar Chart Plot of Age Range Categorical Variable by Class Label

按类别标签划分的年龄范围类别变量的条形图

有关使用 Seaborn 绘制条形图的更多示例,请参见:使用分类数据绘制

直方图

直方图通常用于总结数字数据样本的分布。

x 轴代表观察的离散面元或间隔。例如,值在 1 和 10 之间的观测值可以被分成五个仓,值[1,2]将被分配给第一个仓,[3,4]将被分配给第二个仓,以此类推。

y 轴表示数据集中属于每个面元的观测值的频率或数量。

本质上,数据样本被转换成条形图,其中 x 轴上的每个类别代表一个观察值区间。

通过调用 distplot()函数并传递变量,可以在 Seaborn 中创建直方图。

我们将展示一个带有来自糖尿病分类数据集的数字变量的箱线图。我们将只绘制一个变量,在这种情况下,第一个变量,即患者怀孕的次数。

...
# create histogram plot
distplot(dataset[[0]])

将这些联系在一起,完整的示例如下所示。

# histogram plot of a numerical variable
from pandas import read_csv
from seaborn import distplot
from matplotlib import pyplot
# load the dataset
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/pima-indians-diabetes.csv'
dataset = read_csv(url, header=None)
# create histogram plot
distplot(dataset[[0]])
# show plot
pyplot.show()

运行该示例首先加载糖尿病数据集,并创建变量的直方图,显示值的分布,硬截止值为零。

该图显示了直方图(箱数)以及概率密度函数的平滑估计。

Histogram Plot of Number of Times Pregnant Numerical Variable

怀孕次数数值变量直方图

有关使用 Seaborn 绘制直方图的更多示例,请参见:可视化数据集的分布

方框图和触须图

盒式和触须图,简称盒式图,通常用于总结数据样本的分布。

x 轴用于表示数据样本,如果需要,可以在 x 轴上并排绘制多个箱线图。

y 轴代表观察值。绘制一个方框来总结数据集的中间 50%,从第 25 个百分位数的观察值开始,到第 75 个百分位数结束。这被称为四分位数区间,或 IQR。中间值,或第 50 个百分点,用一条线画出来。

称为须的线从盒子的两端延伸出来,计算为(1.5 * IQR),以展示分布中可感知值的预期范围。络腮胡子外的观察结果可能是异常值,用小圆圈表示。

通过调用 boxplot()函数并传递数据,可以在 Seaborn 中创建 boxplot。

我们将展示一个带有来自糖尿病分类数据集的数字变量的箱线图。我们将只绘制一个变量,在这种情况下,第一个变量,即患者怀孕的次数。

...
# create box and whisker plot
boxplot(x=0, data=dataset)

将这些联系在一起,完整的示例如下所示。

# box and whisker plot of a numerical variable
from pandas import read_csv
from seaborn import boxplot
from matplotlib import pyplot
# load the dataset
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/pima-indians-diabetes.csv'
dataset = read_csv(url, header=None)
# create box and whisker plot
boxplot(x=0, data=dataset)
# show plot
pyplot.show()

运行该示例首先加载糖尿病数据集,并创建第一个输入变量的箱线图,显示患者怀孕次数的分布。

我们可以看到中位数刚刚超过 2.5 倍,一些异常值上升了 15 倍左右(哇!).

Box and Whisker Plot of Number of Times Pregnant Numerical Variable

孕次数值变量的盒须图

我们可能还想对照类标签,为类别变量(如第一个变量)的每个值绘制数字变量的分布。

这可以通过调用 boxplot() 函数,将类变量作为 x 轴传递,将数值变量作为 y 轴传递来实现。

...
# create box and whisker plot
boxplot(x=8, y=0, data=dataset)

将这些联系在一起,完整的示例如下所示。

# box and whisker plot of a numerical variable vs class label
from pandas import read_csv
from seaborn import boxplot
from matplotlib import pyplot
# load the dataset
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/pima-indians-diabetes.csv'
dataset = read_csv(url, header=None)
# create box and whisker plot
boxplot(x=8, y=0, data=dataset)
# show plot
pyplot.show()

运行该示例首先加载糖尿病数据集,并创建数据的箱线图,将怀孕次数的分布显示为两类标签的数字变量。

Box and Whisker Plot of Number of Times Pregnant Numerical Variable by Class Label

按类别标签列出的数值变量怀孕次数的方框图和触须图

散点图

散点图通常用于总结两个配对数据样本之间的关系。

成对的数据样本意味着对于给定的观察记录了两个测量值,例如一个人的体重和身高。

x 轴代表第一个样本的观察值,y 轴代表第二个样本的观察值。图上的每个点代表一个单独的观察。

通过调用散点图()函数并传递两个数值变量,可以在 Seaborn 中创建散点图。

我们将用来自糖尿病分类数据集的两个数值变量演示散点图。我们将绘制第一个变量与第二个变量的对比图,在本例中,第一个变量是患者怀孕的次数,第二个是两小时口服葡萄糖耐量试验后的血浆葡萄糖浓度(变量的更多细节在此)。

...
# create scatter plot
scatterplot(x=0, y=1, data=dataset)

将这些联系在一起,完整的示例如下所示。

# scatter plot of two numerical variables
from pandas import read_csv
from seaborn import scatterplot
from matplotlib import pyplot
# load the dataset
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/pima-indians-diabetes.csv'
dataset = read_csv(url, header=None)
# create scatter plot
scatterplot(x=0, y=1, data=dataset)
# show plot
pyplot.show()

运行该示例首先加载糖尿病数据集,并创建前两个输入变量的散点图。

我们可以看到这两个变量之间有某种统一的关系。

Scatter Plot of Number of Times Pregnant vs. Plasma Glucose Numerical Variables

怀孕次数与血糖数值变量的散点图

我们可能还想绘制一对数值变量与类标签之间的关系。

这可以通过使用散点图()函数并通过“色调”参数指定类变量(列索引 8)来实现,如下所示:

...
# create scatter plot
scatterplot(x=0, y=1, hue=8, data=dataset)

将这些联系在一起,完整的示例如下所示。

# scatter plot of two numerical variables vs class label
from pandas import read_csv
from seaborn import scatterplot
from matplotlib import pyplot
# load the dataset
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/pima-indians-diabetes.csv'
dataset = read_csv(url, header=None)
# create scatter plot
scatterplot(x=0, y=1, hue=8, data=dataset)
# show plot
pyplot.show()

运行该示例首先加载糖尿病数据集,并创建前两个变量与类别标签的散点图。

Scatter Plot of Number of Times Pregnant vs. Plasma Glucose Numerical Variables by Class Label

按类别标记的怀孕次数与血糖数值变量的散点图

进一步阅读

如果您想更深入地了解这个主题,本节将提供更多资源。

教程

蜜蜂

摘要

在本教程中,您发现了针对机器学习的 Seaborn 数据可视化的温和介绍。

具体来说,您了解到:

  • 如何使用条形图、直方图、方框图和触须图总结变量的分布。
  • 如何用线图和散点图总结关系?
  • 如何比较同一图上不同类值的变量分布和关系?

你有什么问题吗? 在下面的评论中提问,我会尽力回答。

使用标签传播的半监督学习

原文:machinelearningmastery.com/semi-superv…

半监督学习是指试图同时利用已标记和未标记训练数据的算法。

半监督学习算法不像监督学习算法那样只能从有标签的训练数据中学习。

半监督学习的一种流行方法是创建一个连接训练数据集中的示例的图,并通过图的边缘传播已知的标签来标记未标记的示例。这种半监督学习方法的一个例子是用于分类预测建模的标签传播算法

在本教程中,您将发现如何将标签传播算法应用于半监督学习分类数据集。

完成本教程后,您将知道:

  • 标签传播半监督学习算法如何工作的直觉。
  • 如何使用监督学习算法开发半监督分类数据集并建立表现基线。
  • 如何开发和评估标签传播算法,并使用模型输出来训练监督学习算法。

我们开始吧。

Semi-Supervised Learning With Label Propagation

带标签传播的半监督学习 图片由the blues dud提供,保留部分权利。

教程概述

本教程分为三个部分;它们是:

  1. 标签传播算法
  2. 半监督分类数据集
  3. 半监督学习中的标签传播

标签传播算法

标签传播是一种半监督学习算法。

该算法是在 2002 年朱晓金和邹斌·盖拉马尼的技术报告中提出的,该报告的标题为“利用标签传播从有标签和无标签数据中学习”

该算法的直觉是创建了一个图形,该图形根据距离连接数据集中的所有示例(行),例如欧几里德距离。然后,图中的节点具有基于图中邻近连接的示例的标签或标签分布的标签软标签或标签分布。

许多半监督学习算法依赖于由标记和未标记的例子所诱导的数据的几何形状来改进仅使用标记数据的监督方法。这种几何形状自然可以用经验图 g = (V,E)来表示,其中节点 V = {1,…,n}表示训练数据,边 E 表示它们之间的相似性

—第 193 页,半监督学习,2006。

传播指的是标签被分配给图中的节点并沿着图的边传播到连接的节点的迭代性质。

这个过程有时被称为标签传播,因为它将标签从已标记的顶点(固定的)通过边逐渐“传播”到所有未标记的顶点。

—第 48 页,半监督学习介绍,2009。

该过程重复固定次数的迭代,以加强分配给未标记示例的标签。

从用已知标签(1 或 1)标记的节点 1、2、…、l 和用 0 标记的节点 l + 1、…、n 开始,每个节点开始将其标签传播给其邻居,并且重复该过程直到收敛。

—第 194 页,半监督学习,2006。

现在我们已经熟悉了标签传播算法,让我们看看如何在项目中使用它。首先,我们必须定义一个半监督分类数据集。

半监督分类数据集

在本节中,我们将为半监督学习定义一个数据集,并在该数据集上建立一个表现基线。

首先,我们可以使用make _ classion()函数定义一个合成分类数据集。

我们将用两个类(二进制分类)和两个输入变量以及 1000 个示例来定义数据集。

...
# define dataset
X, y = make_classification(n_samples=1000, n_features=2, n_informative=2, n_redundant=0, random_state=1)

接下来,我们将数据集分割成训练数据集和测试数据集,分割比例为 50-50(例如,每组 500 行)。

...
# split into train and test
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.50, random_state=1, stratify=y)

最后,我们将训练数据集再次分成两部分,一部分有标签,另一部分我们假装没有标签。

...
# split train into labeled and unlabeled
X_train_lab, X_test_unlab, y_train_lab, y_test_unlab = train_test_split(X_train, y_train, test_size=0.50, random_state=1, stratify=y_train)

将这些联系在一起,下面列出了准备半监督学习数据集的完整示例。

# prepare semi-supervised learning dataset
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
# define dataset
X, y = make_classification(n_samples=1000, n_features=2, n_informative=2, n_redundant=0, random_state=1)
# split into train and test
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.50, random_state=1, stratify=y)
# split train into labeled and unlabeled
X_train_lab, X_test_unlab, y_train_lab, y_test_unlab = train_test_split(X_train, y_train, test_size=0.50, random_state=1, stratify=y_train)
# summarize training set size
print('Labeled Train Set:', X_train_lab.shape, y_train_lab.shape)
print('Unlabeled Train Set:', X_test_unlab.shape, y_test_unlab.shape)
# summarize test set size
print('Test Set:', X_test.shape, y_test.shape)

运行该示例准备数据集,然后总结三个部分的形状。

结果证实,我们有一个 500 行的测试数据集、一个 250 行的标记训练数据集和 250 行的未标记数据。

Labeled Train Set: (250, 2) (250,)
Unlabeled Train Set: (250, 2) (250,)
Test Set: (500, 2) (500,)

一个有监督的学习算法只有 250 行来训练一个模型。

半监督学习算法将具有 250 个标记行以及 250 个未标记行,这些行可以以多种方式用于改进标记的训练数据集。

接下来,我们可以使用仅适用于标记训练数据的监督学习算法,在半监督学习数据集上建立表现基线。

这一点很重要,因为我们期望半监督学习算法的表现优于仅适用于标记数据的监督学习算法。如果不是这样,那么半监督学习算法就没有技巧。

在这种情况下,我们将使用逻辑回归算法来拟合训练数据集的标记部分。

...
# define model
model = LogisticRegression()
# fit model on labeled dataset
model.fit(X_train_lab, y_train_lab)

然后,该模型可用于对整个搁置测试数据集进行预测,并使用分类精确率进行评估。

...
# make predictions on hold out test set
yhat = model.predict(X_test)
# calculate score for test set
score = accuracy_score(y_test, yhat)
# summarize score
print('Accuracy: %.3f' % (score*100))

将这些联系在一起,下面列出了在半监督学习数据集上评估监督学习算法的完整示例。

# baseline performance on the semi-supervised learning dataset
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.linear_model import LogisticRegression
# define dataset
X, y = make_classification(n_samples=1000, n_features=2, n_informative=2, n_redundant=0, random_state=1)
# split into train and test
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.50, random_state=1, stratify=y)
# split train into labeled and unlabeled
X_train_lab, X_test_unlab, y_train_lab, y_test_unlab = train_test_split(X_train, y_train, test_size=0.50, random_state=1, stratify=y_train)
# define model
model = LogisticRegression()
# fit model on labeled dataset
model.fit(X_train_lab, y_train_lab)
# make predictions on hold out test set
yhat = model.predict(X_test)
# calculate score for test set
score = accuracy_score(y_test, yhat)
# summarize score
print('Accuracy: %.3f' % (score*100))

运行该算法使模型适合标记的训练数据集,并在保持数据集上对其进行评估,并打印分类精确率。

:考虑到算法或评估程序的随机性,或数值精确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。

在这种情况下,我们可以看到该算法实现了大约 84.8%的分类准确率。

我们期望一种有效的半监督学习算法能获得比这更好的精确率。

Accuracy: 84.800

接下来,让我们探索如何将标签传播算法应用于数据集。

半监督学习中的标签传播

标签传播算法可通过标签传播类在 Sklearn Python 机器学习库中获得。

通过调用 fit() 函数,该模型可以像任何其他分类模型一样进行拟合,并通过 predict() 函数用于对新数据进行预测。

...
# define model
model = LabelPropagation()
# fit model on training dataset
model.fit(..., ...)
# make predictions on hold out test set
yhat = model.predict(...)

重要的是,提供给 fit() 函数的训练数据集必须包括整数编码的已标记示例(按照正常情况)和标记为-1 的未标记示例。

然后,作为拟合模型的一部分,模型将确定未标记示例的标签。

模型拟合后,训练数据集中已标记和未标记数据的估计标签可通过标签传播类上的“转导 _ ”属性获得。

...
# get labels for entire training dataset data
tran_labels = model.transduction_

现在我们已经熟悉了如何在 Sklearn 中使用标签传播算法,让我们看看如何将其应用于我们的半监督学习数据集。

首先,我们必须准备训练数据集。

我们可以将训练数据集的输入数据连接成一个数组。

...
# create the training dataset input
X_train_mixed = concatenate((X_train_lab, X_test_unlab))

然后,我们可以为训练数据集中未标记部分的每一行创建一个-1 值(未标记)的列表。

...
# create "no label" for unlabeled data
nolabel = [-1 for _ in range(len(y_test_unlab))]

然后,该列表可以与来自训练数据集标记部分的标签连接起来,以对应于训练数据集的输入数组。

...
# recombine training dataset labels
y_train_mixed = concatenate((y_train_lab, nolabel))

我们现在可以在整个训练数据集上训练标签传播模型。

...
# define model
model = LabelPropagation()
# fit model on training dataset
model.fit(X_train_mixed, y_train_mixed)

接下来,我们可以使用该模型对保持数据集进行预测,并使用分类精确率评估该模型。

...
# make predictions on hold out test set
yhat = model.predict(X_test)
# calculate score for test set
score = accuracy_score(y_test, yhat)
# summarize score
print('Accuracy: %.3f' % (score*100))

将这些联系在一起,下面列出了在半监督学习数据集上评估标签传播的完整示例。

# evaluate label propagation on the semi-supervised learning dataset
from numpy import concatenate
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.semi_supervised import LabelPropagation
# define dataset
X, y = make_classification(n_samples=1000, n_features=2, n_informative=2, n_redundant=0, random_state=1)
# split into train and test
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.50, random_state=1, stratify=y)
# split train into labeled and unlabeled
X_train_lab, X_test_unlab, y_train_lab, y_test_unlab = train_test_split(X_train, y_train, test_size=0.50, random_state=1, stratify=y_train)
# create the training dataset input
X_train_mixed = concatenate((X_train_lab, X_test_unlab))
# create "no label" for unlabeled data
nolabel = [-1 for _ in range(len(y_test_unlab))]
# recombine training dataset labels
y_train_mixed = concatenate((y_train_lab, nolabel))
# define model
model = LabelPropagation()
# fit model on training dataset
model.fit(X_train_mixed, y_train_mixed)
# make predictions on hold out test set
yhat = model.predict(X_test)
# calculate score for test set
score = accuracy_score(y_test, yhat)
# summarize score
print('Accuracy: %.3f' % (score*100))

运行该算法使模型适合整个训练数据集,并在保持数据集上对其进行评估,并打印分类精确率。

:考虑到算法或评估程序的随机性,或数值精确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。

在这种情况下,我们可以看到标签传播模型实现了大约 85.6%的分类准确率,这略高于仅在实现了大约 84.8%准确率的标签训练数据集上的逻辑回归拟合。

Accuracy: 85.600

目前为止,一切顺利。

对于半监督模型,我们可以使用的另一种方法是获取训练数据集的估计标签,并拟合监督学习模型。

回想一下,我们可以从标签传播模型中检索整个训练数据集的标签,如下所示:

...
# get labels for entire training dataset data
tran_labels = model.transduction_

然后,我们可以使用这些标签以及所有输入数据来训练和评估监督学习算法,例如逻辑回归模型。

希望适合整个训练数据集的监督学习模型将获得比单独的半监督学习模型更好的表现。

...
# define supervised learning model
model2 = LogisticRegression()
# fit supervised learning model on entire training dataset
model2.fit(X_train_mixed, tran_labels)
# make predictions on hold out test set
yhat = model2.predict(X_test)
# calculate score for test set
score = accuracy_score(y_test, yhat)
# summarize score
print('Accuracy: %.3f' % (score*100))

将这些联系在一起,下面列出了使用估计的训练集标签来训练和评估监督学习模型的完整示例。

# evaluate logistic regression fit on label propagation for semi-supervised learning
from numpy import concatenate
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.semi_supervised import LabelPropagation
from sklearn.linear_model import LogisticRegression
# define dataset
X, y = make_classification(n_samples=1000, n_features=2, n_informative=2, n_redundant=0, random_state=1)
# split into train and test
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.50, random_state=1, stratify=y)
# split train into labeled and unlabeled
X_train_lab, X_test_unlab, y_train_lab, y_test_unlab = train_test_split(X_train, y_train, test_size=0.50, random_state=1, stratify=y_train)
# create the training dataset input
X_train_mixed = concatenate((X_train_lab, X_test_unlab))
# create "no label" for unlabeled data
nolabel = [-1 for _ in range(len(y_test_unlab))]
# recombine training dataset labels
y_train_mixed = concatenate((y_train_lab, nolabel))
# define model
model = LabelPropagation()
# fit model on training dataset
model.fit(X_train_mixed, y_train_mixed)
# get labels for entire training dataset data
tran_labels = model.transduction_
# define supervised learning model
model2 = LogisticRegression()
# fit supervised learning model on entire training dataset
model2.fit(X_train_mixed, tran_labels)
# make predictions on hold out test set
yhat = model2.predict(X_test)
# calculate score for test set
score = accuracy_score(y_test, yhat)
# summarize score
print('Accuracy: %.3f' % (score*100))

运行该算法将半监督模型拟合到整个训练数据集上,然后将监督学习模型拟合到具有推断标签的整个训练数据集上,并在保持数据集上对其进行评估,打印分类精确率。

:考虑到算法或评估程序的随机性,或数值精确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。

在这种情况下,我们可以看到,半监督模型跟随监督模型的这种分层方法在保持数据集上实现了大约 86.2%的分类精确率,甚至优于单独使用的半监督学习,后者实现了大约 85.6%的精确率。

Accuracy: 86.200

通过调整 LabelPropagation 模型的超参数,能达到更好的效果吗? 让我知道你在下面的评论中发现了什么。

进一步阅读

如果您想更深入地了解这个主题,本节将提供更多资源。

报纸

蜜蜂

文章

摘要

在本教程中,您发现了如何将标签传播算法应用于半监督学习分类数据集。

具体来说,您了解到:

  • 标签传播半监督学习算法如何工作的直觉。
  • 如何使用监督学习算法开发半监督分类数据集并建立表现基线。
  • 如何开发和评估标签传播算法,并使用模型输出来训练监督学习算法。

你有什么问题吗? 在下面的评论中提问,我会尽力回答。