結論

逆行列とは、掛けると単位行列 I になる行列で、A⁻¹ と書きます。行列式が0でない正方行列にだけあります。

この記事でわかること

  • 2×2の公式と、3×3の掃き出し法の全7手順
  • 余因子9個の計算と、NumPy・SymPyでの検算
  • solveがinvより4〜5倍速い実測とエラー原文

2026年10月22日更新|NumPy 2.4.6・SciPy 1.17.1で実行確認

逆行列は「数の逆数」を行列に広げたものです。3 × (1/3) = 1 と同じように、A × A⁻¹ = I(単位行列)になります。ただし、行列式が0の行列には逆行列がありません。

flowchart TD
    A[正方行列 A] --> B{行列式 det A は 0 か}
    B -->|0 でない| C[逆行列 A⁻¹ がある<br>A A⁻¹ = A⁻¹ A = I]
    B -->|0| D[逆行列はない<br>特異行列]
    C --> E[連立方程式は<br>solve で解く]
    D --> F[擬似逆行列 pinv で<br>最小二乗の解]

急いでいる人向けに、よく調べられることの答えを先にまとめます。

知りたいこと 答え 詳しい節
2×2 の公式 (1/(ad−bc)) × [[d, −b], [−c, a]] 2×2
3×3 の求め方 [A|I] を掃き出して [I|A⁻¹] にする 掃き出し法
存在する条件 行列式 ≠ 0(=正則行列) 存在条件
検算のしかた A × A⁻¹ が単位行列になるか 2×2
(AB)⁻¹ B⁻¹A⁻¹(順番が逆になる) 性質
Python で1行 np.linalg.inv(A) Python
連立方程式なら inv より np.linalg.solve(A, b) solve
正方でない・特異なら 擬似逆行列 np.linalg.pinv(A) 擬似逆行列

確認環境:Ubuntu 24.04・Python 3.11.15・NumPy 2.4.6・SciPy 1.17.1・SymPy 1.14.0(BLAS は OpenBLAS 0.3.31、速さの計測は1スレッド)。3×3 の掃き出し法の各手順と余因子9個を分数のまま計算して出力し、NumPy の inv・solve・pinv・cond、SymPy の inv、自作の掃き出し法の関数で同じ答えになることを確かめました。inv と solve の速さと誤差(100〜4000次)、特異行列のエラー原文、ヒルベルト行列で条件数と誤差が増える様子、擬似逆行列と最小二乗法の一致も実行し、出力をそのまま載せています。関数の仕様は NumPy(2.5 のマニュアル)・SciPy・SymPy の公式ドキュメントで、定義と性質は Wikipedia「逆行列」「擬似逆行列」・英語版 Wikipedia「Invertible matrix」「Moore–Penrose inverse」で確かめました(確認日 2026年10月22日)。

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「逆行列とは|求め方(2×2公式・掃き出し法・余因子)をPythonで検算」

逆行列とは(意味を数の逆数と図で)

この節では、逆行列が「何を元に戻す行列なのか」が分かります。

正方行列 A に対して、A X = X A = I(単位行列)を満たす行列 X を A の逆行列と呼び、A⁻¹(エー・インバース)と書きます。 英語では inverse matrix です。逆行列を持つ行列を正則行列(せいそくぎょうれつ)、または可逆行列と呼びます。

単位行列 I は、対角線が1で、ほかが0の正方行列です。数の「1」と同じで、どんな行列に掛けても相手を変えません(A I = I A = A)。

数の世界 行列の世界
1 単位行列 I
3 の逆数 1/3(3 × 1/3 = 1) A の逆行列 A⁻¹(A A⁻¹ = I)
0 には逆数がない 行列式が0の行列には逆行列がない
3x = 6 なら x = 6 ÷ 3 A x = b なら x = A⁻¹ b
割り算 行列の割り算は無い。逆行列を掛ける

行列を「ベクトルを別のベクトルに移す変換」と見ると、逆行列は「移したものを元に戻す変換」です。A = [[2, 1], [4, 3]] で確かめます。

flowchart TD
    X[ベクトル x<br>例 1, 3] -->|A を掛ける| Y[ベクトル y = A x<br>例 5, 13]
    Y -->|A⁻¹ を掛ける| Z[元の x に戻る<br>1, 3]

A は (1, 0) を (2, 4) に、(0, 1) を (1, 3) に移します。(1, 3) は (5, 13) に移り、A⁻¹ を掛けると (1, 3) に戻ります。この「元に戻す」ができない変換に、逆行列はありません(次の節)。

逆行列が使われる場面

1連立方程式を解く

A x = b を x = A⁻¹ b と書ける。数式で解の形を表すときの基本。プログラムで解くときは solve を使う。

2最小二乗法・回帰

回帰の係数は (XᵀX)⁻¹Xᵀy で表せる(正規方程式)。正方でない X には擬似逆行列を使う。

33D・ゲーム・画像

回転・拡大・移動の変換を元に戻す。カメラの座標からワールド座標へ戻す計算や、画像の射影変換の逆変換。

4統計・機械学習

多変量正規分布の式に共分散行列の逆行列が出る。マハラノビス距離、カルマンフィルター、ガウス過程など。

逆行列が存在する条件(行列式・正則・特異)

この節では、逆行列が「ある・ない」の見分け方と、行列式が0だと逆行列がない理由が分かります。

正方行列 A に逆行列があるのは、行列式 det A が0でないときだけです。 行列式が0の行列を特異行列(とくいぎょうれつ、singular matrix)と呼びます。正方でない行列(2×3 など)には、ふつうの逆行列はありません。

行列式が0だと逆行列がない理由

S = [[1, 2], [2, 4]] は、2行目が1行目のちょうど2倍で、行列式は 1×4 − 2×2 = 0 です。いくつかのベクトルを S で移しました。

[1, 0]  -> [1 2]
[0, 1]  -> [2 4]
[3, 0]  -> [3 6]
[1, 1]  -> [3 6]
[-1, 2] -> [3 6]

(3, 0)・(1, 1)・(−1, 2) という別々のベクトルが、どれも (3, 6) に移りました。 S は平面全体を直線 y = 2x の上に押しつぶすので、(3, 6) を見ても元がどれだったかを決められません。これが「元に戻す行列(逆行列)が作れない」ということです。

