Слишком много значений _coef для LogisticRegression в конвейере - PullRequest
0 голосов
/ 27 января 2019

Я использую sklearn-pandas DataFrameMapper в конвейере sklearn.Чтобы оценить вклад функции в конвейер объединения объектов, я хотел бы измерить коэффициенты оценщика (логистическая регрессия).В следующем примере кода три столбца текстового содержимого a, b и c векторизованы и выбраны для X_train:

import pandas as pd
import numpy as np
import pickle
from sklearn_pandas import DataFrameMapper
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
np.random.seed(1)

data = pd.read_csv('https://pastebin.com/raw/WZHwqLWr')
#data.columns

X = data.copy()
y = data.result
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=1)

mapper = DataFrameMapper([
        ('a', CountVectorizer()),
        ('b', CountVectorizer()),
        ('c', CountVectorizer())
])

pipeline = Pipeline([
        ('featurize', mapper),
        ('clf', LogisticRegression(random_state=1))
        ])

pipeline.fit(X_train, y_train)
y_pred = pipeline.predict(X_test)

print(abs(pipeline.named_steps['clf'].coef_))
#array([[0.3567311 , 0.3567311 , 0.46215153, 0.10542043, 0.3567311 ,
#        0.46215153, 0.46215153, 0.3567311 , 0.3567311 , 0.3567311 ,
#        0.3567311 , 0.46215153, 0.46215153, 0.3567311 , 0.46215153,
#        0.3567311 , 0.3567311 , 0.3567311 , 0.3567311 , 0.46215153,
#        0.46215153, 0.46215153, 0.3567311 , 0.3567311 ]])

print(len(pipeline.named_steps['clf'].coef_[0]))
#24

В отличие от обычного анализа нескольких объектов, который обычно возвращает коэффициенты равной длинына число объектов DataFrameMapper возвращает большую матрицу коэффициентов.

a) Как объяснено всего 24 коэффициента в верхнем регистре?б) Какой лучший способ получить доступ к значению coef_ каждой функции ("a", "b", "c")?

Желаемый вывод:

a: coef_score (float)
b: coef_score (float)
c: coef_score (float)

Спасибо!

Ответы [ 2 ]

0 голосов
/ 30 января 2019

Хотя ваш начальный кадр данных действительно содержал столбцы только для трех ваших функций a, b и c, класс Pandas DataFrameMapper() применил SKlearn CountVectorizer() к соответствующим корпусам слов каждого столбца a,б и в.В результате было создано всего 24 функции, которые затем были переданы в ваш LogisticRegression() классификатор.Вот почему вы получили непомеченный список из 24 значений, когда пытались получить доступ к атрибуту .coef_ классификатора.

Однако довольно просто сопоставить каждый из этих 24 coeff_ баллов с исходным столбцом (a, b или c), из которого они получены, а затем вычислите среднюю оценку коэффициента для каждого столбца.Вот как мы это сделаем:

Исходный кадр данных выглядит следующим образом:

             a                   b                c   result
2   here we go   hello here we are   this is a test        0
73  here we go   hello here we are   this is a test        0
...

И если мы запустим следующую строку, мы сможем увидеть список всех 24 функций, которые былисозданный DataFrameMapper / CountVectorizer(), используемым в вашем mapper объекте:

pipeline.named_steps['featurize'].transformed_names_

['a_another',
 'a_example',
 'a_go',
 'a_here',
 'a_is',
 'a_we',
 'b_are',
 'b_column',
 'b_content',
 'b_every',
 'b_has',
 'b_hello',
 'b_here',
 'b_text',
 'b_we',
 'c_can',
 'c_deal',
 'c_feature',
 'c_how',
 'c_is',
 'c_test',
 'c_this',
 'c_union',
 'c_with']

len(pipeline.named_steps['featurize'].transformed_names_)

24

Теперь вот как мы вычислим средние оценки коэффицентов для трех наборов функций, полученных из a / b / c столбцы:

col_names = list(data.drop(['result'], axis=1).columns.values)
vect_feats = pipeline.named_steps['featurize'].transformed_names_
clf_coef_scores = abs(pipeline.named_steps['clf'].coef_)

def get_avg_coef_scores(col_names, vect_feats, clf_coef_scores):
    scores = {}
    start_pos = 0
    for n in col_names:
        num_vect_feats = len([i for i in vect_feats if i[0] == n])
        end_pos = start_pos + num_vect_feats
        scores[n + '_avg_coef_score'] = np.mean(clf_coef_scores[0][start_pos:end_pos])
        start_pos = end_pos
    return scores

Если мы вызываем функцию, которую мы только что написали, мы получаем следующий вывод:

get_avg_coef_scores(col_names, vect_feats, clf_coef_scores)

{'a_avg_coef_score': 0.3499861323284858,
 'b_avg_coef_score': 0.40358462487685853,
 'c_avg_coef_score': 0.3918712435073411}

Если мы хотим проверить, какиеиз 24 коэффициентов принадлежит каждому созданному объекту, мы можем использовать следующее понимание словаря:

{key:clf_coef_scores[0][i] for i, key in enumerate(vect_feats)}

{'a_another': 0.3567310993987888,
 'a_example': 0.3567310993987888,
 'a_go': 0.4621515317244458,
 'a_here': 0.10542043232565701,
 'a_is': 0.3567310993987888,
 'a_we': 0.4621515317244458,
 'b_are': 0.4621515317244458,
 'b_column': 0.3567310993987888,
 'b_content': 0.3567310993987888,
 'b_every': 0.3567310993987888,
 'b_has': 0.3567310993987888,
 'b_hello': 0.4621515317244458,
 'b_here': 0.4621515317244458,
 'b_text': 0.3567310993987888,
 'b_we': 0.4621515317244458,
 'c_can': 0.3567310993987888,
 'c_deal': 0.3567310993987888,
 'c_feature': 0.3567310993987888,
 'c_how': 0.3567310993987888,
 'c_is': 0.4621515317244458,
 'c_test': 0.4621515317244458,
 'c_this': 0.4621515317244458,
 'c_union': 0.3567310993987888,
 'c_with': 0.3567310993987888}
0 голосов
/ 30 января 2019

После восстановления установленного DataFrameMapper из Pipeline, вы можете получить доступ к его содержимому, используя метод .features.Это позволяет перебирать функции CountVectorizer, которые вы использовали для преобразования строк в переменные с горячим кодированием.Каждый CountVecotrizer имеет метод .vocabulary_, который точно сообщает, какой столбец представляет строка.

Таким образом, вы можете просто последовательно извлекать CountVectorizer в DataFrameMapper и для каждого из них извлекать последовательно строку, представляющую каждый столбец во входной матрице.Это позволит вам иметь последовательность, точно представляющую метки ваших коэффициентов.

На основе вашего примера этот фрагмент кода должен делать то, что вам нужно, и что я подробно описал выше (пожалуйста, предупредите меня, если вы получите какую-либо ошибку, я исправлю ее на основе ваших отзывов):

# recover the fitted mapper
fitted_mapper = pipeline.named_steps['featurize'] 

mapped_labels = list()
# iterate through the CountVectorizers
for label, fun in fitted_mapper.features:
    # Iterate through the sorted vocabulary
    for level, _ in sorted(fun.vocabulary_.items()):
        mapped_labels.append(label+'_'+level)

# the ordered sequence of vectorized strings
print(mapped_labels)

# pick up the coefficients
coefs = pipeline.named_steps['clf'].coef_[0]

# pair mapped labels and coefs and print them
for label, coef in zip(mapped_labels, coefs):
    print("%s:%0.5f" % (label, coef))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...