序文ご存知のとおり、TiDB バージョン 5.1 では多くの新機能が追加されましたが、その 1 つが ANSI SQL 99 標準の共通テーブル式 (CTE) です。一般的に、CTE はステートメント スコープ内の一時的なビューとして使用して、複雑な SQL ステートメントを分離し、開発効率を向上させることができます。ただし、CTE を使用するもう 1 つの重要な方法、つまり再帰 CTE があり、これにより CTE は自分自身を参照できるようになります。これが、SQL 関数を完成させるパズルの最後の核となるピースです。 StackOverflow で「SQL や TSQL はチューリング完全ですか? 2」という議論がありましたが、その中で最も賛成票を集めた返信には次の文が書かれていました。
このスライド セットでは、Andrew Gierth が、チューリング完全であることが証明されている循環タグ システムを構築することで、CTE とウィンドウ化 SQL がチューリング完全であることを証明しています。ただし、CTE 機能は重要な部分です。CTE 機能を使用すると、名前付きサブ式を作成して自分自身を参照し、問題を再帰的に解決することができます。
つまり、CTE とウィンドウ関数によって、SQL はチューリング完全な言語になります。 これは、私が何年も前に読んだ記事「BigQuery 上の純粋な SQL で実装されたディープ ニューラル ネットワーク」を思い出させます。著者は純粋な SQL を使用して DNN モデルを実装しましたが、リポジトリ1を開いた後、それがクリックベイトのタイトルであることがわかりました。実際、彼は反復トレーニングを実装するために Python を使い続けました。 したがって、再帰 CTE によって「反復」する機能が提供されるため、 TiDB で純粋な SQL を使用して機械学習モデルのトレーニングと推論を実装できるかどうかに挑戦したいと思うようになりました。 アイリスデータセットまず、シンプルな機械学習モデルとタスクを選択する必要があります。sklearn の入門データセットである iris データセットを試してみましょう。このデータセットには、3 つのカテゴリに 150 件のレコードが含まれており、各カテゴリに 50 件のデータがあります。各レコードには、萼片の長さ、萼片の幅、花弁の長さ、花弁の幅の 4 つの特徴があります。これらの 4 つの特徴を使用して、アイリスの花がどの品種 (iris-setosa、iris-versicolour、iris-virginica) に属するかを予測できます。 データ(すでに CSV 形式)をダウンロードした後、まずそのデータを TiDB にインポートします。 mysql > テーブルiris ( sl float 、 sw float 、 pl float 、 pw float 、 type varchar ( 16 ) ) を作成します。
mysql >ローカル INFILE 'iris.csv'のデータをテーブルiris にロードします。フィールドは',' で終了し、行は'\n' で終了します。
mysql >アイリス制限から* を10から選択します。
+------+------+------+------+------------+
| sl | sw | pl | pw |タイプ|
+------+------+------+------+------------+
| 5.1 | 3.5 | 1.4 | 0.2 |アイリス-セトサ|
| 4.9 | 3 | 1.4 | 0.2 |アイリス-セトサ|
| 4.7 | 3.2 | 1.3 | 0.2 |アイリス-セトサ|
| 4.6 | 3.1 | 1.5 | 0.2 |アイリス-セトサ|
| 5 | 3.6 | 1.4 | 0.2 |アイリス-セトサ|
| 5.4 | 3.9 | 1.7 | 0.4 |アイリス-セトサ|
| 4.6 | 3.4 | 1.4 | 0.3 |アイリス-セトサ|
| 5 | 3.4 | 1.5 | 0.2 |アイリス-セトサ|
| 4.4 | 2.9 | 1.4 | 0.2 |アイリス-セトサ|
| 4.9 | 3.1 | 1.5 | 0.1 |アイリス-セトサ|
+------+------+------+------+-------------+
セット内の行数は10 です( 0.00秒)
mysql > iris group by type からtype 、 count ( * ) を選択します。
+-----------------+----------+
|タイプ| カウント( * ) |
+-----------------+----------+
|アイリス- versicolor | 50 |
|アイリス-セトサ| 50 |
|アイリス- virginica | 50 |
+-----------------+----------+
セット内の3行( 0.00秒)
ソフトマックスロジスティック回帰ここでは、多重分類を実現するために、単純な機械学習モデルである Softmax ロジスティック回帰を選択します。 以下の写真と説明は百度百科2より引用 ソフトマックス回帰で x をクラス y に分類する確率は次のとおりです。 コスト関数は次のとおりです。 グラデーションは次のようになります: したがって、勾配は勾配降下法によって毎回更新できます。 モデル推論まず、推論を実装するための SQL ステートメントを記述します。上記で定義したモデルとデータによると、入力データ X には 5 つの次元 (sl、sw、pl、pw、定数 1.0) があり、出力にはワンホット エンコーディングが使用されます。 mysql > テーブルデータの作成(
x0 小数点( 35 , 30 ) 、 x1 小数点( 35 , 30 ) 、 x2 小数点( 35 , 30 ) 、 x3 小数点( 35 , 30 ) 、 x4 小数点( 35 , 30 ) 、
y0 小数点( 35 , 30 ) 、 y1 小数点( 35 , 30 ) 、 y2 小数点( 35 , 30 )
) ;
mysql >データに挿入
選択
sl 、 sw 、 pl 、 pw 、 1.0 、
type = 'Iris-setosa'の場合1 、そうでない場合は0終了、
type = 'Iris-versicolor'の場合1 、そうでない場合は0終了、
type = 'Iris-virginica'の場合1 、そうでない場合は0終了
アイリスから;
3 つのカテゴリ * 5 つの次元 = 15 のパラメーターがあります。 mysql > テーブル重みを作成(
w00 10 進数( 35 , 30 ) 、 w01 10 進数( 35 , 30 ) 、 w02 10 進数( 35 , 30 ) 、 w03 10 進数( 35 , 30 ) 、 w04 10 進数( 35 , 30 ) 、
w10 小数点( 35 , 30 ) 、 w11 小数点( 35 , 30 ) 、 w12 小数点( 35 , 30 ) 、 w13 小数点( 35 , 30 ) 、 w14 小数点( 35 , 30 ) 、
w20 小数点( 35 , 30 ) 、 w21 小数点( 35 , 30 ) 、 w22 小数点( 35 , 30 ) 、 w23 小数点( 35 , 30 ) 、 w24 小数点( 35 , 30 ) ) ;
まず、すべてを 0.1、0.2、0.3 に初期化します (ここではデモンストレーションの便宜上異なる数値が選択されていますが、0.1 に初期化することもできます)。 mysql >重み値に挿入(
0.1 、 0.1 、 0.1 、 0.1 、 0.1 、
0.2 、 0.2 、 0.2 、 0.2 、 0.2 、
0.3、0.3、0.3、0.3、0.3 ) ;
次に、すべてのデータを推論した後の結果の精度を計算する SQL ステートメントを記述します。 理解を容易にするために、まずこのプロセスを説明する疑似コードを示しましょう。 重量= (
w00 、 w01 、 w02 、 w03 、 w04 、
w10 、 w11 、 w12 、 w13 、 w14 、
w20 、 w21、w22、w23 、 w24、w25、w26、w27、w28、w29、w30、w31、w32 、 w33、w34、w35、w36、w38、w39、w40、w41、w42、w43、w44、w45、w46 、 w48、w50、w51、w52、w53、w54
)
すべてのデータのデータ( x0 、 x1 、 x2 、 x3 、 x4 、 y0 、 y1 、 y2 )について:
exp0 = exp ( x0 * w00 、 x1 * w01 、 x2 * w02 、 x3 * w03 、 x4 * w04 )
exp1 = exp ( x0 * w10 、 x1 * w11 、 x2 * w12 、 x3 * w13 、 x4 * w14 ) です。
exp2 = exp ( x0 * w20 、 x1 * w21 、 x2 * w22 、 x3 * w23 、 x4 * w24 ) です。
合計exp = exp0 + exp1 + exp2
//ソフトマックス
p0 = exp0 /合計exp
p1 = exp1 /合計exp
p2 = exp2 /合計exp
//推論結果
r0 = p0 > p1 かつp0 > p2
r1 = p1 > p0 かつp1 > p2
r2 = p2 > p0 かつp2 > p1
データ.correct = ( y0 == r0 かつy1 == r1 かつy2 == r2 )
sum (データ.correct ) / count (データ)を返します。
上記のコードでは、Data 内の各要素の行を計算します。まず、3 つのベクトルのドット積の exp を求め、次にソフトマックスを求め、最後に p0、p1、p2 のうち最大のものを 1 として選択し、残りを 0 として選択します。これでサンプルの推論が完了します。サンプルの最終的な推論結果が元の分類と一致している場合、それは正しい予測です。最後に、すべてのサンプルの正しい予測の数を合計して、最終的な精度を取得します。 以下は SQL 実装です。各データ行を重み (1 行のデータのみ) で結合し、各データ行の推論結果を計算し、正しいサンプル数を合計することを選択します。 合計( y0 = r0 かつy1 = r1 かつy2 = r2 ) / カウント( * ) を選択
から
( 選択
y0 、 y1 、 y2 、
p0 > p1 かつp0 > p2 (r0 の場合) 、 p1 > p0 かつp1 > p2 (r1 の場合) 、 p2 > p0 かつp2 > p1 (r2 の場合)
から
( 選択
y0 、 y1 、 y2 、
e0 / ( e0 + e1 + e2 )は p0 として、 e1 / ( e0 + e1 + e2 )は p1 として、 e2 / ( e0 + e1 + e2 )は p2 として
から
( 選択
y0 、 y1 、 y2 、
exp (
w00 * x0 + w01 * x1 + w02 * x2 + w03 * x3 + w04 * x4
)を e0 として、
exp (
w10 * x0 + w11 * x1 + w12 * x2 + w13 * x3 + w14 * x4
)をe1 として、
exp (
w20 * x0 + w21 * x1 + w22 * x2 + w23 * x3 + w24 * x4
)をe2 とする
データから、重み) t1
) t2
) t3 ;
上記の SQL は、上記の疑似コードの計算プロセスをほぼ段階的に実装しており、結果は次のようになります。 +-------------------------------------------------+
|合計( y0 = r0 かつy1 = r1 かつy2 = r2 ) / カウント( * ) |
+-------------------------------------------------+
| 0.3333 |
+-------------------------------------------------+
セット内の1行( 0.01秒)
次に、モデルのパラメータを学習します。 モデルトレーニング注意: 問題を単純化するために、「トレーニング セット」や「検証セット」などの問題は考慮せず、すべてのデータをトレーニングにのみ使用します。 まず疑似コードを示し、次にその疑似コードに基づいて SQL を記述します。 重量= (
w00 、 w01 、 w02 、 w03 、 w04 、
w10 、 w11 、 w12 、 w13 、 w14 、
w20 、 w21、w22、w23 、 w24、w25、w26、w27、w28、w29、w30、w31、w32 、 w33、w34、w35、w36、w38、w39、w40、w41、w42、w43、w44、w45、w46 、 w48、w50、w51、w52、w53、w54
)
iter in反復の場合:
合計00 = 0
合計01 = 0
...
合計23 = 0
合計24 = 0
すべてのデータのデータ( x0 、 x1 、 x2 、 x3 、 x4 、 y0 、 y1 、 y2 )について:
exp0 = exp ( x0 * w00 、 x1 * w01 、 x2 * w02 、 x3 * w03 、 x4 * w04 )
exp1 = exp ( x0 * w10 、 x1 * w11 、 x2 * w12 、 x3 * w13 、 x4 * w14 ) です。
exp2 = exp ( x0 * w20 、 x1 * w21 、 x2 * w22 、 x3 * w23 、 x4 * w24 ) です。
合計exp = exp0 + exp1 + exp2
//ソフトマックス
p0 = y0 - exp0 / sum_exp
p1 = y1 - exp1 / sum_exp
p2 = y2 - exp2 / sum_exp
合計00 += p0 * x0
合計01 += p0 * x1
合計02 += p0 * x2
...
合計23 += p2 * x3
合計24 += p2 * x4
w00 = w00 +学習率* sum00 /データサイズ
w01 = w01 +学習率* sum01 /データサイズ
...
w23 = w23 +学習率* sum23 /データサイズ
w24 = w24 +学習率* sum24 /データサイズ
sum や w などのベクトルを手動で展開することを選択したため、複雑に見えます。 次に、SQL トレーニングの作成を開始します。まず、1 回の反復のみで SQL を作成します。 学習率とサンプル数を設定する mysql > @lr = 0.1 を設定します。
クエリは正常です。0行が影響を受けました( 0.00秒)
mysql > @dsize を150 に設定します。
クエリは正常です。0行が影響を受けました( 0.00秒)
1 回繰り返します: 選択
w00 + @lr * sum ( d00 ) / @dsize はw00 、 w01 + @lr * sum ( d01 ) / @dsize はw01 、 w02 + @lr * sum ( d02 ) / @dsize はw02 、 w03 + @lr * sum ( d03 ) / @dsize はw03 、 w04 + @lr * sum ( d04 ) / @dsize はw04 、
w10 + @lr * sum ( d10 ) / @dsize はw10 、 w11 + @lr * sum ( d11 ) / @dsize はw11 、 w12 + @lr * sum ( d12 ) / @dsize はw12 、 w13 + @lr * sum ( d13 ) / @dsize はw13 、 w14 + @lr * sum ( d14 ) / @dsize はw14 、
w20 + @lr * sum ( d20 ) / @dsize はw20 、 w21 + @lr * sum ( d21 ) / @dsize はw21 、 w22 + @lr * sum ( d22 ) / @dsize はw22 、 w23 + @lr * sum ( d23 ) / @dsize はw23 、 w24 + @lr * sum ( d24 ) / @dsize はw24
から
( 選択
w00 、 w01 、 w02 、 w03 、 w04 、
w10 、 w11 、 w12 、 w13 、 w14 、
w20 、 w21 、 w22 、 w23 、 w24 、
p0 * x0 を d00 として、 p0 * x1 を d01 として、 p0 * x2 を d02 として、 p0 * x3 を d03 として、 p0 * x4 を d04 として、
p1 * x0 をd10 、 p1 * x1 をd11 、 p1 * x2 をd12 、 p1 * x3 をd13 、 p1 * x4 をd14 、
p2 * x0 をd20 、 p2 * x1 をd21 、 p2 * x2 をd22 、 p2 * x3 をd23 、 p2 * x4 を d24 とする
から
( 選択
w00 、 w01 、 w02 、 w03 、 w04 、
w10 、 w11 、 w12 、 w13 、 w14 、
w20 、 w21 、 w22 、 w23 、 w24 、
x0 、 x1 、 x2 、 x3 、 x4 、
y0 - e0 / ( e0 + e1 + e2 )を p0 として、 y1 - e1 / ( e0 + e1 + e2 )を p1 として、 y2 - e2 / ( e0 + e1 + e2 )を p2 として
から
( 選択
w00 、 w01 、 w02 、 w03 、 w04 、
w10 、 w11 、 w12 、 w13 、 w14 、
w20 、 w21 、 w22 、 w23 、 w24 、
x0 、 x1 、 x2 、 x3 、 x4 、 y0 、 y1 、 y2 、
exp (
w00 * x0 + w01 * x1 + w02 * x2 + w03 * x3 + w04 * x4
)を e0 として、
exp (
w10 * x0 + w11 * x1 + w12 * x2 + w13 * x3 + w14 * x4
)をe1 として、
exp (
w20 * x0 + w21 * x1 + w22 * x2 + w23 * x3 + w24 * x4
)をe2 とする
データから、重み) t1
) t2
) t3 ;
結果は、1 回の反復後のモデル パラメータです。 +----------------------------------+----------------------------------+----------------------------------+----------------------------------+----------------------------------+----------------------------------+----------------------------------+--+----------------------------------+----------------------------------+----------------------------------+----------------------------------+----------------------------------+----------------------------------+
| w00 | w01 | w02 | w03 | w04 | w10 | w11 | w12 | w13 | w14 | w20 | w21 | w22 | w23 | w24 |
+----------------------------------+----------------------------------+----------------------------------+----------------------------------+----------------------------------+----------------------------------+----------------------------------+--+----------------------------------+----------------------------------+----------------------------------+----------------------------------+----------------------------------+----------------------------------+
| 0.242000022455130986666666666667 | 0.199736070114635900000000000000 | 0.1356891027741257733333333333333 | 0.1043729384173256873333333333333 | 0.12877532001171743066666666667 | 0.2961282845904381 3333333333333333 | 0.2371249257077482466666666666667 | 0.281477497498236260000000000000 | 0.225631554555397960000000000000 | 0.2153900253424992133333333333333 | 0.061871692954430866666666666667 | 0.163139004177615846666666666667 | 0.182833399727637980000000000000 | 0.2699955070272763533333333333333 | 0.255834654645783353333333333333 |
+----------------------------------+----------------------------------+----------------------------------+----------------------------------+----------------------------------+----------------------------------+----------------------------------+--+----------------------------------+----------------------------------+----------------------------------+----------------------------------+----------------------------------+----------------------------------+
セット内の1行( 0.03秒)
以下がコア部分です。反復トレーニングには再帰 CTE を使用します。 mysql > @num_iterations = 1000 を設定します。
クエリは正常です。0行が影響を受けました( 0.00秒)
基本的な考え方は、各反復の入力は前の反復の結果であり、反復回数を制御するために増分反復変数を追加するというものです。一般的なアーキテクチャは次のとおりです。 再帰的なcte ( iter , weight ) は
(
1 、 init_weight を選択
すべて結合
iter + 1 、 new_weight を選択
CTE から
ここで、ites < @num_iterations
)
次に、1 回の反復の SQL をこの反復フレームワークと組み合わせます (計算精度を向上させるために、中間結果にいくつかの型変換が追加されます)。 再帰重み( iter 、
w00 、 w01 、 w02 、 w03 、 w04 、
w10 、 w11 、 w12 、 w13 、 w14 、
w20 、 w21 、 w22 、 w23 、 w24 ) として
(
1を選択、
キャスト( 0.1 をDECIMAL ( 35 , 30 ) として) 、キャスト( 0.1をDECIMAL ( 35 , 30 ) として) 、キャスト( 0.1 をDECIMAL ( 35 , 30 ) として) 、キャスト( 0.1をDECIMAL ( 35 , 30 ) として) 、キャスト( 0.1をDECIMAL ( 35 , 30 ) として) 、
キャスト( 0.1 をDECIMAL ( 35 , 30 ) として) 、キャスト( 0.1をDECIMAL ( 35 , 30 ) として) 、キャスト( 0.1 をDECIMAL ( 35 , 30 ) として) 、キャスト( 0.1をDECIMAL ( 35 , 30 ) として) 、キャスト( 0.1をDECIMAL ( 35 , 30 ) として) 、
キャスト( 0.1 をDECIMAL ( 35 , 30 ) として) 、キャスト( 0.1をDECIMAL ( 35 , 30 ) として) 、キャスト( 0.1 をDECIMAL ( 35 , 30 ) として) 、キャスト( 0.1をDECIMAL ( 35 , 30 ) として) 、キャスト( 0.1をDECIMAL ( 35 , 30 ) として)
すべて結合
選択
反復+ 1 、
w04 + @lr * cast ( sum ( d04 ) as DECIMAL ( 35 , 30 ) ) / @dsize as w04 , w05 + @lr * cast ( sum ( d05 ) as DECIMAL ( 35 , 30 ) ) / @dsize as w05 , w06 + @lr * cast ( sum ( d06 ) as DECIMAL ( 35 , 30 ) ) / @dsize as w06 , w07 + @lr * cast ( sum ( d07 ) as DECIMAL ( 35 , 30 ) ) / @dsize as w07 ,
30 ) ) / @dsizeをw13 、 w14 として+ @lr * cast ( sum ( d14 )をDECIMAL ( 35 、 30 ) として) / @dsizeをw14 、 w15 として+ @lr * cast ( sum ( d16 ) をDECIMAL ( 35 、 30 )として) / @dsizeをw15 、 w16 として+ @lr * cast ( sum ( d17 )をDECIMAL ( 35 、 30 ) として) / @dsize をw16 として、
30 ) ) / @dsize をw23 、 w24 として+ @lr * キャスト( sum ( d24 )をDECIMAL ( 35 、 30 ) として) / @dsize をw24 、 w25 として+ @lr * キャスト( sum ( d26 ) をDECIMAL ( 35 、 30 )として) / @dsize をw25
から
( 選択
反復、 w00 、 w01 、 w02 、 w03 、 w04 、
w10 、 w11 、 w12 、 w13 、 w14 、
w20 、 w21 、 w22 、 w23 、 w24 、
p0 * x0 を d00 として、 p0 * x1 を d01 として、 p0 * x2 を d02 として、 p0 * x3 を d03 として、 p0 * x4 を d04 として、
p1 * x0 をd10 、 p1 * x1 をd11 、 p1 * x2 をd12 、 p1 * x3 をd13 、 p1 * x4 をd14 、
p2 * x0 をd20 、 p2 * x1 をd21 、 p2 * x2 をd22 、 p2 * x3 をd23 、 p2 * x4 を d24 とする
から
( 選択
反復、 w00 、 w01 、 w02 、 w03 、 w04 、
w10 、 w11 、 w12 、 w13 、 w14 、
w20 、 w21 、 w22 、 w23 、 w24 、
x0 、 x1 、 x2 、 x3 、 x4 、
y0 - e0 / ( e0 + e1 + e2 )を p0 として、 y1 - e1 / ( e0 + e1 + e2 )を p1 として、 y2 - e2 / ( e0 + e1 + e2 )を p2 として
から
( 選択
反復、 w00 、 w01 、 w02 、 w03 、 w04 、
w10 、 w11 、 w12 、 w13 、 w14 、
w20 、 w21 、 w22 、 w23 、 w24 、
x0 、 x1 、 x2 、 x3 、 x4 、 y0 、 y1 、 y2 、
exp (
w00 * x0 + w01 * x1 + w02 * x2 + w03 * x3 + w04 * x4
)を e0 として、
exp (
w10 * x0 + w11 * x1 + w12 * x2 + w13 * x3 + w14 * x4
)をe1 として、
exp (
w20 * x0 + w21 * x1 + w22 * x2 + w23 * x3 + w24 * x4
)をe2 とする
データから、重み、iter < @num_iterations ) t1
) t2
) t3
カウント( * ) > 0
)
iter = @num_iterations となるweight から* を選択します。
このバージョンと上記の 1 回の反復バージョンの違いは 2 つあります。
- データの結合重み付けの後、反復回数を制御するために
where iter < @num_iterations を追加し、最終出力にiter + 1 as iter 列を追加します。 - 最後に、最後に入力データがない場合でも集計によってデータが出力され、反復が終了しない状況を回避するために
having count(*) > 0 追加しました。
すると、次のような結果が得られます。 エラー3577 ( HY000 ) :再帰共通テーブル式'weight'の再帰クエリ ブロックでは、再帰テーブルは1 回だけ参照する必要があり、 サブクエリでは参照できません。
ああ、これは...再帰 CTE では再帰部分でのサブクエリは許可されません。しかし、上記のサブクエリをすべてマージすることは不可能ではないので、手動でマージしてもう一度試します。 エラー3575 ( HY000 ) :再帰共通テーブル式'cte'には、再帰クエリ ブロック内の集計関数もウィンドウ関数も含めることはできません。
! ! ! !サブクエリが許可されていない場合は、SQL を手動で変更できますが、集計関数が許可されていない場合は、他に選択肢はありません。 ここではチャレンジが失敗したと宣言することしかできません... ねえ、なぜ TiDB の実装を変更できないのですか? 提案の紹介によると、再帰 CTE の実装は TiDB の基本的な実行フレームワークから逸脱しません。@wjhuang2016 に相談したところ、サブクエリと集計関数が許可されない理由は 2 つあることがわかりました。
- MySQLでは許可されません
- 許可されると、対処すべきコーナーケースが多くなり、非常に複雑になります。
しかし、ここでは関数をテストするだけなので、このチェックを一時的に削除するのは悪い考えではありません。 diff 2では、サブクエリと集計関数のチェックが削除されています。 もう一度実行してみましょう: +------+----------------------------------+-----------------------------------+-----------------------------------+-----------------------------------+-----------------------------------+-----------------------------------+-----------------------------------+----------------------------------+----------------------------------+----------------------------------+
|反復| w00 | w01 | w02 | w03 | w04 | w10 | w11 | w12 | w13 | w14 | w20 | w21 | w22 | w23 | w24 |
+------+----------------------------------+-----------------------------------+-----------------------------------+-----------------------------------+-----------------------------------+-----------------------------------+-----------------------------------+----------------------------------+----------------------------------+----------------------------------+
| 1000 | 0.988746701341992382020000000002 | 2.154387045383744124308666666676 | - 2.71779165746753750086666666671 | - 1.21990545926424930979999999999 | 0.523764101056271250025665250523 | 0.822804724410132626693333333336 | - 0.100577045244777709968533333327 | - 0.033359805866941626546666666669 | - 1.046591158370568595420000000005 | 0.757865074561280001352887284083 | - 1.511551425752124944953333333333 | - 1.753810000138966371560000000008 | 3.051151463334479351666666666650 | 2.5664966176348179482666666666655 | - 0.981629175617551201349829226980 |
+------+----------------------------------+-----------------------------------+-----------------------------------+-----------------------------------+-----------------------------------+-----------------------------------+-----------------------------------+----------------------------------+----------------------------------+----------------------------------+
成功! 1000 回の反復後にパラメータを取得しました。 新しいパラメータを使用して精度を再計算してみましょう。 +-------------------------------------------------+
|合計( y0 = r0 かつy1 = r1 かつy2 = r2 ) / カウント( * ) |
+-------------------------------------------------+
| 0.9867 |
+-------------------------------------------------+
セット内の1行( 0.02秒)
今回は正解率が98%に達しました。 結論今回は、主に TiDB v5.1 の再帰 CTE 機能を利用して、純粋な SQL を使用して TiDB で Softmax ロジスティック回帰モデルをトレーニングすることに成功しました。テストプロセス中に、TiDB の再帰 CTE では現在サブクエリと集計関数が許可されていないことがわかりました。この制限を回避するために TiDB コードを変更するだけで、最終的にモデルのトレーニングに成功し、iris データセットで 98% の精度を達成しました。 議論- いくつかのテストを行った結果、PostgreSQL も MySQL も再帰 CTE での集計関数の使用をサポートしていないことがわかりました。実装には難しいコーナーケースがいくつかある可能性があります。詳細については話し合うことができます。
- この試みは、すべての次元を手動で拡張するものです。実は、すべての次元を拡張する必要がない実装(例えば、データテーブルのスキーマが(idx、dim、value))も書きましたが、この実装では重みテーブルを2回結合する必要があり、つまりCTEで2回再帰的にアクセスする必要があるため、TiDB Executorの実装も変更する必要があるため、ここでは書きませんでした。しかし実際には、この実装はより汎用的で、1 つの SQL であらゆる次元数のモデルを処理できます (当初は TiDB を使用して MINIST をトレーニングしようと考えていました)。
|