質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.86%

  • Java

    12467questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • ArrayList

    75questions

    Java用のタグです。arrayListはListインターフェースを実装した、リサイズ可能な配列用クラスです。

類似度を使ったクラスタリング法

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 618

Yoshi-5630

score 3

実現したいこと

IaaSクラウドオントロジクラスタリングに関するシステムを作っています

要素(elem)と要素(elem)
要素(elem)とクラスタ(cluster)
クラスタ(cluster)とクラスタ(cluster)

このそれぞれ3種類を、類似度を使いJavaで実現したいと思っています。

発生している問題(分からないこと)

イメージとしては、類似度(Similarity)で
要素(elem)と要素(elem)を線で結ぶ
要素(elem)とクラスタ(cluster)を線で結ぶ
クラスタ(cluster)とクラスタ(cluster)を線で結ぶ

で作りたいと考えていますが、類似度を測った後、類似度が高い要素、又はクラスタを線で結ぶという表現をどのようにすればよいか(コードの書き方)がわからないという感じです。

このように3種類をそれぞれメソッドで実装したまでは普通なのですが、そこから全く手がついていません。

試したこと

本を引っ張り出して読んで、HashMapとか文字列結合などありましたが、どれも実装できませんでした。
単に自分がプログラミングが嫌いなので、逃げてるだけかもしれません。(このような場で言うことではないですが)

補足情報(言語/FW/ツール等のバージョンなど)

上記の説明ではわからないと思いますので、パワーポイントのスライドを添付させていただきます。

大変わかりづらい説明で恐縮でございますが、どうぞ宜しくお願いします。

[イメージ説明]

public class Plan1 {

    public static void main(String[] args) throws IOException {

        final String MODE = "CSV";
        final String ClusteringMode = "Avarage";
        double hreshold = 0.5d;
        int clusterSize = 32;
        String ontFile = "IaaS.owl";

        int elemSize = 0;
        HashMap<String, Integer> elemList = new HashMap<String, Integer>();
        double[][] similarity = null;

        OntModel m = ModelFactory.createOntologyModel();
        try {
            m.read(new FileInputStream("IaaS.owl"), "RDF/XML-ABBREV"); // 指定したファイルをバイナリファイルとして読み込む
        } catch (FileNotFoundException e) {
            e.printStackTrace();

        }
        HashMap<String, String> query = new HashMap<String, String>();
        OntModel ontModel = loadOnt("IaaS.owl");
        String mode = "NORMAL";
        String[] csv = loadCSV("cluster.csv");
        query.put("CPU", "");
        query.put("OS", "");
        query.put("Memory", "");
        query.put("GHz", "");
        query.put("HDD", "");
        query.put("SLA", "");
        query.put("RAM", "");
        query.put("Hourly_Usage_Rate", "");
        query.put("Monthly_Usage_Rate", "");
    }

    static String setClusterName(String line, OntModel m) throws IOException {
        String[] elems = toArray(line);
        HashMap<String, Integer> names = new HashMap<String, Integer>();
        for (int i = 0; i < elems.length; i++) {
            if (!elems[i].isEmpty() && !elems[i].equals("")) {
                OntClass targetClass = m
                        .getOntClass("http://www.owl-ontologies.com/Ontology1383285788.owl#" + elems[i]);

                @SuppressWarnings("unchecked")
                Iterator<OntClass> superClasses = targetClass.listSuperClasses(true);
                while (superClasses.hasNext()) {
                    OntClass superClass = superClasses.next();
                    if ((getString(superClass).equals("CPU") || getString(superClass).equals("Memory")
                            || getString(superClass).equals("GHz") || getString(superClass).equals("HDD")
                            || getString(superClass).equals("SLA") || getString(superClass).equals("RAM")
                            || getString(superClass).equals("Hourly_Usage_Rate")
                            || getString(superClass).equals("Hourly_Usage_Rate"))
                            && !names.containsKey(getString(superClass))) {
                        names.put(getString(superClass), 1);
                    } else if ((getString(superClass).equals("OS") || getString(superClass.getSuperClass()).equals("OS")
                            || getString(superClass.getSuperClass().getSuperClass()).equals("OS"))
                            && !names.containsKey(getString(superClass))) {
                        names.put("OS", 1);
                    }
                }
            }
        }
        line += ":";
        Iterator<String> name = names.keySet().iterator();
        while (name.hasNext()) {
            String key = name.next();
            line += key + ",";
        }
        return line.substring(0, line.length() - 1);
    }