零行列 O(成分が全部0)も、すべてのベクトルを0に移すので逆行列がありません。np.linalg.inv(np.zeros((2, 2))) も LinAlgError: Singular matrix でした。

行列式は、変換で面積(3×3 なら体積)が何倍になるかを表します。A = [[2, 1], [4, 3]] の行列式は 2 で、面積を2倍にします。行列式が0の変換は、面積を0に押しつぶします。

逆行列があることと同じ意味の条件

次の条件は、n×n の正方行列ではどれも同じ意味です(英語版 Wikipedia「Invertible matrix」の一覧から主なもの)。どれか1つを確かめれば、逆行列があるかどうかが分かります。

条件 確かめ方の例 S = [[1,2],[2,4]]
行列式が0でない np.linalg.det(A) 0.0
階数(ランク)が n np.linalg.matrix_rank(A) 1
行基本変形で単位行列にできる 掃き出し法で途中に0の行が出ない 2行目が全部0になる
A x = b の解がちょうど1つ どの b でも解が1つに決まる 解なし、または無数
A x = 0 の解が x = 0 だけ 列(行)が1次独立 x = (2, −1) も解
0 が固有値でない np.linalg.eigvals(A) 固有値に0がある

2×2の逆行列の公式

この節では、2×2 の逆行列を一発で出す公式と、計算の例・検算のしかたが分かります。

A = [[a, b], [c, d]] で ad − bc ≠ 0 のとき、A⁻¹ = (1/(ad − bc)) × [[d, −b], [−c, a]] です。 覚え方は「a と d を入れ替え、b と c の符号を変えて、行列式で割る」です。

A = | a  b |          A⁻¹ =      1      | d  −b |
    | c  d |                 ―――――――  | −c  a |
                              ad − bc

A = [[2, 1], [4, 3]] で計算します。

1

行列式を求める

ad − bc = 2×3 − 1×4 = 2。0でないので逆行列がある。

det A = 2

2

入れ替えて符号を変える

a と d を入れ替え、b と c の符号を変えると [[3, −1], [−4, 2]]。

余因子行列

3

行列式で割る

各成分を2で割って A⁻¹ = [[3/2, −1/2], [−2, 1]]。

× 1/2

4

検算する

A A⁻¹ の1行1列は 2×3/2 + 1×(−2) = 1、1行2列は 2×(−1/2) + 1×1 = 0。全部で単位行列になれば正しい。

A A⁻¹ = I

NumPy と SymPy で同じ計算をすると、手計算と同じ答えになりました。

np.linalg.inv: [[ 1.5 -0.5]
                [-2.   1. ]]
sympy        : det 2  inv [[3/2, -1/2], [-2, 1]]

公式の「行列式で割る」から、行列式が0なら割れない=逆行列がない、ことも読み取れます。 なぜこの形になるかは、A に [[d, −b], [−c, a]] を掛けると [[ad − bc, 0], [0, ad − bc]] になることから分かります。これを ad − bc で割れば単位行列です。

3×3の逆行列の求め方①掃き出し法(行基本変形)

この節では、3×3 以上の逆行列を求めるいちばん一般的な方法、掃き出し法(ガウス・ジョルダン法)の全手順が分かります。

A の右に単位行列 I を並べた [A|I] を作り、行基本変形で左半分を単位行列にすると、右半分が A⁻¹ になります。 使ってよい操作(行基本変形)は次の3つだけです。

操作 書き方の例 注意
ある行を0でない数で割る(掛ける) R3 = R3 ÷ 2 0を掛けるのは不可
ある行に、別の行の何倍かを足す(引く) R3 = R3 − 4 × R1 引く行そのものは変えない
2つの行を入れ替える R1 ⇔ R2 ピボットが0のときに使う

例は A = [[0, 1, 2], [1, 0, 3], [4, −3, 8]] です。1行1列が0なので、行の入れ替えから始まります。Python の分数(fractions)で1手ずつ計算し、そのまま出力しました。

--- start [A | I]
  [    0      1      2 |    1      0      0 ]
  [    1      0      3 |    0      1      0 ]
  [    4     -3      8 |    0      0      1 ]
--- swap R1 <-> R2
  [    1      0      3 |    0      1      0 ]
  [    0      1      2 |    1      0      0 ]
  [    4     -3      8 |    0      0      1 ]
--- R3 = R3 - (4) x R1
  [    1      0      3 |    0      1      0 ]
  [    0      1      2 |    1      0      0 ]
  [    0     -3     -4 |    0     -4      1 ]
--- R3 = R3 - (-3) x R2
  [    1      0      3 |    0      1      0 ]
  [    0      1      2 |    1      0      0 ]
  [    0      0      2 |    3     -4      1 ]
--- R3 = R3 / 2
  [    1      0      3 |    0      1      0 ]
  [    0      1      2 |    1      0      0 ]
  [    0      0      1 |  3/2     -2    1/2 ]
--- R1 = R1 - (3) x R3
  [    1      0      0 | -9/2      7   -3/2 ]
  [    0      1      2 |    1      0      0 ]
  [    0      0      1 |  3/2     -2    1/2 ]
--- R2 = R2 - (2) x R3
  [    1      0      0 | -9/2      7   -3/2 ]
  [    0      1      0 |   -2      4     -1 ]
  [    0      0      1 |  3/2     -2    1/2 ]
inverse: [['-9/2', '7', '-3/2'], ['-2', '4', '-1'], ['3/2', '-2', '1/2']]
A x Ainv = [['1', '0', '0'], ['0', '1', '0'], ['0', '0', '1']]

7回の操作で左半分が単位行列になり、右半分が逆行列です。

        | −9/2   7   −3/2 |         1   | −9   14  −3 |
A⁻¹ =   |  −2    4    −1  |   =   ―――  | −4    8  −2 |
        |  3/2  −2    1/2 |         2   |  3   −4   1 |

手順を言葉でまとめると、1列目から順に「ピボット(対角の数)を1にする → 同じ列のほかの行を0にする」を繰り返すだけです。

1

[A|I] を作る

A の右に同じ大きさの単位行列を並べる。3×3 なら3行6列。

左が A、右が I

2

ピボットを決める

対角の位置が0なら、下の行で0でないものと入れ替える。例では1行1列が0なので R1 と R2 を入れ替えた。

行の入れ替え

3

ピボットを1にする

その行全体をピボットの数で割る。例の3列目では R3 を2で割った。

