數據預處理,降維,特徵提取,聚類

數據預處理,降維,特徵提取,聚類

數據預處理,使用StandardScaler進行數據的預處理

# 導入numpy
import numpy 
# 導入繪圖工具
import matplotlib.pyplot as plt
%matplotlib inline
# 導入數據集生成工具
from sklearn.datasets import make_blobs
X, y = make_blobs(n_samples=40, centers=2, random_state=50, cluster_std=2)
# 使用散點圖繪製數據
plt.scatter(X[:,0], X[:,1], c = y, cmap = plt.cm.cool)
plt.show()

在這裏插入圖片描述

樣本數爲40,分類centers爲2,隨機狀態random_state爲50,標準差cluster_std爲2的數據。

使用sklearn的preprocessing模塊對這個手工生成的數據集進行處理

# 導入StandardScaler
from sklearn.preprocessing import StandardScaler
# 使用StandardScaler進行數據預處理
X_1 = StandardScaler().fit_transform(X)
# 使用散點圖繪製經過數據預處理的數據點
plt.scatter(X_1[:,0], X_1[:,1], c = y, cmap=plt.cm.cool)
# 顯示圖像
plt.show()

在這裏插入圖片描述

似乎沒有什麼變化,但是這裏的xxyy軸發生了變化,現在的數據所有的特徵1的數值都在-2到3之間,特徵2的數值都在-3到2之間。因爲StandardScaler的原理就是,把所有的數據的特徵值轉化爲;均值爲零,方差爲一的狀態。這樣一來就可以確保數據的大小都是一致的,更有利於模型的訓練。

使用MinMaxScaler進行數據預處理

# 導入MinMaxScaler
from sklearn.preprocessing import MinMaxScaler
# 使用MinMaxScaler進行數據預處理
X_2 = MinMaxScaler().fit_transform(X)
# 繪製散點圖
plt.scatter(X_2[:,0],X_2[:,1],c=y,cmap=plt.cm.cool)
plt.show()

在這裏插入圖片描述

這樣一來,所有的數據每個特徵值都被轉換到0和1之間。這會使得模型的訓練速度加快,同時準確率也會得以提高。

使用RobustScaler進行數據預處理

# 導入RobustScaler
from sklearn.preprocessing import RobustScaler
# 使用RobustScaler進行數據預處理
X_3 = RobustScaler().fit_transform(X)
# 繪製散點圖
plt.scatter(X_3[:,0], X_3[:,1], c=y, cmap=plt.cm.cool)
plt.show()

在這裏插入圖片描述

這種方法和StandarScaler比較近似,但是他使用的是中位數和四分位數。他會直接把一些異常值剔除,有點類似於“去掉一個最高分,去掉一個最低分”

使用Normalizer進行數據預處理

# 導入Normalizer
from sklearn.preprocessing import Normalizer
# 使用Normalizer進行數據預處理
X_4 = Normalizer().fit_transform(X)
# 繪製散點圖
plt.scatter(X_4[:,0], X_4[:,1], c=y, cmap=plt.cm.cool)
plt.show()

在這裏插入圖片描述

Normalizer方法講數據或者說所有樣本的特徵向量轉化爲歐幾里得距離爲1.也就是把數據的分佈變成一個半徑爲1的圓, 或者是一個球。通常在,我們只想保留數據的特徵向量的方向,而忽略其數值的時候使用

使用scale函數,對單個類似數組的數據集執行操作

import sklearn.preprocessing
import numpy as np
X_train = np.array([[1, -1, 2],
                   [2, 0, 0],
                   [0, 1, -1]])
X_scaled = sklearn.preprocessing.scale(X_train)
plt.scatter(X_train[:2,:],X_train[1:3,:])
plt.show()

在這裏插入圖片描述

X_scaled
array([[ 0.        , -1.22474487,  1.33630621],
       [ 1.22474487,  0.        , -0.26726124],
       [-1.22474487,  1.22474487, -1.06904497]])
plt.scatter(X_scaled[:2,:],X_scaled[1:3,:])
plt.show()

在這裏插入圖片描述

print("均值:",X_scaled.mean(axis = 0))
print("單位方差:",X_scaled.std(axis = 0))
均值: [0. 0. 0.]
單位方差: [1. 1. 1.]

標度數據的均值和單位方差爲零

使用MaxAbsScaler進行數據預處理

