分享

Python机器学习库sklearn数据预处理,数据集构建,特征选择

 Z2ty6osc12zs6c 2018-04-20
  1. from IPython.display import Image  
  2. %matplotlib inline  
  3. # Added version check for recent scikit-learn 0.18 checks  
  4. from distutils.version import LooseVersion as Version  
  5. from sklearn import __version__ as sklearn_version  

处理缺省值

  1. <span style="font-size:12px;">import pandas as pd  
  2. from io import StringIO  
  3.   
  4. csv_data = '''''A,B,C,D 
  5. 1.0,2.0,3.0,4.0 
  6. 5.0,6.0,,8.0 
  7. 10.0,11.0,12.0,'''  
  8. print(type(csv_data))  
  9. # If you are using Python 2.7, you need to convert the string to unicode:  
  10. #csv_data = unicode(csv_data)  
  11.   
  12. df = pd.read_csv(StringIO(csv_data))     
  13. #StringIO的行为与file对象非常像,但它不是磁盘上文件,而是一个内存里的“文件”,可以将操作磁盘文件那样来操作StringIO  
  14. #StringIO在内存中读写str,要想把str写入StringIO:先创建一个StringIO,然后像文件一样写入即可  
  15. df  
  16. #type(df) #pandas.core.frame.DataFrame</span>  

  1. df.isnull().sum()  #isnull判定每个位置是否是NaN,计算每一特征中:有几个样本在该特征上存在缺失  
  2. #Output:  
  3. #A    0  
  4. #B    0  
  5. #C    1  
  6. #D    1  
  7. #dtype: int64  

1.)直接删除缺省值多的样本或者特征

  1. df.dropna()   #删存在缺省值的样本  

  1. df.dropna(axis=1)   #删存在缺省值的特征  

  1. df.dropna(how='all')   #删所以特征都缺失的样本  

  1. df.dropna(thresh=4)   #删特征数少于参数指定个数的样本  

  1. df.dropna(subset=['C'])   #删在指定特征处有缺失的样本  

2.)重新计算缺省值


  1. from sklearn.preprocessing import Imputer  
  2. #http:///stable/modules/generated/sklearn.preprocessing.Imputer.html#sklearn.preprocessing.Imputer  
  3. imr = Imputer(missing_values='NaN', strategy='mean', axis=0)   #用NaN所在特征列的均值填充NaN  
  4. imr = imr.fit(df)  
  5. imputed_data = imr.transform(df.values)  
  6. imputed_data  
  7. #Output:  
  8. #array([[  1. ,   2. ,   3. ,   4. ],  
  9. #       [  5. ,   6. ,   7.5,   8. ],  
  10. #       [ 10. ,  11. ,  12. ,   6. ]])  
  1. df.values  
  2. #Output:  
  3. #array([[  1.,   2.,   3.,   4.],  
  4. #       [  5.,   6.,  nan,   8.],  
  5. #       [ 10.,  11.,  12.,  nan]])  

处理类别型数据

  1. import pandas as pd  
  2. df = pd.DataFrame([['green', 'M', 10.1, 'class1'],  
  3.                    ['red', 'L', 13.5, 'class2'],  
  4.                    ['blue', 'XL', 15.3, 'class1']])  
  5. df.columns = ['color', 'size', 'price', 'classlabel']  
  6. df  

1.)序列特征映射

  1. size_mapping = {'XL': 3,'L': 2,'M': 1}  
  2. df['size'] = df['size'].map(size_mapping)   #将size特征列的XL等字符替换成字典size_mapping映射对应的数字  
  3. df  

  1. inv_size_mapping = {v: k for k, v in size_mapping.items()}     
  2. #字典推导式,items()是将字典中键值转化成元组对,整体以列表返回  
  3. #size_mapping.items():dict_items([('XL', 3), ('L', 2), ('M', 1)])  
  4. df['size'].map(inv_size_mapping)  
  5. #Output:  
  6. #0     M  
  7. #1     L  
  8. #2    XL  
  9. #Name: size, dtype: object  

