無料の Python 機械学習コース 5: 多クラス分類ロジスティック回帰

無料の Python 機械学習コース 5: 多クラス分類ロジスティック回帰

ロジスティック回帰の2つの方法:勾配降下法と最適化関数

ロジスティック回帰は非常に人気のある機械学習手法です。従属変数がカテゴリの場合、ロジスティック回帰を使用します。この記事では、多クラス分類問題に対するロジスティック回帰の実装に焦点を当てます。ロジスティック回帰を使用してバイナリ分類を実装する方法はすでにご存知だと思います。

バイナリ分類にロジスティック回帰をまだ使用したことがない場合は、この記事を読み進める前に、まずこの記事を読むことをお勧めします。

[[359675]]

マルチクラス分類はバイナリ分類に基づいて構築されるためです。

この記事では、バイナリ分類の概念、公式、実例を学びます。

多クラス分類

マルチクラス分類の実装は、バイナリ分類と同じ考え方に従います。ご存知のように、バイナリ分類では「はい」か「いいえ」の問題を解決します。上記の記事の例と同様に、出力は、人が心臓病を患っているかどうかという質問に答えます。カテゴリーは心臓病と心臓病なしの 2 つだけです。

出力が 1 の場合、その人は心臓病を患っており、出力が 0 の場合、その人は心臓病を患っていません。

多クラス分類では、2 つ以上のクラスがあります。ここに例があります。たとえば、入力特徴として、自動車、トラック、自転車、ボートのさまざまな特性とプロパティがあるとします。私たちの仕事は、ラベル(車、トラック、自転車、ボート)を予測することです。

どうすれば解決できるでしょうか?

各クラスを、心臓病の有無というバイナリ分類問題として扱います。

このアプローチは「1対多」アプローチと呼ばれます。

1 対すべての方法では、1 つのクラスを使用すると、そのクラスは 1 で表され、残りのクラスは 0 になります。

たとえば、車、トラック、バイク、ボートの 4 つのカテゴリがあるとします。車を扱うときは、車を 1 として使用し、残りのカテゴリを 0 として使用します。同様に、トラックを扱う場合、トラックの要素は 1 になり、残りのカテゴリは 0 になります。


実際に実装してみると、さらに理解しやすくなります。読みながらコーディングとコードの実行を続けることをお勧めします。

ここでは、このアルゴリズムを 2 つの異なる方法で実装します。

  • 勾配降下法。
  • 機能メソッドを最適化します。

重要な方程式とその仕組み:

ロジスティック回帰では、シグモイド関数を使用して出力を予測します。シグモイド関数は 0 から 1 までの値を返します。通常、0.5 などのしきい値を使用します。シグモイド関数によって返される値が 0.5 以上の場合は 1 とみなされ、シグモイド関数によって返される値が 0.5 未満の場合は 0 とみなされます。


z は、入力特徴と、theta として示されるランダムに初期化された値の積です。


X は入力特徴です。ほとんどの場合、入力関数は複数あります。したがって、この式は非常に大きくなります。


X1、X2、X3 は入力特徴であり、各入力特徴に対してシータがランダムに初期化されます。先頭の Theta0 はバイアス項です。

アルゴリズムの目的は、各反復でこのシータを更新して、入力機能と出力ラベル間の関係を確立できるようにすることです。

コスト関数と勾配降下法

コスト関数は、予測が元の出力からどの程度離れているかを示します。式は次のとおりです。


ここ:

  • mはトレーニング例またはトレーニングデータの数です。
  • yは元の出力ラベルです。
  • h は仮定または予測される出力です。

これは勾配降下法の方程式です。この式を使用して、各反復でシータ値を更新します。


勾配降下法の実装

前提条件:

  • Python コードの読み書きに慣れている必要があります。
  • 必須の Numpy および Pandas ライブラリ。

ここでは実装を段階的に説明します。

(1)必要なパッケージとデータセットをインポートします。私は、Coursera の Andrew Ng の機械学習コースからデータセットを取得しました。これは手書き認識データセットです。 1 から 10 までの数字。

ピクセルデータセットから数字を認識する必要があります。このデータセットでは、入力変数と出力変数が Excel ファイル内の異なるワークシートに整理されています。このページの最後にあるリンクからデータセットを自由にダウンロードしてください。

