在機器學習中,選擇合適的算法固然重要,但是數據的處理也同樣重要。通過對數據的處理,能提高計算效率,提高預測識別精確度等等
以下記錄下一些數據處理的方法
一、處理缺失值
對於數據集中有缺失值的,粗暴的方法是直接刪除該行或者該列的數據,但是這樣不可取。可以通過計算每一列或者每一行的平均值來替代該值。
from sklearn.preprocessing import Imputer import pandas as pd df = pd.read_csv(data_dir) imr = Imputer(missing_values='NaN', strategy='mean', axis=0) imr = imr.fit(df) imputed_data = imr.transform(df.values)
strategy除了mean還有其他的選項
二、處理分類數據,如果數據中有字符串,可以將字符串和數值做個映射
from sklearn.preprocessing import LabelEncoder class_le = LabelEncoder() y = class_le.fit_transform(df['classlabel'].values)
可以使用inverse_transform得到原始字符串
如果數據中有離散的特征值,可以對其進行獨熱編碼
比如顏色,r,g,b如果通過圖片的映射得到r=1,g=2,b=3機器會認為b>g>r,顯然不符合我們的要求
可以將其編碼為100,010,001來識別
from sklearn.preprocessing import OneHotEncoder ohe = OneHotEncoder(categorical_features=[0]) ohe.fit_transform(X).toarray()
將數據集隨機分隔成訓練集和測試集
from sklearn.cross_validation import train_test_split X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.3, random_state=0)
將數據集分成70%訓練集30%測試集
三、標准化和歸一化
歸一化是將特征范圍縮小到0-1。主要目的是為了簡化計算
計算公式
標准化是將數據按比例縮放,使其落入一個小的特定區間
四、過擬合問題
如果一個模型在訓練集的表現比測試集好很多,很可能就是過擬合了,即泛化能力太差,具有高方差
產生的一個原因是對應給定的訓練集數據,模型過於復雜。常用的減小泛化誤差的做法
1收集更多的訓練集數據
2正則化,即引入模型復雜度的懲罰項
3選擇簡單的模型,參數少一點的
4降低數據的維度
五、正則化(特征選擇,處理過擬合問題的一種方式)
常用的正則項有
L1正則權重參數的絕對值和
L2正則權重參數的平方和
正則項是對現在損失函數的懲罰項,鼓勵權重參數取小一點的值,懲罰大權重參數,
正則化后的新損失函數=原始損失函數+正則項
對於sklearn中支持L1正則的模型,只需要初始化的時候用penalty參數設置為L1正則即可
from sklearn.linear_model import LogisticRegression LogisticRegression(penalty='l1')
六、降維(特征抽取,處理過擬合的一種方式)
1主成分分析PCA,用於無監督數據壓縮
2線性判別分析LDA,用於監督降維作為一種監督降維
3核PCA
特征抽取可以理解為是一種數據壓縮的手段,用於提高計算效率,減小維度詛咒。
PCA主成分分析是一種廣泛使用的無監督的線性轉換技術,主要用於降維
PCA的步驟
1.將d維度原始數據標准化
2.構建協方差矩陣
3.求解協方差矩陣的特征向量和特征值
4.選證值最大的k個特征值對應的特征向量,k就是新特征空間的維度,k<<d
5利用k特征向量構建映射矩陣W
6將原始d維度的數據集X,通過映射矩陣W轉換到k維度的特征子空間
標准化數據集
from sklearn.cross_validation import train_test_split from sklearn.preprocessing import StandardScaler X, y = xxx,xxx X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0) sc = StandardScaler() X_train_std = sc.fit_transform(X_train) X_test_std = sc.transform(X_test)
協方差計算公式
計算協方差矩陣
import numpy as np cov_mat = np.cov(X_train_std.T)
獲取特征值和特征向量
eigen_vals, eigen_vecs = np.linalg.eig(cov_mat)
eigen_vals為特征值,eigen_vecs為特征向量
特征值越大其包含的信息越多
可以使用方差解釋率(特征值占特征值總和的比例)來查看其占比,取最大的幾項,舍棄占比低的
tot = sum(eigen_vals) var_exp = [(i / tot) for i in sorted(eigen_vals, reverse=True)] cum_var_exp = np.cumsum(var_exp)
假設前兩項占比最大
eigen_pairs = [(np.abs(eigen_vals[i]), eigen_vecs[:, i]) for i in range(len(eigen_vals))] eigen_pairs.sort(reverse=True) w = np.hstack((eigen_pairs[0][1][:, np.newaxis], eigen_pairs[1][1][:, np.newaxis])) X_train_pca = X_train_std.dot(w)
將維度降到二維
更簡單的方法
from sklearn.decomposition import PCA pca = PCA(n_components=2) X_train_pca = pca.fit_transform(X_train_std) X_test_pca = pca.transform(X_test_std)
LDA的一個假設是數據服從正態分布,同時每個類含有相同的協方差矩陣,每個特征都統計獨立。即使真是數據可能不服從假設,LDA也依然具有很好的表現
LDA的步驟
1.將d維度原始數據進行標准化.
2.對每一個類,計算d維度的平均向量.
3.構建類間(between-class)散點矩陣和類內(within-class)散點矩陣
.
4.計算矩陣的特征向量和特征值.
5.選擇值最大的前k個特征值對應的特征向量,構建d*d維度的轉換矩陣,每一個特征向量是
的一列.
6.使用矩陣將原始數據集映射到新的特征子空間.
簡單的方法
from sklearn.lda import LDA lda = LDA(n_components=2) X_train_lda = lda.fit_transform(X_train_std, y_train)
核PCA(處理非線性可分數據)
運用核PCA,將非線性可分的數據轉換到新的,低維度的特征子空間,然后運用線性分類器解決
核函數的功能可以理解為:通過創造出原始特征的一些非線性組合,將原來的d維度數據集映射到k維度特征空間的d<k
先將數據轉換到一個高維度的空間,然后在該空間運用標准PCA重新將數據映射到一個比原來還低的空間,最后就可以用線性分類器解決問題了
from scipy.spatial.distance import pdist, squareform from scipy import exp from scipy.linalg import eigh def rbf_kernel_pca(X, gamma, n_components): sq_dists = pdist(X, 'sqeuclidean') mat_sq_dists = squareform(sq_dists) K = exp(-gamma * mat_sq_dists) N = K.shape[0] one_n = np.ones((N, N)) / N K = K - one_n.dot(K) - K.dot(one_n) + one_n.dot(K).dot(one_n) eigvals, eigvecs = eigh(K) X_pc = np.column_stack((eigvecs[:, -i] for i in range(1, n_components + 1))) return X_pc
sklearn實現核PCA
from sklearn.datasets import make_moons from sklearn.decomposition import KernelPCA X, y = make_moons(n_samples=100, random_state=123) scikit_kpca = KernelPCA(n_components=2, kernel='rbf', gamma=15) X_skernpca = scikit_kpca.fit_transform(X)
使用PCA,我們將數據映射到一個低維度的子空間並且最大化正交特征軸的方差,PCA不考慮類別信息。LDA是一種監督降維方法,意味着他要考慮訓練集的類別信息,目標是將類別最大化地可分。最后,學習了核PCA,它能夠將非線性數據集映射到低維特征空間,然后數據變成線性可分了
摘自https://www.gitbook.com/book/ljalphabeta/python-/details