行を割る

4

同じ列のほかを0にする

ほかの行から「ピボットの行 × その行の数」を引く。上の行も下の行も0にする。

行の何倍かを引く

5

次の列へ進み、検算する

全部の列が終わったら右半分が A⁻¹。A × A⁻¹ が単位行列になるかを確かめる。

A A⁻¹ = I

途中で左半分のある行が全部0になったら、その行列には逆行列がありません。 S = [[1, 2], [2, 4]] では、R2 = R2 − 2 × R1 で2行目の左半分が [0, 0] になり、そこで止まります。逆行列があるかどうかの判定と計算を同時にできるのが、掃き出し法の強みです。

行基本変形は、どれも「基本行列」を左から掛けることと同じです。 たとえば R1 と R2 の入れ替えは、単位行列の1行目と2行目を入れ替えた行列 [[0, 1, 0], [1, 0, 0], [0, 0, 1]] を A に左から掛けることで、結果は [[1, 0, 3], [0, 1, 2], [4, −3, 8]] になりました。7回の操作の基本行列を全部掛けた積 E7 … E2 E1 が A を I にするので、その積が A⁻¹ です。[A|I] の右半分は、その積を I に掛けた結果を記録しています。

3×3の逆行列の求め方②余因子行列

この節では、行列式と余因子(よいんし)を使って逆行列を求める方法を、9個の余因子を全部計算して示します。

A⁻¹ = (1/det A) × adj A です。adj A(余因子行列)は、各成分の余因子を並べた行列を転置したものです。 2×2 の公式は、この式の2×2の場合です。

手順1:行列式を求める(サラスの方法)

A = [[0, 1, 2], [1, 0, 3], [4, −3, 8]] の行列式を、3×3 で使えるサラスの方法で計算します。

det A = 0×0×8 + 1×3×4 + 2×1×(−3) − 2×0×4 − 1×1×8 − 0×3×(−3)
      = 0 + 12 − 6 − 0 − 8 − 0
      = −2

手順2:余因子を9個求める

i 行 j 列の余因子 Cij は、「A から i 行と j 列を取り除いた 2×2 の行列式」に (−1)^(i+j) を掛けたものです。符号は市松模様(+ − + / − + − / + − +)になります。SymPy で1つずつ出力しました。

det A = -2
C11 = (-1)^2 x det[[0, 3], [-3, 8]] = 9
C12 = (-1)^3 x det[[1, 3], [4, 8]] = 4
C13 = (-1)^4 x det[[1, 0], [4, -3]] = -3
C21 = (-1)^3 x det[[1, 2], [-3, 8]] = -14
C22 = (-1)^4 x det[[0, 2], [4, 8]] = -8
C23 = (-1)^5 x det[[0, 1], [4, -3]] = 4
C31 = (-1)^4 x det[[1, 2], [0, 3]] = 3
C32 = (-1)^5 x det[[0, 2], [1, 3]] = 2
C33 = (-1)^6 x det[[0, 1], [1, 0]] = -1
cofactor matrix: [[9, 4, -3], [-14, -8, 4], [3, 2, -1]]
adj A (transpose): [[9, -14, 3], [4, -8, 2], [-3, 4, -1]]
A^-1 = adj/det: [[-9/2, 7, -3/2], [-2, 4, -1], [3/2, -2, 1/2]]

手順3:転置して行列式で割る

余因子を並べた行列 [[9, 4, −3], [−14, −8, 4], [3, 2, −1]] を転置(行と列を入れ替え)すると adj A です。転置を忘れるのがいちばん多い間違いです。 adj A を det A = −2 で割ると、掃き出し法と同じ A⁻¹ = [[−9/2, 7, −3/2], [−2, 4, −1], [3/2, −2, 1/2]] になりました。

掃き出し法と余因子、どちらを使うか

掃き出し法(ガウス・ジョルダン法)

4×4 以上でも同じ手順で進められる

逆行列が無いことも途中で分かる

計算の量は n³ に比例し、コンピューターの方法の土台

分数が途中で出やすく、写し間違いに注意

余因子行列

逆行列の各成分を式で書ける(理論・証明向き)

3×3 なら 2×2 の行列式9個で済み、分数が最後まで出ない

4×4 では 3×3 の行列式が16個必要で、急に大変になる

転置と符号の付け忘れが起きやすい

状況 選ぶ方法
2×2 公式(余因子の2×2版)
3×3 を手で、分数を避けたい 余因子行列
3×3 を手で、逆行列があるか分からない 掃き出し法
4×4 以上を手で 掃き出し法
プログラムで数値を求める np.linalg.inv(中身は LU 分解)
プログラムで分数のまま求める SymPy の Matrix(A).inv()
連立方程式を解きたい 逆行列を作らず np.linalg.solve

Wikipedia「逆行列」は、クラメルの公式(行列式を使う方法)は理論上は重要だが、逆行列の数値計算には向かない、と書いています。

逆行列の性質(公式一覧)

この節では、逆行列の計算でよく使う性質と、それが成り立つことを NumPy で確かめた結果が分かります。

性質 式 実行結果
積の逆行列 (AB)⁻¹ = B⁻¹A⁻¹ True(A⁻¹B⁻¹ とは False)
転置の逆行列 (Aᵀ)⁻¹ = (A⁻¹)ᵀ True
複素行列の随伴(共役転置) (Aᴴ)⁻¹ = (A⁻¹)ᴴ True(2×2 の複素行列)
逆行列の逆行列 (A⁻¹)⁻¹ = A True
定数倍 (kA)⁻¹ = (1/k) A⁻¹ True(k = 3)
行列式 det(A⁻¹) = 1 / det A −0.4999999999999997 と −0.5
左右どちらから掛けても I A⁻¹A = AA⁻¹ = I True・True
対角行列 対角成分の逆数を並べる diag(2, 4, 5) → 0.5・0.25・0.2
回転行列 逆行列は転置と同じ True
冪零行列 N(Nⁿ = O) (I − N)⁻¹ = I + N + … + Nⁿ⁻¹ True(3×3 で I + N + N²)
import numpy as np
inv = np.linalg.inv
A = np.array([[0, 1, 2], [1, 0, 3], [4, -3, 8.]])
B = np.array([[2, 1, 0], [1, 3, 1], [0, 1, 4.]])
print(np.allclose(inv(A @ B), inv(B) @ inv(A)))   # True
print(np.allclose(inv(A @ B), inv(A) @ inv(B)))   # False(順番が逆だと成り立たない)
print(np.allclose(inv(A.T), inv(A).T))            # True

