将 2 种不同类型的 X 训练数据同时传递给 ML 模型

数据挖掘 机器学习 Python scikit-学习 nlp
2022-03-05 04:13:12

我正在尝试根据标题和摘要对一本书是否是小说/非小说进行分类。

这是两种不同类型的信息 - 有没有办法在将其提供给模型之前进行分割,而不是连接信息titlesummary

例如:

标题:"such a long journey"

概括:"it is bombay in 1971, the year india went to..."

标签:("fiction"其中虚构=1)

当前程序:

到目前为止我一直在做的是连接信息,所以上面变成了,

example = "such a long journey it is bombay in 1971, the year india went to..."
label = 1

然后是通常的设置,例如,

X.append(example)
y.append(label)
...
X = lemmatize(X)
...
X_train, X_test, y_train, y_test = split_data(X,y)

vectorizer = TfidfVectorizer(...)
X_train = vectorizer.fit_transform(X_train)
X_test = vectorizer.transform(X_test)

classifier.fit(X_train, y_train)
y_predict = classifier.predict(X_test)

但是提供连接的数据在直觉上是错误的。有一个更好的方法吗?

如果由于某种原因它可能与 sklearn (keras,tensorflow)以外的库一起使用,我也愿意听到这个消息。


更新

从,

X = ['two'],['two'],['four'],['two'],['four'],['four']]
y = ['human','human','dog','human','dog','dog']

到,

X = [['two','hello'],['two','hello'],['four','bark'],['two','hi'],['four','bark'],['four','woof']]
y = ['human','human','dog','human','dog','dog']

导致错误被抛出。

'list' object has no attribute 'lower'is X 是一个列表,'numpy.ndarray' object has no attribute 'lower'如果 X 是一个数组。

当我打电话时抛出错误,

X_train = vectorizer.fit_transform(X_train)

是否可以传入特征向量?

3个回答

您可以在输入上应用两个独立的向量化步骤X(一个向量化器用于描述,另一个用于摘要),然后将获得的特征矩阵连接成单个特征矩阵。

这样做,您将拥有诸如 之类的功能description_"such", description_"long", ..., summary_"bombay", summary_"1971", ...,因此您应用的任何模型都将能够:

  1. 完全使用描述和摘要中的所有功能
  2. 赋予描述标记和摘要标记不同的权重

神经网络中,可以创建具有多个输入的模型除了连接,您可以为标题创建单独的输入,为摘要创建另一个输入,其中标题的输入大小小于摘要的输入大小。在 keras 中,您可以执行以下操作:

MAX_TITLE_LENGTH = 50
MAX_SUMMARY_LENGTH = 500
EMBEDDING_DIM = 50
CLASS_SIZE = 20

input_title = Input(shape=(MAX_TITLE_LENGTH,), name='input_title')
input_summary = Input(shape=(MAX_SUMMARY_LENGTH,), name='input_summary')

emb_title = Embedding(VOCAB_SIZE, EMBEDDING_DIM, input_length=MAX_TITLE_LENGTH)(input_title)
emb_summary = Embedding(VOCAB_SIZE, EMBEDDING_DIM, input_length=MAX_SUMMARY_LENGTH)(input_summary)

a = LSTM(128)(emb_title)
a = Dense(128, activation='relu')(a)

b = LSTM(512)(emb_summary)
b = Dense(128, activation='relu')(b)

z = Concatenate()([a, b])
z = Dense(128, activation='relu')(z)
output = Dense(CLASS_SIZE, activation='softmax')(z)

model = Model(inputs=[input_title , input_summary], outputs=output)

另外,关于您的错误:

'list' 对象没有属性 'lower'

您是否正在尝试将列表中的字符串转换为小写?如果是这样,请检查您的代码。它试图转换列表而不是字符串,因此出现此错误。

您看到的错误是因为您传递给 vectorizer 的输入是列表列表(或数组数组),而如TfidfVectorizer 语法中所述,您应该传递一系列字符串