    static double[][] setSimilarity(double[][] similarity) {// similarityの計算方法

        System.out.println("---- Set Similarity ----");
        for (int i = 0; i < similarity.length; i++) {
            for (int j = i + 1; j < similarity.length; j++) {
                similarity[i][j] = Math.random() + 0.1 * Math.random();
                if (similarity[i][j] == 0)
                    similarity[i][j] = 0.001;
                similarity[j][i] = similarity[i][j];
                System.out.println(i + "-" + j + ":" + similarity[i][j]);
            }
        }
        return similarity; // 計算結果をsimilarityに返す
    }

    @SuppressWarnings("unused")
    static void Elem_And_Elem(ArrayList<Integer>[] cluster, double[][] similarity, int elemSize, int currentNum)
            throws IOException {

        int a_min = 0;
        int b_min = 0;
        double sim_min = 1.0d;
        double sim_max = 0.0d;

        for (int i = 0; i < cluster[currentNum].size(); i++) {
            int num1 = cluster[currentNum].get(i);
            for (int j = 0; j < cluster[currentNum].size(); j++) {
                int num2 = cluster[currentNum].get(j);
                if (similarity[num1][num2] < sim_min && num1 != num2) {
                    if (cluster[currentNum * 2].isEmpty() && cluster[currentNum * 2 + 1].isEmpty()) {
                        a_min = num1;
                        b_min = num2;
                        sim_min = similarity[num1][num2];
                    } else if (!cluster[currentNum * 2].contains(num1) && !cluster[currentNum * 2 + 1].contains(num2)) {
                        a_min = num1;
                        b_min = num2;
                        sim_min = similarity[num1][num2];
                    }
                }
            }
            if (sim_min == 1.0d)
                break;
       }
    }

