Expert System

인화·2025년 10월 18일

인공지능

목록 보기
3/6

전문가 시스템 (Expert System)

 전문가 시스템이란, 특정 분야 전문가의 지식을 모방하고, 이러한 지식을 컴퓨터 프로그램으로 구현한 것으로, 주어진 특정 문제를 해결하거나 조언을 제공하기 위해 사용된다.

 전문가 시스템은 특정 영역 전문가 수준의 문제 해결 능력을 지닌 컴퓨터 프로그램이며, 이를 위해 전문가의 지식을 "규칙"이라는 형태로 지식 베이스에 저장하고, 이 규칙들을 통해 추론을 수행한다. 이는 기존의 절차적 코드가 아닌 규칙으로 표현되는 지식을 통해 추론함으로써 복잡한 문제를 해결하도록 설계되었으며, 인공지능 소프트웨어 최초의 성공적 형태이다.

 이러한 전문가 시스템은 의료 진단, 주식 투자 조언, 기계 고장 진단 등에 활용된다.

 전문가 시스템은 전문가의 지식을 모방해 비전문가도 전문가 수준의 결정을 내릴 수 있고, 일관된 판단을 제공하며 지식의 확산과 보존이 용이하다는 장점이 있다. 또한, IF THEN을 사용하는 규칙은 인간 전문가의 지식을 표현하는 자연스러운 방식이며, 지식 베이스와 추론 엔진이 분리되므로 다른 영역에도 쉽게 적용할 수 있다.

 하지만, 복잡한 지식 베이스 작성이 필요하고, 전문가의 직관적인 판단을 완벽히 반영하기 어려우며, 환경 변화에 따른 지식 업데이트가 필요하다는 단점이 존재하기도 한다. 또한, 지식을 학습할 수 없고, 탐색이 비효율적이며, 규칙이 많아지면 유지보수가 어려워진다는 단점이 존재한다.


전문가 시스템의 구성 요소

  • 지식 베이스 (Knowledge Base) : 전문가의 지식을 규칙 형태로 저장하는 부분
    • 전문가의 지식을 저장하는 장소
    • 규칙, 사실, 전략 등 다양한 형태로 저장 가능함.
  • 추론 엔진 (Inference Engine) : 지식 베이스의 규칙들을 바탕으로 문제 해결을 위한 추론을 수행하는 부분
    • 지식 베이스의 정보를 활용해 실제 추론 및 결정을 내리는 장소
  • 사용자 인터페이스 : 사용자와 시스템 간의 상호작용을 위한 부분

지식 베이스 (Knowledge Base)

 지식 베이스는전문가의 지식과 경험을 형식화하여 저장한다. 이때, 지식의 획득은 전문가로부터 직접적인 인터뷰나 문서 분석을 통해 이뤄질 수 있고, 시간이 지나면서 바뀌는 지식 또는 새로운 정보는 업데이트가 필요하다.

구성 요소

  • 규칙 (Rules) : "만약 ~라면 ~하다"
    • 규칙은 생성 규칙(Production Rule)이라고도 한다.
    • 규칙에 AND, OR, 수학 연산자 등을 사용할 수 있다.
  • 팩트 (Facts) : 현재 상황이나 문제에 대한 정보, 사용자로부터 입력 받은 정보나 시스템이 이미 알고 있는 정보 등

지식 표현 방법

  • 생성 규칙 : if A then B, 특정 조건이 충족될 때 해당되는 동작이나 결정을 나타내는 형식
  • 술어 논리 : 객체나 객체 사이의 관계나 속성을 표현하는 술어
  • 의미망 : 개념과 개념 사이의 관계를 그래프 형식으로 나타낸 것으로 node는 개념, edge는 relationship
  • 프레임 : 관련 정보, 속성을 묶어서 표현하는 자료구조
  • 개념 그래프 : 지식의 의미적 관계를 그래프로 표현한 방법

