출처
되도록이면 책의 내용과 코드를 그대로 옮기기 보다는 요약과 보충설명!
: 가설 를 사용하여 일련의 샘플을 평가하는 비용 함수 (더보기)
: 제곱항을 합한 것의 제곱근 계산
: 실제 값과 예측 값의 차이를 제곱해 평균(=MSE)한 뒤 루트를 씌웠기 때문에, 실제 값과 유사한 단위로 다시 변환하여 해석이 용이해짐. 유클리디안 노름에 해당.
: MAE에 비해 덜 직관적이고, 조금 더 이상치에 민감. 그렇지만 종 모양 분포처럼 이상치가 매우 드물 경우 잘 맞아서 널리 사용됨.
: 절댓값의 합 계산
: 실제 값과 예측 값의 차이를 절댓값으로 변환해 평균냄. 맨해튼 노름.
: 직관적이고, 이상치가 많을 경우 사용하기 좋음. 즉 로버스트(robust)하다! 극단적인 이상치로부터의 영향을 덜 받는다.
왜 사진 크기 조절이 안되지..?
fit()
으로 추정.transform()
로 변환된 데이터셋을 반환.fit_transform()
: 값 추정과 자료 변환을 동시에, 즉 fit()과 transform()을 연달아 호출하는 것과 동일(method chaining).predict()
로 새로운 데이터셋을 받아 예측값 반환score()
로 예측의 품질을 측정: 모델링할 때 사용자가 직접 세팅해주는 값
범주형 변수를 0과 1의 이진 벡터로 표시한다.
: 한 특성은 1, 나머지 특성은 0으로 표시
: 만약 n개의 특성이 존재한다면, n개의 특성 배열을 n차원 벡터로 표현
밀집된 넘파이 배열이 아닌 사이파이(ScyPy) 희소 행렬(sparse matrix)로 출력
: 밀집된 넘파이 배열로 바꾸려면 OneHotEncoder(sparse=False)
또는 toarray()
사용
: 행렬의 값이 대부분 0인 경우.
: 대부분 0인데, 이걸 행렬로 다 나열하는건 메모리 낭비임. 더 간단히 표현할 수 있음
: COO matrix, CSR matrix, DOK 방식 등
: 동적 타이핑의 한 종류로, 객체의 변수 및 메소드의 집합이 객체의 타입을 결정하는 것을 말한다.
"만약 어떤 새가 오리처럼 걷고, 헤엄치고, 꽥꽥거리는 소리를 낸다면 나는 그 새를 오리라고 부를 것이다."
: 객체의 속성이나 매서드가 (즉, 무엇을 할 수 있는지 없는지) 객체의 유형을 결정하는 방식
: 만약 두 class가 동일한 값을 출력한다면(가진 함수가 같다거나), 덕 타이핑에서는 두 class를 같은 타입으로 본다.
: 데이터에서 최솟값을 뺀 후, 최댓값과 최솟값의 차이로 나눠준다.
: 반환 결과는 0 ~ 1 범위로, 이 범위 안에 들도록 값을 이동하고 scale을 조정하는 방법
: 이상치에 매우 민감(이상치가 매우 크면 분모가 매우 커져서 변환된 값이 0 근처에 몰림)
: 데이터에서 평균을 빼고 표준편차로 나누어 분산이 1이 되도록 해준다.
: 표준 정규 분포를 따르게 된다
: 이상치에 덜 민감
: 훈련 세트를 k개의 폴드(fold)로 무작위 분할하여, k번 훈련하고 평가함.
: 훈련할 때마다 매번 다른 하나의 폴드를 평가에 사용, 나머지 k - 1개 폴드는 훈련에 사용. k개의 평가 점수가 담긴 배열을 생성
: 여러 다른 모델을 모아서 하나의 모델을 만드는 기법
: 즉, 교차 검증을 일반화 시킨 모델 학습법임.
: 머신러닝 알고리즘의 성능을 극대화는 방법 중 하나
os
: Operating System의 약자. 환경 변수나 디렉터리, 파일 등의 OS 자원을 제어할 수 있게 해주는 모듈.os.path.join()
: 운영체제에 맞게 폴더 구분자를 다뤄서 경로를 생성해줌. 그냥 join이나 +로는 운영체제가 다를 때 에러가 발생하기 때문.urllib.request.urlretrieve()
: url에 대응되는 대상 압축파일을 사용자가 지정한 이름으로 다운받음.tarfile
: 여러 개의 파일을 tar 형식으로 합치거나 이를 해제할 때 사용하는 모듈tarfile.open()
함수를 이용하여 열고, extractall()
함수를 이용하여 지정한 경로에 압축 해제iloc( )
: index 기반 selecting.loc( )
: 라벨 값 기반 selecting.df.drop(labels=None, axis=0, index=None, columns=None, level=None, inplace=False, errors='raise')
: pandas dataframe의 행/열 삭제. axis(0: 행, 1: 열). inplace: 원본 변경 여부df.dropna(axis=0, how='any', thresh=None, subset=None, inplace=False)
: axis(0: 행 삭제, 1: 열 삭제), subset: 열 라벨toarray()
: 희소 행렬을 밀집된 넘파이 배열로 바꿈get_params()
와 set_params()
: 사이킷런의 파이프라인과 그리드 탐색에 꼭 필요한 메서드 (아직 이해X)np.c_
: 열에 대하여 분리된 것을 연결 시켜줌 (행은 np.r_)데이터프레임명.values
또는 데이터프레임명.to_numpy()
: 데이터프레임을 numpy 배열 형식으로 변환: 실제 데이터를 가지고 데이터 전처리부터 모델 훈련, 예측까지 전과정을 경험해보자
Q. 비즈니스의 목적이 정확히 무엇인가?
: 나의 모델의 출력이 다른 신호들과 함께 다른 머신러닝 시스템의 입력이 되는가?
Q. 현재 솔루션은 어떻게 구성되어 있는가?
: 회귀에서의 평가 지표를 선택하자
: RMSE? MAE?
: 예: 만약 출력된 가격 값이 하위 시스템에서 카테고리로 바꾼다면? 가격을 정확히 예측하는 건 필요 없고, 카테고리를 구하면 됨.
: 파이썬, 패키지, 주피터 노트북은 설치되어 있다고 하자.
: housing.csv를 압축한 housing.tgz를 다운 받아 압축을 풀고, 판다스로 데이터를 읽어 들이면 데이터프레임으로 반환됨.
: head()
, info()
, value_counts()
: 범주형 카테고리, describe()
: 숫자형 특성, hist()
why 지금 테스트 세트를 만들고, 보지 말아야 하는가?
: 데이터 스누핑 편향(data snooping)
: 우리의 뇌는 과대적합되기 쉬워서, 테스트 세트를 들여다보게 되면 겉으로 드러난 특성에 맞는 모델을 선택할지도 모름. 그렇게 되면 새로운 데이터에 잘 일반화 되지 않고 오차가 크게 발생하 것임.
사이킷런(scikit-learn)의 model_selection 패키지 안에 train_test_split
모듈을 활용하여 손쉽게 train set과 test set을 분리할 수 있음.
책의 split_train_test()은 테스트 세트를 만들기 위한 일련의 과정을 보여준 예시일 뿐.
pd.cut()
으로 연속적인 숫자형인 'median_income'을 카테고리로 나누어 원본 데이터에 'income_cat' 추가StratifiedShuffleSplit
사용train_test_split()
의 stratify 파라미터 사용drop()
으로 삭제plot()
으로 산점도 그려보기corr()
, scatter_matrix
로 피어슨 상관계수(r) 살펴보기: train set에서 예측 변수와 레이블을 분리.
dropna()
등drop()
등fillna()
, SimpleImputer 등SimpleImputer
클래스fit()
한 다음에 transform()
하여(더보기) 모든 수치형 특성의 결측치를 중간값으로 대체OrdinalEncoder
클래스fit_transform()
사용하여 범주형 카테고리의 텍스트를 숫자로 변환: 범주형을 숫자로 변환했을 때, 숫자(순서) 자체에는 아무 의미가 없을지라도 머신러닝 알고리즘은 가까이 있는 두 값을 떨어져 있는 두 값보다 더 비슷하다고 생각함.
: 예: 봄 여름 가을 겨울을 1, 2, 3, 4로 하면.. 가을은 봄의 3배의 의미를 지니는가? NO!
-> 더미 특성을 만들어서 해결하자
OneHotEncoder
클래스: 사이킷런은 상속이 아닌 덕 타이핑(더보기)를 지원한다.
: 따라서, fit(), transform(), fit_transform() 메서드를 구현한 파이썬 클래스를 만들면 사이킷런의 기능을 이용하여 어디서든 적용할 수 있는 나만의 변환기를 만들 수 있다.
TransformerMixin
상속fit_transform()
메서드BaseEstimator
상속get_params()
와 set_params()
를 얻게 됨(이때, no *args & **kargs)CombinedAttributesAdder()
: 일반적으로 머신러닝 알고리즘은 입력 숫자 특성들의 스케일이 많이 다르면 잘 작동하지 않음.
min-max 스케일링
: 사이킷런의 MinMaxScaler
변환기
: 사이킷런의 Normalizer
라는 전처리 기능과 혼동하지 말 것('정규화'는 여러 의미로 사용되니까 조심하자)
표준화
: 사이킷런의 StandardScaler
변환기
: 변환 단계가 많기 때문에, 정확히 순서대로 실행되는게 중요함
사이킷런의 Pipeline
클래스
: 연속된 변환을 순서대로 처리
: 연속된 단계를 나타내는 이름/추정기 쌍의 목록을 입력으로 받고, 차례대로 fit()과 transform()을 하고, 한 단계의 출력을 다음 단계의 입력으로 전달. 마지막 단계에서는 fit() 메서드만 호출
ColumnTransformer
클래스
: 하나의 변환기로 각 열마다 적절한 변환을 적용하여 모든 열을 처리
: 여기서는 수치형과 범주형 각각 변환
LinearRegression()
으로 선형 회귀 모델 훈련DecisionTreeRegressor()
훈련: 테스트 세트를 보지 않기 위해 훈련 세트의 일부분으로 훈련을 하고 다른 일부분은 모델 검증에 사용하기로 함
train_test_split()
: 훈련 세트를 더 작은 훈련 세트와 검증 세트로 나눔
훌륭한 대안: 사이킷런의 k-겹 교차 검증(k-fold cross-validation)(더보기)
: 결정 트리 교차 검증 RMSE 평균: 71407.687...
: 오히려 선형 회귀 모델보다 나쁜 결과
앞서 결정 트리가 과대적합 되었기 때문에, 교차 검증에서 선형 회귀보다 나쁜 성능을 보임
RandomForestRegressor
모델 교차 검증
: 특성을 무작위로 선택해서 많은 결정 트리를 만들고 그 예측을 평균 내는 방식.
: 앙상블 학습 (더보기)
: 훈련 세트에 대한 랜덤 포레스트 RMSE 평균: 18603.515...
: 교차 검증한 RMSE 평균: 50182.303...
: 비교적 적은 수의 조합을 탐구할 때 사용
GridSearchCV
RandomForestRegressor
모델에 대해 시도: 하이퍼파라미터 탐색 공간이 커질때 사용
RandomizedSearchCV
GridSearchCV
와 차이점은, 각 반복마다 하이퍼파라미터에 임의의 수를 대입하여 지정한 횟수만큼 평가.: 최상의 모델을 분석하여 통찰을 얻을 수 있음. 예를 들어, 상대적으로 덜 중요한 특성을 제외하거나, 추가 특성을 포함하거나, 이상치를 제외할 수 있음.
: 테스트 세트에서 예측 변수와 레이블을 얻은 후 full_pipeline을 사용해 데이터를 변환(이때, 테스트 세트에서는 훈련하면 안되므로 transform()만 호출해야함)하고 테스트 세트에서 최종 모델을 평가.
: RMSE: 47730
95% 신뢰 구간 측정하기
: scipy.stats.t.interval()
하이퍼파라미터 튜닝을 많이 했다면, 검증 데이터에서 좋은 성능을 내도록 셈리하게 튜닝되었기 때문에 새로운 데이터셋에서는 조금 성능이 낮게 나오는게 일반적임.
: 본문을 다 이해한 다음에 하자..ㅜㅜ
86p. "예를 들어 각 샘플마다 식별자의 해시값을 계산하여 해시 최댓값의 20%보다 작거나 같은 샘플만 테스트 세트로 보낼 수 있습니다."가 잘 이해되지 않습니다. 해시값은 그 샘플만의 고유값이며, 그 고유값은 변하지 않기 때문에 식별자로 사용한다는 것은 이해하였습니다. 그러나 '해시 최댓값의 20%보다 작거나 같은 샘플만 테스트 세트로 보낸다'는 것이 이해가 되지 않습니다. 만약 새로운 데이터가 추가되면, 그 데이터들의 해시 최대값이 현재 해시 최댓값보다 크다면 해시 최댓값의 20%가 변경되지 않나요? 즉 '해시 최대값'이 어떤 것을 의미하는지 궁금합니다.
105p. 나만의 변환기 제작 파트에서 BaseEstimator를 사용하는 이유가 이해되지 않습니다. 또한 get_params()와 set_params()를 포함하는데, 이 두 메서드가 *args나 **kargs는 사용할 수 없는 구체적인 이유가 무엇인지 궁금합니다. 생성자에 명시된 매개변수 이외의 다른 변수가 들어가면 어떤 오류가 발생하는걸까요?
108p. "파이프라인 객체는 마지막 추정기와 동일한 메서드를 제공합니다."가 잘 이해되지 않습니다. 본문에서는 StandardScaler가 마지막 추정기인데, 이것이 무엇을 의미하나요? 만약 본문의 세 추정기들간 순서가 바뀌면 어떤 일이 일어나는건가요?