了解特征缩放对机器学习模型的影响

388 阅读8分钟

特征扩展对机器学习模型的影响

在机器学习中,我们用来训练模型的数据集有不可预测的数值,这些数值可能会在大范围内相互变化。数值之间可能会有很大的差异,特别是当它们代表不同的尺度时,这可能会使它们难以比较,例如,公斤、升、毫米、英里、像素等。

特征缩放的引入就是为了解决这个难题。它对数字进行调整,使其容易比较那些不在彼此范围内的数值。这有助于提高模型的准确性,特别是那些使用对特征缩放敏感的算法,即梯度下降算法和基于距离的算法。

有两种缩放特征的技术。

  1. 归一化--数值被重新划分为0和1之间的范围。
  2. 标准化--数值被重新调整到以标准差为单位的平均值为中心。

选择在你的数据集上使用哪种方法,要根据你的数据集、机器学习算法和你可能解决的问题类型来决定。

在这个方法中,我们将学习如何实现每种方法。我们将首先建立一个没有特征缩放的预测模型,一个有标准化特征的预测模型,最后是一个有规范化特征的预测模型。我们还将为这三者使用相同的数据集,以比较我们的数据集如何影响我们对技术的选择。

前提条件

我们需要具备以下条件

  1. Python编程语言的基本知识。
  2. 机器学习的基础知识。
  3. Jupyter Notebook/ Jupyter Lab/ Google Colab。

使用给定的数据进行训练,我们将建立模型来预测一个病人是否被诊断为疾病MB

导入库

在我们的笔记本中,让我们导入以下库并运行单元。

import pandas as pd
import numpy as np
from sklearn.preprocessing import LabelEncoder, StandardScaler, MinMaxScaler
from sklearn.model_selection import train_test_split
from sklearn.svm import LinearSVC,SVC
from sklearn.metrics import classification_report

1.初始模型

(i) 从github获取数据集

我们将使用pandas从原始数据集的URL中读取CSV文件。

url = 'https://github.com/Sajeyks/Section-dataset1/blob/main/data.csv?raw=true'
df = pd.read_csv(url,index_col=0)

(ii) 探索我们的数据集

我们将使用df.info ,检查我们的数据集由哪些部分组成。

df.info()

输出。

df.info()

正如你所看到的,我们的数据集包含32个列,其中大部分是浮点,一个包含对象。前31列也处于良好状态;因此不需要替换或删除一些行。

我们还可以使用df.head() ,看看我们数据集前十行的数值。

df.head(10)

输出。

fd.head(10)

(iii) 准备数据集

现在我们将选择一组能够影响我们数据集中因变量(诊断)的属性。

my_features = ['radius_mean', 'perimeter_mean', 'area_mean', 'compactness_mean', 'concavity_mean', 'concave points_mean',
               'perimeter_worst', 'area_worst', 'compactness_worst', 'concavity_worst', 'concave points_worst']

然后我们将在y(dependent)X(independent) 变量之间分割数据。

y = df.diagnosis
X = df[my_features]

正如我们在上面看到的,y(diagnosis)是一个对象数据类型,用于表示诊断的状态。机器学习算法只与数值打交道;因此我们需要用数字来表示我们的诊断状态。为了做到这一点,我们将使用LabelEncoder 。我们有两个类别的诊断状态,MB 。标签编码器将把它们分别改为10 的类别。

lb = LabelEncoder()
y = lb.fit_transform(df.diagnosis)

如果你现在检查y ,你会看到它转变为一个数组1's0's

print(y)

输出。

print(y)

之后,我们现在可以继续将我们的数据集按30:70的比例分成训练集和测试集。

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=1)

(iv) 拟合模型

我们将使用LinearSVC ,建立一个支持向量分类器模型,将我们的数据归类为两种诊断状态中的一种。

classifier = LinearSVC()
# fitting model
classifier.fit(X_train,y_train)
# predict
y_predict = classifier.predict(X_test)
# check accuracy
accuracy_b4 = classifier.score(X_test, y_test)

(v) 预测

然后我们可以同时打印预测和测试样本,并尝试比较结果。

print(y_predict)

print(y_predict)

print(y_test)

print(y_test)

2.使用标准比例

我们将建立另一个模型,在拟合前使用standard scaling ,对数据集进行分级。

(i) 创建和分析数据框架

使用下面的代码导入数据集,读取然后创建第二个数据框架。

df1 = pd.read_csv(url,index_col=0)
# dataframe summary
df1.head(10)

注意到各列的数值是如何分布在一个很大的范围内,即有些是122.80,有些是0.11840。

df.head(10)

(二) 实施标准缩放

为了正确缩放,我们将首先在一个列表中收集所有数字列的名称,然后使用该列表来适应标准缩放器。

col =[]
for col_name in df1.columns:
    if df1[col_name].dtype=='object':
        pass
    else:
        col.append(col_name)
