に 通信網 または グラフ は、次の形式の構造化データの一種です。 ノード 、リンクで記述されたそれらの間の関係、または エッジ 。グラフ内のノードとエッジには、数値またはカテゴリ、あるいはさらに複雑ないくつかの属性が含まれる場合があります。
今日、大量のデータがネットワークまたはグラフの形で利用可能です。たとえば、Webページとハイパーリンク、ソーシャルネットワーク、セマンティックネットワーク、生物学的ネットワーク、科学文献の引用ネットワークなどを備えたWorld WideWebです。
に 木 は特殊なタイプのグラフであり、当然、多くのタイプのデータを表すのに適しています。樹木の分析は、コンピューターとデータサイエンスの重要な分野です。この記事では、ツリーのリンク構造の分析について説明します。特に、ツリーグラフを相互に比較する方法であるツリーカーネルに焦点を当て、それらの類似点または相違点の定量化可能な測定値を取得できるようにします。これは、次のような多くの最新のアプリケーションにとって重要なプロセスです。 分類 そして データ分析 。
分類 重要なコンポーネントです 機械学習 そして データ分析 。一般的に、分類は次のいずれかになります。 監視あり または 監督されない 。教師あり分類では、クラスはすでに既知であり、分類モデルは、正しいクラスがすでに与えられているトレーニングデータから構築されます。対照的に、教師なし分類は、何も知られていないクラスを識別しようとし、類似性の測定値に基づいてデータをカテゴリにグループ化します。
教師なし分類をグラフ理論と組み合わせて、類似したツリーネットワークのグループを識別することができます。ツリーデータ構造は、複数のドメインからのオブジェクトをモデル化するために使用されます。たとえば、自然言語処理(NLP)では、解析ツリーは順序付けられたラベル付きツリーとしてモデル化されます。自動推論では、検索によって多くの問題が解決されます。検索スペースは、頂点が検索状態に関連付けられているツリーとして表され、エッジは推論ステップを表します。また、 半構造化データ HTMLやXMLドキュメントなどは、順序付けられたラベル付きツリーとしてモデル化できます。
これらのドメインは、教師なし分類手法を使用して有効に分析できます。 NLPでは、分類を使用して、一連の文を質問、コマンド、およびステートメントに自動的にグループ化できます。同様に、類似のWebサイトのグループは、分類方法をHTMLソースに適用することで識別できます。これらの各ケースで必要なのは、2つのツリーが互いにどの程度「類似」しているかを測定する方法だけです。
ほとんどの分類アルゴリズムでは、データをに変換する必要があります ベクトル化された形式 、データの値を表します 特徴 の中に フィーチャースペース 、線形代数を使用して特徴空間でデータを分析できるようにします。樹木などの構造化データまたは半構造化データでは、特徴空間が構造に関する情報を保持する必要があるため、結果のベクトルの次元(つまり、特徴空間内の特徴の数)が非常に高くなる可能性があります。
多くの分類手法が入力の次元に効果的にスケーリングできないことを考えると、これは重大な欠点となる可能性があります。言い換えると、それらの分類力は、入力の次元数の増加とともに減少します。この問題は、 次元の呪い 。
このパフォーマンスの低下の理由を理解するには、スペースを検討してください。 バツ 寸法の d 。仮定 バツ 均一に分布した点のセットが含まれています。の次元数の場合 バツ 増加すると、同じ密度を維持するために必要なポイントの数が指数関数的に増加する必要があります。言い換えると、入力の次元が多いほど、そのデータがまばらである可能性が高くなります。一般に、データ要素間の相関が弱すぎてアルゴリズムが検出できないため、スパースデータセットは適切な分類子を構築するのに十分な情報を提供しません。
上記の各フィーチャスペースには、8つのデータポイントが含まれています。 1次元空間では、左側に5つのポイント、右側に3つのポイントのグループを簡単に識別できます。これらのポイントをより多くのフィーチャ(つまり、ディメンション)に拡張すると、これらのグループを見つけるのがより困難になります。実際のアプリケーションでは、フィーチャスペースは簡単に数百の次元を持つことができます。
構造化データのベクトル化された表現は、ドメインに関する情報を効果的に使用して、管理可能な機能のセットを選択できる場合に適しています。このような情報が利用できない場合は、ベクトル空間で操作を実行せずに、構造化データを直接処理できる手法を利用することが望ましいです。
カーネルメソッド データをベクトル形式に変換する必要はありません。彼らが必要とする唯一の情報は、データセット内のアイテムの各ペアの類似性の測定です。この測定は、 カーネル 、およびそれを決定するための関数は、 カーネル関数 。カーネル法は、特徴空間で線形関係を探します。機能的には、機能空間内の2つのデータポイントのドット積を取得することと同等であり、実際、機能の設計は、カーネル関数の設計において依然として有用なステップである可能性があります。ただし、カーネル法の方法では、カーネル関数がカーネル関数である限り、内積をカーネル関数に置き換えることが可能であることが示されるため、機能空間を直接操作することは避けられます。 対称 、 正の半定値 元の空間のデータを入力として受け取ることができる関数。
したがって、カーネル関数を使用する利点は、特徴空間のサイズに依存せず、カーネル関数の複雑さに依存する計算の複雑さで巨大な特徴空間を分析できることです。つまり、カーネルメソッドは呪いを受けません。次元の呪い。
で構成される有限データセットを考えると n 例では、を生成することにより、データ内の類似性の完全な表現を取得できます。 カーネルマトリックス そのサイズは常に n×n 。このマトリックスは、個々の例のサイズとは無関係です。このプロパティは、大きな特徴空間を持つ例の小さなデータセットを分析する場合に役立ちます。
ブートストラップファイルとは
一般に、カーネル法は、データ表現の質問に対する異なる回答に基づいています。入力ポイントを特徴空間にマッピングする代わりに、データはカーネル行列のペアワイズ比較によって表されます に 、および関連するすべての分析は、カーネル行列に対して実行できます。
多くのデータマイニング方法をカーネル化できます。ツリー構造のデータインスタンスを、次のようなカーネルメソッドで分類するには サポートベクターマシン 、有効な(対称正定値)カーネル関数を定義するだけで十分です k:T×T→ R 、とも呼ばれます ツリーカーネル 。実用的に有用なツリーカーネルの設計では、ツリーのサイズ全体で多項式時間で計算可能であり、検出できる必要があります。 同型グラフ 。そのようなツリーカーネルは呼ばれます コンプリート ツリーカーネル。
それでは、木の類似性を測定するための便利なツリーカーネルをいくつか紹介しましょう。主なアイデアは、カーネルマトリックスを構築するために、データセット内のツリーの各ペアのカーネルを計算することです。カーネルマトリックスは、ツリーのセットを分類するために使用できます。
まず、文字列カーネルの簡単な紹介から始めます。これは、ツリーを文字列に変換することに基づく別のカーネル法を紹介するのに役立ちます。
定義しましょう 1つにY(s) 部分文字列の出現数として Y 文字列で s 、と |s| 文字列の長さを示します。ここで説明する文字列カーネルは、次のように定義されます。
にストリング(S1、S2)=Σs∈F1つにs(S1)1つにs(S2)にs
どこ F 両方で発生する部分文字列のセットです S1 そして S2 、およびパラメータ にs 重みパラメータとして機能します(たとえば、重要な部分文字列を強調するため)。ご覧のとおり、このカーネルは、多くの共通の部分文字列を共有している場合、文字列のペアにより高い値を与えます。
この文字列カーネルを使用して、ツリーカーネルを構築できます。このカーネルの背後にある考え方は、ツリーの構造をエンコードする体系的な方法で2つのツリーを2つの文字列に変換し、上記の文字列カーネルをそれらに適用することです。
次のように、2つのツリーを2つの文字列に変換します。
しましょう T ターゲットツリーの1つを示し、 label(ns) ノードの文字列ラベル ns に T 。 日(ns) のサブツリーの文字列表現を示します T に根ざした ns 。だからもし nルート のルートノードです T 、 日(nルート) ツリー全体の文字列表現です T 。
次に、 string(T)= tag(nルート) の文字列表現を示します T 。以下の手順をボトムアップ方式で再帰的に適用し、 文字列(T) :
次の図は、このツリーから文字列への変換の例を示しています。結果は、「[」などの開始区切り文字で始まり、対応する終了区切り文字「]」で終わる文字列です。ネストされた区切り文字の各ペアは、特定のノードをルートとするサブツリーに対応します。
これで、上記の変換を2つのツリーに適用できます。 T1 そして T2 、2つの文字列を取得するには S1 そして S2 。そこから、上記の文字列カーネルを簡単に適用できます。
間のツリーカーネル T1 そして T2 2つの文字列を介して S1 そして S2 現在、次のように指定できます。
に木(T1、T2)= Kストリング(文字列(T1)、string(T2))= Kストリング(S1、S2)=Σs∈F1つにs(S1)1つにs(S2)にs
ほとんどのアプリケーションでは、重みパラメータは次のようになります に|s| 、長さに基づいて部分文字列に重みを付ける |s| 。の典型的な重み付け方法 に|s| は:
カーネルを計算するには、すべての一般的な部分文字列を決定するだけで十分です F 、およびそれらが発生する回数をカウントする S1 そして S2 。一般的な部分文字列を見つけるこの追加の手順は、よく研究された問題であり、次の方法で実行できます。 OR(|S1|+|S2|) 、採用 接尾辞木 または 接尾辞配列 。ノードのラベルを記述するために必要な最大文字数(ビット、バイト、文字など)が一定であると仮定すると、変換された文字列の長さは次のようになります。 |S1|= O(|T1|) そして |S2|= O(|T2|) 。したがって、カーネル関数の計算の計算の複雑さは次のとおりです。 OR(|T1|+|T2|) 、線形です。
上記のツリーカーネルは、ツリーを文字列に変換するために、水平または幅優先のアプローチを使用していました。このアプローチは非常に単純ですが、この変換は、元の形式で直接ツリーを操作できないことを意味します。
このセクションでは、ツリーの垂直構造を操作するツリーカーネルを定義し、カーネルがツリーを直接操作できるようにします。
根から葉の1つへのパスのサブセクションは、 サブパス 、および サブパスセット ツリーに含まれるすべてのサブパスのセットです。
ツリーカーネルを定義したいとします。 K(T1、T2) 2本の木の間 T1 そして T2 。サブパスセットを使用することで、このツリーカーネルを次のように定義できます。
K(T1、T2)=Σp∈P1つにp(T1)1つにp(T2)に|p|
どこ 1つにp(T) サブパスの回数です p ツリーで発生します T 、 |p| サブパス内のノードの数です p 、および P のすべてのサブパスのセットです T1 そして T2 。 に|p| は前のセクションで紹介したものと同様の重量です。
ここでは、深さ優先探索を使用したこのカーネルの簡単な実装を示します。このアルゴリズムは2次時間で実行されますが、接尾辞木または接尾辞配列、または線形リズム時間を達成できるマルチキークイックソートアルゴリズムの拡張を使用して、より効率的なアルゴリズムが存在します( OR(|T1|ログ|T2|) )平均:
subpath_track = {} def generate_subpaths(path, l): if l == len(path): if tuple(path) not in subpath_track: subpath_track[tuple(path)] = 1 else: subpath_track[tuple(path)] += 1 else: index = 0 while l+index-1 この例では、重み付けパラメーターwを使用しました|s| に|p|= 1 。これにより、すべてのサブパスに等しい重みが与えられます。ただし、使用する場合は多くあります に -スペクトルの重み付け、または動的に割り当てられた重み値が適切です。
マイニングウェブサイト
まとめる前に、ツリー分類の実際のアプリケーションの1つであるWebサイトの分類について簡単に見てみましょう。多くのデータマイニングのコンテキストでは、一部のデータがどの「タイプ」のWebサイトからのものであるかを知ることは有益です。同様のサービスのWebページの構造が類似しているため、ツリーを使用してさまざまなWebサイトのページを非常に効果的に分類できることがわかりました。
どうすればいいですか? HTMLドキュメントは、ツリーに非常によく似た論理的なネスト構造を持っています。各ドキュメントには1つのルート要素が含まれ、追加の要素が内部にネストされています。 HTMLタグ内のネストされた要素は、そのタグの子ノードと論理的に同等です。

