Kaggle : 메르카리 (Ridge 회귀)

이번은 연수의 일환으로, 과거의 카글르 대회에 임했기 때문에
간단하게 정리해 보았습니다.

· Mercari Price Suggestion Challenge

메르카리의 상품 정보로부터, Ridge 회귀를 이용해 가격을 예상해 갑니다.

1. 모듈 준비



import numpy as np
import pandas as pd
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.preprocessing import LabelBinarizer
from scipy.sparse import csr_matrix, hstack
from sklearn.model_selection import train_test_split
from sklearn.linear_model import Ridge
from sklearn.metrics import mean_squared_log_error

2. 데이터 준비



데이터를 로드합니다.

train = pd.read_csv('train.tsv', sep='\t')
test = pd.read_csv('test.tsv', sep='\t')

데이터 수를 확인합니다.

print(train.shape)
print(test.shape)

# (1482535, 8)
# (693359, 7)

train 데이터와 test 데이터를 결합합니다.

all_data = pd.concat([train, test])
all_data.head()



데이터의 기본 정보를 확인합니다.

all_data.info(null_counts=True)

'''
<class 'pandas.core.frame.DataFrame'>
Int64Index: 2175894 entries, 0 to 693358
Data columns (total 9 columns):
brand_name           1247687 non-null object
category_name        2166509 non-null object
item_condition_id    2175894 non-null int64
item_description     2175890 non-null object
name                 2175894 non-null object
price                1482535 non-null float64
shipping             2175894 non-null int64
test_id              693359 non-null float64
train_id             1482535 non-null float64
dtypes: float64(3), int64(2), object(4)
memory usage: 166.0+ MB
'''

각 열 데이터의 고유 수(중복을 계산하지 않음)를 확인합니다.

print(all_data.brand_name.nunique())
print(all_data.category_name.nunique())
print(all_data.name.nunique())
print(all_data.item_description.nunique())

# 5289
# 1310
# 1750617
# 1862037

3. 전처리



데이터는 각 열에 대해 전처리됩니다.

이번에는 문자 데이터가 많기 때문에 BoW 벡터와 TF-IDF를 사용하여 데이터를 정리해 나갑니다.

그 때, 다른 라벨 인코딩하는 특징량에 대해서는, 데이터량이 너무 커져 버리기 때문에
희소 행렬 (성분에 0이 많은 행렬 = 희소 행렬)로 변환하여 압축을 유지합니다.
# name

cv = CountVectorizer()
name = cv.fit_transform(all_data.name)

# item_description

all_data.item_description.fillna(value='null', inplace=True)

tv = TfidfVectorizer()
item_description = tv.fit_transform(all_data.item_description)

# category_name

all_data.category_name.fillna(value='null', inplace=True)

lb = LabelBinarizer(sparse_output=True)
category_name = lb.fit_transform(all_data.category_name)
# brand_name

all_data.brand_name.fillna(value='null', inplace=True)

brand_name = lb.fit_transform(all_data.brand_name)

# item_condition_id, shipping

onehot_cols = ['item_condition_id', 'shipping']
onehot_data = csr_matrix(pd.get_dummies(all_data[onehot_cols], sparse=True))

마지막으로 이러한 데이터를 결합하여 희소 행렬 데이터로 변환합니다.

X_sparse = hstack((name, item_description, category_name, brand_name, onehot_data)).tocsr()

4. 모델 만들기



결합 데이터 all_data 정보
train 데이터에는 목적 변수가 있지만 test 데이터에는 없기 때문에
X 의 데이터량을 y 와 같은 사이즈 (= tran 데이터의 행수)로 해 둡니다.
nrows = train.shape[0]
X = X_sparse[:nrows]

y (가격 데이터)는 데이터에 편차가 있으며 예측 결과에 영향을 미치기 때문에
표준화도 좋지만 이번에는 로그 변환을 해 둡니다.

단, y 의 값이 0 이라도 문제가 없도록, $\log(y+1)$ 로 변환을 실시합니다.

y = np.log1p(train.price)
y[:5]

'''
0    2.397895
1    3.970292
2    2.397895
3    3.583519
4    3.806662
Name: price, dtype: float64
'''

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)

ridge = Ridge()
ridge.fit(X_train, y_train)

'''
Ridge(alpha=1.0, copy_X=True, fit_intercept=True, max_iter=None,
   normalize=False, random_state=None, solver='auto', tol=0.001)
'''

5. 성능 평가



y_pred = ridge.predict(X_test)

이번은 RMSE(콤페용에 조금 개량)의 지표로 평가합니다.

모델링하기 전에 y를 로그로 변환했으므로 모델링 후 실행 취소해야합니다.
평가식 중, 그 처리를 실시하고 있습니다.

def rmse(y_test, y_pred):
    return np.sqrt(mean_squared_log_error(np.expm1(y_test), np.expm1(y_pred)))

rmse(y_test, y_pred)

# 0.4745184301527575

이상으로부터, 메르카리의 상품 정보로부터 가격 예측을 해, 평가할 수 있었습니다.

이번에는 초학자를 향해 기사를 정리했습니다.
조금이라도 도움이 된 것 같으면 LGBT를 해 주시면 감사하겠습니다.

잘 읽어 주셔서 감사합니다.

좋은 웹페이지 즐겨찾기