ํŠœํ† ๋ฆฌ์–ผ: ๋„ค์ž„๋“œ ์—”ํ‹ฐํ‹ฐ ์ธ์‹(NER)์„ ์œ„ํ•ด BERT๋ฅผ ๋ฏธ์„ธ ์กฐ์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•

๋ชฉ์ฐจ

ํŠœํ† ๋ฆฌ์–ผ: NER์šฉ BERT๋ฅผ ๋ฏธ์„ธ ์กฐ์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•

    Skim AI์˜ ๋จธ์‹ ๋Ÿฌ๋‹ ์—ฐ๊ตฌ์› ํฌ๋ฆฌ์Šค ํŠธ๋ž€์ด ์ฒ˜์Œ ๊ฒŒ์‹œํ–ˆ์Šต๋‹ˆ๋‹ค.

Google Colab์—์„œ ์‹คํ–‰

์†Œ๊ฐœ

์ด ๋ฌธ์„œ์—์„œ๋Š” ๋„ค์ž„๋“œ ์—”ํ‹ฐํ‹ฐ ์ธ์‹(NER)์„ ์œ„ํ•ด BERT๋ฅผ ๋ฏธ์„ธ ์กฐ์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ํŠนํžˆ, NER์„ ์œ„ํ•ด BERT ๋ณ€ํ˜•์ธ SpanBERTa๋ฅผ ํ›ˆ๋ จํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์–‘ํ•œ ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ์œ„ํ•œ ์ŠคํŽ˜์ธ์–ด์šฉ ์‚ฌ์šฉ์ž ์ง€์ • BERT ์–ธ์–ด ๋ชจ๋ธ ํ›ˆ๋ จ์— ๋Œ€ํ•œ ์‹œ๋ฆฌ์ฆˆ 3๋ถ€ ์ค‘ 2๋ถ€์ž…๋‹ˆ๋‹ค:

์ด์ „ ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ์—์„œ ์ €ํฌ ํŒ€์ด ์ŠคํŽ˜์ธ์–ด์šฉ ํŠธ๋žœ์Šคํฌ๋จธ ์–ธ์–ด ๋ชจ๋ธ์ธ SpanBERTa๋ฅผ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋Œ€๊ทœ๋ชจ ๋ง๋ญ‰์น˜์— ๋Œ€ํ•ด ์‚ฌ์ „ ํ•™์Šต์‹œํ‚จ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์„ค๋ช…ํ•œ ๋ฐ” ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ชจ๋ธ์€ ๋ฌธ๋งฅ์— ๋”ฐ๋ผ ์‹œํ€€์Šค์—์„œ ๋งˆ์Šคํ‚น๋œ ๋‹จ์–ด๋ฅผ ์ •ํ™•ํ•˜๊ฒŒ ์˜ˆ์ธกํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์œผ๋กœ ๋‚˜ํƒ€๋‚ฌ์Šต๋‹ˆ๋‹ค. ์ด ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ์—์„œ๋Š” ํŠธ๋žœ์Šคํฌ๋จธ ๋ชจ๋ธ์˜ ์„ฑ๋Šฅ์„ ์‹ค์ œ๋กœ ํ™œ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋ช…๋ช…๋œ ์—”ํ‹ฐํ‹ฐ ์ธ์‹ ์ž‘์—…์„ ์œ„ํ•ด SpanBERTa๋ฅผ ๋ฏธ์„ธ ์กฐ์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์˜ ์ •์˜์— ๋”ฐ๋ฅด๋ฉด Wikipedia์—”ํ‹ฐํ‹ฐ ์‹๋ณ„, ์—”ํ‹ฐํ‹ฐ ์ฒญํ‚น, ์—”ํ‹ฐํ‹ฐ ์ถ”์ถœ์ด๋ผ๊ณ ๋„ ํ•˜๋Š” ๋ช…๋ช…๋œ ์—”ํ‹ฐํ‹ฐ ์ธ์‹(NER)์€ ๋น„์ •ํ˜• ํ…์ŠคํŠธ์— ์–ธ๊ธ‰๋œ ๋ช…๋ช…๋œ ์—”ํ‹ฐํ‹ฐ๋ฅผ ์ฐพ์•„์„œ ์‚ฌ๋žŒ ์ด๋ฆ„, ์กฐ์ง, ์œ„์น˜, ์˜๋ฃŒ ์ฝ”๋“œ, ์‹œ๊ฐ„ ํ‘œํ˜„, ์ˆ˜๋Ÿ‰, ํ™”ํ ๊ฐ€์น˜, ๋ฐฑ๋ถ„์œจ ๋“ฑ๊ณผ ๊ฐ™์€ ์‚ฌ์ „ ์ •์˜๋œ ์นดํ…Œ๊ณ ๋ฆฌ๋กœ ๋ถ„๋ฅ˜ํ•˜๋Š” ์ •๋ณด ์ถ”์ถœ์˜ ํ•˜์œ„ ์ž‘์—…์ž…๋‹ˆ๋‹ค.

์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. run_ner.py ํ—ˆ๊น… ํŽ˜์ด์Šค์™€ CoNLL-2002 ๋ฐ์ดํ„ฐ ์„ธํŠธ ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ SpanBERTa๋ฅผ ๋ฏธ์„ธ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์„ค์ •

