1.0.0 • Published 5 years ago

tetrapod v1.0.0

Weekly downloads
84
License
MIT
Repository
-
Last release
5 years ago

Tetrapod.js

Tetrapod.js 는 변형된 비속어 단어 표현들을 파악하고 탐지하기 위해 개발 되고 있는 모듈형 프로그램입니다. 한국어에서 존재하는 비속어 단어들을 우선적으로 탐지 대상으로 정하여 개발되고 있으며, 향후 모든 언어에서 변형된 비속어 표현을 탐지하는데 사용될 수 있습니다.

현재 초기 개발 진행 중에 있는 프로젝트입니다.

프로젝트 목표

대체로 분위기가 좋지 않으면, 언어 또한 그렇게 된다. (When the general atmosphere is bad, language must suffer)

인터넷 상에서 다수가 모여서 대화 중 분위기가 나빠지거나 사회 내 분위기가 나쁘게 되면, 이에따라 사람들이 사용하는 언어 또한 과격하게 되거나 비속어나 저속한 단어를 섞어 사용하는 사람들이 등장하게 됩니다. 이러한 상황의 근본적 원인은 사회적 문제일 수도, 개인적 문제일 수도 있습니다. 이러한 표현은 당사자의 감정을 담고 있으며 이를 본 사람들 또한 감정이 상하게 되는 경우가 생깁니다.

생각이 언어를 오염시킨다면, 언어 역시 생각을 오염시킬 수 있다. (If thought corrupts language, language can also corrupt thought.)

언어는 감정을 실을 수 있는 매개체로써, 어떠한 언어적 표현을 보고 기분이 나쁘게 만드는 것 뿐만 아니라, 어떠한 감정을 전달하기 위한 목적만을 위해서 사회적으로 개인 또는 집단에 의해서 모두가 사용하는 언어가 변형될 수 있습니다. 그렇게 언어에 담기는 감정에는 성적인 감정이 담길 수도, 폭력적인 감정이 담길 수도 있으며 그 유형은 매우 다양합니다.

한국어는 자음과 모음을 모아서 쓸 수 있는 모아쓰기가 가능한 점에서 기존 다른 언어권과는 다르게 어떠한 단어가 변형되어 생길 수 있는 파생단어가 생기기 매우 쉬우며 변형된 단어를 기계적으로 탐지하기 매우 어려운 구조를 갖추고 있습니다.

자신이 쓰는 언어를 간결하게 한다면, 가장 어리석은 통설로부터 자유로워질 수 있다. 불필요한 관용어를 쓸 수 없으며, 어리석은 표현을 쓰면 그 어리석음이 스스로에게도 분명히 드러나 보이게 된다. (If you simplify your English, you are freed from the worst follies of orthodoxy. You cannot speak any of the necessary dialects, and when you make a stupid remark its stupidity will be obvious, even to yourself.)

이 프로젝트의 목표는 인터넷 상에서 범람하는 비속어가 무분별하게 퍼지는 것을 방지할 수 있는 어떠한 방파제와 같은 모듈을 개발하는 것입니다. 많은 곳에서 사용되는 것을 목적으로 하기에 이 프로젝트 구성은 Copyleft 로 구성되며 유무상을 가리지 않고 무료로 자유로운 사용이 가능하게끔 배포되는 것을 목적으로 합니다.

라이센스

MIT Licensed

기존 비속어 탐지 체계의 한계

기존의 필터링은 문장 단위로 비속어 문자가 문자열 상에 존재하는지 만을 확인합니다. 가령 바보 라는 비속어를 차단하려 할때 이용자가 안녕 바보야 라는 메세지를 입력했다면, 바보라는 문장이 존재하는 경우와 같이, 변형되지 않은 욕설이 존재하는 메시지에 한해서만 탐지가 가능합니다. 그러나 아래와 같은 변형에 대해서는 대처하지 못합니다.

  • 문자 사이사이에 불규칙한 글자를 섞었을 때
    • 안녕 바111보야, 안녕 바아아아보야
  • 발음 상 또는 모양 상 유사한 표현으로 대체한 경우
    • 안녕 빠아뽀오야!, 안녕 ba보야!
  • 한글 받침 등 특수한 조합을 이용해 변형한 비속어의 경우
    • 값삾핪닚닶
  • 문자를 일부 뒤집어서 표현한경우
    • 제발 좀 입 닥쳐! => 제발 좀 입 쳐닥!

