2. 用scikit-learn估計器分類
阿新 • • 發佈:2018-12-14
# -*- coding: utf-8 -*- """ Created on Sat Sep 22 09:43:28 2018 @author: asus """ #2 用scikit-learn估計器分類 #估計器(Estimator):用於分類、聚類和迴歸分析 #轉換器(Transformer):用於資料預處理和資料轉換 #流水線(Pipeline):組合資料探勘流程,便於再次使用。 #2.1 scikit-learn估計器 #主要引數 #fit():訓練演算法,設定內部引數。該函式接收訓練集及其類別兩個引數。 #predict():引數為測試集。預測測試集類別,並返回一個包含測試集各條資料類別的陣列。 #scikit-learn提供了大量估計器,其中有支援向量機(SVM)、隨機森林、神經網路等。 #2.1.1 近鄰演算法 #計算量大,在特徵取離散值的資料集上表現很差。 #常用的距離度量,歐氏距離,曼哈頓距離,餘弦距離。 #即將用到的資料集叫作電離層,這些資料是由高頻天線收集的。最後一列,'g'好,'b'壞,為數 #據的好壞,即是否提供了有價值的資訊。 import numpy as np import csv data_filename = "E:/books/Python資料探勘入門與實踐/ionosphere.data" #建立NumPy陣列x和y存放資料集。資料大小已知,共有351行34列。 x = np.zeros((351, 34), dtype='float') y = np.zeros((351,), dtype='bool') with open(data_filename, 'r') as input_file: reader = csv.reader(input_file) #遍歷檔案中的每一行資料。用列舉函式獲得每行的索引號 for i, row in enumerate(reader): #獲取每一個個體的前34個值,將其轉化為浮點型,儲存到X中 data = [float(datum) for datum in row[:-1]] x[i] = data #獲得每個個體最後一個表示類別的值,把字母轉化為數字,如果類別為‘g’,值為1, #否則為0 y[i] = row[-1] == 'g' #2.1.4 努力實現流程標準化 #建立訓練集和測試集 from sklearn.cross_validation import train_test_split x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=14) #x_train訓練集,x_test測試集。y_train,y_test分別為以上兩個資料集的類別資訊。 #匯入K近鄰分類器這個類,併為其初始化一個例項。預設選擇5個近鄰作為分類依據。 from sklearn.neighbors import KNeighborsClassifier estimator = KNeighborsClassifier() #估計器建立好後,接下來就要用訓練資料進行訓練。K近鄰估計器分析訓練集中的資料,比較待分 #類的新資料點和訓練集中的資料,找到新資料點的近鄰。 estimator.fit(x_train, y_train) #接著,用測試集測試演算法,評估它在測試集上的表現 y_predicted = estimator.predict(x_test) accuracy = np.mean(y_test == y_predicted) * 100 print("The test accuracy is {:.1f}%".format(accuracy)) #2.1.5 執行演算法 #交叉檢驗 from sklearn.cross_validation import cross_val_score scores = cross_val_score(estimator, x, y, scoring='accuracy') average_accuracy = np.mean(scores) * 100 print("The test accuracy is {:.1f}%".format(average_accuracy)) #2.1.6 設定引數 #n_neighbors,選取多少個近鄰作為預測依據。 #測試1到20的n_neighbors avg_scores = [] all_scores = [] parameter_values = list(range(1, 21)) for n_neighbors in parameter_values: estimator = KNeighborsClassifier(n_neighbors=n_neighbors) scores = cross_val_score(estimator, x, y, scoring='accuracy') #把不同n_neighbors值的得分和平均儲存起來,留作分析用 avg_scores.append(np.mean(scores)) all_scores.append(scores) %matplotlib inline from matplotlib import pyplot as plt plt.plot(parameter_values, avg_scores, '-o') #2.2 流水線在預處理中的應用 #轉換器(Transformer),它接受原始資料集,返回轉換後的資料集。 #2.2.1 預處理案例 #講解需要,先對資料集做些破壞 x_broken = np.array(x) #建立一個副本 x_broken[:,::2] /= 10 #每隔一行,就把第二行的特徵除以10 #數值範圍變了,再次計算正確率 estimator = KNeighborsClassifier() #原始資料集的正確率 original_scores = cross_val_score(estimator, x, y, scoring='accuracy') print("The test accuracy is {:.1f}%".format(np.mean(original_scores) * 100)) #副本的正確率 broken_scores = cross_val_score(estimator, x_broken, y, scoring='accuracy') print("The test accuracy is {:.1f}%".format(np.mean(broken_scores) * 100)) #2.2.2 標準預處理 from sklearn.preprocessing import MinMaxScaler #規範化,標準化,最小值用0代替,最大值用1代替,其餘值介於兩者之間 x_transformed = MinMaxScaler().fit_transform(x) #其他規範化方法 #為使每條資料各特徵值的和為1,使用sklearn.preprocessing.Normalizer #為使各特徵的均值為0,方差為1,使用sklearn.preprocessing.StandardScaler,常用作規範 #化的基準 #為將數值型特徵的二值化,使用sklearn.preprocessing.Binarizer,大於閾值的為1,反之為0 #2.2.3 組裝起來 x_transformed = MinMaxScaler().fit_transform(x_broken) estimator = KNeighborsClassifier() transformed_scores = cross_val_score(estimator, x_transformed, y, scoring='accuracy') print("The test accuracy is {:.1f}%".format(np.mean(transformed_scores) * 100)) #正確率又再次升回來了 #異常值會影響近鄰演算法,不同演算法對值域大小的敏感度不同 #2.3 流水線 #流水線把這些步驟儲存到資料探勘的工作流中。之後你就可以用它們讀入資料,做各種必要的處 #理,然後給出預測結果。 from sklearn.pipeline import Pipeline #流水線的輸入為一連串的資料探勘步驟,其中最後一步必須是估計器,前幾步是轉換器。 #每一部都用元組(‘名稱’,步驟)表示。 scaling_pipeline = Pipeline([('scale', MinMaxScaler()), ('predict', KNeighborsClassifier())]) #流水線的核心是元素為元組的列表。第一個元組規範特徵取值範圍,第二個元組實現預測功能。 scores = cross_val_score(scaling_pipeline, x_broken, y, scoring='accuracy') print("The pipeline scored an average accuracy for is {0:.1f}%". format(np.mean(scores) * 100))