๋‹ค์šด๋กœ๋“œ ํŠธ๋žœ์Šคํฌ๋จธ ๋ฅผ ํด๋ฆญํ•˜๊ณ  ํ•„์š”ํ•œ ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

%pture
!.git clone https://github.com/huggingface/transformers
 ํŠธ๋žœ์Šคํฌ๋จธ
!.pip ์„ค์น˜ .
!.pip ์„ค์น˜ -r ./examples/requirements.txt
 ..

๋ฐ์ดํ„ฐ

1. ๋ฐ์ดํ„ฐ ์„ธํŠธ ๋‹ค์šด๋กœ๋“œ

์•„๋ž˜ ๋ช…๋ น์€ ๋ฐ์ดํ„ฐ ์„ธํŠธ๋ฅผ ๋‹ค์šด๋กœ๋“œํ•˜๊ณ  ์••์ถ•์„ ํ•ด์ œํ•ฉ๋‹ˆ๋‹ค. ํŒŒ์ผ์—๋Š” ๋‹ค์Œ ์„ธ ๊ฐ€์ง€ ๋ถ€๋ถ„์— ๋Œ€ํ•œ ํ›ˆ๋ จ ๋ฐ ํ…Œ์ŠคํŠธ ๋ฐ์ดํ„ฐ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. CoNLL-2002 ๊ณต์œ  ์ž‘์—…:

  • esp.testa: ๊ฐœ๋ฐœ ๋‹จ๊ณ„๋ฅผ ์œ„ํ•œ ์ŠคํŽ˜์ธ์–ด ํ…Œ์ŠคํŠธ ๋ฐ์ดํ„ฐ
  • esp.testb: ์ŠคํŽ˜์ธ์–ด ํ…Œ์ŠคํŠธ ๋ฐ์ดํ„ฐ
  • esp.train: ์ŠคํŽ˜์ธ ์—ด์ฐจ ๋ฐ์ดํ„ฐ
%pture
!wget -O 'conll2002.zip' 'https://drive.google.com/uc?export=download&id=1Wrl1b39ZXgKqCeAFNM9EoXtA1kzwNhCe'
!.unzip 'conll2002.zip'

๊ฐ ๋ฐ์ดํ„ฐ ์ง‘ํ•ฉ์˜ ํฌ๊ธฐ์ž…๋‹ˆ๋‹ค:

!wc -l conll2002/esp.train
!wc -l conll2002/esp.testa
!wc -l conll2002/esp.testb
273038 conll2002/esp.train
54838 conll2002/esp.testa
53050 conll2002/esp.testb

๋ชจ๋“  ๋ฐ์ดํ„ฐ ํŒŒ์ผ์—๋Š” ๋‹จ์–ด, ๊ด€๋ จ ํ’ˆ์‚ฌ ํƒœ๊ทธ, IOB2 ํ˜•์‹์˜ ๋ช…๋ช…๋œ ์—”ํ‹ฐํ‹ฐ ํƒœ๊ทธ์˜ ์„ธ ๊ฐ€์ง€ ์—ด์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌธ์žฅ ๋‚˜๋ˆ„๊ธฐ๋Š” ๋นˆ ์ค„๋กœ ์ธ์ฝ”๋”ฉ๋ฉ๋‹ˆ๋‹ค.

!head -n20 conll2002/esp.train
๋ฉœ๋ฒ„๋ฅธ NP B-LOC
( Fpa O
ํ˜ธ์ฃผ NP B-LOC
) Fpt O
, Fc O
25 Z O
may NC O
( Fpa O
EFE NC B-ORG
) Fpt O
. Fp O

- Fg O

El DA O
Abogado NC B-PER
์ผ๋ฐ˜ AQ I-PER
๋ธ SP I-PER
NC ์ƒํƒœ I-PER
, Fc O

ํ›ˆ๋ จ, ๊ฐœ๋ฐœ ๋ฐ ํ…Œ์ŠคํŠธ ๋ฐ์ดํ„ฐ ์„ธํŠธ์˜ ๊ฒฝ์šฐ ๋‹จ์–ด ์—ด๊ณผ ๋ช…๋ช…๋œ ์—”ํ‹ฐํ‹ฐ ํƒœ๊ทธ ์—ด๋งŒ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.

!cat conll2002/esp.train | cut -d " " -f 1,3 > train_temp.txt
!cat conll2002/esp.testa | cut -d " " -f 1,3 > dev_temp.txt
!cat conll2002/esp.testb | cut -d " " -f 1,3 > test_temp.txt

2. ์ „์ฒ˜๋ฆฌ

์ถ”๊ฐ€ ์ „์ฒ˜๋ฆฌ ๋‹จ๊ณ„์™€ ๋ชจ๋ธ ํ•™์Šต์— ํ•„์š”ํ•œ ๋ช‡ ๊ฐ€์ง€ ๋ณ€์ˆ˜๋ฅผ ์ •์˜ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค:

MAX_LENGTH = 120 #@param {type: "์ •์ˆ˜"}
MODEL = "chriskhanhtran/spanberta" #@param ["chriskhanhtran/spanberta", "bert-base-multilingual-cased"]