또한 비속어를 일부 포함하고 있지만 정상적으로 쓰일 수 있는 단어들이 존재하여 일부 표현을 오탐지할 확률을 높이기도 합니다.

  • 한자 발음상 동일한 단어이나 뜻이 다른 표현이 일부 더해져 있는 경우
    • 그 사건의 시발점은 A씨였다.

Tetrapod.js 은 이러한 비속어 탐지 알고리즘의 한계를 극복하기위해서, 정상단어를 먼저 찾아서 탐지 범위에서 배제한다음, 비속어 단어를 한 글자 씩 존재여부를 파악합니다. 또한 한국어 욕설을 수집하고 해당 욕설의 변형유형을 음운, 음절, 어절 3단계에 걸쳐서 가능한 모든 변형가능한 형태를 파악합니다.

프로젝트 상 탐지 알고리즘 구성

Tetrapod.js 에서 사용하는 비속어 탐지 알고리즘의 구성은 다음과 같습니다.

정상단어 목록 구성

  • 시발점과 같은 단어의 오탐지를 막기 위해서 사전에 문자열에서 찾아서 비속어 탐지시 탐지대상에서 제외시킬 용도의 정상단어 목록을 구성합니다.

비속어단어 목록 구성

  • 여러 비속어 단어의 변형을 모두 파악하기 위해서, 음운, 음절, 어절 3단계에 걸쳐서 각 글자 요소들의 변형을 모두 파악하여서 비속어 단어 목록을 구성합니다. 해당 내용은 하단에 Bias 구성란 에서 자세히 설명합니다.

프로젝트 상 탐지 알고리즘 구성

Tetrapod.js 에서 사용하는 비속어 탐지 알고리즘의 진행과정은 다음과 같습니다.

정상 단어 탐색 후 배제

  • 메시지에서 정상단어를 찾아서 해당 문자열의 시작 위치와 끝나는 위치를 기록합니다. 해당 문자열 범위는 이후 알고리즘 탐지시 범위에서 배제됩니다.

메시지의 15자단위 분리

  • 모든 문자열은 15자 단위의 청크 메시지 로 분리됩니다.

한 글자씩 비속어 단어 탐색

  • 갖추고 있는 모든 비속어 문자를 글자단위로 모두 분리합니다. 그 후 청크 메시지에 해당 비속어 문자의 글자가 존재하는지, 몇번째 위치에 존재하는지를 파악합니다.
  • 만약 문자들이 모두 존재할 경우 해당 문자들의 위치를 해당 비속어 단어의 글자순서대로 정렬합니다. 이때 만약 순서가 일관되지 않다면 글자가 섞여있는 것으로 간주합니다.
  • 만약 글자가 섞여있는 경우 비속어 단어의 사이에 완성된 한글 문자가 존재하는지를 확인하고 존재한다면 이를 비속어 목록에서 제외합니다. (, 는 완성된 한글이 아니며 완성된 한글은 유니코드로 (0xAC00) ~ (0xD7A3) 사이의 글자를 뜻합니다.) 또한 완성형 글자이더라도 자음이 인경우에는 비속어 예외처리를 하지 않습니다. 예: 바아아보오 와 같이 이어주는 음의 경우 비속어 처리가 필요합니다.

Bias 데이터 포멧

  • 비속어 단어는 음운마다 발음이 약간씩 달라지거나 모양이 약간씩 달라지는 변형 단어가 파생될 수 있으므로, 각 음운별로 모든 변형 가능한 조합을 알아내야할 필요가 있습니다. 이를 명확하게 파악하기 위해서 모든 음운과 음절, 어절에 쓰일 수 있는 구조를 1차원 배열 또는 2차원 배열로 표현하여서 변형구조를 어절단계에서 파악할 수 있는 어떠한 데이터 구조가 필요합니다. 이를 위해서 개발된 데이터 구조가 Bias 데이터 포멧입니다.

RecursiveList

  • Bias 데이터 포멧은 필터에 사용될 비속어를 2차원 배열을 중첩해나가면서 조합될 단어의 목록을 구성할 수 있게 돕습니다. 2차원 배열은 before+after 구조로, 각 차원 데이터가 합쳐져서 단어를 구성하게 됩니다. 이를 RecursiveList 라고 하며 다음과 같은 예시형태로 구성될 수 있습니다.
