經典的分類例子:
經典的分類例子:
- 現在講講我們這個經典的分類應用,在數據挖掘的領域,有一個非常有名的鳶尾花叫Iris(這個數據集有150個數據樣本)。
- 我們要根據這個花的四個特徵(萼片長度sepal length, 寬度sepal width, 花瓣長度petal length, 寬度petal width)將花分為三個類別(Iris Setosa, Iris Versicolour, Iris Virginia)。
- 這個數據集已經包含在scikit-learn這個庫裡面了,所以可以直接引用。
- 首先,載入數據集:
from sklearn.datasets import load_irisimport numpy as npdataset = load_iris()X = dataset.datay = dataset.target
- 當然 你要也可以查看數據集的詳細信息:
print(dataset.DESCR)
- 在這裡,我們要對數據進行離散化的處理,當某種類別的數據高於一個閾值(threshold),我們就給這個數據賦值1,反之賦值0。
- 這裡閾值我們選擇每個特徵數值的平均值,如下:
#計算每一列數據的平均值attribute_means = X.mean(axis = 0)#assert是一個斷言,如果平均值計算之後attribute_means的長度不等於4,則觸發異常assert attribute_means.shape == (n_features,)#現在我們將數據集從數值型轉化為0 和 1的稀疏矩陣X_d = np.array(X >= attribute_means, dtype = int)
- 演算法的開始思路大概是這樣的:迭代每一個特徵的每一個值,計算每一個類與其對應的特徵值數量(分為0 和 1)。記錄下次數最高的特徵值,與剩餘特徵值之和。
- 例如:對於某個特徵(有0、1兩種值),對於0這個值,有20個在類別A,60個在類別B,20個在類別C。則這個特徵的預測值就是B(有60次對的,但也有40次是錯誤的),因為有40次的值對應類別A與類別C(對數值1,同理)。
- 在這個例子里,我們用OneR演算法來進行分類。OneR就是:將所有的特徵統計完,計算所有特徵的錯誤率,再選擇錯誤率最低的特徵作為唯一的分類標準。以下用代碼實現一下:
from collections import defaultdictfrom operator import itemgetter#創建一個函數,用於選擇: 參數包括數據集、類別、特徵的索引、還有數值#X是數據集、y_true是類別、feature是特徵的索引、value是0 或 1def train_feature_value(X, y_true, feature, value): #用字典來計算特定預測的頻率 class_counts = defaultdict(int) #循環每一個樣本,然後計算每一對類與數值的頻率 for sample, y in zip(X, y_true): if sample[feature] == value: class_counts[y] += 1 #對數值進行排序,選擇最高的那個 sorted_class_counts = sorted(class_counts.items(), key = itemgetter(1), reverse = True) most_frequent_class = sorted_class_counts[0][0] #現在計算沒有將值賦給頻率最高的類別的數量,也就是錯誤分類之和 n_samples = X.shape[1] error = sum([class_count for class_value, class_count in class_counts.items() if class_value != most_frequent_class]) return most_frequent_class, error
- 下面寫一個Train的函數,用數據來訓練模型:
def train(X, y_true, feature): #判斷傳入的變數是有效的 n_samples, n_features = X.shape assert 0 <= feature < n_features #set函數是無序且無重複的集合,獲得某個特徵的無重複元素集合 values = set(X[:,feature]) #保存預測的最高頻率的類 和 錯誤分類之和 predictors = dict() errors = [] for current_value in values: most_frequent_class, error = train_feature_value(X, y_true, feature, current_value) predictors[current_value] = most_frequent_class errors.append(error) #計算總的error與預測的結果 total_error = sum(errors) return predictors, total_error
- 在分類的方法中,我們的目的是訓練一個模型,而後用這個模型來分類未見過的數據。
- 另外,將數據集分為:訓練集 和 測試集(測試集的作用就是測試模型的準確率有多少)。
- 在scikit-learn庫里包含可以將數據分為training部分和testing部分的功能:
#測試OneR演算法#這個類庫會把數據集分為兩個部分(默認是25%的數據用於測試)from sklearn.cross_validation import train_test_split#Xd_train與Xd_test分別是訓練集和測試集,而y_train與y_test分別是兩個兩個數據集對應的類別Xd_train, Xd_test, y_train, y_test = train_test_split(X_d, y, random_state = 14)#現在為數據集的feature計算所有的predictorsall_predictors = {}errors = {}for feature_index in range(Xd_train.shape[1]): predictors, total_error = train(Xd_train, y_train, feature_index) all_predictors[feature_index] = predictors errors[feature_index] = total_error#根據One-Rule演算法來找出最好的特徵#best_feature, best_error = sorted(errors.items(), key = itemgetter(1))[0]#best_feature, best_error = sorted(errors.items(), key = itemgetter(1))[0]#根據predictors 與 best_feature來創建模型model = {feature: best_feature, predictor: all_predictors[best_feature]}#model是一個字典,根據這個模型,我們可以預測未分類樣本的類別#如果要一次性分類多個樣本,則可以用這個方法def predict(X_test, model): variable = model[feature] predictor = model[predictor] y_predicted = np.array([predictor[int(sample[variable])] for sample in X_test]) return y_predicted#對於測試集,我們可以這麼用y_predicted = predict(Xd_test, model)#最後,來計算一下精準度(accuracy)accuracy = np.mean(y_predicted == y_test) * 100print("The test accuracy is {:.1f}%".format(accuracy))
- 最後的輸出結果是:
The test accuracy is 65.8%
- 這樣子我們就實現了對這個類別的分類啦。
總結:
- 結合性分析的例子可以把數據集中不同元素之間的關聯給找出來,那分類(classification)的話,則可以把相同的數據分成不同的類別。這也是數據挖掘中很常用的一個方式,例如圖片的識別分類、判斷病人有沒有癌症等等。
- 分類的目標是根據現有的數據集來訓練一個模型,之後根據這個模型來對新的數據進行分類。例如:根據以前的郵件中垃圾郵件的情況,訓練一個垃圾郵件的模型,這樣來判斷新的有件是不是垃圾郵件。
參考資料:
- Robert Layton. (2017). Learning Data Mining with Python, (2nd ed). Birmingham, UK: Packt Publishing Ltd.
- OneR
推薦閱讀:
※「Python」用Cosine Similarity實現相關文章推薦
※用戶畫像——搜狗用戶挖掘:文本分類
※《Python數據科學實戰》案例一:個人貸款違約預測模型
※手把手教你快速構建自定義分類器
※如何構建一般時間序列問題的回歸解決方案