2.)类别编码

  1. import numpy as np  
  2. class_mapping = {label: idx for idx, label in enumerate(np.unique(df['classlabel']))}     
  3. #enumerate将列表参数映射成带序号的元组对  
  4. #class_mapping作用是找出出现一个新classlabel时对应的index  
  5. class_mapping  
  6. #Output:  
  7. #{'class1': 0, 'class2': 1}  
  1. df['classlabel'] = df['classlabel'].map(class_mapping)  
  2. df  

  1. inv_class_mapping = {v: k for k, v in class_mapping.items()}  
  2. df['classlabel'] = df['classlabel'].map(inv_class_mapping)  
  3. df  


  1. from sklearn.preprocessing import LabelEncoder  
  2. #http:///stable/modules/preprocessing_targets.html#preprocessing-targets  
  3. class_le = LabelEncoder()  
  4. y = class_le.fit_transform(df['classlabel'].values)  
  5. y  
  6. #Output:  
  7. #array([0, 1, 0], dtype=int64)  
  1. class_le.inverse_transform(y)  
  2. #Output:  
  3. #array(['class1', 'class2', 'class1'], dtype=object)  

3.)对类别型的特征用one-hot编码


  1. X = df[['color', 'size', 'price']].values  
  2. from sklearn.preprocessing import LabelEncoder  
  3. color_le = LabelEncoder()  
  4. X[:, 0] = color_le.fit_transform(X[:, 0])   #对color特征列进行顺序出现编码  
  5. X  
  6. #Output:  
  7. #array([[1, 1, 10.1],  
  8. #       [2, 2, 13.5],  
  9. #       [0, 3, 15.3]], dtype=object)  
  1. #检验color特征列编码序号原理,对应df结构看  
  2. from sklearn.preprocessing import LabelEncoder  
  3. color_le = LabelEncoder()  
  4. color_le.fit(df['color'])  
  5. #Output:  
  6. #array(['blue', 'green', 'red'], dtype=object)  
  7. color_le.classes_  
  1. from sklearn.preprocessing import OneHotEncoder  
  2. #http:///stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html#sklearn.preprocessing.OneHotEncoder  
  3. ohe = OneHotEncoder(categorical_features=[0])   #categorical_features参数指定独热特征列  
  4. ohe.fit_transform(X).toarray()  
  5. #Output:  
  6. #array([[  0. ,   1. ,   0. ,   1. ,  10.1],  
  7. #       [  0. ,   0. ,   1. ,   2. ,  13.5],  
  8. #       [  1. ,   0. ,   0. ,   3. ,  15.3]])  
  1. pd.get_dummies(df[['price', 'color', 'size']])   #pandas内的独热方法get_dummies()  

切分数据集(训练集与测试集)

  1. df_wine = pd.read_csv('https://archive.ics./ml/machine-learning-databases/wine/wine.data',header=None)  
  2. df_wine.columns = ['Class label', 'Alcohol', 'Malic acid', 'Ash',  
  3.                    'Alcalinity of ash', 'Magnesium', 'Total phenols',  
  4.                    'Flavanoids', 'Nonflavanoid phenols', 'Proanthocyanins',  
  5.                    'Color intensity', 'Hue', 'OD280/OD315 of diluted wines',  
  6.                    'Proline']  
  7. print('Class labels', np.unique(df_wine['Class label']))  
  8. #df_wine.to_csv('wine.csv')  
  9. df_wine.head()  
  10. #Output:  
  11. #Class labels [1 2 3]  

  1. if Version(sklearn_version) < '0.18':  
  2.     from sklearn.cross_validation import train_test_split  
  3. else:  
  4.     from sklearn.model_selection import train_test_split  
  5. X, y = df_wine.iloc[:, 1:].values, df_wine.iloc[:, 0].values   #df_wine数据的第一列作为标签类别,其余列作为特征  
  6. X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)   #全部数据的30%作为测试集  