2차원 배열 예시
let data = [[
    "바",
    "ba"
],[
    "보",
    "bo"
]]
let result = Bias.recursiveList(data)
let resultCheck = [
    "바보",
    "바bo",
    "ba보",
    "babo"
]
console.log(result == resultCheck)
// true
중첩된 2차원 배열 예시

RecursiveList 로는 자음과 모음의 변형과정을 세분화해서 명시하는데 적합한 구조를 갖추고 있습니다. 하지만 자음 모음을 합성해서 완성된 한글문자로 합친다던지, 자음과 모음을 재활용할 수 있는 어떠한 구조는 RecursiveComponent 에서 다룹니다.

let data = [[
    [[
        'ㅂ',
        'ㅃ'
    ],[
        'ㅏ',
        'ㅑ'
    ]],
    "ba"
],[
    "보",
    "bo"
]]
let result = Bias.recursiveList(data)
let resultCheck = [
    "ㅂㅏ보",
    "ㅂㅑ보",
    "ㅃㅏ보",
    "ㅃㅑ보",
    "ㅂㅏbo",
    "ㅂㅑbo",
    "ㅃㅏbo",
    "ㅃㅑbo",
    "ba보",
    "babo"
]
console.log(result == resultCheck)
// true

RecursiveComponent

RecursiveComponent 는 RecursiveList 의 재사용성을 높이고 배열 상에서 사용가능한 부가적인 함수개념을 제공합니다.

변수 및 코드 분리

RecursiveComponent 는 변수코드가 존재하며, 자음과 모음 같이 한글문자의 최소 단위인 음운 을 RecursiveList 로 표현할 때 재활용성을 높이기 위해서 변수를 사용하며, 해당 음운들로 어떠한 최종적인 음절을 구성할 때 코드 를 구성합니다.

자유로운 JSON 파일구성

RecursiveComponent 를 구성할 때 한국어의 경우 음운, 음절, 어절 의 형태로 구성될 수 있지만, 향후 개발 과정에서 새로운구조가 필요하거나, 차후 다른 언어에 확장형태로 다른 구조를 취해야할 가능성이 있기에, 보다 유연하게 데이터를 분리해야할 필요가 있습니다. 이를 위해서 JSON 형태로 데이터를 표현할 수 있게 허용하고 있으며, JSON 데이터는 해당 소스폴더 안에만 있다면 내부에 얼마나 중첩된 폴더아래에 JSON파일이 존재하던, 어떤 이름으로 폴더가 존재하던, 어떤 이름으로 JSON 파일이 존재하던 이를 모두 수집해서 구성할 수 있게끔 RecursiveComponent 를 구성하였고, 이를 통해서 자유롭게 데이터 명칭 부여를 하고 자유로운 데이터 카테고리 부여가 가능합니다.

JSON내에서의 변수 구성 예

JSON 에서 객체를 하나 생성후 그 안에 var 라는 이름의 객체를 하나 담으면, 그 var 객체 안에 변수를 생성할 수 있습니다. 한국어 데이터의 경우엔 이를 통해서 음운 데이터를 구성하며, 이 과정에서 한 음운발음변형모양변형 데이터를 RecursiveComponent 로 모두 구성합니다. 이렇게 구성된 의 음운 데이터화 예시는 다음과 같습니다.

{
    "var": {
        "ㅂ_발음변형": [
            "ㅂ",
            "ㅃ",
            "ㅍ"
        ],
        "ㅂ_모양변형": [
            "ㅂ",
            "ㅃ",
            "ㅍ",
            "b",
            "f"
        ]
    }
}
JSON내에서 변수 간 참조

JSON 형태로 Bias 데이터를 구성할 때 변수를 구성할 수 있는데, 이 변수 내에서 다른 변수를 써야하는 상황이 생길 수 있습니다. 한국어는 주로 음절 데이터 구성시 음운 변수를 불러와야함과 동시에 자신도 변수여야하는 상황이 발생하는데, 이런 상황을 위해서 변수가 변수를 참조할 수 있도록 구성되어 있습니다. 변수는 RecursiveList 를 사용할때 요소 앞에 *를 붙여서 사용하면 해당 위치에 변수 데이터가 참조됩니다. 음절 데이터 구성 시

변수간 참조 및 함수 사용 예시
{
    "var": {
        "시": [
            {
                "type": "단어병합",
                "data": [[
                    "*ㅅ_모양변형"
                ], [
                    ""
                ]]
            },

            {
                "type": "자모합성",
                "data": [
                    [
                        "ㅅ",
                        "ㅆ"
                    ], [
                        "*ㅣ_발음변형"
                    ]
                ],
                "exclude": ["쇠"]
            }
        ]
    }
}

