【机器学习】基本模型简易代码整理

目录

    • 对数几率回归
      • 原理
      • 损失函数和优化
      • 特点和应用
    • 支持向量机SVM
      • 原理
      • 损失函数与优化
      • 优点与应用
    • 信息增益
    • 决策树


本文对机器学习课程考试中可能出现的模型代码题进行总结,仅供参考。

对数几率回归

对数几率回归(Logistic Regression)是机器学习中一种广泛应用的统计学习方法,主要用于二分类问题。尽管其名字中包含“回归”这个词,但实际上它是一种分类算法,而不是传统的回归算法。

原理

对数几率回归的核心思想是使用逻辑函数(也称为Sigmoid函数)将线性回归的输出映射到[0,1]区间,从而可以得到一个概率值。

Sigmoid函数定义为:
σ ( z ) = 1 1 + e − z \sigma(z) = \frac{1}{1 + e^{-z}} σ(z)=1+ez1

其中, z = w 0 + w 1 x 1 + w 2 x 2 + … + w n x n z = w_0 + w_1 x_1 + w_2 x_2 + \ldots + w_n x_n z=w0+w1x1+w2x2++wnxn是线性组合。

对于二分类问题,假设正类的标签为1,负类的标签为0,我们可以使用对数几率函数来建模某个实例属于正类的概率为:
P ( Y = 1 ∣ X ) = σ ( w T x ) = 1 1 + e − w T x P(Y=1|X) = \sigma(w^T x) = \frac{1}{1 + e^{-w^T x}} P(Y=1∣X)=σ(wTx)=1+ewTx1

损失函数和优化

对数几率回归使用最大似然估计来估计参数 ( w )。对于给定的训练数据,损失函数(或对数似然函数)为:
L ( w ) = ∑ i = 1 m [ y ( i ) log ⁡ ( σ ( w T x ( i ) ) ) + ( 1 − y ( i ) ) log ⁡ ( 1 − σ ( w T x ( i ) ) ) ] L(w) = \sum_{i=1}^{m} [y^{(i)} \log(\sigma(w^T x^{(i)})) + (1 - y^{(i)}) \log(1 - \sigma(w^T x^{(i)}))] L(w)=i=1m[y(i)log(σ(wTx(i)))+(1y(i))log(1σ(wTx(i)))]
通常,为了最小化这个损失函数,可以使用梯度下降或其他优化算法。

特点和应用

  1. 线性决策边界:对数几率回归产生的是一个线性决策边界,它可以用于分类任务。
  2. 概率估计:除了分类外,对数几率回归还可以提供实例属于某一类别的概率估计。
  3. 简单和高效:相对于其他更复杂的模型,对数几率回归通常计算速度较快,容易实现和解释。

总之,对数几率回归是一种基于线性模型和逻辑函数的分类算法,广泛应用于各种应用场景,如文本分类、信用评分、医学诊断等。

  • 对数几率回归
import numpy as np
import pandas as pd
def generate_data():
    datasets = pd.read_csv('dataSet.csv', header=None).values.tolist()
    labels = pd.read_csv('labels.csv', header=None).values.tolist()
    return datasets, labels
def sigmoid(X):
    hx = 1/(1+np.exp(-X))
    return hx
    #code end here
def gradientDescent(dataMatIn, classLabels):
    alpha = 0.001  # 学习率,也就是题目描述中的 α
    iteration_nums = 100  # 迭代次数,也就是for循环的次数
    dataMatrix = np.mat(dataMatIn) 
    labelMat = np.mat(classLabels).transpose() 
    m, n = np.shape(dataMatrix)  # 返回dataMatrix的大小。m为行数,n为列数。
    weight_mat = np.ones((n, 1)) #初始化权重矩阵
    for i in range(iteration_nums):
        hx=sigmoid(dataMatrix*weight_mat)
        weight_mat-=alpha*dataMatrix.transpose()*(hx-labelMat)
    return weight_mat
if __name__ == '__main__':
    dataMat, labelMat = generate_data()
    print(gradientDescent(dataMat, labelMat))

支持向量机SVM

