如何将我的索引向量更改为可在 sklearn 中使用的稀疏特征向量?

Posted

技术标签:

【中文标题】如何将我的索引向量更改为可在 sklearn 中使用的稀疏特征向量?【英文标题】:How can I change my index vector into sparse feature vector that can be used in sklearn? 【发布时间】:2018-01-22 23:05:50 【问题描述】:

我正在做一个新闻推荐系统,我需要为用户和他们阅读的新闻建立一个表格。我的原始数据是这样的:

001436800277225 [12,456,157]
009092130698762 [248]
010003000431538 [361,521,83]
010156461231357 [173,67,244]
010216216021063 [203,97]
010720006581483 [86]
011199797794333 [142,12,86,411,201]
011337201765123 [123,41]
011414545455156 [62,45,621,435]
011425002581540 [341,214,286]

第一列是userID,第二列是newsIDnewsID是索引列,比如转换后,第一行[12,456,157]表示这个用户已经读了第12个,第 456 和 157 条新闻(在稀疏向量中,第 12 列、第 456 列和第 157 列是1,而其他列的值是0)。我想把这些数据改成稀疏向量格式,可以在Kmeans或sklearn的DBscan算法中用作输入向量。 我该怎么做?

【问题讨论】:

【参考方案1】:

一种选择是显式构造稀疏矩阵。我经常发现在COO matrix format 中构建矩阵然后转换为CSR format 更容易。

from scipy.sparse import coo_matrix

input_data = [
    ("001436800277225", [12,456,157]),
    ("009092130698762", [248]),
    ("010003000431538", [361,521,83]),
    ("010156461231357", [173,67,244])    
]

NUMBER_MOVIES = 1000 # maximum index of the movies in the data
NUMBER_USERS = len(input_data) # number of users in the model

# you'll probably want to have a way to lookup the index for a given user id.
user_row_map = 
user_row_index = 0

# structures for coo format
I,J,data = [],[],[]
for user, movies in input_data:

    if user not in user_row_map:
        user_row_map[user] = user_row_index
        user_row_index+=1

    for movie in movies:
        I.append(user_row_map[user])
        J.append(movie)
        data.append(1)  # number of times users watched the movie

# create the matrix in COO format; then cast it to CSR which is much easier to use
feature_matrix = coo_matrix((data, (I,J)), shape=(NUMBER_USERS, NUMBER_MOVIES)).tocsr()

【讨论】:

csr_matrix 接受 coo 样式的输入。在实践中,虽然它会做你所做的事情 - 创建一个 coo 然后转换。【参考方案2】:

sklearn.preprocessing使用MultiLabelBinarizer

from sklearn.preprocessing import MultiLabelBinarizer

mlb = MultiLabelBinarizer()

pd.DataFrame(mlb.fit_transform(df.newsID), columns=mlb.classes_)

   12   41   45   62   67   83   86   97   123  142 ...   244  248  286  341  361  411  435  456  521  621
0    1    0    0    0    0    0    0    0    0    0 ...     0    0    0    0    0    0    0    1    0    0
1    0    0    0    0    0    0    0    0    0    0 ...     0    1    0    0    0    0    0    0    0    0
2    0    0    0    0    0    1    0    0    0    0 ...     0    0    0    0    1    0    0    0    1    0
3    0    0    0    0    1    0    0    0    0    0 ...     1    0    0    0    0    0    0    0    0    0
4    0    0    0    0    0    0    0    1    0    0 ...     0    0    0    0    0    0    0    0    0    0
5    0    0    0    0    0    0    1    0    0    0 ...     0    0    0    0    0    0    0    0    0    0
6    1    0    0    0    0    0    1    0    0    1 ...     0    0    0    0    0    1    0    0    0    0
7    0    1    0    0    0    0    0    0    1    0 ...     0    0    0    0    0    0    0    0    0    0
8    0    0    1    1    0    0    0    0    0    0 ...     0    0    0    0    0    0    1    0    0    1
9    0    0    0    0    0    0    0    0    0    0 ...     0    0    1    1    0    0    0    0    0    0

【讨论】:

非常感谢。这是一个很好的方法。但是我的数据是高维的,大概800000*92000左右,每行1的个数只有不到10列,而其他90000+列都是0。我觉得这个方案可能会浪费很多资源,不不是吗? sklearn 可能有一个创建稀疏矩阵的处理器,如***.com/questions/45678491/… 中所述。 Pandas 稀疏格式不同于scipy 的一种。

以上是关于如何将我的索引向量更改为可在 sklearn 中使用的稀疏特征向量?的主要内容,如果未能解决你的问题,请参考以下文章

如何将我的代码从回调函数更改为承诺 [重复]

如何成功地将我的默认合并工具实用程序更改为 opendiff

如何将我的节点 winston JSON 输出更改为单行

如何将我的 UICollectionView Flowlayout 更改为具有水平滚动的垂直列表

如何将我的 JAVA 卡生命周期状态更改为 OP_READY?

BigQuery:如何将我的一列的类型从 INTEGER 更改为 STRING?