我不确定如何在BigQuery(或任何SQL的方言)中有效地创建你想要的1-0(单热门)编码,但我绝对知道如何在Python中创建它 .
聚合这些数据以便在Python中使用的最有效方法可能是执行以下操作......
看起来你的BigQuery表遵循这个结构:
从this question开始,您可以使用以下内容将每个SKU聚合到一行:
SELECT UserID, STRING_AGG(SKU) AS SKU_string FROM my_transactions_table GROUP BY UserID
哪个应该给你这个(从上面的示例表):
从那里,在Python中使用这些数据非常容易:
>>> import pandas as pd
>>> df = pd.read_csv('~/Desktop/test.csv', sep='\t')
>>> df
UserID SKU_string
0 1 a,b,c
1 2 b,b
2 3 c,b,a
我们可以使用scikit-learn的CountVectorizer类来计算每个用户的每个产品的出现次数:
>>> from sklearn.feature_extraction.text import CountVectorizer
>>> vec = CountVectorizer(tokenizer=lambda x: x.split(','))
>>> X = vec.fit_transform(df['SKU_string'])
>>> X
<3x3 sparse matrix of type ''
with 7 stored elements in Compressed Sparse Row format>
>>> pd.DataFrame(X.toarray(), columns=vec.get_feature_names())
a b c
0 1 1 1
1 0 2 0
2 1 1 1
如果您愿意,可以将该矩阵加入DataFrame和您可能选择的其他用户元数据:
>>> df = df.join(pd.DataFrame(X.toarray(), columns=['product_{}'.format(x) for x in vec.get_feature_names()]))
>>> df
UserID SKU_string product_a product_b product_c
0 1 a,b,c 1 1 1
1 2 b,b 0 2 0
2 3 c,b,a 1 1 1
但是,如果你有尽可能多的不同产品,我很可能会建议不要这样做 . 10,000个产品会创建10,000个额外的 not-sparse 列,如果您拥有大量客户,可能会占用大量内存 .
此外,如果要将 X 对象( scipy.sparse.csr_matrix )严格转换为一零编码,请尝试以下操作:
>>> import numpy as np
>>> import scipy.sparse
>>> def booleanize_csr_matrix(mat):
... ''' Convert sparse matrix with positive integer elements to 1s '''
... nnz_inds = mat.nonzero()
... keep = np.where(mat.data > 0)[0]
... n_keep = len(keep)
... result = scipy.sparse.csr_matrix(
... (np.ones(n_keep), (nnz_inds[0][keep], nnz_inds[1][keep])),
... shape=mat.shape
... )
... return result
...
>>> pd.DataFrame(booleanize_csr_matrix(X).toarray(), columns=vec.get_feature_names())
a b c
0 1.0 1.0 1.0
1 0.0 1.0 0.0
2 1.0 1.0 1.0
从那里,您可以使用各种算法在用户的基础上推荐项目...您可以查看sklearn.metrics.pairwise.cosine_similarity来测量每个用户的购买向量之间的角度 .