支持向量机(Support Vector Machine,简称 SVM)是一种机器学习算法,主要用于分类和回归分析。尤其在分类问题中,SVM 是非常受欢迎和有效的方法之一。

原理

在分类问题中,SVM 的目标是找到一个最优的超平面,以最大化两个不同类别的数据点(即支持向量)之间的间隔。这个超平面可以有效地将两个不同的类别分开。

  1. 线性可分情况:在两类数据是线性可分的情况下,SVM 试图找到一个使得间隔最大化的超平面。这个间隔是由距离最近的正类和负类样本点决定的,这些样本点被称为支持向量。

  2. 软间隔与核技巧:在实际应用中,数据往往不是完全线性可分的。为了解决这个问题,SVM 引入了“软间隔”概念,允许一些样本出现在错误的一侧。此外,通过核技巧,SVM 可以将线性不可分的数据映射到高维空间,从而使其线性可分。

损失函数与优化

在 SVM 中,损失函数旨在最大化间隔并确保所有的样本点(或大部分样本点)被正确分类。数学上,这通常通过求解一个二次规划(Quadratic Programming)问题来实现。

优点与应用

  1. 高效的边界:SVM 通过最大化间隔来找到一个鲁棒的决策边界,对噪声和异常值具有一定的鲁棒性。
  2. 核技巧:SVM 可以使用不同的核函数(如线性、多项式、径向基函数等)处理线性和非线性分类问题。
  3. 广泛应用:除了分类任务,SVM 还可以用于回归分析、异常检测等多种任务。

然而,SVM 也有其局限性,如处理大规模数据集时可能面临计算效率问题,对于高度非线性和复杂的问题,选择合适的核函数和参数也是一项挑战。

  • SVM
import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
def create_data():
    iris = load_iris()
    df = pd.DataFrame(iris.data, columns=iris.feature_names)
    df['label'] = iris.target
    df.columns = ['sepal length', 'sepal width', 'petal length', 'petal width', 'label']
    data = np.array(df.iloc[:100, [0, 1, -1]])
    for i in range(len(data)):
        if data[i,-1] == 0:
            data[i,-1] = -1
    return data[:,:2], data[:,-1]
#使用RBF(Radial basis function)核函数处理
def K(x,z,sigma=1.5):
    return np.exp(np.dot((x-z),(x-z).T)/-(2*sigma**2))
#对应课本147页的g(x_i),该函数助于验证KKT条件
def g(i,x,y,alpha,b):
    sum=b
    for j in range(len(y)):
        sum+=alpha[j]*y[j]*K(x[i],x[j])
    return sum
#验证第i个样本点是否满足KKT条件
def isKKT(alpha,i,x,y,b,C):
    if alpha[i]==0 and y[i]*g(i,x,y,alpha,b)>=1:
        return True
    elif alpha[i]==C and y[i]*g(i,x,y,alpha,b)<=1:
        return True
    elif alpha[i]>0 and alpha[i]<C and y[i]*g(i,x,y,alpha,b)==1:
        return True
    else:
        return False
#验证第i个样本点违反KKT条件的程度。由于KKT条件和y_i*g(x_i)与1的不等式有关
#因此计算y_i*g(x_i)与1之间差值的绝对值作为衡量违反程度的标准
def vioKKT(alpha,i,x,y,b):
    return abs(y[i]*g(i,x,y,alpha,b)-1)
#在数组x中找到值为a的元素第一次出现的位置
def findindex(x,a):
    for i in range(len(x)):
        if x[i]==a:
            return i
#某个样本点分类误差函数
def E(w,b,x_k,y_k):
    predi_k=int(np.sign(np.dot(w,x_k.T)+b))
    return predi_k-y_k
#计算样本点与分割直线的距离
def distance_count(x,w,b):
    return abs(w[0]*x[0]+w[1]*x[1]+b) / np.sqrt(w[0]**2 + w[1]**2)

SVM-sklearn

