当前位置:首页>python>Python-逻辑回归

Python-逻辑回归

  • 2026-09-02 19:18:18
Python-逻辑回归
软件:VS Code
目标:滑坡/灾害易发性预测
一、基本原理
逻辑回归(Logistic Regression)是一种经典的分类算法,核心思想:线性回归的输出范围是 (−∞,+∞),无法直接表示概率。逻辑回归的关键就是在线性回归的基础上,套一个Sigmoid函数,把输出压缩到(0,1)区间,从而表示属于某一类的概率。
给定输入特征X=(x1,x2,…,xn),逻辑回归的预测过程分两步:
1.线性方程:z=w1x1+w2x2+...+wnxn+b
2.Sigmoid映射:
其中w是权重向量,b是偏置项。最终根据σ(z)是否大于阈值(通常 0.5)来做分类决策。
二、算法步骤
第一阶段:训练阶段
迭代寻找最优w和b,这个阶段的目标是利用1000个样本共同计算出一套最准的参数
1. 初始化
归一化:将所有坡度值缩放到[0,1]之间
计算机先给参数随机赋个初值,比如:w=0.0;b=0.0
设置学习率α=0.1(迈步的大小)总迭代轮数Epochs=500
1个轮次:模型训练时,所有训练样本被计算完一次,500Epoch表示看了500遍全部训练样本
迭代次数:模型参数(w和b)每进行一次更新(迈出一步梯度下降),就记作一次迭代。如果是全量更新则轮次和迭代次数相同,如果采用小样本更新,就是用部分样本训练一次就更新w和b则不等,比如样本共1000个,每次用10个样本更新一次w和b则1轮次=100*1个迭代次数
2. 循环迭代计算
每一轮 (Epoch):每一轮都要把1000个样点全部跑一遍
       每次迭代:假设采用小批量梯度下降,每10个样点更新一次参数
     第一步:算线性得分z,计算当前10个点的预测值
             z=w⋅Slope+b
     第二步:算预测概率P(Sigmoid 函数),计算每个点的误差
                     P,此时因为 w,b都是0,P算出来是0.5
              第三步:计算损失
                     单个样本损失:
                     批次平均损失 (J):
                第四步:计算梯度
计算这10个点平均梯度
              第四步:更新全局参数
                      w=w−α⋅Δw
                      b=b−α⋅Δb
               第五步:结束
                      重复上述循环,直到所有样点的总损失(Loss)不再下  降,或者跑满了500轮。得到最优的w和b
第二阶段:预测阶段
利用得到的最佳w和b对全图的栅格单元进行预测,得到滑坡概率分布图
三、实现
import numpy as npimport pandas as pd#第一阶段:训练阶段#1. 从 CSV 读取数据df = pd.read_csv('逻辑回归.csv')#提取特征(X)和标签(y)X = df[['Slope', 'NDVI']].values  # 矩阵形式 [n_samples, 2]y = df['Landslide'].values.reshape(-1, 1)  # 变成列向量 [n_samples, 1]# 2. 数据归一化 (Min-Max) 得到每一列的最大值和最小值X_min = X.min(axis=0)X_max = X.max(axis=0)X_norm = (X - X_min) / (X_max - X_min)  #得到标准化后的值# 3. 参数初始化n_samples, n_features = X.shapew = np.zeros((n_features, 1))  # 唯一的全局权重[2, 1]b = 0                          # 唯一的全局偏置lr = 0.2                       # 学习率epochs = 500                   # 最大轮次Epochsdef sigmoid(z):    return 1 / (1 + np.exp(-z))print(f"开始训练,样本数: {n_samples}, 最大轮次: {epochs}...")# 迭代循环,这个每迭代一次用的是全量样本for i in range(epochs):    #A.前向传播:计算预测概率P    z = np.dot(X_norm, w) + b #一次性计算出所有样本的wi*xi    p = sigmoid(z)        #B.计算总损失Loss (交叉熵)     #这一步是为了监控模型是否在进步    loss = -np.mean(y * np.log(p + 1e-9) + (1 - y) * np.log(1 - p + 1e-9))        #C.计算梯度 (基于损失函数求导)     error = p - y    dw = np.dot(X_norm.T, error) / n_samples  # 汇总所有样本对w的改进    db = np.sum(error) / n_samples           # 汇总所有样本对b的改进       #D.参数更新 (朝着损失减小的方向迈步)    w = w - lr * dw    b = b - lr * db        #每200轮打印一次进度    if i % 200 == 0:        print(f"Epoch {i:4d} | Loss: {loss:.6f}")print("\n训练完成!")print(f"最终参数 w (权重): \n{w}")print(f"最终参数 b (截距): {b:.4f}")#第二阶段:预测阶段def predict_landslide(slope_val, ndvi_val):    """    输入原始特征值,输出滑坡概率    """    # 1. 对新样点进行同样的归一化    new_x = np.array([[slope_val, ndvi_val]])    new_x_norm = (new_x - X_min) / (X_max - X_min)    # 2. 代入学好的公式 (不再计算Loss和梯度)    z_pred = np.dot(new_x_norm, w) + b     prob = sigmoid(z_pred)[0][0]    return prob# 预测test_slope = 35.0test_ndvi = 0.3probability = predict_landslide(test_slope, test_ndvi)print("-" * 40)print(f"测试样点:坡度 {test_slope}°, NDVI {test_ndvi}")print(f"模型计算的滑坡概率: {probability:.4%}")print(f"最终分类判定: {'【滑坡危险】'if probability > 0.5else'【区域安全】'}")
四、效果

最新文章

随机文章