将其他数据合并到我的 TFIDF 数组
Combine additional data to my TFIDF array
我正在尝试使用 scikit-learn 创建文本分类模型。起初,我只使用文本的 tfidf 数组作为特征。我的数据集的结构如下所示(数据集存储在名为 df
的 pandas 数据框中):
>>>df.head(2)
id_1 id_2 id_3 target text
11 454 320 197 some text here
15 440 111 205 text goes here too
>>>df.info()
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 id_1 500 non-null uint16
1 id_2 500 non-null uint16
2 id_3 500 non-null uint16
3 target 500 non-null uint16
4 text 500 non-null object
因此,我拆分了 train/test 数据集并继续创建 tfidf 向量并转换数据以进行训练和测试。
X_train, X_test, y_train, y_test = train_test_split(df['text'], df['target'], random_state=0)
vectorizer = TfidfVectorizer(max_features=500, decode_error="ignore", ngram_range=(1, 2))
vectorizer.fit(X_train)
X_train_tfidf = vectorizer.transform(X_train)
X_test_tfidf = vectorizer.transform(X_test)
到目前为止,代码显然工作正常。但是,需要改进算法,包括另一个功能。对于此改进,我想将 id_1
列添加到我的特征中(它可能是我们 ML 模型的重要信息)。因此,除了我的 tfidf 矩阵之外,我还想添加此列 (id_1
) 和我的新功能,以便我可以将其作为参数传递来训练模型。
我尝试过的:
X_train, X_test, y_train, y_test = train_test_split(df['text'], df['target'], random_state=0)
vectorizer = TfidfVectorizer(max_features=500, decode_error="ignore", ngram_range=(1, 2))
vectorizer.fit(X_train)
X_train_tfidf = vectorizer.transform(X_train)
X_test_tfidf = vectorizer.transform(X_test)
X_train_all_features = pd.concat([pd.DataFrame(X_train_tfidf.toarray()), df['id_1']], axis = 1)
所以,我的结构形状是
>>>print(X_train_tfidf.shape)
(37, 500) # as expected (I'm loading 50 lines, so this is about 75%)
>>>print(X_train_all_features.shape)
(50, 501) # n of columns is expected, but not the lines, because the df[id_1] was not splited in train_test_split function
简而言之,我想传递给我的 ML 算法,如下图所示 - 我的 tfidf 向量和我的 id_1
特征:
我觉得我遗漏了一些非常基本的东西,但即使进行了所有研究,我仍然能够令人满意地解决我的问题。老实说,我迷失在问题的那一部分,我不知道如何从这里发展
理想情况下,您希望先添加新列,然后再进行拆分。如果出于某种原因这不合适,我建议如下:
您需要 X_train_tfidf 中的观察索引,以便能够从 df['id_1'] 中获得相应的值,因此不能简单地连接整个 df['id_1'] 列到 X_train_tfidf。尝试替换
X_train_all_features = pd.concat([pd.DataFrame(X_train_tfidf.toarray()), df['id_1']], axis = 1)
通过以下代码:
X_train_all_features = X_train_tfidf.copy()
X_train_all_features['id_1'] = df.loc[X_train_tfidf.index.values, 'id_1']
让我知道这是否有效。
你的 df 有 50 行,X_train_tfidf 37,pd.concat() returns 数据帧有 50 行,剩下的 13 行用 NaN 填充。
您将特征的所有值都添加到训练 tf-idf 中,这不是您想要的。
添加新列时不要搞乱train/val拆分,我建议在原始数据帧的索引上进行拆分
idx_train, idx_test = train_test_split(df.index, random_state=0)
X_train, y_train = df.loc[idx_train, 'text'], df.loc[idx_train, 'target']
# same for test
然后您可以添加 "id1" 功能:
X_train_all_features = pd.concat([pd.DataFrame(X_train_tfidf.toarray()), df.loc[idx_train, 'id_1']], axis = 1)
更新
我看不出将稀疏矩阵转换为 pandas 数据帧的原因。使用足够大的数据集会非常慢。相反,将您的特征添加到矩阵中,以便稍后在下游算法中使用它。
from scipy.sparse import hstack
X_train_tfidf = hstack([X_train_tfidf, df.loc[idx_train, 'id1'].values.reshape(-1, 1)])
检查尺寸
X_train_tfidf.shape # should be (37, 501)
我正在尝试使用 scikit-learn 创建文本分类模型。起初,我只使用文本的 tfidf 数组作为特征。我的数据集的结构如下所示(数据集存储在名为 df
的 pandas 数据框中):
>>>df.head(2)
id_1 id_2 id_3 target text
11 454 320 197 some text here
15 440 111 205 text goes here too
>>>df.info()
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 id_1 500 non-null uint16
1 id_2 500 non-null uint16
2 id_3 500 non-null uint16
3 target 500 non-null uint16
4 text 500 non-null object
因此,我拆分了 train/test 数据集并继续创建 tfidf 向量并转换数据以进行训练和测试。
X_train, X_test, y_train, y_test = train_test_split(df['text'], df['target'], random_state=0)
vectorizer = TfidfVectorizer(max_features=500, decode_error="ignore", ngram_range=(1, 2))
vectorizer.fit(X_train)
X_train_tfidf = vectorizer.transform(X_train)
X_test_tfidf = vectorizer.transform(X_test)
到目前为止,代码显然工作正常。但是,需要改进算法,包括另一个功能。对于此改进,我想将 id_1
列添加到我的特征中(它可能是我们 ML 模型的重要信息)。因此,除了我的 tfidf 矩阵之外,我还想添加此列 (id_1
) 和我的新功能,以便我可以将其作为参数传递来训练模型。
我尝试过的:
X_train, X_test, y_train, y_test = train_test_split(df['text'], df['target'], random_state=0)
vectorizer = TfidfVectorizer(max_features=500, decode_error="ignore", ngram_range=(1, 2))
vectorizer.fit(X_train)
X_train_tfidf = vectorizer.transform(X_train)
X_test_tfidf = vectorizer.transform(X_test)
X_train_all_features = pd.concat([pd.DataFrame(X_train_tfidf.toarray()), df['id_1']], axis = 1)
所以,我的结构形状是
>>>print(X_train_tfidf.shape)
(37, 500) # as expected (I'm loading 50 lines, so this is about 75%)
>>>print(X_train_all_features.shape)
(50, 501) # n of columns is expected, but not the lines, because the df[id_1] was not splited in train_test_split function
简而言之,我想传递给我的 ML 算法,如下图所示 - 我的 tfidf 向量和我的 id_1
特征:
我觉得我遗漏了一些非常基本的东西,但即使进行了所有研究,我仍然能够令人满意地解决我的问题。老实说,我迷失在问题的那一部分,我不知道如何从这里发展
理想情况下,您希望先添加新列,然后再进行拆分。如果出于某种原因这不合适,我建议如下:
您需要 X_train_tfidf 中的观察索引,以便能够从 df['id_1'] 中获得相应的值,因此不能简单地连接整个 df['id_1'] 列到 X_train_tfidf。尝试替换
X_train_all_features = pd.concat([pd.DataFrame(X_train_tfidf.toarray()), df['id_1']], axis = 1)
通过以下代码:
X_train_all_features = X_train_tfidf.copy()
X_train_all_features['id_1'] = df.loc[X_train_tfidf.index.values, 'id_1']
让我知道这是否有效。
你的 df 有 50 行,X_train_tfidf 37,pd.concat() returns 数据帧有 50 行,剩下的 13 行用 NaN 填充。
您将特征的所有值都添加到训练 tf-idf 中,这不是您想要的。
添加新列时不要搞乱train/val拆分,我建议在原始数据帧的索引上进行拆分
idx_train, idx_test = train_test_split(df.index, random_state=0)
X_train, y_train = df.loc[idx_train, 'text'], df.loc[idx_train, 'target']
# same for test
然后您可以添加 "id1" 功能:
X_train_all_features = pd.concat([pd.DataFrame(X_train_tfidf.toarray()), df.loc[idx_train, 'id_1']], axis = 1)
更新 我看不出将稀疏矩阵转换为 pandas 数据帧的原因。使用足够大的数据集会非常慢。相反,将您的特征添加到矩阵中,以便稍后在下游算法中使用它。
from scipy.sparse import hstack
X_train_tfidf = hstack([X_train_tfidf, df.loc[idx_train, 'id1'].values.reshape(-1, 1)])
检查尺寸
X_train_tfidf.shape # should be (37, 501)