현제의 현재이야기
[OSOD] 출시와 보완 기록 본문
문법 CHECK 기능
원래 계획에는 있었으나 무산되었었던 문법 기능을 추가해보았다. open ai api를 사용해서 최소한의 토큰으로 문법 검사를 해주는 코드를 짜보았다.
class GrammarCheckView(APIView):
def post(self, request):
openai.api_key = ''
text = request.data.get('text')
if not text:
return Response({'response': "", 'ai': "검사할 문장이 없어요!", 'original': "", 'bool': False}, status=status.HTTP_400_BAD_REQUEST)
response = openai.Completion.create(
model="text-davinci-003",
prompt=f"'{text}' correct if grammar wrong. don't contain \" ",
temperature=0,
max_tokens=60,
top_p=1.0,
frequency_penalty=0.0,
presence_penalty=0.0
)
target_res = response.choices[0].text.strip()
if target_res[0] == "\"":
cut_target = target_res.strip("\"")
if text == cut_target:
res = cut_target
ai = grammar_correct_response()
bool = True
else:
res = cut_target
ai = grammar_wrong_response()
bool = False
else:
if text == target_res:
res = target_res
ai = grammar_correct_response()
bool = True
else:
res = target_res
ai = grammar_wrong_response()
bool = False
- 자꾸만 띄어쓰기를 사용하길래 don't contain을 하라고 했으나 .. 그럼에도 불구하고 가끔씩 띄어쓰기를 하길래
- 아예 첫 글자가 \n, 즉 띄어쓰기면 없애버리고 기존 text와 비교를 하였다.
- 기본 로직은 처음 넣은 문장과 바꾼 문장이 같다면 문법 이상이 없는거고, 바꾼 것이 있다면 틀린 것으로 출력했다.
def grammar_wrong_response():
a = random.randrange(0,4)
first = ['이런건 어때요?', '제가 한번 제안할게요!', '이게 더 자연스러울 수도 있어요!', '이게 더 나을 수도 있어요!', '이렇게 작문할 수도 있어요!']
return f"{first[a]}"
def grammar_correct_response():
a = random.randrange(0,4)
first = ['완벽해요!', '틀린게 없는 문장이에요!', '너무 좋은걸요?', '완벽한 문장이에요!!', '굉장히 좋은 문장이에요!']
return f"{first[a]}"
- 응답도 하나만 하면 재미없어서 이렇게 랜덤함수로 돌려서 반응으 뱉게 하였다.
- 최소한의 토큰을 사용한 로직이기 때문에 가끔 이상하게 구문이 아닌 단어를 추천해주지만.. 무료 api 허용량이 생각보다 적어서 이렇게가 최선일 것 같다.
구문 검사
원래 프론트 단에서 in 검사로 들어있는지 없는지만 검사했으나.. 세상에는 많은 변형이 있기에 자연어처리 라이브러리를 썼다.
def is_pattern_used(sentence, pattern):
sentence = sentence.replace("'ve", " have").replace("'ll", " will").replace("n't", " not").replace("re", " are")
pattern = pattern.replace("'ve", " have").replace("'ll", " will").replace("n't", " not").replace("re", " are")
nlp = spacy.load("en_core_web_sm")
pattern_doc = nlp(pattern.lower())
for doc in pattern_doc:
if doc.lemma_ == "will":
sentence = sentence.replace("'d", " would")
elif doc.lemma_ == "have":
sentence = sentence.replace("'d", " had").replace("'s", " has")
sentence_doc = nlp(sentence.lower())
new_sentence = " ".join([token.lemma_ if token.pos_ == "AUX" or token.pos_ == "VERB" else token.text for token in sentence_doc])
new_pattern = " ".join([token.lemma_ if token.pos_ == "AUX" or token.pos_ == "VERB" else token.text for token in pattern_doc])
if new_pattern in new_sentence:
return True
else:
return False
print(is_pattern_used("She's good at him", "has good at"))
- 기본 로직은 우선 축약어는 다 원형으로 바꿨다.
- 'd 는 would가 될 수 있고 had가 될 수있기 때문에 일단을 저렇게 처리했다.
- 그리고 조동사나 동사면 모두 원형으로 바꾸고 in을 하였다.
nlp = spacy.load("en_core_web_sm")
patterns = {"'ve": " have", "'ll": " will", "n't": " not", "'re": " are"}
def is_pattern_used(sentence, pattern):
for old, new in patterns.items():
sentence = sentence.replace(old, new)
pattern = pattern.replace(old, new)
pattern_doc = nlp(pattern.lower())
for doc in pattern_doc:
if doc.lemma_ == "will":
sentence = sentence.replace("'d", " would")
elif doc.lemma_ == "have":
sentence = sentence.replace("'d", " had").replace("'s", " has")
sentence_doc = nlp(sentence.lower())
# Use a generator expression instead of a list comprehension
new_sentence = " ".join(token.lemma_ if token.pos_ in {"AUX", "VERB"} else token.text for token in sentence_doc)
new_pattern = " ".join(token.lemma_ if token.pos_ in {"AUX", "VERB"} else token.text for token in pattern_doc)
return new_pattern in new_sentence
- 검사하는데 시간이 너무 오래 걸려서 최적화를 하였다.
- one's는 어떻게 처리하지...?
'DRF > OSOD' 카테고리의 다른 글
2006, 'MySQL server has gone away' 해결 기록 (0) | 2023.04.28 |
---|---|
[OSOD] 자동 메일 api, Apscheduler (0) | 2023.04.09 |
[OSOD] 닉네임 중복 검사, Password Reset template (0) | 2023.03.07 |
[OSOD] Django Rest Framework + React Google social login (1) | 2023.03.05 |
[OSOD] Non-serializer (0) | 2023.02.20 |
Comments