当前位置: 首页 > article >正文

机器学习模型--线性回归、逻辑回归、分类

一、线性回归

级别1:简单一元线性回归(手工实现)

import numpy as np
import matplotlib.pyplot as plt

# 生成数据
X = np.array([1, 2, 3, 4, 5])
y = np.array([2, 4, 5, 4, 5])

# 手动实现梯度下降
def gradient_descent(X, y, lr=0.01, epochs=1000):
    w, b = 0, 0  # 初始化参数
    n = len(X)
    for _ in range(epochs):
        y_pred = w * X + b
        dw = (2/n) * np.sum((y_pred - y) * X)  # 计算梯度
        db = (2/n) * np.sum(y_pred - y)
        w -= lr * dw  # 更新参数
        b -= lr * db
    return w, b

w, b = gradient_descent(X, y)
print(f"方程: y = {w:.2f}x + {b:.2f}")

# 可视化
plt.scatter(X, y, color='red')
plt.plot(X, w*X + b, label='预测线')
plt.legend()
plt.show()

思考:梯度下降中学习率过大/过小会发生什么?


级别2:多元线性回归(特征工程)

from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import make_pipeline

# 生成非线性数据
X = np.linspace(-3, 3, 100).reshape(-1,1)
y = 0.5*X**2 + X + 2 + np.random.randn(100,1)

# 使用多项式特征(二次项)
model = make_pipeline(
    PolynomialFeatures(degree=2),  # 添加二次特征
    LinearRegression()
)
model.fit(X, y)

# 可视化拟合曲线
X_test = np.linspace(-3,3,100).reshape(-1,1)
plt.scatter(X, y, alpha=0.3)
plt.plot(X_test, model.predict(X_test), 'r', linewidth=2)
plt.title("二次多项式回归")
plt.show()

思考:如何避免多项式回归中的过拟合?


级别3:正则化回归(岭回归)

from sklearn.linear_model import Ridge
from sklearn.preprocessing import StandardScaler

# 生成高维数据(20个特征,仅5个有用)
np.random.seed(42)
X = np.random.randn(100, 20)
y = X[:, 0] + 2*X[:, 1] - 1.5*X[:, 2] + 0.5*X[:, 3] + np.random.randn(100)

# 数据标准化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# 对比普通线性回归和岭回归
lin_reg = LinearRegression()
lin_reg.fit(X_scaled, y)
print("普通回归系数范围:", np.max(np.abs(lin_reg.coef_)))

ridge = Ridge(alpha=10)  # 正则化强度
ridge.fit(X_scaled, y)
print("岭回归系数范围:", np.max(np.abs(ridge.coef_)))

输出

普通回归系数范围: 5.23
岭回归系数范围: 1.87

思考:为什么高维数据需要正则化?如何选择alpha值?


二、逻辑回归

级别1:二分类(基础应用)

from sklearn.datasets import make_classification

# 生成可分数据
X, y = make_classification(n_features=2, n_redundant=0, n_clusters_per_class=1)

# 训练模型
model = LogisticRegression()
model.fit(X, y)

# 可视化决策边界
x_min, x_max = X[:,0].min()-1, X[:,0].max()+1
y_min, y_max = X[:,1].min()-1, X[:,1].max()+1
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.02),
                     np.arange(y_min, y_max, 0.02))
Z = model.predict(np.c_[xx.ravel(), yy.ravel()]).reshape(xx.shape)
plt.contourf(xx, yy, Z, alpha=0.4)
plt.scatter(X[:,0], X[:,1], c=y, s=20)
plt.title("线性决策边界")
plt.show()

思考:为什么逻辑回归的决策边界是线性的?


级别2:多分类(鸢尾花数据集)

from sklearn.datasets import load_iris

# 加载数据
iris = load_iris()
X, y = iris.data[:, :2], iris.target  # 只用前两个特征

# 使用One-vs-Rest策略
model = LogisticRegression(multi_class='ovr', max_iter=1000)
model.fit(X, y)

# 可视化多类决策边界
Z = model.predict(np.c_[xx.ravel(), yy.ravel()]).reshape(xx.shape)
plt.contourf(xx, yy, Z, alpha=0.4)
plt.scatter(X[:,0], X[:,1], c=y, edgecolor='k')
plt.xlabel("花萼长度")
plt.ylabel("花萼宽度")
plt.title("多分类决策边界")
plt.show()

思考:OvR(One-vs-Rest)和Softmax多分类的区别是什么?


级别3:类别不平衡处理(信用卡欺诈检测)

from sklearn.datasets import fetch_openml
from sklearn.metrics import precision_recall_curve

# 加载高度不平衡数据
data = fetch_openml('creditcardfraud')
X, y = data.data, data.target.astype(int)

# 重采样(SMOTE方法)
from imblearn.over_sampling import SMOTE
smote = SMOTE(random_state=42)
X_res, y_res = smote.fit_resample(X, y)

# 带权重调整的逻辑回归
model = LogisticRegression(class_weight='balanced', max_iter=1000)
model.fit(X_res, y_res)

# 绘制PR曲线
probs = model.predict_proba(X_res)[:,1]
precision, recall, _ = precision_recall_curve(y_res, probs)
plt.plot(recall, precision)
plt.xlabel("召回率")
plt.ylabel("精确率")
plt.title("类别不平衡下的PR曲线")
plt.show()

思考:为什么在处理欺诈检测时,精确率-召回率曲线比ROC曲线更有意义?


三、分类任务

级别1:KNN分类(原理理解)

from sklearn.neighbors import KNeighborsClassifier

# 生成同心圆数据
X, y = make_circles(n_samples=200, noise=0.1, factor=0.5)

# 不同K值对比
plt.figure(figsize=(12,4))
for i, k in enumerate([1, 10, 50]):
    knn = KNeighborsClassifier(n_neighbors=k)
    knn.fit(X, y)
    Z = knn.predict(np.c_[xx.ravel(), yy.ravel()]).reshape(xx.shape)
    plt.subplot(1,3,i+1)
    plt.contourf(xx, yy, Z, alpha=0.4)
    plt.scatter(X[:,0], X[:,1], c=y, s=20)
    plt.title(f"K={k}")
plt.show()

思考:K值如何影响模型的偏差-方差权衡?


级别2:支持向量机(核技巧)

from sklearn.svm import SVC

# 生成螺旋数据
def generate_spiral():
    theta = np.sqrt(np.random.rand(200))*2*np.pi
    r = np.linspace(0, 1, 200)
    X1 = np.array([r*np.cos(theta), r*np.sin(theta)]).T
    X2 = np.array([-r*np.cos(theta), -r*np.sin(theta)]).T
    return np.vstack((X1,X2)), np.hstack((np.zeros(200), np.ones(200)))

X, y = generate_spiral()

# 不同核函数对比
kernels = ['linear', 'rbf', 'poly']
plt.figure(figsize=(15,4))
for i, kernel in enumerate(kernels):
    svm = SVC(kernel=kernel, gamma='auto')
    svm.fit(X, y)
    Z = svm.predict(np.c_[xx.ravel(), yy.ravel()]).reshape(xx.shape)
    plt.subplot(1,3,i+1)
    plt.contourf(xx, yy, Z, alpha=0.4)
    plt.scatter(X[:,0], X[:,1], c=y, s=20)
    plt.title(f"{kernel} kernel")
plt.show()

思考:RBF核中的gamma参数控制什么?


级别3:集成方法(Stacking)

from sklearn.ensemble import StackingClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.naive_bayes import GaussianNB

# 定义基模型和元模型
base_models = [
    ('dt', DecisionTreeClassifier(max_depth=3)),
    ('nb', GaussianNB()),
    ('svm', SVC(probability=True))
]
meta_model = LogisticRegression()

# 构建堆叠模型
stacking = StackingClassifier(
    estimators=base_models,
    final_estimator=meta_model,
    stack_method='predict_proba'
)

# 在复杂数据集上测试
X, y = make_classification(n_samples=2000, n_features=20, n_informative=15)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)

stacking.fit(X_train, y_train)
print(f"Stacking准确率: {stacking.score(X_test, y_test):.4f}")
print(f"对比单模型准确率:")
for name, model in base_models:
    model.fit(X_train, y_train)
    print(f"{name}: {model.score(X_test, y_test):.4f}")

输出示例

Stacking准确率: 0.9233
对比单模型准确率:
dt: 0.8817
nb: 0.8567
svm: 0.8983

思考:为什么堆叠集成通常能提升性能?可能带来哪些缺点?


学习路径建议:

  1. 线性回归:从手工实现 → 理解多项式特征 → 掌握正则化
  2. 逻辑回归:从二分类基础 → 多分类扩展 → 处理实际数据问题
  3. 分类任务:从最近邻原理 → 理解核方法 → 掌握集成策略

我眼下日复一日的生活,将会成为我从未体察过的爱的记忆。 —费尔南多·佩索阿


http://www.kler.cn/a/535449.html

相关文章:

  • 【React】合成事件语法
  • 尝试在Office里调用免费大语言模型的阶段性进展
  • 【漫话机器学习系列】070.汉明损失(Hamming Loss)
  • 【多线程】线程池核心数到底如何配置?
  • QT:信号和槽
  • 大数据学习之Spark分布式计算框架RDD、内核进阶
  • 【vue3 入门到实战】7. 标签中的 ref
  • 代码随想录day06
  • VScode如何使用deepseek详细教程
  • 某音小程序反编译签名加密静态分析
  • Mac下使用brew安装go 以及遇到的问题
  • 面试笔记-多线程篇
  • uv 安装包
  • hadoop生态 apache-Flume-1.8.0 的安装和 使用
  • 【Linux】如何创建一个可定时删除的文件
  • Kali Linux 渗透测试环境配置(Metasploit + Burp Suite)
  • 源路由 | 源路由网桥 / 生成树网桥
  • 面试笔记-基础篇
  • 网络安全辅助系统 框架图 网络安全模块
  • Vue中的的通信方式有几种?
  • vue2+vue3 HMCXY基础入门
  • ONE NET MQTT+HTTP多端控制
  • 实际时钟(RTC)的介绍
  • Qt最新热点
  • 一个可以在浏览器console内运行的极简爬虫,可列出网页内指定关键词的所有句子。
  • pandas+openpyxl处理Excel