jubatus/jubatus#448 における変更内容をまとめる。
大雑把には以下の変更を行った。
- 今まではdriverがmixableを持つ場合があった(driverごとにまちまち)
mixable_holderはdriverが持っているため、各アルゴリズムに対して、mixable_holderを受け取ってmixableを登録するregister_mixables(mixable_holder&)という関数を追加した。datum_to_fv_converterについてもmixableを移動した。
- 今まではアルゴリズムがモデルへの生ポインタを持っている場合があった
- その際、外からは
shared_ptrにくるんだmixableを渡す - そのために各アルゴリズムは
shared_ptr経由でmixableを持つ mixable_holder::get_mixablesを使う処理(mixerなど)もこれに追随させた
- アルゴリズムごとにストレージが異なる場合、その違いを透過的に扱えないため
- driverの
get_status関数においてストレージにアクセスしていたが、アルゴリズムにget_status関数を追加することで対応した。
anomalyやrecommenderなどは、異なるストレージが混在していたため、モデル型としてstd::stringを用いて、ストレージ側で型の違いを解決していた- MIX処理を簡潔に書けるようにするため、mixableのレベルで型解決するように変更した
- こうすることで、
framework::mixableが型の変換を勝手にやってくれるようになり、アルゴリズム開発者は冗長なserializationを書かずに済むようになる
- こうすることで、
- この変更のために、次のクラスに
MSGPACK_DEFINEを追加した。anomaly::lof_entry(元storage::lof_storage::lof_entry)common::key_managerstorage::bit_vectorstorage::lsh_entrystorage::sparse_matrix_storage
- 新しく追加されたmixableは、ストレージ
*_storageの定義されているヘッダにmixable_*_storageという名前で定義した。 - ほとんどのmixableはモデルの型が異なるだけで定義が一緒になったので、
framework::delegating_mixableに実装をまとめた。- これはアルゴリズムにMIX処理を委譲するだけのmixable。
- これでよいのか、MIX処理自体をアルゴリズムのクラスからmixableに移した方が良いのかについては 要検討 。
- 追加したmixableの一覧
- recommender
mixable_bit_index_storagemixable_inverted_index_storagemixable_lsh_index_storagemixable_recommender_mock_storage
- anomaly
mixable_lof_storage
- recommender
- 削除したmixableの一覧
mixable_recommendermixable_anomaly_storage
portable_mixerがstring型以外のモデルに対応していなかったので対応させた。- これらの変更に伴って、主にrecommenderとanomalyにおいてMIX処理における不必要な(de)serializationを削除した
以下、各タスクごとに上記以外の固有の変更について述べる。
classifier_baseのprotectedメンバ変数をprivateに移した- 代わりにprotectedの
get_storage関数を暫定的に追加した。 get_storageの戻り値に正しくconstをつけるために、storage_baseの関数get, get2, get3, inp, get_statusをconstメンバ関数に変更した。
- 代わりにprotectedの
- mixableは個別のアルゴリズム実装ではなく
classifier_baseに移動- 同じ
linear_function_mixerをmixableとして使っているため、暫定的に - 本当はインターフェイスを束ねるベースクラスと、共通のmixableに関する処理をまとめるベースクラスとは分けないといけない
- 特に今後異なるmixableを使うアルゴリズムを追加したくなったら、ここを分けないといけない
- 今は暫定的にここが密結合になっている
- 同じ
特になし
特になし
recommender_storage_baseを削除- ストレージ毎にmixableを分離し、それらを各アルゴリズムが所有するようにしたので、不要となった
recommender_storage.hppを削除
anomaly_storage_baseを削除- ストレージ毎にmixableを分離し、それらを各アルゴリズムが所有するようにしたので、不要となった
lof(recommenderベース)- ストレージが内部に
recommender_baseを持っていたが、アルゴリズム (lof) が持つように変更- ただしストレージも引き続き
recommender_baseを所有する(処理に用いるため)
- ただしストレージも引き続き
- MIX処理を
lofとrecommender_baseで完全に分けた lof_storageの名前空間をstorageからanomalyに変更(一貫性を増すため)lof_entryおよびlof_table_tの定義をlof_storageのprivateメンバからanomaly直下に移動- モデルの型として使うため
- ストレージが内部に
light_lof(nearest_neighborベース)light_lofのメンバ変数からmixable_nearest_neighbor_を削除- mixableに関する処理はすべて対応するアルゴリズムが行う(ここでは
nearest_neighbor_engine_)
- mixableに関する処理はすべて対応するアルゴリズムが行う(ここでは
mixable_weight_managerをdriver/からfv_converter/以下に移動
get_statusの役割・要求があまり決まっていないので、アルゴリズムにget_statusを置くのは反対です。仮という形で置いておく分には良いと思います。mixable(とストレージの区別もしつつ、では)
get_statusで何を返すべきか、どんな情報がアルゴリズムごとに異なるのか決まっていない・議論されていないため、共通化する部分・共通化できない部分はどこなのか整理する必要がありそうです。また、mixable依存の任意の情報の取得には、map<string, string> によるget_status よりもQt(QObject)のpropertyといった仕組みが向いていると思います。