1.导库
2.加载数据
data = pd.read_csv('your_dataset.csv')
X = data.drop('target_column', axis=1)
y = data['target_column']
3.划分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
4.数据预处理
# 使用 StandardScaler 进行特征标准化
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
5.选择并训练模型
model = SVC(kernel='rbf', C=1.0, gamma='scale')
model.fit(X_train_scaled, y_train)
# kernel: 核函数的类型,可以选择线性核'linear'、多项式核'poly'、径向基核'rbf'等。
# C: 正则化参数,控制决策边界的平滑度,值越小,决策边界越平滑。
# gamma: 核函数的系数,影响数据映射到高维空间后的形状,值越大,影响范围越小。
6.模型评估
y_pred = model.predict(X_test_scaled)
print("Accuracy:", accuracy_score(y_test, y_pred))
print("Classification Report:\n", classification_report(y_test, y_pred))

信息增益

在机器学习和数据挖掘中,信息增益(Information Gain)是用于特征选择的一个关键指标,特别是在决策树算法(如ID3、C4.5等)中。信息增益的目标是找到最能区分不同类别的特征。

信息增益的计算基于信息论中的熵(Entropy)概念。给定一个数据集,其熵表示了该数据集的不确定性或混乱程度。具体来说,熵的计算公式为:
Entropy ( S ) = − ∑ i = 1 c p i log ⁡ 2 p i \text{Entropy}(S) = - \sum_{i=1}^{c} p_i \log_2 p_i Entropy(S)=i=1cpilog2pi
其中,
p i p_i pi是数据集中第 i类样本所占的比例,c 是类别的总数。

在特征选择过程中,我们希望找到那些能最大程度地降低数据集整体熵的特征。因此,信息增益用于衡量某个特征引入后整体熵的减少量。对于特征 ( A ),其信息增益 Gain ( S , A ) \text{Gain}(S, A) Gain(S,A)的计算公式为:
Gain ( S , A ) = Entropy ( S ) − ∑ v ∈ Values ( A ) ∣ S v ∣ ∣ S ∣ × Entropy ( S v ) \text{Gain}(S, A) = \text{Entropy}(S) - \sum_{v \in \text{Values}(A)} \frac{|S_v|}{|S|} \times \text{Entropy}(S_v) Gain(S,A)=Entropy(S)vValues(A)SSv×Entropy(Sv)
其中:

  • ( S S S ) 是原始数据集。
  • ( A A A ) 是待评估的特征。
  • ( Values ( A ) \text{Values}(A) Values(A) ) 是特征 ( A A A ) 可能的取值集合。
  • ( S v S_v Sv ) 是数据集 ( S S S ) 中特征 ( A A A ) 取值为 ( v v v ) 的样本子集。
  • ( ∣ S ∣ |S| S ) 和 ( ∣ S v ∣ |S_v| Sv ) 分别表示数据集 ( S S S ) 和子集 ( S v S_v Sv ) 的大小。

通过计算不同特征的信息增益,我们可以确定哪个特征是最佳的划分特征,以便在决策树的构建过程中进行节点分裂。特征选择过程的目标是在保持模型预测准确性的同时,尽可能减少模型的复杂性。

  • 信息增益
import numpy as np
import pandas as pd
from collections import Counter
import random
dataSet = pd.read_csv('dataSet.csv', header=None).values.T  # 转置 5*15数组
def entropy(data):  # 信息熵 data 一维数组
    numEntres = len(data)
    cnt = Counter(data)  # 计数每个值出现的次数  Counter({1: 8, 0: 5})
    probability_lst = [1.0 * cnt[i] / numEntres for i in cnt]
    return -np.sum([p * np.log2(p) for p in probability_lst])  # 返回信息熵
def calc_max_info_gain(dataSet):  #信息增益
    label = np.array(dataSet[-1])
    total_entropy = entropy(label)
    max_info_gain = [0, 0]
    for feature in range(4):  # 4种特征 我命名为特征:0 1 2 3
        f_index = {}
        for idx, v in enumerate(dataSet[feature]):
            if v not in f_index:
                f_index[v] = []
            f_index[v].append(idx)
        f_impurity = 0
        for k in f_index:
            # 根据该特征取值对应的数组下标 取出对应的标签列表 比如分支1有多少个正负例 分支2有...
            f_l = label[f_index[k]]
            f_impurity += entropy(f_l) * len(f_l) / len(label)  # 循环结束得到各分支混杂度的期望
        gain = total_entropy - f_impurity  # 信息增益IG
        if gain > max_info_gain[1]:
            max_info_gain = [feature, gain]
    return max_info_gain