この記事を読んでいる場合は、各コード スニペットを実行してアルゴリズムを学習してください。

必要なパッケージとデータセットをインポートしましょう。

  1. pandasをpdとしてインポートする
  2. numpyをnpとしてインポートする
  3. xl = pd.ExcelFile ('ex3d1.xlsx')
  4. df = pd .read_excel(xl, 'X',ヘッダー=なし)

(2)出力変数yをインポートする

  1. y = pd .read_excel(xl, 'y',ヘッダー=なし)

(3)入力変数とθを使用して仮定を定義する。計算された出力変数を返します。

  1. def hypothesis(theta, X):
  2. 1 / (1 + np.exp(-(np.dot(theta, XT)))) - 0.0000001 を返す

(4)入力変数、出力変数、シータを用いてコスト関数を構築する。想定されるコストを返します。これは、予測が元の出力からどの程度離れているかについての情報を提供することを意味します。

  1. defコスト(X, y, theta):
  2. y1 =仮説(X, θ)
  3. -(1/len(X)) * np.sum(y*np.log(y1) + (1-y)*np.log(1-y1)) を返します。

(5)次に、データの前処理を行います。

データはクリーンです。前処理はほとんど必要ありません。入力変数にバイアス列を追加する必要があります。 dfとyの長さを確認してください。長さが異なると、モデルは機能しません。

  1. 印刷(長さ(df))
  2. 印刷(長さ(y))
  3.  
  4. X = pd .concat([pd.Series(1,インデックス= df .index,名前= '00' ), df],= 1 )

(6)y列の数字の範囲は1から10です。つまり、カテゴリは 10 個あることになります。

y は必要のない DataFrame です。列は値を含むシリーズとしてのみ保持します。

  1. y y = y.iloc[:, 0]

各クラスごとに y と同じ長さの列を作成します。クラスが 5 の場合、その行に 1 を含む列を作成し、それ以外の場合は 5 と 0 を含む列を作成します。

確認します。いくつかのクラスがあります。

  1. y.ユニーク()

