scikit-learn의 fetch_mldata('MNIST original') 에러
scikit-learn은 테스트 데이터로 사용할 수 있는 여러 데이터셋를 간편하게 로딩하는 기능을 제공합니다. 특히 머신러닝 테스트에 사용할 수 있는 대표적인 데이터셋을 로딩하는 기능을 제공하기 때문에, 이 기능을 이용하여 많은 문서가 이용하여 입문자 문서를 작성하는 것이 일반적입니다.
scikit-learn이 제공하는 데이터셋 로딩 기능 중에서 fetch_mldata 함수는 mldata.org의 데이터셋을 이용합니다. 최근에 mldata.org 사이트가 장애가 발생하면서 이 함수는 정상적으로 작동하지 않습니다. 이 오류를 우회하는 방법을 정리합니다.
무엇이 문제인가?
<그림 1>과 같이 fetch_mldata를 실행하면 HTTP Error 404 에로 로그가 출력됩니다.
현재(2018.08.04)은 mldata.org 사이트는 <그림 2>와 같이 서비스에 문제가 있습니다. fetch_mldata 함수는 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 참조>
<그림 4>는 다음과 같은 절차를 진행합니다.
/root/scikit_learn_data/mldata
에 데이터 파일 다운로드/root/scikit_learn_data/mldata
에 파일 목록 확인- sklearn의 fetch_mldata로 데이터 로딩
Solution2: 데이터파일 다운로드 및 data_home를 매개변수로 지정
fetch_mldata는 data_home을 지정하는 방법을 제공합니다. <그림 5>는 현재 디렉터리에 mldata 디레터리를 생성 후, mldata에 데이터파일을 다운로드하는 과정을 설명합니다.
<그림 6>은 data_home을 지정하여 MNIST 데이터 파일을 로딩하는 코드입니다. 앞에서 데이터파일을 mldata 디렉터리에 다운로드 했습니다.
mldata의 상위 디렉터리를 data_home
으로 지정합니다.
솔루션 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 디렉터리의 상위 디렉터리를 지정해야 합니다.
- mat 파일은 Matlab 파일 포맷입니다. 머신러닝의 많은 데이터셋이 mat 파일로 공개되어 있습니다. SciPy는 mat 파일을 읽어서 Numpy 객체로 변환하는 기능을 제공합니다. [return]
- 전체 URL => http://mldata.org/repository/data/download/matlab/mnist_original.mat [return]