π‘ μ€μ΅ λͺ©μ : KoNLPyλ‘ νκ΅μ΄ ννμ λΆμκΈ°λ₯Ό μ¬μ©ν΄ 보기
μ κ·ν: μΌκ΄λκ² μ μ²λ¦¬ ν΄μ λΆνμνκ² ν ν°μ μμ±νμ§ μκ³ κ°μ μλ―Έλ₯Ό λΆμ¬νκ² λ©λλ€.
λνμ μΈ μμ°μ΄μ²λ¦¬ λκ΅¬μΈ NLTK, Spacyλ νκ΅μ΄λ₯Ό μ§μνμ§ μμ΅λλ€. μμ΄λ₯Ό μ¬μ©νλ€λ©΄ ν΄λΉλꡬλ₯Ό μ¬μ©ν΄λ λ©λλ€. νμ§λ§ νκ΅μ΄ ννμ λΆμ λ±μ κΈ°λ₯μ μ 곡νμ§ μκΈ° λλ¬Έμ KoNLPyλ‘ μ€μ΅ν©λλ€.
KoNLPyλ μ€μΉκ° κΉλ€λ‘μ΅λλ€. Java, C, C++λ‘ μμ±λ λꡬλ₯Ό νμ΄μ¬μΌλ‘ μ¬μ©ν μ μλλ‘ μ°κ²°ν΄ μ£Όλ λꡬμ΄κΈ° λλ¬Έμ μ¬λ¬ νκ²½ μμ‘΄μ±μ΄ μμ΅λλ€. νκ²½ μμ‘΄μ±μ λ§μ‘±ν΄μΌ λμνλ λκ΅¬κ° μμ΅λλ€.
ννμ λΆμ λ° νμ¬ νκΉ β KoNLPy 0.6.0 documentation
ννμ λΆμκΈ°λ§λ€ νμ¬λ₯Ό νκΉ νλ λ°©λ²μ΄ λ€ λ€λ¦ λλ€.
π€ νμ¬νκΉ
ν λ λͺ
μ¬μλ μ΄λ€ 곡ν΅μ μ΄ μμκΉμ?
Nλ‘ μμ
π€ λμ¬μλ μ΄λ€ 곡ν΅μ μ΄ μμκΉμ?
Vλ‘ μμ
π‘ μ μ²λ¦¬λ μλκ° μ€λ 걸리기 λλ¬Έμ μ μ²λ¦¬ν κ²λ§ νμΌμ λ°λ‘ μ μ₯ν΄μ μ¬μ©νκΈ°λ ν¨
π‘ Pecab : Pecab is a pure python Korean morpheme analyzer based on Mecab.
π‘ Okt: stemming κΈ°λ₯μ μ 곡
from konlpy.tag import Okt
okt = Okt()
okt.pos("λ²μ€μ μ΄νμκ°μ λ¬Έμνμμ΅λλ€. μ΄?!", stem=True)
>>>
[('λ²μ€', 'Noun'),
('μ', 'Josa'),
('μ΄ν', 'Noun'),
('μκ°', 'Noun'),
('μ', 'Josa'),
('λ¬Έμ', 'Noun'),
('νλ€', 'Verb'), # νμμ΅λλ€ => νλ€
('.', 'Punctuation'),
('μ΄', 'Eomi'),
('?!', 'Punctuation')]
okt.pos("λ²μ€μ μ΄νμκ°μ λ¬Έμνλ€. μ΄?!", stem=True)
>>>
[('λ²μ€', 'Noun'),
('μ', 'Josa'),
('μ΄ν', 'Noun'),
('μκ°', 'Noun'),
('μ', 'Josa'),
('λ¬Έμ', 'Noun'),
('νλ€', 'Verb'), # νλ€ => νλ€
('.', 'Punctuation'),
('μ΄', 'Eomi'),
('?!', 'Punctuation')]
π‘ νμ¬ νκΉ ν λ μκ°μ΄ λ무 μ€λ 걸리λλ° μλλ₯Ό κ°μ νκ³ μ νλ€λ©΄ λ©ν°μ€λ λλ₯Ό λ§λ€μ΄μ μ²λ¦¬νλ λ°©λ²μ΄ μλ€.
# ννμ λΆμκΈ°(Okt) λΆλ¬μ€κΈ°
# ['Josa', 'Eomi', 'Punctuation'] μ‘°μ¬, μ΄λ―Έ, ꡬλμ μ κ±°
# μ 체 ν
μ€νΈμ μ μ©ν΄ μ£ΌκΈ° μν΄ ν¨μλ₯Ό λ§λλλ€.
# 1) ν
μ€νΈλ₯Ό μ
λ ₯λ°μ΅λλ€.
# 2) νμ¬νκΉ
μ ν©λλ€. [('λ¬Έμ', 'Noun'), ('νλ€', 'Verb'), ('?!', 'Punctuation')]
# 3) νκΉ
κ²°κ³Όλ₯Ό λ°μμ μν ν©λλ€.
# 4) νλμ© μν νμ λ νν ννλ‘ κ°μ Έμ€κ² λ©λλ€. ('μ', 'Josa')
# 5) ννμμ 1λ² μΈλ±μ€μ μλ νμ¬λ₯Ό κ°μ Έμ΅λλ€.
# 6) ν΄λΉ νμ¬κ° μ‘°μ¬, μ΄λ―Έ, ꡬλμ μ΄λ©΄ μ μΈνκ³ append λ‘ μΈλ±μ€ 0λ² κ°λ§ λ€μ 리μ€νΈμ λ΄μμ€λλ€.
# 7) " ".join() μΌλ‘ 곡백문μλ‘ μ°κ²°ν΄ μ£Όλ©΄ λ€μ λ¬Έμ₯μ΄ λ©λλ€.
# 8) μ μ²λ¦¬ ν μμ±λ λ¬Έμ₯μ λ°νν©λλ€.
def okt_clean(text):
clean_text = []
# νμ¬νκΉ
μ ν©λλ€. [('λ¬Έμ', 'Noun'), ('νλ€', 'Verb'), ('?!', 'Punctuation')]
# νκΉ
κ²°κ³Όλ₯Ό λ°μμ μν ν©λλ€.
for word in okt.pos(text, norm=True, stem=True):
# ν΄λΉ νμ¬κ° μ‘°μ¬, μ΄λ―Έ, ꡬλμ μ΄λ©΄ μ μΈνκ³ append λ‘ μΈλ±μ€ 0λ² κ°λ§ λ€μ 리μ€νΈμ λ΄μμ€λλ€.
if word[1] not in ['Josa', 'Eomi', 'Punctuation']:
clean_text.append(word[0])
# " ".join() μΌλ‘ 곡백문μλ‘ μ°κ²°ν΄ μ£Όλ©΄ λ€μ λ¬Έμ₯μ΄ λ©λλ€.
return " ".join(clean_text)
okt_clean("λ¬λ¬νκ±° λ¨Ήκ³ μΆμλ° λ μ΄λ?")
>>>
'λ¬λ¬ ν κ±° λ¨Ήλ€ μΆλ€ λ μ΄λ»λ€'
π‘ μ€μ΅ λͺ©μ : μνμ€ λ°©μμ μΈμ½λ©μ μ¬μ©ν΄ λ³΄κ³ , Bag of Words μ TF-IDF λ°©μκ³Ό μνμ€ λ°©μμ΄ μ΄λ€ μ°¨μ΄κ° μλμ§ μμ보기
π‘ μ€μ΅ νλ¦
1) Tokenizer μΈμ€ν΄μ€λ₯Ό μμ±
2) fit_on_textsμ word_indexλ₯Ό μ¬μ©νμ¬ key valueλ‘ μ΄λ£¨μ΄μ§ λμ
λ리λ₯Ό μμ±
3) texts_to_sequencesλ₯Ό μ΄μ©νμ¬ text λ¬Έμ₯μ μ«μλ‘ μ΄λ£¨μ΄μ§ 리μ€νΈλ‘ λ³κ²½
4) λ§μ§λ§μΌλ‘ pad_sequencesλ₯Ό μ΄μ©νμ¬ λ¦¬μ€νΈμ κΈΈμ΄λ₯Ό ν΅μΌν
tf.keras.preprocessing.text.Tokenizer(
num_words=None,
filters='!"#$%&()*+,-./:;<=>?@[\\]^_`{|}~\t\n',
lower=True,
split=' ',
char_level=False,
oov_token=None,
analyzer=None,
**kwargs
)
μ΄ ν΄λμ€λ₯Ό μ¬μ©νλ©΄ κ° ν μ€νΈλ₯Ό μΌλ ¨μ μ μ(κ° μ μλ μ¬μ μ μλ ν ν°μ μΈλ±μ€μ) λλ λ¨μ΄ μμ λ°λΌ κ° ν ν°μ κ³μκ° μ΄μ§μΌ μ μλ 벑ν°λ‘ λ³ννμ¬ ν μ€νΈ λ§λμΉλ₯Ό 벑ν°νν μ μμ΅λλ€.(TF-IDFκΈ°λ°)
맀κ°λ³μ
num_words
: λ¨μ΄ λΉλμ λ°λΌ μ μ§ν μ΅λ λ¨μ΄ μμ
λλ€. κ°μ₯ μΌλ°μ μΈ λ¨μ΄ λ§ μ μ§λ©λλ€.
filters
: κ° μμκ° ν
μ€νΈμμ νν°λ§λ λ¬ΈμμΈ λ¬Έμμ΄μ
λλ€. κΈ°λ³Έκ°μ λ¬Έμλ₯Ό μ μΈν λͺ¨λ ꡬλμ κ³Ό ν λ° μ€ λ°κΏ 'μ
λλ€.
lower
: λΆμΈ. ν
μ€νΈλ₯Ό μλ¬Έμλ‘ λ³νν μ§ μ¬λΆμ
λλ€.
split
: str. λ¨μ΄ λΆν μ μν κ΅¬λΆ κΈ°νΈμ
λλ€.
char_level
: Trueμ΄λ©΄ λͺ¨λ λ¬Έμκ° ν ν°μΌλ‘ μ²λ¦¬λ©λλ€.
oov_token
: μ£Όμ΄μ§ κ²½μ°, κ·Έκ²μ word_indexμ μΆκ°λκ³ text_to_sequence νΈμΆ μ€μ μ΄ν λ°μ λ¨μ΄λ₯Ό λ체νλ λ° μ¬μ©λ©λλ€.
π‘ num_words=vocab_size
λ₯Ό μ§μ νλ©΄ ν΄λΉ λ¬Έμ₯μ λ¨μ΄ μκ° μ§μ ν vocab_size
λ₯Ό λμΌλ©΄ λΉλμκ° μ μ λ¨μ΄λ μ μΈνκ³ μΆλ ₯νλ€. (= λΉλμκ° λμ λ¨μ΄λ§ vocab_size - 1
λ§νΌ μΆλ ₯)
λ¨μ΄ μλ₯Ό λ무 λ§μ΄ μ§μ νλ©΄ λμ€μ νμ΅μ ν λ λ무 μ€λ 걸릴 μ μκ³ λ¬Έμ₯ κΈΈμ΄κ° λ€ μ κ°κ°μ λλ€. λ¨μ΄ μλ₯Ό μ ννλ©΄ μ΄νμ μλ λ¨μ΄κ° λ±μ₯νμ λ μνμ€μ λλ½μ΄ λκΈ° λλ¬Έμ μ΄λ° κ°μ μ²λ¦¬νλ λ°©λ²μ΄ μμ΅λλ€.
oov_token
(out-of-vocabulary)μ μ¬μ©νλ©΄ μλ μ΄νλ μλ μ΄νλΌκ³ ννν΄ μ€λλ€.
π€ oov_token κ°μΌλ‘ λ£μ΄μ€ μ μλ κ°μ μ΄λ€κ²λ€μ΄ μλμ?
λ§μ€ν¬κ°, μ’
κ²°, ν¨λ© λ±μΌλ‘ μ¬μ©νκΈ°λ ν©λλ€.
"<oov>"
λ₯Ό μ¬μ©νμ§ μκ³ λ€λ₯Έ λ¬Έμλ₯Ό μ¬μ©ν΄λ μκ΄μ μμ΅λλ€.
[UNK]: unknownμ μλ―Έλ‘ λ§μ΄ μ¬μ©νκΈ΄ ν©λλ€
π‘ μΈλ±μ€κ° 0λΆν° μμνμ§ μκ³ 1λΆν° μμνλ€.
tokenizer = Tokenizer(num_words=10, oov_token="<oov>")
tokenizer.fit_on_texts(corpus)
print(tokenizer.word_index)
print(corpus)
corpus_sequences = tokenizer.texts_to_sequences(corpus)
corpus_sequences
>>>
{'<oov>': 1, 'λ¬Έμμ
λλ€': 2, 'μ΄νμκ°': 3, 'seoul': 4, 'μμΈ': 5, 'μ½λ‘λ': 6, 'μμμ§μκΈ': 7, 'μΈμ²': 8, 'μ§νμ² ': 9, 'bus': 10, 'λ²μ€': 11}
['SEOUL μμΈ μ½λ‘λ μμμ§μκΈ λ¬Έμμ
λλ€.?', 'μΈμ² μ§νμ² μ΄νμκ° λ¬Έμμ
λλ€.!', 'Bus λ²μ€ μ΄νμκ° λ¬Έμμ
λλ€.#']
[[4, 5, 6, 7, 2], [8, 9, 3, 2], [1, 1, 3, 2]]
κΈΈμ΄κ° λ§μ§ μμμ μ λλ‘ numpy arrayκ° λ§λ€μ΄μ§μ§ μλλ°, μ΄λ΄ λλ Padding κΈ°λ²
μ μ¬μ©ν΄ κΈΈμ΄λ₯Ό λ§μΆ°μ£Όλ©΄ λλ€.
κΈ°λ³Έμ μΌλ‘ κ°μ₯ κΈΈμ΄κ° κ°μ₯ κΈ΄ sequenceμ λ§μΆ° μΈμ½λ©
β μμ
pad_sequences(sequences, maxlen=None, dtype='int32',
padding='pre', truncating='pre', value=0.0)
>>> sequence = [[1], [2, 3], [4, 5, 6]]
>>> tf.keras.preprocessing.sequence.pad_sequences(sequence)
array([[0, 0, 1],
[0, 2, 3],
[4, 5, 6]], dtype=int32)
>>> tf.keras.preprocessing.sequence.pad_sequences(sequence, value=-1)
# 0λμ -1λ‘ μ±μ
array([[-1, -1, 1],
[-1, 2, 3],
[ 4, 5, 6]], dtype=int32)
>>> tf.keras.preprocessing.sequence.pad_sequences(sequence, padding='post')
# 0μ λ€μ μΆκ°
array([[1, 0, 0],
[2, 3, 0],
[4, 5, 6]], dtype=int32)
>>> tf.keras.preprocessing.sequence.pad_sequences(sequence, maxlen=2)
array([[0, 1],
[2, 3],
[5, 6]], dtype=int32)
π‘ sequence λ°©μμ μΈμ½λ©μ μμλ₯Ό 보쑴νκΈ° λλ¬Έμ RNN(μμλ₯Ό κ³ λ €νλ μκ³ λ¦¬μ¦)μμ λμ μ±λ₯μ λΈλ€.
λ¨Έμ λ¬λμμλ sequence λ°©μ λ³΄λ€ TF-IDFλ₯Ό μ¬μ©νλ κ²μ΄ λ λμ μ±λ₯μ λΈλ€.
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
"""
1) tokenizer λΆλ¬μ€κΈ°
2) fit_on_text
3) sequence λ§λ€κΈ°
4) padding
"""
tokenizer = Tokenizer(num_words=7, oov_token="[UNK]")
tokenizer.fit_on_texts(corpus2)
print(tokenizer.word_index)
print(corpus2)
corpus_sequences = tokenizer.texts_to_sequences(corpus2)
pads = pad_sequences(corpus_sequences, maxlen=10, padding="pre")
print(corpus2)
print(word_to_index)
print(pads)
np.array(pads)
>>>
{'[UNK]': 1, 'λ¬Έμμ
λλ€': 2, 'μ½λ‘λ': 3, 'μ§νμ² ': 4, 'μΉκ°μ₯': 5, 'bus': 6, 'μλ΄μ
λλ€': 7, 'covid19': 8, '거리λκΈ°μ': 9, 'μμμ§μκΈ': 10, 'μ΄νμκ°κ³Ό': 11, 'μκΈ': 12, 'μ λ³μ§λ£μ': 13, 'μ΄νμκ°': 14, 'ν°λ―Έλ': 15, 'μμΉ': 16, '거리λκΈ°': 17, 'taxi': 18}
['COVID19 거리λκΈ°μ μ½λ‘λ μμμ§μκΈ λ¬Έμμ
λλ€.', 'μ§νμ² μ΄νμκ°κ³Ό μ§νμ² μκΈ λ¬Έμμ
λλ€.', 'μ§νμ² μΉκ°μ₯ λ¬Έμμ
λλ€.', 'μ½λ‘λ μ λ³μ§λ£μ λ¬Έμμ
λλ€.', 'Bus μ΄νμκ° λ¬Έμμ
λλ€.', 'BUS ν°λ―Έλ μμΉ μλ΄μ
λλ€.', 'μ½λ‘λ 거리λκΈ° μλ΄μ
λλ€.', 'taxi μΉκ°μ₯ λ¬Έμμ
λλ€.']
['COVID19 거리λκΈ°μ μ½λ‘λ μμμ§μκΈ λ¬Έμμ
λλ€.', 'μ§νμ² μ΄νμκ°κ³Ό μ§νμ² μκΈ λ¬Έμμ
λλ€.', 'μ§νμ² μΉκ°μ₯ λ¬Έμμ
λλ€.', 'μ½λ‘λ μ λ³μ§λ£μ λ¬Έμμ
λλ€.', 'Bus μ΄νμκ° λ¬Έμμ
λλ€.', 'BUS ν°λ―Έλ μμΉ μλ΄μ
λλ€.', 'μ½λ‘λ 거리λκΈ° μλ΄μ
λλ€.', 'taxi μΉκ°μ₯ λ¬Έμμ
λλ€.']
{'λ¬Έμμ
λλ€': 1, 'μ΄νμκ°': 2, 'seoul': 3, 'μμΈ': 4, 'μ½λ‘λ': 5, 'μμμ§μκΈ': 6, 'μΈμ²': 7, 'μ§νμ² ': 8, 'bus': 9, 'λ²μ€': 10}
[[0 0 0 0 0 1 1 3 1 2]
[0 0 0 0 0 4 1 4 1 2]
[0 0 0 0 0 0 0 4 5 2]
[0 0 0 0 0 0 0 3 1 2]
[0 0 0 0 0 0 0 6 1 2]
[0 0 0 0 0 0 6 1 1 1]
[0 0 0 0 0 0 0 3 1 1]
[0 0 0 0 0 0 0 1 5 2]]
array([[0, 0, 0, 0, 0, 1, 1, 3, 1, 2],
[0, 0, 0, 0, 0, 4, 1, 4, 1, 2],
[0, 0, 0, 0, 0, 0, 0, 4, 5, 2],
[0, 0, 0, 0, 0, 0, 0, 3, 1, 2],
[0, 0, 0, 0, 0, 0, 0, 6, 1, 2],
[0, 0, 0, 0, 0, 0, 6, 1, 1, 1],
[0, 0, 0, 0, 0, 0, 0, 3, 1, 1],
[0, 0, 0, 0, 0, 0, 0, 1, 5, 2]], dtype=int32)
π‘ λλ¬Έμλ μλμΌλ‘ μλ¬Έμλ‘ λ³νλ¨.
π‘ num_words
λ₯Ό λ¬Έμ₯ κΈΈμ΄μ λΉν΄ λ무 μκ² μ€μ νλ©΄ oov
κ° λ무 λ§μ΄ μκΈ°κ² λμ΄ μ±λ₯μ΄ μ μ’μμ§λ€. λ¬Έμ₯μ΄ λ무 κΈΈλ©΄ num_words
λ₯Ό μ€μ νμ§ μλ κ²λ λ°©λ².
- tokenizerμ word_index μμ±μ λ¨μ΄μ μ«μμ ν€-κ° μμ ν¬ν¨νλ λμ λ리λ₯Ό λ°ννλ€.
- fit_on_texts() λ©μλλ λ¬Έμ λ°μ΄ν°λ₯Ό μ λ ₯λ°μμ λΉλμλ₯Ό κΈ°μ€μΌλ‘ λ¨μ΄ μ§ν©μ μμ±νλ€.
- Tokenizerλ μ μ μΈμ½λ©μ μννλ λ°©λ²μ λλ€.
to_categoricla()λ μ μ μΈμ½λ© κ²°κ³Όλ₯Ό μ λ ₯μΌλ‘ λ°μ λ°λ‘ μ-ν« μΈμ½λ© κ³Όμ μ μννλ λ°©λ²μ΄λ€.- texts_to_sequences() λ©μλλ ν μ€νΈ μμ λ¨μ΄λ€μ μ«μμ μνμ€μ ννλ‘ λ³ννλ€.
[4,1,2]
π€ μμ, λ§₯λ½, μνμ€ κ° μ€μν λ°μ΄ν°λ μ΄λ€ λ°μ΄ν°κ° μμκΉμ?
μκ³μ΄λ°μ΄ν°, μ£Όμ, λ μ¨, μ
보
μμκ° μ€μν μκ³μ΄ λ°μ΄ν°(μ£Όκ° λ°μ΄ν° λ±)λ μμ§ μκ³ μμλλ‘ λλκΈ°λ νλ€.
RNN (Recurrent Neural Network)μ μκ³μ΄ λλ μμ°μ΄μ κ°μ μνμ€ λ°μ΄ν°λ₯Ό λͺ¨λΈλ§νλ λ° κ°λ ₯ν μ κ²½λ§ ν΄λμ€μ λλ€.
μ
λ ₯ κ°―μ μΆλ ₯ κ°―μμ λ°λΌμ one to many, many to one, many to many λ‘ λλ μ§μ§λ§ ν΅μ¬μ νμμ€ν
μΌλ‘ μ΄μ hidden state μ μμνκ³Ό νμμ μ μΈ
νμ΄ ν¨κ» μ°μ°
μΆμ² : http://cs231n.stanford.edu/slides/2017/cs231n_2017_lecture10.pdf
π€ RNN λͺ¨λΈμ λ§λ€ μμ μ΄λ©° μΆλ ₯μΈ΅μ κΈ°μ‘΄μ λ§λ€μλ κ²μ²λΌ λ§λ€ μμ μ
λλ€. "νμ ", "κ²½μ ", "볡μ§" labelμ one-hot-encoding μ ν΄μ£Όλ μ΄μ ?
λΆλ₯ λͺ¨λΈμ μΆλ ₯μΈ΅μ softmax
λ‘ μ¬μ©νκΈ° μν΄μ.
softmax λ κ° ν΄λμ€μ νλ₯ κ°μ λ°ννλ©° κ°κ°μ ν΄λμ€μ ν©κ³λ₯Ό ꡬνμ λ 1μ΄ λ©λλ€.
Q: tqdm μ μ¬μ©λͺ©μ μ 무μμΌκΉμ?
A: μ€λ 걸리λ μμ
μ ν λ μ§νμνλ₯Ό νμν΄μ€λλ€.