对连续值特征做幅度缩放(scaling)


  1. from sklearn.preprocessing import MinMaxScaler  
  2. #http:///stable/modules/generated/sklearn.preprocessing.MinMaxScaler.html#sklearn.preprocessing.MinMaxScaler  
  3. #U(0,1)区间[0,1]上的均匀分布缩放,按单个特征列看  
  4. mms = MinMaxScaler()  
  5. X_train_norm = mms.fit_transform(X_train)  
  6. X_test_norm = mms.transform(X_test)  
  7. from sklearn.preprocessing import StandardScaler  
  8. #N(0,1)正态分布缩放  
  9. stdsc = StandardScaler()  
  10. X_train_std = stdsc.fit_transform(X_train)  
  11. X_test_std = stdsc.transform(X_test)  

特征选择

1.) 通过L1正则化的截断型效应选择


  1. from sklearn.linear_model import LogisticRegression  
  2. lr = LogisticRegression(penalty='l1', C=0.1)  
  3. lr.fit(X_train_std, y_train)  
  4. print('Training accuracy:', lr.score(X_train_std, y_train))  
  5. print('Test accuracy:', lr.score(X_test_std, y_test))  
  6. #Output:  
  7. #Training accuracy: 0.983870967742  
  8. #Test accuracy: 0.981481481481  
  1. lr.intercept_  
  2. #Output:  
  3. #array([-0.38380842, -0.15812178, -0.70041244])  
  1. lr.coef_  
  2. #Output:  
  3. #array([[ 0.28025703,  0.        ,  0.        , -0.02792998,  0.        ,  
  4. #         0.        ,  0.71008021,  0.        ,  0.        ,  0.        ,  
  5. #         0.        ,  0.        ,  1.23625518],  
  6. #       [-0.64387692, -0.06882766, -0.05718195,  0.        ,  0.        ,  
  7. #         0.        ,  0.        ,  0.        ,  0.        , -0.92717674,  
  8. #         0.05982319,  0.        , -0.37086571],  
  9. #       [ 0.        ,  0.06151692,  0.        ,  0.        ,  0.        ,  
  10. #         0.        , -0.63612079,  0.        ,  0.        ,  0.49812314,  
  11. #        -0.35823174, -0.57118053,  0.        ]])  
  1. import matplotlib.pyplot as plt  
  2. fig = plt.figure()  
  3. ax = plt.subplot(111)      
  4. colors = ['blue', 'green', 'red', 'cyan', 'magenta', 'yellow', 'black',  
  5.           'pink', 'lightgreen', 'lightblue', 'gray', 'indigo', 'orange']  
  6. weights, params = [], []  
  7. for c in range(-4, 6):  
  8.     lr = LogisticRegression(penalty='l1', C=10**c, random_state=0)  
  9.     lr.fit(X_train_std, y_train)  
  10.     weights.append(lr.coef_[1])  
  11.     params.append(10**c)  
  12. weights = np.array(weights)   #10*13的数组  
  13. for column, color in zip(range(weights.shape[1]), colors):  
  14.     plt.plot(params, weights[:, column], label=df_wine.columns[column + 1], color=color)  
  15. #column+1去掉第一列label列  
  16. plt.axhline(0, color='black', linestyle='--', linewidth=1)  
  17. plt.xlim([10**(-5), 10**5])  
  18. plt.ylabel('weight coefficient')  
  19. plt.xlabel('C')  
  20. plt.xscale('log')  
  21. plt.legend(loc='upper left')  
  22. ax.legend(loc='upper center', bbox_to_anchor=(1.38, 1.03), ncol=1, fancybox=True)  
  23. # plt.savefig('./figures/l1_path.png', dpi=300)  
  24. plt.show()  

