2단계: 데이터 탐색하기
컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요.
모델을 빌드하고 학습시키는 것은 워크플로의 한 부분일 뿐입니다. 이해 데이터의 특성을 미리 파악하면 보다 효과적인 있습니다. 이는 단순히 더 높은 정확도를 얻는 것을 의미할 수 있습니다. 또한 다음을 의미할 수도 있습니다. 학습에 필요한 데이터나 컴퓨팅 리소스가 더 적게 필요합니다.
데이터 세트 로드
먼저 데이터 세트를 Python에 로드해 보겠습니다.
def load_imdb_sentiment_analysis_dataset(data_path, seed=123): """Loads the IMDb movie reviews sentiment analysis dataset. # Arguments data_path: string, path to the data directory. seed: int, seed for randomizer. # Returns A tuple of training and validation data. Number of training samples: 25000 Number of test samples: 25000 Number of categories: 2 (0 - negative, 1 - positive) # References Mass et al., http://www.aclweb.org/anthology/P11-1015 Download and uncompress archive from: http://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz """ imdb_data_path = os.path.join(data_path, 'aclImdb') # Load the training data train_texts = [] train_labels = [] for category in ['pos', 'neg']: train_path = os.path.join(imdb_data_path, 'train', category) for fname in sorted(os.listdir(train_path)): if fname.endswith('.txt'): with open(os.path.join(train_path, fname)) as f: train_texts.append(f.read()) train_labels.append(0 if category == 'neg' else 1) # Load the validation data. test_texts = [] test_labels = [] for category in ['pos', 'neg']: test_path = os.path.join(imdb_data_path, 'test', category) for fname in sorted(os.listdir(test_path)): if fname.endswith('.txt'): with open(os.path.join(test_path, fname)) as f: test_texts.append(f.read()) test_labels.append(0 if category == 'neg' else 1) # Shuffle the training data and labels. random.seed(seed) random.shuffle(train_texts) random.seed(seed) random.shuffle(train_labels) return ((train_texts, np.array(train_labels)), (test_texts, np.array(test_labels)))
데이터 확인
데이터를 로드한 후에는 몇 가지 검사를 실행하는 것이 좋습니다. 샘플이 예상과 일치하는지 직접 확인합니다. 예를 들어 무작위로 샘플 몇 개를 인쇄하여 감정 라벨이 리뷰의 감정에 해당합니다. 무작위 순서로 선별한 리뷰입니다. IMDb 데이터 세트에서 분석: “ 시간을 절약할 수 있습니다. 1980년대 중반에 아무 의미도 일어나지 않았을 때 중간 지점에 도달해야 합니다.'라는 질문에 예상되는 감정 (부정적인 감정)이 샘플 라벨에 따라 다릅니다.
주요 측정항목 수집
데이터가 확인되면 다음과 같은 중요한 측정항목을 수집하세요. 텍스트 분류 문제를 규정하는 데 도움이 됩니다.
샘플 수: 데이터에 있는 총 예시 수입니다.
클래스 수: 데이터에 있는 주제 또는 카테고리의 총 개수입니다.
클래스당 샘플 수: 클래스당 샘플 수 확인할 수 있습니다. 균형 잡힌 데이터 세트에서는 모든 클래스가 비슷한 수를 갖습니다. 샘플의 각 클래스의 샘플 수는 크게 다를 수 있습니다
샘플당 단어 수: 한 샘플의 단어 수 중앙값입니다.
단어의 빈도 분포: 빈도를 보여주는 분포 (일치하는 항목 수)를 반환합니다.
샘플 길이 분포: 단어 수를 보여주는 분포 각 샘플에 적용됩니다
IMDb 리뷰 데이터 세트에서 이러한 측정항목의 값이 무엇인지 살펴보겠습니다. (단어-빈도 및 샘플-길이에 대한 도표는 그림 3과 4를 참고하세요.) 배포).
측정항목 이름 | 측정항목 값 |
샘플 수 | 25000 |
클래스 수 | 2 |
클래스당 샘플 수 | 12500 |
샘플당 단어 수 | 174 |
표 1: IMDb 리뷰 데이터 세트 측정항목
explore_data.py
포함된 함수로 이러한 측정항목을 계산하고 분석합니다. 다음은 몇 가지 예입니다.
import numpy as np import matplotlib.pyplot as plt def get_num_words_per_sample(sample_texts): """Returns the median number of words per sample given corpus. # Arguments sample_texts: list, sample texts. # Returns int, median number of words per sample. """ num_words = [len(s.split()) for s in sample_texts] return np.median(num_words) def plot_sample_length_distribution(sample_texts): """Plots the sample length distribution. # Arguments samples_texts: list, sample texts. """ plt.hist([len(s) for s in sample_texts], 50) plt.xlabel('Length of a sample') plt.ylabel('Number of samples') plt.title('Sample length distribution') plt.show()