์•„๋ž˜ ์Šคํฌ๋ฆฝํŠธ๋Š” ๋‹ค์Œ๋ณด๋‹ค ๊ธด ๋ฌธ์žฅ์„ ๋ถ„ํ• ํ•ฉ๋‹ˆ๋‹ค. MAX_LENGTH (ํ† ํฐ ๊ธฐ์ค€)์„ ์ž‘์€ ํ† ํฐ์œผ๋กœ ์ค„์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ํ† ํฐํ™”ํ•  ๋•Œ ๊ธด ๋ฌธ์žฅ์ด ์ž˜๋ ค์„œ ํ•™์Šต ๋ฐ์ดํ„ฐ๊ฐ€ ์†์‹ค๋˜๊ณ  ํ…Œ์ŠคํŠธ ์„ธํŠธ์˜ ์ผ๋ถ€ ํ† ํฐ์ด ์˜ˆ์ธก๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

%pture
!.wget "https://raw.githubusercontent.com/stefan-it/fine-tuned-berts-seq/master/scripts/preprocess.py"
!python3 preprocess.py train_temp.txt $MODEL $MAX_LENGTH > train.txt
!python3 preprocess.py dev_temp.txt $MODEL $MAX_LENGTH > dev.txt
!python3 preprocess.py test_temp.txt $MODEL $MAX_LENGTH > test.txt
2020-04-22 23:02:05.747294: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] ๋™์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ libcudart.so.10.1์„ ์„ฑ๊ณต์ ์œผ๋กœ ์—ด์—ˆ์Šต๋‹ˆ๋‹ค.
๋‹ค์šด๋กœ๋“œ ์ค‘์ž…๋‹ˆ๋‹ค: 100% 1.03k/1.03k [00:00<00:00, 704kB/s]
๋‹ค์šด๋กœ๋“œ ์ค‘์ž…๋‹ˆ๋‹ค: 100% 954k/954k [00:00<00:00, 1.89MB/s]
๋‹ค์šด๋กœ๋“œ ์ค‘: 100% 512k/512k [00:00<00:00, 1.19MB/s]
๋‹ค์šด๋กœ๋“œ ์ค‘: 100% 16.0/16.0 [00:00<00:00, 12.6kB/s]
2020-04-22 23:02:23.409488: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] ๋™์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ libcudart.so.10.1์„ ์„ฑ๊ณต์ ์œผ๋กœ ์—ด์—ˆ์Šต๋‹ˆ๋‹ค.
2020-04-22 23:02:31.168967: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] ๋™์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ libcudart.so.10.1์„ ์„ฑ๊ณต์ ์œผ๋กœ ์—ด์—ˆ์Šต๋‹ˆ๋‹ค.

3. ๋ผ๋ฒจ

CoNLL-2002/2003 ๋ฐ์ดํ„ฐ ์„ธํŠธ์—๋Š” 9๊ฐ€์ง€ ํด๋ž˜์Šค์˜ NER ํƒœ๊ทธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค:

  • O, ๋ช…๋ช…๋œ ์—”ํ‹ฐํ‹ฐ ์™ธ๋ถ€
  • B-MIS, ๋‹ค๋ฅธ ๊ธฐํƒ€ ๋ฒ•์ธ ๋ฐ”๋กœ ๋’ค์˜ ๊ธฐํƒ€ ๋ฒ•์ธ ์‹œ์ž‘
  • I-MIS, ๊ธฐํƒ€ ๋ฒ•์ธ
  • B-PER, ๋‹ค๋ฅธ ์‚ฌ๋žŒ ์ด๋ฆ„ ๋ฐ”๋กœ ๋’ค์˜ ์ด๋ฆ„ ์‹œ์ž‘ ๋ถ€๋ถ„
  • I-PER, ๊ฐœ์ธ ์ด๋ฆ„
  • B-ORG, ๋‹ค๋ฅธ ์กฐ์ง์˜ ๋ฐ”๋กœ ๋’ค์—์„œ ์‹œ์ž‘๋˜๋Š” ์กฐ์ง์˜ ์‹œ์ž‘
  • I-ORG, ์กฐ์ง
  • B-LOC, ๋‹ค๋ฅธ ์œ„์น˜ ๋ฐ”๋กœ ๋’ค์— ์žˆ๋Š” ์œ„์น˜์˜ ์‹œ์ž‘์ 
  • I-LOC, ์œ„์น˜

๋ฐ์ดํ„ฐ ์ง‘ํ•ฉ์— CoNLL-2002/2003 ๋ฐ์ดํ„ฐ ์ง‘ํ•ฉ๊ณผ ๋‹ค๋ฅธ ๋ ˆ์ด๋ธ”์ด ์žˆ๊ฑฐ๋‚˜ ๋” ๋งŽ์€ ๋ ˆ์ด๋ธ”์ด ์žˆ๋Š” ๊ฒฝ์šฐ ์•„๋ž˜ ์ค„์„ ์‹คํ–‰ํ•˜์—ฌ ๋ฐ์ดํ„ฐ์—์„œ ๊ณ ์œ  ๋ ˆ์ด๋ธ”์„ ๊ฐ€์ ธ์™€์„œ ๋‹ค์Œ ์œ„์น˜์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. labels.txt. ์ด ํŒŒ์ผ์€ ๋ชจ๋ธ ๋ฏธ์„ธ ์กฐ์ •์„ ์‹œ์ž‘ํ•  ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

!cat train.txt dev.txt test.txt | cut -d " " -f 2 | grep -v "^$"| sort | uniq > labels.txt

