目次
1. 著者紹介
Ren Zhengfu、男性、西安理工大学電子情報学部、2022 年度大学院生
研究の方向性: 残響のある背景下でのターゲットのエコー検出
電子メール: [email protected]
Chen Mengdan、女性、西安理工大学電子情報学部、2022 年度大学院生、Zhang Honwei の人工知能研究グループ
研究方向: マシン ビジョンと人工知能
電子メール: [email protected]
2. デシジョンツリーアルゴリズム
2.1 決定木の原理
2.1.1 基本原則
デシジョン ツリー (Decision Tree) は、特徴とラベルを持つ一連のデータから決定ルールを要約し、これらのルールを樹状図構造で提示して分類と回帰を解決できるノンパラメトリック教師あり学習方法です。決定木アルゴリズムは理解しやすく、あらゆる種類のデータに適用でき、さまざまな問題の解決に優れた性能を発揮し、特にツリーモデルを核としたさまざまな統合アルゴリズムは、さまざまな業界や分野で広く使用されています。
たとえば、次のデータセットを見てみましょう。
私たちがやりたいのは、これらのデータに基づいて動物を分類することですが、デシジョンツリーはこれをどのように行うのか、図を描画します。
2.1.2 ノードの概念
- ルート ノード: 入力エッジはありませんが、出力エッジはあります。最初の機能固有の質問を含めます。
- 中間ノード: 入力エッジと出力エッジの両方があります。入力エッジは 1 つだけですが、多数の出力エッジが存在する可能性があります。これらは特性に関する質問です。
- リーフ ノード: 入力エッジはありますが、出力エッジはありません。各リーフ ノードはカテゴリ ラベルです。
- 子ノードと親ノード 接続されている2つのノードのうち、ルートノードに近い方が親ノード、もう一方が子ノードです。
デシジョン ツリーは、多くの属性の中からより重要な最初のいくつかの属性を選択してツリーを構築します。上図で最初の質問がある場所をルートノード、結論前の各質問を中間ノード、各結論(動物カテゴリ)をリーフノードと呼びます。
では、決定木によって解決されるべき中心的な問題は何でしょうか?
(1) データテーブルから最適なノードと最適なブランチを見つけるにはどうすればよいですか?
(2) 決定木の成長を止めて過剰適合を防ぐにはどうすればよいでしょうか?
デシジョン ツリーに関連するほとんどすべてのモデル調整方法は、これら 2 つの問題を中心に展開されます。
2.2 デシジョンツリーの構築
明らかに、任意のデータ セット上のすべての特徴を分岐に使用でき、特徴上の任意のノードを自由に組み合わせることができるため、データ セット上に多数の決定木を開発でき、その数は指数関数的なレベルに達する可能性があります。これらの木の中には必ず最良の木が存在し、この最良の木を「世界最適木」と呼びます。
デシジョン ツリー構築の基本的な手順は次のとおりです。
- 最初は、すべてのレコードがノードとみなされます。
- 各変数の各セグメンテーション方法を調べて、最適なセグメンテーション ポイントを見つけます。
- 2 つのノード N1 と N2 に分割します。
- 各ノードが十分に「純粋」になるまで、N1 と N2 に対してそれぞれステップ 2 ~ 3 を実行し続けます。
スプリットポイントの品質を評価する方法? 分割ポイントが現在のすべてのノードを 2 つのカテゴリに分割して、各クラスを非常に「純粋」にすることができる場合、つまり、同じクラスのレコードがより多く存在する場合、それは優れた分割ポイントです。
2.3 デシジョンツリーの長所と短所
デシジョンツリーアドバンテージ:
- 木を描いて見ることができるので分かりやすく説明しやすい。
- データの準備はほとんど必要ありません。他の多くのアルゴリズムでは通常、データの正規化、ダミー変数の作成、NULL 値の削除などが必要です。ただし、sklearn のデシジョン ツリー モジュールは欠損値の処理をサポートしていないことに注意してください。
- ツリーを使用するコスト (データを予測する場合など) は、ツリーのトレーニングに使用されるデータ ポイント数の対数であり、他のアルゴリズムと比較して非常に低コストです。
- 数値データとカテゴリデータの両方、回帰と分類の両方を処理できます。他の手法は、多くの場合、変数タイプが 1 つだけのデータセットの分析に特化しています。
- 複数出力の問題、つまり複数のラベルを持つ問題を処理する能力は、1 つのラベル内に複数のラベル分類がある問題と区別することに注意してください。
デシジョンツリー欠点がある:
- デシジョン ツリー学習者は、データに対して適切に一般化できない、過度に複雑なツリーを作成する可能性があります。これを過学習といいます。この問題を回避するには、枝刈り、リーフ ノードに必要なサンプルの最小数の設定、ツリーの最大深さの設定などのメカニズムが必要ですが、これらのパラメーターの統合と調整は初心者にとっては比較的分かりにくい場合があります。
- 決定木は不安定であり、データの小さな変更によりまったく異なる木が生成される可能性があるため、この問題はアンサンブル アルゴリズムによって解決する必要があります。
- 決定木の学習は、局所最適 (各ノードの最適) を最適化することで全体の最適を達成しようとする貪欲アルゴリズムに基づいていますが、このアプローチは大域最適の決定木に戻ることを保証できません。この問題は、アンサンブル アルゴリズムによっても解決できます。ランダム フォレストでは、分岐プロセス中に特徴とサンプルがランダムにサンプリングされます。
3. 実験計画
3.1 データセットの紹介
データセットのダウンロード:
タイタニックのデータセットは、 kaggle の公式 Web サイトから取得されており、アカウントを登録している場合は、公式 Web サイトから直接ダウンロードできます。
登録していない場合、または登録に失敗した場合 (よくある問題は確認コードがないことです)、中国のTianchi Web サイトからダウンロードできます。
データ セットには 3 つの CSV 形式ファイルが含まれています。train.csv は使用したいデータ (トレーニングとテストに使用できる特徴とラベルの両方)、test.csv は kaggle によって提供されるテスト セット (ラベルなし)データ セットには
変数が含まれます:
train.csv に含まれる特定の情報:
test.csv に含まれる特定の情報:
3.2 コードの実装
完全なコード:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import cross_val_score
from sklearn import tree
from sklearn.feature_extraction import DictVectorizer
from sklearn.tree import export_graphviz
data = pd.read_csv(r"train.csv")
data.info()
#删除冗余字段
data_new = data.drop(["Name","Ticket","Cabin"],axis=1)
#axis=1,轴向=1即对列进行操作
#使用年龄字段的均值填补缺失值
data_new["Age"] = data_new["Age"].fillna(data_new["Age"].mean())
#将embarked字段中含有缺失值的行删除
data_new.dropna(axis=0)
data_new.info()
#将sex、embarked字段转换为字段属性,可有两种不同的方法
labels = data_new["Embarked"].unique().tolist()
data_new["Embarked"] = data_new["Embarked"].apply(lambda x:labels.index(x))
data_new["Sex"] = (data_new["Sex"]=="male").astype("int")
#至此数据的基本处理已经结束
x = data_new.iloc[:,data_new.columns!="Survived"]
y = data_new.iloc[:,data_new.columns=="Survived"]
xtrain,xtest,ytrain,ytest = train_test_split(x,y,test_size=0.3)
for i in [xtrain,xtest,ytrain,ytest]:
i.index = range(i.shape[0])
clf = DecisionTreeClassifier(random_state=25)
clf = clf.fit(xtrain,ytrain)
score = clf.score(xtest,ytest)
print('score:',score)
clf = DecisionTreeClassifier(random_state=25)
clf = clf.fit(xtrain,ytrain)
score_mean = cross_val_score(clf,x,y,cv=10).mean()
print('score_mean:',score)
#交叉验证的结果比单个的结果更低,因此要来调整参数,首先想到的是max_depth,因此绘制超参数曲线
score_test=[]
score_train=[]
for i in range(10):
clf = DecisionTreeClassifier(random_state=25
,max_depth=i+1)
clf = clf.fit(xtrain,ytrain)
score_tr = clf.score(xtrain,ytrain)
score_te = cross_val_score(clf,x,y,cv=10).mean()
score_train.append(score_tr)
score_test.append(score_te)
print("\nbefore:",max(score_test))
#绘制超参数图像
plt.plot(range(1,11),score_train,color="red",label="train")
plt.plot(range(1,11),score_test,color="blue",label="test")
plt.legend()
plt.xticks(range(1,11))
plt.show()
#调整参数criterion,观察图像变化
score_test =[]
score_train = []
for i in range(10):
clf = DecisionTreeClassifier(random_state=25
,max_depth=i+1
,criterion="entropy")
clf = clf.fit(xtrain,ytrain)
score_tr = clf.score(xtrain,ytrain)
score_te = cross_val_score(clf,x,y,cv=10).mean()
score_train.append(score_tr)
score_test.append(score_te)
print("after:",max(score_test))
#绘制图像
plt.plot(range(1,11),score_train,color="red",label="train")
plt.plot(range(1,11),score_test,color="blue",label="test")
plt.xticks(range(1,11))
plt.legend()
plt.show()
#parameters:本质是一串参数和这串参数对应的,我们希望网格搜索来搜索的参数的取值范围
parameters = {
"splitter":("best","random")
,"min_samples_leaf":[*range(1,20,5)]
,"min_impurity_decrease":[*np.linspace(0,0.5,20)]
}
clf = DecisionTreeClassifier(random_state=25
,max_depth=3
,criterion="entropy")
clf.fit(xtrain,ytrain)
GS = GridSearchCV(clf,parameters,cv=10)
GS = GS.fit(xtrain,ytrain)
print('准确率:',GS.best_score_)
print(GS.best_params_)
3.3 実行結果
関数の画像からわかるように、ハイパーパラメータ曲線を描きます。max_ Depth > 3 の場合、トレーニング セットのスコアはテスト セットのスコアよりもはるかに高く、過剰適合現象が発生するため、 max_ Depth=3 がより適切な値です。。
パラメータを調整した後、画像観察から次のことがわかります。max_ Depth = 3 の場合、criterion="entropy" により 2 つの点が近づきます。となり、以下の図に示すようにスコアが向上しました 0.8181730