技術共有

機械学習 (5) -- 教師あり学習 (6) -- ロジスティック回帰

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

目次と一連の記事へのリンク

前の記事:機械学習 (5) -- 教師あり学習 (5) -- 線形回帰 2
次の記事:機械学習 (5) -- 教師あり学習 (7) -- SVM1


序文

tips:标题前有“***”的内容为补充内容,是给好奇心重的宝宝看的,可自行跳过。文章内容被“文章内容”删除线标记的,也可以自行跳过。“!!!”一般需要特别注意或者容易出错的地方。

本系列文章是作者边学习边总结的,内容有不对的地方还请多多指正,同时本系列文章会不断完善,每篇文章不定时会有修改。

由于作者时间不算富裕,有些内容的《算法实现》部分暂未完善,以后有时间再来补充。见谅!

文中为方便理解,会将接口在用到的时候才导入,实际中应在文件开始统一导入。


1. 一般的な理解と定義

1. ロジスティック回帰とは (What)

ロジスティック回帰 = 線形回帰 + シグモイド関数

ロジスティック回帰(ロジスティック回帰)とは、単純にバイナリデータを分割する直線を見つけることです。

2. ロジスティック回帰の目的 (Why)

特定のカテゴリに属する​​オブジェクトを分類することによって二項分類問題を解決します確率値特定のカテゴリに属する​​かどうかを判断するために、このカテゴリはデフォルトで 1 (肯定的な例) としてマークされ、他のカテゴリは 0 (否定的な例) としてマークされます。

3. この行を見つける方法 (方法)

実際、これは線形回帰ステップと似ていますが、違いは「モデルのフィッティング効果の確認」と「モデルの位置角度の調整」に使用される方法にあります。

  1. 最初の直線としてランダムに直線を描きます
  2. フィッティング効果を確認し、
  3. 最適でない場合(しきい値に達している場合)、ラインの位置と角度を調整します
  4. 最良の効果 (設定されたしきい値に達する) が得られるまでステップ 2 と 3 を繰り返し、最終的に目的のモデルが得られます。

入力データを0~1にマッピングする関数(シグモイド関数)を使用する必要があり、関数の値が0.5より大きい場合は1、それ以外の場合は0と判定されます。これは確率表現に変換できます。

2. 原理理解と公式

1.パーセプトロン

1.1. 問題の説明

写真の分類を例に挙げると、写真を縦方向と横方向に分割します。

このデータをグラフ上に表示する方法は、グラフ内の異なる色の点 (異なるカテゴリ) を分離するために、このような線を描きます。この分類の目的は、そのような線を見つけることです。

これは「重みベクトルを法線ベクトルにする直線」です(重みベクトルをその線に垂直にする)

w は重みベクトルであり、法線ベクトルの直線になります。

1.2. パーセプトロンモデル

複数の値を受け入れ、各値にそれぞれの重みを乗算し、最終的に合計を出力するモデル。

1.3. 判別関数

内積はベクトル間の類似度の尺度であり、正の結果は類似性を示し、値 0 は垂直性を示し、負の結果は非類似性を示します。

使用|w| と |x| は両方とも正の数なので、内積の符号は cosθ によって決まります。つまり、90 度未満の場合は同様になります。 90度を超えると、それは似ていない、つまり

1.4. パラメータ推定(重み更新式)

元のラベル値と等しい場合、重みベクトルは更新されません。元のラベル値と等しくない場合、重みベクトルの更新にベクトル加算が使用されます。

図に示すように、元のラベルと等しくない場合は、

アップデート後は直線

アップデート後は同等

手順:まず直線をランダムに決定し(つまり重みベクトルwをランダムに決定)、内積に実数値データxを代入し、等しい場合に判別関数で値(1または-1)を取得します。元のラベル値に戻すと、重みベクトルは更新されません。元のラベル値と異なる場合は、ベクトル加算を使用して重みベクトルを更新します。

! ! !注: パーセプトロンは線形分離可能な問題のみを解決できます。
線形分離可能:直線で分類できる場合
線形不可分性: 直線で分類できない

2. シグモイド関数

黒はシグモイド関数、赤はステップ関数(不連続)

機能: ロジスティック回帰の入力は線形回帰の結果です。シグモイド関数は、線形回帰で予測値を取得できます。これにより、分類タスクである値から確率への変換が完了します。

