Dalam posting ini, saya ingin melengkapi artikel ini dan memberi tahu Anda bagaimana Anda dapat menggunakan Wikipedia WikiExtractor dengan lebih fleksibel, memfilter artikel berdasarkan kategori.
Semuanya dimulai dengan fakta bahwa saya membutuhkan definisi untuk berbagai istilah. Istilah dan definisinya biasanya menjadi kalimat pertama di setiap halaman Wikipedia. Mengikuti jalur paling sederhana, saya mengekstrak semua artikel dan dengan cepat mengambil semua yang saya butuhkan dengan pelanggan tetap. Masalahnya adalah bahwa definisi telah melebihi 500 MB, dan ada terlalu banyak hal yang tidak perlu, misalnya, nama entitas, kota, tahun, dll. yang tidak saya butuhkan.
Saya berasumsi dengan benar bahwa alat WikiExtractor (saya akan menggunakan versi yang berbeda, tautannya ada di bawah) memiliki semacam filter, dan ternyata itu adalah filter kategori. Kategori adalah tag untuk artikel yang memiliki struktur hierarki untuk mengatur halaman. Saya sangat senang untuk memasang kategori "Ilmu Tepat", dengan sangat naif percaya bahwa semua artikel yang terkait dengan ilmu pasti akan dimasukkan dalam daftar, tetapi keajaiban tidak terjadi - setiap halaman memiliki kumpulan kecil kategori sendiri dan tidak ada informasi di satu halaman tentang bagaimana kategori ini berhubungan. Ini berarti bahwa jika saya membutuhkan halaman tentang ilmu eksakta, saya harus menunjukkan semua kategori yang merupakan turunan dari "Ilmu eksakta".
Tidak masalah, sekarang saya akan menemukan layanan, pikir saya, yang akan dengan mudah mengirimkan semua kategori dari awal tertentu kepada saya. Sayangnya, saya hanya menemukan ini di mana Anda bisa melihat bagaimana kategori ini terkait. Upaya untuk mengulang kategori secara manual juga tidak berhasil, tetapi saya "senang" bahwa kategori ini memiliki struktur bukan pohon, seperti yang saya pikirkan selama ini, tetapi hanya grafik berarah dengan siklus. Selain itu, hierarki itu sendiri sangat mengambang - saya akan mengatakan sebelumnya bahwa dengan menetapkan titik awal "Matematika", Anda dapat dengan mudah menjangkau Alexander I. Akibatnya, saya hanya perlu memulihkan grafik ini secara lokal dan entah bagaimana mendapatkan daftar kategori yang saya minati.
, : - , , , - .
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
__
_
_
__
__
__
__
__
___
_
...
_
___
__
_____
_
_
____
_
_
_
_
__
_
_()
...
_
_
_
_
_
_
-_
_
_
_
_
_
Untuk menerapkan kategori ini untuk pemfilteran untuk bahasa Rusia, Anda perlu mengubah sesuatu di sumbernya. Saya menggunakan versi ini . Sekarang ada yang baru, mungkin perbaikan di bawah ini sudah tidak relevan lagi. Di file WikiExtractor.py, Anda perlu mengganti "Kategori" dengan "Kategori" di dua tempat. Area dengan versi yang sudah dikoreksi disajikan di bawah ini:
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))
Setelah itu Anda perlu menjalankan perintah
python WikiExtractor.py --filter_category categories --output wiki_filtered ruwiki-latest-pages-articles.xml
dimana kategori adalah file dengan kategori. Artikel yang difilter akan berada di wiki_filtered.
Itu saja. Terima kasih atas perhatian Anda.