特征扩展对机器学习模型的影响
在机器学习中,我们用来训练模型的数据集有不可预测的数值,这些数值可能会在大范围内相互变化。数值之间可能会有很大的差异,特别是当它们代表不同的尺度时,这可能会使它们难以比较,例如,公斤、升、毫米、英里、像素等。
特征缩放的引入就是为了解决这个难题。它对数字进行调整,使其容易比较那些不在彼此范围内的数值。这有助于提高模型的准确性,特别是那些使用对特征缩放敏感的算法,即梯度下降算法和基于距离的算法。
有两种缩放特征的技术。
- 归一化--数值被重新划分为0和1之间的范围。
- 标准化--数值被重新调整到以标准差为单位的平均值为中心。
选择在你的数据集上使用哪种方法,要根据你的数据集、机器学习算法和你可能解决的问题类型来决定。
在这个方法中,我们将学习如何实现每种方法。我们将首先建立一个没有特征缩放的预测模型,一个有标准化特征的预测模型,最后是一个有规范化特征的预测模型。我们还将为这三者使用相同的数据集,以比较我们的数据集如何影响我们对技术的选择。
前提条件
我们需要具备以下条件
- Python编程语言的基本知识。
- 机器学习的基础知识。
- Jupyter Notebook/ Jupyter Lab/ Google Colab。
使用给定的数据进行训练,我们将建立模型来预测一个病人是否被诊断为疾病M 或B 。
导入库
在我们的笔记本中,让我们导入以下库并运行单元。
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()
输出。

正如你所看到的,我们的数据集包含32个列,其中大部分是浮点,一个包含对象。前31列也处于良好状态;因此不需要替换或删除一些行。
我们还可以使用df.head() ,看看我们数据集前十行的数值。
df.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 。我们有两个类别的诊断状态,M 和B 。标签编码器将把它们分别改为1 和0 的类别。
lb = LabelEncoder()
y = lb.fit_transform(df.diagnosis)
如果你现在检查y ,你会看到它转变为一个数组1's 和0's 。
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_test)

2.使用标准比例
我们将建立另一个模型,在拟合前使用standard scaling ,对数据集进行分级。
(i) 创建和分析数据框架
使用下面的代码导入数据集,读取然后创建第二个数据框架。
df1 = pd.read_csv(url,index_col=0)
# dataframe summary
df1.head(10)
注意到各列的数值是如何分布在一个很大的范围内,即有些是122.80,有些是0.11840。

(二) 实施标准缩放
为了正确缩放,我们将首先在一个列表中收集所有数字列的名称,然后使用该列表来适应标准缩放器。
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)

(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()
记下这些数值。

(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()

如果你把这个描述与上面的描述相比较,你会发现其中的差别。如果你检查所有列的min 和max 值,它们分别是0 和1 。这意味着我们的特征现在是在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)

正如你在上面看到的,feature scaled 模型的准确度得分要高于初始模型。这就继续证明了特征缩放对模型的影响。
你还会注意到,特征缩放模型的准确性是一致的,而初始(未缩放)模型的准确性一直在波动,尽管设置了一个随机状态值。
在两种缩放技术之间做出选择
当涉及到在normalization 和standardization 之间进行选择时,这取决于。
- 数据集属性--如果你的数据集不遵循高斯分布,那么归一化是首选。
- 性能--你应该尝试使用这两种方法,并比较哪种方法对你的模型更有效。对于我们来说,
Standard Scaling,结果更好。
例外情况
- 当使用基于树的算法,即随机森林和决策树时,不需要进行特征缩放。
- 当对一个包含单热编码的分类数据的数据集使用标准化时,你应该排除编码的列。不这样做可能会导致你的数据集失去其分类属性。
结论
我们已经了解了feature scaling 的重要性,研究了Standard Scaling 技术和Normalization 技术,了解了如何实现每一种技术,并比较了使用每种技术的结果。正如我们从比较结果中了解到的那样,feature scaling 可以显著提高模型的性能。它还有助于稳定一个模型的准确性。现在你可以在你的机器学习项目中选择并实现这些feature scaling 技术。