# fitting the standard scaler
for i in col:
    sc = StandardScaler().fit(df1[[i]])
    df1[i] = sc.transform(df1[[i]]) 

使用standard scaler ,从sklearn ,我们可以使用standardization 技术来重新缩放我们的特征。

现在,如果我们再次检查我们的df1 ,你会注意到数值之间的范围是如何被缩小的。

df1.head(10)

df.head(10)

(iii) 分割我们的数据集

y1 被赋予已经以数字形式编码的诊断状态,而 被赋予与第一个模型相同的特征。X1

lb = LabelEncoder()
y1 = lb.fit_transform(df1.diagnosis)
X1 = df1[my_features]

之后,我们现在可以继续,将我们的数据集进一步分割成训练集和测试集。

x_train1, x_test1, Y_train1, Y_test1 = train_test_split(X1, y1, test_size=0.3, random_state=1)

(iv) 拟合模型

我们将使用我们在第一个模型中使用的相同算法来拟合我们的模型。

classifier = LinearSVC()
# fit model
classifier.fit(x_train1, Y_train1)
# predicting
Y_predict1 = classifier.predict(x_test1)
# accuracy
accuracy_after_stdScaler = classifier.score(x_test1, Y_test1)

(v) 预测

为了检查预测结果,我们将使用。

print(Y_predict1)

让我们将结果与测试集进行比较。

print(Y_test1)

3.使用归一化

现在我们将建立最终的模型,它也使用同样的训练算法和数据集,但数据集在使用前将首先进行归一化处理。

(i) 创建一个数据框架

和上面的模型一样,我们首先需要获取和我们的数据集,然后将其存储在一个数据框架中。

df2 = pd.read_csv(url,index_col=0)
## df2 summary
df2.describe()

记下这些数值。

df2.describe()

(ii) 在因变量(Y)和自变量(X)之间分割数据

在这里,我们将选择目标、特征和标签来编码我们的非数字目标(Y2)。

lb = LabelEncoder()
y2 = lb.fit_transform(df2.diagnosis)
X2 = df2[my_features]

(iii) 实施归一化

在这个模型的准备中,下一个也是关键的部分是normalizing 数据集,在这种情况下,是特征。

norm = MinMaxScaler()
X2 = norm.fit_transform(X2)

现在,让我们来看看归一化后的数据集。

X2_df = pd.DataFrame(X2)
X2_df.describe()

df2.describe()

如果你把这个描述与上面的描述相比较,你会发现其中的差别。如果你检查所有列的minmax 值,它们分别是01 。这意味着我们的特征现在是在1和0之间重新缩放。

(iv) 将数据集分割成训练集和测试集

现在我们可以将我们的数据集分成训练集和测试集。

X_train2, X_test2, y_train2, y_test2 = train_test_split(X2, y2, test_size=0.3, random_state=1)

(v) 拟合模型

我们将使用与前两个模型相同的拟合过程。

classifier = LinearSVC()
# fit model
classifier.fit(X_train2, y_train2)
#predicting
y_predict2 = classifier.predict(X_test2)
#accuracy
accuracy_after_normalization = classifier.score(X_test2, y_test2)

(vi) 预测

要比较测试值和预测值。

print(y_predict2)

同时:

print(y_test)

特征缩放的影响

我们用变量来存储每个模型的准确性。为了检查它们,我们需要打印它们。

print("Accuracy 1 :", accuracy_b4, "   Accuracy 2 :", accuracy_after_stdScaler, "    Accuracy 3:", accuracy_after_normalization)

print(accuracy)

正如你在上面看到的,feature scaled 模型的准确度得分要高于初始模型。这就继续证明了特征缩放对模型的影响。

你还会注意到,特征缩放模型的准确性是一致的,而初始(未缩放)模型的准确性一直在波动,尽管设置了一个随机状态值。

在两种缩放技术之间做出选择

当涉及到在normalizationstandardization 之间进行选择时,这取决于。

  1. 数据集属性--如果你的数据集不遵循高斯分布,那么归一化是首选。
  2. 性能--你应该尝试使用这两种方法,并比较哪种方法对你的模型更有效。对于我们来说,Standard Scaling ,结果更好。

例外情况

  1. 当使用基于树的算法,即随机森林和决策树时,不需要进行特征缩放。
  2. 当对一个包含单热编码的分类数据的数据集使用标准化时,你应该排除编码的列。不这样做可能会导致你的数据集失去其分类属性。

结论

我们已经了解了feature scaling 的重要性,研究了Standard Scaling 技术和Normalization 技术,了解了如何实现每一种技术,并比较了使用每种技术的结果。正如我们从比较结果中了解到的那样,feature scaling 可以显著提高模型的性能。它还有助于稳定一个模型的准确性。现在你可以在你的机器学习项目中选择并实现这些feature scaling 技术。