(AB)⁻¹ は B⁻¹A⁻¹ で、掛ける順番が逆になります。 「靴下を履いてから靴を履いたら、脱ぐときは靴が先」と同じで、後からした変換を先に戻すためです。行列の積は順番を入れ替えると結果が変わるので、A⁻¹B⁻¹ では成り立ちませんでした。

行列式は 1/det A と一致しますが、浮動小数点の計算なので −0.5 ではなく −0.4999999999999997 と出ました。小数の比較は == ではなく np.allclose で行います。

逆行列で連立方程式を解く

この節では、連立方程式を行列で書き、逆行列で解く方法が分かります。

連立方程式は A x = b と書けます。A に逆行列があれば、両辺に左から A⁻¹ を掛けて x = A⁻¹ b です。 次の3元連立方程式を解きます。

       y + 2z =  5          | 0   1  2 | | x |   |  5 |
  x      + 3z =  7    →     | 1   0  3 | | y | = |  7 |
 4x − 3y + 8z = 15          | 4  −3  8 | | z |   | 15 |

係数の行列は、前の節で逆行列を求めた A そのものです。A⁻¹ に b を掛けます。

x = −9/2 × 5 + 7 × 7 − 3/2 × 15 = −22.5 + 49 − 22.5 = 4
y =   −2 × 5 + 4 × 7 −   1 × 15 = −10 + 28 − 15     = 3
z =  3/2 × 5 − 2 × 7 + 1/2 × 15 = 7.5 − 14 + 7.5    = 1

NumPy でも同じ答えになりました。

A = np.array([[0, 1, 2], [1, 0, 3], [4, -3, 8]])
b = np.array([5, 7, 15])
print(np.linalg.solve(A, b))         # [4. 3. 1.]
print(np.linalg.inv(A) @ b)          # [4. 3. 1.]

2元連立方程式 2x + y = 5、4x + 3y = 13 も、2×2 の公式の例 A = [[2, 1], [4, 3]] で x = 1、y = 3 になりました(np.linalg.solve(B, [5, 13]) → [1. 3.])。

数式の上では x = A⁻¹ b ですが、プログラムで解くときは逆行列を作らずに solve を使います。 理由は後の節「inv より solve がよい理由」で実測します。

Pythonで逆行列を求める(NumPy・SymPy)

この節では、NumPy で逆行列を求めて検算するコードと、分数のまま求める方法が分かります。

import numpy as np

A = np.array([[0, 1, 2], [1, 0, 3], [4, -3, 8]])
Ai = np.linalg.inv(A)                          # 逆行列
print(Ai, Ai.dtype)
print(A @ Ai)                                  # 検算(単位行列になるか)
print(np.allclose(A @ Ai, np.eye(3)))          # True なら正しい
print(np.linalg.det(A), np.linalg.matrix_rank(A), np.linalg.cond(A))
[[-4.5  7.  -1.5]
 [-2.   4.  -1. ]
 [ 1.5 -2.   0.5]] float64
[[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]]
True
-2.0 3 99.38723879785424

整数の行列を渡しても、結果は小数(float64)で返ります。行列式 −2.0・階数 3・条件数 99.4 も一緒に確かめておくと、逆行列が信用できるかが分かります(条件数は後の節)。

やりたいこと 書き方 備考
逆行列 np.linalg.inv(A) 正方行列だけ
連立方程式 A x = b np.linalg.solve(A, b) 逆行列を作らない
擬似逆行列 np.linalg.pinv(A) 正方でなくてよい
最小二乗の解 np.linalg.lstsq(A, b) 解が無い・無数でも使える
行列式・階数・条件数 det・matrix_rank・cond 逆行列の前の確認
逆行列の2乗など np.linalg.matrix_power(A, -2) 負の指数は逆行列
分数のまま sympy.Matrix(A).inv() 手計算の答え合わせ向き
小数を分数で見る Fraction(x).limit_denominator() 標準ライブラリ fractions

手計算の答え合わせには、SymPy が分数のまま出すので便利です。

import sympy as sp
A = sp.Matrix([[0, 1, 2], [1, 0, 3], [4, -3, 8]])
print(A.det())        # -2
print(A.inv())        # Matrix([[-9/2, 7, -3/2], [-2, 4, -1], [3/2, -2, 1/2]])
print(A.adjugate())   # 余因子行列 Matrix([[9, -14, 3], [4, -8, 2], [-3, 4, -1]])
print(sp.Matrix.hstack(A, sp.eye(3)).rref()[0])   # [A | I] を掃き出した結果

NumPy の結果を分数で見るなら、標準ライブラリの fractions.Fraction(x).limit_denominator() を使います。上の Ai は [['-9/2', '7', '-3/2'], ['-2', '4', '-1'], ['3/2', '-2', '1/2']] と表示できました。配列の作り方や @(行列の積)の書き方は、関連記事「NumPyの使い方 基本一覧|配列の作成・演算・形状変更」で扱っています。

掃き出し法を Python で書く(コピペで使える完成版)

ライブラリを使わずに、掃き出し法をそのまま書いた関数です。対角の数が0に近いと誤差が大きくなるので、各列で絶対値が最大の行と入れ替える「部分ピボット選択」を入れています。

def inverse(a, eps=1e-12):
    """正方行列 a(リストのリスト)の逆行列を、掃き出し法(部分ピボット選択つき)で返す。"""
    n = len(a)
    if any(len(row) != n for row in a):
        raise ValueError("正方行列ではありません")
    # [A | I] を作る
    m = [list(map(float, row)) + [1.0 if i == j else 0.0 for j in range(n)]
         for i, row in enumerate(a)]
    for c in range(n):
        # c 列目で絶対値が最大の行をピボットにして入れ替える(部分ピボット選択)
        p = max(range(c, n), key=lambda r: abs(m[r][c]))
        if abs(m[p][c]) < eps:
            raise ValueError("逆行列はありません(特異行列)")
        m[c], m[p] = m[p], m[c]
        piv = m[c][c]
        m[c] = [v / piv for v in m[c]]               # ピボットを 1 にする
        for r in range(n):                           # ほかの行の c 列目を 0 にする
            if r != c and m[r][c] != 0.0:
                k = m[r][c]
                m[r] = [x - k * y for x, y in zip(m[r], m[c])]
    return [row[n:] for row in m]                    # 右半分が逆行列

