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에서 파일을 다운로드하도록 구현되어 있습니다.

[^2]: 전체 URL => http://mldata.org/repository/data/download/matlab/mnist_original.mat

## 오류 해결 방법

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

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

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

- https://github.com/amplab/datascience-sp14/raw/master/lab7/mldata/mnist-original.mat

 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```에 데이터 파일 다운로드 1. ```/root/scikit_learn_data/mldata```에 파일 목록 확인 1. 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]
작성자: 김태완
김태완 avatar
작성자: 김태완
1999년 부터 Java, Framework, Middleware, SOA, DB Replication, Cache, CEP, NoSQL, Big Data, Cloud를 키워드로 살아왔습니다. 현재는 빅데이터와 Machine Learning을 중점에 두고 있습니다.
E-mail: taewanme@gmail.com