了解机器学习中标准化的概念

2022-12-08 12:18 438 阅读 ID:577
磐创AI
磐创AI

介绍

标准化是一种特征缩放技术,它以这样的方式缩小数据,即依赖于距离和权重的算法(如KNN、Logistic Regression等)不应受到不均匀缩放数据集的影响,因为如果发生这种情况,则模型精度将不会很好(将在实际中显示出来)。

如果我们将以数据点以均值为中心且分布的标准偏差为1的方式均匀地缩放数据,则算法将平等地处理权重。

在本文中,我们不仅会看到如何使用 Python 在机器学习中进行标准缩放,还会看到缩放的效果。比较分布(缩放前后),以便了解缩放如何影响样本空间,最后,我们将会展示标准缩放是否有助于消除异常值。

import numpy as np # linear algebra
import pandas as pd # data processing
import matplotlib.pyplot as plt
import seaborn as sns

我们正在导入一些必需的库,这将有助于实施标准化。

  • Numpy:用于求解与线性代数相关的方程。
  • Pandas:用于 DataFrame 操作和预处理。
  • Matplotlib 和 Seaborn:用于数据可视化和查看分布。
df = pd.read_csv('Social_Network_Ads.csv')
df=df.iloc[:,2:]
df.sample(5)
import numpy as np # linear algebra
import pandas as pd # data processing
# import matplotlib.pyplot as plt
# import seaborn as sns

df = pd.read_csv('Social_Network_Ads.csv')
df=df.iloc[:,2:]
print(df.sample(5))

输出:

     Age  EstimatedSalary  Purchased
388   47            34000          1
360   43           129000          1
70    25            80000          0
339   39           122000          1
370   60            46000          1

推论:为了实施标准化技术,我们使用社交网络广告代理数据集。请注意,这里我只保留必要的列,以便将重点放在概念上,而不是理解数据集的复杂性。通过查看一组不同的样本来探索数据集。

训练测试拆分

  from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(df.drop('Purchased', axis=1),
                                                    df['Purchased'],
                                                    test_size=0.3,
                                                    random_state=0)

X_train.shape, X_test.shape  

输出:

((280, 2), (120, 2))

推论:在进行标准缩放之前是否进行训练测试拆分总是存在争议,但在我看来,在标准化之前进行这一步是至关重要的,如果我们缩放了整个数据,那么对于我们的算法来说,可能就没有测试数据了,这最终会导致过度拟合的情况。另一方面,如果我们现在只缩放训练数据,那么我们仍然会有测试数据。

StandardScaler

from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()

# fit the scaler to the train set, it will learn the parameters
scaler.fit(X_train)

# transform train and test sets
X_train_scaled = scaler.transform(X_train)
X_test_scaled = scaler.transform(X_test)

代码分解:

  1. 在应用标准缩放之前,我们需要从SKLEARN.preprocessing导入StandardScaler模块并启动该对象的实例。
  2. 然后我们只使用fit函数来训练数据集。正如我们所讨论的,这很重要,为了避免过度拟合的情况,我们只使用训练数据集。
  3. 第三步,标准缩放是转换训练和测试数据集。请注意,这里我们使用的是整个数据集,而不仅仅是训练数据集。
scaler.mean_

输出:

array([3.78642857e+01, 6.98071429e+04])

推论:上面的输出都是关于我们在标准化过程中以均值为中心后得到的两个特征的相应平均值。

X_train_scaled = pd.DataFrame(X_train_scaled, columns=X_train.columns)
X_test_scaled = pd.DataFrame(X_test_scaled, columns=X_test.columns)

推论:尽管我们有DataFrame形式的X_train和X_test,但当我们看到X_train_scaled和X_test_scaled时,它将返回NumPy数组结构,我们首先将其转换为DataFrame。

np.round(X_train.describe(), 1)

输出:

![](http://qiniu.aihubs.net/Standardization (4).png)

np.round(X_train_scaled.describe(), 1)

输出:

推论:以上两个输出仅用于记录两种情况的平均值(Scaled 和 Pre-Scaled数据)。其中 Pre-Scaled 数据集有一些平均值和标准偏差,而另一方面 Scaled 数据有平均值 0 和标准偏差 1,如果符合这种情况,则意味着我们已经成功地缩放了数据集。

缩放效果

在本文的这一部分,我们将看到标准化对模型准确性的可能影响,以及这些技术对哪些类型的算法有用。让我们做一些可视化。

fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(12, 5))

ax1.scatter(X_train['Age'], X_train['EstimatedSalary'])
ax1.set_title("Before Scaling")
ax2.scatter(X_train_scaled['Age'], X_train_scaled['EstimatedSalary'],color='red')
ax2.set_title("After Scaling")
plt.show()

输出:

推论:不要在上面的图中选择红点和蓝点, 因为它们是相同的。真正的区别在于 X 和 Y 尺度;缩放后,我们可以看到均值发生了变化,现在它位于原点(标准缩放的条件)。

fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(12, 5))

# before scaling
ax1.set_title('Before Scaling')
sns.kdeplot(X_train['Age'], ax=ax1)
sns.kdeplot(X_train['EstimatedSalary'], ax=ax1)

# after scaling
ax2.set_title('After Standard Scaling')
sns.kdeplot(X_train_scaled['Age'], ax=ax2)
sns.kdeplot(X_train_scaled['EstimatedSalary'], ax=ax2)
plt.show()

输出:

推论:现在查看使用KDE 图对缩放和非缩放数据的概率密度函数。在非缩放数据的情况下,我们只能在 Y 轴上看到 Age,在 X 轴上看到 Estimated Salary, 这是因为数据不是均匀缩放的,但另一方面,当缩放完成时然后,这两个特征都在样本空间中流动良好。

分布比较

在这里,我们将比较Age和Estimated Salary分布的分布图,看看标准化过程之后是否会对数据集的分布产生任何影响。

fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(12, 5))

# before scaling
ax1.set_title('Age Distribution Before Scaling')
sns.kdeplot(X_train['Age'], ax=ax1)

# after scaling
ax2.set_title('Age Distribution After Standard Scaling')
sns.kdeplot(X_train_scaled['Age'], ax=ax2)
plt.show()

输出:

fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(12, 5))

# before scaling
ax1.set_title('Salary Distribution Before Scaling')
sns.kdeplot(X_train['EstimatedSalary'], ax=ax1)

# after scaling
ax2.set_title('Salary Distribution Standard Scaling')
sns.kdeplot(X_train_scaled['EstimatedSalary'], ax=ax2)
plt.show()

输出:

推论:在上面的两个图中,我们已经看到了两种情况下的特征,即缩放之前和缩放之后,并获得了确凿的证据表明标准化不会改变分布,只是数据的规模会改变。

为什么缩放很重要?

到目前为止,我们看到了缩放如何影响数据集的分布和性质。现在是时候看看为什么缩放在模型构建之前很重要,或者它如何提高模型的准确性。

除此之外,我们还将看到哪种算法显示了效果,我们采用了两种算法,即逻辑回归,其中距离有很大的意义,另一种是决策树,与距离无关。

那么,让我们看看这两种算法将如何对标准缩放做出反应。

from sklearn.linear_model import LogisticRegression

# Building Logistic Regression instance
lr = LogisticRegression()
lr_scaled = LogisticRegression()

# Model training
lr.fit(X_train,y_train)
lr_scaled.fit(X_train_scaled,y_train)

# Storing the predictions of both scaled and pre-scaled data
y_pred = lr.predict(X_test)
y_pred_scaled = lr_scaled.predict(X_test_scaled)

from sklearn.metrics import accuracy_score
print("Actual",accuracy_score(y_test,y_pred))
print("Scaled",accuracy_score(y_test,y_pred_scaled))

输出:

Actual 0.6583333333333333
Scaled 0.8666666666666667

