機器學習實踐/數據預處理/離散特徵處理(1)

import pandas as pd 
df = pd.DataFrame([
            ['green', 'M', 10.1, 'class1'], 
            ['red', 'L', 13.5, 'class2'], 
            ['blue', 'XL', 15.3, 'class1']])
#numpy添加列表名稱 (記下這種手法:先通過pd.DataFrame()添加數據,再用columns()補充列名)
df.columns = ['color', 'size', 'prize', 'class label']
df

先用比較簡單的映射字典法來對離散屬性進行處理

'''
把標籤轉換成數值型   這樣的連續化將沒有順序關係的類別變成具有順序關係0,1,2等,
同時也導致了不同類別之間的距離不相等,簡單的用L1範式,0-1距離爲1,0-2距離爲2
'''

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



'''
df['class label'] 
輸出:
0    class1
1    class2
2    class1
Name: class label, dtype: object 

set(df['class label'])
輸出:
    {'class1', 'class2'}
是把df['class label']裏面的數據裝到一個集合裏面,並且自動去除重複項


for idx,label in enumerate(set(df['class label'])):
    print(idx,label) 
輸出:
0 class1
1 class2 
enumerate()作用是把遍歷集合參數,返回序號和集合的數據項


class_mapping是鍵值對{label:idx}
class_mapping
輸出:
{'class1': 0, 'class2': 1} 
''' 

df['class label'] = df['class label'].map(class_mapping)
'''
map(class_mapping)利用class_mapping鍵值對的數值去替換原本的離散屬性
'''
df

 

 

#同上,應用映射字典的方法 將離散型屬性轉化成數值型屬性

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

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

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

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

df

#映射字典  還原數據的方法
#color_mapping.items() 返回的是鍵值對 比如 green,(0,0,1),其他的同理
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()}

#實際上就是  map的重複利用  鍵值對反過來而已
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

 接下來利用sklearn對數據進行預處理

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'])
#輸出:array(['class1', 'class2', 'class1'], dtype=object)

用scikit DictVectorizer一次性全部變換

使用 DictVectorizer將得到特徵的字典

df.transpose().to_dict().values()#得到屬性的字典

'''
輸出:
dict_values([{'color': 'green', 'size': 'M', 'class label': 0, 'prize': 10.1}, {'color': 'red', 'size': 'L', 'class label': 1, 'prize': 13.5}, {'color': 'blue', 'size': 'XL', 'class label': 0, 'prize': 15.3}])
'''
#獲取除了class_label屬性以爲的其他屬性
feature = df.iloc[:, :-1]
from sklearn.feature_extraction import DictVectorizer
dvec = DictVectorizer(sparse=False)

X = dvec.fit_transform(feature.transpose().to_dict().values())
X
'''
輸出:
array([[  0. ,   1. ,   0. ,  10.1,   0. ,   1. ,   0. ],
       [  0. ,   0. ,   1. ,  13.5,   1. ,   0. ,   0. ],
       [  1. ,   0. ,   0. ,  15.3,   0. ,   0. ,   1. ]])
'''

#可以調用 get_feature_names 來返回新的列的名字,其中0和1就代表是不是這個屬性.
pd.DataFrame(X, columns=dvec.get_feature_names())

接下來是將離散類型轉化成獨熱編碼

#OneHotEncoder 必須使用整數作爲輸入,所以得先預處理一下

#先通過LabelEncoder()轉化成正常的數值型屬性
color_le = LabelEncoder()

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

from sklearn.preprocessing import OneHotEncoder

ohe = OneHotEncoder(sparse=False)

X = ohe.fit_transform(df['color'].values)
X
'''
輸出:
array([[ 0.,  1.,  0.],
       [ 0.,  0.,  1.],
       [ 1.,  0.,  0.]])
這裏有一個問題 雖然生成獨熱編碼 但是如何把這個編碼 放到原本的數據裏面???
'''

#另外 這裏是先把文字屬性轉成數字屬性,數字屬性轉成獨熱編碼,通過LabelBinarizer可以實現一次性轉化
from sklearn.preprocessing import LabelBinarizer
encoder = LabelBinarizer()
housing_cat_1hot=encoder.fit_transform(df['color'])
housing_cat_1hot
'''
輸出:
array([[ 0.,  1.,  0.],
       [ 0.,  0.,  1.],
       [ 1.,  0.,  0.]]) 
'''

利用pandas實現轉化,不過這種算是獨熱編碼嘛?

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']  

#Pandas庫中同樣有類似的操作,使用get_dummies也可以得到相應的特徵
pd.get_dummies(df)

總結:數據預處理中的離散型數值的處理,主要有兩種,一種是普通數值轉換(實現方法有:1.手動之多映射字典,將其轉化成數值型;2.利用sklearn 的LabelEncoder()),另一種是獨熱編碼(實現方法有:sklean 的OneHotEncoder()和LabelBinarizer())

至於DictVectorizer()和pandas的get_dummies()方法,這種轉化方法算是獨熱嘛??

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章