出力:

  1. 配列([10, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype = int64 )

したがって、クラスは 10 個あります。 10列、df.shape[0]行数でDataFrameを開始します。

  1. y1 = np .zeros([df.shape[0], len(y.unique())])
  2. y1 = pd .DataFrame(y1)

これを簡単なコードでプログラム的に実行します。

  1. iが範囲(0, len(y.unique()))内にある場合:
  2. jが範囲(0, len(y1))内にある場合:
  3. y[j] == y.unique()[i]の場合:
  4. y1.iloc[j, i] = 1
  5. そうでない場合: y1.iloc[j, i] = 0
  6. y1.head()

(7)ここで関数「gradient_descent」を定義します。この関数は、入力変数、出力変数、シータ、アルファ、エポック数を引数として受け取ります。ここで、アルファは学習率です。

ニーズに応じて選択する必要があります。学習率が小さすぎたり大きすぎたりすると、アルゴリズムの速度が低下する可能性があります。さまざまな学習率でアルゴリズムを実行し、適切な学習率を取得するというアイデアが気に入っています。適切な学習率を選択するには、複数回の反復が必要になる場合があります。

y1 の各列に対して、バイナリ分類を実装します。

たとえば、数字 2 を考えると、数字 2 は 1 を返し、残りの数字は 0 を返す必要があります。したがって、クラスが 10 個あるため、各エポック (反復) は 10 回実行されます。つまり、ここにネストされた for ループがあります。

  1. 定義gradient_descent(X, y, theta, alpha, epochs):
  2. m =長さ(X)
  3. i が範囲(0, エポック)内である場合:
  4. jが範囲(0, 10)内にある場合:
  5. シータ= pd.DataFrame (シータ)
  6. h =仮説(theta.iloc[:,j], X)
  7. kが範囲(0, theta.shape[0])内にある場合:
  8. theta.iloc[k, j] - = (alpha/m) * np.sum((hy.iloc[:, j])*X.iloc[:, k])
  9. シータ= pd.DataFrame (シータ)
  10. リターンシータ、コスト

(8)θを初期化する。各クラスに対してロジスティック回帰を実装することを忘れないでください。各コースにはシータの範囲もあります。

1500エポック実行中です。時間の経過とともに精度が向上すると確信しています。

  1. シータ= np .zeros([df.shape[1]+1, y1.shape[1]])
  2. θ =勾配降下(X,y1,θ,0.02,1500)

(9)この更新されたシータを使用して出力変数を計算します。

  1. 出力= []
  2. iが範囲(0, 10)内にある場合:
  3. θ1 = pd.DataFrame (θ)
  4. h =仮説(theta1.iloc[:,i], X)
  5. 出力.append(h)
  6. 出力= pd .DataFrame(出力)

(10)計算された出力を元の出力変数と比較してモデルの精度を計算する。

  1. 精度= 0  
  2. 範囲(0, 10)内の列の場合:
  3. 範囲(len(y1))内の行の場合:
  4. y1.iloc[row, col] == 1 かつ output.iloc[col, row] > = 0.5 の場合:
  5. 精度 += 1
  6. 精度精度= 精度/長さ(X)

精度は72%です。精度はもっと高くなると思います。時間がかかりすぎるため、アルゴリズムを再実行しませんでした。

このプログラムを実行している場合は、ぜひさらに多くのエポックを試して、コメント セクションで正確さをお知らせください。

勾配降下法に加えて、すでに組み込まれている最適化関数を使用することもできます。

このアプローチでは、最適化関数を使用してアルゴリズムのシータを最適化します。これはより速い方法です。

最適化機能を備えた実装

(1)前回と同じデータセットを使用します。同じノートブックを使用する場合は、別の名前を使用してデータセットをインポートします。

  1. xls = pd.ExcelFile ('ex3d1.xlsx')
  2. df = pd .read_excel(xls, 'X',ヘッダー=なし)

(2)dfの偏差項にはすべて1の列を追加する必要がある。

  1. X = np .c_[np.ones((df.shape[0], 1)), df]

(3)「y」のデータをインポートする。

  1. y = pd .read_excel(xls, 'y',ヘッダー=なし)

これは DataFrame なので、列 0 をシリーズにして、次元を X の次元と一致させるために 2 次元にします。

  1. y y = y[0]
  2. y y = y[:, np.newaxis]

ここで、「y」には 1 つの列のみがあります。 10 クラスの場合は 10 列にします。各列は 1 つのクラスを処理します。たとえば、クラス 10 を処理する場合、10 の位置を保持し、残りの値をゼロに置き換えます。これは、y 自体とクラス (例: 3) を受け取る関数 y_change です。その後、他のすべてのクラスでは 1 が 3 に、0 が 0 に置き換えられます。この機能は、後の手順ですぐに使用されます。

  1. 定義 y_change(y, cl):
  2. y_pr = []
  3. iが範囲(0, len(y))内にある場合:
  4. y[i] == clの場合:
  5. y_pr.append(1)
  6. それ以外:
  7. y_pr.追加(0)
  8. y_prを返す

データの準備が完了しました。次にモデルを開発します。

(4)仮説関数を定義する。これは以前と同じ方法です。

  1. def hypothesis(X, theta):
  2. z = np .dot(X, シータ)
  3. 1/(1+np.exp(-(z))) を返す

(5)コスト関数を開発する。この方法も前の方法と同じです。

  1. コスト関数を定義します(theta, X, y):
  2. m = X .shape[0]
  3. y1 =仮説(X, θ)
  4. -(1/len(X)) * np.sum(y*np.log(y1) + (1-y)*np.log(1-y1)) を返します。

(6)勾配を定義する。これは違います。この関数は、theta を更新する方法を定義します。

  1. 定義勾配(theta, X, y):
  2. m = X .shape[0]
  3. y1 =仮説(X, θ)
  4. 戻り値 (1/m) * np.dot(XT, y1 - y)

(7)次に最適化関数をインポートし、thetaを初期化します。初期シータ値としてゼロを取りました。他の値でも同様に機能するはずです。

  1. scipy.optimize から、minimize、fmin_tnc をインポートします。
  2. シータ= np .zeros((X.shape[1], 1))

8. X、y、theta を入力として受け取る fit 関数を作成しましょう。最適化関数を使用して、最適化されたシータを出力します。

次の 3 つのパラメータを取ります。

  • 最小限に抑える必要がある機能
  • 最適化するパラメータは、
  • 最適化に使用されるパラメータ。

この例では、コスト関数を最小化する必要があり、そのためにはシータを最適化する必要があります。入力変数 X と出力変数 y は、使用されるパラメーターです。

この最適化関数は、勾配という別のパラメータを取ります。ただし、これはオプションです。ここでは、勾配の式または関数を示します。だから私たちはそれに取り組んでいます。

  1. def fit(X, y, θ):
  2. opt_weigths = fmin_tnc ( func = cost_function
  3. x0 = θ fprime =勾配
  4. 引数= (X, y.flatten()))
  5. opt_weigths[0]を返す

(9)このフィッティング法を使って最適化されたθを求めます。各クラスごとにシータを個別に最適化する必要があります。ステップ 3 の y_change メソッドを使用して、各クラスごとに 'y' がそれに応じて変更される関数を開発しましょう。

  1. def find_param(X, y, θ):
  2. y_uniq =リスト(set(y.flatten()))
  3. シータリスト= []
  4. i が y_uniq 内にある場合:
  5. y_tr = pd.Series (y_change(y, i))
  6. y_tr y_tr = y_tr[:, np.newaxis]
  7. theta1 = (X, y, theta)に適合
  8. theta_list.append(theta1)
  9. theta_listを返す

この方法を使用して最終シータを見つけます

  1. theta_list = find_param (X, y, theta)

(10)今度は出力を予測します。クラスも個別に予測する必要があります。

  1. def predict(theta_list, x, y):
  2. y_uniq =リスト(set(y.flatten()))
  3. y_hat = [0]*len(y)
  4. iが範囲(0, len(y_uniq))内にある場合:
  5. y_tr = y_change (y、y_uniq[i]) です。
  6. y1 =仮説(X, theta_list[i])
  7. kが範囲(0, len(y))内にある場合:
  8. y_tr[k] == 1かつy1[k] > = 0.5の場合:
  9. y_hat[k] = y_uniq[i]
  10. y_hatを返す

上記の予測方法を使用して、予測出力 y_hat を計算します。

  1. y_hat =予測(theta_list, X, y)

(11)計算精度

  1. 精度= 0  
  2. iが範囲(0, len(y))内にある場合:
  3. y_hat[i] == y.flatten()[i]の場合:
  4. 精度 += 1print(精度/長さ(df)*100)

このプロセスにより 100% の精度が実現します。今。プロジェクトでどのロジスティック回帰法を使用するかは、あなた次第です。

この論文でもニューラルネットワークを使用して同じ問題を解決しています。

データセットを取得するには、この GitHub ページを確認してください。

https://github.com/rashida048/Machine-Learning-With-Python/blob/master/ex3d1.xlsx

<<:  2021 年の機械学習の今後はどうなるのでしょうか?

>>:  Googleの上級研究員が解雇される:論文論争の裏側

ブログ    
ブログ    

推薦する

AIがサプライチェーンを変革する7つの方法

ビジネスにおける AI の役割は拡大し続けています。これは、サプライ チェーンとビジネス プロセスの...

不動産テクノロジーの6つのトレンド: テクノロジーが不動産業界に破壊的変化をもたらす

[[315285]]現代の技術進歩の影響を免れる業界はありませんが、不動産業界はこの点では孤立した業...

...

...

AIトレーニングの最大の障害は計算能力ではなく「メモリの壁」である

[[390958]]この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI...

ChatGPT Enterprise Editionがリリースされ、OpenAIはこれをこれまでで最も強力なバージョンと呼んでいる

執筆者:Qianshan過去 1 か月間、OpenAI に関する物議を醸す報道が多くありました。一方...

...

OpenCV を使用した画像の二値化とグレースケール変換

関連概念バイナリ画像とは、2 つの色 (通常は黒と白) のみを含む画像です。バイナリ画像では、各ピク...

...

...

データベース列ストレージ: 最適な圧縮アルゴリズムを設計するための近道

データベースの保存方法によって、データベース操作の効率が決まります。51CTO データベース チャネ...

アクチュエータ研究の進歩により、0.1mm未満のロボットが誕生しました。

英国の雑誌「ネイチャー」は26日、ロボット工学の最新成果を発表した。ロボットを動かすための重要な部品...

...

機械学習のケーススタディ: クレジットカード詐欺検出

私は51CTOアカデミー講師の唐玉迪です。51CTOアカデミーの「4.20 ITリチャージフェスティ...