機械学習とGridDBによる給与予測

線形回帰は、ある変数の値を別の変数の値に基づいて予測する教師あり機械学習手法です。予測される変数は「従属変数」と呼ばれ、他の変数の予測に使用される変数は「独立変数」と呼ばれます。線形回帰では、1つ以上の独立変数を使用して線形方程式の係数を推定します。線形回帰は、予測された出力値と期待される出力値の差を最小化する直線を生成します。

本稿では、JavaとGridDBを使用して、個人の経験年数に基づいて給与を予測する線形回帰モデルを実装します。

GridDBへのデータの書き込み

使用するデータは、個人の経験年数と給与を表します。

高速なクエリ性能など多くの利点を持つGridDBにデータを格納します。まず、Javaライブラリをインポートして、これを実現します。


import com.toshiba.mwcloud.gs.Collection;
import com.toshiba.mwcloud.gs.GSException;
import com.toshiba.mwcloud.gs.GridStore;
import com.toshiba.mwcloud.gs.GridStoreFactory;
import com.toshiba.mwcloud.gs.Query;
import com.toshiba.mwcloud.gs.RowKey;
import com.toshiba.mwcloud.gs.RowSet;
import java.util.*;

GridDBはデータをコンテナに整理し、各コンテナはJavaの静的クラスとして表現できます。データを格納するコンテナを表現するJavaの静的クラスを作成してみましょう。


static class SalaryData {
    @RowKey int id;
        double yearsExperience;
    double salary;
     }

GridDBコンテナを作成し、SalaryDataという名前を付けました。3つのカラムを持つSQLテーブルとして考えてください。

GridDBにデータを書き込むには、まずデータベースへの接続を確立する必要があります。そのためには、java.utilパッケージからPropertiesファイルを作成し、key:value構文を使用してGridDBの認証情報を渡す必要があります。


Properties props = new Properties();
props.setProperty("notificationMember", "127.0.1.1:10001");
props.setProperty("clusterName", "myCluster");
props.setProperty("user", "admin");
props.setProperty("password", "admin");
GridStore store = GridStoreFactory.getInstance().getGridStore(props);

データベースとのやり取りには store 変数を使用します。

接続が完了したので、GridDBにデータを格納することができます。まず、データ行を定義します。


SalaryData  row1 = new SalaryData();
row1.id=1;
row1.yearsExperience=1.1;
row1.salary=39343.00;

SalaryData  row2 = new SalaryData();
row2.id=2;
row2.yearsExperience=1.3;
row2.salary=46205.00;

SalaryData  row3 = new SalaryData();
row3.id=3;
row3.yearsExperience=1.5;
row3.salary=37731.00;

SalaryData  row4 = new SalaryData();
row4.id=4;
row4.yearsExperience=2.0;
row4.salary=43525.00;

SalaryData  row5 = new SalaryData();
row5.id=5;
row5.yearsExperience=2.2;
row5.salary=39891.00;

SalaryData  row6 = new SalaryData();
row6.id=6;
row6.yearsExperience=2.9;
row6.salary=56642.00;

SalaryData  row7 = new SalaryData();
row7.id=7;
row7.yearsExperience=3.0;
row7.salary=60150.00;

SalaryData  row8 = new SalaryData();
row8.id=8;
row8.yearsExperience=3.2;
row8.salary=54445.00;

SalaryData  row9 = new SalaryData();
row9.id=9;
row9.yearsExperience=3.2;
row9.salary=64445.00;

SalaryData  row10 = new SalaryData();
row10.id=10;
row10.yearsExperience=3.7;
row10.salary=57189.00;

SalaryData  row11 = new SalaryData();
row11.id=11;
row11.yearsExperience=3.9;
row11.salary=63218.00;

SalaryData  row12 = new SalaryData();
row12.id=12;
row12.yearsExperience=4.0;
row12.salary=55794.00;


SalaryData  row13 = new SalaryData();
row13.id=13;
row13.yearsExperience=4.0;
row13.salary=56957.00;

SalaryData  row14 = new SalaryData();
row14.id=14;
row14.yearsExperience=4.1;
row14.salary=57081.00;

SalaryData  row15 = new SalaryData();
row15.id=15;
row15.yearsExperience=4.5;
row15.salary=61111.00;

SalaryData  row16 = new SalaryData();
row16.id=16;
row16.yearsExperience=4.9;
row16.salary=67938.00;

SalaryData  row17 = new SalaryData();
row17.id=17;
row17.yearsExperience=5.1;
row17.salary=66029.00;

SalaryData  row18 = new SalaryData();
row18.id=18;
row18.yearsExperience=5.3;
row18.salary=83088.00;

SalaryData  row19 = new SalaryData();
row19.id=19;
row19.yearsExperience=5.9;
row19.salary=81363.00;

SalaryData  row20 = new SalaryData();
row20.id=20;
row20.yearsExperience=6.0;
row20.salary=93940.00;

SalaryData  row21 = new SalaryData();
row21.id=21;
row21.yearsExperience=6.8;
row21.salary=91738.00;

SalaryData  row22 = new SalaryData();
row22.id=22;
row22.yearsExperience=7.1;
row22.salary=98273.00;

SalaryData  row23 = new SalaryData();
row23.id=23;
row23.yearsExperience=7.9;
row23.salary=101302.00;

SalaryData  row24 = new SalaryData();
row24.id=24;
row24.yearsExperience=8.2;
row24.salary=113812.00;

SalaryData  row25 = new SalaryData();
row25.id=25;
row25.yearsExperience=8.7;
row25.salary=109431.00;

データを格納する SalaryData コンテナを選択しましょう。