if __name__ == "__main__":
    A = [[0, 1, 2], [1, 0, 3], [4, -3, 8]]
    for row in inverse(A):
        print(row)
    try:
        inverse([[1, 2], [2, 4]])
    except ValueError as e:
        print("ValueError:", e)
[-4.5, 7.0, -1.5]
[-2.0, 4.0, -1.0]
[1.5, -2.0, 0.5]
ValueError: 逆行列はありません(特異行列)

乱数の行列で NumPy の inv と比べると、差は最大でも 1e-13 程度(計算機の丸め誤差)で一致しました。速さは、3×3 では自作の方が速く、大きくなるほど NumPy が大きく上回りました。

n=  3 maxdiff 8.9e-16  pure python     0.05 ms  numpy  0.089 ms
n= 10 maxdiff 7.8e-14  pure python     0.16 ms  numpy  0.028 ms
n= 50 maxdiff 1.3e-13  pure python    11.06 ms  numpy  0.162 ms
n=100 maxdiff 2.5e-14  pure python    87.35 ms  numpy  0.593 ms
n=200 maxdiff 1.5e-14  pure python   764.00 ms  numpy  2.479 ms

200×200 で約300倍の差です。仕組みを学ぶには自作、使うときは NumPy、と分けます。

inv より solve がよい理由(速さと誤差の実測)

この節では、連立方程式を inv(A) @ b ではなく solve(A, b) で解く理由が、速さと誤差の実測で分かります。

solve は逆行列を作らずに LU 分解で直接解くので、inv で逆行列を作ってから掛けるより速く、誤差も小さくなります。 NumPy のドキュメントは、solve は LAPACK の _gesv で計算すると書いています。英語版 Wikipedia「Invertible matrix」も、多くの実用の場面では連立方程式を解くのに逆行列は要らない、と書いています。

乱数の n×n 行列で、右辺 b が1本の連立方程式を解く時間(5回の最速、1スレッド)と、残差 ‖Ax − b‖ ÷ ‖b‖ を測りました。

import numpy as np, time
rng = np.random.default_rng(0)
A = rng.standard_normal((n, n)); b = rng.standard_normal(n)
x1 = np.linalg.inv(A) @ b          # 逆行列を作ってから掛ける
x2 = np.linalg.solve(A, b)         # 逆行列を作らずに解く
n=  100 inv@b      0.29 ms  solve      0.08 ms  ratio  3.6  resid inv 4.7e-14 solve 4.2e-14
n=  500 inv@b     16.17 ms  solve      3.44 ms  ratio  4.7  resid inv 1.4e-13 solve 5.9e-14
n= 1000 inv@b    109.14 ms  solve     21.05 ms  ratio  5.2  resid inv 2.0e-12 solve 1.0e-12
n= 2000 inv@b    545.99 ms  solve    125.90 ms  ratio  4.3  resid inv 1.3e-11 solve 7.2e-12
n= 4000 inv@b   3585.13 ms  solve    885.21 ms  ratio  4.1  resid inv 3.3e-11 solve 7.1e-12

4000×4000 の連立方程式を解く時間棒の長さは inv@b を100%とした割合

inv(A) @ b3.59秒
solve(A, b)0.89秒

どの大きさでも solve が3.6〜5.2倍速く、残差も同じか小さくなりました(4000次で 3.3e-11 と 7.1e-12)。 逆行列を作る計算は、LU 分解に加えて「単位行列の n 本の列それぞれについて解く」分が増えるためです。

右辺が何本もあるとき(b が行列)も、solve(A, B) にまとめて渡す方が速くなりました(2000次)。

右辺の本数 k inv(A) @ B solve(A, B)
1 567.2 ms 144.4 ms
10 619.8 ms 161.7 ms
100 611.4 ms 201.1 ms
1000 1342.6 ms 345.4 ms

右辺があとから1本ずつ届く場合は、SciPy の lu_factor で一度だけ LU 分解しておき、lu_solve で解きます。2000次で、分解が 121.0 ms、その後は1本 1.54 ms でした。

連立方程式 A x = b を解くとき

x = np.linalg.inv(A) @ b逆行列を作るぶん遅い。4000次で3.59秒。悪条件の行列では誤差も大きい
→
x = np.linalg.solve(A, b)LU 分解で直接解く。4000次で0.89秒。残差は計算機の精度に近い

逆行列そのものが欲しいとき(成分を見る・式に使う)だけ inv を使う

特異行列のエラー原文と直し方(Singular matrix)

この節では、逆行列の計算で出るエラーの原文と、原因・直し方が分かります。どれも NumPy 2.4.6・SciPy 1.17.1 で実際に出たものです。

>>> np.linalg.inv(np.array([[1, 2], [2, 4]]))
numpy.linalg.LinAlgError: Singular matrix
>>> np.linalg.inv(np.ones((2, 3)))
numpy.linalg.LinAlgError: Last 2 dimensions of the array must be square
>>> np.linalg.solve(A, [1, 2])          # A は 3×3
ValueError: solve1: Input operand 1 has a mismatch in its core dimension 0, with gufunc signature (m,m),(m)->(m) (size 2 is different from 3)
>>> A ** -1                              # A は整数の配列
ValueError: Integers to negative integer powers are not allowed.
>>> scipy.linalg.inv(np.array([[1, 2], [2, 4.]]))
numpy.linalg.LinAlgError: A singular matrix detected: slice(s) [0] are singular.
エラー・警告 原因 直し方
LinAlgError: Singular matrix 行列式が0(行や列が他の組み合わせで書ける) matrix_rank で階数を確かめる。解きたいなら lstsq か pinv
LinAlgError: Last 2 dimensions of the array must be square 正方でない行列を inv に渡した 形を確かめる。最小二乗なら pinv・lstsq
ValueError: solve1: ... mismatch in its core dimension 0 b の長さが A の行数と違う b の形を (n,) か (n, k) にそろえる
ValueError: Integers to negative integer powers are not allowed. A ** -1 は成分ごとの逆数で、整数では不可 np.linalg.inv(A) を使う
UFuncTypeError: Cannot cast ufunc 'inv' input from dtype('<U21') ... 文字列が混ざった astype(float) で数値にする。CSV の読み込みを見直す
結果が全部 nan 入力に nan がある np.isnan(A).any() で確かめて欠損を除く
LinAlgWarning: An ill-conditioned matrix detected: ... rcond = 1.33e-18.(SciPy) 逆行列はあるが、ほぼ特異で誤差が大きい 次の節の条件数を見る。スケールをそろえる・lstsq
LinAlgError: A singular matrix detected: slice(s) [0] are singular.(SciPy) SciPy で特異行列を渡した NumPy の Singular matrix と同じ対処

