探索五大机器学习技术及其应用
Posted 川川菜鸟
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了探索五大机器学习技术及其应用相关的知识,希望对你有一定的参考价值。
没有一种机器学习算法可以解决所有类型的机器学习问题。机器学习任务可能千差万别,算法的选择将取决于数据的大小、维数和稀疏性等因素。目标变量、数据的质量以及特征内部以及特征与目标变量之间存在的相互作用和统计关系。
在本文中,我将提供机器学习的五种最常用算法的快速参考指南。这将介绍算法的内部工作原理以及使每个算法更适合特定任务的注意事项。
这将包括对线性回归、逻辑回归、随机森林、XGBoost 和 K-means 的简要介绍。对于每种算法,我将介绍以下内容:
- 基本原理。
- 示例代码。
- 应该什么时候使用。
- 优点和缺点。
文章目录
一、线性回归
1.1 基本原理
线性回归是一种有监督的机器学习算法,用于预测连续的目标变量。对于简单的线性回归,其中有一个自变量(特征)和一个因变量(目标),算法可以用以下等式表示。
y=a+bx
其中y是因变量,X是特征变量,b是直线的斜率,a是截距。
简单线性回归可以可视化为散点图,其中 x 轴包含因变量,y 轴包含自变量。线性回归算法通过数据点绘制一条最佳拟合线,最大限度地减少预测输出和实际输出之间的变化。
1.2 示例代码
from sklearn.datasets import make_regression
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from yellowbrick.regressor import PredictionError
X, y = make_regression(
n_samples=500, n_features=5, noise=50, coef=False
)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
model = LinearRegression()
visualizer = PredictionError(model)
visualizer.fit(X_train, y_train)
visualizer.score(X_test, y_test)
visualizer.show()
1.3 应该什么时候使用
- 线性回归只能用于解决基于回归的问题。
- 因变量和自变量之间必须存在线性关系。
- 残差必须服从正态分布。
- 特征之间必须没有相关性。
- 该算法假设训练数据是随机采样的。
- 最适合基于回归的问题,其中数据中的关系既是线性的又是简单的。
1.4 优缺点
优点:
- 高度可解释和快速训练。
- 在线性可分数据上表现非常好。
缺点:
- 对异常值不稳健。
- 非常简单,因此它不能很好地模拟现实世界数据中的复杂性。
- 该算法也容易过拟合。
二、逻辑回归
2.1 基本原理
逻辑回归本质上是线性回归模型,以适应分类问题。逻辑回归不是拟合直线,而是应用逻辑函数将线性方程的输出压缩在 0 和 1 之间。结果是 S 形曲线而不是穿过数据点的直线,如下图所示。
选择 0 和 1 之间的阈值来分隔类,通常为 0.5。本质上,我们在 0.5 处绘制一条穿过 S 曲线的水平线。这条线上方的任何数据点都属于 1 类,低于该线的任何数据点都属于 0 类。
2.2 示例代码
import seaborn as sns
import pandas as pd
from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
X, y = make_classification(n_features=1,
n_informative=1,
n_redundant=0,
n_classes=2,
n_clusters_per_class=1,
flip_y=0.2,
random_state=0)
df = pd.DataFrame(X, columns=['x'])
df['y'] = y
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
lr = LogisticRegression(C=1e5)
model = lr.fit(X_train, y_train)
y_pred = model.predict(X_test)
sns.regplot(x='x', y='y', data=df, logistic=True, ci=None)
2.3应该什么时候使用
- 该算法只能用于解决分类问题。
- 特征和目标变量之间必须存在线性关系。
- 观测值的数量必须大于特征的数量。
- 最适合数据中的关系既是线性又简单的分类问题。
2.4优缺点
优点:
- 与线性回归一样,该算法可解释性强且训练速度快。
- 它在线性可分数据上表现非常好。
缺点:
- 容易过度拟合。
- 与线性回归一样,它不能很好地模拟复杂关系。
三、随机森林
3.1 基本原理
随机森林算法构建决策树的“森林” 。森林中的每棵树都会根据给定的一组特征生成预测。一旦生成了所有预测,就会进行多数表决,并且最常预测的类别形成最终预测。
决策树是一种非常直观的算法。它具有类似流程图的结构,其中包含代表测试的一系列节点。每个测试的结果都会产生分裂,并创建一个或多个叶节点,直到实现最终预测。超参数决定树的生长深度和使用的节点分裂函数。
随机森林算法遵循以下步骤序列:
- 训练数据集根据森林中树木的数量随机分成多个样本。树的数量是通过超参数设置的。
- 使用其中一个数据子集并行训练决策树。
- 评估所有树的输出,并将最常出现的预测作为最终结果。
3.2 示例代码
from sklearn.datasets import make_classification
from sklearn.ensemble import RandomForestClassifier
X, y = make_classification(random_state=0)
X_train, X_test, Y_train, Y_test = train_test_split(X, y, random_state=0)
rf = RandomForestClassifier(n_estimators=100,
random_state=0)
rf.fit(X_train, Y_train)
3.3 应该什么时候使用
- 该算法可用于解决基于分类和回归的问题。
- 它特别适合具有高维度的大型数据集,因为该算法本身就执行特征选择。
3.4 优缺点
优点:
- 它可以模拟线性和非线性关系。
- 它对异常值不敏感。
- 随机森林能够在包含缺失数据的数据集上表现良好。
缺点:
- 随机森林可能容易过度拟合,尽管这可以通过修剪在一定程度上减轻。
- 尽管可以提取特征重要性以提供一定程度的可解释性,但它不像线性回归和逻辑回归那样可解释。
四、XGBoost
4.1 基本原理
XGBoost 是一种基于梯度提升决策树的算法。它类似于随机森林,因为它构建决策树的集合,但 XGBoost 不是并行训练模型,而是顺序训练模型。每个决策树都从先前模型产生的错误中学习。这种按顺序训练模型的技术称为提升。
XGBoost 中的梯度是指使用弱学习器的特定类型的提升。弱学习器是非常简单的模型,仅比随机机会表现更好。该算法从初始的弱学习器开始。每个后续模型都针对先前决策树产生的错误。这一直持续到无法做出进一步的改进并产生最终的强大学习者模型。
4.2 示例代码
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from xgboost import XGBClassifier
X, y = make_classification(random_state=0)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
model = XGBClassifier()
model.fit(X_train, y_train)
4.3 应该什么时候使用
- 它可用于解决基于分类和回归的问题。
- XGBoost 通常被认为是用于结构化数据监督学习的最佳和最灵活的算法之一,因此适用于范围广泛的数据集和问题类型。
4.4 优缺点
优点:
- XGboost 非常灵活,因为它在小型和大型数据集上都能同样出色地工作。
- 与其他复杂算法相比,它具有计算效率,因此可以更快地训练模型。
缺点:
- 它不适用于非常稀疏或非结构化的数据。
- 它被认为是一个黑盒模型,比其他一些算法更难解释。
- 由于模型从其前一个模型的错误中学习的机制,XGBoost 可能对异常值敏感。
五、K 均值
5.1 基本原理
K-means 是最流行的聚类算法之一,它是一种无监督机器学习形式,旨在在训练数据集中找到相似示例的组。
该算法通过首先初始化随机簇质心来工作。然后对于每个数据点,通常使用欧几里德距离或余弦相似度的距离度量将其分配给最近的质心。一旦分配了所有数据点,质心就会移动到已分配数据点的平均值。重复这些步骤,直到质心分配停止改变。
5.2 示例代码
from sklearn.datasets import make_blobs
from sklearn.cluster import KMeans
X, y_true = make_blobs(n_samples=250, centers=3,
cluster_std=0.60, random_state=0)
kmeans = KMeans(n_clusters=3)
kmeans.fit(X)
y_kmeans = kmeans.predict(X)
5.3 应该什么时候使用
- K-means 仅适用于无监督聚类。
- 对于这些类型的问题,它通常被认为是一种很好的全能算法。
5.4 优缺点
优点:
- 这是一个实现起来相对简单的算法。
- 它可以用于大型数据集。
- 由此产生的簇很容易解释。
缺点:
- K-means 对异常值很敏感。
- 该算法未找到最佳簇数。这必须在实施之前由其他技术确定。
- 聚类结果不一致。如果 K-means 在数据集上多次运行,它每次都会产生不同的结果。
六、总结对比
- 线性回归:最适合解决存在线性关系且关系相对简单的数据集的基于回归的问题。
- 逻辑回归:最适合解决数据线性可分且数据集维数较低的分类问题。
- 随机森林:最适合具有复杂关系的大型高维数据集。
- XGBoost:适用于范围广泛的结构化数据集和问题。与随机森林相比,计算效率更高。
- K-means:最适合解决无监督聚类问题。
五大经典算法之回溯法及其应用
前言
回溯法是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”, 这就是回溯法的定义;这个和穷举法有些关联,都在不断的试探;而下面从从九宫格、八皇后、数独问题、来理解回溯法
回溯法的应用
九宫格问题
我们要将4或者9个数或者16个数 n的n次方个数放入九宫格中,使得所有斜线和直线的数相加都等于相同的值,怎么解决这个问题;这就是通过回溯法可以解决的问题
解决问题的方法
- 现在第一行的中间填第一个数1
- 开始往右上角放数字,只要超过了上边,就放到下面,如果超过了左边就放右边
- 当遇到右上角有数据,这里就是回溯了,放到当前数据的下面,然后继续往右上走
- 就这样不断的往右上走,我们就能成下面的数独了
代码实现
我们首先定义创建九宫格
public static int n=5;
public static int[][] array=new int[n][n];
主要逻辑
首先定义填入的数据,和定义起始位置
int x=1;//要填入的数据
//定义起始位置
int row=0;
int col=n/2;
array[row][col]=1;
数组的行和列的位置开始填写后面的数据
//开始填写后面的数据
while(x<n*n){
//在选择下一位置的时候,先记录下现在的位置
int tempRow=row;
int tempCol=col;
//向右上移动
row--;
if(row<0){
row=n-1;
}
col++;
if(col==n){
col=0;
}
x++;
if(array[row][col]==0){//如果右上没填,直接填入
array[row][col]=x;
}else{//如果没填,就放到当前位置的下面
//还原
row=tempRow;
col=tempCol;
row++;
array[row][col]=x;
}
}
- //在选择下一位置的时候,先记录下现在的位置int tempRow=row; int tempCol=col;
- row--;就是往右上走,如果row<0 则 放到最下面 row=n-1;
- col++; 如果col==n时 列号达到最大时, col=0;
- if(array[row][col]==0){//如果右上没填,直接填入; 直接填入
- 如果没填,就放到当前位置的下面 ;这里就涉及到还原 记录的 tempRow 进行还原
完整的代码
public static int n=5;
public static int[][] array=new int[n][n];
//逻辑
public static void squaredUp(int[][] array){
int x=1;//要填入的数据
//定义起始位置
int row=0;
int col=n/2;
array[row][col]=1;
//开始填写后面的数据
while(x<n*n){
//在选择下一位置的时候,先记录下现在的位置
int tempRow=row;
int tempCol=col;
//向右上移动
row--;
if(row<0){
row=n-1;
}
col++;
if(col==n){
col=0;
}
x++;
if(array[row][col]==0){//如果右上没填,直接填入
array[row][col]=x;
}else{//如果没填,就放到当前位置的下面
//还原
row=tempRow;
col=tempCol;
row++;
array[row][col]=x;
}
}
}
八皇后问题
也就是在国际象棋中,放一个棋子上,而这个棋子斜线和直线 上都可以吃棋子,因此在摆放时,棋盘上放一个皇后,而这个皇后相互之间不能吃,这就是八皇后问题
先放一个棋子,然后放第二个棋子时,就要判定和其他棋子是否能吃到,在周围试探放如果行就放,不行就退回上一行,从上一行找能放的格子,到最后八行都能放下去的时候就是八皇后了
- 也就是开始放到这里时 还可以
- 然后我们继续往下试
当遇到下面的情况,我们无法摆,就要退回去,重新找另外种方式摆,直到摆满8个就算解决问题了,这就是回溯法
代码实现
设计思想,通过一维数组来表示二维数组,也就是 一维数组 ,用值表示哪个位置
//下标表示行号 值表示列号
public static int[] array=new int[8];
- 然后处理8皇后的问题,首先考虑一个事情,要存放新的棋子时,我们要找到新的棋子与老的棋子不相交。也就是下面的图
- 需要专门判断当前列放入的位置和以前放入位置有冲突 从0开始,判断是否有冲突
for(int i=0;i<n;i++){
//条件1 array[i]==array[n] 在一列上
//条件2 abs(n-i)==abs(array[n]-array[i])
if(array[i]==array[n] || Math.abs(n-i)==Math.abs(array[n]-array[i])){
return false;
}
}
return true;
这里 在同一列很简单,也就是array[n]=array[i]则表明有冲突了,array[n] 表示当前要填的固定的比如是上面的4 固定的,而array[i]表示 之前填的位置,看是否相等的,就是刚才已经确定的 ,这里就没填。
- 怎么理解次对角线上的冲突拉,也就是
- n-i绝对值等于array[n]-array[i] 的绝对值,这就是相同的,就在对角线上的
最后
//如果有结果了就退出
if(row==8){
printResult();
System.out.println("---------");
return;
}
//开始从第一列到最后一列一个个放入
for(int col=0;col<8;col++){
array[row]=col;
if(judge(row)){//判断是否可以放入
eightQueens(row+1);//就开始下一行
}
}
回溯是通过递归来做的,这就是解决8皇后问题
数独问题
规则
在9x9的方格上面,要求每一行和每一列从1到9的位置不重复的,然后每一个3x3的格子的数字,也是填1到9不能重复
- 我们开始从第一个开始填写,看是否满足 ,能满足就继续往前填,不能满足就退回来重新填
这个和8皇后很像
这里放4就有问题,然后就要重新在返回写过
代码实现
我们先写一个随意的二维数组,占好位
public static int[][] result=new int[9][9];
- 判断数字是否可以用
//判断行和列不重复
for (int i = 0; i < 9; i++) {
if(result[row][i]==number || result[i][col]==number){
return false;
}
}
然后继续考虑3*3宫里面没有重复值
要求到其中一个没有重复值,我们只要 行列位置除以三就行
//判断自已所在的宫里面没有重复值
int tempRow=row/3;
int tempCol=col/3;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if(result[tempRow*3+i][tempCol*3+j]==number){
return false;
}
}
}
进行判断就行 是否有重复值就行
- 我们从第一个开始往后填
public static void sudoku(){
sudoku(0,0);
}
public static void sudoku(int i,int j){
if(i==8 && j==9){
printResult();
return;
}
if(j==9){//横着放的时候,如果到了最右边,就回到下一行的第一个
i++;
j=0;
}
if(result[i][j]==0){//如果是空格
for (int k = 1; k <= 9; k++) {
if(judge(i,j,k)){
result[i][j]=k;
sudoku(i,j+1);
//让前一次的格子还原
result[i][j]=0;
}
}
}else{
sudoku(i,j+1);
}
}
这里不断往后放的时候,我们得还原空格,得还原回来。也就是等于0,就是递归下去。
这有很多组解得。
总结
最后学习回溯法,和递归关系比较密切,穷举法,效率大家能想到比较低,我们是为了解决某些问题用回溯法,也算是我们常用经典得算法。
以上是关于探索五大机器学习技术及其应用的主要内容,如果未能解决你的问题,请参考以下文章