해당 비속어 탐지 체계의 한계

해당 프로젝트는 문맥을 이해하고 문맥상에서 어떠한 단어가 부적절한 의도로 사용되었는지, 표현의도 를 판단하지는 못합니다.

  • 단어상 동음이의어로 표현 상 구별점이 존재하지 않는 경우
    • 2016년 병신년(丙申年)에는 이러한 일이 있었습니다.
  • 정상단어를 의도가 불순하게 사용하는 경우
    • 너는 어머니가 없구나
  • 비속어로 오해가능한 정상단어를 의도가 불순하게 사용하는 경우
    • 너가 시발점이야 이 시발점아!

개발 목표

  • 국립국어원에서의 한국어 정상 단어 목록 확보
  • 인터넷 상에서 쓰이는 비속어 데이터 1차 수집
  • 문자열 상에서 정상단어를 찾아서 모든 정상단어 위치를 파악하는 알고리즘
  • 글자단위 비속어 단어 탐지 알고리즘
  • 뒤집히거나 뒤섞인 비속어 단어 표현의 경우 사람이 인지 가능한 수준만을 비속어로 선정해서 차단하는 알고리즘 추가
  • 비속어단어 만을 삭제하거나 특정 특수문자로 대치하는 표현 정정 함수
  • 비속어 단어의 변형 예를 음운, 음절, 어절 3단계로 나누어서 정리해나갈 수 있는 분할된 JSON 기반 파일 데이터 병합 체계
  • 배열형태로 단어를 전/후 값으로 나눠서 구성할 수 있는 Bias 데이터 포멧 (예: 바를 ㅂ/ㅏ 로 나누어서 표현할 수 있게 하는 체계를 뜻합니다.)
  • n차원 형태로 중첩시킬 수 있는 Bias 데이터 포멧 구성 (바/보 라는 단어의 변형 예를 모두 구할때, 별도로 존재하는 ㅂ/ㅏㅂ/ㅗ 데이터를 연결시켜서 구성시킬 수 있는 체계를 뜻합니다.)
  • n차원의 데이터를 병합할 수 있는 Bias 데이터 포멧
  • Bias 데이터 포멧에서의 음절 변수
  • Bias 데이터 포멧에서의 응용 함수
  • Bias 데이터 포멧에서의 자모합성 함수
  • Bias 데이터 포멧에서의 결과배제 함수
  • Bias 데이터 포멧에서 테스트 중 중복생선된 단어 탐지 및 삭제 필터
  • 1차 수집된 비속어 데이터의 Bias 재해석
  • LZString 을 통한 Bias 데이터의 minify 화 및 압축 추출 및 메모리 로드 체계
  • 전체 비속어 단어 목록을 사전에 저장하는 형태가 아닌, 비속어 단어 탐지가 발생할때 해당 단어 목록을 실시간으로 구성하여서 쓰다가, 이를 메모리상에 LRU 캐싱 해놓고 씀으로 전체 데이터 용량을 줄이는 동적인 Bias 데이터 해석 체계
  • 청크 메시지의 15자->30자 확대 및, 청크 메시지가 연속될 경우, 중간의 15자끼리 이어서 새로운 청크메시지를 임의로 만들어서 검사를 돌리는 보완체계 (청크 메시지 사이에 걸려서 필터링 되지 않는 예외 상황 해결)
  • 청크 메시지에서 비속어 단어의 글자가 메시지 상에 있는지 확인할 때 중첩적으로 존재하는 글자가 존재하는 경우, 이를 모두 수집한 후 모든 경우수를 다 계산해서 비속어 검산하는 알고리즘 구현
  • 검색엔진 기반 웹 크롤링을 통한 비속어 탐지시도 및 변형단어 수집시도
  • 테스트 페이지 및 테스트 서버 구성
  • gpu.js 쉐이더 기반의 GPU 병렬 연산 가속화 구현 (모든 청크메시지를 숫자 배열화 한 후 코어단에 이를 공유된 메모리 형태로 전달하고, 숫자 배열화 된 비속어 문자들을 코어에게 전달하면 이를 모든 코어 하나하나가 각각의 숫자배열 일치 유무를 파악하는 구조)
1.0.0

5 years ago

0.0.4

9 years ago

0.0.3

9 years ago

0.0.2

9 years ago