3. ロジスティック回帰

3.1. モデルの定義

ロジスティック回帰 = 線形回帰 + シグモイド関数

線形回帰:

シグモイド関数:

ロジスティック回帰:

y がラベルを表すようにするには、次のように変更します。

確率を計算するには、以下を使用します。

3.2. 判別関数

つまり、カテゴリは確率によって区別できます。

3.3. 決定境界

これは次のように書き換えることができます。

いつ

代替データ:

こんな絵もあるよ

データ分類に使用される直線が決定境界です

3.4. 目的関数(対数尤度関数)

私たちが望んでいるのはこれです:
y=1 の場合、P(y=1|x) が最大になります
y=0 の場合、P(y=0|x) が最大になります

尤度関数 (同時確率): 最大化したい確率は次のとおりです。

対数尤度関数: 尤度関数を直接微分することは困難です。最初に対数を取る必要があります。

変形後は次のようになります。

3.4. パラメータ推定 (勾配降下法)

尤度関数の微分:

3. メリットとデメリット

3.1. 利点:

1. 実装が簡単: ロジスティック回帰は、理解と実装が簡単なシンプルなアルゴリズムです。
2. 高い計算効率: ロジスティック回帰は比較的少量の計算を必要とし、大規模なデータセットに適しています。
3. 強い解釈可能性: ロジスティック回帰の出力結果は確率値であり、モデルの出力を直感的に説明できます。

3.2. 欠点:

1. 線形分離可能性の要件: ロジスティック回帰は線形モデルであり、非線形分離可能問題に対してはあまり効果がありません。
2. 特徴相関問題: ロジスティック回帰は、入力特徴間の相関の影響をより受けやすく、特徴間に強い相関がある場合、モデルのパフォーマンスが低下する可能性があります。
3. 過学習問題: サンプルの特徴が多すぎる場合、またはサンプルの数が少ない場合、ロジスティック回帰では過学習の問題が発生する傾向があります。

3. ** アルゴリズムの実装

1. データを取得する

  1. import numpy as np
  2. import pandas as pd
  3. import matplotlib.pyplot as plt
  4. %matplotlib notebook
  5. # 读取数据
  6. train=pd.read_csv('csv/images2.csv')
  7. train_x=train.iloc[:,0:2]
  8. train_y=train.iloc[:,2]
  9. # print(train_x)
  10. # print(train_y)
  11. # 绘图
  12. plt.figure()
  13. plt.plot(train_x[train_y ==1].iloc[:,0],train_x[train_y ==1].iloc[:,1],'o')
  14. plt.plot(train_x[train_y == 0].iloc[:,0],train_x[train_y == 0].iloc[:,1],'x')
  15. plt.axis('scaled')
  16. # plt.axis([0,500,0,500])
  17. plt.show()

2. データ処理

  1. # 初始化参数
  2. theta=np.random.randn(3)
  3. # 标准化
  4. mu = train_x.mean(axis=0)
  5. sigma = train_x.std(axis=0)
  6. # print(mu,sigma)
  7. def standardize(x):
  8. return (x - mu) / sigma
  9. train_z = standardize(train_x)
  10. # print(train_z)
  11. # 增加 x0
  12. def to_matrix(x):
  13. x0 = np.ones([x.shape[0], 1])
  14. return np.hstack([x0, x])
  15. X = to_matrix(train_z)
  16. # 绘图
  17. plt.figure()
  18. plt.plot(train_z[train_y ==1].iloc[:,0],train_z[train_y ==1].iloc[:,1],'o')
  19. plt.plot(train_z[train_y == 0].iloc[:,0],train_z[train_y == 0].iloc[:,1],'x')
  20. plt.axis('scaled')
  21. # plt.axis([0,500,0,500])
  22. plt.show()

3.シグモイド関数と判別関数

  1. # sigmoid 函数
  2. def f(x):
  3. return 1 / (1 + np.exp(-np.dot(x, theta)))
  4. # 分类函数
  5. def classify(x):
  6. return (f(x) >= 0.5).astype(np.int)

