44行のコードでNLPタスクのWikipedia、フィルタリングを解析します

この投稿では、この記事を補足し、Wikipedia WikiExtractorをより柔軟に使用して、カテゴリで記事をフィルタリングする方法を説明します。



それはすべて、さまざまな用語の定義が必要だったという事実から始まりました。用語とその定義は通常、すべてのWikipediaページの最初の文です。最も簡単な方法で、すべての記事を抽出し、常連で必要なものをすべてすばやく取得しました。問題は、定義のサイズが500 MBを超えており、名前付きエンティティ、都市、年など、不要なものが多すぎることです。私は必要ありません。



WikiExtractorツール(別のバージョンを使用します。リンクは以下にあります)に何らかのフィルターがあると正しく想定しましたが、カテゴリー別のフィルターであることが判明しました。カテゴリは、ページを整理するための階層構造を持つ記事のタグです。正確な科学に関連するすべての記事がリストに含まれると非常に素朴に信じて、「正確な科学」というカテゴリを設定できてうれしかったですが、奇跡は起こりませんでした。各ページには独自の小さなカテゴリのセットがあり、1つのページに情報はありません。これらのカテゴリがどのように関連するかについて。つまり、正確な科学に関するページが必要な場合は、「正確な科学」の子孫であるすべてのカテゴリを指定する必要があります。



まあ、それは問題ではありません、今私は、与えられたスタートから私にすべてのカテゴリーを簡単に出荷するサービスを見つけるだろうと思いました。残念ながら、これらのカテゴリがどのように関連しているかを確認できる場所でのみこれを見つけました。カテゴリを手動で繰り返す試みも失敗しましたが、これらのカテゴリが、これまでずっと考えていたようにツリーではなく、サイクルを含む有向グラフの構造を持っていることを「うれしく思いました」。さらに、階層自体は非常に浮かんでいます。開始点「数学」を設定することで、アレクサンダーIに簡単に到達できることを事前に述べておきます。その結果、このグラフをローカルに復元し、どういうわけか興味のあるカテゴリのリストを取得する必要がありました。



, : - , , , - .



Ubuntu 16.04, , , 18.04 .





, ,



  • ruwiki-latest-pages-articles.xml.bz2
  • ruwiki-latest-categorylinks.sql.gz
  • ruwiki-latest-category.sql.gz
  • ruwiki-latest-page.sql.gz


categorylinks , , [[Category:Title]] , . cl_from, id , cl_to, . , id , page () page_id page_title. , . , , , , , . category([](category table)) cat_title. pages-articles.xml .



mysql. ,



sudo apt-get install mysql-server  mysql-client


, mysql , .



$ mysql -u username -p
mysql> create database category;
mysql> create database categorylinks;
mysql> create database page;


, . .



$  mysql -u username -p category < ruwiki-latest-category.sql
$  mysql -u username -p categorylinks < ruwiki-latest-categorylinks.sql
$  mysql -u username -p page < ruwiki-latest-page.sql




, csv.



mysql> select page_title, cl_to from categorylinks.categorylinks join page.page
on cl_from = page_id  where page_title in (select cat_title from category) INTO outfile '/var/lib/mysql-files/category.csv' FIELDS terminated by ';' enclosed by '"' lines terminated by '\n';


. .





, , — , . , , , , 1,6 1,1. .



import pandas as pd
import networkx as nx
from tqdm.auto import tqdm, trange

#Filtering
df = pd.read_csv("category.csv", sep=";", error_bad_lines=False)
df = df.dropna()
df_filtered = df[df.parant.str.contains("[--]+:") != True] 
df_filtered = df_filtered[df_filtered.parant.str.contains(",_") != True]
df_filtered = df_filtered[df_filtered.parant.str.contains("__") != True] 
df_filtered = df_filtered[df_filtered.parant.str.contains("_") != True] 
df_filtered = df_filtered[df_filtered.parant.str.contains(",_") != True] 
df_filtered = df_filtered[df_filtered.parant.str.contains("__") != True]
df_filtered = df_filtered[df_filtered.parant.str.contains("__") != True]
df_filtered = df_filtered[df_filtered.parant.str.contains("_") != True] 
df_filtered = df_filtered[df_filtered.parant.str.contains("__") != True]
df_filtered = df_filtered[df_filtered.parant.str.contains("") != True] 

# Graph recovering
G = nx.DiGraph()
c = 0
for i, gr in tqdm(df_filtered.groupby('child')):

    vertex = set()
    edges = []
    for i, r in gr.iterrows():
        G.add_node(r.parant, color="white")
        G.add_node(r.child, color="white")
        G.add_edge(r.parant, r.child)




, , , , .



counter = 0
nodes = []

def dfs(G, node, max_depth):
    global nodes, counter
    G.nodes[node]['color'] = 'gray'
    nodes.append(node)
    counter += 1
    if counter == max_depth:
        counter -= 1
        return
    for v in G.successors(node):
        if G.nodes[v]['color'] == 'white':
            dfs(G, v, max_depth)
        elif G.nodes[v]['color'] == 'gray':
            continue
    counter -= 1


, nodes . " " 5 . 2500 . , , , , - , , , — , . , , .



, .



_

CAM
__
_
_
__
__


__
__
__
___
_

...

_
___
__
_____
_
_
____
_
_
_
_
__
_
_()

...


_

_
_

_
_
_
-_

_
_
_
_
_


ただし、これらのカテゴリをロシア語のフィルタリングに適用するには、ソースを微調整する必要があります。このバージョンを使用しました今、何か新しいことがあります。おそらく、以下の修正はもはや関係ありません。WikiExtractor.pyファイルでは、2か所で「Category」を「Category」に置き換える必要があります。すでに修正されたバージョンの領域を以下に示します。




tagRE = re.compile(r'(.*?)<(/?\w+)[^>]*?>(?:([^<]*)(<.*?>)?)?')
#                    1     2               3      4
keyRE = re.compile(r'key="(\d*)"')
catRE = re.compile(r'\[\[:([^\|]+).*\]\].*')  # capture the category name [[Category:Category name|Sortkey]]"

def load_templates(file, output_file=None):
...


if inText:
    page.append(line)
    # extract categories
    if line.lstrip().startswith('[[:'):
        mCat = catRE.search(line)
        if mCat:
            catSet.add(mCat.group(1))


その後、コマンドを実行する必要があります



python WikiExtractor.py --filter_category categories --output wiki_filtered ruwiki-latest-pages-articles.xml


ここで、categoriesはcategoriesを含むファイルです。フィルタリングされた記事はwiki_filteredにあります。

それで全部です。清聴ありがとうございました。




All Articles