자습서: ML.NET 모델 작성기를 사용하여 웹 애플리케이션에서 웹 사이트 댓글 감정 분석

웹 애플리케이션에서 실시간으로 댓글의 감정을 분석하는 방법에 대해 알아봅니다.

이 자습서에서는 실시간으로 웹 사이트 댓글에서 감정을 분류하는 ASP.NET Core Razor Pages 애플리케이션을 만드는 방법을 보여 줍니다.

이 자습서에서는 다음과 같은 작업을 수행하는 방법을 살펴봅니다.

  • ASP.NET Core Razor Pages 애플리케이션 만들기
  • 데이터 준비 및 이해
  • 시나리오 선택
  • 데이터 로드
  • 모델 학습
  • 모델 평가
  • 예측에 모델 사용

dotnet/samples 리포지토리에서 이 자습서의 소스 코드를 찾을 수 있습니다.

필수 구성 요소

필수 구성 요소 및 설치 지침 목록을 보려면 모델 작성기 설치 가이드를 방문하세요.

Razor Pages 애플리케이션 만들기

ASP.NET Core Razor Pages 애플리케이션을 만듭니다.

  1. Visual Studio에서 새 프로젝트 만들기 대화 상자를 엽니다.
  2. "새 프로젝트 만들기" 대화 상자에서 ASP.NET Core Web App 프로젝트 템플릿을 선택합니다.
  3. 이름 텍스트 상자에 "SentimentRazor"를 입력하고 다음 단추를 선택합니다.
  4. 추가 정보 대화 상자에서 모든 기본값을 그대로 두고 만들기 단추를 선택합니다.

데이터 준비 및 이해

Wikipedia detox 데이터 세트를 다운로드합니다. 웹 페이지가 열리면 페이지를 마우스 오른쪽 단추로 클릭하고 다른 이름으로 저장을 선택하여 컴퓨터의 아무 위치에 파일을 저장합니다.

wikipedia-detox-250-line-data.tsv 데이터 세트의 각 행은 사용자가 Wikipedia에 남긴 다른 검토를 나타냅니다. 첫 번째 열은 텍스트의 감정(0은 무해, 1은 유해)를 나타내고, 두 번째 열은 사용자가 남긴 댓글을 나타냅니다. 열은 탭으로 구분됩니다. 데이터는 다음과 같습니다.

감정 SentimentText
1 ==RUDE== Dude, you are rude upload that carl picture back, or else.
1 == OK! == 메신저가 와일드 원스 위키를 기물 파손하려고 합니다!!!
0 I hope this helps.

Model Builder 구성 파일 만들기

먼저 솔루션에 기계 학습 모델을 추가하면 파일을 만들 mbconfig 라는 메시지가 표시됩니다. mbconfig 파일은 세션을 다시 열 수 있도록 Model Builder에서 사용자가 수행하는 모든 작업을 추적합니다.

  1. 솔루션 탐색기에서 SentimentRazor 프로젝트를 마우스 오른쪽 단추로 클릭하고 추가>Machine Learning Model... 을 선택합니다.
  2. 대화 상자에서 Model Builder 프로젝트 SentimentAnalysis.mbconfig의 이름을 지정하고 추가를 선택합니다.

시나리오 선택

모델 작성기 시나리오 화면

모델을 학습하려면 모델 작성기에서 제공하는 사용 가능한 기계 학습 시나리오 목록에서 선택해야 합니다.

이 샘플의 경우 작업은 텍스트 분류입니다. 모델 작성기 확장의 시나리오 단계에서 텍스트 분류 시나리오를 선택합니다.

환경 선택

Model Builder는 선택한 시나리오에 따라 다양한 환경에서 학습할 수 있습니다.

환경으로 로컬(GPU)을 선택하고 다음 단계 단추를 클릭합니다.

참고

이 시나리오에서는 GPU 환경에서 가장 잘 작동하는 딥 러닝 기술을 사용합니다. GPU가 없는 경우 로컬(CPU) 환경을 선택하지만 학습 시간이 상당히 길어질 것으로 예상됩니다. 모델 작성기에서 GPU를 사용하는 방법에 대한 자세한 내용은 Model Builder의 GPU 지원 가이드를 참조하세요.

데이터 로드

