机器学习特征数据预处理

Python之王

共 11799字,需浏览 24分钟

 ·

2021-11-12 15:22



  • 标签处理

  • 特征处理

  • scikit-learn 特征处理

    • scikit LabelEncoder

    • scikit  DictVectorizer

    • scikit  OneHotEncoder

    • pandas get_dummies

  • 标准化

  • 归一化

  • Standardization and Min-Max scaling

  • plot


离散值处理

关于特征值离散化的相关内容下面直接进行举例,主要是标签处理、特征处理和OneHot。

import pandas as pd
df = pd.DataFrame([
            ['green''M', 10.1, 'class1'], 
            ['red''L', 13.5, 'class2'], 
            ['blue''XL', 15.3, 'class1']])

df.columns = ['color''size''prize''class label']
df

标签处理

通常我们会把字符型的标签转换成数值型的

class_mapping = {label:idx for idx,label in enumerate(set(df['class label']))}

df['class label'] = df['class label'].map(class_mapping)
df

特征处理

对于特征来说,我们一般可以做一个映射的字典

size_mapping = {
           'XL': 3,
           'L': 2,
           'M': 1}

df['size'] = df['size'].map(size_mapping)
df

我们还可以做这样的转换进行编码

color_mapping = {
           'green': (0,0,1),
           'red': (0,1,0),
           'blue': (1,0,0)}

df['color'] = df['color'].map(color_mapping)
df

对于数据,我们同样可以给它反变换回去

inv_color_mapping = {v: k for k, v in color_mapping.items()}
inv_size_mapping = {v: k for k, v in size_mapping.items()}
inv_class_mapping = {v: k for k, v in class_mapping.items()}

df['color'] = df['color'].map(inv_color_mapping)
df['size'] = df['size'].map(inv_size_mapping)
df['class label'] = df['class label'].map(inv_class_mapping)
df

scikit-learn 特征处理

scikit LabelEncoder

from sklearn.preprocessing import LabelEncoder

class_le = LabelEncoder()
df['class label'] = class_le.fit_transform(df['class label'])
df

反变换回去可以用这个函数 inverse_transform :

class_le.inverse_transform(df['class label'])

scikit  DictVectorizer

使用 DictVectorizer将得到特征的字典

df.transpose().to_dict().values()
feature = df.iloc[:, :-1]
feature

对所有的数据都做了映射

from sklearn.feature_extraction import DictVectorizer
dvec = DictVectorizer(sparse=False)

X = dvec.fit_transform(feature.transpose().to_dict().values())
X

可以调用 get_feature_names 来返回新的列的名字,其中0和1就代表是不是这个属性.

pd.DataFrame(X, columns=dvec.get_feature_names())

scikit  OneHotEncoder

OneHotEncoder 必须使用整数作为输入,所以得先预处理一下

color_le = LabelEncoder()
df['color'] = color_le.fit_transform(df['color'])

df
from sklearn.preprocessing import OneHotEncoder
ohe = OneHotEncoder(sparse=False)

X = ohe.fit_transform(df[['color']].values)
X

pandas get_dummies

Pandas库中同样有类似的操作,使用get_dummies也可以得到相应的特征

import pandas as pd
df = pd.DataFrame([
            ['green''M', 10.1, 'class1'], 
            ['red''L', 13.5, 'class2'], 
            ['blue''XL', 15.3, 'class1']])

df.columns = ['color''size''prize''class label']

size_mapping = {
           'XL': 3,
           'L': 2,
           'M': 1}
df['size'] = df['size'].map(size_mapping)

class_mapping = {label:idx for idx,label in enumerate(set(df['class label']))}
df['class label'] = df['class label'].map(class_mapping)


df

对整个DF使用get_dummies 将会得到新的列:

pd.get_dummies(df)

标准化与归一化

标准化

同样我们都需要对原始数据进行处理,少不了的就是 standardization (或者叫做 Z-score normalization)

要求 均值 和标准差

转换公式如下:

这个意义是十分重大的,想象一下,我们经常通过梯度下降来进行优化求解,公式一般如下,如果特征之间的数值差异太大,那么更新的结果肯定也会产生较大的差异,这是我们所不希望的。在最开始的时候,我们认为特征之间的重要程度的是一样,并不想偏袒哪个特征,所以这部预处理工作必做!

参数更新:

归一化

另一种方法叫做 Min-Max scaling (或者叫做 "normalization"也就是我们常说的0-1归一化).
处理后的所有特征的值都会被压缩到 0到1区间上.这样做还可以抑制离群值对结果的影响. 归一化公式如下:

