scikit-learn의 fetch_mldata('MNIST original') 에러

scikit-learn의 fetch_mldata('MNIST original') 에러

scikit-learn은 테스트 데이터로 사용할 수 있는 여러 데이터셋를 간편하게 로딩하는 기능을 제공합니다. 특히 머신러닝 테스트에 사용할 수 있는 대표적인 데이터셋을 로딩하는 기능을 제공하기 때문에, 이 기능을 이용하여 많은 문서가 이용하여 입문자 문서를 작성하는 것이 일반적입니다.

scikit-learn이 제공하는 데이터셋 로딩 기능 중에서 fetch_mldata 함수는 mldata.org의 데이터셋을 이용합니다. 최근에 mldata.org 사이트가 장애가 발생하면서 이 함수는 정상적으로 작동하지 않습니다. 이 오류를 우회하는 방법을 정리합니다.

무엇이 문제인가?

<그림 1>과 같이 fetch_mldata를 실행하면 HTTP Error 404 에로 로그가 출력됩니다.

모델 복잡도 & Epoch에 대한 과대적합 & 과소적합
그림 1: 모델 복잡도 & Epoch에 대한 과대적합 & 과소적합

현재(2018.08.04)은 mldata.org 사이트는 <그림 2>와 같이 서비스에 문제가 있습니다. fetch_mldata 함수는 mldata.org에 데이터셋을 다운로드하여 사용하기 때문에 문제가 되는 것입니다.

mldata.org 서비스 장애 화면
그림 2: mldata.org 서비스 장애 화면

아래 코드는 fetch_mldata 함수의 구현 코드입니다. 다음은 scikit-learn/sklearn/datasets/mldata.py의 구현 코드입니다.

#Line 29
MLDATA_BASE_URL = "http://mldata.org/repository/data/download/matlab/%s"

def fetch_mldata(dataname, target_name='label', data_name='data',
                 transpose_data=True, data_home=None):
    ## 코드 생략             
    if not exists(data_home):
        os.makedirs(data_home)

    matlab_name = dataname + '.mat'
    filename = join(data_home, matlab_name)

    # if the file does not exist, download it

    #Line 151
    if not exists(filename):
        urlname = MLDATA_BASE_URL % quote(dataname)
        try:
            mldata_url = urlopen(urlname)
        except HTTPError as e:
            if e.code == 404:
                e.msg = "Dataset '%s' not found on mldata.org." % dataname
            raise
        # store Matlab file
        try:
            with open(filename, 'w+b') as matlab_file:
                copyfileobj(mldata_url, matlab_file)
        except:
            os.remove(filename)
            raise
        mldata_url.close()

    ## 코드 생략

fetch_mldata 함수의 구현 부에서 151라인data_home 디렉터리에 데이터 파일(mat 파일1)이 없으면 MLDATA_BASE_URL에서 파일을 다운로드하도록 구현되어 있습니다.

fetch_mldata("MNIST original")은 matlab 파일 포맷인 mnist_original.mat 파일을 다운로드 하고 로딩하는 함수입니다. 이 함수를 실행할 때 오류가 발생하는 이유는 mnist_original.mat2 파일을 mldata.org에서 다운받을 수 없기 때문입니다.

오류 해결 방법

fetch_mldata("MNIST original") 실행 오류는 해결하는 방법은 다음과 같이 2가지가 있습니다.

  • data_home 디렉터리에 mnist_original.mat 다운로드한 다음에 함수 실행
  • mnist_original.mat 다운로드한 다음, data_home을 지정하여 함수 실행

두 방법 모두 mnist_original.dat 파일을 별도로 다운로드해야 합니다. mnist_original.dat 파일은 다음 URL에서 다운로드 할 수 있습니다.

mnist_original.dat의 파일 사이즈는 약 52.9MB입니다.

Solution1: {data_home}/mldata에 데이터파일 다운로드

이 방법은 fetch_mldata 함수의 기본 data_home 경로에 데이터파일을 다운로드하여 사용하는 방법입니다. sklearn.datasets의 데이터 파일 기본 위치를 get_data_home 함수로 확인할 수 있습니다. <그림 3 참조>

skleran의 data_home의 위치 확인
그림 3: skleran의 data_home의 위치 확인

<그림 4>는 다음과 같은 절차를 진행합니다.

  1. /root/scikit_learn_data/mldata에 데이터 파일 다운로드
  2. /root/scikit_learn_data/mldata에 파일 목록 확인
  3. sklearn의 fetch_mldata로 데이터 로딩
MNIST original 다운로드 및 fetch_mldata로 로딩
그림 4: MNIST original 다운로드 및 fetch_mldata로 로딩

Solution2: 데이터파일 다운로드 및 data_home를 매개변수로 지정

fetch_mldata는 data_home을 지정하는 방법을 제공합니다. <그림 5>는 현재 디렉터리에 mldata 디레터리를 생성 후, mldata에 데이터파일을 다운로드하는 과정을 설명합니다.

현재 디렉터리에 mldata 디렉터리 생성 후, 데이터파일 다운로드
그림 5: 현재 디렉터리에 mldata 디렉터리 생성 후, 데이터파일 다운로드

<그림 6>은 data_home을 지정하여 MNIST 데이터 파일을 로딩하는 코드입니다. 앞에서 데이터파일을 mldata 디렉터리에 다운로드 했습니다. mldata의 상위 디렉터리를 data_home으로 지정합니다.

data_home을 지정하여 MNIST original 로딩
그림 6: data_home을 지정하여 MNIST original 로딩

솔루션 2의 실행 코드는 다음과 같습니다.

from sklearn.datasets import fetch_mldata
mnist = fetch_mldata("MNIST original", data_home="./")
x = mnist.data
y = mnist.target
print(x.shape, y.shape)
(70000, 784) (70000,)

요약

scikit-learn의 fetch_mldata함수 오류는 해결하는 방법을 다음과 같이 두 가지로 정리했습니다.

  • 1. data_home 경로를 확인하고 {data_home}/mldata에 데이터페일을 내려받고, fetch_mldata를 수행하는 방법
  • 2. 데이터 파일을 내려받고 fetch_mldata를 매개변수로 지정하여 사용하는 방법

2번에서 data_home을 지정할 때, 데이터파일을 저장된 mldata 디렉터리의 상위 디렉터리를 지정해야 합니다.


  1. mat 파일은 Matlab 파일 포맷입니다. 머신러닝의 많은 데이터셋이 mat 파일로 공개되어 있습니다. SciPy는 mat 파일을 읽어서 Numpy 객체로 변환하는 기능을 제공합니다. [return]
  2. 전체 URL => http://mldata.org/repository/data/download/matlab/mnist_original.mat [return]
작성자: 김태완
김태완 avatar
작성자: 김태완
1999년 부터 Java, Framework, Middleware, SOA, DB Replication, Cache, CEP, NoSQL, Big Data, Cloud를 키워드로 살아왔습니다. 현재는 한국오라클 빅데이터 팀 소속으로 빅데이터와 Machine Learning을 중점에 두고 있습니다. 최근에는 Deep Learning을 열공 중입니다.
E-mail: taewanme@gmail.com