그림 3: IMDb의 단어 빈도 분포

그림 4: IMDb의 샘플 길이 분포
달리 명시되지 않는 한 이 페이지의 콘텐츠에는 Creative Commons Attribution 4.0 라이선스에 따라 라이선스가 부여되며, 코드 샘플에는 Apache 2.0 라이선스에 따라 라이선스가 부여됩니다. 자세한 내용은 Google Developers 사이트 정책을 참조하세요. 자바는 Oracle 및/또는 Oracle 계열사의 등록 상표입니다.
최종 업데이트: 2025-07-27(UTC)
[[["이해하기 쉬움","easyToUnderstand","thumb-up"],["문제가 해결됨","solvedMyProblem","thumb-up"],["기타","otherUp","thumb-up"]],[["필요한 정보가 없음","missingTheInformationINeed","thumb-down"],["너무 복잡함/단계 수가 너무 많음","tooComplicatedTooManySteps","thumb-down"],["오래됨","outOfDate","thumb-down"],["번역 문제","translationIssue","thumb-down"],["샘플/코드 문제","samplesCodeIssue","thumb-down"],["기타","otherDown","thumb-down"]],["최종 업데이트: 2025-07-27(UTC)"],[[["\u003cp\u003eUnderstanding your data before model building can lead to improved model performance, including higher accuracy and reduced resource requirements.\u003c/p\u003e\n"],["\u003cp\u003eThe IMDb movie reviews dataset contains 25,000 samples, is balanced with 12,500 samples per class (positive and negative), and has a median of 174 words per sample.\u003c/p\u003e\n"],["\u003cp\u003eBefore training, it's crucial to verify your data and examine key metrics like the number of samples, classes, samples per class, words per sample, word frequency, and sample length distribution.\u003c/p\u003e\n"],["\u003cp\u003eThe provided code and functions can be utilized to load the dataset, perform data checks, calculate metrics (e.g., median words per sample), and visualize data distributions (e.g., sample length).\u003c/p\u003e\n"]]],[],null,["Building and training a model is only one part of the workflow. Understanding\nthe characteristics of your data beforehand will enable you to build a better\nmodel. This could simply mean obtaining a higher accuracy. It could also mean\nrequiring less data for training, or fewer computational resources.\n\nLoad the Dataset\n\nFirst up, let's load the dataset into Python. \n\n```python\ndef load_imdb_sentiment_analysis_dataset(data_path, seed=123):\n \"\"\"Loads the IMDb movie reviews sentiment analysis dataset.\n\n # Arguments\n data_path: string, path to the data directory.\n seed: int, seed for randomizer.\n\n # Returns\n A tuple of training and validation data.\n Number of training samples: 25000\n Number of test samples: 25000\n Number of categories: 2 (0 - negative, 1 - positive)\n\n # References\n Mass et al., http://www.aclweb.org/anthology/P11-1015\n\n Download and uncompress archive from:\n http://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz\n \"\"\"\n imdb_data_path = os.path.join(data_path, 'aclImdb')\n\n # Load the training data\n train_texts = []\n train_labels = []\n for category in ['pos', 'neg']:\n train_path = os.path.join(imdb_data_path, 'train', category)\n for fname in sorted(os.listdir(train_path)):\n if fname.endswith('.txt'):\n with open(os.path.join(train_path, fname)) as f:\n train_texts.append(f.read())\n train_labels.append(0 if category == 'neg' else 1)\n\n # Load the validation data.\n test_texts = []\n test_labels = []\n for category in ['pos', 'neg']:\n test_path = os.path.join(imdb_data_path, 'test', category)\n for fname in sorted(os.listdir(test_path)):\n if fname.endswith('.txt'):\n with open(os.path.join(test_path, fname)) as f:\n test_texts.append(f.read())\n test_labels.append(0 if category == 'neg' else 1)\n\n # Shuffle the training data and labels.\n random.seed(seed)\n random.shuffle(train_texts)\n random.seed(seed)\n random.shuffle(train_labels)\n\n return ((train_texts, np.array(train_labels)),\n (test_texts, np.array(test_labels)))\n```\n\nCheck the Data\n\nAfter loading the data, it's good practice to **run some checks** on it: pick a\nfew samples and manually check if they are consistent with your expectations.\nFor example, print a few random samples to see if the sentiment label\ncorresponds to the sentiment of the review. Here is a review we picked at random\nfrom the IMDb dataset: *\"Ten minutes worth of story stretched out into the\nbetter part of two hours. When nothing of any significance had happened at the\nhalfway point I should have left.\"* The expected sentiment (negative) matches\nthe sample's label.\n\nCollect Key Metrics\n\nOnce you've verified the data, collect the following important metrics that can\nhelp characterize your text classification problem:\n\n1. ***Number of samples***: Total number of examples you have in the data.\n\n2. ***Number of classes***: Total number of topics or categories in the data.\n\n3. ***Number of samples per class***: Number of samples per class\n (topic/category). In a balanced dataset, all classes will have a similar number\n of samples; in an imbalanced dataset, the number of samples in each class will\n vary widely.\n\n4. ***Number of words per sample***: Median number of words in one sample.\n\n5. ***Frequency distribution of words***: Distribution showing the frequency\n (number of occurrences) of each word in the dataset.\n\n6. ***Distribution of sample length***: Distribution showing the number of words\n per sample in the dataset.\n\nLet's see what the values for these metrics are for the IMDb reviews dataset\n(See Figures [3](#figure-3) and [4](#figure-4) for plots of the word-frequency and sample-length\ndistributions).\n\n| Metric name | Metric value |\n|-----------------------------|--------------|\n| Number of samples | 25000 |\n| Number of classes | 2 |\n| Number of samples per class | 12500 |\n| Number of words per sample | 174 |\n\n**Table 1: IMDb reviews dataset metrics**\n\n[explore_data.py](https://github.com/google/eng-edu/blob/master/ml/guides/text_classification/explore_data.py)\ncontains functions to\ncalculate and analyse these metrics. Here are a couple of examples: \n\n```python\nimport numpy as np\nimport matplotlib.pyplot as plt\n\ndef get_num_words_per_sample(sample_texts):\n \"\"\"Returns the median number of words per sample given corpus.\n\n # Arguments\n sample_texts: list, sample texts.\n\n # Returns\n int, median number of words per sample.\n \"\"\"\n num_words = [len(s.split()) for s in sample_texts]\n return np.median(num_words)\n\ndef plot_sample_length_distribution(sample_texts):\n \"\"\"Plots the sample length distribution.\n\n # Arguments\n samples_texts: list, sample texts.\n \"\"\"\n plt.hist([len(s) for s in sample_texts], 50)\n plt.xlabel('Length of a sample')\n plt.ylabel('Number of samples')\n plt.title('Sample length distribution')\n plt.show()\n```\n\n\n**Figure 3: Frequency distribution of words for IMDb**\n\n\n**Figure 4: Distribution of sample length for IMDb**"]]