选择正确的编码方法—Label vs OneHot Encoder
在机器学习(ML)模型中,我们经常需要将分类即文本特征转换为其数字表示。最常用的两种方法是使用Label Encoder或OneHot Encoder。然而,大多数机器学习(ML)新手不熟悉编码选择对其机器学习模型的影响,通过在正确的场景中使用正确的编码,机器学习模型的准确性可能会大幅度地改变。
本文我们将了解Label和OneHot编码器的工作原理,了解如何在python中使用这些编码器,看看它们对预测的影响
Label Encoder:
使用Sklearn Library可以实现Python中的Label Encoder。Sklearn提供了一种非常有效的工具,用于将分类特征的级别编码为数值。LabelEncoder编码值介于0和n_classes-1之间的标签,其中n是不同标签的数量。如果标签重复,它将指定与先前分配的值相同的值。
考虑下面的例子:
如果我们必须将此数据传递给机器学习模型,我们需要使用Label Encoder将Country列编码为其数字表示。应用Label Encoder后,我们将得到如下所示的结果
分类值已转换为数值
这就是所有的标签编码。但是根据数据,标签编码引入了一个新问题。例如,我们将一组国家/地区名称编码为数字数据。这实际上是分类数据,行之间没有任何关系。
这里的问题是因为同一列中有不同的数字,模型会误解数据的某种顺序,0 <1 <2。
这样机器学习模型可能会产生一种相关性,比如随着国家数量的增加,人口数量的增加,但这显然不是其他数据或预测集中的情形。为了克服这个问题,我们使用了One Hot Encoder。
One Hot Encoder:
现在,正如我们已经讨论的那样,根据我们所拥有的数据,我们可能遇到这样的情况:在Label Encoder之后,我们可能会混淆我们的机器学习模型,认为列具有某种顺序或层次结构的数据。为避免这种情况,我们将使用'OneHotEncode'。
OneHotEncode的作用是,它需要一个具有分类数据的列,该列已经过Label Encoder,然后将该列拆分为多个列。数字由1和0替换,具体取决于哪个列具有什么值。在我们的例子中,我们将获得四个新列,每个国家一个 -Japan, U.S, India和China。
对于第一列值为Japan的行,“Japan”列将为“1”,其他三列将为“0”。同样,对于第一列值为US的行,“U.s”列将为“1”,其他三列将为“0”,依此类推。
OneHotEncode的国家/地区值
Python的实际例子说明了使用Label和OneHotEncode对预测的影响
我们将使用汽车数据集(您可以从此处下载数据集https://www.kaggle.com/toramky/automobile-dataset)根据各种特征来预测汽车价格。用于本文的数据只是一个样本数据,但通过均方根误差评估预测结果可以清楚地看到预测结果的差异,机器学习模型预测的rmse越接近0。
我们将运行xgboost回归算法模型(您可以使用您选择的任何回归算法)并使用Label Encoder预测价格,然后使用One Hot Encoder并比较结果。
代码片段:
import pandas as pd import numpy as np import xgboost from sklearn.model_selection import train_test_split from sklearn.preprocessing import LabelEncoder from math import sqrt from sklearn.metrics import mean_squared_error data = pd.read_csv('D://Blogs//insurance.csv') testdata = pd.read_csv('D://Blogs//insuranceTest.csv') mergedata = data.append(testdata) testcount = len(testdata) count = len(mergedata)-testcount X_cat = mergedata.copy() X_cat = mergedata.select_dtypes(include=['object']) X_enc = X_cat.copy() #ONEHOT ENCODING BLOCK #X_enc = pd.get_dummies(X_enc, columns=['sex','region','smoker']) #mergedata = mergedata.drop(['sex','region','smoker'],axis=1) #END ENCODING BLOCK # ============================================================================= # #LABEL ENCODING BLOCK # X_enc = X_enc.apply(LabelEncoder().fit_transform) # mergedata = mergedata.drop(X_cat.columns, axis=1) # #END LABEL ENCODING BLOCK # # ============================================================================= FinalData = pd.concat([mergedata,X_enc], axis=1) train = FinalData[:count] test = FinalData[count:] trainy = train['charges'].astype('int') trainx = train.drop(['charges'], axis=1) test = test.drop(['charges'], axis=1) X_train,X_test, y_train,y_test = train_test_split(trainx, trainy, test_size=0.3) clf = xgboost.XGBRegressor() clf.fit(X_train,y_train) y_testpred= clf.predict(X_test) y_pred = clf.predict(test) dftestpred = pd.DataFrame(y_testpred) dfpred = pd.DataFrame(y_pred) rms = sqrt(mean_squared_error(y_test, y_testpred)) print("RMSE:", rms)
RMSE输出:RMSE:4931.632574106283
现在让我们从代码片段中取消对One Hot encoder块的注释,而注释Label Encoder块查看RMSE
import pandas as pd import numpy as np import xgboost from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score, confusion_matrix from sklearn.preprocessing import LabelEncoder from math import sqrt from sklearn.metrics import mean_squared_error data = pd.read_csv('D://Blogs//insurance.csv') testdata = pd.read_csv('D://Blogs//insuranceTest.csv') mergedata = data.append(testdata) testcount = len(testdata) count = len(mergedata)-testcount X_cat = mergedata.copy() X_cat = mergedata.select_dtypes(include=['object']) X_enc = X_cat.copy() #ONEHOT ENCODING BLOCK X_enc = pd.get_dummies(X_enc, columns=['sex','region','smoker']) mergedata = mergedata.drop(['sex','region','smoker'],axis=1) #END ENCODING BLOCK # ============================================================================= # #LABEL ENCODING BLOCK # #X_enc = X_enc.apply(LabelEncoder().fit_transform) # #mergedata = mergedata.drop(X_cat.columns, axis=1) # #END LABEL ENCODING BLOCK # # ============================================================================= FinalData = pd.concat([mergedata,X_enc], axis=1) train = FinalData[:count] test = FinalData[count:] trainy = train['charges'].astype('int') trainx = train.drop(['charges'], axis=1) test = test.drop(['charges'], axis=1) X_train,X_test, y_train,y_test = train_test_split(trainx, trainy, test_size=0.3) clf = xgboost.XGBRegressor() clf.fit(X_train,y_train) y_testpred= clf.predict(X_test) y_pred = clf.predict(test) dftestpred = pd.DataFrame(y_testpred) dfpred = pd.DataFrame(y_pred) rms = sqrt(mean_squared_error(y_test, y_testpred)) print("RMSE:", rms)
RMSE输出:RMSE:4793.667005276121
One Hot Encoder 的RMSE小于 Label Encoder,这意味着使用One Hot Encoder 提供了更好的准确性,因为我们知道更接近RMSE到0更好的精度,再次不用担心如此大的RMSE,因为我说这只是一个示例数据帮助我们了解Label和OneHot编码器对我们模型的影响。