모델 작성기는 SQL Server 데이터베이스 또는 로컬 파일 csv 또는 tsv 형식의 두 가지 소스에서 데이터를 허용합니다.

  1. 모델 작성기 도구의 데이터 단계에서 데이터 원본 옵션에서 파일을 선택합니다.
  2. 파일 선택 텍스트 상자 옆의 있는 단추를 선택하고 파일 탐색기를 사용하여 wikipedia-detox-250-line-data.tsv 파일을 선택합니다.
  3. 열에서 감정을 선택하여 예측(레이블) 드롭다운을 선택합니다 .
  4. 텍스트 열 드롭다운에서 SentimentText를 선택합니다.
  5. 다음 단계 단추를 선택하여 모델 작성기의 다음 단계로 이동합니다.

모델 학습

이 자습서에서 감정 분석 모델을 학습시키는 데 사용되는 기계 학습 작업은 텍스트 분류입니다. 모델 학습 프로세스 중에 Model Builder는 NAS-BERT 신경망 아키텍처를 사용하여 데이터 세트에 대한 텍스트 분류 모델을 학습합니다.

  1. 학습 시작을 선택합니다.

  2. 학습이 완료되면 학습 프로세스의 결과가 학습 화면의 학습 결과 섹션에 표시됩니다. 학습 결과를 제공하는 것 외에도 SentimentAnalysis.mbconfig 파일 아래에 세 개의 코드 숨김 파일이 만들어집니다.

    • SentimentAnalysis.consumption.cs - 이 파일에는 ModelInput 모델 사용을 위해 생성된 함수뿐만 Predict 아니라 및 ModelOutput 스키마도 포함됩니다.
    • SentimentAnalysis.training.cs - 이 파일에는 모델 작성기에서 모델을 학습시키기 위해 선택한 학습 파이프라인(데이터 변환, 트레이너, 트레이너 하이퍼 매개 변수)이 포함되어 있습니다. 이 파이프라인을 사용하여 모델을 다시 학습시킬 수 있습니다.
    • *SentimentAnalysis.zip - 학습된 ML.NET 모델을 나타내는 직렬화된 zip 파일입니다.
  3. 다음 단계 단추를 선택하여 다음 단계로 이동합니다.

모델 평가

학습 단계의 결과는 최상의 성능을 가진 하나의 모델이 됩니다. 모델 작성기 도구의 평가 단계에서 출력 섹션에는 에서 가장 성능이 뛰어난 모델에서 사용하는 트레이너와 평가 메트릭이 포함됩니다.

평가 메트릭에 만족하지 않는 경우 모델 성능을 개선하기 위한 몇 가지 쉬운 방법은 더 많은 데이터를 사용하는 것입니다.

그렇지 않으면 다음 단계 단추를 선택하여 모델 작성기의 사용 단계로 이동합니다.

소비 프로젝트 템플릿 추가(선택 사항)

사용 단계에서 Model Builder는 모델을 사용하는 데 사용할 수 있는 프로젝트 템플릿을 제공합니다. 이 단계는 선택 사항이며 모델 사용에 가장 적합한 방법을 선택할 수 있습니다.

  • 콘솔 애플리케이션
  • Web API

코드를 추가하여 예측하기

PredictionEngine 풀 구성

단일 예측을 수행하려면 PredictionEngine<TSrc,TDst>을 만들어야 합니다. PredictionEngine<TSrc,TDst>는 스레드로부터 안전하지 않습니다. 또한 애플리케이션 내에서 필요한 모든 위치에서 인스턴스를 만들어야 합니다. 애플리케이션이 커지면 이 프로세스를 관리할 수 없게 됩니다. 성능 및 스레드 보안을 개선하려면 종속성 주입과 PredictionEnginePool 서비스를 함께 사용합니다. 이 서비스는 애플리케이션 전체에서 사용할 PredictionEngine<TSrc,TDst> 개체의 ObjectPool<T>을 만듭니다.

  1. Microsoft.Extensions.ML NuGet 패키지를 설치합니다.

    1. 솔루션 탐색기에서 프로젝트를 마우스 오른쪽 단추로 클릭하고 NuGet 패키지 관리를 선택합니다.
    2. 패키지 원본으로 "nuget.org"를 선택합니다.
    3. 찾아보기 탭을 선택하고 Microsoft.Extensions.ML을 검색합니다.
    4. 목록에서 패키지를 선택하고 설치 단추를 선택합니다.
    5. 변경 내용 미리 보기 대화 상자에서 확인 단추를 선택합니다.
    6. 나열된 패키지 라이선스 조건에 동의하면 라이선스 수락 대화 상자에서 동의함 단추를 선택합니다.
  2. SentimentRazor 프로젝트에서 Program.cs 파일을 엽니다.

  3. Microsoft.Extensions.ML NuGet 패키지 및 SentimentRazorML.Model 프로젝트를 참조하도록 다음 using 문을 추가합니다.

    using Microsoft.Extensions.ML;
    using static SentimentRazor.SentimentAnalysis;
    
  4. PredictionEnginePool<TData,TPrediction>Program.cs 파일에서 애플리케이션에 대한 을 구성합니다.

    builder.Services.AddPredictionEnginePool<ModelInput, ModelOutput>()
        .FromFile("SentimentAnalysis.zip");
    