추론 엔진 (Inference Engine)

 추론 엔진에서는 지식 베이스에 저장된 규칙과 팩트를 활용해 문제 해결을 위한 추론을 수행한다.

 추론 엔진은 지식 베이스의 지식을 활용해 추론 및 결정을 수행하는 모듈로, 두 가지 구성 요소로 구성된다.

  • 장기 기억 장치 : 전문가의 지식이 전략 형태로 저장되는 장소
  • 단기 기억 장치 : 현재 문제 상황에서 판단에 필요한 정보를 임시로 저장하는 공간

추론 방식

  • 정방향 추론 (Forward Chaining) : 현재 팩트들로부터 새로운 팩트를 도출해 나가는 방식으로, "이 사실들이 주어졌을 때 어떤 결론을 낼 수 있을까?"라는 방식으로 추론함.
    • 정방향 추론은 초기 상태에서 시작해 규칙을 적용함으로써 목표 상태에 도달하는 방식의 추론 방식으로, 사실들을 기반으로 규칙을 도출하고, 새로운 사실이나 목표를 도출하는 과정이다.
    • 주어진 사실을 기반으로 명확한 추론을 시작할 수 있고, 다양한 결과와 사실을 도출해 낼 수 있다는 장점이 있으나, 특정 목표를 향해 가지 않기에 불필요한 규칙 적용이 발생할 수도 있고, 이에 따라 추론 과정이 길어질 수 있다는 단점이 존재한다.
  • 역방향 추론 (Backward Chaining) : 원하는 결론을 설정하고, 그 결론을 만족시키는 팩트나 규칙을 찾아가는 방식으로 "이 결론을 내리려면 어떤 사실들이 필요할까?"라는 방식으로 추론함.
    • 역방향 추론은 목표 상태에서 시작해 이를 만족시키기 위한 규칙을 역으로 추적해 나가는 방식의 추론 방식을 의미한다. 다시 말해, 원하는 결과나 목표를 얻기 위해 필요한 조건이 무엇인지 찾아나가는 과정이다.
    • 명확한 목표를 가지고 추론을 수행하므로 효율적이고, 필요한 규칙만을 적용하므로 전체 추론 과정이 간결하다는 장점이 있으나, 초기 상태 정보가 부족하면 추론 시작조차 어렵고, 특정 목표에 대한 규칙이 없으면 추론이 불가능하다는 단점이 존재한다.

추론 엔진의 작동 순서

  1. 팩트 확인 : 사용자로부터 입력받은 정보나 이미 알고 있는 정보를 팩트로 간주함.
  2. 규칙 적용 : 해당 팩트에 적용 가능한 규칙을 찾아냄.
  3. 추론 수행 : 적용 가능한 규칙을 바탕으로 새로운 팩트나 결론을 도출함.

Code Example

# 지식 베이스와 추론 엔진이 어떻게 설계되는지
class ExpertSystem: # 추론 엔진
  def __init__(self):
    self.knowledge_base = KnowledgeBase() # 지식 베이스 객체 초기화

  # 진단 규칙을 평가하는 함수로, 규칙 조건이 사용자로부터 받은 증상과 일치하는지 검사
  # 만약 조건이 AND나 OR로 연결된 여러 개의 증상들로 구성되어 있다면, check_condition 함수는 자신을 재귀적으로 호출하여 각 하위 조건을 평가함.
  def check_condition(self, condition, selected_symptoms):
    # "condition" : "stomach_pain" 와 같이 단일 증상인지 확인
    if isinstance(condition, str): # condition이 문자열 인스턴스면
      return condition in selected_symptoms # 사용자가 입력한 증상이 conditiion에 포함되는지 확인

    op = condition.get("op") # 딕셔너리에서 op의 value만 추출
    if op == "AND":
      # "conds" : ["fever", "cough", "sore_throat"]과 같은 증상들
      # 증상이 모두 있어야 True
      return all(self.check_condition(sub_cond, selected_symptoms) for sub_cond in condition["conds"])
    elif op == "OR":
      # 증상 중 하나라도 있으면 True
      return any(self.check_condition(sub_cond, selected_symptoms) for sub_cond in condition["conds"])
  # 사용자로부터 입력받은 증상들을 바탕으로 check_condition 함수를 사용하여 가장 적합한 진단을 반환하는 함수
  # True/False 결과 받아서 규칙에 맞는지 확인하고, 맞으면 진단명과 설명 return
  def diagnose(self, selected_symptoms): # 증상에 따른 진단
    for rule in self.knowledge_base.rules: # 규칙 하나씩 꺼내보면서 (독감, 감기, 위염, 편두통 등)
      if self.check_condition(rule["condition"], selected_symptoms): # 사용자의 증상이 지식 베이스에 포함되는지 확인
        return rule["diagnosis"], rule.get("explanation", "") # 진단명과 설명 return
    return "No specific diagnosis.", "Consult a doctor." # 기본 답변 return

