------------------------------------本博客所有內容以學習、研究和分享為主,如需轉載,請聯系本人,標明作者和出處,並且是非商業用途,謝謝!--------------------------------
系列目錄:

1 第一部分 模型的評估與數據處理 2 3 機器學習基礎與實踐(一)----數據清洗 4 5 機器學習基礎與實踐(二)----數據轉換 6 7 機器學習基礎與實踐(三)----數據降維 8 9 10 11 第二部分 特征工程 12 13 機器學習基礎與實踐(四)----特征選擇 14 15 機器學習基礎與實踐(五)----特征提取 16 17 機器學習基礎與實踐(六)----模型選擇與評估 18 19 20 21 第三部分 算法基礎之有監督算法 22 23 機器學習基礎與實踐(七)----廣義線性模型 24 25 機器學習基礎與實踐(八)----最小二乘法 26 27 機器學習基礎與實踐(九)----LDA 28 29 機器學習基礎與實踐(十)----SGD 30 31 機器學習基礎與實踐(十一)----K近鄰 32 33 機器學習基礎與實踐(十二)----高斯過程 34 35 機器學習基礎與實踐(十三)----決策樹(ID3,C4.5,C5.0,CART) 36 37 機器學習基礎與實踐(十四)----朴素貝葉斯 38 39 機器學習基礎與實踐(十五)----支持向量機 40 41 機器學習基礎與實踐(十六)----集成學習(Bagging,RF,AdaBoost,Gradient Tree Boosting,Voting Classifier) 42 43 機器學習基礎與實踐(十七)----感知機模型 44 45 機器學習基礎與實踐(十八)----多分類算法 46 47 48 49 第四部分 算法基礎之無監督算法 50 51 機器學習基礎與實踐(十九)----K-means 52 53 機器學習基礎與實踐(二十)----Affinity propagation 54 55 機器學習基礎與實踐(二十一)----Mean-shift 56 57 機器學習基礎與實踐(二十二)----Spectral clustering 58 59 機器學習基礎與實踐(二十三)----Ward hierachical 60 61 機器學習基礎與實踐(二十四)----Agglomerative clustering 62 63 機器學習基礎與實踐(二十五)----DBSCAN 64 65 機器學習基礎與實踐(二十六)----Gaussian mixtures 66 67 機器學習基礎與實踐(二十七)----Birch 68 69 70 71 第五部分 算法基礎之推薦算法 72 73 機器學習基礎與實踐(二十八)----相似度計算 74 75 機器學習基礎與實踐(二十九)----Arules關聯規則 76 77 機器學習基礎與實踐(三十)----Fp-Growth 78 79 機器學習基礎與實踐(三十一)----User-based or Item-based 80 81 82 83 第六部分 算法基礎之半監督模型 84 85 機器學習基礎與實踐(三十二)----Label Propagation 86 87 88 89 第七部分 算法基礎之其他模型 90 91 機器學習基礎與實踐(三十三)----概率圖模型 92 93 機器學習基礎與實踐(三十四)----最大熵模型 94 95 機器學習基礎與實踐(三十五)----規則學習 96 97 機器學習基礎與實踐(三十六)----強化學習 98 99 機器學習基礎與實踐(三十七)----條件隨機場 100 101 機器學習基礎與實踐(三十八)----保序回歸(Isotonic regression) 102 103 機器學習基礎與實踐(三十九)----Probability calibration
本文目錄:
一.標准化的原因二.適用情況三.三種數據變換方法的含義與應用四.具體方法及代碼一)標准化1.1 scale----零均值單位方差1.2 StandardScaler二)歸一化2.1 MinMaxScaler(最小最大值標准化)2.2 MaxAbsScaler(絕對值最大標准化)2.3 對稀疏數據進行標准化2.4 對離群點進行標准化三)正則化3.1 L1、L2正則化四)二值化4.1特征二值化五)對類別特征進行編碼六)缺失值的插補七)生成多項式特征八)自定義轉換
正文:
Normalizing(正則化):通常是指除以向量的范數。例如:將一個向量的歐氏長度等價於1 。在神經網絡中,“正則化”通常是指將向量的范圍重縮放至最小化或者一定范圍,使所有的元素都在[0,1]范圍內。通常用於文本分類或者文本聚類中。
Standardizing(標准化):通常是為了消除不同屬性或樣方間的不齊性,使同一樣方內的不同屬性間或同一屬性在不同樣方內的方差減小。例如:如果一個向量包含高斯分布的隨機值,你可能會通過除以標准偏差來減少均值,然后獲得零均值單位方差的“標准正態”隨機變量。
那么問題是,當我們在訓練模型的時候,一定要對數據進行變換嗎?這得視情況而定。很多人對多層感知機有個誤解,認為輸入的數據必須在[0,1]這個范圍內。雖然標准化后在訓練模型效果會更好,但實際上並沒有這個要求。但是最好使輸入數據中心集中在0周圍,所以把數據縮放到[0,1]其實並不是一個好的選擇。
如果你的輸出激活函數的范圍是[0,1](sigmoid函數的值域),那你必須保證你的目標值也在這個范圍內。但通常請款下,我們會使輸出激活函數的范圍適應目標函數的分布,而不是讓你的數據來適應激活函數的范圍。
當我們使用激活函數的范圍為[0,1]時,有些人可能更喜歡把目標函數縮放到[0.1,0.9]這個范圍。我懷疑這種小技巧的之所以流行起來是因為反向傳播的標准化太慢了導致的。但用這種方法可能會使輸出的后驗概率值不對。如果你使用一個有效的訓練算法的話,完全不需要用這種小技巧,也沒有必要去避免溢出(overflow)
1 from sklearn import preprocessing 2 import numpy as np 3 #raw_data 4 X = np.array([[1., -1., 2.], [2., 0., 0.], [0., 1., -1.]]) 5 X_scaled = preprocessing.scale(X) 6 #output 7 X_scaled = [[ 0. -1.22474487 1.33630621] 8 [ 1.22474487 0. -0.26726124] 9 [-1.22474487 1.22474487 -1.06904497]] 10 #scaled之后的數據零均值,單位方差 11 X_scaled.mean(axis=0) # column mean: array([ 0., 0., 0.]) 12 X_scaled.std(axis=0) #column standard deviation: array([ 1., 1., 1.])
1.2 StandardScaler----計算訓練集的平均值和標准差,以便測試數據集使用相同的變換
1 scaler = preprocessing.StandardScaler().fit(X) 2 #out: 3 StandardScaler(copy=True, with_mean=True, with_std=True) 4 scaler.mean_ 5 #out: 6 array([ 1., 0. , 0.33333333]) 7 scaler.std_ 8 #out: 9 array([ 0.81649658, 0.81649658, 1.24721913]) 10 #測試將該scaler用於輸入數據,變換之后得到的結果同上 11 scaler.transform(X) 12 #out: 13 array([[ 0., -1.22474487, 1.33630621], [ 1.22474487, 0. , -0.26726124], [-1.22474487,1.22474487, -1.06904497]]) 14 scaler.transform([[-1., 1., 0.]]) 15 #scale the new data, out: 16 array([[-2.44948974, 1.22474487, -0.26726124]])
注:1)若設置with_mean=False 或者 with_std=False,則不做centering 或者scaling處理。
2)scale和StandardScaler可以用於回歸模型中的目標值處理。
二)歸一化----將數據特征縮放至某一范圍(scalingfeatures to a range)
另外一種標准化方法是將數據縮放至給定的最小值與最大值之間,通常是0與1之間,可用MinMaxScaler實現。或者將最大的絕對值縮放至單位大小,可用MaxAbsScaler實現。
使用這種標准化方法的原因是,有時數據集的標准差非常非常小,有時數據中有很多很多零(稀疏數據)需要保存住0元素。
2.1 MinMaxScaler(最小最大值標准化)
公式:X_std = (X - X.min(axis=0)) / (X.max(axis=0) - X.min(axis=0)) ;
X_scaler = X_std/ (max - min) + min
1 #例子:將數據縮放至[0, 1]間 2 X_train = np.array([[1., -1., 2.], [2., 0., 0.], [0., 1., -1.]]) 3 min_max_scaler = preprocessing.MinMaxScaler() 4 X_train_minmax = min_max_scaler.fit_transform(X_train) 5 #out: 6 array([[ 0.5 , 0. , 1. ], 7 [ 1. , 0.5 , 0.33333333], 8 [ 0. , 1. , 0. ]]) 9 #將上述得到的scale參數應用至測試數據 10 X_test = np.array([[ -3., -1., 4.]]) 11 X_test_minmax = min_max_scaler.transform(X_test) #out: array([[-1.5 , 0. , 1.66666667]]) 12 #可以用以下方法查看scaler的屬性 13 min_max_scaler.scale_ #out: array([ 0.5 , 0.5, 0.33...]) 14 min_max_scaler.min_ #out: array([ 0., 0.5, 0.33...])
與上述標准化方法相似,但是它通過除以最大值將訓練集縮放至[-1,1]。這意味着數據已經以0為中心或者是含有非常非常多0的稀疏數據。
1 X_train = np.array([[ 1., -1., 2.], 2 [ 2., 0., 0.], 3 [ 0., 1., -1.]]) 4 max_abs_scaler = preprocessing.MaxAbsScaler() 5 X_train_maxabs = max_abs_scaler.fit_transform(X_train) 6 # out: 7 array([[ 0.5, -1., 1. ], [ 1. , 0. , 0. ], [ 0. , 1. , -0.5]]) 8 X_test = np.array([[ -3., -1., 4.]]) 9 X_test_maxabs = max_abs_scaler.transform(X_test) 10 #out: 11 array([[-1.5, -1. , 2. ]]) 12 max_abs_scaler.scale_ 13 #out: 14 array([ 2., 1., 2.])
其實在scale模塊里,也提供了這兩種方法: minmax_scale和
maxabs_scale
2.3 對稀疏數據進行標准化
對稀疏數據進行中心化會破壞稀疏數據的結構,這樣做沒什么意義。但是我們可以對稀疏數據的輸入進行標准化,尤其是特征在不同的標准時。MaxAbsScaler
和 maxabs_scale是專門為稀疏數據設計的,也是常用的方法。但是
scale
和 StandardScaler只接受scipy.sparse的矩陣作為輸入,並且必須設置with_centering=False。否則會出現
ValueError且破壞稀疏性,而且還會無意中分配更多的內存導致內存崩潰。
RobustScaler不適用於稀疏數據的輸入,但是你可以用
transform 方法。
scalers接受壓縮的稀疏行(Compressed Sparse Rows)和壓縮的稀疏列(Compressed Sparse Columns)的格式(具體參考scipy.sparse.csr_matrix 和
scipy.sparse.csc_matrix
)。其他的稀疏格式會被轉化成壓縮的稀疏行(Compressed Sparse Rows)格式。為了避免這種不必要的內存拷貝,推薦使用CSR或者CSC的格式。如果數據很小,可以在稀疏矩陣上運用toarray 方法。
2.4 對離群點進行標准化
如果你的數據有離群點(上一篇我們提到過),對數據進行均差和方差的標准化效果並不好。這種情況你可以使用robust_scale
和 RobustScaler 作為替代。它們有對數據中心化和數據的縮放魯棒性更強的參數。
1 x=np.array([[1.,-1.,2.], 2 [2.,0.,0.], 3 [0.,1.,-1.]]) 4 x_normalized=preprocessing.normalize(x,norm='l2') 5 print(x_normalized) 6 7 # 可以使用processing.Normalizer()類實現對訓練集和測試集的擬合和轉換 8 normalizer=preprocessing.Normalizer().fit(x) 9 print(normalizer) 10 normalizer.transform(x)
注:稀疏數據輸入:
normalize
和 Normalizer 既接受稠密數據(dense array-like),也接受稀疏矩陣(from scipy.sparse)作為輸入
稀疏數據需要轉換成壓縮的稀疏行(Compressed Sparse Rows)格式(詳見scipy.sparse.csr_matrix),為了避免不必要的內存拷貝,推薦使用CSR。
特征二值化是把數值特征轉化成布爾值的過程。這個方法對符合多變量伯努利分布的輸入數據進行預測概率參數很有效。詳細可以見這個例子sklearn.neural_network.BernoulliRBM
.
此外,在文本處理中也經常會遇到二值特征值(很可能是為了簡化概率推理),即使在實際中正則化后的詞頻或者TF-IDF的值通常只比未正則化的效果好一點點。
對於 Normalizer,
Binarizer工具類通常是在Pipeline階段(
sklearn.pipeline.Pipeline
)的前期過程會用到。下面舉一個具體的例子:
1 #input 2 X = [[ 1., -1., 2.], 3 [ 2., 0., 0.], 4 [ 0., 1., -1.]] 5 #binary 6 binarizer = preprocessing.Binarizer().fit(X) # fit does nothing 7 binarizer 8 Binarizer(copy=True, threshold=0.0) 9 #transform 10 binarizer.transform(X) 11 #out: 12 array([[ 1., 0., 1.], 13 [ 1., 0., 0.], 14 [ 0., 1., 0.]]) 15 16 # 調整閾值 17 binarizer = preprocessing.Binarizer(threshold=1.1) 18 binarizer.transform(X) 19 #out: 20 array([[ 0., 0., 1.], 21 [ 1., 0., 0.], 22 [ 0., 0., 0.]]) 23
注:稀疏數據輸入:
binarize
和 Binarizer
既接受稠密數據(dense array-like),也接受稀疏矩陣(from scipy.sparse)作為輸入
稀疏數據需要轉換成壓縮的稀疏行(Compressed Sparse Rows)格式(詳見scipy.sparse.csr_matrix),為了避免不必要的內存拷貝,推薦使用CSR。
五)對類別特征進行編碼
我們經常會遇到一些類別特征,這些特征不是離散型的數值,而是這樣的:["男性","女性"],["來自歐洲","來自美國","來自亞洲"],["使用Firefox瀏覽器","使用Chrome瀏覽器","使用Safari瀏覽器","使用IE瀏覽器"]等等。這種類型的特征可以被編碼為整型(int),如["男性","來自美國","使用IE瀏覽器"]可以表示成[0,1,3],["女性","來自亞洲","使用Chrome瀏覽器"]可以表示成[1,2,1]。這些整數式的表示不能直接作為sklearn的參數,因為我們需要的是連續型的輸入,而且我們通常是有序的翻譯這些特征,而不是所有的特征都是有序化的(譬如瀏覽器就是按人工排的序列)。
將這些類別特征轉化成sklearn參數中可以使用的方法是:使用one-of-K或者one-hot編碼(獨熱編碼OneHotEncoder
)。它可以把每一個有m種類別的特征轉化成m中二值特征。舉例如下:
1 enc = preprocessing.OneHotEncoder() 2 #input 3 enc.fit([[0, 0, 3], [1, 1, 0], [0, 2, 1], [1, 0, 2]]) 4 OneHotEncoder(categorical_features='all', dtype=<... 'float'>,handle_unknown='error', n_values='auto', sparse=True) 5 #transform 6 enc.transform([[0, 1, 3]]).toarray() 7 #out 8 array([[ 1., 0., 0., 1., 0., 0., 0., 0., 1.]])
默認情況下,特征的類別數量是從數據集里自動判斷出來的。當然,你也可以用n_values這個參數。我們剛剛舉的例子中有兩種性別,三種地名和四種瀏覽器,當我們fit之后就可以將我們的數據轉化為數值了。從結果中來看,第一個數字代表性別([0,1]代表男性,女性),第二個數字代表地名([0,1,2]代表歐洲、美國、亞洲),最后一個數字代表瀏覽器([3,0,1,2]代表四種瀏覽器)
此外,字典格式也可以編碼: Loading features from dicts
OneHotEncoder參數:class sklearn.preprocessing.
OneHotEncoder
(n_values='auto', categorical_features='all', dtype=<class 'float'>, sparse=True, handle_unknown='error')
n_values : ‘auto’, int or array of ints
每個特征的數量
- ‘auto’ : 從訓練數據的范圍中得到
- int : 所有特征的最大值(number)
- array : 每個特征的最大值(number)
categorical_features: “all” or array of indices or mask :
確定哪些特征是類別特征
- ‘all’ (默認): 所有特征都是類別特征,意味着所有特征都要進行OneHot編碼
- array of indices: 類別特征的數組索引
- mask: n_features 長度的數組,切dtype = bool
非類別型特征通常會放到矩陣的右邊
dtype : number type, default=np.float
輸出數據的類型
sparse : boolean, default=True
設置True會返回稀疏矩陣,否則返回數組
handle_unknown : str, ‘error’ or ‘ignore’
當一個不明類別特征出現在變換中時,報錯還是忽略
六)缺失值的插補
上篇我們講了五種方法來解決缺失值的問題,其實sklearn里也有一個工具Imputer可以對缺失值進行插補。Imputer類可以對缺失值進行均值插補、中位數插補或者某行/列出現的頻率最高的值進行插補,也可以對不同的缺失值進行編碼。並且支持稀疏矩陣。
1 import numpy as np 2 from sklearn.preprocessing import Imputer 3 #用均值插補缺失值 4 imp = Imputer(missing_values='NaN', strategy='mean', axis=0) 5 imp.fit([[1, 2], [np.nan, 3], [7, 6]]) 6 Imputer(axis=0, copy=True, missing_values='NaN', strategy='mean', verbose=0) 7 X = [[np.nan, 2], [6, np.nan], [7, 6]] 8 print(imp.transform(X)) 9 [[ 4. 2. ] 10 [ 6. 3.666...] 11 [ 7. 6. ]] 12 13 #對稀疏矩陣進行缺失值插補 14 import scipy.sparse as sp 15 X = sp.csc_matrix([[1, 2], [0, 3], [7, 6]]) 16 imp = Imputer(missing_values=0, strategy='mean', axis=0) 17 imp.fit(X) 18 Imputer(axis=0, copy=True, missing_values=0, strategy='mean', verbose=0) 19 X_test = sp.csc_matrix([[0, 2], [6, 0], [7, 6]]) 20 print(imp.transform(X_test)) 21 [[ 4. 2. ] 22 [ 6. 3.666...] 23 [ 7. 6. ]]
在稀疏矩陣中,缺失值被編碼為0存儲為矩陣中,這種格式是適合於缺失值比非缺失值多得多的情況。此外,Imputer類也可以用於Pipeline中
Imputor類的參數:class sklearn.preprocessing.
Imputer
(missing_values='NaN', strategy='mean', axis=0, verbose=0, copy=True)
missing_values : int或"NaN",默認NaN(String類型)
strategy : string, 默認為mean,可選則mean、median、most_frequent
axis :int, 默認為0(axis = 0,對列進行插值;axis= 1,對行進行插值)
verbose : int, 默認為0
copy : boolean, 默認為True
True:會創建一個X的副本
False:在任何合適的地方都會進行插值。
但是以下四種情況,計算設置的copy = Fasle,也會創建一個副本:
1.X不是浮點型數組
2.X是稀疏矩陣,而且miss_value = 0
3.axis= 0,X被編碼為CSR矩陣
4.axis= 1,X被編碼為CSC矩陣
舉個實例(在用隨機森林算法之前先用Imputer類進行處理):
1 import numpy as np 2 3 from sklearn.datasets import load_boston 4 from sklearn.ensemble import RandomForestRegressor 5 from sklearn.pipeline import Pipeline 6 from sklearn.preprocessing import Imputer 7 from sklearn.cross_validation import cross_val_score 8 9 rng = np.random.RandomState(0) 10 11 dataset = load_boston() 12 X_full, y_full = dataset.data, dataset.target 13 n_samples = X_full.shape[0] 14 n_features = X_full.shape[1] 15 16 # Estimate the score on the entire dataset, with no missing values 17 estimator = RandomForestRegressor(random_state=0, n_estimators=100) 18 score = cross_val_score(estimator, X_full, y_full).mean() 19 print("Score with the entire dataset = %.2f" % score) 20 21 # Add missing values in 75% of the lines 22 missing_rate = 0.75 23 n_missing_samples = np.floor(n_samples * missing_rate) 24 missing_samples = np.hstack((np.zeros(n_samples - n_missing_samples, 25 dtype=np.bool), 26 np.ones(n_missing_samples, 27 dtype=np.bool))) 28 rng.shuffle(missing_samples) 29 missing_features = rng.randint(0, n_features, n_missing_samples) 30 31 # Estimate the score without the lines containing missing values 32 X_filtered = X_full[~missing_samples, :] 33 y_filtered = y_full[~missing_samples] 34 estimator = RandomForestRegressor(random_state=0, n_estimators=100) 35 score = cross_val_score(estimator, X_filtered, y_filtered).mean() 36 print("Score without the samples containing missing values = %.2f" % score) 37 38 # Estimate the score after imputation of the missing values 39 X_missing = X_full.copy() 40 X_missing[np.where(missing_samples)[0], missing_features] = 0 41 y_missing = y_full.copy() 42 estimator = Pipeline([("imputer", Imputer(missing_values=0, 43 strategy="mean", 44 axis=0)), 45 ("forest", RandomForestRegressor(random_state=0, 46 n_estimators=100))]) 47 score = cross_val_score(estimator, X_missing, y_missing).mean() 48 print("Score after imputation of the missing values = %.2f" % score)
結果:
Score with the entire dataset = 0.56 Score without the samples containing missing values = 0.48 Score after imputation of the missing values = 0.55
七)生成多項式特征
在輸入數據中增加非線性特征可以有效的提高模型的復雜度。簡單且常用的方法就是使用多項式特征(polynomial features),可以得到特征的高階交叉項:
1 import numpy as np 2 from sklearn.preprocessing import PolynomialFeatures 3 X = np.arange(6).reshape(3, 2) 4 X 5 array([[0, 1], 6 [2, 3], 7 [4, 5]]) 8 poly = PolynomialFeatures(2) 9 poly.fit_transform(X) 10 array([[ 1., 0., 1., 0., 0., 1.], 11 [ 1., 2., 3., 4., 6., 9.], 12 [ 1., 4., 5., 16., 20., 25.]])
然而有時候我們只需要特征的交叉項,可以設置interaction_only=True來得到:
1 X = np.arange(9).reshape(3, 3) 2 X 3 array([[0, 1, 2], 4 [3, 4, 5], 5 [6, 7, 8]]) 6 poly = PolynomialFeatures(degree=3, interaction_only=True) 7 poly.fit_transform(X) 8 array([[ 1., 0., 1., 2., 0., 0., 2., 0.], 9 [ 1., 3., 4., 5., 12., 15., 20., 60.], 10 [ 1., 6., 7., 8., 42., 48., 56., 336.]])
這個方法可能大家在工作中比較少見,但世界上它經常用於核方法中,如選擇多項式核時 ( sklearn.svm.SVC
, sklearn.decomposition.KernelPCA
)
八)自定義轉換
如果以上的方法覺得都不夠,譬如你想用對數據取對數,可以自己用 FunctionTransformer自定義一個轉化器,並且可以在Pipeline中使用
1 import numpy as np 2 from sklearn.preprocessing import FunctionTransformer 3 transformer = FunctionTransformer(np.log1p)#括號內的就是自定義函數 4 X = np.array([[0, 1], [2, 3]]) 5 transformer.transform(X) 6 array([[ 0. , 0.69314718], 7 [ 1.09861229, 1.38629436]])
告訴你怎么用:
如果你在做一個分類任務時,發現第一主成分與這個不相關,你可以用FunctionTransformer把第一列除去,剩下的列用PCA:
1 import matplotlib.pyplot as plt 2 import numpy as np 3 4 from sklearn.cross_validation import train_test_split 5 from sklearn.decomposition import PCA 6 from sklearn.pipeline import make_pipeline 7 # from sklearn.preprocessing import FunctionTransformer 8 # 如果報錯ImportError: cannot import name FunctionTransformer,可以使用下面的語句 9 from sklearn.preprocessing import * 10 11 12 def _generate_vector(shift=0.5, noise=15): 13 return np.arange(1000) + (np.random.rand(1000) - shift) * noise 14 15 16 def generate_dataset(): 17 """ 18 This dataset is two lines with a slope ~ 1, where one has 19 a y offset of ~100 20 """ 21 return np.vstack(( 22 np.vstack(( 23 _generate_vector(), 24 _generate_vector() + 100, 25 )).T, 26 np.vstack(( 27 _generate_vector(), 28 _generate_vector(), 29 )).T, 30 )), np.hstack((np.zeros(1000), np.ones(1000))) 31 32 33 def all_but_first_column(X): 34 return X[:, 1:] 35 36 37 def drop_first_component(X, y): 38 """ 39 Create a pipeline with PCA and the column selector and use it to 40 transform the dataset. 41 """ 42 pipeline = make_pipeline( 43 PCA(), FunctionTransformer(all_but_first_column), 44 ) 45 X_train, X_test, y_train, y_test = train_test_split(X, y) 46 pipeline.fit(X_train, y_train) 47 return pipeline.transform(X_test), y_test 48 49 50 if __name__ == '__main__': 51 X, y = generate_dataset() 52 plt.scatter(X[:, 0], X[:, 1], c=y, s=50) 53 plt.show() 54 X_transformed, y_transformed = drop_first_component(*generate_dataset()) 55 plt.scatter( 56 X_transformed[:, 0], 57 np.zeros(len(X_transformed)), 58 c=y_transformed, 59 s=50, 60 ) 61 plt.show()
結果:
寫到這里基本上關於數據轉化的方法已經介紹的差不多了,周四寫第三篇--數據降維。寫的比較倉促,有錯誤的歡迎提出來~