4. パラメータ設定とトレーニング

  1. # 学习率
  2. ETA = 1e-3
  3. # 重复次数
  4. epoch = 5000
  5. # 更新次数
  6. count = 0
  7. print(f(X))
  8. # 重复学习
  9. for _ in range(epoch):
  10. theta = theta - ETA * np.dot(f(X) - train_y, X)
  11. # 日志输出
  12. count += 1
  13. print('第 {} 次 : theta = {}'.format(count, theta))

5. 図面確認

  1. # 绘图确认
  2. plt.figure()
  3. x0 = np.linspace(-2, 2, 100)
  4. plt.plot(train_z[train_y ==1].iloc[:,0],train_z[train_y ==1].iloc[:,1],'o')
  5. plt.plot(train_z[train_y == 0].iloc[:,0],train_z[train_y == 0].iloc[:,1],'x')
  6. plt.plot(x0, -(theta[0] + theta[1] * x0) / theta[2], linestyle='dashed')
  7. plt.show()

 

6.検証

  1. # 验证
  2. text=[[200,100],[500,400],[150,170]]
  3. tt=pd.DataFrame(text,columns=['x1','x2'])
  4. # text=pd.DataFrame({'x1':[200,400,150],'x2':[100,50,170]})
  5. x=to_matrix(standardize(tt))
  6. print(x)
  7. a=f(x)
  8. print(a)
  9. b=classify(x)
  10. print(b)
  11. plt.plot(x[:,1],x[:,2],'ro')

 

4. インターフェースの実装

1. 乳がんデータセットの概要

1.1、API

from sklearn.datasets import load_breast_cancer

1.2. 基本情報

  1. # 键
  2. print("乳腺癌数据集的键:",breast_cancer.keys())
  3. # 特征值名字、目标值名字
  4. print("乳腺癌数据集的特征数据形状:",breast_cancer.data.shape)
  5. print("乳腺癌数据集的目标数据形状:",breast_cancer.target.shape)
  6. print("乳腺癌数据集的特征值名字:",breast_cancer.feature_names)
  7. print("乳腺癌数据集的目标值名字:",breast_cancer.target_names)
  8. # print("乳腺癌数据集的特征值:",breast_cancer.data)
  9. # print("乳腺癌数据集的目标值:",breast_cancer.target)
  10. # 返回值
  11. # print("乳腺癌数据集的返回值:n", breast_cancer)
  12. # 返回值类型是bunch--是一个字典类型
  13. # 描述
  14. # print("乳腺癌数据集的描述:",breast_cancer.DESCR)
  15. # 每个特征信息
  16. print("最小值:",breast_cancer.data.min(axis=0))
  17. print("最大值:",breast_cancer.data.max(axis=0))
  18. print("平均值:",breast_cancer.data.mean(axis=0))
  19. print("标准差:",breast_cancer.data.std(axis=0))

  1. # 取其中间两列特征
  2. x=breast_cancer.data[0:569,0:2]
  3. y=breast_cancer.target[0:569]
  4. samples_0 = x[y==0, :]
  5. samples_1 = x[y==1, :]
  6. # 实现可视化
  7. plt.figure()
  8. plt.scatter(samples_0[:,0],samples_0[:,1],marker='o',color='r')
  9. plt.scatter(samples_1[:,0],samples_1[:,1],marker='x',color='y')
  10. plt.xlabel('mean radius')
  11. plt.ylabel('mean texture')
  12. plt.show()

  1. # 绘制每个特征直方图,显示特征值的分布情况。
  2. for i, feature_name in enumerate(breast_cancer.feature_names):
  3. plt.figure(figsize=(6, 4))
  4. sns.histplot(breast_cancer.data[:, i], kde=True)
  5. plt.xlabel(feature_name)
  6. plt.ylabel("数量")
  7. plt.title("{}直方图".format(feature_name))
  8. plt.show()

  1. # 绘制箱线图,展示每个特征最小值、第一四分位数、中位数、第三四分位数和最大值概括。
  2. plt.figure(figsize=(10, 6))
  3. sns.boxplot(data=breast_cancer.data, orient="v")
  4. plt.xticks(range(len(breast_cancer.feature_names)), breast_cancer.feature_names, rotation=90)
  5. plt.xlabel("特征")
  6. plt.ylabel("值")
  7. plt.title("特征箱线图")
  8. plt.show()