特に注意したいのは、A ** -1 や 1 / A は逆行列ではなく「成分ごとの逆数」になることです。小数の配列だとエラーにならず、RuntimeWarning: divide by zero encountered in reciprocal(1 / A では ... in divide)と警告を出して、0の成分が inf の行列を返しました。逆行列は np.linalg.inv(A) か np.linalg.matrix_power(A, -1) で求めます。np.matrix 型なら M.I でも逆行列が返りますが、NumPy のドキュメントは、このクラスは線形代数でも使うことを勧めず、ふつうの配列を使うよう書いています。

エラーが出ないのに答えがおかしい、という場合もあります。 NumPy のドキュメントは inv について「a が悪条件のときは LinAlgError が出ることも出ないこともあり、浮動小数点の誤差で結果が不正確になることがある」と書いています。これが次の節の条件数です。

条件数とは(誤差が大きくなる例)

この節では、逆行列や連立方程式の答えがどれくらい信用できるかを、条件数(じょうけんすう)という1つの数で判断する方法が分かります。

条件数は「入力の小さなずれが、答えで最大何倍のずれになるか」を表す数で、np.linalg.cond(A) で求めます。 1 に近いほど安定(良条件)、大きいほど不安定(悪条件)です。Wikipedia「条件数」は、条件数は問題そのものの性質で、計算の方法には依存しない、と説明しています。

2×2 で、b が 0.0001 ずれると答えが 1 ずれる

A = [[1, 1], [1, 1.0001]] は、行列式が 0.0001 で、ほぼ特異な行列です。右辺 b をわずかに変えて解きました。

cond 40002.000074915224 det 9.99999999999889e-05
inv [[ 10001. -10000.]
 [-10000.  10000.]]
b [2, 2.0001] x [1. 1.]
b [2, 2.0002] x [0. 2.]
b [2.0001, 2.0001] x [2.0001 0.    ]
0.0001右辺 b の変化2.0001 → 2.0002
1答え x の変化(1, 1) → (0, 2)
4万条件数cond = 40002

b の2つ目が 0.0001 変わっただけで、答えが (1, 1) から (0, 2) に変わりました。 逆行列の成分が 10001・−10000 と大きく、b のずれが1万倍されるためです。測定値の誤差が 0.0001 あるなら、この連立方程式の答えはほとんど決まりません。

ヒルベルト行列で、条件数が大きいほど正しい桁が減る

ヒルベルト行列(i 行 j 列が 1/(i + j − 1))は、悪条件の例としてよく使われます。正解を x = (1, 1, …, 1) にして b = H x を作り、解き直した答えと正解の最大のずれを測りました。

from scipy.linalg import hilbert
H = hilbert(n); x_true = np.ones(n); b = H @ x_true
np.linalg.cond(H)
np.abs(np.linalg.inv(H) @ b - x_true).max()
np.abs(np.linalg.solve(H, b) - x_true).max()
n= 4 cond 1.6e+04 log10   4.2  err inv 1.8e-12 solve 5.4e-14  resid inv 8.2e-14 solve 0.0e+00  |inv(H)H-I|max 2.3e-13
n= 6 cond 1.5e+07 log10   7.2  err inv 2.0e-09 solve 6.6e-11  resid inv 8.1e-12 solve 1.5e-16  |inv(H)H-I|max 4.6e-10
n= 8 cond 1.5e+10 log10  10.2  err inv 2.9e-06 solve 7.2e-08  resid inv 7.1e-08 solve 6.0e-17  |inv(H)H-I|max 5.3e-07
n=10 cond 1.6e+13 log10  13.2  err inv 8.1e-03 solve 4.4e-05  resid inv 4.2e-05 solve 1.0e-16  |inv(H)H-I|max 1.2e-03
n=12 cond 1.6e+16 log10  16.2  err inv 7.1e+00 solve 2.8e-01  resid inv 2.7e-02 solve 1.1e-16  |inv(H)H-I|max 9.6e-01
n=13 cond 4.5e+18 log10  18.7  err inv 1.7e+03 solve 4.5e+01  resid inv 2.6e+00 solve 5.2e-16  |inv(H)H-I|max 1.8e+02
n=14 cond 3.2e+17 log10  17.5  err inv 1.2e+03 solve 7.5e+00  resid inv 1.1e+00 solve 4.8e-17  |inv(H)H-I|max 1.3e+02

条件数の桁数(log10)と、solve の答えで正しく残った桁数(−log10 誤差)を並べると、足して17前後(16.8〜17.6)になりました。

---
config:
  xyChart:
    width: 480
    height: 300
---
xychart-beta
    title "条件数の桁数(棒)と正しく残った桁数(線)"
    x-axis "ヒルベルト行列の次数" [4, 6, 8, 10, 12]
    y-axis "桁" 0 --> 18
    bar [4.2, 7.2, 10.2, 13.2, 16.2]
    line [13.3, 10.2, 7.1, 4.4, 0.6]

float64 の精度は約16桁(np.finfo(float).eps = 2.22e-16)で、条件数が 10 の k 乗なら、答えの正しい桁はおよそ 17 − k 桁まで減りました。 12次では条件数 1.6e+16 で、正しい桁がほぼ残らず、誤差 0.28 でした。それでも inv は12〜14次でエラーを出さずに値を返し、inv(H) @ H は単位行列から最大 180 もずれました。

inv と solve を比べると、どの次数でも solve の誤差が inv の約1/25〜1/180 で、残差(H x − b)は solve が常に 1e-16 前後でした。悪条件の行列ほど、逆行列を経由しない差が大きく出ます。

