數據的特徵預處理
單個特徵
(1)歸一化python
歸一化首先在特徵(維度)很是多的時候,能夠防止某一維或某幾維對數據影響過大,也是爲了把不一樣來源的數據統一到一個參考區間下,這樣比較起來纔有意義,其次能夠程序能夠運行更快。 例如:一我的的身高和體重兩個特徵,假如體重50kg,身高175cm,因爲兩個單位不同,數值大小不同。若是比較兩我的的體型差距時,那麼身高的影響結果會比較大,k-臨近算法會有這個距離公式。git
min-max方法算法
經常使用的方法是經過對原始數據進行線性變換把數據映射到[0,1]之間,變換的函數爲:數組
X^{'}{=}\frac{x-min}{max-min}X′=max−minx−minapp
其中min是樣本中最小值,max是樣本中最大值,注意在數據流場景下最大值最小值是變化的,另外,最大值與最小值很是容易受異常點影響,因此這種方法魯棒性較差,只適合傳統精確小數據場景。dom
- min-max自定義處理
這裏咱們使用相親約會對象數據在MatchData.txt,這個樣本時男士的數據,三個特徵,玩遊戲所消耗時間的百分比、每一年得到的飛行常客里程數、每週消費的冰淇淋公升數。而後有一個 所屬類別,被女士評價的三個類別,不喜歡、魅力通常、極具魅力。 首先導入數據進行矩陣轉換處理函數
import numpy as np def data_matrix(file_name): """ 將文本轉化爲matrix :param file_name: 文件名 :return: 數據矩陣 """ fr = open(file_name) array_lines = fr.readlines() number_lines = len(array_lines) return_mat = zeros((number_lines, 3)) # classLabelVector = [] index = 0 for line in array_lines: line = line.strip() list_line = line.split('\t') return_mat[index,:] = list_line[0:3] # if(listFromLine[-1].isdigit()): # classLabelVector.append(int(listFromLine[-1])) # else: # classLabelVector.append(love_dictionary.get(listFromLine[-1])) # index += 1 return return_mat
輸出結果爲測試
[[ 4.09200000e+04 8.32697600e+00 9.53952000e-01] [ 1.44880000e+04 7.15346900e+00 1.67390400e+00] [ 2.60520000e+04 1.44187100e+00 8.05124000e-01] ..., [ 2.65750000e+04 1.06501020e+01 8.66627000e-01] [ 4.81110000e+04 9.13452800e+00 7.28045000e-01] [ 4.37570000e+04 7.88260100e+00 1.33244600e+00]]
咱們查看數據集會發現,有的數值大到幾萬,有的才個位數,一樣若是計算兩個樣本之間的距離時,其中一個影響會特別大。也就是說飛行里程數對於結算結果或者說相親結果影響較大,可是統計的人以爲這三個特徵同等重要,因此須要將數據進行這樣的處理。編碼
這樣每一個特徵任意的範圍將變成[0,1]的區間內的值,或者也能夠根據需求處理到[-1,1]之間,咱們再定義一個函數,進行這樣的轉換。spa
def feature_normal(data_set): """ 特徵歸一化 :param data_set: :return: """ # 每列最小值 min_vals = data_set.min(0) # 每列最大值 max_vals = data_set.max(0) ranges = max_vals - min_vals norm_data = np.zeros(np.shape(data_set)) # 得出行數 m = data_set.shape[0] # 矩陣相減 norm_data = data_set - np.tile(min_vals, (m,1)) # 矩陣相除 norm_data = norm_data/np.tile(ranges, (m, 1))) return norm_data
輸出結果爲
[[ 0.44832535 0.39805139 0.56233353] [ 0.15873259 0.34195467 0.98724416] [ 0.28542943 0.06892523 0.47449629] ..., [ 0.29115949 0.50910294 0.51079493] [ 0.52711097 0.43665451 0.4290048 ] [ 0.47940793 0.3768091 0.78571804]]
這樣得出的結果都很是相近,這樣的數據能夠直接提供測試驗證了
- min-max的scikit-learn處理
scikit-learn.preprocessing中的類MinMaxScaler,將數據矩陣縮放到[0,1]之間
(3)標準化
經常使用的方法是z-score標準化,通過處理後的數據均值爲0,標準差爲1,處理方法是:
>>> X_train = np.array([[ 1., -1., 2.], ... [ 2., 0., 0.], ... [ 0., 1., -1.]]) ... >>> min_max_scaler = preprocessing.MinMaxScaler() >>> X_train_minmax = min_max_scaler.fit_transform(X_train) >>> X_train_minmax array([[ 0.5 , 0. , 1. ], [ 1. , 0.5 , 0.33333333], [ 0. , 1. , 0. ]])
X^{'}{=}\frac{x-\mu}{\sigma}X′=σx−μ
其中\muμ是樣本的均值,\sigmaσ是樣本的標準差,它們能夠經過現有的樣本進行估計,在已有的樣本足夠多的狀況下比較穩定,適合嘈雜的數據場景
sklearn中提供了StandardScalar類實現列標準化:
In [2]: import numpy as np In [3]: X_train = np.array([[ 1., -1., 2.],[ 2., 0., 0.],[ 0., 1., -1.]]) In [4]: from sklearn.preprocessing import StandardScaler In [5]: std = StandardScaler() In [6]: X_train_std = std.fit_transform(X_train) In [7]: X_train_std Out[7]: array([[ 0. , -1.22474487, 1.33630621], [ 1.22474487, 0. , -0.26726124], [-1.22474487, 1.22474487, -1.06904497]])
(3)缺失值
因爲各類緣由,許多現實世界的數據集包含缺乏的值,一般編碼爲空白,NaN或其餘佔位符。然而,這樣的數據集與scikit的分類器不兼容,它們假設數組中的全部值都是數字,而且都具備和保持含義。使用不完整數據集的基本策略是丟棄包含缺失值的整個行和/或列。然而,這是以丟失多是有價值的數據(即便不完整)的代價。更好的策略是估算缺失值,即從已知部分的數據中推斷它們。
(1)填充缺失值 使用sklearn.preprocessing中的Imputer類進行數據的填充
class Imputer(sklearn.base.BaseEstimator, sklearn.base.TransformerMixin) """ 用於完成缺失值的補充 :param param missing_values: integer or "NaN", optional (default="NaN") 丟失值的佔位符,對於編碼爲np.nan的缺失值,使用字符串值「NaN」 :param strategy: string, optional (default="mean") 插補策略 若是是「平均值」,則使用沿軸的平均值替換缺失值 若是爲「中位數」,則使用沿軸的中位數替換缺失值 若是「most_frequent」,則使用沿軸最頻繁的值替換缺失 :param axis: integer, optional (default=0) 插補的軸 若是axis = 0,則沿列排列 若是axis = 1,則沿行排列 """ >>> import numpy as np >>> from sklearn.preprocessing import Imputer >>> imp = Imputer(missing_values='NaN', strategy='mean', axis=0) >>> imp.fit([[1, 2], [np.nan, 3], [7, 6]]) Imputer(axis=0, copy=True, missing_values='NaN', strategy='mean', verbose=0) >>> X = [[np.nan, 2], [6, np.nan], [7, 6]] >>> print(imp.transform(X)) [[ 4. 2. ] [ 6. 3.666...] [ 7. 6. ]]
多個特徵
降維
PCA(Principal component analysis),主成分分析。特色是保存數據集中對方差影響最大的那些特徵,PCA極其容易受到數據中特徵範圍影響,因此在運用PCA前必定要作特徵標準化,這樣才能保證每維度特徵的重要性等同。
sklearn.decomposition.PCA
class PCA(sklearn.decomposition.base) """ 主成成分分析 :param n_components: int, float, None or string 這個參數能夠幫咱們指定但願PCA降維後的特徵維度數目。最經常使用的作法是直接指定降維到的維度數目,此時n_components是一個大於1的整數。 咱們也能夠用默認值,即不輸入n_components,此時n_components=min(樣本數,特徵數) :param whiten: bool, optional (default False) 判斷是否進行白化。所謂白化,就是對降維後的數據的每一個特徵進行歸一化。對於PCA降維自己來講通常不須要白化,若是你PCA降維後有後續的數據處理動做,能夠考慮白化,默認值是False,即不進行白化 :param svd_solver: 選擇一個合適的SVD算法來降維,通常來講,使用默認值就夠了。 """
經過一個例子來看
>>> import numpy as np >>> from sklearn.decomposition import PCA >>> X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]]) >>> pca = PCA(n_components=2) >>> pca.fit(X) PCA(copy=True, iterated_power='auto', n_components=2, random_state=None, svd_solver='auto', tol=0.0, whiten=False) >>> print(pca.explained_variance_ratio_) [ 0.99244... 0.00755...]