if __name__ == '__main__':
    info_res = calc_max_info_gain(dataSet)
    print("信息增益最大的特征索引为:{0},对应的信息增益为{1}".format(info_res[0], info_res[1]))

决策树

通过交叉验证来选择适当的树深度是一种常见的模型选择方法。下面是一般的步骤:

  1. 划分数据集: 将数据集划分为训练集和验证集。通常,采用k折交叉验证,将数据集分成k个子集,每次使用k-1个子集作为训练数据,剩余的一个子集作为验证数据。

  2. 建立决策树: 使用训练集建立决策树模型,可以通过调整树的深度来控制模型的复杂性。

  3. 评估模型: 在每个交叉验证的迭代中,使用验证集评估模型性能。可以使用一些性能指标(如准确率、F1分数等)来衡量模型在验证集上的表现。

  4. 选择最佳深度: 对于每个树深度,计算模型在所有交叉验证迭代中的平均性能。选择在验证集上性能最好的树深度作为最终模型的深度。

  5. 训练最终模型: 使用整个训练集训练一个新的决策树模型,选择的深度是在验证集上表现最好的深度。

这个过程称为网格搜索(Grid Search),因为它涉及对深度的多个可能值进行搜索,找到使得模型性能最优的深度。在实际应用中,可以使用不同的性能指标、树的深度范围和交叉验证的折数进行调整,以获得最佳模型。

决策树-sklearn

1.导库
2.加载数据
data = pd.read_csv('your_dataset.csv')
X = data.drop('target_column', axis=1)
y = data['target_column']
3.划分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
4.数据预处理
# 示例:使用 StandardScaler 进行特征标准化
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
5.选择并训练模型
(1)决策树
model = DecisionTreeClassifier(criterion='gini', max_depth=None, random_state=42)
model.fit(X_train, y_train)
# criterion: 衡量分割质量的标准,可以选择基尼系数'gini'或信息增益'entropy'。
# max_depth: 决策树的最大深度,控制树的复杂度,防止过拟合。
# random_state: 为了确保可重复性,设置一个随机种子。2)随机森林
model = RandomForestClassifier(n_estimators=100, criterion='gini', max_depth=None, random_state=42)
model.fit(X_train, y_train)
# n_estimators: 随机森林中决策树的数量3)SVM
model = SVC(kernel='rbf', C=1.0, gamma='scale')
model.fit(X_train_scaled, y_train)
# kernel: 核函数的类型,可以选择线性核'linear'、多项式核'poly'、径向基核'rbf'等。
# C: 正则化参数,控制决策边界的平滑度,值越小,决策边界越平滑。
# gamma: 核函数的系数,影响数据映射到高维空间后的形状,值越大,影响范围越小。
5.模型评估
y_pred = model.predict(X_test)
print("Accuracy:", accuracy_score(y_test, y_pred))
print("Classification Report:\n", classification_report(y_test, y_pred))

SVM伪代码

Input: 训练集 D = {(x1, y1), (x2, y2), ..., (xm, ym)}, 学习率 η, 松弛变量惩罚参数 C
Output: SVM模型参数 w, b
// 初始化模型参数
w = [0, 0, ..., 0]  // 与特征数一致的零向量
b = 0
// 定义SVM模型的目标函数
def svm_objective_function(w, b, C, D):
    loss = 0.5 * np.dot(w, w)  // 正则化项
    for i in range(len(D)):
        xi, yi = D[i]
        loss += C * max(0, 1 - yi * (np.dot(w, xi) + b))  // Hinge Loss
    return loss
// 训练SVM模型
for epoch in range(num_epochs):
    for i in range(len(D)):
        xi, yi = D[i]
        // 判断是否违反约束条件
        if yi * (np.dot(w, xi) + b) < 1:
            // 更新模型参数
            w = w - η * (w - C * yi * xi)
            b = b + η * C * yi
        else:
            // 没有违反约束条件,只更新正则化项
            w = w - η * w
// 返回训练后的模型参数
Output: w, b

你可能感兴趣的:(机器学习,机器学习,人工智能,学习,算法)