条件数 cond(A) 読み方 すること
1〜1e3 程度 良条件。結果はほぼ信用できる そのまま使う
1e6〜1e10 6〜10桁ほど失う 答えの桁数を意識する。solve を使う
1e12 以上 正しい桁が数桁しか残らない 変数のスケールをそろえる。モデルを見直す
1e16 前後(1/eps)以上 float64 では特異と同じ lstsq・pinv・正則化(リッジ)を使う

条件数を下げる方法として、変数の単位や大きさをそろえる(標準化)があります。多項式の当てはめで x をそろえると条件数が 1.9e+09 から 7.3e+02 に下がった実測は、関連記事「最小二乗法とは|公式・手計算の例とPythonでの求め方を実例で解説」で扱っています。小数の計算で誤差が出るそもそもの理由は、関連記事「JavaScriptの小数計算誤差と丸め|toFixedの落とし穴と正しい対処法」で扱っています。

擬似逆行列(pinv)と最小二乗法の関係

この節では、正方でない行列や特異行列にも使える「擬似逆行列」と、それが最小二乗法の答えになる理由が分かります。

擬似逆行列(ムーア・ペンローズ一般化逆行列、A⁺ と書く)は、どんな形の行列にも1つだけ決まる「逆行列の代わり」です。 A が正則なら A⁺ = A⁻¹ です。英語版 Wikipedia によると、1920年に E. H. ムーア、1951年に A. ビエルハマー、1955年に R. ペンローズが独立に示しました。次の4つの条件をすべて満たす行列として決まります。

① A A⁺ A = A
② A⁺ A A⁺ = A⁺
③ (A A⁺)ᵀ = A A⁺
④ (A⁺ A)ᵀ = A⁺ A

正方でない行列:pinv の答えは最小二乗法の直線と同じ

最小二乗法の記事と同じ5点 (1, 2)・(2, 3)・(3, 5)・(4, 4)・(5, 6) で、直線 y = a x + b を当てはめます。X は5行2列で正方でないので、inv は使えません。

x = np.array([1, 2, 3, 4, 5.]); y = np.array([2, 3, 5, 4, 6.])
X = np.column_stack([x, np.ones(5)])          # 5×2
print(np.linalg.pinv(X) @ y)                   # 擬似逆行列
print(np.linalg.inv(X.T @ X) @ X.T @ y)        # 正規方程式 (XᵀX)⁻¹Xᵀy
print(np.linalg.lstsq(X, y)[0])                # 最小二乗
pinv(X) shape (2, 5)
pinv(X)@y [0.9 1.3]
(XtX)^-1 Xt @y [0.9 1.3]
lstsq [0.9 1.3]
pinv == (XtX)^-1Xt: True
inv(X): LinAlgError Last 2 dimensions of the array must be square

3つとも a = 0.9、b = 1.3 で、最小二乗法の直線 y = 0.9x + 1.3 と同じになりました。 X の列が1次独立のとき、擬似逆行列は (XᵀX)⁻¹Xᵀ と同じ行列になります(True)。NumPy のドキュメントも、擬似逆行列を「A x = b の最小二乗問題を解く行列」と説明しています。pinv(X) @ X は 2×2 の単位行列(左逆行列)になりますが、X @ pinv(X) は 5×5 の単位行列にはなりません。

特異な正方行列:解が無数なら長さが最小の解

S = [[1, 2], [2, 4]] は特異行列で inv はエラーでしたが、pinv は答えを返します。

pinv(S)= [[0.04 0.08]
 [0.08 0.16]]  = S/25: True
S@Sp@S==S True
Sp@S@Sp==Sp True
(S@Sp)^T==S@Sp True
(Sp@S)^T==Sp@S True
min-norm solution of x+2y=3: [0.6 1.2] norm 1.3416407864998734 check [3. 6.]
other solution (3,0) norm 3.0 (1,1) norm 1.4142135623730951
inconsistent b=(3,5): pinv [0.52 1.04] S@x [2.6 5.2]
  • 4つの条件はすべて True でした。
  • S x = (3, 6) は「x + 2y = 3」と同じ式で、解は無数にあります。pinv は、その中で長さ(ノルム)が最小の (0.6, 1.2) を返しました。 (3, 0) は長さ 3.0、(1, 1) は 1.414 で、(0.6, 1.2) の 1.342 がいちばん短い解です。
  • S x = (3, 5) は解がありません(矛盾)。pinv は S x が (3, 5) にいちばん近くなる (0.52, 1.04) を返し、S x は (2.6, 5.2) でした。
行列の状態 使うもの 返ってくる答え
正方で正則 solve(または inv) ただ1つの解
縦長(式が多い)で列が1次独立 lstsq・pinv 最小二乗の解
解が無数(特異・横長) pinv・lstsq 長さが最小の解
解が無い(矛盾) pinv・lstsq ずれの二乗和が最小の解
ほぼ特異(条件数が大きい) lstsq・pinv(rcond で小さい特異値を0に) 安定した近似解

pinv は特異値分解(SVD)で計算し、特異値が「最大の特異値 × 1e-15」以下のものを0として扱います(rcond の既定値。NumPy 2.5 のマニュアル)。最小二乗法の公式・正規方程式・決定係数は、関連記事「最小二乗法とは|公式・手計算の例とPythonでの求め方を実例で解説」で扱っています。

逆行列のよくある間違い

この節では、逆行列の手計算とプログラムで起こりやすい間違いを、確かめる順に並べます。

  • 1先に行列式が0でないか確かめたかS = [[1,2],[2,4]] は det 0 で逆行列なし。NumPy は LinAlgError: Singular matrix
  • 2余因子を並べたあと転置したか余因子の行列は [[9,4,−3],…]、転置した adj A は [[9,−14,3],…]。転置を忘れると別の行列になる
  • 3余因子の符号 (−1)^(i+j) を付けたかC12 = (−1)³ × det[[1,3],[4,8]] = (−1) × (−4) = 4。符号は市松模様
  • 4(AB)⁻¹ を A⁻¹B⁻¹ にしていないか正しくは B⁻¹A⁻¹。NumPy で A⁻¹B⁻¹ との比較は False だった
  • 5A ** -1 や 1/A で逆行列を求めていないか成分ごとの逆数になる。逆行列は np.linalg.inv(A)
  • 6連立方程式に inv(A) @ b を使っていないかsolve の方が4〜5倍速く、悪条件でも誤差が小さい
  • 7エラーが出なければ正しい、と思っていないかヒルベルト12次は inv がエラーなしで誤差7.1の答えを返した。cond を見る
  • 8最後に A × A⁻¹ = I で検算したか手計算は1成分ずつ、プログラムは np.allclose(A @ Ai, np.eye(n))