1.3. 欠損値と外れ値

  1. # 创建DataFrame对象
  2. df = pd.DataFrame(breast_cancer.data, columns=breast_cancer.feature_names)
  3. # 检测缺失值
  4. print("缺失值数量:")
  5. print(df.isnull().sum())
  6. # 检测异常值
  7. print("异常值统计信息:")
  8. print(df.describe())
  9. # 使用.describe()方法获取数据集的统计信息,包括计数、均值、标准差、最小值、25%分位数、中位数、75%分位数和最大值。

1.4. 関連性

  1. # 创建DataFrame对象
  2. df = pd.DataFrame(breast_cancer.data, columns=breast_cancer.feature_names)
  3. # 计算相关系数
  4. correlation_matrix = df.corr()
  5. # 可视化相关系数热力图
  6. plt.figure(figsize=(10, 8))
  7. sns.heatmap(correlation_matrix, annot=True, cmap="coolwarm")
  8. plt.title("Correlation Heatmap")
  9. plt.show()

2、API

  1. sklearn.linear_model.LogisticRegression
  2. 导入:
  3. from sklearn.linear_model import LogisticRegression
  4. 语法:
  5. LogisticRegression(solver='liblinear', penalty=‘l2’, C = 1.0)
  6. solver可选参数:{'liblinear', 'sag', 'saga','newton-cg', 'lbfgs'},
  7. 默认: 'liblinear';用于优化问题的算法。
  8. 对于小数据集来说,“liblinear”是个不错的选择,而“sag”和'saga'对于大型数据集会更快。
  9. 对于多类问题,只有'newton-cg''sag''saga''lbfgs'可以处理多项损失;“liblinear”仅限于“one-versus-rest”分类。
  10. penalty:正则化的种类
  11. C:正则化力度

2. プロセス

2.1. データの取得

  1. from sklearn.datasets import load_breast_cancer
  2. from sklearn.model_selection import train_test_split
  3. from sklearn.linear_model import LogisticRegression
  4. # 获取数据
  5. breast_cancer = load_breast_cancer()

2.2. データの前処理

  1. # 划分数据集
  2. x_train,x_test,y_train,y_test = train_test_split(breast_cancer.data, breast_cancer.target, test_size=0.2, random_state=1473)

2.3. 特徴量エンジニアリング

2.4. モデルのトレーニング

  1. # 实例化学习器
  2. lr = LogisticRegression(max_iter=10000)
  3. # 模型训练
  4. lr.fit(x_train, y_train)
  5. print("建立的逻辑回归模型为:n", lr)

 

2.5. モデルの評価

  1. # 用模型计算测试值,得到预测值
  2. y_pred = lr.predict(x_test)
  3. print('预测前20个结果为:n', y_pred[:20])
  4. # 求出预测结果的准确率和混淆矩阵
  5. from sklearn.metrics import accuracy_score, confusion_matrix,precision_score,recall_score
  6. print("预测结果准确率为:", accuracy_score(y_test, y_pred))
  7. print("预测结果混淆矩阵为:n", confusion_matrix(y_test, y_pred))
  8. print("预测结果查准率为:", precision_score(y_test, y_pred))
  9. print("预测结果召回率为:", recall_score(y_test, y_pred))

  1. from sklearn.metrics import roc_curve,roc_auc_score,auc
  2. fpr,tpr,thresholds=roc_curve(y_test,y_pred)
  3. plt.plot(fpr, tpr)
  4. plt.axis("square")
  5. plt.xlabel("假正例率/False positive rate")
  6. plt.ylabel("正正例率/True positive rate")
  7. plt.title("ROC curve")
  8. plt.show()
  9. print("AUC指标为:",roc_auc_score(y_test,y_pred))

 

  1. # 求出预测取值和真实取值一致的数目
  2. num_accu = np.sum(y_test == y_pred)
  3. print('预测对的结果数目为:', num_accu)
  4. print('预测错的结果数目为:', y_test.shape[0]-num_accu)
  5. print('预测结果准确率为:', num_accu/y_test.shape[0])

2.6. 結果の予測

モデル評価後に渡されたモデルを実際の値に代入して予測することができます。


昔の夢を追体験することができます。見てみましょう:機械学習 (5) -- 教師あり学習 (5) -- 線形回帰 2
次に何が起こるかを知りたい場合は、見てみましょう。機械学習 (5) -- 教師あり学習 (7) -- SVM1