OpenAI Embedding 기능을 사용하기 위해 PDF 에서 Text를 추출하여 특정 길이로 분리할 필요가 있었어 langchain 의 CharacterTextSplitter 를 사용하였다.
인스톨
pip install langchain
CharacterTextSplitter
from langchain.text_splitter import CharacterTextSplitter
story = '어느 마을에 양치기 소년이 하나 있었는데,\n 늑대들이 나타나 양을 물어간다느니 잡아먹는다느니 식으로 수시로 장난삼아 소리치곤 했다. 두세 번 정도는 마을 사람들이 놀라 부리나케 달려왔다. 하지만 그 때마다 골탕을 먹고 바보가 된 기분으로 화를 내거나 투덜거리며 돌아갔다.\n 그러던 어느 날 진짜로 늑대가 나타나서 양들을 잡아먹거나 물어가기 시작했다. 양치기는 이번엔 절대로 거짓말이 아니고 진짜라면서 마을 사람들에게 도와 달라고 호소했으나, 마을 사람들은 이번에도 절대로 속지 않을 것이며, 설령 진짜로 늑대가 나타났다 한들 다 저 녀석의 업보라고 칠 것이라면서 한 명도 도와주러 오지 않았다. 결국 양치기는 그렇게 양떼를 모두 잃고 말았다.'
text_splitter = CharacterTextSplitter(
separator = "\n",
chunk_size = 100,
chunk_overlap = 20,
length_function = len,
)
chunks = text_splitter.split_text(text)
결과
-------------- [0] 분리 길이 : 23 -------------- 어느 마을에 양치기 소년이 하나 있었는데, -------------- [1] 분리 길이 : 126 -------------- 늑대들이 나타나 양을 물어간다느니 잡아먹는다느니 식으로 수시로 장난삼아 소리치곤 했다. 두세 번 정도는 마을 사람들이 놀라 부리나케 달려왔다. 하지만 그 때마다 골탕을 먹고 바보가 된 기분으로 화를 내거나 투덜거리며 돌아갔다. -------------- [2] 분리 길이 : 206 -------------- 그러던 어느 날 진짜로 늑대가 나타나서 양들을 잡아먹거나 물어가기 시작했다. 양치기는 이번엔 절대로 거짓말이 아니고 진짜라면서 마을 사람들에게 도와 달라고 호소했으나, 마을 사람들은 이번에도 절대로 속지 않을 것이며, 설령 진짜로 늑대가 나타났다 한들 다 저 녀석의 업보라고 칠 것이라면서 한 명도 도와주러 오지 않았다. 결국 양치기는 그렇게 양떼를 모두 잃고 말았다. |
chunk_size 설정과 관계없이 분리자(separator) 단위로 분리하는 결과가 나왔다. 또한 chunk_overlap 설정도 무시하는 결과도 나왔다.
여러 chunk_size 로 테스트해 본 결과 아래와 같은 동작이 일어남을 파악했다.
(1) 일단 분리자로 각 패러그래프를 만듦
(2) 맨 마지막 패러그래프는 길이에 관계없이 절대 건들지 않음
(3) 나머지 패러그래프의 길이를 가지고 전후 패러그래프의 길이를 조사를 해서 길이의 합이 chunk_size 를 넘지 않는다면 합치고 넘는다면 두 패러그래프를 그대로 둚.
RecursiveCharacterTextSplitter
from langchain.text_splitter import RecursiveCharacterTextSplitter
story = '어느 마을에 양치기 소년이 하나 있었는데,\n 늑대들이 나타나 양을 물어간다느니 잡아먹는다느니 식으로 수시로 장난삼아 소리치곤 했다. 두세 번 정도는 마을 사람들이 놀라 부리나케 달려왔다. 하지만 그 때마다 골탕을 먹고 바보가 된 기분으로 화를 내거나 투덜거리며 돌아갔다.\n 그러던 어느 날 진짜로 늑대가 나타나서 양들을 잡아먹거나 물어가기 시작했다. 양치기는 이번엔 절대로 거짓말이 아니고 진짜라면서 마을 사람들에게 도와 달라고 호소했으나, 마을 사람들은 이번에도 절대로 속지 않을 것이며, 설령 진짜로 늑대가 나타났다 한들 다 저 녀석의 업보라고 칠 것이라면서 한 명도 도와주러 오지 않았다. 결국 양치기는 그렇게 양떼를 모두 잃고 말았다.'
text_splitter = RecursiveCharacterTextSplitter(
chunk_size = 100,
chunk_overlap = 20,
length_function = len,
)
chunks = text_splitter.split_text(text)
결과
문장길이 : 358 -------------- [0] 분리 길이 : 23 -------------- 어느 마을에 양치기 소년이 하나 있었는데, -------------- [1] 분리 길이 : 96 -------------- 늑대들이 나타나 양을 물어간다느니 잡아먹는다느니 식으로 수시로 장난삼아 소리치곤 했다. 두세 번 정도는 마을 사람들이 놀라 부리나케 달려왔다. 하지만 그 때마다 골탕을 먹고 -------------- [2] 분리 길이 : 46 -------------- 하지만 그 때마다 골탕을 먹고 바보가 된 기분으로 화를 내거나 투덜거리며 돌아갔다. -------------- [3] 분리 길이 : 96 -------------- 그러던 어느 날 진짜로 늑대가 나타나서 양들을 잡아먹거나 물어가기 시작했다. 양치기는 이번엔 절대로 거짓말이 아니고 진짜라면서 마을 사람들에게 도와 달라고 호소했으나, 마을 -------------- [4] 분리 길이 : 99 -------------- 도와 달라고 호소했으나, 마을 사람들은 이번에도 절대로 속지 않을 것이며, 설령 진짜로 늑대가 나타났다 한들 다 저 녀석의 업보라고 칠 것이라면서 한 명도 도와주러 오지 않았다. -------------- [5] 분리 길이 : 44 -------------- 한 명도 도와주러 오지 않았다. 결국 양치기는 그렇게 양떼를 모두 잃고 말았다. |
(1) 일단 분리자로 각 패러그래프를 만듦
(2) chunk_size 보다 짧은 패러그래프는 그대로 둠
(3) chunk_size 보다 긴 패러그래프를 대상으로 chunk_size 로 분리를 함
(4) 분리 대상인 긴 패러그래프에서 분리되는 2번째 문장부터는 앞의 문장으로부터 chunk_overlap 만큼 가져와서 합친다.
이상으로 부터 엄밀히 길이 단위로 문장을 분리하고자 한다면 RecursiveCharacterTextSplitter 가 적합하다.
'data science > python' 카테고리의 다른 글
numpy 조건에 맞는 값들만 뽑아내기 (0) | 2024.01.07 |
---|---|
list ( [ , ], [ , ] ... ) 최대, 최소값 구하기 (0) | 2024.01.07 |
2중 in 을 사용하여 리스트 만들기 (0) | 2024.01.06 |
(python) logging (1) | 2023.12.20 |
(python) PDF 내의 텍스트 추출하기 (0) | 2023.12.03 |