推断:在上面的代码中,我们首先导入了Logistic Regression,然后按照与之前相同的每个步骤使用标准缩放对数据进行了缩放,当我们将实际数据模型的准确性与缩放数据进行比较时,我们发现在这种算法的情况下缩放数据非常有帮助,因为准确度从65% 提高到 87%。

from sklearn.tree import DecisionTreeClassifier

dt = DecisionTreeClassifier()
dt_scaled = DecisionTreeClassifier()

dt.fit(X_train,y_train)
dt_scaled.fit(X_train_scaled,y_train)

y_pred = dt.predict(X_test)
y_pred_scaled = dt_scaled.predict(X_test_scaled)

print("Actual",accuracy_score(y_test,y_pred))
print("Scaled",accuracy_score(y_test,y_pred_scaled))

输出:

Actual 0.875
Scaled 0.875

推论:正如我们在前面的ML算法中所做的一样,我们在决策树分类器中也做了同样的事情,但在这种情况下,我们可以看到缩放并没有提高模型的准确性,因为缩放对于KNN、PCA等依赖于距离的算法是有帮助的。

标准化后异常值的影响

这是我们将在本文课程中讨论的最后一件事,在这里我们将了解标准化后异常值的影响,即标准缩放是否可以去除异常值或者它对它们没有影响。因此,让我们快速找出答案。

df = df.append(pd.DataFrame({'Age':[5,90,95],'EstimatedSalary':[1000,250000,350000],'Purchased':[0,1,1]}),ignore_index=True)
df

输出:

推论: 在上面的代码中,我们追加(添加)了三个新数据点,通过这些数据点的值,我们可以假设它们将是整个样本空间中的异常值。

plt.scatter(df['Age'], df['EstimatedSalary'])

输出:

推论:在上图中,我们可以看到三个完全不同的数据点,这是我们刚刚在原始数据集中估算的异常值

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(df.drop('Purchased', axis=1),
                                                    df['Purchased'],
                                                    test_size=0.3,
                                                    random_state=0)

X_train.shape, X_test.shape

输出:

((282, 2), (121, 2))

正如开头提到的关于训练测试拆分的那样,在使用标准缩放之前遵循这种技术是一种很好的做法(推荐但不是必需的)。

from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()

# fit the scaler to the train set, it will learn the parameters
scaler.fit(X_train)

# transform train and test sets
X_train_scaled = scaler.transform(X_train)
X_test_scaled = scaler.transform(X_test)

推理:同样,使用StandardScaler在训练集上的拟合函数对数据集进行标准化,并同时转换测试集和训练集。

X_train_scaled = pd.DataFrame(X_train_scaled, columns=X_train.columns)
X_test_scaled = pd.DataFrame(X_test_scaled, columns=X_test.columns)
fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(12, 5))

ax1.scatter(X_train['Age'], X_train['EstimatedSalary'])
ax1.set_title("Before Scaling")
ax2.scatter(X_train_scaled['Age'], X_train_scaled['EstimatedSalary'],color='red')
ax2.set_title("After Scaling")
plt.show()

输出

推论:从上面的代码中,我们绘制了缩放前后的刺激,从结果中可以看出,标准缩放不会影响异常值,因为数据点根本没有改变它们的位置。

结论

本文要点:

  1. 首先,我们讨论了标准缩放,然后我们在应用标准化之前了解了训练测试拆分的重要性。
  2. 然后我们比较了这两种情况下数据集的分布,即,对于实际数据集和缩放后的数据集,在查看分布之后,我们得到了分布没有改变的结论性证据。
  3. 然后我们通过比较两种最常用的算法(但背后有不同的数学直觉)了解了为什么缩放很重要。最后一个主题是对离群值的影响,我们观察所输出的图,离群值没有影响。

这是本文的 github 链接:

https://github.com/Aman-Preet-Singh-Gulati/interview-preparation/tree/main/Blog%203

免责声明:作者保留权利,不代表本站立场。如想了解更多和作者有关的信息可以查看页面右侧作者信息卡片。
反馈
to-top--btn