2.) 遍历子特征集选择法

  1. from sklearn.base import clone  
  2. from itertools import combinations  
  3. import numpy as np  
  4. from sklearn.metrics import accuracy_score  
  5. #http:///stable/modules/generated/sklearn.metrics.accuracy_score.html#sklearn.metrics.accuracy_score  
  6. if Version(sklearn_version) < '0.18':  
  7.     from sklearn.cross_validation import train_test_split  
  8. else:  
  9.     from sklearn.model_selection import train_test_split  
  10.   
  11. class SBS():  
  12.     def __init__(self, estimator, k_features, scoring=accuracy_score, test_size=0.25, random_state=1):  
  13.         self.scoring = scoring  
  14.         self.estimator = clone(estimator)   #构造一个具有相同参数的估计器  
  15.         #http:///stable/modules/generated/sklearn.base.clone.html#sklearn.base.clone  
  16.         self.k_features = k_features  
  17.         self.test_size = test_size  
  18.         self.random_state = random_state  
  19.   
  20.     def fit(self, X, y):  
  21.         X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=self.test_size, random_state=self.random_state)  
  22.         dim = X_train.shape[1]   #13  
  23.         self.indices_ = tuple(range(dim))   #(0,1,2,...,12)  
  24.         self.subsets_ = [self.indices_]  
  25.         score = self._calc_score(X_train, y_train, X_test, y_test, self.indices_)   #全特征组合得分  
  26.         self.scores_ = [score]  
  27.   
  28.         while dim > self.k_features:   #至少要考虑到k_features个特征  
  29.             scores = []  
  30.             subsets = []  
  31.             for p in combinations(self.indices_, r=dim - 1):   #combinations求组合,不取全部13个特征:每次只取12个特征,11个特征...  
  32.                 score = self._calc_score(X_train, y_train, X_test, y_test, p)  
  33.                 scores.append(score)  
  34.                 subsets.append(p)  
  35.             best = np.argmax(scores)   #argmax求分数最高的特征组合所在的索引  
  36.             self.indices_ = subsets[best]   #根据索引,取分数最高特征组合  
  37.             self.subsets_.append(self.indices_)   #同个数特征的各个组合中,得分最高的组合构成的列表  
  38.             dim -= 1  
  39.             self.scores_.append(scores[best])   #同个数特征的各个组合中,最优特征组合的得分构成的列表  
  40.         self.k_score_ = self.scores_[-1]   #每k个特征组合的最好得分,直接取scores_列表中最好加入的元素  
  41.         return self  
  42.   
  43.     def transform(self, X):  
  44.         return X[:, self.indices_]  
  45.   
  46.     def _calc_score(self, X_train, y_train, X_test, y_test, indices):  
  47.         self.estimator.fit(X_train[:, indices], y_train)  
  48.         y_pred = self.estimator.predict(X_test[:, indices])  
  49.         score = self.scoring(y_test, y_pred)   #用accuracy_score方法计算  
  50.         return score  
  51. #indices_是每个维度最优特征组合元组,subsets_是包含各个维度最优特征组合元组的列表,scores_是包含各个维度最优特征组合得分的列表  
  1. import matplotlib.pyplot as plt  
  2. from sklearn.neighbors import KNeighborsClassifier  
  3. knn = KNeighborsClassifier(n_neighbors=2)  
  4. # selecting features  
  5. sbs = SBS(knn, k_features=1)  
  6. sbs.fit(X_train_std, y_train)  
  7.   
  8. # plotting performance of feature subsets  
  9. k_feat = [len(k) for k in sbs.subsets_]  
  10.   
  11. plt.plot(k_feat, sbs.scores_, marker='o')  
  12. plt.ylim([0.7, 1.1])  
  13. plt.ylabel('Accuracy')  
  14. plt.xlabel('Number of features')  
  15. plt.grid()  
  16. plt.tight_layout()  
  17. # plt.savefig('./sbs.png', dpi=300)  
  18. plt.show()  

  1. k5 = list(sbs.subsets_[8])  
  2. print(df_wine.columns[1:][k5])   #去除第一个标签列计数  
  3. #Output:  
  4. #Index(['Alcohol', 'Malic acid', 'Alcalinity of ash', 'Hue', 'Proline'], dtype='object')  
  1. knn.fit(X_train_std, y_train)   #全部特征建模得分  
  2. print('Training accuracy:', knn.score(X_train_std, y_train))  
  3. print('Test accuracy:', knn.score(X_test_std, y_test))  
  4. #Output:  
  5. #Training accuracy: 0.983870967742  
  6. #Test accuracy: 0.944444444444  
  1. knn.fit(X_train_std[:, k5], y_train)   #只选k5组合包含的特征建模得分  
  2. print('Training accuracy:', knn.score(X_train_std[:, k5], y_train))  
  3. print('Test accuracy:', knn.score(X_test_std[:, k5], y_test))  
  4. #Output:  
  5. #Training accuracy: 0.959677419355  
  6. #Test accuracy: 0.962962962963  

