2017-11-23 14 views
0

저는 R에서 왔기 때문에 scikit API는 여전히 매우 혼란 스럽습니다. 나는이 튜토리얼 http://michelleful.github.io/code-blog/2015/06/20/pipelines/을 따라 파이프 라인에 대해 배웠다. 그래서 그냥 참조를 위해 가짜 데이터 집합을 만들 수 있습니다 :Scikit 사용자 정의 트랜스포머 치수 불일치를 배우십시오

x1,x2,y 
foo,zoo,1 
bar,moo,2 
goo,too,3 
roo,zoo,4 
too,moo,5 

내 목표는 매우 간단합니다 : X1과 X2 플러스 X1과 X2 모두에서 일부 사용자 정의 기능에서 별도의 TFIDF 행렬을 사용하여, Y에 선형 회귀 훈련 (즉, , 단어 길이 등).

x1에서 tfidf 만 사용하는 간단한 작업부터 시작하겠습니다. 여기에 전체 코드입니다 : 몇 가지 용어가 모두 열차에 표시되지 않습니다 아마도 때문에,

from sklearn.feature_extraction.text import TfidfVectorizer 
from sklearn.feature_extraction.text import CountVectorizer 
from sklearn.model_selection import train_test_split 
from sklearn.metrics import mean_squared_log_error 
from sklearn.linear_model import LinearRegression 
from sklearn.pipeline import Pipeline, FeatureUnion 
from sklearn.model_selection import KFold 
from sklearn.model_selection import cross_val_score 
from sklearn.metrics import fbeta_score, make_scorer 
from sklearn.base import BaseEstimator, TransformerMixin 

import pandas as pd 
import numpy as np 
import time 
import re 
import math 

def clip_RMSLE(y, y_pred, **kwargs): 
    y_pred[y_pred < 0] = 0.0 
    to_sum = [(math.log(y_pred[i] + 1) - math.log(y[i] + 1)) ** 2.0 for i,pred in enumerate(y_pred)] 
    return (sum(to_sum) * (1.0/len(y))) ** 0.5 

class ColumnNgram(BaseEstimator, TransformerMixin): 
    def __init__(self, colname, tokenizer, ngram_rg): 
     self.colname = colname 
     self.tokenizer = tokenizer 
     self.ngram_rg = ngram_rg 
     self.tfidf = None 

    def transform(self, df, y=None): 
     tfidf = TfidfVectorizer(tokenizer=self.tokenizer, ngram_range=self.ngram_rg) 
     return tfidf.fit_transform(df[self.colname].values) 

    def fit(self, df, y=None): 
     return self 


start = time.time() 
seed = 1991 
ngram_rg = (1,2) 
RMSLE = make_scorer(clip_RMSLE, greater_is_better=False) 

def tokenizer(text): 
    if text: 
     result = re.findall('[a-z]{2,}', text.lower()) 
    else: 
     result = [] 
    return result 

df = pd.read_csv('fake.csv', sep=',') 
y = df['y'].values 

pipeline = Pipeline([('tfidf', ColumnNgram('x1', tokenizer, ngram_rg)), 
('linear_reg', LinearRegression(n_jobs=1)) 
]) 

kfold = KFold(n_splits=2, random_state=seed) 
results = cross_val_score(pipeline, df, y, cv=kfold, scoring=RMSLE) 
print(results) 
print(results.mean()) 

end = time.time() 
print('Timeto finish this thing: %0.2fs' % (end - start)) 

I 오류 ValueError: dimension mismatch 받고 있어요/검증 주름. 이 일을하는 올바른 방법은 무엇입니까? 고맙습니다!

+0

전체 코드를 입력하십시오. – sera

+0

전체 코드를 추가하겠습니다. – Fernando

답변

1
이에 ColumnNgram 변경

:

class ColumnNgram(BaseEstimator, TransformerMixin): 
    def __init__(self, colname, tokenizer, ngram_rg): 
     self.colname = colname 
     self.tokenizer = tokenizer 
     self.ngram_rg = ngram_rg 
     self.tfidf = None 

    def transform(self, df, y=None): 
     self.tfidf.transform(df[self.colname].values) 

    def fit(self, df, y=None): 
     self.tfidf = TfidfVectorizer(tokenizer=self.tokenizer, ngram_range=self.ngram_rg) 
     self.tfidf.fit(df[self.colname].values) 
     return self 

당신은 선언하고 fit()의 훈련 데이터에 대해 배워야한다. 현재 transform()에 대한 각 호출에서 데이터를 다시 맞추고 있습니다. 분명히 제안한대로 열차 및 유효성 검사 세트의 다른 기능으로 복귀합니다.

TfidfVectorizer은 fit() 중에 데이터를 학습 한 다음 새 데이터를 다시 맞추는 대신 transform()에서 새 데이터 만 변환하는 것이 올바른 방법입니다.

+0

고맙습니다. 문서를 읽을 시간입니다! – Fernando