감정 분석 처리기 만들기

예측은 애플리케이션의 기본 페이지에서 수행됩니다. 따라서 사용자 입력을 취하고 PredictionEnginePool<TData,TPrediction>을 사용하여 예측을 반환하는 메서드를 추가해야 합니다.

  1. Pages 디렉터리에 있는 Index.cshtml.cs 파일을 열고 다음 using 문을 추가합니다.

    using Microsoft.Extensions.ML;
    using static SentimentRazor.SentimentAnalysis;
    

    Program.cs 파일에 구성된 를 사용 PredictionEnginePool<TData,TPrediction> 하려면 사용하려는 모델의 생성자에 삽입해야 합니다.

  2. Pages/Index.cshtml.cs 파일 내의 IndexModel 클래스 내에서 를 참조 PredictionEnginePool<TData,TPrediction> 하는 변수를 추가합니다.

    private readonly PredictionEnginePool<ModelInput, ModelOutput> _predictionEnginePool;
    
  3. 클래스에서 생성자를 IndexModel 수정하고 해당 클래스에 PredictionEnginePool<TData,TPrediction> 서비스를 삽입합니다.

    public IndexModel(ILogger<IndexModel> logger, PredictionEnginePool<ModelInput, ModelOutput> predictionEnginePool)
    {
        _logger = logger;
        _predictionEnginePool = predictionEnginePool;
    }
    
  4. PredictionEnginePool을 사용하여 웹 페이지에서 받은 사용자 입력으로부터 예측을 수행하는 메서드 처리기를 만듭니다.

    1. OnGet 메서드 아래 OnGetAnalyzeSentiment라는 새 메서드를 만듭니다.

      public IActionResult OnGetAnalyzeSentiment([FromQuery] string text)
      {
      
      }
      
    2. 사용자의 입력이 비어 있거나 null인 경우 OnGetAnalyzeSentiment 메서드 내에서 중립 감정을 반환합니다.

      if (String.IsNullOrEmpty(text)) return Content("Neutral");
      
    3. 입력이 유효할 경우 ModelInput의 새 인스턴스를 만듭니다.

      var input = new ModelInput { SentimentText = text };
      
    4. PredictionEnginePool<TData,TPrediction>을 사용하여 감정을 예측합니다.

      var prediction = _predictionEnginePool.Predict(input);
      
    5. 다음 코드를 사용하여 예측된 bool 값을 유해 또는 무해로 변환합니다.

      var sentiment = Convert.ToBoolean(prediction.PredictedLabel) ? "Toxic" : "Not Toxic";
      
    6. 마지막으로 감정을 웹 페이지로 반환합니다.

      return Content(sentiment);
      

웹 페이지 구성