๋ฏธ์„ธ ์กฐ์ • ๋ชจ๋ธ

๋‹ค์Œ์€ ๋‹ค์Œ์˜ ์˜ˆ์ œ ์Šคํฌ๋ฆฝํŠธ์ž…๋‹ˆ๋‹ค. ํŠธ๋žœ์Šคํฌ๋จธ์˜ ์ €์žฅ์†Œ์—์„œ NER์šฉ ๋ชจ๋ธ์„ ๋ฏธ์„ธ ์กฐ์ •ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. 2020๋…„ 4์›” 21์ผ ์ดํ›„ Hugging Face๋Š” ์˜ˆ์ œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜์—ฌ ์ƒˆ๋กœ์šด ํŠธ๋ ˆ์ด๋„ˆ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”. ํ–ฅํ›„ ์ถฉ๋Œ์„ ๋ฐฉ์ง€ํ•˜๋ ค๋ฉด ์ด๋Ÿฌํ•œ ์—…๋ฐ์ดํŠธ ์ด์ „ ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜์„ธ์š”.

%pture
!wget "https://raw.githubusercontent.com/chriskhanhtran/spanish-bert/master/ner/run_ner.py"
!wget "https://raw.githubusercontent.com/chriskhanhtran/spanish-bert/master/ner/utils_ner.py"

์ด์ œ ์ด์ „ ํ•™์Šต์„ ํ•  ์ฐจ๋ก€์ž…๋‹ˆ๋‹ค. ๋‚ด ์ด์ „ ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ์ €๋Š” ๋Œ€๊ทœ๋ชจ ์ŠคํŽ˜์ธ์–ด ๋ง๋ญ‰์น˜์— ๋Œ€ํ•ด RoBERTa ์–ธ์–ด ๋ชจ๋ธ์„ ์‚ฌ์ „ ํ•™์Šต์‹œ์ผœ ๋ฌธ๋งฅ์— ๋”ฐ๋ผ ๋งˆ์Šคํฌ๋œ ๋‹จ์–ด๋ฅผ ์˜ˆ์ธกํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋ชจ๋ธ์€ ์–ธ์–ด์˜ ๊ณ ์œ ํ•œ ์†์„ฑ์„ ํ•™์Šตํ–ˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์ „ ํ•™์Šต๋œ ๋ชจ๋ธ์„ ํ—ˆ๊น… ํŽ˜์ด์Šค์˜ ์„œ๋ฒ„์— ์—…๋กœ๋“œํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ๋ชจ๋ธ์„ ๋กœ๋“œํ•˜๊ณ  NER ์ž‘์—…์— ๋งž๊ฒŒ ๋ฏธ์„ธ ์กฐ์ •์„ ์‹œ์ž‘ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์•„๋ž˜๋Š” ํŠธ๋ ˆ์ด๋‹ ํ•˜์ดํผํŒŒ๋ผ๋ฏธํ„ฐ์ž…๋‹ˆ๋‹ค.

MAX_LENGTH = 128 #@param {type: "์ •์ˆ˜"}
MODEL = "chriskhanhtran/spanberta" #@param ["chriskhanhtran/spanberta", "bert-base-multilingual-cased"]
OUTPUT_DIR = "spanberta-ner" #@param ["spanberta-ner", "bert-base-ml-ner"]
BATCH_SIZE = 32 #@param {type: "์ •์ˆ˜"}
NUM_EPOCHS = 3 #@param {type: "์ •์ˆ˜"}
SAVE_STEPS = 100 #@param {type: "integer"}
LOGGING_STEPS = 100 #@param {type: "์ •์ˆ˜"}
SEED = 42 #@param {type: "integer"}

๊ต์œก์„ ์‹œ์ž‘ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

!python3 run_ner.py
  --data_dir ./
  --model_type bert
  --labels ./labels.txt
  --model_name_or_path $MODEL
  --output_dir $OUTPUT_DIR
  --max_seq_length $MAX_LENGTH
  --num_train_epochs $NUM_EPOCHS
  --per_gpu_train_batch_size $BATCH_SIZE
  --save_steps $SAVE_STEPS
  --logging_steps $LOGGING_STEPS
  --seed $SEED
  --do_train
  --do_eval
  --do_predict
  --overwrite_output_dir

๊ฐœ๋ฐœ ์„ธํŠธ์—์„œ์˜ ์„ฑ๋Šฅ:

04/21/2020 02:24:31 - INFO - __main__ - ***** ํ‰๊ฐ€ ๊ฒฐ๊ณผ *****
04/21/2020 02:24:31 - INFO - __main__ - f1 = 0.831027443864822
04/21/2020 02:24:31 - INFO - __main__ - ์†์‹ค = 0.1004064822183894
04/21/2020 02:24:31 - INFO - __main__ - ์ •๋ฐ€๋„ = 0.8207885304659498
04/21/2020 02:24:31 - INFO - __main__ - recall = 0.8415250344510795

ํ…Œ์ŠคํŠธ ์„ธํŠธ์—์„œ์˜ ์„ฑ๋Šฅ:

04/21/2020 02:24:48 - INFO - __main__ - ***** ํ‰๊ฐ€ ๊ฒฐ๊ณผ *****
04/21/2020 02:24:48 - INFO - __main__ - f1 = 0.8559533721898419
04/21/2020 02:24:48 - INFO - __main__ - ์†์‹ค = 0.06848683688204177
04/21/2020 02:24:48 - INFO - __main__ - ์ •๋ฐ€๋„ = 0.845858475041141
04/21/2020 02:24:48 - INFO - __main__ - recall = 0.8662921348314607

๋‹ค์Œ์€ ๋ฏธ์„ธ ์กฐ์ •์˜ ํ…์„œ๋ณด๋“œ์ž…๋‹ˆ๋‹ค. ์ŠคํŒฌ๋ฒ„ํƒ€ ๋ฐ bert-๊ธฐ๋ฐ˜-๋‹ค๊ตญ์–ด-์ผ€์ด์Šค ๋ฅผ 5๊ฐœ์˜ ์—ํฌํฌ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. 3๊ฐœ์˜ ์—ํฌํฌ ์ดํ›„์—๋Š” ๋ชจ๋ธ์ด ํ•™์Šต ๋ฐ์ดํ„ฐ์— ๊ณผ๋„ํ•˜๊ฒŒ ์ ํ•ฉํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ถ„๋ฅ˜ ๋ณด๊ณ ์„œ

๋ชจ๋ธ์ด ์‹ค์ œ๋กœ ์–ผ๋งˆ๋‚˜ ์ž˜ ์ž‘๋™ํ•˜๋Š”์ง€ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด ์˜ˆ์ธก์„ ๋กœ๋“œํ•˜๊ณ  ๋ถ„๋ฅ˜ ๋ณด๊ณ ์„œ๋ฅผ ์‚ดํŽด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

def read_examples_from_file(file_path):
    """CoNLL-2002/2003 ๋ฐ์ดํ„ฐ ํŒŒ์ผ์—์„œ ๋‹จ์–ด์™€ ๋ ˆ์ด๋ธ”์„ ์ฝ์Šต๋‹ˆ๋‹ค.

    Args:
      file_path (str): NER ๋ฐ์ดํ„ฐ ํŒŒ์ผ์˜ ๊ฒฝ๋กœ.

    ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค:
      ์˜ˆ์‹œ(๋”•์…”๋„ˆ๋ฆฌ): ๋‘ ๊ฐœ์˜ ํ‚ค๊ฐ€ ์žˆ๋Š” ๋”•์…”๋„ˆ๋ฆฌ: words (๋ชฉ๋ก ๋ชฉ๋ก)
        ๊ฐ ์‹œํ€€์Šค์—์„œ ๋‹จ์–ด๋ฅผ ๋“ค๊ณ  ๋ ˆ์ด๋ธ” (๋ชฉ๋ก ๋ชฉ๋ก) ๋ณด์œ 
        ํ•ด๋‹น ๋ ˆ์ด๋ธ”.
    """
    ์—ด๋‹ค(ํŒŒ์ผ_๊ฒฝ๋กœ, ์ธ์ฝ”๋”ฉ="utf-8")๋ฅผ f๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค:
        examples = {"words": [], "labels": []}
        words = []
        labels = []
        f์˜ ์ค„์— ๋Œ€ํ•ด
            if line.startswith("-DOCSTART-") ๋˜๋Š” line == "" ๋˜๋Š” line == "\n":
                if words:
                    examples["words"].append(words)
                    examples["labels"].append(labels)
                    words = []
                    labels = []
            else:
                splits = line.split(" ")
                words.append(splits[0])
                len(splits) > 1์ด๋ฉด
                    labels.append(splits[-1].replace("\n", ""))
                else:
                    # ์˜ˆ์ œ์—์„œ๋Š” mode = "test"์— ๋Œ€ํ•œ ๋ ˆ์ด๋ธ”์ด ์—†์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
                    labels.append("O")
    ๋ฐ˜ํ™˜ ์˜ˆ์ œ

์›์‹œ ํ…์ŠคํŠธ ํŒŒ์ผ์—์„œ ๋ฐ์ดํ„ฐ์™€ ๋ ˆ์ด๋ธ”์„ ์ฝ์Šต๋‹ˆ๋‹ค:

y_true = read_examples_from_file("test.txt")["labels"]
y_pred = read_examples_from_file("spanberta-ner/test_predictions.txt")["labels"]

๋ถ„๋ฅ˜ ๋ณด๊ณ ์„œ๋ฅผ ์ธ์‡„ํ•ฉ๋‹ˆ๋‹ค:

seqeval.metrics์—์„œ classification_report๋ฅผ classification_report_seqeval๋กœ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

print(classification_report_seqeval(y_true, y_pred))
           ์ •๋ฐ€ ๋ฆฌ์ฝœ F1 ์ ์ˆ˜ ์ง€์›

      LOC 0.87 0.84 0.85 1084
      ORG 0.82 0.87 0.85 1401
     ๊ธฐํƒ€ 0.63 0.66 0.65 340
      PER 0.94 0.96 0.95 735

๋งˆ์ดํฌ๋กœ ํ‰๊ท  0.84 0.86 0.85 3560
๋งคํฌ๋กœ ํ‰๊ท  0.84 0.86 0.85 3560

