机器学习算法:10种常用算法及其实现

120 阅读6分钟

咱们先来聊聊机器学习里那些常用的算法,不用把它们想得太复杂,其实就像工具箱里的各种工具,各有各的用处。

先从线性回归说起,它就像我们小时候在坐标系里画直线,想找一条最合适的线穿过尽可能多的点。比如我们想根据学生的学习时长来预测考试分数,就可以用它。你看这段代码,首先导入需要的库,然后模拟一些学习时长和分数的数据。X 是学习时长,y 是对应的分数。创建线性回归模型后,用这些数据去训练它,最后就能预测学习 6 小时的分数了。

import numpy as np
from sklearn.linear_model import LinearRegression
# 学习时长数据(小时)
X = np.array([[1], [2], [3], [4], [5]])
# 对应考试分数
y = np.array([60, 65, 75, 80, 90])
# 创建线性回归模型
model = LinearRegression()
# 训练模型
model.fit(X, y)
# 预测学习6小时的分数
print("学习6小时的预测分数:", model.predict([[6]]))

了解了线性回归,咱们再看看逻辑回归。它和线性回归有点像,但它不是用来预测具体数值的,而是用来做分类的。比如判断一封邮件是不是垃圾邮件,结果只有是或不是两种。下面的代码里,我们用一些肿瘤的特征数据来训练模型,然后预测新的肿瘤是良性还是恶性。

import numpy as np
from sklearn.linear_model import LogisticRegression
# 肿瘤特征数据(假设是某种指标)
X = np.array([[2.3], [3.1], [1.8], [4.5], [2.7], [3.8], [1.5], [4.2]])
# 0表示良性,1表示恶性
y = np.array([0, 1, 0, 1, 0, 1, 0, 1])
# 创建逻辑回归模型
model = LogisticRegression()
# 训练模型
model.fit(X, y)
# 预测新肿瘤的性质,这里输入的是一个新的指标值
print("新肿瘤的预测结果(0为良性,1为恶性):", model.predict([[3.0]]))

接下来是决策树,听名字就知道,它像一棵会做决策的树。比如我们去买水果,先看颜色,再看形状,一步步判断是什么水果。决策树就是这样,根据特征一步步划分,最终得到分类结果。下面的代码用鸢尾花数据集来训练模型,然后预测一朵新花的种类。

from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
# 加载鸢尾花数据集
iris = load_iris()
X = iris.data  # 花的特征数据
y = iris.target  # 花的种类
# 创建决策树模型
model = DecisionTreeClassifier()
# 训练模型
model.fit(X, y)
# 预测一朵新花的种类,这里输入的是花的四个特征值
print("新花的种类预测结果:", model.predict([[5.1, 3.5, 1.4, 0.2]]))

随机森林就像是很多棵决策树聚在一起商量事情。一个人的判断可能有偏差,一群人的判断往往更靠谱。随机森林就是通过多个决策树的投票来得到最终结果,稳定性更好。看这段代码,还是用鸢尾花数据集,创建随机森林模型后训练,再做预测。

from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestClassifier
iris = load_iris()
X = iris.data
y = iris.target
# 创建随机森林模型,里面包含10棵树
model = RandomForestClassifier(n_estimators=10)
model.fit(X, y)
print("新花的种类预测结果:", model.predict([[5.1, 3.5, 1.4, 0.2]]))

支持向量机听起来有点高大上,其实它的想法很简单,就是在数据点之间找一条最宽的分界线。比如在二维平面上有两类点,支持向量机就想找到一条直线,让两类点到直线的距离都尽可能远,这样分类效果更好。下面用简单的二维数据来试试。

import numpy as np
from sklearn.svm import SVC
# 两类数据点
X = np.array([[1, 2], [2, 3], [3, 3], [6, 5], [7, 7], [8, 6]])
y = np.array([0, 0, 0, 1, 1, 1])
# 创建支持向量机模型
model = SVC()
model.fit(X, y)
# 预测新点的类别
print("新点(4,4)的类别:", model.predict([[4, 4]]))