OnGetAnalyzeSentiment에서 반환하는 결과는 Index 웹 페이지에 동적으로 표시됩니다.

  1. Pages 디렉터리에서 Index. cshtml 파일을 열고 해당 내용을 다음 코드로 바꿉니다.

    @page
    @model IndexModel
    @{
        ViewData["Title"] = "Home page";
    }
    
    <div class="text-center">
        <h2>Live Sentiment</h2>
    
        <p><textarea id="Message" cols="45" placeholder="Type any text like a short review"></textarea></p>
    
        <div class="sentiment">
            <h4>Your sentiment is...</h4>
            <p>😡 😐 😍</p>
    
            <div class="marker">
                <div id="markerPosition" style="left: 45%;">
                    <div>▲</div>
                    <label id="markerValue">Neutral</label>
                </div>
            </div>
        </div>
    </div>    
    
  2. 다음으로, wwwroot\css 디렉터리에서 site.css 페이지 끝에 css 스타일 코드를 추가합니다.

    /* Style for sentiment display */
    
    .sentiment {
        background-color: #eee;
        position: relative;
        display: inline-block;
        padding: 1rem;
        padding-bottom: 0;
        border-radius: 1rem;
    }
    
    .sentiment h4 {
        font-size: 16px;
        text-align: center;
        margin: 0;
        padding: 0;
    }
    
    .sentiment p {
        font-size: 50px;
    }
    
    .sentiment .marker {
        position: relative;
        left: 22px;
        width: calc(100% - 68px);
    }
    
    .sentiment .marker > div {
        transition: 0.3s ease-in-out;
        position: absolute;
        margin-left: -30px;
        text-align: center;
    }
    
    .sentiment .marker > div > div {
        font-size: 50px;
        line-height: 20px;
        color: green;
    }
    
    .sentiment .marker > div label {
        font-size: 30px;
        color: gray;
    }
    
  3. 그런 다음 웹 페이지에서 OnGetAnalyzeSentiment 처리기로 입력을 보내는 코드를 추가합니다.

    1. wwwroot\js 디렉터리에 있는 site.js 파일에서 OnGetAnalyzeSentiment 처리기에 사용자 입력을 사용하여 GET HTTP 요청을 하는 getSentiment라는 함수를 만듭니다.

      function getSentiment(userInput) {
          return fetch(`Index?handler=AnalyzeSentiment&text=${userInput}`)
              .then((response) => {
                  return response.text();
              })
      }
      
    2. 그 아래에 감정이 예측되면 웹 페이지에서 표식의 위치를 동적으로 업데이트하는 updateMarker라는 또 다른 함수를 추가합니다.

      function updateMarker(markerPosition, sentiment) {
          $("#markerPosition").attr("style", `left:${markerPosition}%`);
          $("#markerValue").text(sentiment);
      }
      
    3. 사용자의 입력을 가져와 getSentiment 함수를 사용하여 OnGetAnalyzeSentiment 함수에 보내고 updateMarker 함수를 사용하여 표식을 업데이트하는 updateSentiment라는 이벤트 처리기 함수를 만듭니다.

      function updateSentiment() {
      
          var userInput = $("#Message").val();
      
          getSentiment(userInput)
              .then((sentiment) => {
                  switch (sentiment) {
                      case "Not Toxic":
                          updateMarker(100.0, sentiment);
                          break;
                      case "Toxic":
                          updateMarker(0.0, sentiment);
                          break;
                      default:
                          updateMarker(45.0, "Neutral");
                  }    
              });
      }        
      
    4. 마지막으로 이벤트 처리기를 등록하고 id=Message 특성을 사용하여 textarea 요소에 바인딩합니다.

      $("#Message").on('change input paste', updateSentiment)        
      

애플리케이션 실행

이제 애플리케이션이 설정되었으므로 브라우저에서 시작해야 하는 애플리케이션을 실행합니다.

애플리케이션이 시작되면 이 모델에 충분한 데이터가 없습니다! 를 텍스트 영역에 입력합니다. 표시되는 예측 감정은 독성이어야 합니다.

예측된 감정 창이 있는 실행 창

참고

PredictionEnginePool<TData,TPrediction> 는 의 PredictionEngine<TSrc,TDst>여러 인스턴스를 만듭니다. 모델의 크기 때문에 모델을 처음 사용하여 예측을 수행하는 데 몇 초 정도 걸릴 수 있습니다. 후속 예측은 즉각적이어야 합니다.

다음 단계

본 자습서에서는 다음 작업에 관한 방법을 학습했습니다.

  • ASP.NET Core Razor Pages 애플리케이션 만들기
  • 데이터 준비 및 이해
  • 시나리오 선택
  • 데이터 로드
  • 모델 학습
  • 모델 평가
  • 예측에 모델 사용

추가 리소스

이 자습서에서 언급한 항목에 대한 자세한 내용은 다음 리소스를 참조하세요.