Skip to main content
 首页 » 编程设计

python - 使用 sklearn 和 pandas 在一个模型中结合词袋和其他特征

2023年05月26日8unruledboy

我正在尝试根据帖子的文本和其他特征(一天中的时间、帖子的长度等)对帖子的得分进行建模

我想知道如何将这些不同类型的功能最好地组合到一个模型中。现在,我有类似以下的内容(从 herehere 窃取)。

import pandas as pd 
... 
 
def features(p): 
    terms = vectorizer(p[0]) 
    d = {'feature_1': p[1], 'feature_2': p[2]} 
    for t in terms: 
        d[t] = d.get(t, 0) + 1 
    return d 
 
posts = pd.read_csv('path/to/csv') 
 
# Create vectorizer for function to use 
vectorizer = CountVectorizer(binary=True, ngram_range=(1, 2)).build_tokenizer() 
y = posts["score"].values.astype(np.float32)  
vect = DictVectorizer() 
 
# This is the part I want to fix 
temp = zip(list(posts.message), list(posts.feature_1), list(posts.feature_2)) 
tokenized = map(lambda x: features(x), temp) 
X = vect.fit_transform(tokenized) 

从 pandas 数据框中提取我想要的所有特征,只是将它们全部压缩在一起,这似乎很愚蠢。有没有更好的方法来完成这一步?

CSV 如下所示:

ID,message,feature_1,feature_2 
1,'This is the text',4,7 
2,'This is more text',3,2 
... 

请您参考如下方法:

你可以用你的 map 和 lambda 做任何事情:

tokenized=map(lambda msg, ft1, ft2: features([msg,ft1,ft2]), posts.message,posts.feature_1, posts.feature_2) 

这样可以节省临时临时步骤并遍历 3 列。

另一种解决方案是将消息转换为它们的 CountVectorizer 稀疏矩阵,并将该矩阵与来自帖子数据帧的特征值连接起来(这将跳过必须构造一个 dict 并生成一个类似于使用 DictVectorizer 得到的稀疏矩阵):

import scipy as sp 
posts = pd.read_csv('post.csv') 
 
# Create vectorizer for function to use 
vectorizer = CountVectorizer(binary=True, ngram_range=(1, 2)) 
y = posts["score"].values.astype(np.float32)  
 
X = sp.sparse.hstack((vectorizer.fit_transform(posts.message),posts[['feature_1','feature_2']].values),format='csr') 
X_columns=vectorizer.get_feature_names()+posts[['feature_1','feature_2']].columns.tolist() 
 
 
posts 
Out[38]:  
   ID              message  feature_1  feature_2  score 
0   1   'This is the text'          4          7     10 
1   2  'This is more text'          3          2      9 
2   3   'More random text'          3          2      9 
 
X_columns 
Out[39]:  
[u'is', 
 u'is more', 
 u'is the', 
 u'more', 
 u'more random', 
 u'more text', 
 u'random', 
 u'random text', 
 u'text', 
 u'the', 
 u'the text', 
 u'this', 
 u'this is', 
 'feature_1', 
 'feature_2'] 
 
X.toarray() 
Out[40]:  
array([[1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 4, 7], 
       [1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 3, 2], 
       [0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 3, 2]]) 

另外 sklearn-pandas 还具有 DataFrameMapper,它也可以满足您的需求:

from sklearn_pandas import DataFrameMapper 
mapper = DataFrameMapper([ 
    (['feature_1', 'feature_2'], None), 
    ('message',CountVectorizer(binary=True, ngram_range=(1, 2))) 
]) 
X=mapper.fit_transform(posts) 
 
X 
Out[71]:  
array([[4, 7, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1], 
       [3, 2, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1], 
       [3, 2, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0]]) 

注意:使用最后一种方法时,X 不是稀疏的。

X_columns=mapper.features[0][0]+mapper.features[1][1].get_feature_names() 
 
X_columns 
Out[76]:  
['feature_1', 
 'feature_2', 
 u'is', 
 u'is more', 
 u'is the', 
 u'more', 
 u'more random', 
 u'more text', 
 u'random', 
 u'random text', 
 u'text', 
 u'the', 
 u'the text', 
 u'this', 
 u'this is']