Collection<String, SalaryData> sd= store.putCollection("SalaryData", SalaryData.class);

ここで put() 関数を呼び出して、データをデータベースに書き込むことができます。


sd.put(row1);
sd.put(row2);
sd.put(row3);
sd.put(row4);
sd.put(row5);
sd.put(row6);
sd.put(row7);
sd.put(row8);
sd.put(row9);
sd.put(row10);
sd.put(row11);
sd.put(row12);
sd.put(row13);
sd.put(row14);
sd.put(row15);
sd.put(row16);
sd.put(row17);
sd.put(row18);
sd.put(row19);
sd.put(row20);
sd.put(row21);
sd.put(row22);
sd.put(row23);
sd.put(row24);
sd.put(row25);

データの取得

GridDBからデータを取得し、機械学習モデルに適用します。SalaryDataコンテナに格納されているすべてのデータを選択して返すTQLクエリを記述します。


Query<salarydata> query = sd.query("select *");
RowSet</salarydata><salarydata> rs = query.fetch(false);
double x=0;
double y=0;
double[][] data = {{x},{y}};

System.out.println("Training dataset:");
while(rs.hasNext()) {
SalaryData sd1 = rs.next();
x=sd1.yearsExperience;
y=sd1.salary;


System.out.println(x +" "+ y);
double[][] d= {{x},{y}};
data=d.clone();

}</salarydata>

select * は、SalaryDataコンテナに格納されているすべてのデータを取得するTQLクエリです。また、データベースから取得した際のyearsExperieneとsalaryの値をそれぞれ格納するために、xとyという2つの変数を定義しました。データは、dataという名前の配列に格納されています。whileループは、GridDBコンテナのすべての行を繰り返し処理するのに役立ちます。

Wekaインスタンスの作成

Weka機械学習ライブラリを使用して線形回帰モデルを適合させます。 データをWekaインスタンスに変換する必要があります。 まず、データセットの属性を作成し、FastVectorデータ構造に格納します。 次に、データセットからWekaインスタンスを作成します。

まず、属性とインスタンスを格納するためのデータ構造を作成します。


int numInstances = data[0].length;
FastVector atts = new FastVector();
List<instance> instances = new ArrayList</instance><instance>();</instance>

afor ループを作成し、FastVector データ構造に属性を追加しながら、データ項目に反復処理を行うことができます。


for(int dim = 0; dim < 2; dim++)
    {
        Attribute current = new Attribute("Attribute" + dim, dim);

    if(dim == 0)
        {
       for(int obj = 0; obj < numInstances; obj++)
            {
                instances.add(new SparseInstance(numInstances));
            }
        }

       for(int obj = 0; obj < numInstances; obj++)
        {
            instances.get(obj).setValue(current, data[dim][obj]);
            
        }
        atts.addElement(current);
    }
    
Instances newDataset = new Instances("Dataset", atts, instances.size());

整数変数 dim は、属性を格納するための2次元データ構造を生成します。また、モデルの構築に使用する特定の属性を持つオブジェクトも作成しました。これらは newDataset という名前のインスタンス変数に格納されています。

線形回帰モデルの構築

データ・インスタンスはこれで準備が整いました。それらを使用して機械学習モデルを構築することができます。まず、Wekaから必要なライブラリをインポートしましょう:


import weka.classifiers.Classifier;
import weka.classifiers.Evaluation;
import weka.core.Attribute;
import weka.core.FastVector;
import weka.core.Instance;
import weka.core.Instances;
import weka.core.SparseInstance;

データセットにクラス属性を設定しましょう。


newDataset.setClassIndex(1);

上記のコードでは、salary をデータセットのクラス属性として設定しています。

次に、Wekaライブラリの LinearRegression() 関数を使用して、線形回帰分類器を構築します。


for(Instance inst : instances)
newDataset.add(inst);
Classifier classifier = new weka.classifiers.functions.LinearRegression();

classifier.buildClassifier(newDataset);

この関数のインスタンスを作成し、classifierという名前を付けました。次に、buildClassifier()関数を呼び出して、データセットを使用して分類器を構築しました。

予測を行う

線形回帰モデルを使用して、経験年数に基づいて給与を予測してみましょう。予測を行うために、データセットの最後のインスタンスを使用します。


Instance pd = newDataset.lastInstance();
double value = classifier.classifyInstance(pd);                 
        System.out.println(value);

pd は、私たちのデータセットの最後のインスタンスのインスタンスです。 classifyInstance() 関数は、そのインスタンスの salary の値を予測します。

モデルを実行

モデルを実行するには、まず次の URL から Weka API をダウンロードします。

http://www.java2s.com/Code/Jar/w/weka.htm

Wekaバージョン3.7.0を選択します。

ターミナルで次のコマンドを実行して、gridstore.jarおよびweka-3-7-0.jarファイルのクラス・パスを設定します。

export CLASSPATH=$CLASSPATH:/usr/share/java/gridstore.jar
export CLASSPATH=$CLASSPATH:/mnt/c/Users/user/Desktop/weka-3.7.0.jar

上記のコマンドは、ファイルの場所によって変更される場合があります。

次のコマンドを実行して、.javaファイルをコンパイルします。

javac Salary.java

生成された.classファイルを次のコマンドで実行します。

java Salary

モデルは、その人物の給与を109431.0ドルと予測しました。

ブログの内容について疑問や質問がある場合は Q&A サイトである Stack Overflow に質問を投稿しましょう。 GridDB 開発者やエンジニアから速やかな回答が得られるようにするためにも "griddb" タグをつけることをお忘れなく。 https://stackoverflow.com/questions/ask?tags=griddb

Leave a Reply

Your email address will not be published. Required fields are marked *