์ด ๋ณด๊ณ ์„œ์— ํ‘œ์‹œ๋˜๋Š” ๋ฉ”ํŠธ๋ฆญ์€ ์—”ํ‹ฐํ‹ฐ์˜ ๋ชจ๋“  ๋‹จ์–ด๊ฐ€ ์ •ํ™•ํ•˜๊ฒŒ ์˜ˆ์ธก๋˜์–ด์•ผ ํ•˜๋‚˜์˜ ์ •ํ™•ํ•œ ์˜ˆ์ธก์œผ๋กœ ๊ณ„์‚ฐ๋˜๋Š” NER ๋ฐ POS ํƒœ๊น…๊ณผ ๊ฐ™์€ NLP ์ž‘์—…์„ ์œ„ํ•ด ํŠน๋ณ„ํžˆ ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด ๋ถ„๋ฅ˜ ๋ณด๊ณ ์„œ์˜ ๋ฉ”ํŠธ๋ฆญ์€ ๋‹ค์Œ๋ณด๋‹ค ํ›จ์”ฌ ๋‚ฎ์Šต๋‹ˆ๋‹ค. SCIKIT-Learn์˜ ๋ถ„๋ฅ˜ ๋ณด๊ณ ์„œ.

numpy๋ฅผ np๋กœ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
sklearn.metrics์—์„œ classification_report ๊ฐ€์ ธ์˜ค๊ธฐ

print(classification_report(np.concatenate(y_true), np.concatenate(y_pred)))
              ์ •๋ฐ€ ๋ฆฌ์ฝœ F1 ์ ์ˆ˜ ์ง€์›

       B-LOC 0.88 0.85 0.86 1084
      B-MISC 0.73 0.73 0.73 339
       B-OG 0.87 0.91 0.89 1400
       B-PER 0.95 0.96 0.95 735
       I-LOC 0.82 0.81 0.81 325
      I-MISC 0.85 0.76 0.80 557
       I-OG 0.89 0.87 0.88 1104
       I-PER 0.98 0.98 0.98 634
           O 1.00 1.00 1.00 45355

    ์ •ํ™•๋„ 0.98 51533
   ๋งคํฌ๋กœ ํ‰๊ท  0.89 0.87 0.88 51533
WEIGHTED AVG 0.98 0.98 0.98 51533

์œ„์˜ ๋ณด๊ณ ์„œ์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋“ฏ์ด ์ €ํฌ ๋ชจ๋ธ์€ ์‚ฌ๋žŒ, ์œ„์น˜, ์กฐ์ง์„ ์˜ˆ์ธกํ•˜๋Š” ๋ฐ ์ข‹์€ ์„ฑ๋Šฅ์„ ๋ณด์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ์„ ์œ„ํ•ด ๋” ๋งŽ์€ ๋ฐ์ดํ„ฐ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. MISC ์—”ํ‹ฐํ‹ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ์ด๋Ÿฌํ•œ ์—”ํ‹ฐํ‹ฐ์— ๋Œ€ํ•œ ๋ชจ๋ธ์˜ ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ•ฉ๋‹ˆ๋‹ค.

ํŒŒ์ดํ”„๋ผ์ธ

๋ชจ๋ธ์„ ๋ฏธ์„ธ ์กฐ์ •ํ•œ ํ›„์—๋Š” ์ด ํŠœํ† ๋ฆฌ์–ผ์— ๋”ฐ๋ผ ์ปค๋ฎค๋‹ˆํ‹ฐ์™€ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŽ˜์ด์ง€. ์ด์ œ Hugging Face์˜ ์„œ๋ฒ„์—์„œ ๋ฏธ์„ธ ์กฐ์ •๋œ ๋ชจ๋ธ์„ ๋กœ๋“œํ•˜์—ฌ ์ŠคํŽ˜์ธ์–ด ๋ฌธ์„œ์—์„œ ๋ช…๋ช…๋œ ์—”ํ‹ฐํ‹ฐ๋ฅผ ์˜ˆ์ธกํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํŠธ๋žœ์Šคํฌ๋จธ์—์„œ ๊ฐ€์ ธ์˜ค๊ธฐ ํŒŒ์ดํ”„๋ผ์ธ, ์ž๋™ ๋ชจ๋ธ ํฌ ํ† ํฐ ๋ถ„๋ฅ˜, ์ž๋™ ํ† ํฐ ํ™”๊ธฐ

model = AutoModelForTokenClassification.from_pretrained("skimai/spanberta-base-cased-ner-conll02")
ํ† ํฐํ™”๊ธฐ = AutoTokenizer.from_pretrained("skimai/spanberta-base-cased-ner-conll02")

ner_model = ํŒŒ์ดํ”„๋ผ์ธ('ner', ๋ชจ๋ธ=๋ชจ๋ธ, ํ† ํฐํ™”๊ธฐ=ํ† ํฐํ™”๊ธฐ)

์•„๋ž˜ ์˜ˆ๋Š” ๋‹ค์Œ์—์„œ ๊ฐ€์ ธ์˜จ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜๊ฒฌ ๊ทธ๋ฆฌ๊ณ  "์Šคํ‹ฐ๋ธ ๋ฏ€๋ˆ„์‹  ์žฌ๋ฌด์žฅ๊ด€์€ ์ฝ”๋กœ๋‚˜19 ํŒฌ๋ฐ๋ฏน ์ดํ›„ ๋ฏธ๊ตญ์˜ ๊ฒฝ์ œ ํšŒ๋ณต์€ ์ˆ˜๊ฐœ์›”์ด ๊ฑธ๋ฆด ๊ฒƒ์ด๋ผ๊ณ  ๋งํ–ˆ์Šต๋‹ˆ๋‹ค."