Standardizing 和 Normalizing的Scikit-learn实现

葡萄酒数据集由3个不同的类组成,每一行对应一个特定的葡萄酒样本。类标签(1、2、3)列在第一列中,列2-14对应13个不同的属性(特征):

  1. Alcohol
  2. Malic acid
from sklearn.datasets import load_wine
wine = load_wine()
df= pd.concat([pd.DataFrame(wine.target),pd.DataFrame(wine["data"][:,:2],)],axis=1)
df.columns = ['Class label''Alcohol''Malic acid']

在数据中,Alcohol和Malic acid 衡量的标准应该是不同的,特征之间数值差异较大

Standardization and Min-Max scaling

from sklearn import preprocessing

std_scale = preprocessing.StandardScaler().fit(df[['Alcohol''Malic acid']])
df_std = std_scale.transform(df[['Alcohol''Malic acid']])

minmax_scale = preprocessing.MinMaxScaler().fit(df[['Alcohol''Malic acid']])
df_minmax = minmax_scale.transform(df[['Alcohol''Malic acid']])

print('Mean after standardization:\nAlcohol={:.2f}, Malic acid={:.2f}'
      .format(df_std[:,0].mean(), df_std[:,1].mean()))
print('\nStandard deviation after standardization:\nAlcohol={:.2f}, Malic acid={:.2f}'
      .format(df_std[:,0].std(), df_std[:,1].std()))
print('Min-value after min-max scaling:\nAlcohol={:.2f}, Malic acid={:.2f}'
      .format(df_minmax[:,0].min(), df_minmax[:,1].min()))
print('\nMax-value after min-max scaling:\nAlcohol={:.2f}, Malic acid={:.2f}'
      .format(df_minmax[:,0].max(), df_minmax[:,1].max()))

plot

from matplotlib import pyplot as plt

def plot():
    plt.figure(figsize=(8,6))

    plt.scatter(df['Alcohol'], df['Malic acid'], 
            color='green', label='input scale', alpha=0.5)

    plt.scatter(df_std[:,0], df_std[:,1], color='red'
            label='Standardized [$N  (\mu=0, \; \sigma=1)$]', alpha=0.3)

    plt.scatter(df_minmax[:,0], df_minmax[:,1], 
            color='blue', label='min-max scaled [min=0, max=1]', alpha=0.3)

    plt.title('Alcohol and Malic Acid content of the wine dataset')
    plt.xlabel('Alcohol')
    plt.ylabel('Malic Acid')
    plt.legend(loc='upper left')
    plt.grid()
    
    plt.tight_layout()

plot()
plt.show()

我们将原始的和变换后都放到了同一个图上,观察下结果吧!接下来我们再看看数据是否被打乱了呢?

fig, ax = plt.subplots(3, figsize=(6,14))

for a,d,l in zip(range(len(ax)), 
               (df[['Alcohol''Malic acid']].values, df_std, df_minmax),
               ('Input scale'
                'Standardized [$N  (\mu=0, \; \sigma=1)$]'
                'min-max scaled [min=0, max=1]')
                ):
    for i,c in zip(range(1,4), ('red''blue''green')):
        ax[a].scatter(d[df['Class label'].values == i, 0], 
                  d[df['Class label'].values == i, 1],
                  alpha=0.5,
                  color=c,
                  label='Class %s' %i
                  )
    ax[a].set_title(l)
    ax[a].set_xlabel('Alcohol')
    ax[a].set_ylabel('Malic Acid')
    ax[a].legend(loc='upper left')
    ax[a].grid()
    
plt.tight_layout()

plt.show()

在机器学习中,如果我们对训练集做了上述处理,那么同样的对测试集也必须要经过相同的处理

std_scale = preprocessing.StandardScaler().fit(X_train)
X_train = std_scale.transform(X_train)
X_test = std_scale.transform(X_test)




Python“宝藏级”公众号【Python之王】专注于Python领域,会爬虫,数分,C++,tensorflow和Pytorch等等

近 2年共原创 100+ 篇技术文章。创作的精品文章系列有:

日常收集整理了一批不错的 Python 学习资料,有需要的小伙可以自行免费领取。

获取方式如下:公众号回复资料领取Python等系列笔记,项目,书籍,直接套上模板就可以用了。资料包含算法、python、算法小抄、力扣刷题手册和 C++ 等学习资料!

浏览 25
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报