K - 近邻算法就像 “物以类聚”,判断一个样本属于什么类别,就看它周围最近的几个样本大多属于什么类别。比如想知道一个新水果是什么,就看看它旁边的水果都是什么,多数是什么就认为它是什么。代码里用鸢尾花数据集来演示,设置 K 值为 3,就是看最近的 3 个样本。

from sklearn.datasets import load_iris
from sklearn.neighbors import KNeighborsClassifier
iris = load_iris()
X = iris.data
y = iris.target
# 创建K-近邻模型,K=3
model = KNeighborsClassifier(n_neighbors=3)
model.fit(X, y)
print("新花的种类预测结果:", model.predict([[5.1, 3.5, 1.4, 0.2]]))

朴素贝叶斯算法基于概率来分类,它假设各个特征之间是相互独立的。比如判断一封邮件是不是垃圾邮件,它会看邮件里出现 “优惠”“中奖” 等词的概率,再综合起来判断。下面用文本分类的例子来看看,先把文本转换成数字特征,再用朴素贝叶斯模型训练。

from sklearn.naive_bayes import MultinomialNB
from sklearn.feature_extraction.text import CountVectorizer
# 一些文本数据
texts = ["我喜欢机器学习", "机器学习很有趣", "足球比赛很精彩", "我喜欢看足球"]
# 文本对应的类别,0表示机器学习相关,1表示足球相关
labels = [0, 0, 1, 1]
# 将文本转换为特征向量
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(texts)
# 创建朴素贝叶斯模型
model = MultinomialNB()
model.fit(X, labels)
# 预测新文本的类别
new_text = ["我喜欢足球和机器学习"]
new_X = vectorizer.transform(new_text)
print("新文本的类别(0:机器学习,1:足球):", model.predict(new_X))

K - 均值聚类和前面的分类算法不太一样,它是无监督学习,不知道样本的类别,而是把相似的样本聚成一类。比如把一群人按照身高体重分成几类,不需要提前知道类别。代码里生成一些随机数据,然后聚成 3 类。

import numpy as np
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
# 生成随机数据
X = np.random.randn(100, 2)
# 创建K-均值模型,聚成3类
model = KMeans(n_clusters=3)
model.fit(X)
# 得到每个样本的聚类标签
labels = model.predict(X)
# 可视化聚类结果
plt.scatter(X[:, 0], X[:, 1], c=labels)
plt.show()

主成分分析主要用来降维,当数据的特征很多时,它能把高维数据转换成低维的,同时保留主要信息。比如有很多特征描述一个人的身体状况,主成分分析可以把它们浓缩成几个主要成分,方便分析。下面用鸢尾花数据集,把 4 个特征降到 2 个。

from sklearn.datasets import load_iris
from sklearn.decomposition import PCA
iris = load_iris()
X = iris.data
# 创建主成分分析模型,降到2维
pca = PCA(n_components=2)
# 对数据进行降维
X_reduced = pca.fit_transform(X)
print("降维前的形状:", X.shape)
print("降维后的形状:", X_reduced.shape)

最后说说梯度提升机,它是一种集成学习方法,通过不断迭代来提升模型性能。就像一群人接力赛跑,后面的人根据前面的人的不足来调整自己的跑法,让整体成绩更好。下面用房价预测的例子,不过这里用的是波士顿房价数据集(注意:新版本 sklearn 可能移除了该数据集,可用其他数据集替代)。

from sklearn.ensemble import GradientBoostingRegressor
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
# 加载波士顿房价数据集
boston = load_boston()
X = boston.data
y = boston.target
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
# 创建梯度提升机模型
model = GradientBoostingRegressor()
model.fit(X_train, y_train)
# 测试模型
print("模型在测试集上的得分:", model.score(X_test, y_test))