HTMLドキュメントをツリーに変換できるコードを見てみましょう。
def html_to_dom_tree(root): node_id = 1 q = deque() graph = nx.Graph() q.appendleft({'element': root, 'root_id': node_id}) while len(q): node = q.pop() if node and node['element'].name == 'body': graph.add_node(node_id, element=node['element'].name) node_id += 1 root_id = node['root_id'] labels[root_id] = node['element'].name for t in node['element'].contents: if t and t.name: graph.add_node(node_id, element=t.name) graph.add_edge(root_id, node_id) q.appendleft({'element': t, 'root_id': node_id}) node_id += 1 return graph
これにより、次のようなツリーデータ構造が生成されます。

上記の実装では、いくつかの役立つPythonライブラリを利用しています。 NetworkX 、複雑なグラフ構造を操作するため、および 美しいスープ 、Webからデータをプルし、ドキュメントを操作するため。
呼び出しhtml_to_dom_tree(soup.find('body'))
Webページの要素をルートとするNetworkXグラフオブジェクトを返します。
1,000のWebサイトホームページのセットでグループを検索するとします。各ホームページをこのようなツリーに変換することで、たとえば前のセクションで示したサブパスツリーカーネルを使用して、それぞれを比較できます。これらの類似性の測定により、たとえば、eコマースサイト、ニュースサイト、ブログ、教育サイトは、相互の類似性によって簡単に識別できることがわかりました。
結論
この記事では、ツリー構造のデータ要素を相互に比較する方法を紹介し、カーネル法をツリーに適用して、それらの類似性の定量化可能な測定値を取得する方法を示しました。カーネル法は、高次元空間で操作する場合に優れた選択肢であることが証明されています。これは、ツリー構造を操作する場合の一般的な状況です。これらの手法は、カーネルマトリックス上で動作する十分に研究された方法を使用して、ツリーの大規模なセットをさらに分析するための準備を整えます。
ツリー構造は、XMLおよびHTMLドキュメント、化合物、自然言語処理、または特定のタイプのユーザーの動作など、多くの実際の単語領域で発生します。 HTMLからツリーを構築する例で示されているように、これらの手法により、これらのドメインで意味のある分析を実行できます。