Ich habe einen Pandas Datenrahmen, der Informationen über Nachrichten enthält, die vom Benutzer gesendet werden. Für mein Modell bin ich daran interessiert, fehlende Empfänger einer Nachricht zu prognostizieren i, e gegeben Empfänger A, B, C einer Nachricht Ich möchte vorhersagen, wer noch Teil der Empfänger sein sollte.Wie transformiert man mehrere Features in einer PipeLine mit FeatureUnion?
Ich mache Multi-Label-Klassifizierung mit OneVsRestClassifier und LinearSVC. Für Funktionen möchte ich die Empfänger der Nachricht verwenden. Thema und Körper.
Da Empfänger eine Liste von Benutzern ist, möchte ich diese Spalte mit MultiLabelBinarizer transformieren. Für Betreff und Text mag ich TFIDF
Mein Eingang Beize Dateidaten verwenden, haben wie folgt: Alle Werte sind Strings außer Empfänger die ein Satz()
[[message_id,sent_time,subject,body,set(recipients),message_type, is_sender]]
Ich bin mit benutzerdefinierter Funktion Vereinigung mit Transformatoren in der Pipeline, um dies wie folgt zu erreichen.
Ich bin mir nicht sicher, ob ich die featurization der CoRecipients Spalte richtig mache. Da die Ergebnisse nicht richtig aussehen. Irgendeine Ahnung?
UPDATE 1
den Code des MLB Transformators wie folgt verändert:
class MultiLabelTransformer(BaseEstimator, TransformerMixin):
def __init__(self, column):
self.column = column
def fit(self, X, y=None):
self.mlb = MultiLabelBinarizer()
self.mlb.fit(X[self.column])
return self
def transform(self, X):
return self.mlb.transform(X[self.column])
und fixiert den Test zu verwenden, setzen df_test
mlb = MultiLabelBinarizer(classes=top_recips)
train_x = df_train[['Subject', 'Body', 'CoRecipients']]
train_y = mlb.fit_transform(df_train['TopRecipients'])
test_x = df_test[['Subject', 'Body', 'CoRecipients']]
test_y = mlb.transform(df_test['TopRecipients'])
die unten sehend KeyError
Traceback (most recent call last):
File "E:\Projects\NLP\FeatureUnion.py", line 99, in <module>
predictions = pipeline.predict(test_x)
File "C:\Python27\lib\site-packages\sklearn\utils\metaestimators.py", line 115, in <lambda>
out = lambda *args, **kwargs: self.fn(obj, *args, **kwargs)
File "C:\Python27\lib\site-packages\sklearn\pipeline.py", line 306, in predict
Xt = transform.transform(Xt)
File "C:\Python27\lib\site-packages\sklearn\pipeline.py", line 768, in transform
for name, trans, weight in self._iter())
File "C:\Python27\lib\site-packages\sklearn\externals\joblib\parallel.py", line 779, in __call__
while self.dispatch_one_batch(iterator):
File "C:\Python27\lib\site-packages\sklearn\externals\joblib\parallel.py", line 625, in dispatch_one_batch
self._dispatch(tasks)
File "C:\Python27\lib\site-packages\sklearn\externals\joblib\parallel.py", line 588, in _dispatch
job = self._backend.apply_async(batch, callback=cb)
File "C:\Python27\lib\site-packages\sklearn\externals\joblib\_parallel_backends.py", line 111, in apply_async
result = ImmediateResult(func)
File "C:\Python27\lib\site-packages\sklearn\externals\joblib\_parallel_backends.py", line 332, in __init__
self.results = batch()
File "C:\Python27\lib\site-packages\sklearn\externals\joblib\parallel.py", line 131, in __call__
return [func(*args, **kwargs) for func, args, kwargs in self.items]
File "C:\Python27\lib\site-packages\sklearn\pipeline.py", line 571, in _transform_one
res = transformer.transform(X)
File "C:\Python27\lib\site-packages\sklearn\pipeline.py", line 426, in _transform
Xt = transform.transform(Xt)
File "E:\Projects\NLP\FeatureUnion.py", line 37, in transform
return self.mlb.transform(X[self.column])
File "C:\Python27\lib\site-packages\sklearn\preprocessing\label.py", line 765, in transform
yt = self._transform(y, class_to_index)
File "C:\Python27\lib\site-packages\sklearn\preprocessing\label.py", line 789, in _transform
indices.extend(set(class_mapping[label] for label in labels))
File "C:\Python27\lib\site-packages\sklearn\preprocessing\label.py", line 789, in <genexpr>
indices.extend(set(class_mapping[label] for label in labels))
KeyError: u'[email protected]'
> UPDATE 2
Arbeits Code
class MultiLabelTransformer(BaseEstimator, TransformerMixin):
def __init__(self, column, classes):
self.column = column
self.classes = classes
def fit(self, X, y=None):
self.mlb = MultiLabelBinarizer(classes=self.classes)
self.mlb.fit(X[self.column])
return self
def transform(self, X):
return self.mlb.transform(X[self.column])
# drop rows where top recipients = 0
df = df.loc[df['TopRecipients'].str.len() > 0]
df_train = df.loc[df['SentTime'] <= '2017-10-15']
df_test = df.loc[(df['SentTime'] > '2017-10-15') &
(df['MessageType'] == 'Meeting')]
mlb = MultiLabelBinarizer(classes=top_recips)
train_x = df_train[['Subject', 'Body', 'CoRecipients']]
train_y = mlb.fit_transform(df_train['TopRecipients'])
test_x = df_test[['Subject', 'Body', 'CoRecipients']]
test_y = mlb.transform(df_test['TopRecipients'])
# get all unique co-recipients
co_recips = list(set([a for b in df.CoRecipients.tolist() for a in b]))
# create pipeline
pipeline = Pipeline([
('features', FeatureUnion(
# list of features
transformer_list=[
('subject_tfidf', Pipeline([
('selector', ColumnSelector(column='Subject')),
('tfidf', TfidfVectorizer(min_df=0.0025, ngram_range=(1, 4)))
])),
('body_tfidf', Pipeline([
('selector', ColumnSelector(column='Body')),
('tfidf', TfidfVectorizer(min_df=0.0025, ngram_range=(1, 4)))
])),
('recipients_binarizer', Pipeline([
('multi_label', MultiLabelTransformer(column='CoRecipients', classes=co_recips))
]))
],
# weight components in FeatureUnion
transformer_weights={
'subject_tfidf': 3.0,
'body_tfidf': 1.0,
'recipients_binarizer': 1.0,
}
)),
('classifier', OneVsRestClassifier(LinearSVC(), n_jobs=-1))
])
print "train"
pipeline.fit(train_x, train_y)
print "predict"
predictions = pipeline.predict(test_x)
Ich habe den Code für MultiLabelTrasnformer wie Sie vorgeschlagen geändert und ich erhalte jetzt einen KeyError beim Versuch, auf test_x vorherzusagen Aktualisieren Sie den Code in der Q mit Änderungen vorgeschlagen. Ich glaube, dass der Fehler passiert, weil es einige Empfänger gibt, die nur in den Testdaten auftauchen, die nicht in den Zugdaten vorhanden sind, wie Sie angespielt haben. Wie kann ich das beheben, so dass der Multi-Label-Binarizer über alle möglichen Empfänger in Zug- und Test-Sets informiert? – user330612
@ user330612 Verwenden Sie das Attribut classes im 'MultiLabelTrasnformer' für alle bekannten Beschriftungen in der Spalte CoRecipients. So wie du es für y_train und y_test gemacht hast. –
Bekam das. Aber wie gebe ich diese Liste der einzigartigen CoRecipients an den MultiLabelTransformer weiter? co_recips = Liste (set ([a für b in df.CoRecipients.tolist() für a in b])) – user330612