์‹œํ€€์Šค = "La recuperaciรณn econรณmica de los Estados United States despuรฉs de la " \
           "์ฝ”๋กœ๋‚˜ ๋ฐ”์ด๋Ÿฌ์Šค ํŒฌ๋ฐ๋ฏน์€ ๋ช‡ ๋‹ฌ ์•ˆ์— ๋๋‚  ๊ฒƒ์ด๋ผ๊ณ  " \
           "์Šคํ‹ฐ๋ธ ๋ฏ€๋ˆ„์‹  ์žฌ๋ฌด์žฅ๊ด€."
ner_model(์‹œํ€€์Šค)
[{'entity': 'B-ORG', 'score': 0.9155661463737488, 'word': 'ฤ Estados'},
 {'entity': 'I-ORG', 'score': 0.800682544708252, 'word': 'ฤ Unidos'},
 {'entity': 'I-MISC', 'score': 0.5006815791130066, 'word': 'ฤ corona'},
 {'entity': 'I-MISC', 'score': 0.510674774646759, 'word': 'virus'},
 {'entity': 'B-PER', 'score': 0.5558510422706604, 'word': 'ฤ Secretario'},
 {'entity': 'I-PER', 'score': 0.7758238315582275, 'word': 'ฤ del'},
 {'entity': 'I-PER', 'score': 0.7096233367919922, 'word': 'ฤ Tesoro'},
 {'entity': 'B-PER', 'score': 0.9940345883369446, 'word': 'ฤ Steven'},
 {'entity': 'I-PER', 'score': 0.9962581992149353, 'word': 'ฤ M'},
 {'entity': 'I-PER', 'score': 0.9918380379676819, 'word': 'n'},
 {'entity': 'I-PER', 'score': 0.9848328828811646, 'word': 'uch'},
 {'entity': 'I-PER', 'score': 0.8513168096542358, 'word': 'in'}]

๋ฉ‹์ง€๋„ค์š”! ๋ฏธ์„ธ ์กฐ์ •๋œ ๋ชจ๋ธ์€ ์˜ˆ์ œ์—์„œ ๋ชจ๋“  ์—”ํ‹ฐํ‹ฐ๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ์ธ์‹ํ•˜๊ณ  ์‹ฌ์ง€์–ด "์ฝ”๋กœ๋‚˜ ๋ฐ”์ด๋Ÿฌ์Šค"๋„ ์ธ์‹ํ•ฉ๋‹ˆ๋‹ค.

๊ฒฐ๋ก 

๋ช…๋ช…๋œ ๊ฐœ์ฒด ์ธ์‹์€ ํ…์ŠคํŠธ์—์„œ ์ค‘์š”ํ•œ ์ •๋ณด๋ฅผ ๋น ๋ฅด๊ฒŒ ์ถ”์ถœํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋น„์ฆˆ๋‹ˆ์Šค์— ์ ์šฉํ•˜๋ฉด ๊ณ„์•ฝ์„œ๋‚˜ ๋ฌธ์„œ๋ฅผ ์ฝ๋Š” ์‚ฌ๋žŒ์˜ ์ƒ์‚ฐ์„ฑ ํ–ฅ์ƒ์— ์ง์ ‘์ ์ธ ์˜ํ–ฅ์„ ๋ฏธ์น  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ NER์€ ๋‹จ์–ด ์ˆ˜์ค€์—์„œ ์ •ํ™•ํ•œ ๋ถ„๋ฅ˜๊ฐ€ ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐฑ์˜ค๋ธŒ์›Œ๋“œ์™€ ๊ฐ™์€ ๋‹จ์ˆœํ•œ ์ ‘๊ทผ ๋ฐฉ์‹์œผ๋กœ๋Š” ์ด ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ๊นŒ๋‹ค๋กœ์šด NLP ์ž‘์—…์ž…๋‹ˆ๋‹ค.

์‚ฌ์ „ ํ•™์Šต๋œ BERT ๋ชจ๋ธ์„ ํ™œ์šฉํ•˜์—ฌ ์ŠคํŽ˜์ธ์–ด์— ๋Œ€ํ•œ NER ์ž‘์—…์—์„œ ์šฐ์ˆ˜ํ•œ ์„ฑ๋Šฅ์„ ๋น ๋ฅด๊ฒŒ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์‚ดํŽด๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์‚ฌ์ „ ํ›ˆ๋ จ๋œ SpanBERTa ๋ชจ๋ธ์€ ๋ฌธ์„œ ๋ถ„๋ฅ˜์™€ ๊ฐ™์€ ๋‹ค๋ฅธ ์ž‘์—…์—๋„ ๋ฏธ์„ธ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‹œํ€€์Šค ๋ถ„๋ฅ˜ ๋ฐ ๊ฐ์ • ๋ถ„์„์„ ์œ„ํ•ด BERT๋ฅผ ๋ฏธ์„ธ ์กฐ์ •ํ•˜๋Š” ์ž์„ธํ•œ ํŠœํ† ๋ฆฌ์–ผ์„ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด ์‹œ๋ฆฌ์ฆˆ์˜ ๋‹ค์Œ 3๋ถ€์—์„œ๋Š” ์ตœ์‹  ์„ฑ๋Šฅ์„ ๋น ๋ฅด๊ฒŒ ๋‹ฌ์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ๋ณ€์••๊ธฐ ๋ชจ๋ธ์— ๋Œ€ํ•œ ๋ณด๋‹ค ํšจ์œจ์ ์ธ ์‚ฌ์ „ ๊ต์œก ์ ‘๊ทผ ๋ฐฉ์‹์ธ ELECTRA๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋Œ€ํ•ด์ฃผ์„ธ์š”!

