我在特征表的数据库中有一个这样的数据结构,称为token_vector
(哈希):
Feature.find(1).token_vector = { "a" => 0.1, "b" => 0.2, "c" => 0.3 }
其中有 25 个功能。首先,我将数据输入到 Redis 中script/console
:
REDIS.set( "feature1",
"#{ TokenVector.to_json Feature.find(1).token_vector }"
)
# ...
REDIS.set( "feature25",
"#{ TokenVector.to_json Feature.find(25).token_vector }"
)
TokenVector.to_json
首先将哈希转换为 JSON 格式。存储在 Redis 中的 25 个 JSON 散列占用大约 8 MB。
我有一个方法,叫做Analysis#locate
. 此方法采用两个 token_vector 之间的点积。哈希的点积是这样工作的:
hash1 = { "a" => 1, "b" => 2, "c" => 3 }
hash2 = { "a" => 4, "b" => 5, "c" => 6, "d" => 7 }
散列中的每个重叠键(在这种情况下为 a、b 和 c,而不是 d)将它们的值成对相乘,然后相加。
a
in的值为hash1
1,a
in的hash2
值为 4。将它们相乘得到1*4 = 4
。
b
in的值为hash1
2,b
in的hash2
值为 5。将它们相乘得到2*5 = 10
。
c
in的值为hash1
3,c
in的hash2
值为 6。将它们相乘得到3*6 = 18
。
d
in的值hash1
不存在,d
in的hash2
值为 7。在这种情况下,d = 0
为第一个散列设置。将这些相乘得到0*7 = 0
.
现在将相乘的值相加。4 + 10 + 18 + 0 = 32
. 这是 hash1 和 hash2 的点积。
Analysis.locate( hash1, hash2 ) # => 32
我有一个经常使用的方法,Analysis#topicize
. 这个方法接受一个参数,token_vector
,它只是一个哈希,类似于上面。取25 个特征中的每一个Analysis#topicize
的点积,并创建这 25 个点积的新向量,称为。A只是一个数组。代码如下所示:token_vector
token_vectors
feature_vector
feature_vector
def self.topicize token_vector
feature_vector = FeatureVector.new
feature_vector.push(
locate( token_vector, TokenVector.from_json( REDIS.get "feature1" ) )
)
# ...
feature_vector.push(
locate( token_vector, TokenVector.from_json( REDIS.get "feature25" ) )
)
feature_vector
end
如您所见,它采用我在上面输入 Redistoken_vector
的每个特征的点积token_vector
,并将值推送到数组中。
我的问题是,每次调用该方法大约需要 18 秒。我在滥用 Redis 吗?我认为问题可能是我不应该将 Redis 数据加载到 Ruby 中。我是否应该向 Redis 发送数据 ( token_vector
) 并编写一个 Redis 函数来让它执行该dot_product
函数,而不是用 Ruby 代码编写它?