旋轉隨機森林算法


 

  當輸入數據中存在非線性關系的時候,基於線性回歸的模型就會失效,而基於樹的算法則不受數據中非線性關系的影響,基於樹的方法最大的一個困擾時為了避免過擬合而對樹進行剪枝的難度,對於潛在數據中的噪聲,大型的樹傾向於受影響,導致低偏差(過度擬合)或高方差(極度不擬合)。不過如果我們生成大量的樹,最終的預測值采用集成所有樹產生的輸出的平均值,就可以避免方差的問題。


1. 隨機森林:集成技術,采用大量的樹來建模,但這里我們要保證樹之間沒有相互關聯,不能選擇所有屬性,而是隨機選擇一個屬性的子集給某個樹。雖然我們再隨機森林中構建最大深度的樹,這樣它們可以很好適應自舉的樣本,得到的偏差較低,后果是引入了高方差,但通過構建大量樹,使用平均法則作為最后的預測值,可以解決方差問題。

2. 超隨機樹:比隨機森林引入更多隨機化,可以更高效地解決方差問題,它的運算復雜度也略有降低。隨機森林是自舉部分實例來給每棵樹,但超隨機樹是使用完整的訓練集數據,另外關於給定K作為給定節點隨機選擇的屬性數量,它隨機選擇割點,不考慮目標變量,不像隨機森林那樣基於基尼不純度或熵標准。這種更多隨機化帶來的架構可以更好的降低方差。而且由於划分節點不需要相關標准,因此不需要花費時間來鑒定最適合用來划分數據集的屬性

3. 旋轉森林:前兩種需要集成大量的樹才能獲得好效果,而旋轉森林可以用較小的樹來獲取相同甚至更好的效果。算法場景是投票場景屬性被划分為大小相等的K個不重疊的子集,然后結合PCA、旋轉矩陣來完成模型的構建。

下面是代碼:

  1 # -*- coding: utf-8 -*-
  2 """
  3 Created on Wed Apr 11 17:01:22 2018
  4 @author: Alvin AI
  5 """
  6 
  7 from sklearn.datasets import make_classification
  8 from sklearn.metrics import classification_report
  9 from sklearn.cross_validation import train_test_split
 10 from sklearn.decomposition import PCA
 11 from sklearn.tree import DecisionTreeClassifier
 12 import numpy as np
 13 
 14 
 15 # 加載數據
 16 def get_data():
 17     no_features = 50
 18     redundant_features = int(0.1 * no_features)
 19     informative_features = int(0.6 * no_features)
 20     repeated_features = int(0.1 * no_features)
 21     x, y = make_classification(n_samples=500, n_features=no_features, \
 22                                flip_y=0.03, n_informative=informative_features, \
 23                                n_redundant=redundant_features, \
 24                                n_repeated=repeated_features, random_state=7)
 25     return x, y
 26 
 27 
 28 # 得到隨機子集
 29 def get_random_subset(iterable, k):
 30     subsets = []
 31     iteration = 0
 32     np.random.shuffle(iterable)  # 打亂特征索引
 33     subset = 0
 34     limit = len(iterable) / k
 35     while iteration < limit:
 36         if k <= len(iterable):
 37             subset = k
 38         else:
 39             subset = len(iterable)
 40         subsets.append(iterable[-subset:])
 41         del iterable[-subset:]
 42         iteration += 1
 43     return subsets
 44 
 45 
 46 # 建立旋轉森林模型
 47 def build_rotationtree_model(x_train, y_train, d, k):
 48     models = []  # 決策樹
 49     r_matrices = []  # 與樹相關的旋轉矩陣
 50     feature_subsets = []  # 迭代中用到的特征子集
 51     for i in range(d):
 52         x, _, _, _ = train_test_split(x_train, y_train, test_size=0.3, random_state=7)
 53         # 特征的索引
 54         feature_index = range(x.shape[1])
 55         # 獲取特征的子集
 56         # 10個子集,每個子集包含5個索引
 57         random_k_subset = get_random_subset(feature_index, k)  # 10個子集
 58         feature_subsets.append(random_k_subset)  # 25個樹,每個樹10個子集
 59         R_matrix = np.zeros((x.shape[1], x.shape[1]), dtype=float)  # 旋轉矩陣
 60         for each_subset in random_k_subset:
 61             pca = PCA()
 62             x_subset = x[:, each_subset]  # 提取出子集內索引對應的x值
 63             pca.fit(x_subset)  # 主成分分析
 64             for ii in range(0, len(pca.components_)):
 65                 for jj in range(0, len(pca.components_)):
 66                     R_matrix[each_subset[ii], each_subset[jj]] = \
 67                         pca.components_[ii, jj]
 68         x_transformed = x_train.dot(R_matrix)
 69 
 70         model = DecisionTreeClassifier()
 71         model.fit(x_transformed, y_train)
 72         models.append(model)
 73         r_matrices.append(R_matrix)
 74     return models, r_matrices, feature_subsets
 75 
 76 
 77 def model_worth(models, r_matrices, x, y):
 78     predicted_ys = []
 79     for i, model in enumerate(models):
 80         x_mod = x.dot(r_matrices[i])
 81         predicted_y = model.predict(x_mod)
 82         predicted_ys.append(predicted_y)
 83 
 84         predicted_matrix = np.asmatrix(predicted_ys)  # 轉化為矩陣 25*350
 85 
 86         final_prediction = []
 87         for i in range(len(y)):
 88             pred_from_all_models = np.ravel(predicted_matrix[:, i])  # 將多維數組降為一維
 89             non_zero_pred = np.nonzero(pred_from_all_models)[0]  # nonzeros(a)返回數組a中值不為零的元素的下標
 90             is_one = len(non_zero_pred) > len(models) / 2  # 如果非0預測大於模型內樹的總數的一半則為1
 91             final_prediction.append(is_one)
 92         print classification_report(y, final_prediction)
 93     return predicted_matrix
 94 
 95 
 96 # 主函數
 97 if __name__ == "__main__":
 98     x, y = get_data()
 99     # 數據集划分
100     x_train, x_test_all, y_train, y_test_all = train_test_split(x, y, \
101                                                                 test_size=0.3, random_state=9)
102     x_dev, x_test, y_dev, y_test = train_test_split(x_test_all, y_test_all, \
103                                                     test_size=0.3, random_state=9)
104     models, r_matrices, features = build_rotationtree_model(x_train, y_train, 25, 5)  # 輸的數量25,要用的特征子集5
105     predicted_matrix1 = model_worth(models, r_matrices, x_train, y_train)
106     predicted_matrix2 = model_worth(models, r_matrices, x_dev, y_dev)

詳情參見https://blog.csdn.net/qq_33704653/article/details/80090175


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM