目录
1、逻辑回归(Logistic Regression)—— 最简单的分类 “基准线”
1.1、通俗理解
1.2、核心原理
1.3、关键公式解析
1.4、实战技巧
1.5、案列
1.5.1、完整代码
1.5.2、实验结果
2、决策树(Decision Tree)—— 像 “问路” 一样做判断
2.1、通俗理解
2.2、核心原理
2.3、关键公式解析
2.4、实战技巧
2.5、案例
2.5.1、完整代码
2.5.2、实验结果
3、随机森林(Random Forest)——“众人拾柴火焰高”
3.1、通俗理解
3.2、核心原理
3.3、关键优势
3.4、实战技巧
3.5、示例
3.5.1、完整代码
3.5.2、实验结果
4、支持向量机(SVM)—— 找 “最宽的分隔带”
4.1、通俗理解
4.2、核心原理
4.3、关键公式解析
4.4、实战技巧
4.5、示例
4.5.1、完整代码
4.5.2、实验结果
5、K 近邻(KNN)——“跟着邻居学样”
5.1、通俗理解
5.2、核心原理
5.3、关键参数
5.4、实战技巧
5.5、示例
5.5.1、完整代码
5.5.2、实验结果
下文:
区别:十大算法全景对比表(新增维度)
总结:如何选对算法?
分类算法是机器学习中最核心的技术之一,它能让计算机从已知数据中学习规律,对新数据的类别做出判断。本文将用通俗的语言拆解十大分类算法,帮你真正吃透每种算法的本质。
1、逻辑回归(Logistic Regression)—— 最简单的分类 “基准线”
1.1、通俗理解
逻辑回归就像一个 “概率计算器”,它先通过线性公式算出一个 “分数”,再把这个分数转换成 0-1 之间的概率(比如 “用户点击广告的概率是 80%”),最后用 0.5 作为阈值判断类别(>0.5 为 “会点击”,否则为 “不会”)。
1.2、核心原理
线性得分:先用线性模型计算样本的得分(w是权重,x是特征,b是偏置)。
概率转换:通过 Sigmoid 函数把得分z压缩到 [0,1],得到属于正类的概率:(当z=0时,;z越大,概率越接近 1;z越小,越接近 0)
分类判断:若,预测为正类(1);否则为负类(0)。
1.3、关键公式解析
Sigmoid 函数的魔力:它能把无限范围的z“挤” 进 0-1,正好对应概率的取值范围。
损失函数(交叉熵损失):用来衡量预测概率与真实标签的差距,公式为: (y是真实标签 0/1,是预测概率)
1.4、实战技巧
必须做特征缩放(如标准化),否则权重会受特征单位影响(比如 “身高” 以米为单位和以厘米为单位,权重差异很大)。
对不平衡数据,可调整阈值(比如少数类重要时,用 0.3 作为阈值提高召回率)。
1.5、案列
用逻辑回归预测 “贷款违约”:特征包括收入、负债、信用分,模型算出某用户违约概率 0.7,超过 0.5,预测为 “会违约”。
1.5.1、完整代码
"""
文件名: Loan_Default_Prediction
作者: 墨尘
日期: 2025/7/28
项目名: llm_finetune
备注: 本代码使用逻辑回归模型预测贷款违约,特征包括收入、负债、信用分
"""
# 导入必要的库
import numpy as np # 用于数值计算和数组操作
import matplotlib.pyplot as plt # 用于数据可视化
import pandas as pd # 用于数据处理
from sklearn.datasets import make_classification # 用于生成虚拟分类数据集
from sklearn.linear_model import LogisticRegression # 导入逻辑回归模型
from sklearn.model_selection import train_test_split, cross_val_score, learning_curve # 数据分割、交叉验证、学习曲线工具
from sklearn.metrics import confusion_matrix, roc_curve, auc, accuracy_score, precision_score, recall_score, f1_score # 模型评估指标
from sklearn.preprocessing import StandardScaler # 特征标准化(贷款数据通常需要标准化)
# 设置中文显示,避免可视化时中文乱码
plt.rcParams["font.family"] = ["SimHei"] # 指定中文字体
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示为方块的问题
if __name__ == '__main__': # 主程序入口
# 生成贷款违约相关的虚拟数据集(3个特征:收入、负债、信用分)
# 生成基础数据(1000个样本,3个特征,二分类)
X, y = make_classification(
n_samples=1000, # 样本数量:1000个贷款申请人
n_features=3, # 特征数量:3个(收入、负债、信用分)
n_classes=2, # 类别:0=不违约,1=违约
n_informative=3, # 3个特征均对违约有影响
n_redundant=0, # 无冗余特征
random_state=42 # 随机种子,保证结果可复现
)
# 将特征转换为实际业务含义(调整数值范围使其符合现实意义)
# 收入:缩放为3-15万元/年
X[:, 0] = X[:, 0] * 2 + 9 # 均值9,范围约3-15
# 负债:缩放为0-5万元
X[:, 1] = (X[:, 1] + 2) * 1.25 # 范围约0-5
# 信用分:缩放为300-850分(常见信用分范围)
X[:, 2] = (X[:, 2] + 2) * 137.5 + 300 # 范围300-850
# 转换为DataFrame便于处理
df = pd.DataFrame(X, columns=['收入(万元/年)', '负债(万元)', '信用分'])
df['是否违约'] = y
X = df[['收入(万元/年)', '负债(万元)', '信用分']].values # 特征矩阵
y = df['是否违约'].values # 标签(0=不违约,1=违约)
# 数据探索性分析(EDA):了解贷款数据分布
plt.figure(figsize=(15, 5)) # 创建画布
# 子图1:三个特征的分布(箱线图)
plt.subplot(1, 2, 1)
plt.boxplot(X)
plt.title('贷款申请人特征分布')
plt.xticks(range(1, X.shape[1] + 1), ['收入(万元/年)', '负债(万元)', '信用分'])
plt.ylabel('数值')
# 子图2:违约与不违约的样本数量
plt.subplot(1, 2, 2)
# 修正变量名,使用英文或拼音避免中文变量名
default_count = len(y[y == 1]) # 违约数量(标签为1的样本数)
non_default_count = len(y[y == 0]) # 不违约数量(标签为0的样本数)
plt.bar(['不违约', '违约'], [non_default_count, default_count], color=['green', 'red'])
plt.title('贷款违约情况分布')
plt.ylabel('申请人数量')
# 在柱状图上标注具体数量
plt.text(0, non_default_count + 10, f'{non_default_count}人', ha='center')
plt.text(1, default_count + 10, f'{default_count}人', ha='center')
plt.tight_layout() # 自动调整布局
plt.savefig('贷款数据探索.png') # 保存图片
plt.close() # 关闭画布
# 数据预处理:特征标准化(逻辑回归对特征尺度敏感,标准化后性能更稳定)
scaler = StandardScaler() # 初始化标准化器
X_scaled = scaler.fit_transform(X) # 对特征进行标准化(均值为0,标准差为1)
# 数据集分割:70%训练,30%测试
X_train, X_test, y_train, y_test = train_test_split(
X_scaled, y,
test_size=0.3, # 测试集占30%
random_state=42 # 随机种子,保证分割结果可复现
)
# 创建并训练逻辑回归模型(贷款违约预测模型)
# class_weight='balanced':自动平衡类别权重,应对可能的样本不平衡问题
model = LogisticRegression(class_weight='balanced')
model.fit(X_train, y_train) # 用训练数据训练模型,学习特征与违约的关系
# 模型预测
y_pred = model.predict(X_test) # 预测类别:0=不违约,1=违约
y_prob = model.predict_proba(X_test)[:, 1] # 预测为违约的概率(0-1之间)
# 计算评估指标(针对贷款违约场景的业务指标)
accuracy = accuracy_score(y_test, y_pred) # 准确率:整体预测正确的比例
precision = precision_score(y_test, y_pred) # 精确率:预测为违约的客户中实际违约的比例(降低误拒优质客户的风险)
recall = recall_score(y_test, y_pred) # 召回率:实际违约客户中被正确识别的比例(降低坏账风险)
f1 = f1_score(y_test, y_pred) # F1分数:综合精确率和召回率的指标
# 打印评估结果(结合业务解读)
print(f"贷款违约预测模型评估:")
print(f"准确率: {accuracy:.4f} (整体预测正确的比例)")
print(f"精确率: {precision:.4f} (预测为违约的客户中,实际违约的比例)")
print(f"召回率: {recall:.4f} (实际违约的客户中,被正确识别的比例)")
print(f"F1分数: {f1:.4f} (综合精确率和召回率的指标)")
# 10折交叉验证(评估模型稳定性,减少数据分割带来的随机性影响)
cv_scores = cross_val_score(
LogisticRegression(class_weight='balanced'), # 待验证的模型
X_scaled, y, # 整个数据集
cv=10, # 10折交叉验证
scoring='accuracy' # 评估指标为准确率
)
# 输出交叉验证结果:均值±标准差(反映模型的平均性能和稳定性)
print(f"交叉验证准确率: {np.mean(cv_scores):.4f} ± {np.std(cv_scores):.4f}")
# 可视化评估结果(针对贷款场景调整标签,更贴合业务理解)
plt.figure(figsize=(16, 12)) # 创建大画布
# 子图1:特征重要性(展示收入、负债、信用分对违约的影响程度)
plt.subplot(2, 2, 1)
coef = model.coef_[0] # 模型系数(系数越大,该特征对违约的影响越显著)
# 正值表示该特征越高,违约概率越大;负值表示该特征越高,违约概率越小
plt.bar(['收入', '负债', '信用分'], coef, color=['blue', 'orange', 'green'])
plt.title('特征对贷款违约的影响')
plt.ylabel('系数值(正值促进违约,负值抑制违约)')
plt.axhline(y=0, color='r', linestyle='-') # 绘制y=0参考线
# 在柱状图上标注系数值
for i, v in enumerate(coef):
plt.text(i, v + 0.05, f'{v:.2f}', ha='center')
# 子图2:混淆矩阵(详细展示预测结果的分布)
plt.subplot(2, 2, 2)
cm = confusion_matrix(y_test, y_pred) # 计算混淆矩阵
# 混淆矩阵含义:
# cm[0,0]:实际不违约且预测不违约(正确)
# cm[0,1]:实际不违约但预测违约(误判,可能错失优质客户)
# cm[1,0]:实际违约但预测不违约(漏判,可能产生坏账)
# cm[1,1]:实际违约且预测违约(正确)
plt.imshow(cm, interpolation='nearest', cmap=plt.cm.Greens) # 绘制热力图
plt.title('贷款违约预测混淆矩阵')
plt.colorbar() # 颜色条,指示数值与颜色的对应关系
plt.xticks([0, 1], ['预测不违约', '预测违约'], rotation=45)
plt.yticks([0, 1], ['实际不违约', '实际违约'])
plt.ylabel('实际情况')
plt.xlabel('预测结果')
# 在混淆矩阵上标注具体数值
thresh = cm.max() / 2 # 阈值,用于区分文字颜色(确保清晰可见)
for i, j in np.ndindex(cm.shape):
plt.text(j, i, format(cm[i, j], 'd'),
ha="center", va="center",
color="white" if cm[i, j] > thresh else "black")
# 子图3:ROC曲线(评估模型区分违约与不违约的能力)
plt.subplot(2, 2, 3)
fpr, tpr, _ = roc_curve(y_test, y_prob) # 计算假阳性率和真阳性率
roc_auc = auc(fpr, tpr) # 计算AUC值(ROC曲线下面积,越大模型性能越好)
plt.plot(fpr, tpr, color='darkorange', lw=2,
label=f'ROC曲线 (面积 = {roc_auc:.2f})')
plt.plot([0, 1], [0, 1], color='red', lw=2, linestyle='--') # 随机猜测的基准线(AUC=0.5)
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('假阳性率 (错误预测为违约的比例)')
plt.ylabel('真阳性率 (正确预测为违约的比例)')
plt.title('贷款违约预测ROC曲线')
plt.legend(loc="lower right")
# 子图4:不同阈值对贷款违约预测的影响(帮助业务决策确定最佳阈值)
plt.subplot(2, 2, 4)
thresholds = [0.3, 0.4, 0.5, 0.6, 0.7] # 不同的违约概率阈值
recall_list = [] # 存储不同阈值下的召回率
precision_list = [] # 存储不同阈值下的精确率
for threshold in thresholds:
# 当预测概率大于等于阈值时,判定为违约
y_pred_threshold = (y_prob >= threshold).astype(int)
recall_list.append(recall_score(y_test, y_pred_threshold))
precision_list.append(precision_score(y_test, y_pred_threshold))
plt.plot(thresholds, recall_list, marker='o', label='召回率(识别违约的能力)')
plt.plot(thresholds, precision_list, marker='s', label='精确率(预测违约的准确性)')
plt.title('不同阈值对贷款违约预测的影响')
plt.xlabel('违约概率阈值(超过此值则预测为违约)')
plt.ylabel('指标值')
plt.legend()
plt.grid()
plt.tight_layout()
plt.savefig('贷款违约模型评估.png')
plt.close()
# 学习曲线(分析模型在不同样本量下的表现,判断是否需要更多数据)
train_sizes, train_scores, test_scores = learning_curve(
LogisticRegression(class_weight='balanced'),
X_scaled, y,
train_sizes=np.linspace(0.1, 1.0, 10), # 训练样本比例:10%到100%
cv=5, # 5折交叉验证
scoring='accuracy', # 评估指标为准确率
n_jobs=-1 # 并行计算,使用所有可用CPU核心
)
# 计算均值和标准差
train_mean = np.mean(train_scores, axis=1)
train_std = np.std(train_scores, axis=1)
test_mean = np.mean(test_scores, axis=1)
test_std = np.std(test_scores, axis=1)
# 绘制学习曲线
plt.figure(figsize=(10, 6))
plt.plot(train_sizes, train_mean, color='blue', marker='o', label='训练集准确率')
# 填充标准差区间,展示数据波动
plt.fill_between(train_sizes, train_mean + train_std, train_mean - train_std, alpha=0.15, color='blue')
plt.plot(train_sizes, test_mean, color='green', marker='s', label='测试集准确率')
plt.fill_between(train_sizes, test_mean + test_std, test_mean - test_std, alpha=0.15, color='green')
plt.title('贷款违约预测模型学习曲线')
plt.xlabel('训练样本数量(贷款申请人数量)')
plt.ylabel('准确率')
plt.legend()
plt.grid()
plt.savefig('贷款模型学习曲线.png')
plt.close()
# 模拟实际预测场景:预测一个新用户的违约概率
# 示例用户数据:收入8万,负债2万,信用分650
new_user = np.array([[8, 2, 650]])
# 标准化(使用训练好的scaler,保证与训练数据处理方式一致)
new_user_scaled = scaler.transform(new_user)
# 预测违约概率
default_prob = model.predict_proba(new_user_scaled)[0, 1]
print(f"\n示例用户违约预测:")
print(f"收入:{new_user[0,0]}万元/年,负债:{new_user[0,1]}万元,信用分:{new_user[0,2]}分")
print(f"预测违约概率:{default_prob:.2%}") # 以百分比形式展示
# 根据阈值0.5判断结果
print(f"预测结果:{'会违约' if default_prob > 0.5 else '不会违约'}(阈值0.5)")
print("\n贷款违约预测模型训练和评估完成,结果已保存为图片文件")
1.5.2、实验结果
贷款数据探索
贷款模型学习曲线
贷款违约模型评估
贷款违约示例
2、决策树(Decision Tree)—— 像 “问路” 一样做判断
2.1、通俗理解
决策树就像我们问路时的 “分支选择”:比如 “收入是否大于 50 万?是→看工作是否稳定