๊ท€์‚ฌ์˜ AI ์†”๋ฃจ์…˜์— ๋Œ€ํ•ด ๋…ผ์˜ํ•ด ๋ณด์„ธ์š”

    ๊ด€๋ จ ๊ฒŒ์‹œ๋ฌผ

    • LLM ํ”„๋กฌํ”„ํŠธ ๊ธฐ์ˆ 

      ํšจ๊ณผ์ ์ธ ๋Œ€๊ทœ๋ชจ ์–ธ์–ด ๋ชจ๋ธ(LLM) ํ”„๋กฌํ”„ํŠธ๋ฅผ ๋งŒ๋“œ๋Š” ๊ธฐ์ˆ ์€ AI ์‹ค๋ฌด์ž์—๊ฒŒ ์ค‘์š”ํ•œ ๊ธฐ์ˆ ์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ž˜ ์„ค๊ณ„๋œ ํ”„๋กฌํ”„ํŠธ๋Š” LLM์˜ ์„ฑ๋Šฅ์„ ํฌ๊ฒŒ ํ–ฅ์ƒ์‹œ์ผœ ๋ณด๋‹ค ์ •ํ™•ํ•˜๊ณ  ๊ด€๋ จ์„ฑ์ด ๋†’์œผ๋ฉฐ ์ฐฝ์˜์ ์ธ ๊ฒฐ๊ณผ๋ฌผ์„ ์–ป์„ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. ์ด ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ์—์„œ๋Š” 10๊ฐ€์ง€ ํ”„๋กฌํ”„ํŠธ์— ๋Œ€ํ•ด ์‚ดํŽด๋ด…๋‹ˆ๋‹ค.

      ํ”„๋กฌํ”„ํŠธ ์—”์ง€๋‹ˆ์–ด๋ง
    • ์ƒ์œ„ 10๊ฐœ AI ์œ ํŠœ๋ธŒ ์ฑ„๋„

      ์ธ๊ณต์ง€๋Šฅ ๋ถ„์•ผ๋Š” ์ง€์†์ ์ธ ํ•™์Šต์„ ์š”๊ตฌํ•˜๋ฉฐ, YouTube๋Š” ์ธ๊ณต์ง€๋Šฅ ๊ต์œก ๋ฐ ์ „๋ฌธ์„ฑ ๊ฐœ๋ฐœ์„ ์œ„ํ•œ ๊ฐ€์žฅ ๊ฐ•๋ ฅํ•œ ํ”Œ๋žซํผ ์ค‘ ํ•˜๋‚˜๋กœ ๋ถ€์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ์—ฐ๊ตฌ ๋…ผ๋ฌธ๊ณผ ์ „ํ†ต์ ์ธ ํ•™์Šต ๊ฒฝ๋กœ๊ฐ€ ์—ฌ์ „ํžˆ ์ค‘์š”ํ•˜์ง€๋งŒ, ์„ ๋„์ ์ธ AI ์œ ํŠœ๋ฒ„๋“ค์€

      ์ œ๋„ˆ๋ ˆ์ดํ‹ฐ๋ธŒ AI
    • ์œ ํŠœ๋ธŒ์šฉ AI ๋„๊ตฌ

      ์—ญ๋™์ ์ธ YouTube ์ฝ˜ํ…์ธ  ์ œ์ž‘ ํ™˜๊ฒฝ์—์„œ AI ๋„๊ตฌ๋ฅผ ํ™œ์šฉํ•˜๋ฉด ๋™์˜์ƒ ์ œ์ž‘ ํ”„๋กœ์„ธ์Šค๋ฅผ ํฌ๊ฒŒ ๊ฐœ์„ ํ•˜๊ณ  ์›Œํฌํ”Œ๋กœ๋ฅผ ๊ฐ„์†Œํ™”ํ•˜๋ฉฐ ์ฑ„๋„์˜ ์„ฑ์žฅ์„ ์ด‰์ง„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋™์˜์ƒ ํŽธ์ง‘ ์†Œํ”„ํŠธ์›จ์–ด๋ถ€ํ„ฐ ํ‚ค์›Œ๋“œ ์กฐ์‚ฌ ๋„๊ตฌ๊นŒ์ง€, ๋‹ค์Œ๊ณผ ๊ฐ™์€ AI ๊ธฐ๋ฐ˜ ์†”๋ฃจ์…˜์€ YouTube ํฌ๋ฆฌ์—์ดํ„ฐ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

      TV, ์˜ํ™” ๋ฐ ์ฝ˜ํ…์ธ 

    ๋น„์ฆˆ๋‹ˆ์Šค๋ฅผ ๊ฐ•ํ™”ํ•  ์ค€๋น„ ์™„๋ฃŒ

    ko_KRํ•œ๊ตญ์–ด