【问题标题】:TF-IDF algorithm in gremlingremlin 中的 TF-IDF 算法
【发布时间】:2014-06-24 19:51:46
【问题描述】:

我试图在我的 rexster 图形数据库中计算 TF_IDF。这是我得到的:

假设我有一个图,它由一组表示术语的顶点 T 和一组表示文档的顶点 D 组成。

在 T 中的术语和 D 中的文档之间存在边 E。每条边都有一个词频 tf。

例如。 (伪代码):

#x, y, and z are arbitrary IDs.
T(x) - E(y) -> D(z)

E(y).tf = 20

T(x).outE()
  => A set of edges.

T(x).outE().inV()
  => A list of Documents, a subset of D

当我尝试执行以下操作时,如何编写一个计算 TF_IDF 的 Germlin 脚本?

  • 答:给定一个词t,计算每个与t直接相关的Document的TF_IDF。
  • B:给定一组术语Ts,计算Ts.outE().inV()中每个文档的TF_IDF与Ts中每个适用术语相关的总和。

到目前为止我所拥有的:

#I know this does not work
term = g.v(404)
term.outE().inV().as('docs').path().
groupBy{it.last()}{
  it.findAll{it instanceof Edge}.
  collect{it.getProperty('frequency')} #I would actually like to use augmented frequency (aka frequency_of_t_in_document / max_frequency_of_any_t_in_document) 
}.collect{d,tf-> [d, 
  tf * ??log(??g.V.has('isDocument') / docs.count() ?? ) ??
]}

#I feel I am close, but I can't quite make this work.

【问题讨论】:

    标签: graph-databases gremlin tf-idf


    【解决方案1】:

    我可能还没有涵盖这部分

    B: ...关于Ts中的每个适用术语。

    ...但其余的应该按预期工作。我写了一个小辅助函数,它接受单个术语以及多个术语:

    tfidf = { g, terms, N ->
      def closure = {
        def paths = it.outE("occursIn").inV().path().toList()
        def numPaths = paths.size()
        [it.getProperty("term"), paths.collectEntries({
          def title = it[2].getProperty("title")
          def tf = it[1].getProperty("frequency")
          def idf = Math.log10(N / numPaths)
          [title, tf * idf]
        })]
      }
      def single = terms instanceof String
      def pipe = single ? g.V("term", terms) : g.V().has("term", T.in, terms)
      def result = pipe.collect(closure).collectEntries()
      single ? result[terms] : result
    }
    

    然后我拿维基百科的例子来测试一下:

    g = new TinkerGraph()
    
    g.createKeyIndex("type", Vertex.class)
    g.createKeyIndex("term", Vertex.class)
    
    t1 = g.addVertex(["type":"term","term":"this"])
    t2 = g.addVertex(["type":"term","term":"is"])
    t3 = g.addVertex(["type":"term","term":"a"])
    t4 = g.addVertex(["type":"term","term":"sample"])
    t5 = g.addVertex(["type":"term","term":"another"])
    t6 = g.addVertex(["type":"term","term":"example"])
    
    d1 = g.addVertex(["type":"document","title":"Document 1"])
    d2 = g.addVertex(["type":"document","title":"Document 2"])
    
    t1.addEdge("occursIn", d1, ["frequency":1])
    t1.addEdge("occursIn", d2, ["frequency":1])
    t2.addEdge("occursIn", d1, ["frequency":1])
    t2.addEdge("occursIn", d2, ["frequency":1])
    t3.addEdge("occursIn", d1, ["frequency":2])
    t4.addEdge("occursIn", d1, ["frequency":1])
    t5.addEdge("occursIn", d2, ["frequency":2])
    t6.addEdge("occursIn", d2, ["frequency":3])
    
    N = g.V("type","document").count()
    
    tfidf(g, "this", N)
    tfidf(g, "example", N)
    tfidf(g, ["this", "example"], N)
    

    输出:

    gremlin> tfidf(g, "this", N)
    ==>Document 1=0.0
    ==>Document 2=0.0
    gremlin> tfidf(g, "example", N)
    ==>Document 2=0.9030899869919435
    gremlin> tfidf(g, ["this", "example"], N)
    ==>this={Document 1=0.0, Document 2=0.0}
    ==>example={Document 2=0.9030899869919435}
    

    我希望这已经有所帮助。

    干杯, 丹尼尔

    【讨论】:

    • 一回到我的测试环境设置位置,我就会尝试一下!非常感谢! :D
    • 我遇到了一些麻烦。我怀疑它实际上与实现本身有关。我正在运行 Titan 0.4.2,我收到以下错误:WARNING: Exception during FilterChain execution java.lang.ClassCastException: com.tinkerpop.rexster.protocol.msg.ErrorResponseMessage cannot be cast to org.glassfish.grizzly.asyncqueue.WritableMessage *stack_trace*。知道如何解决这个问题吗?我自己尝试了所有部分,它们似乎可以工作..
    • 此错误与 tfidf 方法的最后一行有关:single ? result[terms] : result
    猜你喜欢
    • 2018-08-22
    • 2015-04-17
    • 2012-04-23
    • 1970-01-01
    • 2017-07-01
    • 2020-05-11
    • 2017-11-14
    • 1970-01-01
    • 2015-05-07
    相关资源
    最近更新 更多