    static void Cluster_And_Elem(ArrayList<Integer>[] cluster, double[][] similarity, int elemSize, int currentNum) throws IOException {

    @SuppressWarnings("unchecked") // ClusteringTest.javaより引用
    static void Cluster_And_Cluster(double[][] similarity, int elemSize, int clusterSize,
            HashMap<String, Integer> elemList, String ontFile, OntModel m) throws IOException {

        ArrayList<Integer>[] cluster = new ArrayList[clusterSize * 2];
        // ArrayList
        for (int i = 0; i < clusterSize * 2; i++) { // 0からクラスタサイズの2倍作成を繰り返す
            cluster[i] = new ArrayList<Integer>();
        }


        for (int i = 0; i < elemSize; i++) {
            cluster[1].add(i);
        }

        cluster = ClusteringProccess(cluster, similarity, elemSize, 1); //

        // クラスタリングの結果
        System.out.println("---- Clustering Result ----");
        for (int i = 0; i < cluster.length; i++) {
            System.out.print("Cluster[" + i + "]:");
            for (int j = 0; j < cluster[i].size(); j++) {
                System.out.print(cluster[i].get(j) + " ");
            }
            System.out.println("");
            return;
        }
    }

    private static ArrayList<Integer>[] ClusteringProccess(ArrayList<Integer>[] cluster, double[][] similarity,
            int elemSize, int i) throws IOException {
        // TODO 自動生成されたメソッド・スタブ
        return null;
    }

    @SuppressWarnings("unused")
    private static String[] toArray(String line) throws IOException {
        return line.split(":")[1].split(",");
    }

    /**
     *
     * @param rdfNode
     * @return
     */
    @SuppressWarnings("unused")
    private static String getString(RDFNode rdfNode) {
        return rdfNode.toString().substring(rdfNode.toString().indexOf("#") + 1, rdfNode.toString().length());
    }


    private static String[] loadCSV(String file) throws IOException {
        ArrayList<String> csv = new ArrayList<String>();
        FileReader fr;
        try {
            fr = new FileReader(file);
            BufferedReader br = new BufferedReader(fr);
            String line;
            while ((line = br.readLine()) != null) {
                csv.add(line);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return (String[]) csv.toArray(new String[0]);
    }


    private static OntModel loadOnt(String file) {
        OntModel ontModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);

        try {
            ontModel.read(new FileInputStream(file), "RDF/XML-ABBREV");
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        }
        return ontModel;
    }
}

※ソースコードの全体を載せます。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • swordone

    2017/01/05 00:33

    クラスタはここではIntegerの配列の配列ということになるのですか?クラスタを実現するその型を独自クラスなどに変えることは可能ですか?

    キャンセル

  • yuba

    2017/01/05 07:53

    線で結ぶというのは、ビジュアル表現上線で結びたいという話ですか? それともデータ構造的にリンクされた状態を表現したいという話ですか?

    キャンセル

  • Yoshi-5630

    2017/01/05 10:01

    型の表現の、変更は可能です。

    キャンセル

  • Yoshi-5630

    2017/01/05 10:02

    線で結ぶというのは、データ構造上でリンクと言う意味です。

    キャンセル

回答 2

checkベストアンサー

+1

スライドの雰囲気から大学の講義課題のようにお見受けしますので、指導教官の方の意図する教育効果を損なわないよう慎重めに(一から十まで答えを書いてしまわないよう気をつけて)回答します。

要素間のリンクをどう表現するかですが、これは大体どのアルゴリズム本にも先頭の方に書いてあり、「二分木」というデータ構造を用います。
二分木をJavaでどう書き下ろすかは、「継承」もしくは「実装」という方法を使います。

ここまでまず調べてみてください。
わからないところはコメント欄で質問してもらって続けましょう(ただし、本当に講義課題であるなら、まずは指導教官に質問するのが筋かと思います。彼らは学生をサポートするという業務のために報酬をもらっているわけですから)。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/01/05 12:41 編集

    ご回答ありがとうございます。

    yuba様の言われる方法を調べてみようと思います。

    講義資料ではなくて、より質問内容をイメージをしやすくするために、あの様な書式になってしまいました。

    キャンセル

0

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;

public class DendrogramMax {


    public static void main(String[] args) throws IOException {
        int N = 647; //要素647
        HashMap<String, Integer> elemList = LoadDepth(); //elemListという名前のハッシュマップにLoadDepthを割り当てる
        double[][] similarity = LoadSimilarity(N, elemList); //double [][] similarityを(N,elemList)とする

        HashMap<Integer, ElemPair> objectList = new HashMap<Integer, ElemPair>(); //objectListを初期化

        for(int i = 0; i < N; i++){
            objectList.put(i, new ElemPair(i+"", i, null, 1));
            System.out.println(i+": "+i+", null, 1");
        } //要素の数647だけ要素のペアの作成を繰り返す

        System.out.println("---------------------------");

        String result = null;
        while(objectList.size()>1){
            double max_value = 0;
            int max_i = 0; //max_iに0を代入
            int max_j = 0; //max_jに0を代入
            int max_key1 = 0; //max_key1に0を代入
            int max_key2 = 0; //max_key2に0を代入
            for(int key1 : objectList.keySet()){
                ElemPair elemPair1 = objectList.get(key1);
                String[] elems1 = elemPair1.elems.replace("{", "").replace("}", "").split(",");
                for(int i = 0; i<elems1.length; i++){
                    for(int key2 : objectList.keySet()){
                        ElemPair elemPair2 = objectList.get(key2);
                        String[] elems2 = elemPair2.elems.replace("{", "").replace("}", "").split(",");
                        for(int j = 0; j<elems2.length; j++){
                            if(similarity[Integer.parseInt(elems1[i])][Integer.parseInt(elems2[j])] > max_value && !elems1[i].equals(elems2[j]) && key1 != key2){
                                max_i = Integer.parseInt(elems1[i]);
                                max_j = Integer.parseInt(elems2[j]);
                                max_key1 = key1; //類似度の高い要素をkey1とする
                                max_key2 = key2; ///類似度の高い要素をkey2とする
                                max_value = similarity[Integer.parseInt(elems1[i])][Integer.parseInt(elems2[j])];
                            }
                        }
                    }
                }
            }
            ElemPair elemLeft = objectList.get(max_key1); //要素の左側(〇,     )にmax_key1を格納
            ElemPair elemRight = objectList.get(max_key2);  //要素の右側(   ,  〇 )にmax_key1を格納
            objectList.remove(max_key1); //ObjectListからmax_key1を削除
            objectList.remove(max_key2); //ObjectListからmax_key2を削除
            objectList.put(max_key1, new ElemPair("{"+elemLeft.elems+","+elemRight.elems+"}", elemLeft, elemRight, max_value));
            result = "{"+elemLeft.elems+","+elemRight.elems+"}";
            System.out.println(objectList.size());
            System.out.println(" {"+elemLeft.elems+","+elemRight.elems+" }: "+elemLeft+", "+elemRight+", "+max_value);

        }


        System.out.println("---------------------------");
        System.out.println("Elements list:");
        for(String key: elemList.keySet()){ //アルファベット順に振った要素番号を647個表示されるまで繰り返す
            System.out.println(key+": "+elemList.get(key));
        }
        System.out.println();
        System.out.println("Dendrogram:");
        System.out.println(result); //結果を表示

    }

    private static HashMap<String, Integer> LoadDepth() throws IOException{
        HashMap<String, Integer> elemList = new HashMap<String, Integer>();
        FileReader fr = new FileReader("depth.csv"); //depthの読み込み
        BufferedReader br = new BufferedReader(fr);
        String line = null;
        int count = 0;
        while ((line = br.readLine()) != null) {
            elemList.put(line.split(",")[0], count);
            count++;
        }
        return elemList;
    }

    private static double[][] LoadSimilarity(int N, HashMap<String, Integer> elemList) throws NumberFormatException, IOException{
        String line = null;
        double[][] similarity = new double[N][N]; //MとNで多次元配列を初期化
        FileReader fr = new FileReader("similarity.csv"); //similarity.csvを読み込み
        BufferedReader br = new BufferedReader(fr);
        while ((line = br.readLine()) != null) {
            similarity[elemList.get(line.split(",")[2])][elemList.get(line.split(",")[3])] = Double.parseDouble(line.split(",")[1]);
        }

        return similarity; //similarityに返す
    }

}

class ElemPair{
    String elems;
    Object elem1;
    Object elem2;
    double distance;

    public ElemPair(String elems, Object elem1, Object elem2, double distance){
        this.elems = elems;
        this.elem1 = elem1;
        this.elem2 = elem2;
        this.distance = distance;
    }
}

という形でできました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.86%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 解決済

    Java if文を多様しないで組みたい

    現在Javaにて名前と科目を入力したら登録した点数がでるプログラムを組んでいます。 エラーは無いのですがif文を多様してしまっているのでif文をあまり使わずに作りたいです。

  • 解決済

    Javaでarraylistを使って任意順のソートをしたい

    前提・実現したいこと CSVを読んで中身を変換、ソートして標準出力をしたい。 CSVの中身は 1 A100,yyyyMMdd,名前 S234,yyyyMMdd,名前

  • 解決済

    異なる配列の要素比較

    現在wikipediaのダンプからデータを抽出しています。 ダンプから一部データを抽出することに成功しており、テキストファイルが二つできています。以下がその内容です。 1:「本

  • 解決済

    Javaもしくは、openoffice calcを用いて様々な文字列を数値に変換したい

    Javaについての質問です。 このようなテキストファイルがあるとします userID           venueID     star g;ajgfadjfajk

  • 解決済

    Javaでのcsv読み取り、合計、上位5位のみ書き出し

    前提・実現したいこと 1)Javaで下図のようなcsvデータ(学校のテストの結果)を読み取る 氏名,英語,国語,数学 山田,80,70,60, 佐藤,70,50,90,

  • 解決済

    ResultSetをまとめて(?)取得する

    Java 超初心者です。 DBに接続し、ブラウザ上にデータベースのデータを検索し表示するプログラムです。 A,B,C三つの名称があるテーブルがあります。 ブラウザ上の検索

  • 解決済

    入力した整数を一文字ずつ配列に格納する方法

    前提・実現したいこと Javaで標準入力に現れた数字文字の出現回数を表示するプログラムを作っています。 入力した整数を一文字ずつ配列に格納する方法が知りたいです。 該当の

  • 解決済

    Java map使い方、書き方

    数値、 文字列 日付を持ったクラスを 数値をキーにmapでこのクラスのデータを 保持するには どうすれば実現できますか。 簡単な質問で失礼します。

同じタグがついた質問を見る

  • Java

    12467questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • ArrayList

    75questions

    Java用のタグです。arrayListはListインターフェースを実装した、リサイズ可能な配列用クラスです。