Linear Regression
Motivation
当我们看到数据集时,我们会尝试找出它的含义。 我们寻找数据点之间的连接,看看我们是否能找到任何模式。 有时这些模式很难看到,所以我们使用代码来帮助我们找到它们。 数据可以遵循许多不同的模式,因此如果我们可以缩小这些选项并编写更少的代码来分析它们,这将有所帮助。 其中一种模式是线性关系。 如果我们可以在数据中找到这种模式,我们可以使用线性回归技术来分析它。
Overview
线性回归是一种用于分析输入变量和单个输出变量之间的线性关系的技术。 线性关系意味着数据点倾向于遵循直线。 简单线性回归仅涉及单个输入变量。 图1显示了具有线性关系的数据集。
code:
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import datasets, linear_model
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
# Create a data set for analysis
x, y = make_regression(n_samples=500, n_features = 1, noise=25, random_state=0)
# Split the data set into testing and training data
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=0)
# Plot the data
sns.set_style("darkgrid")
sns.regplot(x_test, y_test, fit_reg=False)
# Remove ticks from the plot
plt.xticks([])
plt.yticks([])
plt.tight_layout()
plt.show()
我们的目标是找到最佳模拟数据点路径的线,称为最佳拟合线。 等式1中的等式是线性等式的示例。
图2显示了我们在图1中使用的数据集,其中包含最佳拟合线。
code:
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import datasets, linear_model
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
# Create a data set for analysis
x, y = make_regression(n_samples=500, n_features = 1, noise=25, random_state=0)
# Split the data set into testing and training data
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=0)
# Create a linear regression object
regression = linear_model.LinearRegression()
# Train the model using the training set
regression.fit(x_train, y_train)
# Make predictions using the testing set
y_predictions = regression.predict(x_test)
# Plot the data
sns.set_style("darkgrid")
sns.regplot(x_test, y_test, fit_reg=False)
plt.plot(x_test, y_predictions, color='black')
# Remove ticks from the plot
plt.xticks([])
plt.yticks([])
plt.tight_layout()
plt.show()
让我们分解吧。 我们已经知道x是输入值,y是我们预测的输出。 a0和a1描述了我们的线的形状。 a0称为偏差,a1称为权重。 改变a0将在图上向上或向下移动线,改变a1会改变线的斜率。 线性回归有助于我们选择适当的a0和a1值。
请注意,我们可以有多个输入变量。 在这种情况下,我们称之为多元线性回归。 添加额外的输入变量只意味着我们需要找到更多的权重。 对于本练习,我们只考虑简单的线性回归。
When to Use
线性回归是一种有用的技术,但并不总是您数据的正确选择。 当您的独立变量和因变量之间存在线性关系并且您试图预测连续值时,线性回归是一个不错的选择[图1]。
当独立变量和因变量之间的关系更复杂或输出是离散值时,它不是一个好的选择。 例如,图3显示了一个没有线性关系的数据集,因此线性回归不是一个好的选择。
code:
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import datasets, linear_model
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
# Create a data set for analysis
x, y = make_regression(n_samples=500, n_features = 1, noise=25, random_state=0)
y = y ** 2
# Split the data set into testing and training data
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=0)
# Plot the data
sns.set_style("darkgrid")
sns.regplot(x_test, y_test, fit_reg=False)
# Remove ticks from the plot
plt.xticks([])
plt.yticks([])
plt.tight_layout()
plt.show()
值得注意的是,有时您可以将转换应用于数据,使其看起来是线性的。 例如,您可以将对数应用于指数数据以将其展平。 然后,您可以对转换后的数据使用线性回归。 这里记录了一种在sklearn中转换数据的方法。
图4是不看起来线性但可以转换为具有线性关系的数据的示例。
code:
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
from sklearn import datasets, linear_model
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
# Create a data set for analysis
x, y = make_regression(n_samples=500, n_features = 1, noise=25, random_state=0)
y = np.exp((y + abs(y.min())) / 75)
# Split the data set into testing and training data
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=0)
# Plot the data
sns.set_style("darkgrid")
sns.regplot(x_test, y_test, fit_reg=False)
# Remove ticks from the plot
plt.xticks([])
plt.yticks([])
plt.tight_layout()
plt.show()
图5是用对数转换输出变量后的相同数据。
code:
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
from sklearn import datasets, linear_model
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
# Create a data set for analysis
x, y = make_regression(n_samples=500, n_features = 1, noise=25, random_state=0)
y = np.exp((y + abs(y.min())) / 75)
# Transform data so that it looks linear
y = np.log(y)
# Split the data set into testing and training data
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=0)
# Plot the data
sns.set_style("darkgrid")
sns.regplot(x_test, y_test, fit_reg=False)
# Remove ticks from the plot
plt.xticks([])
plt.yticks([])
plt.tight_layout()
plt.show()
Cost Function
一旦我们做出预测,我们需要一些方法来判断它是否合理。 成本函数可以帮助我们做到这一点。 成本函数将所有预测与其实际值进行比较,并为我们提供可用于对预测函数进行评分的单个数字。 图6显示了一个这样的预测的成本。
code:
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import datasets, linear_model
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
# Create a data set for analysis
x, y = make_regression(n_samples=500, n_features = 1, noise=25, random_state=0)
# Split the data set into testing and training data
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=0)
# Create a linear regression object
regression = linear_model.LinearRegression()
# Train the model using the training set
regression.fit(x_train, y_train)
# Make predictions using the testing set
y_predictions = regression.predict(x_test)
# Grab a sample pair of points to analyze cost
point_number = 2
x_sample = [x_test[point_number].item(), x_test[point_number].item()]
y_sample = [y_test[point_number].item(), y_predictions[point_number].item()]
# Plot the data
sns.set_style("darkgrid")
sns.regplot(x_test, y_test, fit_reg=False)
plt.plot(x_test, y_predictions, color='black')
plt.plot(x_sample, y_sample, color='red', label="cost", marker='o')
# Add a legend
n = ['actual value', 'prediction']
for i, txt in enumerate(n):
plt.annotate(txt, (x_sample[i], y_sample[i]), xytext=(10, -10),
textcoords='offset pixels', fontsize=20)
plt.legend(fontsize=20)
# Remove ticks from the plot
plt.xticks([])
plt.yticks([])
plt.tight_layout()
plt.show()
成本函数中出现的两个常见术语是误差和平方误差。 误差[等式2]是我们预测的实际值有多远。
平方此值为我们提供了一般误差距离的有用表达式,如公式3所示。
我们知道实际值之上的误差为2,而实际值之下的误差2应该与彼此差不多。 平方误差使这一点变得清晰,因为这两个值都导致平方误差为4。
我们将使用公式4中所示的均方误差(MSE)函数作为我们的成本函数。 此函数查找所有数据点的平均误差值。
成本函数对我们很重要,因为它们可以衡量模型与目标值的准确程度。 确保我们的模型准确无疑将是后续模块的关键主题。
Methods
较低的成本函数意味着数据点的平均误差较低。 换句话说,较低的成本意味着数据集的更准确的模型。 我们将简要提及一些最小化成本函数的方法。
Ordinary Least Squares
普通最小二乘法是最小化成本函数的常用方法。 在这种方法中,我们将数据视为一个大矩阵,并使用线性代数来估计线性方程中系数的最优值。 幸运的是,你不必担心做任何线性代数,因为Python代码会为你处理它。 这也恰好是用于此模块代码的方法。
以下是此模块中与普通最小二乘相关的Python代码的相关行。
Gradient Descent
梯度下降是一种猜测线性方程系数的迭代方法,以便最小化成本函数。 这个名字来自于微积分中渐变的概念。 基本上,这种方法会略微移动系数的值,并监控成本是否降低。 如果成本在几次迭代中持续增加,我们就会停止,因为我们可能已经达到了最低限度。 可以选择停止前的迭代次数和容差来微调方法。
下面是修改为使用渐变下降的此模块的相关Python代码行。
Code
该模块的主要代码可在linear_regression_lobf.py文件中找到。
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import datasets, linear_model
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
# Create a data set for analysis
x, y = make_regression(n_samples=500, n_features = 1, noise=25, random_state=0)
# Split the data set into testing and training data
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=0)
# Create a linear regression object
regression = linear_model.LinearRegression()
# Train the model using the training set
regression.fit(x_train, y_train)
# Make predictions using the testing set
y_predictions = regression.predict(x_test)
# Plot the data
sns.set_style("darkgrid")
sns.regplot(x_test, y_test, fit_reg=False)
plt.plot(x_test, y_predictions, color='black')
# Remove ticks from the plot
plt.xticks([])
plt.yticks([])
plt.tight_layout()
plt.show()
此模块中的所有数字都是通过对linear_regression.py代码进行简单修改而创建的。
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import datasets, linear_model
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
# Create a data set for analysis
x, y = make_regression(n_samples=500, n_features = 1, noise=25, random_state=0)
# Split the data set into testing and training data
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=0)
# Plot the data
sns.set_style("darkgrid")
sns.regplot(x_test, y_test, fit_reg=False)
# Remove ticks from the plot
plt.xticks([])
plt.yticks([])
plt.tight_layout()
plt.show()
在代码中,我们分析具有线性关系的数据集。 我们将数据分成训练集来训练我们的模型和测试集以测试其准确性。 您可能已经猜到所使用的模型基于线性回归。 我们还使用最佳拟合线显示数据的精美图表。
Conclusion
在本单元中,我们学习了线性回归。 这种技术有助于我们使用线性关系建模数据。 线性关系相当简单但仍然出现在很多数据集中,因此这是一个很好的技术。 学习线性回归是学习更复杂分析技术的良好开端。 我们将在后面的模块中介绍这里介绍的许多概念。