# 導入MaxAbsScaler
from sklearn.preprocessing import MaxAbsScaler
# 使用Normalizer進行數據預處理
X_5 = MaxAbsScaler().fit_transform(X)
# 繪製散點圖
plt.scatter(X_5[:,0], X_5[:,1], c=y, cmap=plt.cm.cool)
plt.show()

在這裏插入圖片描述

通過其最大絕對值縮放每個特徵。分別縮放和轉換每個特徵,以使訓練集中每個特徵的最大絕對值爲1.0。它不會移動/居中數據,因此不會破壞任何稀疏性。
該縮放器也可以應用於稀疏CSR或CSC矩陣。

print(X_5.mean())
print(X_5.std())
-0.3163704548637977
0.306489301692821

處理類別特徵 使用OrdinalEncoder

通常,特徵不是連續值而是類別型的。比如一個人的特徵,這樣的特徵可以有效的編碼爲整數。使用OrdinalEncoder,實現講類別特徵編碼到:(0 to n_categories -1)

# 導入OrdinalEncoder
from sklearn.preprocessing import OrdinalEncoder
# 使用OrdinalEncoder編碼數據
Y = [['male', 'from US', 'uses Safari'],
     ['female', 'from Europe', 'uses Firefox']]
Y_ordinal = OrdinalEncoder().fit_transform(Y)
Y_ordinal
array([[1., 1., 1.],
       [0., 0., 0.]])

但是,此類整數表示不能直接與所有scikit-learn估計器一起使用,因爲它們期望連續輸入,並且會將類別解釋爲有序的,這通常是不希望的(即,瀏覽器集是任意定序的)。

處理類別特徵 使用獨熱碼OneHotEncoder

# 導入OneHotEncoder
from sklearn.preprocessing import OneHotEncoder
# 使用OneHotEncoder處理數據
Y = [['male', 'from US', 'uses Safari'],
     ['female', 'from Europe', 'uses Firefox']]
Y_OneHot = OneHotEncoder().fit_transform(Y)
Y_OneHot
<2x6 sparse matrix of type '<class 'numpy.float64'>'
	with 6 stored elements in Compressed Sparse Row format>
Y_OneHot.toarray()
array([[0., 1., 0., 1., 0., 1.],
       [1., 0., 1., 0., 1., 0.]])
OneHotEncoder().fit(Y)
OneHotEncoder(categories='auto', drop=None, dtype=<class 'numpy.float64'>,
              handle_unknown='error', sparse=True)
OneHotEncoder().categories
'auto'

它將帶有n_categories可能值的每個分類特徵 轉換爲n_categories二進制特徵,其中一個爲1,所有其他爲0

# 可以使用參數明確指定categories
genders = ['female', 'male']
locations = ['from Africa', 'from Asia', 'from Europe', 'from US']
browsers = ['uses Chrome', 'uses Firefox', 'uses IE', 'uses Safari']
# 特徵
X = [['male', 'from US', 'uses Safari'], ['female', 'from Europe', 'uses Firefox']]
X_fit = OneHotEncoder(categories=[genders, locations, browsers]).fit_transform([['female', 'from Asia', 'uses Chrome']]).toarray()
X_fit
array([[1., 0., 0., 1., 0., 0., 1., 0., 0., 0.]])
X_fit = OneHotEncoder(categories=[genders, locations, browsers]).fit_transform(X).toarray()
X_fit
array([[0., 1., 0., 0., 0., 1., 0., 0., 0., 1.],
       [1., 0., 0., 0., 1., 0., 0., 1., 0., 0.]])

