기술나눔

기계 학습(5) -- 지도 학습(6) -- 로지스틱 회귀

2024-07-12

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

목차 및 기사 시리즈 링크

이전 기사:기계 학습(5) -- 지도 학습(5) -- 선형 회귀 2
다음 기사:기계 학습(5) -- 지도 학습(7) --SVM1


머리말

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

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

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

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


1. 대중적인 이해와 정의

1. 로지스틱 회귀란(What)

로지스틱 회귀 = 선형 회귀 + 시그모이드 함수

로지스틱 회귀(Logistic Regression)는 단순히 이진 데이터를 나누기 위해 직선을 찾는 것입니다.

2. 로지스틱 회귀의 목적(왜)

특정 카테고리에 속하는 객체를 분류하여 이진 분류 문제를 해결합니다.확률값특정 카테고리에 속하는지 판단하기 위해 기본적으로 이 카테고리는 1(긍정 예시)로 표시되고, 다른 카테고리는 0(부정 예시)으로 표시됩니다.

3. 이 줄을 찾는 방법(How)

실제로 이는 "모델 피팅 효과 확인"과 "모델 위치 각도 조정"에 사용되는 방법에 차이가 있는 선형 회귀 단계와 유사합니다.

  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. 시그모이드 함수

검은색은 시그모이드 함수, 빨간색은 계단 함수(불연속)

기능: 로지스틱 회귀의 입력은 선형 회귀의 결과입니다.선형 회귀에서 예측 값을 얻을 수 있습니다. Sigmoid 함수는 모든 입력을 [0,1] 간격으로 매핑하여 분류 작업인 값에서 확률로의 변환을 완료합니다.

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