機械学習におけるランダム フォレストは、複数の決定木を含む分類器、アンサンブル アルゴリズムであり、その出力カテゴリは、個々のツリーによって出力されるカテゴリのモードによって決定されます。
ランダム フォレスト = バギング + デシジョン ツリー
袋詰め統合原理
バギング統合プロセス
1. サンプリング: すべてのサンプルの一部をサンプリングする
2. 学習: 弱い学習者をトレーニングする
3. 統合: 平等な権利投票を使用する
例: 次の円と四角形を分類します
。 実装プロセス:
1. さまざまなデータセットのサンプリング
2. 分類器のトレーニング
3. 最終結果を取得するための均等投票
4. 主な実装プロセスの概要
ランダムフォレスト構築プロセス
たとえば、5 つのツリーをトレーニングし、4 つのツリーの結果が True、1 つのツリーの結果が False の場合、最終的な投票結果は True になります。
ランダム フォレスト構築プロセスの主要な手順(トレーニング ケース (サンプル) の数を表すために N を使用し、特徴の数を表すために M を使用します):
1) 一度に 1 つのサンプルをランダムに選択し、置換を含むサンプルを N 回繰り返します (重複したサンプルが表示される可能性があります)
2) m 個の特徴 (m <<M) をランダムに選択し、デシジョン ツリーを構築します。
- 考える
-
1. なぜトレーニング セットをランダムにサンプリングするのでしょうか?
ランダム サンプリングが実行されず、各ツリーのトレーニング セットが同じである場合、最終的なトレーニングされたツリー分類結果はまったく同じになります。 -
2. 置換を伴うサンプリングが必要なのはなぜですか?
置換を伴うサンプリングがない場合、各ツリーのトレーニング サンプルは異なり、交差がありません。このように、各ツリーは「偏り」があり、完全に「一方的」になります (もちろん、これが間違っていると言う可能性もあります)。つまり、各ツリーはトレーニング後に大きく異なり、ランダム フォレストの最終的な分類は複数のツリー (弱分類器) の投票に依存します。
-
ランダムフォレストAPI
ランダムフォレスト分類にはDecisionTreeClassifierとDecisionTreeRegressorランダムフォレスト回帰がありますが、ここではDecisionTreeClassifierを紹介します。
class sklearn.ensemble.RandomForestClassifier(n_estimators=100, *, criterion='gini', max_depth=None, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features='auto', max_leaf_nodes=None, min_impurity_decrease=0.0, bootstrap=True, oob_score=False, n_jobs=None, random_state=None, verbose=0, warm_start=False, class_weight=None, ccp_alpha=0.0, max_samples=None)[source]
-
n_estimators: 整数、オプション (デフォルト = 100) フォレスト内の木の数。
-
基準: 文字列、オプション (デフォルト = "gini") 不純物の尺度。ジニ係数と情報エントロピーの 2 つのオプションがあります。
-
max_ Depth: 整数またはなし、オプション (デフォルト = なし) ツリーの最大の深さ。
-
max_features="auto"、分岐時に考慮される特徴の数を制限します。制限を超える特徴は破棄されます。デフォルト値は、特徴の総数の平方根です。
- 「自動」の場合は、
max_features=sqrt(n_features)
。 - 「sqrt」の場合は、
max_features=sqrt(n_features)
(「auto」と同じ)。 - 「log2」の場合、
max_features=log2(n_features)
。 - なしの場合は、
max_features=n_features
。
- 「自動」の場合は、
-
bootstrap: ブール値、オプション (デフォルト = True) ツリーを構築するときに置換付きサンプリングを使用するかどうか
-
min_samples_split: ノード分割の最小サンプル数
-
min_samples_leaf: リーフ ノードのサンプルの最小数
-
ハイパーパラメータ: n_estimator、max_ Depth、min_samples_split、min_samples_leaf
例
import pandas as pd
import numpy as np
from sklearn.feature_extraction import DictVectorizer
from sklearn.model_selection import train_test_split,GridSearchCV
from sklearn.ensemble import RandomForestClassifier
# 1、获取泰坦尼克号数据集
titan = pd.read_csv('titanic.csv')
#2、数据基本处理
#2.1 确定特征值,目标值
x = titan[['pclass', 'age', 'sex']]
y = titan['survived']
#2.2 缺失值处理
x['age'].fillna(x['age'].mean(), inplace=True)
#2.3 数据集划分
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=22)
#3.特征工程(字典特征抽取)
# 对于x转换成字典数据x.to_dict(orient="records")
transfer = DictVectorizer(sparse=False)
x_train = transfer.fit_transform(x_train.to_dict(orient='records'))
x_test = transfer.fit_transform(x_test.to_dict(orient='records'))
# 4.机器学习(随机森林)
estimator = RandomForestClassifier()
param_grid={
"n_estimators": [120,200,300,500,800,1200], "max_depth": [5, 8, 15, 25, 30]}
estimator=GridSearchCV(estimator,param_grid=param_grid,cv=3)
estimator.fit(x_train,y_train)
# 5.模型评估
score = estimator.score(x_test, y_test)
print("直接计算准确率:\n", score)
print("在交叉验证中验证的最好结果:\n", estimator.best_score_)
print("调整出来的最佳参数:\n", estimator.best_params_)
print("最好的参数模型:\n", estimator.best_estimator_)
print("每次交叉验证后的准确率结果:\n", estimator.cv_results_)
欠損値を埋めるランダムフォレスト回帰
sklearn.impute.SimpleImputerモジュールは、null 値に平均値、中央値、またはその他の一般的に使用される値を簡単に入力できます。次に、ボストンの住宅価格データセットに対して欠損値の充填を実行し均值
、さまざまな状況下でのフィッティング効果を検証して、最適な欠損値の充填方法を見つけます0
。随机森林回归
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
from sklearn.datasets import load_boston
from sklearn.impute import SimpleImputer # 对空值进行
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import cross_val_score
# 获取数据集 --- 共有 506*13=6578 个数据
boston = load_boston()
x_full = boston.data # 数据集
y_full = boston.target # 标签列
n_samples = x_full.shape[0] # 506行
n_features = x_full.shape[1] # 13列 --- 特征名称
欠損値の構築
1. まず欠損値の割合を決定します: 50%、つまり合計 3289 個の欠損データ
rng = np.random.RandomState(0) # 随机种子
missing_rate = 0.5 # 缺失值比例
n_missing_samples = int(np.floor(n_samples*n_features*missing_rate)) # np.floor()向下取整,返回.0格式的浮点数
n_missing_samples # 3289
2. 欠損値は 506*13 データ テーブル全体に散在しています - 3289 個の欠損値 (行と列で構成されるグリッド セルの数) がランダムな位置に生成されます。DataFrame と同様に、欠損値を生成するにはインデックス (行、列) で検索する必要があります。
missing_samples = rng.randint(0,n_samples,n_missing_samples) # 行中随机取出3289个数据
missing_features= rng.randint(0,n_features,n_missing_samples) # 列中随机取出3289个数据
# 使用上述的方式进行抽样,会使得数据远超样本量506(这里的样本量只按照行来计算)
# 我们还可以使用np.random.choice()来进行抽象,可以抽取不重复的随机数,确保数据不会集中在同一行中,某种程度上也保证了数据的分散度
missing_features
3. 欠損値の生成
x_missing = x_full.copy() # 对源数据集进行拷贝
x_missing[missing_samples,missing_features] = np.nan # 通过行、列索引随机定位生成缺失值
x_missing = pd.DataFrame(x_missing)
x_missing
欠損値の埋め込み
① 平均値の埋め込みは
、sklearn.impute の SimpleImputer クラスを使用して埋めます。平均値が入力されます。
# ①.使用均值进行填补
imp_mean = SimpleImputer(missing_values=np.nan,strategy='mean')
x_missing_mean = imp_mean.fit_transform(x_missing) # 训练fit() + 导出predict() ==> fit_transform()
x_missing_mean = pd.DataFrame(x_missing_mean)
x_missing_mean
② 0 の値を使用して塗りつぶす
Strategy='constant'、fill_value=0 は塗りつぶすために定数を使用することを意味し、fill_value は使用される定数が 0 であることを示します。
imp_0 = SimpleImputer(missing_values=np.nan,strategy='constant',fill_value=0)
x_missing_0 = imp_mean.fit_transform(x_missing) # 训练fit() + 导出predict() ==> fit_transform()
x_missing_0 = pd.DataFrame(x_missing_0)
x_missing_0
③ ランダムフォレスト回帰を使用して埋める.
どの回帰も、特徴行列から学習し、連続ラベル y を解くプロセスです. このプロセスが達成できる理由は、回帰アルゴリズムが特徴行列間に何らかの関連性があると信じているためですそしてラベル。実は、ラベルと特徴量は相互に変換することができ、例えば「面積、環境、近くの学校の数から『住宅価格』を予測する」という問題では、「面積、環境」、「」を使うことができます。データを使用して「住宅価格」を予測できます。また、「環境」、「近くの学校の数」、「住宅価格」を使用して「面積」を予測することもできます (「y=」と多少似ています) kx+b」の式)。回帰はこの考え方を使用して欠損値を埋めます。
n 個の特徴を含むデータの場合、特徴 T に欠損値がある場合、特徴 T をラベルとみなし、他の n-1 個の特徴と元のラベルで新しい特徴行列を形成します。T の場合、欠落部分はありません。これが ytrain です。データのこの部分にはラベルと特徴の両方があり、特徴だけがあってラベルがない欠落部分は、予測する必要がある部分です。
特徴 T の非欠損値 + 元のラベルに対応する他の n-1 特徴: xtrain
特徴 T の非欠損値: ytrain
特徴の欠損値 + 元のラベルに対応する他の n-1 個の特徴: xtest
特徴の欠損値: 不明、ytest を予測する必要があります
このアプローチは、特定の機能が大量に欠落しているが、他の機能は完全であるという状況に非常に適しています。
特徴 T に加えて、データ内の他の特徴にも欠損値がある場合はどうなるでしょうか?
答えは、すべてのフィーチャを走査し、欠落が最も少ないフィーチャから埋め始めることです(欠落が最も少ないフィーチャを埋めるには、必要な情報の精度が最も低いためです。フィーチャを埋めるときは、最初に他のフィーチャの欠損値を 0 に置き換えます。回帰予測が完了するたびに、予測値を元の特徴行列に入力し、次の特徴を埋め続けます。埋め込みが完了するたびに、欠損値を持つ特徴の数が増加します。 1 つずつ減らされるので、各サイクルの後、0 で埋める必要がある特徴量はますます少なくなります。最後の特徴量 (この特徴量はすべての特徴量の中で最も欠損値が多いはずです) に到達すると、 0 で埋める必要がある他の特徴を、回帰を使用して他の特徴に多くの有効な情報を埋めました. 最も欠落している特徴を埋めるために使用できます ⑴ 欠損値の数のソート
インデックス
x_missing_reg = x_missing.copy()
# 找出数据集中,缺失值从小到大排序的特征们的顺序
# np.argsort() --- 返回从小到大排序的顺序所对应的索引
sort_columns_index = np.argsort(x_missing_reg.isnull().sum()).values
sort_columns_index
⑵ インデックスを走査し、null 値を埋めます。
for i in sort_columns_index:
# 构建新的特征矩阵(没有选中填充的特征 + 原始的标签)和新标签(被选中填充的特种)
df = x_missing_reg
fillc = df.iloc[:,i] # 当前要填值的一列特征 --- 新标签
df = pd.concat([df.iloc[:,df.columns != i],pd.DataFrame(y_full)],axis=1) # 其余n-1列和完整标签
# 在新的特征矩阵中对含有缺失值的列进行空值填补
df_0 = SimpleImputer(missing_values=np.nan,strategy='constant',fill_value=0).fit_transform(df)
# 提取出测试集、训练集
ytrain = fillc[fillc.notnull()] # 被选出来要填充的特征列中非空的数据 --- 训练标签
ytest = fillc[fillc.isnull()] # 被选出来要填充的特征列中为空的数据 --- 测试标签
xtrain = df_0[ytrain.index,:] # 在新特征矩阵中,被选出来要填充的特征的非空值所对应的记录
xtest = df_0[ytest.index,:] # 在新特征矩阵中,被选出来要填充的特征空值所对应的记录
# 使用随机森林回归来填补缺失值
rfc = RandomForestRegressor(n_estimators=100).fit(xtrain,ytrain)
y_predict = rfc.predict(xtest)
# 将填补好的特征返回到我们的原始特征矩阵中
x_missing_reg.loc[x_missing_reg.iloc[:,i].isnull(),i] = y_predict
④充填結果を
評価する 次に、交差検証 (平均二乗誤差) を使用して、元のデータセット、平均で充填されたデータセット、0 値で充填されたデータセット、およびランダムフォレスト回帰で充填されたデータセットをそれぞれスコア付けします。
# 对空值填补进行评估
X = [x_full,x_missing_mean,x_missing_0,x_missing_reg]
mse = [] # 使用均方误差进行评估
for x in X:
estimator = RandomForestRegressor(n_estimators=100,random_state=0)
scores = cross_val_score(estimator,x,y_full,scoring='neg_mean_squared_error',cv=5).mean()
mse.append(scores * -1)
mse
[21.571667100368845、42.62658760318384、42.62658760318384、17.52358682764511]
評価を通じて、NULL 充填に平均値と 0 値を使用した場合の平均二乗誤差スコアは 40 以上に達し、ランダム フォレスト回帰による充填のフィッティング効果は元のデータセットよりもさらに優れていることがわかります。 , 平均二乗誤差スコアは 17.5 と低いですが、もちろん、過学習の発生を排除することはできません。
# 可视化
plt.figure(figsize=(12,8)) # 画布
colors = ['r','g','b','orange'] # 颜色
x_labels = ["x_full","x_missing_mean","x_missing_0","x_missing_reg"] # 标签
ax = plt.subplot(111) # 添加子图
for i in range(len(mse)):
ax.barh(i,mse[i],color=colors[i],alpha=0.6,align='center')
ax.set_title('Imputation Technique with Boston Data') # 设置标题
ax.set_xlim(left=np.min(mse)*0.9,right=np.max(mse)*1.1) # 设置x轴的范围
ax.set_yticks(range(len(mse)))
ax.set_xlabel("MSE") # 设置x轴标签
ax.set_yticklabels(x_labels) # 设置y轴刻度
plt.show()
パラメータを調整する
樹木モデルの場合、樹木が生い茂るほど奥行きが深くなり、枝葉が増えるほどモデルは複雑になります。したがって、ツリーモデルは当然グラフの右上隅に位置するモデルであり、ランダムフォレストもツリーモデルに基づいているため、固有の複雑性が高いモデルでもあります。ランダム フォレストのパラメーターはすべて、モデルの複雑さを軽減し、モデルを画像の左側に移動し、過剰適合を防止するという 1 つの目標に向かっています。もちろんパラメータ調整に絶対というものはありません。
それぞれの特定のパラメーターは複雑さとモデルにどのような影響を与えるのでしょうか? 精度を比較的高いレベルに修正することを目指して、学習曲線上で最適な値を順番に見つけるためにパラメーターを常に調整してきました。しかし、現在ではランダム フォレストのパラメータ調整の方向性を理解しています。つまり、複雑さを軽減するには、複雑さに大きな影響を与えるパラメータを選択し、その単調性を調査して、複雑さを最小限に抑えることができるパラメータの調整に集中することができます。単調ではないパラメータや複雑さを増すパラメータについては、状況に応じて使用しますが、ほとんどの場合、それらを回避することもできます。経験に基づいて、各パラメータがモデルに及ぼす影響の程度に基づいてランキングが作成されます。パラメータを調整するときは、この順序を参照してください。
パラメータ | 未知のデータに対するモデル評価パフォーマンスへの影響 | 影響レベル |
---|---|---|
n_estimators | 固定的な n_estimators↑ に改善しても、単一モデルの複雑さには影響しません | ⭐⭐⭐⭐ |
最大深さ | 増加と減少があります。デフォルトの最大深度は、最も複雑度が高いです。複雑度が減少する方向にパラメータ max_ Depth↓ を調整します。モデルはより単純になり、画像の左側に移動します。 | ⭐⭐⭐ |
min_samples_leaf | 増加と減少があります。デフォルトの最小制限は 1 で、これは最も複雑度が高くなります。パラメータ min_samples_leaf↑ を複雑度が減少する方向に調整します。モデルはより単純になり、画像の左側に移動します。 | ⭐⭐ |
min_samples_split | 増加と減少があります。デフォルトの最小制限は 2 で、これは最も複雑度が高くなります。パラメータ min_samples_split↑ を複雑度が減少する方向に調整します。モデルはより単純になり、画像の左側に移動します。 | ⭐⭐ |
max_features | 増加と減少があります。デフォルトの auto は、特徴の総数の平方根です。これは、中間の複雑さに位置します。パラメータ max_features↓ を、複雑さを増加または減少させる方向に調整できます。モデルはより単純です。 max_features↑、モデルはより複雑になり、画像は右に移動します。max_features は、モデルを単純にするだけでなく、モデルをより複雑にすることができる唯一のパラメーターです。したがって、このパラメータを調整するときは、パラメータ調整の方向を考慮する必要があります。 | ⭐ |
基準 | 増減がある場合がありますが、通常はジニを使用します。 | 特定の状況に応じて |