如果訓練數據有可能缺少分類特徵,則通常最好指定handle_unknown='ignore’而不是categories如上所述手動設置。如果 handle_unknown='ignore’指定且在轉換過程中遇到未知類別,則不會引發錯誤,但是此功能生成的一鍵編碼列將全爲零(handle_unknown='ignore’僅一鍵編碼支持):

# 數據/特徵
X = [['male', 'from US', 'uses Safari'], ['female', 'from Europe', 'uses Firefox']]
X_fit = OneHotEncoder(handle_unknown='ignore').fit(X)
X_fit
OneHotEncoder(categories='auto', drop=None, dtype=<class 'numpy.float64'>,
              handle_unknown='ignore', sparse=True)
X_fit = OneHotEncoder(handle_unknown='ignore').fit_transform(X).toarray()
X_fit
array([[0., 1., 0., 1., 0., 1.],
       [1., 0., 1., 0., 1., 0.]])

使用Binarizer進行特徵二值化,特徵二值化是閾值化數字特徵以獲得布爾值的過程

# 在文本處理中使用二值化特徵很常見,即使在實踐歸一化數據的表現要好一些。
X = [[ 1., -1.,  2.],
    [ 2.,  0.,  0.],
    [ 0.,  1., -1.]]
# 導入Binarizer
from sklearn.preprocessing import Binarizer
# 使用Binarizer處理數據
X_Bina = Binarizer().fit_transform(X)
X_Bina
array([[1., 0., 1.],
       [1., 0., 0.],
       [0., 1., 0.]])
# 可以調整二值化器的閾值 將數據進行二值化,threshold表示大於閾值的數據爲1,小於閾值的數據爲0
# 使用Binarizer處理數據
X_Bina = Binarizer(threshold=1).fit_transform(X)
X_Bina
array([[0., 0., 1.],
       [1., 0., 0.],
       [0., 0., 0.]])

缺失值的估算

由於各種原因,許多現實世界的數據集包含缺失值,通常將其編碼爲空白,NaN或其他佔位符。但是,此類數據集與scikit-learn估計器不兼容,後者假定數組中的所有值都是數字,並且都具有並具有含義。使用不完整數據集的基本策略是丟棄包含缺失值的整個行和/或列。但是,這是以丟失有價值的數據爲代價的(即使數據不完整)。更好的策略是估算缺失值,即從數據的已知部分推斷出缺失值。參見 插補的通用術語表和API元素條目。

單變量特徵插補

該SimpleImputer課程提供了估算缺失值的基本策略。可以使用提供的恆定值或使用缺失值所在各列的統計信息(平均值,中位數或最頻繁)來估算缺失值。此類還允許使用不同的缺失值編碼。

# 使用np.nan編碼爲缺失值,使用各列的均值來替換缺失值
import numpy as np
from sklearn.impute import SimpleImputer
imp = SimpleImputer(missing_values=np.nan, strategy='mean')
imp.fit([[1,2], [np.nan, 3], [7,6]])
SimpleImputer(add_indicator=False, copy=True, fill_value=None,
              missing_values=nan, strategy='mean', verbose=0)
X = [[np.nan, 2],[6, np.nan],[7, 6]]
print(imp.transform(X))
[[4.         2.        ]
 [6.         3.66666667]
 [7.         6.        ]]
X = [[np.nan, 2],[6, np.nan],[7, 6]]
X_impute = SimpleImputer().fit_transform(X)
X_impute
array([[6.5, 2. ],
       [6. , 4. ],
       [7. , 6. ]])

SimpleImputer同時也支持稀疏矩陣

import scipy.sparse as sp
X = sp.csc_matrix([[1,2],[0,-1],[8,4]])
X
<3x2 sparse matrix of type '<class 'numpy.intc'>'
	with 5 stored elements in Compressed Sparse Column format>
X_sparse = SimpleImputer(missing_values = -1, strategy='mean').fit_transform(X)
X_sparse
<3x2 sparse matrix of type '<class 'numpy.float64'>'
	with 5 stored elements in Compressed Sparse Column format>
print(X_sparse.toarray())
[[1. 2.]
 [0. 3.]
 [8. 4.]]

SimpleImputer同時也可以用於處理分類型的數據

import pandas as pd
df = pd.DataFrame([["a", "x"],
                  [np.nan, "y"],
                  ["a", np.nan],
                  ["b", "y"]], dtype="category")
# 使用出現頻率最高的數據進行填補空值
df_IMputer = SimpleImputer(strategy="most_frequent").fit_transform(df)
print(df_IMputer)
[['a' 'x']
 ['a' 'y']
 ['a' 'y']
 ['b' 'y']]

多元特徵插補

import numpy as np
from sklearn.experimental import enable_iterative_imputer
from sklearn.impute import IterativeImputer
imp = IterativeImputer(max_iter=10, random_state=0)
imp.fit([[1, 2], [3, 6], [4, 8], [np.nan, 3], [7, np.nan]])

X_test = [[np.nan, 2], [6, np.nan], [np.nan, 6]]
# the model learns that the second feature is double the first
print(np.round(imp.transform(X_test)))
[[ 1.  2.]
 [ 6. 12.]
 [ 3.  6.]]
# 顯示的導入enable_iterative_imputer後
# 再從sklearn.impute 導入IterativeImputer
# from sklearn.experimental import enable_iterative_imputer  
# from sklearn.impute import IterativeImputer

# from sklearn.ensemble import RandomForestRegressor
# import pandas as pd

# # 載入數據
# titanic = pd.read_csv("titanic.csv")
# titanic = titanic.loc[:, ['Pclass', 'Age', 'SibSp', 'Parch', 'Fare']]

# # 使用隨機森林估計器
# imp = IterativeImputer(RandomForestRegressor(), max_iter=10, random_state=0)
# titanic = pd.DataFrame(imp.fit_transform(titanic), columns=titanic.columns)

實例1

# 導入紅酒數據集
from sklearn.datasets import load_wine
# 導入MLP神經網絡
from sklearn.neural_network import MLPClassifier
# 導入數據集拆分工具
from sklearn.model_selection import train_test_split
# 建立訓練集和測試集
wine = load_wine()
X_train, X_test, y_train, y_test = train_test_split(wine.data, wine.target, random_state=62)
# 打印數據集
print(X_train.shape, X_test.shape)
(133, 13) (45, 13)
import warnings
warnings.filterwarnings("ignore")
# 設定MLP神經網絡的參數
mlp = MLPClassifier(hidden_layer_sizes=[100,100],max_iter=400,random_state=62)
# 使用MLP擬合數據
mlp.fit(X_train, y_train)
print("未經處理的數據,模型得分爲:{:.2f}".format(mlp.score(X_test, y_test)))
未經處理的數據,模型得分爲:0.93

設定MLP的隱藏層爲2, 每一層100各節點,最大迭代次數400,同時指定random_state,從而保證,重複使用該模型的時候,訓練的結果是一致的。

# 使用MinMaxScaler進行數據預處理
scaler = MinMaxScaler()
scaler.fit(X_train)
X_train_pp = scaler.transform(X_train)
X_test_pp = scaler.transform(X_test)
# 再次訓練模型
mlp.fit(X_train_pp, y_train)
# 打印模型表現
print("經處理的數據,模型得分爲:{:.2f}".format(mlp.score(X_test_pp, y_test)))
經處理的數據,模型得分爲:1.00

數據降維-----主成分分析

# 導入紅酒數據集
from sklearn.preprocessing import StandardScaler
# 對紅酒數據集進行預處理
scaler = StandardScaler()
X = wine.data
y = wine.target
# 處理之後的數據
X_scaled = scaler.fit_transform(X)
print(X_scaled.shape)
(178, 13)

現在的數據集中,樣本數量爲178,特徵數量爲13.

# 導入PCA
from sklearn.decomposition import PCA
# 設置主成份數量爲6
pca = PCA(n_components=2)
pca.fit(X_scaled)
X_pca = pca.transform(X_scaled)
# 打印主成分提取之後的數據形態
print(X_pca.shape)
(178, 2)
# 把三個分類中的主成分提取出來
X0 = X_pca[wine.target==0]
X1 = X_pca[wine.target==1]
X2 = X_pca[wine.target==2]

# 散點圖
plt.scatter(X0[:,0], X0[:,1],c='r', s=60,edgecolor='k')
plt.scatter(X1[:,0], X1[:,1],c='g', s=60,edgecolor='k')
plt.scatter(X2[:,0], X2[:,1],c='b', s=60,edgecolor='k')

# 設置圖注
plt.legend(wine.target_names,loc='best')
plt.xlabel('component1')
plt.ylabel('component2')
# 顯示
plt.show()

在這裏插入圖片描述

原始特徵與PCA主成分之間的關係

# 使用主成分繪製熱力圖
plt.matshow(pca.components_, cmap='plasma')
# 縱軸爲主成分數量
plt.yticks([0,1],["component1","component2"])
plt.colorbar()
# 橫軸爲原始特徵數量
plt.xticks(range(len(wine.feature_names)), wine.feature_names, rotation=60, ha='left')
# 顯示圖像
plt.show()

在這裏插入圖片描述

特徵提取

特徵提取,是構造一個新的特徵空間,並將原始特徵投影在新的空間中得到新的表示。以線性投影爲例,令XRD\boldsymbol{X}\in \mathcal{R}^D爲原始特徵空間,XRK\boldsymbol{X}^{\prime}\in \mathcal{R}^K是經過線性投影后得到的在新空間中的特徵向量,如下:
X=WX \boldsymbol{X}^{\prime}=\boldsymbol{W}\boldsymbol{X}
其中,WRKxD\boldsymbol{W}\in{\mathcal{R}}^{KxD}爲映射矩陣。

PCA主成分分析用於特徵提取

# 導入數據集獲取工具
from sklearn.datasets import fetch_lfw_people
# 載入人臉數據集
faces = fetch_lfw_people(min_faces_per_person=20, resize=0.8)
# 將照片打印出來
fig, axes = plt.subplots(3,4,figsize=(12,9),subplot_kw={'xticks':(), 'yticks':()})
for target, image,ax in zip(faces.target, faces.images, axes.ravel()):
    ax.imshow(image, cmap=plt.cm.gray)
ax.set_title(faces.target_names[target])
plt.show()

在這裏插入圖片描述

# 導入神經網絡
from sklearn.neural_network import MLPClassifier
X_train, X_test, y_train, y_test = train_test_split(faces.data/255, faces.target, random_state=60)
mlp=MLPClassifier(hidden_layer_sizes=[100,100],random_state=62,max_iter=500)
mlp.fit(X_train, y_train)
print("模型識別準確率:{:.2f}".format(mlp.score(X_test, y_test)))
模型識別準確率:0.59

使用白化功能,白化的目的就是:降低冗餘性。白化的過程會讓樣本之間的相關性降低,且所有特徵具有相同的方差

# 使用白化功能處理數據
pca = PCA(whiten=True, n_components=0.9, random_state=60).fit(X_train)
X_train_whiten = pca.transform(X_train)
X_test_whiten = pca.transform(X_test)
X_train_whiten.shape
(1740, 101)
# 使用白化之後的數據訓練神經網絡
mlp.fit(X_train_whiten, y_train)
mlp.score(X_test_whiten, y_test)
0.6327586206896552

K均值聚類

from sklearn.datasets import make_blobs
# 生成分類數爲1的數據集
blobs = make_blobs(random_state=1, centers=1)
X_blobs = blobs[0]
plt.scatter(X_blobs[:,0],X_blobs[:,1],c='r',edgecolor='k')
plt.show()

在這裏插入圖片描述

使用K均值進行聚類

# 導入KMeans
from sklearn.cluster import KMeans
# 設定爲3類
kmeans = KMeans(n_clusters=3)
# 擬合數據
kmeans.fit(X_blobs)

x_min, x_max = X_blobs[:,0].min()-0.5, X_blobs[:,0].max()+0.5
y_min, y_max = X_blobs[:,1].min()-0.5, X_blobs[:,1].max()+0.5

xx, yy = np.meshgrid(np.arange(x_min, x_max, .02),np.arange(y_min, y_max, .02))

z = kmeans.predict(np.c_[xx.ravel(), yy.ravel()])
z = z.reshape(xx.shape)

plt.figure(1)
plt.clf()

plt.imshow(z, interpolation='nearest', extent=(xx.min(), xx.max(), yy.min(),yy.max()),cmap=plt.cm.summer, aspect='auto', origin='lower')

plt.plot(X_blobs[:, 0], X_blobs[:, 1], 'r', markersize=5)

# 使用藍色的❌代表據類的中心
centroids = kmeans.cluster_centers_
plt.scatter(centroids[:,0], centroids[:,1],
           marker = 'x',s = 150, linewidth=3,
           color = 'b', zorder=10)

plt.xlim(x_min,x_max)
plt.ylim(y_min,y_max)

plt.xticks(())
plt.yticks(())

plt.show()

在這裏插入圖片描述

# 打印Kmeans進行聚類的標籤
print("K均值的聚類標籤:\n{}".format(kmeans.labels_))
K均值的聚類標籤:
[2 2 0 1 1 1 2 2 0 1 2 1 2 0 2 1 1 2 0 0 1 0 2 2 2 2 1 2 2 2 0 0 2 2 1 0 1
 0 2 0 1 2 0 0 1 1 1 2 0 2 0 2 1 0 1 1 0 1 1 2 1 0 1 2 0 1 0 0 2 1 1 2 1 1
 1 2 1 2 2 0 1 0 1 1 0 2 1 2 0 0 1 2 0 0 1 1 2 1 1 2]

凝聚聚類算法

# 導入dendrogram和ward工具
from scipy.cluster.hierarchy import dendrogram, ward
# 使用連線的方式進行可視化
linkage = ward(X_blobs)
dendrogram(linkage)

ax = plt.gca()

plt.xlabel("sample index")
plt.ylabel("Cluster distance")

plt.show()

在這裏插入圖片描述


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