TribuoライブラリおよびOracle JDBCを使用したJavaでの機械学習の概要 (2025/12/30)
TribuoライブラリおよびOracle JDBCを使用したJavaでの機械学習の概要 (2025/12/30)
投稿者:Juarez Junior

はじめに
以前のブログ記事では、Oracle LabsのプロジェクトであるSD4Jライブラリについて取り上げました。また、Oracle LabsはGraalVMも開発しており、Java開発者であれば説明の必要もないでしょう。
さて、Oracle LabsのライブラリであるTribuo Machine Learning Libraryについて学びましょう。TribuoはJavaで記述され、Apache v2.0ライセンスで提供されるオープンソースの機械学習ライブラリです。
一般的なMLアルゴリズムを実装し、ONNX Runtime、TensorFlow、 XGBoost、LibLinearといったサードパーティ製MLライブラリへの統合インターフェースを提供します。ネイティブコードへのインターフェースも備えているため、Tribuoはscikit-learnやPyTorchといったPythonライブラリでトレーニングしたモデルをJavaプログラムの一部として
デプロイすることも可能です。
このブログ記事では、ソフトウェア開発者が習得すべき興味深い機械学習ライブラリであるTribuoを紹介します。前半では、Jupyter Notebookを使ってJavaコードを実行し、Tribuoライブラリを使用する方法を説明します。後半では、Oracle AI Database 26aiを使った例を見ていきます。
AI、機械学習、データサイエンスの基礎知識があることが推奨されます。MLの入門書が必要な場合は、こちらのブログ記事「機械学習とは?」をご覧ください。
では、これ以上お待たせせずに、始めましょう!
前提条件
- JDK — Java 開発キット17+
- Oracle AI Database 26ai 無料コンテナイメージ
- Oracle JDBC ドライバー
- 好みの Java IDE — Eclipse、IntelliJ、VS Code
- Apache MavenまたはGradle
- Irisデータセット — IRIS という名前のテーブルにロードされます。
- 環境変数DB_USERNAMEとDB_PASSWORDは、データベース接続をサポートするために構成されています。
ステップ1: Javaアプリケーションを構成する
次の依存関係を使用してMaven pom.xmlファイルを構成します: Oracle JDBCドライバー、Tribuo v4.3.2、およびその他の依存関係。
Mavenの使用
<!-- Tribuo v4.3.2 -->
<dependency>
<groupId>org.tribuo</groupId>
<artifactId>tribuo-all</artifactId>
<version>4.3.2</version>
<type>pom</type>
</dependency>
<!-- Oracle AI Database 26ai JDBC / UCP -->
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc17</artifactId>
<version>${jdbc.version}</version>
</dependency>
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ucp17</artifactId>
<version>${jdbc.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.23.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.23.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.23.1</version>
</dependency>ステップ2: Irisデータセットと対応するデータベーステーブル
アイリスデータセットは、1936年にイギリスの統計学者ロナルド・フィッシャーによって導入された、古典的な多変量データセットです。このデータセットは、アヤメ(Iris setosa)、アヤメ(Iris versicolor)、アヤメ(Iris virginica)の3種からそれぞれ50個ずつ、計150個のアヤメの花の標本で構成されています。各標本について、萼片の長さ、萼片の幅、花弁の長さ、花弁の幅という4つの特徴がセンチメートル単位で測定されています。このデータセットは、そのシンプルさと明確な分離性で知られており、分類手法のデモンストレーションに最適です。
以下に示すように、Oracle Database テーブルにロードするための簡単な SQL スクリプトを作成しました。
-- TABLE DDL
CREATE TABLE IRIS (
id NUMBER,
sepallengthcm NUMBER,
sepalwidthcm NUMBER,
petallengthcm NUMBER,
petalwidthcm NUMBER,
species VARCHAR2(20 BYTE)
);
COMMIT;
-- INSERT STATEMENTS (ALL SAMPLES)
INSERT INTO IRIS VALUES (1,5.1,3.5,1.4,0.2,'Iris-setosa');
INSERT INTO IRIS VALUES (2,4.9,3,1.4,0.2,'Iris-setosa');
INSERT INTO IRIS VALUES (3,4.7,3.2,1.3,0.2,'Iris-setosa');
INSERT INTO IRIS VALUES (4,4.6,3.1,1.5,0.2,'Iris-setosa');
INSERT INTO IRIS VALUES (5,5,3.6,1.4,0.2,'Iris-setosa');
INSERT INTO IRIS VALUES (6,5.4,3.9,1.7,0.4,'Iris-setosa');
INSERT INTO IRIS VALUES (7,4.6,3.4,1.4,0.3,'Iris-setosa');
INSERT INTO IRIS VALUES (8,5,3.4,1.5,0.2,'Iris-setosa');
INSERT INTO IRIS VALUES (9,4.4,2.9,1.4,0.2,'Iris-setosa');
INSERT INTO IRIS VALUES (10,4.9,3.1,1.5,0.1,'Iris-setosa');
INSERT INTO IRIS VALUES (11,5.4,3.7,1.5,0.2,'Iris-setosa');
INSERT INTO IRIS VALUES (12,4.8,3.4,1.6,0.2,'Iris-setosa');
INSERT INTO IRIS VALUES (13,4.8,3,1.4,0.1,'Iris-setosa');
INSERT INTO IRIS VALUES (14,4.3,3,1.1,0.1,'Iris-setosa');
INSERT INTO IRIS VALUES (15,5.8,4,1.2,0.2,'Iris-setosa');
INSERT INTO IRIS VALUES (16,5.7,4.4,1.5,0.4,'Iris-setosa');
INSERT INTO IRIS VALUES (17,5.4,3.9,1.3,0.4,'Iris-setosa');
INSERT INTO IRIS VALUES (18,5.1,3.5,1.4,0.3,'Iris-setosa');
INSERT INTO IRIS VALUES (19,5.7,3.8,1.7,0.3,'Iris-setosa');
INSERT INTO IRIS VALUES (20,5.1,3.8,1.5,0.3,'Iris-setosa');
INSERT INTO IRIS VALUES (21,5.4,3.4,1.7,0.2,'Iris-setosa');
INSERT INTO IRIS VALUES (22,5.1,3.7,1.5,0.4,'Iris-setosa');
INSERT INTO IRIS VALUES (23,4.6,3.6,1,0.2,'Iris-setosa');
INSERT INTO IRIS VALUES (24,5.1,3.3,1.7,0.5,'Iris-setosa');
INSERT INTO IRIS VALUES (25,4.8,3.4,1.9,0.2,'Iris-setosa');
INSERT INTO IRIS VALUES (26,5,3,1.6,0.2,'Iris-setosa');
INSERT INTO IRIS VALUES (27,5,3.4,1.6,0.4,'Iris-setosa');
INSERT INTO IRIS VALUES (28,5.2,3.5,1.5,0.2,'Iris-setosa');
INSERT INTO IRIS VALUES (29,5.2,3.4,1.4,0.2,'Iris-setosa');
INSERT INTO IRIS VALUES (30,4.7,3.2,1.6,0.2,'Iris-setosa');
INSERT INTO IRIS VALUES (31,4.8,3.1,1.6,0.2,'Iris-setosa');
INSERT INTO IRIS VALUES (32,5.4,3.4,1.5,0.4,'Iris-setosa');
INSERT INTO IRIS VALUES (33,5.2,4.1,1.5,0.1,'Iris-setosa');
INSERT INTO IRIS VALUES (34,5.5,4.2,1.4,0.2,'Iris-setosa');
INSERT INTO IRIS VALUES (35,4.9,3.1,1.5,0.1,'Iris-setosa');
INSERT INTO IRIS VALUES (36,5,3.2,1.2,0.2,'Iris-setosa');
INSERT INTO IRIS VALUES (37,5.5,3.5,1.3,0.2,'Iris-setosa');
INSERT INTO IRIS VALUES (38,4.9,3.1,1.5,0.1,'Iris-setosa');
INSERT INTO IRIS VALUES (39,4.4,3,1.3,0.2,'Iris-setosa');
INSERT INTO IRIS VALUES (40,5.1,3.4,1.5,0.2,'Iris-setosa');
INSERT INTO IRIS VALUES (41,5,3.5,1.3,0.3,'Iris-setosa');
INSERT INTO IRIS VALUES (42,4.5,2.3,1.3,0.3,'Iris-setosa');
INSERT INTO IRIS VALUES (43,4.4,3.2,1.3,0.2,'Iris-setosa');
INSERT INTO IRIS VALUES (44,5,3.5,1.6,0.6,'Iris-setosa');
INSERT INTO IRIS VALUES (45,5.1,3.8,1.9,0.4,'Iris-setosa');
INSERT INTO IRIS VALUES (46,4.8,3,1.4,0.3,'Iris-setosa');
INSERT INTO IRIS VALUES (47,5.1,3.8,1.6,0.2,'Iris-setosa');
INSERT INTO IRIS VALUES (48,4.6,3.2,1.4,0.2,'Iris-setosa');
INSERT INTO IRIS VALUES (49,5.3,3.7,1.5,0.2,'Iris-setosa');
INSERT INTO IRIS VALUES (50,5,3.3,1.4,0.2,'Iris-setosa');
INSERT INTO IRIS VALUES (51,7,3.2,4.7,1.4,'Iris-versicolor');
INSERT INTO IRIS VALUES (52,6.4,3.2,4.5,1.5,'Iris-versicolor');
INSERT INTO IRIS VALUES (53,6.9,3.1,4.9,1.5,'Iris-versicolor');
INSERT INTO IRIS VALUES (54,5.5,2.3,4,1.3,'Iris-versicolor');
INSERT INTO IRIS VALUES (55,6.5,2.8,4.6,1.5,'Iris-versicolor');
INSERT INTO IRIS VALUES (56,5.7,2.8,4.5,1.3,'Iris-versicolor');
INSERT INTO IRIS VALUES (57,6.3,3.3,4.7,1.6,'Iris-versicolor');
INSERT INTO IRIS VALUES (58,4.9,2.4,3.3,1,'Iris-versicolor');
INSERT INTO IRIS VALUES (59,6.6,2.9,4.6,1.3,'Iris-versicolor');
INSERT INTO IRIS VALUES (60,5.2,2.7,3.9,1.4,'Iris-versicolor');
INSERT INTO IRIS VALUES (61,5,2,3.5,1,'Iris-versicolor');
INSERT INTO IRIS VALUES (62,5.9,3,4.2,1.5,'Iris-versicolor');
INSERT INTO IRIS VALUES (63,6,2.2,4,1,'Iris-versicolor');
INSERT INTO IRIS VALUES (64,6.1,2.9,4.7,1.4,'Iris-versicolor');
INSERT INTO IRIS VALUES (65,5.6,2.9,3.6,1.3,'Iris-versicolor');
INSERT INTO IRIS VALUES (66,6.7,3.1,4.4,1.4,'Iris-versicolor');
INSERT INTO IRIS VALUES (67,5.6,3,4.5,1.5,'Iris-versicolor');
INSERT INTO IRIS VALUES (68,5.8,2.7,4.1,1,'Iris-versicolor');
INSERT INTO IRIS VALUES (69,6.2,2.2,4.5,1.5,'Iris-versicolor');
INSERT INTO IRIS VALUES (70,5.6,2.5,3.9,1.1,'Iris-versicolor');
INSERT INTO IRIS VALUES (71,5.9,3.2,4.8,1.8,'Iris-versicolor');
INSERT INTO IRIS VALUES (72,6.1,2.8,4,1.3,'Iris-versicolor');
INSERT INTO IRIS VALUES (73,6.3,2.5,4.9,1.5,'Iris-versicolor');
INSERT INTO IRIS VALUES (74,6.1,2.8,4.7,1.2,'Iris-versicolor');
INSERT INTO IRIS VALUES (75,6.4,2.9,4.3,1.3,'Iris-versicolor');
INSERT INTO IRIS VALUES (76,6.6,3,4.4,1.4,'Iris-versicolor');
INSERT INTO IRIS VALUES (77,6.8,2.8,4.8,1.4,'Iris-versicolor');
INSERT INTO IRIS VALUES (78,6.7,3,5,1.7,'Iris-versicolor');
INSERT INTO IRIS VALUES (79,6,2.9,4.5,1.5,'Iris-versicolor');
INSERT INTO IRIS VALUES (80,5.7,2.6,3.5,1,'Iris-versicolor');
INSERT INTO IRIS VALUES (81,5.5,2.4,3.8,1.1,'Iris-versicolor');
INSERT INTO IRIS VALUES (82,5.5,2.4,3.7,1,'Iris-versicolor');
INSERT INTO IRIS VALUES (83,5.8,2.7,3.9,1.2,'Iris-versicolor');
INSERT INTO IRIS VALUES (84,6,2.7,5.1,1.6,'Iris-versicolor');
INSERT INTO IRIS VALUES (85,5.4,3,4.5,1.5,'Iris-versicolor');
INSERT INTO IRIS VALUES (86,6,3.4,4.5,1.6,'Iris-versicolor');
INSERT INTO IRIS VALUES (87,6.7,3.1,4.7,1.5,'Iris-versicolor');
INSERT INTO IRIS VALUES (88,6.3,2.3,4.4,1.3,'Iris-versicolor');
INSERT INTO IRIS VALUES (89,5.6,3,4.1,1.3,'Iris-versicolor');
INSERT INTO IRIS VALUES (90,5.5,2.5,4,1.3,'Iris-versicolor');
INSERT INTO IRIS VALUES (91,5.5,2.6,4.4,1.2,'Iris-versicolor');
INSERT INTO IRIS VALUES (92,6.1,3,4.6,1.4,'Iris-versicolor');
INSERT INTO IRIS VALUES (93,5.8,2.6,4,1.2,'Iris-versicolor');
INSERT INTO IRIS VALUES (94,5,2.3,3.3,1,'Iris-versicolor');
INSERT INTO IRIS VALUES (95,5.6,2.7,4.2,1.3,'Iris-versicolor');
INSERT INTO IRIS VALUES (96,5.7,3,4.2,1.2,'Iris-versicolor');
INSERT INTO IRIS VALUES (97,5.7,2.9,4.2,1.3,'Iris-versicolor');
INSERT INTO IRIS VALUES (98,6.2,2.9,4.3,1.3,'Iris-versicolor');
INSERT INTO IRIS VALUES (99,5.1,2.5,3,1.1,'Iris-versicolor');
INSERT INTO IRIS VALUES (100,5.7,2.8,4.1,1.3,'Iris-versicolor');
INSERT INTO IRIS VALUES (101,6.3,3.3,6,2.5,'Iris-virginica');
INSERT INTO IRIS VALUES (102,5.8,2.7,5.1,1.9,'Iris-virginica');
INSERT INTO IRIS VALUES (103,7.1,3,5.9,2.1,'Iris-virginica');
INSERT INTO IRIS VALUES (104,6.3,2.9,5.6,1.8,'Iris-virginica');
INSERT INTO IRIS VALUES (105,6.5,3,5.8,2.2,'Iris-virginica');
INSERT INTO IRIS VALUES (106,7.6,3,6.6,2.1,'Iris-virginica');
INSERT INTO IRIS VALUES (107,4.9,2.5,4.5,1.7,'Iris-virginica');
INSERT INTO IRIS VALUES (108,7.3,2.9,6.3,1.8,'Iris-virginica');
INSERT INTO IRIS VALUES (109,6.7,2.5,5.8,1.8,'Iris-virginica');
INSERT INTO IRIS VALUES (110,7.2,3.6,6.1,2.5,'Iris-virginica');
INSERT INTO IRIS VALUES (111,6.5,3.2,5.1,2,'Iris-virginica');
INSERT INTO IRIS VALUES (112,6.4,2.7,5.3,1.9,'Iris-virginica');
INSERT INTO IRIS VALUES (113,6.8,3,5.5,2.1,'Iris-virginica');
INSERT INTO IRIS VALUES (114,5.7,2.5,5,2,'Iris-virginica');
INSERT INTO IRIS VALUES (115,5.8,2.8,5.1,2.4,'Iris-virginica');
INSERT INTO IRIS VALUES (116,6.4,3.2,5.3,2.3,'Iris-virginica');
INSERT INTO IRIS VALUES (117,6.5,3,5.5,1.8,'Iris-virginica');
INSERT INTO IRIS VALUES (118,7.7,3.8,6.7,2.2,'Iris-virginica');
INSERT INTO IRIS VALUES (119,7.7,2.6,6.9,2.3,'Iris-virginica');
INSERT INTO IRIS VALUES (120,6,2.2,5,1.5,'Iris-virginica');
INSERT INTO IRIS VALUES (121,6.9,3.2,5.7,2.3,'Iris-virginica');
INSERT INTO IRIS VALUES (122,5.6,2.8,4.9,2,'Iris-virginica');
INSERT INTO IRIS VALUES (123,7.7,2.8,6.7,2,'Iris-virginica');
INSERT INTO IRIS VALUES (124,6.3,2.7,4.9,1.8,'Iris-virginica');
INSERT INTO IRIS VALUES (125,6.7,3.3,5.7,2.1,'Iris-virginica');
INSERT INTO IRIS VALUES (126,7.2,3.2,6,1.8,'Iris-virginica');
INSERT INTO IRIS VALUES (127,6.2,2.8,4.8,1.8,'Iris-virginica');
INSERT INTO IRIS VALUES (128,6.1,3,4.9,1.8,'Iris-virginica');
INSERT INTO IRIS VALUES (129,6.4,2.8,5.6,2.1,'Iris-virginica');
INSERT INTO IRIS VALUES (130,7.2,3,5.8,1.6,'Iris-virginica');
INSERT INTO IRIS VALUES (131,7.4,2.8,6.1,1.9,'Iris-virginica');
INSERT INTO IRIS VALUES (132,7.9,3.8,6.4,2,'Iris-virginica');
INSERT INTO IRIS VALUES (133,6.4,2.8,5.6,2.2,'Iris-virginica');
INSERT INTO IRIS VALUES (134,6.3,2.8,5.1,1.5,'Iris-virginica');
INSERT INTO IRIS VALUES (135,6.1,2.6,5.6,1.4,'Iris-virginica');
INSERT INTO IRIS VALUES (136,7.7,3,6.1,2.3,'Iris-virginica');
INSERT INTO IRIS VALUES (137,6.3,3.4,5.6,2.4,'Iris-virginica');
INSERT INTO IRIS VALUES (138,6.4,3.1,5.5,1.8,'Iris-virginica');
INSERT INTO IRIS VALUES (139,6,3,4.8,1.8,'Iris-virginica');
INSERT INTO IRIS VALUES (140,6.9,3.1,5.4,2.1,'Iris-virginica');
INSERT INTO IRIS VALUES (141,6.7,3.1,5.6,2.4,'Iris-virginica');
INSERT INTO IRIS VALUES (142,6.9,3.1,5.1,2.3,'Iris-virginica');
INSERT INTO IRIS VALUES (143,5.8,2.7,5.1,1.9,'Iris-virginica');
INSERT INTO IRIS VALUES (144,6.8,3.2,5.9,2.3,'Iris-virginica');
INSERT INTO IRIS VALUES (145,6.7,3.3,5.7,2.5,'Iris-virginica');
INSERT INTO IRIS VALUES (146,6.7,3,5.2,2.3,'Iris-virginica');
INSERT INTO IRIS VALUES (147,6.3,2.5,5,1.9,'Iris-virginica');
INSERT INTO IRIS VALUES (148,6.5,3,5.2,2,'Iris-virginica');
INSERT INTO IRIS VALUES (149,6.2,3.4,5.4,2.3,'Iris-virginica');
INSERT INTO IRIS VALUES (150,5.9,3,5.1,1.8,'Iris-virginica');
COMMIT;以下はデータを確認するための簡単なクエリです。

初心者としてこのようなデータセットを視覚化するのに適している場合は、データセットを CSV ファイルとして/src/main/resources/Iris.csvの下に追加しました。
ステップ2: Tribuo MLコンポーネントの簡単な紹介
Tribuoは、データの取り込み、特徴量処理、学習、評価といった関心事を明確に分離する、少数のコア抽象化を基盤として構築されています。このアプリケーションでは、以下のコンポーネントが使用されています。
Javaインポートセクションにリストされている各コンポーネントを簡単に見てみましょう。Javadocもご確認ください。
import org.tribuo.DataSource;
import org.tribuo.Dataset;
import org.tribuo.Model;
import org.tribuo.MutableDataset;
import org.tribuo.Trainer;
import org.tribuo.classification.Label;
import org.tribuo.classification.LabelFactory;
import org.tribuo.classification.evaluation.LabelEvaluation;
import org.tribuo.classification.evaluation.LabelEvaluator;
import org.tribuo.classification.liblinear.LibLinearClassificationTrainer;
import org.tribuo.data.columnar.ResponseProcessor;
import org.tribuo.data.columnar.RowProcessor;
import org.tribuo.data.columnar.processors.field.DoubleFieldProcessor;
import org.tribuo.data.columnar.processors.response.FieldResponseProcessor;
import org.tribuo.data.sql.SQLDBConfig;
import org.tribuo.data.sql.SQLDataSource;
import org.tribuo.evaluation.TrainTestSplitter;データソースDataSource、まだメモリにロードされていない機械学習サンプルのソースを表します。このアプリケーションでは、データソースはJDBC経由で実行されるSQLクエリによってサポートされており、Tribuoはデータベースから直接サンプルをストリーミングできます。
データセットDatasetは、aから派生した例のメモリ内コレクションですDataSource。特徴ベクトルとそれに関連する出力の両方が含まれており、トレーニングと評価に使用される構造となっています。
MutableDataset
変更可能な(変更可能な)MutableDatasetの具体的な実装ですDataset。ここでは、スプリッターによって生成されたトレーニングセットとテストセットを具体化するために使用されています。
モデルModelは学習の結果です。学習したパラメータをカプセル化し、新しい例に対する予測機能を提供します。このアプリケーションでは、モデルはアヤメの花の分類ラベルを予測します。
トレーナーTrainer、データセットからモデルを作成するために使用される学習アルゴリズムを定義します。トレーニング中に最適化ロジックを適用する役割を担います。
ラベルはLabel、Tribuo の分類タスクの出力タイプを表します。各例は、アヤメの種など、単一のカテゴリラベルに関連付けられています。
LabelFactory
インスタンスLabelFactoryの作成と管理を担当しLabel、データセット全体の一貫性と効率的な再利用を保証します。
LibLinearClassificationTrainer
このトレーナーは、LibLinear アルゴリズムを Tribuo に統合し、マルチクラス分類問題に適した高速で確立された線形分類器を提供します。
ResponseProcessorResponseProcessor、生データから出力値を抽出する方法を定義します。この場合、SPECIESSQL結果セットの列をTribuoLabelオブジェクトにマッピングします。
RowProcessor
RowProcessor,特徴抽出と応答処理を組み合わせて、生の入力データの各行を Tribuo の例に変換する方法の座標です。
DoubleFieldProcessor
このフィールド プロセッサは、数値 SQL 列を、Tribuo がトレーニングおよび予測中に使用できる二重値の特徴に変換します。
FieldResponseProcessor FieldResponseProcessor、データ ソース内の特定の列から分類ラベルを抽出し、必要に応じてデフォルト値を割り当てます。
SQLDBConfig SQLDBConfig、データベース URL、資格情報、オプションのプロパティなどの JDBC 接続の詳細をカプセル化し、SQL ベースのデータ ソース用のクリーンな構成オブジェクトを提供します。
SQLDataSource
SQLDataSource、SQL クエリを実行し、構成された行および応答プロセッサを使用して各結果行を機械学習の例に変換するTribuo DataSourceの具体的な実装です。
TrainTestSplitter
このユーティリティは、DataSource設定可能な比率とランダム シードを使用して、トレーニング パーティションとテスト パーティションを別々に分割します。
ステップ3: Tribuo MLサンプルアプリを理解する
アプリケーションのエントリポイントはクラスmain内のメソッドですIrisClassification。このメソッドは完全な機械学習パイプラインを定義します。
- JDBC ベースの Tribuo DataSource を作成します。
- データをトレーニング データセットとテスト データセットに分割します。
- 分類モデルをトレーニングします。
- 両方のデータセットでモデルを評価します。
ログはプロセス全体で使用され、各ステージを観察可能にします。これは、標準の Java アプリケーション内で機械学習ワークフローを実行する場合に特に役立ちます。
JDBC接続の詳細はコード内で明示的に定義され、認証情報は環境変数から読み取られます。これにより、シンプルな構成モデルを維持しながら、機密情報をソースコードから排除できます。
ステップ4: JDBCベースのTribuoデータソースを作成する
機械学習パイプラインは、データベースからデータを読み取る方法を定義することから始まります。SQLクエリは、IRISテーブルから4つの数値的なアイリス特徴と種ラベルを選択します。
SQLDBConfigオブジェクトはJDBC URLおよび資格証明を保持し、RowProcessorは各列の解釈方法を定義します。数値列は機能usingDoubleFieldProcessorにマップされ、種列はFieldResponseProcessorを使用して分類ラベルにマップされます。
最後に、これらのコンポーネントは、リレーショナル・データベースとTribuoの学習パイプラインの間のブリッジとして機能するanSQLDataSourceにアセンブルされます。
` private static DataSource<Label> createJdbcDatasource() throws SQLException {
// Create SQLDataSource using JDBC connection details
String sqlQuery = "SELECT SEPALLENGTHCM, SEPALWIDTHCM, PETALLENGTHCM, PETALWIDTHCM, SPECIES FROM IRIS";
String jdbcUrl = "jdbc:oracle:thin:@localhost:1521/FREEPDB1";
String username = System.getenv("DB_USERNAME");
String password = System.getenv("DB_PASSWORD");
SQLDBConfig dbConfig = new SQLDBConfig(jdbcUrl, username, password, java.util.Collections.emptyMap());
// Create RowProcessor to handle the data transformation
LabelFactory labelFactory = new LabelFactory();
ResponseProcessor<Label> responseProcessor = new FieldResponseProcessor<>("SPECIES", "UNKNOWN", labelFactory);
RowProcessor<Label> rowProcessor = new RowProcessor.Builder<Label>()
.addFieldProcessor(new DoubleFieldProcessor("SEPALLENGTHCM"))
.addFieldProcessor(new DoubleFieldProcessor("SEPALWIDTHCM"))
.addFieldProcessor(new DoubleFieldProcessor("PETALLENGTHCM"))
.addFieldProcessor(new DoubleFieldProcessor("PETALWIDTHCM")).build(responseProcessor);
DataSource<Label> dataSource = new SQLDataSource<>(sqlQuery, dbConfig, labelFactory, rowProcessor, true);
return dataSource;
}ステップ4: データセットをトレーニングセットとテストセットに分割する
データソースが定義されると、アプリケーションはを使用してTrainTestSplitterデータをトレーニング用とテスト用のパーティションに分割します。再現性を確保するために、固定のランダムシードを用いて70/30の割合で分割されます。
各パーティションは としてマテリアライズされMutableDataset、アプリケーションはデータセットのサイズ、特徴量数、利用可能なクラスラベルなどのプロパティを検査できます。この段階でログを記録することで、使用されているデータの構造に関する即時のフィードバックが提供されます。
private static Dataset<Label>[] splitDataSet(DataSource<Label> dataSource) {
// Split the dataset into training (70%) and testing (30%)
TrainTestSplitter<Label> splitter = new TrainTestSplitter<>(dataSource, 0.7, 1234L);
Dataset<Label> trainSet = new MutableDataset<>(splitter.getTrain());
Dataset<Label> testSet = new MutableDataset<>(splitter.getTest());
// Log dataset information
logger.info(String.format("Train Size: %d, Features: %d, Classes: %s", trainSet.size(),
trainSet.getFeatureMap().size(), trainSet.getOutputInfo().getDomain()));
logger.info(String.format("Test Size: %d, Features: %d, Classes: %s", testSet.size(),
testSet.getFeatureMap().size(), testSet.getOutputInfo().getDomain()));
@SuppressWarnings("unchecked")
Dataset<Label>[] result = new Dataset[] { trainSet, testSet };
return result;
}ステップ5: 分類モデルをトレーニングする
トレーニングは LibLinearClassificationTrainerを使用して実行されます。トレーナーはトレーニングデータセットを消費し、Model<Label>インスタンスを生成します。
このステップは学習プロセス全体をカプセル化します。アプリケーションの観点から見ると、トレーニングは単一のメソッド呼び出しであるため、堅牢な機械学習アルゴリズムを活用しながらコードを簡潔に保つことができます。
private static Model<Label> trainLibLinearModel(Dataset<Label> trainSet) {
// Train the model using LibLinear
Trainer<Label> trainer = new LibLinearClassificationTrainer();
logger.info("Training the model...");
Model<Label> model = trainer.train(trainSet);
return model;
}ステップ6: トレーニング済みモデルを評価する
モデル評価は LabelEvaluatorを用いて行われます。LabelEvaluation評価器はトレーニングデータセットとテストデータセットの両方に適用され、それぞれに対して結果を生成します。アプリケーションは両方の評価の精度と混同行列を記録します。
private static void evaluateLibLinearModel(Model<Label> model, Dataset<Label> trainSet, Dataset<Label> testSet) {
// Evaluate model on train and test sets
LabelEvaluator evaluator = new LabelEvaluator();
logger.info("Evaluating on train set...");
LabelEvaluation trainEval = evaluator.evaluate(model, trainSet);
logger.log(Level.INFO, "Train Accuracy: {0}", trainEval.accuracy());
logger.log(Level.INFO, "Train Confusion Matrix:\n{0}", trainEval.getConfusionMatrix());
logger.info("Evaluating on test set...");
LabelEvaluation testEval = evaluator.evaluate(model, testSet);
logger.log(Level.INFO, "Test Accuracy: {0}", testEval.accuracy());
logger.log(Level.INFO, "Test Confusion Matrix:\n{0}", testEval.getConfusionMatrix());
}以下に完全なコードサンプルを示します。
package com.oracle.dev.jdbc;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.tribuo.DataSource;
import org.tribuo.Dataset;
import org.tribuo.Model;
import org.tribuo.MutableDataset;
import org.tribuo.Trainer;
import org.tribuo.classification.Label;
import org.tribuo.classification.LabelFactory;
import org.tribuo.classification.evaluation.LabelEvaluation;
import org.tribuo.classification.evaluation.LabelEvaluator;
import org.tribuo.classification.liblinear.LibLinearClassificationTrainer;
import org.tribuo.data.columnar.ResponseProcessor;
import org.tribuo.data.columnar.RowProcessor;
import org.tribuo.data.columnar.processors.field.DoubleFieldProcessor;
import org.tribuo.data.columnar.processors.response.FieldResponseProcessor;
import org.tribuo.data.sql.SQLDBConfig;
import org.tribuo.data.sql.SQLDataSource;
import org.tribuo.evaluation.TrainTestSplitter;
public class IrisClassification {
private static final Logger logger = Logger.getLogger(IrisClassification.class.getName());
public static void main(String[] args) throws Exception {
logger.info("Classification with the Tribuo Java library, JDBC and the Iris dataset");
try {
// Create JDBC DataSource
DataSource<Label> dataSource = createJdbcDatasource();
// Split dataset and get train/test sets
Dataset<Label>[] datasets = splitDataSet(dataSource);
Dataset<Label> trainSet = datasets[0];
Dataset<Label> testSet = datasets[1];
// Train the model
Model<Label> model = trainLibLinearModel(trainSet);
// Evaluate the model
evaluateLibLinearModel(model, trainSet, testSet);
} catch (SQLException e) {
logger.log(Level.SEVERE, "Database connection error: " + e.getMessage(), e);
throw e;
}
}
private static DataSource<Label> createJdbcDatasource() throws SQLException {
// Create SQLDataSource using JDBC connection details
String sqlQuery = "SELECT SEPALLENGTHCM, SEPALWIDTHCM, PETALLENGTHCM, PETALWIDTHCM, SPECIES FROM IRIS";
String jdbcUrl = "jdbc:oracle:thin:@localhost:1521/FREEPDB1";
String username = System.getenv("DB_USERNAME");
String password = System.getenv("DB_PASSWORD");
SQLDBConfig dbConfig = new SQLDBConfig(jdbcUrl, username, password, java.util.Collections.emptyMap());
// Create RowProcessor to handle the data transformation
LabelFactory labelFactory = new LabelFactory();
ResponseProcessor<Label> responseProcessor = new FieldResponseProcessor<>("SPECIES", "UNKNOWN", labelFactory);
RowProcessor<Label> rowProcessor = new RowProcessor.Builder<Label>()
.addFieldProcessor(new DoubleFieldProcessor("SEPALLENGTHCM"))
.addFieldProcessor(new DoubleFieldProcessor("SEPALWIDTHCM"))
.addFieldProcessor(new DoubleFieldProcessor("PETALLENGTHCM"))
.addFieldProcessor(new DoubleFieldProcessor("PETALWIDTHCM")).build(responseProcessor);
DataSource<Label> dataSource = new SQLDataSource<>(sqlQuery, dbConfig, labelFactory, rowProcessor, true);
return dataSource;
}
private static Dataset<Label>[] splitDataSet(DataSource<Label> dataSource) {
// Split the dataset into training (70%) and testing (30%)
TrainTestSplitter<Label> splitter = new TrainTestSplitter<>(dataSource, 0.7, 1234L);
Dataset<Label> trainSet = new MutableDataset<>(splitter.getTrain());
Dataset<Label> testSet = new MutableDataset<>(splitter.getTest());
// Log dataset information
logger.info(String.format("Train Size: %d, Features: %d, Classes: %s", trainSet.size(),
trainSet.getFeatureMap().size(), trainSet.getOutputInfo().getDomain()));
logger.info(String.format("Test Size: %d, Features: %d, Classes: %s", testSet.size(),
testSet.getFeatureMap().size(), testSet.getOutputInfo().getDomain()));
@SuppressWarnings("unchecked")
Dataset<Label>[] result = new Dataset[] { trainSet, testSet };
return result;
}
private static Model<Label> trainLibLinearModel(Dataset<Label> trainSet) {
// Train the model using LibLinear
Trainer<Label> trainer = new LibLinearClassificationTrainer();
logger.info("Training the model...");
Model<Label> model = trainer.train(trainSet);
return model;
}
private static void evaluateLibLinearModel(Model<Label> model, Dataset<Label> trainSet, Dataset<Label> testSet) {
// Evaluate model on train and test sets
LabelEvaluator evaluator = new LabelEvaluator();
logger.info("Evaluating on train set...");
LabelEvaluation trainEval = evaluator.evaluate(model, trainSet);
logger.log(Level.INFO, "Train Accuracy: {0}", trainEval.accuracy());
logger.log(Level.INFO, "Train Confusion Matrix:\n{0}", trainEval.getConfusionMatrix());
logger.info("Evaluating on test set...");
LabelEvaluation testEval = evaluator.evaluate(model, testSet);
logger.log(Level.INFO, "Test Accuracy: {0}", testEval.accuracy());
logger.log(Level.INFO, "Test Confusion Matrix:\n{0}", testEval.getConfusionMatrix());
}
}ステップ7: Tribuo機械学習アプリを実行する
アプリケーションが実行されると、エンドツーエンドで実行されます。
- データは、JDBC 経由で Oracle データベースからロードされます。
- 特徴とラベルが抽出され、処理されます。
- 分類モデルがトレーニングされます。
- モデルが評価され、結果が記録されます。
完全なコード サンプルを含む Maven プロジェクトをGitHub から入手することもできます。
まとめ
これで完了です。Oracle Labs が作成した強力な Java ライブラリである Tribuo を使用して機械学習を実装する方法を学びました。
Tribuoは、Java開発者が期待するレベルの型安全性と構造を機械学習に提供します。SQLDataSourceを利用することで、Oracleデータベース内のデータを中間形式にエクスポートすることなく、直接トレーニング済みモデルに移行できます。
さらに、Javaでの機械学習は、使い慣れたツールやアーキテクチャを放棄する必要がないという結論に達しました。JDBCとTribuoを組み合わせることで、明確で型安全なAPIを用いてリレーショナルデータを直接操作する、エンドツーエンドの機械学習パイプラインを構築できます。
エコシステムを離れずに機械学習を探求したいと考えている Java 開発者にとって、Tribuo は実用的で取り組みやすい道筋を提供します。
このブログ投稿をお楽しみいただけたら幸いです。今後もご期待ください。
参考文献
- Tribuo
- Tribuo — Javadocs
- データセット - アイリス種 - アイリス植物を3種に分類するための古典的なデータセット
- Oracle AI Database 26ai
- Oracle AI Database 26ai 無料コンテナイメージ
Oracle Developers と Oracle OCI Free Tier
Slack の Oracle Developers チャンネルに参加して、Java、GenAI、Agentic AI、JDK、JDBC、GraalVM、Micronaut、Spring Boot、Helidon、Quarkus、Reactive Streams、クラウド、DevOps、SRE、IaC などのトピックについて話し合ってみましょう。
Oracle Cloudでアプリケーションを無料で構築、テスト、デプロイしましょう!OCI Cloud Free Tierにぜひアクセスしてください!
コメント
コメントを投稿