class KnowledgeBase: # 지식 베이스
  def __init__(self):
    # 질문 시에 활용할 거 (descriptions)
    # 다시 말해, 증상들의 간략한 설명을 담고 있는 딕셔너리로, 이를 통해 사용자에게 어떤 증상을 물어볼지 결정함.
    self.symptom_descriptions = {
        "fever" : "a fever",
        "cough" : "a cough",
        "sore_throat" : "a sore throat",
        "stomach_pain" : "stomach pain",
        "headache" : "a headache",
        "runny_nose" : "a runny nose",
        "itchy_eyes" : "itchy eyes"
    }

    # rule 정의 - 진단 규칙 (AND, OR 조건을 포함한 복잡한 진단 규칙을 모델링함)
    # 각 규칙은 특정 조건과 그 조건이 만족될 때의 진단, 설명으로 구성되며,
    # 조건은 단순히 하나의 증상을 기반으로 할 수도 있고, AND, OR 등 논리 연산자를 포함해 여러 증상의 조합을 기반으로 할 수도 있음.
    self.rules = [
        {
            "condition" : {"op": "AND", "conds" : ["fever", "cough", "sore_throat"]},
            "diagnosis" : "You might have the flu (당신은 독감일 수 있습니다.)",
            "explanation" : "Flu symptoms include fever, cough, and sore throat. (독감의 증상에는 발열, 기침, 목 아픔이 포함됩니다.)"
        },
        {
            "condition" : {"op" : "AND", "conds" : ["runny_nose", "sore_throat"]},
            "diagnosis" : "You might have a cold. (당신은 감기일 수 있습니다.)",
            "explanation" : "Cold symptoms include runny nose and sore throat. (감기의 증상에는 콧물과 목 아픔이 포함됩니다.)"
        },
        {
            "condition" : "stomach_pain",
            "diagnosis" : "You might have gastritis. (당신은 위염일 수 있습니다.)",
            "explanation" : "Pain in the stomach can be a sympotom of gastritis. (위의 통증은 위염의 증상일 수 있습니다.)"
        },
        {
            "condition" : "headache",
            "diagnosis" : "You might have a migraine. (당신은 편두통일 수 있습니다.)",
            "explanation" : "A servere headache can be a symptom of migraine. (심한 두통은 편두통의 증상일 수 있습니다.)"
        },
        {
            "condition" : "itchy_eyes",
            "diagnosis" : "You might have an allergy. (당신은 알레르기일 수 있습니다.)",
            "explanation" : "Itchy eyes can be a symptom of an allergy. (눈이 가렵다면 알레르기의 증상일 수 있습니다.)"
        }
    ]

# 사용자에게 각 증상에 대해 직접 물어보고, 사용자의 응답을 바탕으로 선택된 증상들의 리스트를 반환
# 'yes'로 응답한 증상만 반환 리스트에 포함
def get_symptoms_from_user():
  symptom_descriptions = KnowledgeBase().symptom_descriptions
  selected_symptoms = []

  print("Please answer the following (yes or no):")
  for symptom, description in symptom_descriptions.items():
    answer = input(f"Do you have {description}? ").lower()
    if answer == 'yes':
      selected_symptoms.append(symptom)
  return selected_symptoms

if __name__ == "__main__":
  selected_symptoms = get_symptoms_from_user() # 사용자가 증상 선택
  system = ExpertSystem()
  diagnosis, explanation = system.diagnose(selected_symptoms) # 진단 (진단명, 설명 or 기본 답변 return)
  print(diagnosis)
  print(explanation)
profile
얼렁뚱땅 바보 학부생...

0개의 댓글