2

私はまだscalaに習熟していませんが、それを使用していくつかのデータを処理し、ファイルから次のデータ構造に読み込みます。

Map[Id, (Set[Category], Set[Tag])]

どこ

type Id = String

type Category = String

type Tag = String

基本的に、の各キーはMap、一連のカテゴリと一連のタグに関連付けられているエンティティの一意のIDです。

私の質問は次のとおりです。計算するための最良の(=最も効率的で最も慣用的な)方法はどれですか。

  • すべてのエンティティの頻度にタグを付ける(type TagsFrequencies = Map[Tag, Double]
  • カテゴリごとのタグ頻度(Map[Category, TagsFrequencies]

これが私の試みです:

def tagsFrequencies(tags: List[Tag]): TagsFrequencies =
  tags.groupBy(t => t).map(
    kv => (kv._1 -> kv._2.size.toDouble / tags.size.toDouble))

def computeTagsFrequencies(data: Map[Id, (Set[Category], Set[Tag])]): TagsFrequencies = {
  val tags = data.foldLeft(List[Tag]())(
    (acc, kv) => acc ++ kv._2._2.toList)
  tagsFrequencies(tags)
}

def computeTagsFrequenciesPerCategory(data: Map[Id, (Set[Category], Set[Tag])]): Map[Category, TagsFrequencies] = {

  def groupTagsPerCategory(data: Map[Id, (Set[Category], Set[Tag])]): Map[Category, List[Tag]] =
    data.foldLeft(Map[Category, List[Tag]]())(
      (acc, kv) => kv._2._1.foldLeft(acc)(
        (a, category) => a.updated(category, kv._2._2.toList ++ a.getOrElse(category, Set.empty).toList)))

  val tagsPerCategory = groupTagsPerCategory(data)
  tagsPerCategory.map(tpc => (tpc._1 -> tagsFrequencies(tpc._2)))
}

例として、

val data = Map(
  "id1" -> (Set("c1", "c2"), Set("t1", "t2", "t3")),
  "id2" -> (Set("c1"), Set("t1", "t4")))

それから:

すべてのエンティティのタグ頻度は次のとおりです。

Map(t3 -> 0.2, t4 -> 0.2, t1 -> 0.4, t2 -> 0.2)

カテゴリごとのタグ頻度は次のとおりです。

Map(c1 -> Map(t3 -> 0.2, t4 -> 0.2, t1 -> 0.4, t2 -> 0.2), c2 -> Map(t3 -> 0.3333333333333333, t1 -> 0.3333333333333333, t2 -> 0.3333333333333333))
4

1 に答える 1

2

これはイディオムの書き直しですが、必ずしも効率ではありません。私はあなたの最初のメソッドをもう少し一般的にし(Iterable引数)、identityの代わりに使用しt => t、そして使用しますmapValues

def tagsFrequencies(tags: Iterable[Tag]): TagsFrequencies =
  tags.groupBy(identity).mapValues(_.size / tags.size.toDouble)

これで任意Iterable[Tag]のが必要になるため、これを使用して2番目の方法をクリーンアップできます。

def computeTagsFrequencies(data: Map[Id, (Set[Category], Set[Tag])]) =
  tagsFrequencies(data.flatMap(_._2._2))

そして最後の方法についても同様です。

def computeTagsFrequenciesPerCategory(data: Map[Id, (Set[Category], Set[Tag])]) =
  data.values.flatMap {
    case (cs, ts) => cs.map(_ -> ts)
  }.groupBy(_._1).mapValues(v => tagsFrequencies(v.flatMap(_._2)))

これらの変更はいずれも、意味のある方法でパフォーマンスに影響を与えることはありませんが、もちろん、独自のアプリケーションでベンチマークを行う必要があります。

于 2012-11-26T18:28:52.693 に答える