3.) 通过随机森林对特征重要性排序

  1. from sklearn.ensemble import RandomForestClassifier  
  2. feat_labels = df_wine.columns[1:]   #特征列名  
  3. forest = RandomForestClassifier(n_estimators=2000, random_state=0, n_jobs=-1)  #2000棵树,并行工作数是运行服务器决定  
  4. forest.fit(X_train, y_train)  
  5. importances = forest.feature_importances_   #feature_importances_特征列重要性占比  
  6. indices = np.argsort(importances)[::-1]   #对参数从小到大排序的索引序号取逆,即最重要特征索引——>最不重要特征索引  
  7. for f in range(X_train.shape[1]):  
  8.     print("%2d) %-*s %f" % (f + 1, 30, feat_labels[indices[f]], importances[indices[f]]))     
  9. #-*s表示左对齐字段feat_labels[indices[f]]宽为30  
  10. plt.title('Feature Importances')  
  11. plt.bar(range(X_train.shape[1]), importances[indices], color='lightblue', align='center')  
  12. plt.xticks(range(X_train.shape[1]), feat_labels[indices], rotation=90)  
  13. plt.xlim([-1, X_train.shape[1]])  
  14. plt.tight_layout()  
  15. #plt.savefig('./random_forest.png', dpi=300)  
  16. plt.show()  
  17. #Output:  
  18. # 1) Color intensity                0.183084  
  19. # 2) Proline                        0.163305  
  20. # 3) Flavanoids                     0.152030  
  21. # 4) OD280/OD315 of diluted wines   0.133887  
  22. # 5) Alcohol                        0.103847  
  23. # 6) Hue                            0.077784  
  24. # 7) Total phenols                  0.058778  
  25. # 8) Alcalinity of ash              0.031300  
  26. # 9) Malic acid                     0.024420  
  27. #10) Magnesium                      0.021949  
  28. #11) Proanthocyanins                0.021870  
  29. #12) Nonflavanoid phenols           0.014450  
  30. #13) Ash                            0.013294  

  1. if Version(sklearn_version) < '0.18':  
  2.     X_selected = forest.transform(X_train, threshold=0.15)  
  3. else:  
  4.     from sklearn.feature_selection import SelectFromModel  
  5.     sfm = SelectFromModel(forest, threshold=0.15, prefit=True)     
  6.     #forest参数是建模完带特征重要性信息的估计器,threshold是特征筛选阈值  
  7.     X_selected = sfm.transform(X_train)   #transform对样本X_train进行了选定特征列过滤  
  8. X_selected.shape  
  9. #Output:  
  10. #(124, 3)  
  1. for f in range(X_selected.shape[1]):  
  2.     print("%2d) %-*s %f" % (f + 1, 30, feat_labels[indices[f]], importances[indices[f]]))  
  3. #Output:  
  4. # 1) Color intensity                0.183084  
  5. # 2) Proline                        0.163305  
  6. # 3) Flavanoids                     0.152030  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多