Python Scikit学习:TfidfVectorizer的自定义分析器

Python Scikit学习:TfidfVectorizer的自定义分析器,python,nlp,scikit-learn,Python,Nlp,Scikit Learn,因此,我试图了解如何为python scikit learn的TfidfVectorizer编写自定义分析器 我正在参加下面的卡格尔比赛 作为第一步,我在配料栏做了一些清理 traindf = pd.read_json('../../data/train.json') traindf['ingredients_string'] = [' '.join([WordNetLemmatizer().lemmatize(re.sub('[^A-Za-z]', ' ', line)) for line

因此,我试图了解如何为python scikit learn的TfidfVectorizer编写自定义分析器

我正在参加下面的卡格尔比赛

作为第一步,我在配料栏做了一些清理

traindf = pd.read_json('../../data/train.json')

traindf['ingredients_string'] = [' '.join([WordNetLemmatizer().lemmatize(re.sub('[^A-Za-z]', ' ', line)) for line in lists]).strip() for lists in traindf['ingredients']]   
之后,我使用TfidfVectorizer和Logistic回归分类器创建了一个管道

pip = Pipeline([
    ('vect', TfidfVectorizer(
                             stop_words='english',
                             sublinear_tf=True,
                             use_idf=bestParameters['vect__use_idf'],
                             max_df=bestParameters['vect__max_df'],
                             ngram_range=bestParameters['vect__ngram_range']
                             )),         

    ('clf', LogisticRegression(C=bestParameters['clf__C']))
    ])
然后我适应了我的训练,最后,我预测

X, y = traindf['ingredients_string'], traindf['cuisine'].as_matrix()

X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.7)

parameters = {}

grid_searchTS = GridSearchCV(pip,parameters,n_jobs=3, verbose=1, scoring='accuracy')
grid_searchTS.fit(X_train, y_train)

predictions = grid_searchTS.predict(X_test)
最后,我检查我的分类器是如何通过

print ('Accuracy:', accuracy_score(y_test, predictions))
print ('Confusion Matrix:', confusion_matrix(y_test, predictions))
print ('Classification Report:', classification_report(y_test, predictions))
现在这给了我大约78%的准确率。好的现在,我基本上执行相同的步骤,但有一个变化。我不想在dataframe中为已清理版本的配料创建一个新列,而是想创建一个自定义分析器来完成同样的工作。所以写

def customAnalyzer(text):

    lemTxt = ["".join([WordNetLemmatizer().lemmatize(re.sub('[^A-Za-z]', ' ', ingred)) for ingred in lines.lower()]) for lines in sorted(text)]


    return " ".join(lemTxt).strip()
当然,我会随着时间的推移改变管道

pip = Pipeline([
    ('vect', TfidfVectorizer(
                             stop_words='english',
                             sublinear_tf=True,
                             use_idf=bestParameters['vect__use_idf'],
                             max_df=bestParameters['vect__max_df'],
                             ngram_range=bestParameters['vect__ngram_range'],
                             analyzer=customAnalyzer
                             )),         

    ('clf', LogisticRegression(C=bestParameters['clf__C']))
    ])
最后,因为我认为我的customAnalyzer会处理所有的事情,所以我创建了我的列车测试分割

X, y = traindf['ingredients'], traindf['cuisine'].as_matrix()

X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.7)
但令我惊讶的是,我的准确率下降到了24%

  • 我以这种方式使用自定义分析器的直觉正确吗
  • 我是否还需要实现自定义标记器
  • 我的意图是将每种成分作为一个独立的实体使用。我不想谈论语言。当我创建Ngram时,我希望Ngram由每个单独的成分而不是每个单词组成


    如何实现这一点?

    我不确定您的
    customAnalyzer
    逻辑是否正确。尝试将其逻辑组合到一个表达式中,并在示例
    text
    值上测试它,以查看是否得到了预期的结果。例如:
    “”.join([“”.join([WordNetLemmatizer().lemmatize(re.sub(“[^A-Za-z]”,'',ingred))用于行中的ingred。lower()])用于行中的排序('这是一个示例语句')))。strip()
    产生
    而不是A c e e e e h i l m n p s s t'