逆行列は、行列とベクトルの基本の計算(内積・行列の積)の上に成り立っています。内積と外積の公式と計算例は、関連記事「内積・外積とは|公式と計算例・使い道をNumPyで実演」で扱っています。ベクトルを数値の並びとして扱う考え方は、関連記事「エンベディングとは?ベクトル検索とコサイン類似度を計算例で解説」で扱っています。行列の計算が中心になる別の手法として、相関行列の固有値分解を使う主成分分析は、関連記事「主成分分析(PCA)とは|手順・寄与率・負荷量の読み方をPythonで実演」で扱っています。

よくある質問

Q. 逆行列とは簡単に言うと何ですか? A. 掛けると単位行列 I になる行列で、「数の逆数」の行列版です。A × A⁻¹ = I で、A で移したベクトルを元に戻す働きをします。

Q. 逆行列の求め方で、いちばん簡単なのは? A. 2×2 なら公式 (1/(ad − bc)) × [[d, −b], [−c, a]] です。3×3 なら、分数を避けたいときは余因子行列、逆行列があるか分からないときや4×4 以上は掃き出し法が向いています。

Q. 逆行列が存在する条件は? A. 正方行列で、行列式が0でないことです。階数が n であること、A x = 0 の解が x = 0 だけであることなども同じ意味です。

Q. 逆行列が存在しないのはどんなときですか? A. 行列式が0のときと、正方でないときです。行列式が0になるのは、ある行(列)がほかの行(列)の組み合わせで書けるときで、S = [[1, 2], [2, 4]] は2行目が1行目の2倍です。

Q. 4×4 の逆行列はどう求めますか? A. 掃き出し法で、[A|I](4行8列)を同じ手順で掃き出します。例えば [[1,1,1,−1],[1,1,−1,1],[1,−1,1,1],[−1,1,1,1]] は行列式 −16 で、逆行列は元の行列を4で割ったものでした(SymPy で確認)。

Q. 逆行列の検算はどうしますか? A. A × A⁻¹ を計算して単位行列になるかを確かめます。Python なら np.allclose(A @ Ai, np.eye(n)) が True になるかを見ます。

Q. 転置行列の逆行列は? A. (Aᵀ)⁻¹ = (A⁻¹)ᵀ で、逆行列を転置したものと同じです。回転行列のように「逆行列 = 転置」になる行列は直交行列と呼びます。

Q. Python(NumPy)で逆行列を求めるには? A. np.linalg.inv(A) です。連立方程式を解くだけなら np.linalg.solve(A, b)、正方でない行列には np.linalg.pinv(A) を使います。分数で見たいときは SymPy の Matrix(A).inv() です。

Q. LinAlgError: Singular matrix と出たら? A. 行列式が0の特異行列で、逆行列がありません。np.linalg.matrix_rank(A) で階数を確かめ、データの重複(同じ列が2つある等)を見直します。解が欲しいときは np.linalg.lstsq か pinv を使います。

Q. 擬似逆行列とは何ですか? A. 正方でない行列や特異行列にも1つだけ決まる、逆行列の代わりの行列です。A⁺ b は最小二乗の解(解が無数なら長さが最小の解)になり、5点の直線の当てはめでは y = 0.9x + 1.3 が求まりました。

Q. クラメルの公式と逆行列の関係は? A. クラメルの公式は、逆行列 (1/det A) × adj A を使って x = A⁻¹ b の各成分を行列式の比で書いたものです。Wikipedia「逆行列」は、理論上は重要だが数値計算には向かないと書いています。

まとめ

  • 逆行列 A⁻¹ は、A A⁻¹ = A⁻¹ A = I(単位行列)になる行列。行列式が0でない正方行列(正則行列)にだけある。
  • 2×2 は公式 (1/(ad − bc)) × [[d, −b], [−c, a]]。[[2, 1], [4, 3]] の逆行列は [[3/2, −1/2], [−2, 1]]。
  • 3×3 は掃き出し法([A|I] → [I|A⁻¹]、例では7手)か、余因子9個を並べて転置し、行列式で割る。どちらも同じ答えになった。
  • 性質:(AB)⁻¹ = B⁻¹A⁻¹、(Aᵀ)⁻¹ = (A⁻¹)ᵀ、det(A⁻¹) = 1/det A。
  • 連立方程式は数式では x = A⁻¹ b だが、プログラムでは solve。4000次で inv の4.1倍速く、残差も小さかった。
  • 条件数が 10 の k 乗なら、正しい桁はおよそ 17 − k 桁(float64 の精度は約16桁)。inv はエラーを出さずに不正確な値を返すことがある。
  • 正方でない・特異な行列には擬似逆行列 pinv。答えは最小二乗の解で、正規方程式 (XᵀX)⁻¹Xᵀy と一致した。

参考・出典

確認日はいずれも 2026年10月22日です。

  • Wikipedia「逆行列」:https://ja.wikipedia.org/wiki/逆行列
  • Wikipedia「擬似逆行列」:https://ja.wikipedia.org/wiki/擬似逆行列
  • Wikipedia「条件数」:https://ja.wikipedia.org/wiki/条件数
  • Wikipedia (English)「Invertible matrix」:https://en.wikipedia.org/wiki/Invertible_matrix
  • Wikipedia (English)「Moore–Penrose inverse」:https://en.wikipedia.org/wiki/Moore%E2%80%93Penrose_inverse
  • NumPy「numpy.linalg.inv」:https://numpy.org/doc/stable/reference/generated/numpy.linalg.inv.html
  • NumPy「numpy.linalg.solve」:https://numpy.org/doc/stable/reference/generated/numpy.linalg.solve.html
  • NumPy「numpy.linalg.pinv」:https://numpy.org/doc/stable/reference/generated/numpy.linalg.pinv.html
  • SciPy「scipy.linalg.lu_factor」:https://docs.scipy.org/doc/scipy/reference/generated/scipy.linalg.lu_factor.html
  • SymPy「Matrices」:https://docs.sympy.org/latest/modules/matrices/matrices.html

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「逆行列とは|求め方(2×2公式・掃き出し法・余因子)をPythonで検算」

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?