

f1: 88.43

|       | precision | recall | f1-score | support |
|-------|-----------|--------|----------|---------|
| DAT   |   0.96    |  0.97  |   0.96   |   182   |
| DUR   |   0.79    |  0.82  |   0.80   |   50    |
| LOC   |   0.70    |  0.79  |   0.74   |   206   |
| MNY   |   0.87    |  1.00  |   0.93   |   20    |
| NOH   |   0.91    |  0.93  |   0.92   |   1007  |
| ORG   |   0.86    |  0.89  |   0.88   |   795   |
| PER   |   0.92    |  0.95  |   0.94   |   853   |
| PNT   |   0.78    |  0.78  |   0.78   |   60    |
| POH   |   0.64    |  0.71  |   0.68   |   214   |
| TIM   |   0.76    |  1.00  |   0.86   |   19    |
|-------|-----------|--------|----------|---------|
|micro avg |   0.87    |  0.90  |   0.88   |   3406  |
|macro avg |   0.82    |  0.89  |   0.85   |   3406  |
|weighted avg |   0.87    |  0.90  |   0.89   |   3406  |

```python
from transformers import TFBertModel, BertTokenizer
import os
import tensorflow as tf
import numpy as np
from tqdm import tqdm
from konlpy.tag import Mecab

mecab = Mecab()

checkpoint_path = "./cp-{epoch:04d}.ckpt"
checkpoint_dir = os.path.dirname(checkpoint_path)
latest = tf.train.latest_checkpoint(checkpoint_dir)

index_to_tag = {0: 'B-PER', 1: 'B-LOC', 2: 'I-ORG', 3: 'B-DAT', 4: 'O', 5: 'I-DUR', 6: 'I-TIM', 7: 'I-NOH', 8: 'B-MNY', 9: 'B-PNT', 10: 'I-PER', 11: 'I-PNT', 12: 'I-LOC', 13: 'I-DAT', 14: 'B-TIM', 15: 'B-POH', 16: 'B-NOH', 17: 'I-POH', 18: 'I-MNY', 19: 'B-ORG', 20: 'B-DUR'}

tokenizer = BertTokenizer.from_pretrained("klue/bert-base")
model = TFBertForTokenClassification("klue/bert-base", num_labels=21)
model.load_weights(latest)

class TFBertForTokenClassification(tf.keras.Model):
    def __init__(self, model_name, num_labels):
        super(TFBertForTokenClassification, self).__init__()
        self.bert = TFBertModel.from_pretrained(model_name, from_pt=True)
        self.classifier = tf.keras.layers.Dense(num_labels,
                                                kernel_initializer=tf.keras.initializers.TruncatedNormal(0.02),
                                                name='classifier')

    def call(self, inputs):
        input_ids, attention_mask, token_type_ids = inputs
        outputs = self.bert(input_ids=input_ids, attention_mask=attention_mask, token_type_ids=token_type_ids)
        all_output = outputs[0]
        prediction = self.classifier(all_output)

        return prediction


def convert_examples_to_features_for_prediction(examples, max_seq_len, tokenizer,
                                 pad_token_id_for_segment=0, pad_token_id_for_label=-100):
    cls_token = tokenizer.cls_token
    sep_token = tokenizer.sep_token
    pad_token_id = tokenizer.pad_token_id

    input_ids, attention_masks, token_type_ids, label_masks = [], [], [], []

    for example in tqdm(examples):
        tokens = []
        label_mask = []
        for one_word in example:
            subword_tokens = tokenizer.tokenize(one_word)
            tokens.extend(subword_tokens)
            label_mask.extend([0]+ [pad_token_id_for_label] * (len(subword_tokens) - 1))

        special_tokens_count = 2
        if len(tokens) > max_seq_len - special_tokens_count:
            tokens = tokens[:(max_seq_len - special_tokens_count)]
            label_mask = label_mask[:(max_seq_len - special_tokens_count)]

        tokens += [sep_token]
        label_mask += [pad_token_id_for_label]

        tokens = [cls_token] + tokens
        label_mask = [pad_token_id_for_label] + label_mask


        input_id = tokenizer.convert_tokens_to_ids(tokens)
        attention_mask = [1] * len(input_id)
        padding_count = max_seq_len - len(input_id)
        input_id = input_id + ([pad_token_id] * padding_count)
        attention_mask = attention_mask + ([0] * padding_count)
        token_type_id = [pad_token_id_for_segment] * max_seq_len
        label_mask = label_mask + ([pad_token_id_for_label] * padding_count)

        assert len(input_id) == max_seq_len, "Error with input length {} vs {}".format(len(input_id), max_seq_len)
        assert len(attention_mask) == max_seq_len, "Error with attention mask length {} vs {}".format(len(attention_mask), max_seq_len)
        assert len(token_type_id) == max_seq_len, "Error with token type length {} vs {}".format(len(token_type_id), max_seq_len)
        assert len(label_mask) == max_seq_len, "Error with labels length {} vs {}".format(len(label_mask), max_seq_len)

        input_ids.append(input_id)
        attention_masks.append(attention_mask)
        token_type_ids.append(token_type_id)
        label_masks.append(label_mask)

    input_ids = np.array(input_ids, dtype=int)
    attention_masks = np.array(attention_masks, dtype=int)
    token_type_ids = np.array(token_type_ids, dtype=int)
    label_masks = np.asarray(label_masks, dtype=np.int32)

    return (input_ids, attention_masks, token_type_ids), label_masks


def ner_prediction(examples, max_seq_len, tokenizer, lang='ko'):

    if lang == 'ko':
        examples = [mecab.morphs(sent) for sent in examples]
    else:
        examples = [sent.split() for sent in examples]

    X_pred, label_masks = convert_examples_to_features_for_prediction(
        examples, max_seq_len=128, tokenizer=tokenizer)
    y_predicted = model.predict(X_pred)
    y_predicted = np.argmax(y_predicted, axis=2)

    pred_list = []
    result_list = []

    for i in range(0, len(label_masks)):
        pred_tag = []
        for label_index, pred_index in zip(label_masks[i], y_predicted[i]):
            if label_index != -100:
                pred_tag.append(index_to_tag[pred_index])

        pred_list.append(pred_tag)

    for example, pred in zip(examples, pred_list):
        one_sample_result = []
        for one_word, label_token in zip(example, pred):
            one_sample_result.append((one_word, label_token))
        result_list.append(one_sample_result)

    return result_list


sent1 = '울산에서 활동하고 있는 시각예술 분야 김유경 작가는 최근 지역 AI 기업 코어닷투데이와의 협업을 통한 특별한 전시를 열었다.'
sent2 = '가치관이나 인식에 따라 세상을 불완전하게 보는 인간이 학습을 통해 인지한 부분만을 인식하는 AI와 비슷하다고 보고 전시를 기획했다.'
sent3 = '부산 광안리 해변과 달맞이 고개 등 유동 인구와 차량 이동이 많은 지역 몇 곳을 골라 CCTV 데이터 속 정보를 어떻게 인식하는지, 공간에 대한 찰나를 표현한 작가의 작품을 어떻게 인식하는지 차이를 비교했다.'
test_samples = [sent1, sent2, sent3]
ner_prediction(test_samples, max_seq_len=128, tokenizer=tokenizer, lang='ko')
```
```
[[('울산', 'B-LOC'),
  ('에서', 'O'),
  ('활동', 'O'),
  ('하', 'O'),
  ('고', 'O'),
  ('있', 'O'),
  ('는', 'O'),
  ('시각', 'O'),
  ('예술', 'O'),
  ('분야', 'O'),
  ('김유경', 'B-PER'),
  ('작가', 'O'),
  ('는', 'O'),
  ('최근', 'O'),
  ('지역', 'O'),
  ('AI', 'O'),
  ('기업', 'O'),
  ('코어', 'B-ORG'),
  ('닷', 'I-ORG'),
  ('투데이', 'I-ORG'),
  ('와', 'O'),
  ('의', 'O'),
  ('협업', 'O'),
  ('을', 'O'),
  ('통한', 'O'),
  ('특별', 'O'),
  ('한', 'O'),
  ('전시', 'O'),
  ('를', 'O'),
  ('열', 'O'),
  ('었', 'O'),
  ('다', 'O'),
  ('.', 'O')],
 [('가치관', 'O'),
  ('이나', 'O'),
  ('인식', 'O'),
  ('에', 'O'),
  ('따라', 'O'),
  ('세상', 'O'),
  ('을', 'O'),
  ('불', 'O'),
  ('완전', 'O'),
  ('하', 'O'),
  ('게', 'O'),
  ('보', 'O'),
  ('는', 'O'),
  ('인간', 'O'),
  ('이', 'O'),
  ('학습', 'O'),
  ('을', 'O'),
  ('통해', 'O'),
  ('인지', 'O'),
  ('한', 'O'),
  ('부분', 'O'),
  ('만', 'O'),
  ('을', 'O'),
  ('인식', 'O'),
  ('하', 'O'),
  ('는', 'O'),
  ('AI', 'O'),
  ('와', 'O'),
  ('비슷', 'O'),
  ('하', 'O'),
  ('다고', 'O'),
  ('보', 'O'),
  ('고', 'O'),
  ('전시', 'O'),
  ('를', 'O'),
  ('기획', 'O'),
  ('했', 'O'),
  ('다', 'O'),
  ('.', 'O')],
 [('부산', 'B-LOC'),
  ('광안리', 'I-LOC'),
  ('해변', 'I-LOC'),
  ('과', 'O'),
  ('달맞이', 'B-LOC'),
  ('고개', 'I-LOC'),
  ('등', 'O'),
  ('유동', 'O'),
  ('인구', 'O'),
  ('와', 'O'),
  ('차량', 'O'),
  ('이동', 'O'),
  ('이', 'O'),
  ('많', 'O'),
  ('은', 'O'),
  ('지역', 'O'),
  ('몇', 'O'),
  ('곳', 'O'),
  ('을', 'O'),
  ('골라', 'O'),
  ('CCTV', 'O'),
  ('데이터', 'O'),
  ('속', 'O'),
  ('정보', 'O'),
  ('를', 'O'),
  ('어떻게', 'O'),
  ('인식', 'O'),
  ('하', 'O'),
  ('는지', 'O'),
  (',', 'O'),
  ('공간', 'O'),
  ('에', 'O'),
  ('대한', 'O'),
  ('찰나', 'O'),
  ('를', 'O'),
  ('표현', 'O'),
  ('한', 'O'),
  ('작가', 'O'),
  ('의', 'O'),
  ('작품', 'O'),
  ('을', 'O'),
  ('어떻게', 'O'),
  ('인식', 'O'),
  ('하', 'O'),
  ('는지', 'O'),
  ('차이', 'O'),
  ('를', 'O'),
  ('비교', 'O'),
  ('했', 'O'),
  ('다', 'O'),
  ('.', 'O')]]
```


```
tensorflow-estimator==2.5.0
tensorflow-gpu==2.5.3
transformers @ git+https://github.com/davidegazze/transformers@cf28c1db00410f0df3e654d9866e0ff1d3a45f29
numpy==1.24.3
konlpy==0.6.0
```
{"license": "mit"}
license:mit region:us
TAGS
#license-mit #region-us 

f1: 88.43




TAGS
#license-mit #region-us 
