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

机器学习核心概念速览

机器学习基本概念

  • 有监督学习
  • 分类、回归
  • 无监督学习
  • 聚类、降维

一维数组

import numpy as np
data = np.array([1,2,3,4,5])
print(data)
print(data.shape)
print(len(data.shape))
[1 2 3 4 5]
(5,)
1

二维数组

data2 = np.array([[1,2,3],[4,5,6]])
print(data2)
print(data2.shape)
print(len(data2.shape))
[[1 2 3][4 5 6]]
(2, 3)
2

稀疏矩阵

  • scipy.sparse

可调用对象

  • 函数,lambd表达式,类,类的方法,对象的方法,实现了特殊方法__call__的类的对象

样本

  • 定义:样本是数据集中单个数据点的具体实例。每个样本由一组特征和可能的目标值组成。
    • 例子:在房价预测中,一个样本可以是一个房屋,包含特征(如面积、卧室数量)和目标值(房价)。

特征、特征向量

  • 特征:描述样本属性的变量,例如年龄、身高、性别。
  • 特征向量:将一个样本的所有特征组合成一个向量(数组),表示该样本。
    • 例子:对于一个人,特征可能是 [年龄: 25, 性别: 男, 身高: 175cm]。

特征提取器

  • 定义:一种方法或算法,用于从原始数据中提取有意义的特征。
    • 例子
      • 从文本中提取关键词。
      • 从图像中提取边缘或纹理特征(如 HOG 特征)。

目标

  • 定义:机器学习模型试图预测的值。
    • 例子
      • 分类问题中的类别(例如,猫或狗)。
      • 回归问题中的数值(例如,房价)。

偏差、方差

  • 偏差:模型预测值与真实值之间的平均差距,表示模型的拟合能力。高偏差可能导致欠拟合。
  • 方差:模型对训练数据中噪声的敏感程度。高方差可能导致过拟合。
    • 例子
      • 偏差高的模型可能会忽略数据中的重要模式。
      • 方差高的模型可能会记住训练数据中的噪声。

维度

  • 定义:特征的数量。每个特征可以被看作数据的一个维度。
    • 例子
      • 如果一个样本有 3 个特征(年龄、身高、体重),则数据是 3 维的。

早停法

  • 定义:一种正则化技术,当验证集的性能不再提升时提前终止训练,以防止过拟合。
    • 作用:通过停止训练,避免模型过度学习训练数据。

评估度量

  • 定义:用来衡量模型性能的指标。
    • 分类问题:准确率、召回率、F1 分数。
    • 回归问题:均方误差 (MSE)、平均绝对误差 (MAE)。

拟合

  • 定义:训练模型使其学习数据模式的过程。
    • 过拟合:模型学习了训练数据中的噪声。
    • 欠拟合:模型未能充分学习数据模式。

填充算法

  • 定义:处理缺失数据的算法。
    • 例子:用均值、中位数或众数填充缺失值。

数据泄漏

  • 定义:训练数据中包含了测试数据的信息,导致模型性能虚高。
    • 例子:将目标变量作为特征的一部分。

有监督学习

  • 定义:使用带标签的数据进行训练。
    • 例子:预测房价,数据包含历史房价(标签)。

半监督学习

  • 定义:使用少量带标签数据和大量未带标签数据进行训练。
    • 例子:网页分类,部分网页有类别标签,部分没有。

无监督学习

  • 定义:不使用标签数据,模型通过数据的结构进行学习。
    • 例子:聚类分析(如 K-Means)。

分类器

  • 定义:将输入数据分到特定类别的模型。
    • 例子:支持向量机(SVM)、决策树。

聚类器

  • 定义:将数据分组为若干簇的算法。
    • 例子:K-Means、层次聚类。

离群点检测器

  • 定义:检测数据中的异常点。
    • 例子:银行系统检测信用卡欺诈。

交叉验证生成器

  • 定义:生成交叉验证的训练集和验证集。
    • 作用:确保模型性能的评估更加稳定。

损失函数

  • 定义:衡量模型预测值和真实值之间差异的函数。
    • 例子:均方误差 (MSE)、交叉熵损失。

梯度下降

  • 定义:一种优化算法,通过最小化损失函数找到模型的最佳参数。
    • 变种
      • 批量梯度下降:使用整个数据集计算梯度。
      • 随机梯度下降 (SGD):每次只用一个样本更新梯度。

正则化

  • 定义:防止模型过拟合的一种方法,通过限制模型的复杂度。
    • 例子:L1 正则化(Lasso)、L2 正则化(Ridge)。

泛化

  • 定义:模型在未见过的数据上的表现能力。
    • 良好的泛化能力:模型在训练集和测试集上都能表现良好。

学习曲线

  • 定义:显示模型性能随训练数据量变化的曲线。
    • 作用:帮助诊断过拟合或欠拟合。

召回率

  • 定义:模型正确识别出所有正例的比例。
    • 公式:召回率 = 真正例 / (真正例 + 假反例)

准确率

  • 定义:模型预测正确的样本占总样本的比例。
    • 公式:准确率 = (真正例 + 真反例) / 总样本数

机器学习库scikit-learn简介

# datasets -包含加载常用数据集的函数和生成随机数据的函数

线性回归算法原理与应用

1.简单线性回归(预测儿童身高)

import copy
import numpy as np
from sklearn import linear_model# 训练数据,每一行表示一个样本,包含的信息分别为:
# 儿童年龄,性别(0女1男)
# 父亲、母亲、祖父、祖母、外祖父、外祖母的身高
x = np.array([[1, 0, 180, 165, 175, 165, 170, 165],[3, 0, 180, 165, 175, 165, 173, 165],[4, 0, 180, 165, 175, 165, 170, 165],[6, 0, 180, 165, 175, 165, 170, 165],[8, 1, 180, 165, 175, 167, 170, 165],[10, 0, 180, 166, 175, 165, 170, 165],[11, 0, 180, 165, 175, 165, 170, 165],[12, 0, 180, 165, 175, 165, 170, 165],[13, 1, 180, 165, 175, 165, 170, 165],[14, 0, 180, 165, 175, 165, 170, 165],[17, 0, 170, 165, 175, 165, 170, 165]])# 儿童身高,单位:cm
y = np.array([60, 90, 100, 110, 130, 140, 150, 164, 160, 163, 168])
# 创建线性回归模型
lr = linear_model.LinearRegression()
# 根据已知数据拟合最佳直线
lr.fit(x, y)# 待测的未知数据,其中每个分量的含义和训练数据相同
xs = np.array([[10, 0, 180, 165, 175, 165, 170, 165],[17, 1, 173, 153, 175, 161, 170, 161],[34, 0, 170, 165, 170, 165, 170, 165]])for item in xs:# 为不改变原始数据,进行深复制,并假设超过18岁以后就不再长高了# 对于18岁以后的年龄,返回18岁时的身高item1 = copy.deepcopy(item)if item1[0] > 18:item1[0] = 18print(item, ':', lr.predict(item1.reshape(1,-1)))
[ 10   0 180 165 175 165 170 165] : [140.56153846]
[ 17   1 173 153 175 161 170 161] : [158.41]
[ 34   0 170 165 170 165 170 165] : [176.03076923]

2.岭回归

from sklearn.datasets import load_breast_cancer
from sklearn.linear_model import RidgeClassifier
from sklearn.model_selection import train_test_split# 加载乳腺癌数据,共569个样本,每个样本有30个特征
X, y = load_breast_cancer(return_X_y=True)
# 使用默认参数创建岭回归分类器对象
clf = RidgeClassifier()
# 划分训练集与测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
# 使用训练集拟合模型
clf.fit(X_train, y_train)
# 使用测试集,评估模型得分
print(clf.score(X_test, y_test))
0.9649122807017544

3.Lasso回归

from time import time
from scipy.sparse import coo_matrix
from sklearn.datasets import make_regression
from sklearn.linear_model import LassoX, y = make_regression(n_samples=1000, n_features=8000,  # 样本数量,特征数量n_informative=20,                 # 实际有效的特征数量noise=0.9,                        # 高斯噪声的标准差random_state=20230409,            # 使得每次运行结果相同)
# 把部分数据置0,使数据稀疏
X[X<2] = 0
# 创建压缩稀疏列格式的矩阵,可以使用toarray()转换为稠密格式的数组
X_sparse = coo_matrix(X).tocsc()
# 查看压缩比,nnz属性的值为稀疏矩阵实际保存的数据个数
print(f'压缩后数据量变为原来的:{X_sparse.nnz/X.size:.3%}')# 创建套索回归对象,参数alpha的值越大,选择的特征数量越少
estimator = Lasso(alpha=3, fit_intercept=False, max_iter=10000)
# 使用原始数据拟合模型,记录所用时间以及训练后的模型参数
start = time()
estimator.fit(X, y)
print(f'原始稠密数据训练用时:{time()-start}秒')
coef_dense = estimator.coef_# 使用稀疏矩阵格式的数据重新拟合模型,记录所用时间以及训练后的模型参数
start = time()
estimator.fit(X_sparse, y)
print(f'稀疏矩阵格式的数据训练用时:{time()-start}秒')
coef_sparse = estimator.coef_print(f'两种格式的数据训练后模型参数之差的最大值为:{(coef_sparse-coef_dense).max()}')
压缩后数据量变为原来的:2.271%
原始稠密数据训练用时:0.8571333885192871秒
稀疏矩阵格式的数据训练用时:0.21027755737304688秒
两种格式的数据训练后模型参数之差的最大值为:7.72715225139109e-14

逻辑回归算法基本原理与应用

使用logistic回归预测考试是否及格

from sklearn.linear_model import LogisticRegression# 复习情况,格式为(时长,效率),其中时长等位为小时
X_train = [(1, 0),(3, 0.5),(4, 0.5),(6, 0.5),(8, 1),(10, 1),(11, 1),(12, 1),(13, 1),(14, 1),(17, 1)]
y_train = [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1]# 创建逻辑回归模型
reg = LogisticRegression()
# 拟合模型
reg.fit(X_train, y_train)# 测试数据
X_test = [(3,0.5) ,(8,1) ,(9,1) ,(10,0)]
y_test = [0, 1, 1, 0]
score = reg.score(X_test, y_test)print("模型的准确率为:", score)# 预测
learning = [(8.5,0.5)]
result = reg.predict_proba(learning)
msg = '''模型得分为:{0}
复习时长为:{1[0]}小时,效率为:{1[1]}
预测为及格的概率为:{2[1]}
预测为不及格的概率为:{2[0]}
及格的概率为:{2[1]}
综合判断,您会:{3}'''.format(score, learning[0], result[0], "不及格" if result[0][0] > 0.5 else "及格")
print(msg)# 使用递归算法寻找最优参数得出最小复习时长可以及格
def find_min_study_time(current_hours, efficiency, model, increment=0.1, max_hours=24.0):"""使用递归算法寻找在给定效率下,能够及格的最小复习时长。:param current_hours: 当前尝试的复习时长:param efficiency: 复习效率 (0到1之间):param model: 训练好的逻辑回归模型:param increment: 每次递归增加的时长:param max_hours: 允许尝试的最大复习时长:return: 最小及格复习时长,如果超过max_hours仍未及格则返回None"""if current_hours > max_hours:return None  # 超过最大时长限制,未找到test_data = [(current_hours, efficiency)]pass_probability = model.predict_proba(test_data)[0][1]  # 获取及格的概率if pass_probability > 0.5:return current_hours  # 找到最小及格时长else:# 递归调用,增加时长return find_min_study_time(current_hours + increment, efficiency, model, increment, max_hours)# 示例:寻找效率为0.5时的最小及格复习时长
efficiency_to_test = 0.5
initial_hours = 0.1 # 从一个较小的初始时长开始
min_time_eff_0_5 = find_min_study_time(initial_hours, efficiency_to_test, reg)if min_time_eff_0_5 is not None:print(f"\n在效率为 {efficiency_to_test} 时,预测的最小及格复习时长为: {min_time_eff_0_5:.1f} 小时")# 验证一下这个时长prob_eff_0_5 = reg.predict_proba([(min_time_eff_0_5, efficiency_to_test)])[0]print(f"  - 对应及格概率: {prob_eff_0_5[1]:.4f}, 不及格概率: {prob_eff_0_5[0]:.4f}")
else:print(f"\n在效率为 {efficiency_to_test} 时,在 {max_hours} 小时内未能找到及格的复习时长。")# 示例:寻找效率为1.0时的最小及格复习时长
efficiency_to_test_2 = 1.0
min_time_eff_1_0 = find_min_study_time(initial_hours, efficiency_to_test_2, reg)if min_time_eff_1_0 is not None:print(f"\n在效率为 {efficiency_to_test_2} 时,预测的最小及格复习时长为: {min_time_eff_1_0:.1f} 小时")# 验证一下这个时长prob_eff_1_0 = reg.predict_proba([(min_time_eff_1_0, efficiency_to_test_2)])[0]print(f"  - 对应及格概率: {prob_eff_1_0[1]:.4f}, 不及格概率: {prob_eff_1_0[0]:.4f}")
else:print(f"\n在效率为 {efficiency_to_test_2} 时,在 {max_hours} 小时内未能找到及格的复习时长。")# 以上代码实现了一个简单的逻辑回归模型来预测复习情况,并使用递归算法寻找在给定效率下,能够及格的最小复习时长。
模型的准确率为: 0.75
模型得分为:0.75
复习时长为:8.5小时,效率为:0.5
预测为及格的概率为:0.8134531096860228
预测为不及格的概率为:0.1865468903139772
及格的概率为:0.8134531096860228
综合判断,您会:及格在效率为 0.5 时,预测的最小及格复习时长为: 7.1 小时- 对应及格概率: 0.5183, 不及格概率: 0.4817在效率为 1.0 时,预测的最小及格复习时长为: 7.0 小时- 对应及格概率: 0.5141, 不及格概率: 0.4859

8.5朴素贝叶斯算法原理与应用(中文邮件分类)

import numpy as np
x= np.array([[-1,-1],[-2,-1],[-3,-2],[1,1],[2,1],[3,2]])
y=np.array([1,1,1, 2,2, 2])
from sklearn.naive_bayes import GaussianNB
clf = GaussianNB()#创建高斯朴素贝叶斯模型
clf.fit(x,y)#训练模型
GaussianNB(priors=None)
clf.predict([[-0.8,-1]])
array([1])
# 分类
clf.predict_proba([[-0.8,-1]])#样本属于不同类别的概率
clf.score([[-0.8, -1]],[1])
1.0
# 评分
clf.score([[-0.8, -1],[0, 0]],[1, 2]) # 评分
0.5

重要:中文邮件分类

  • 对文件夹贝叶斯中文邮件分类中的份邮件的文本内容进行训练,其中0.txt 到 126.txt 为垃圾邮件,127.txt 到 253.txt 为正常邮件,模型训练结束后使用 5 封邮件 (151.txt 到 155.txt)的文本内容进行测试,判断这 5 封邮件是否为垃圾邮件。
from re import sub
from os import listdir
from collections import Counter
from itertools import chain
from numpy import array
from jieba import cut
from sklearn.naive_bayes import MultinomialNBdef getWordsFromFile(txtFile):# 获取每一封邮件中的所有词语words = []# 所有存储邮件文本内容的记事本文件都使用UTF8编码with open(txtFile, encoding='utf8') as fp:for line in fp:# 遍历每一行,删除两端的空白字符line = line.strip()# 过滤干扰字符或无效字符line = sub(r'[.【】0-9、—。,!~\*]', '', line)# 分词line = cut(line)# 过滤长度为1的词line = filter(lambda word: len(word)>1, line)# 把本行文本预处理得到的词语添加到words列表中words.extend(line)# 返回包含当前邮件文本中所有有效词语的列表return words# 存放所有文件中的单词
# 每个元素是一个子列表,其中存放一个文件中的所有单词
allWords = []
def getTopNWords(topN):# 按文件编号顺序处理当前文件夹中所有记事本文件# 训练集中共151封邮件内容,0.txt到126.txt是垃圾邮件内容# 127.txt到150.txt为正常邮件内容txtFiles = [str(i)+'.txt' for i in range(151)]# 获取训练集中所有邮件中的全部单词for txtFile in txtFiles:allWords.append(getWordsFromFile(txtFile))# 获取并返回出现次数最多的前topN个单词freq = Counter(chain(*allWords))return [w[0] for w in freq.most_common(topN)]# 全部训练集中出现次数最多的前600个单词
topWords = getTopNWords(600)# 获取特征向量,前600个单词的每个单词在每个邮件中出现的频率
vectors = []
for words in allWords:temp = list(map(lambda x: words.count(x), topWords))vectors.append(temp)
vectors = array(vectors)
# 训练集中每个邮件的标签,1表示垃圾邮件,0表示正常邮件
labels = array([1]*127 + [0]*24)# 创建模型,使用已知训练集进行训练
model = MultinomialNB()
model.fit(vectors, labels)def predict(txtFile):# 获取指定邮件文件内容,返回分类结果words = getWordsFromFile(txtFile)currentVector = array(tuple(map(lambda x: words.count(x),topWords)))result = model.predict(currentVector.reshape(1, -1))[0]return '垃圾邮件' if result==1 else '正常邮件'# 151.txt至155.txt为测试邮件内容
for mail in ('%d.txt'%i for i in range(151, 156)):print(mail, predict(mail), sep=':')
151.txt:垃圾邮件
152.txt:垃圾邮件
153.txt:垃圾邮件
154.txt:垃圾邮件
155.txt:正常邮件

方式二:训练模型进行保存,格式化存储,直接调用函数进行训练识别

from re import sub
from jieba import cutdef getWordsFromFile(txtFile):# 获取每一封邮件中的所有词语words = []# 所有存储邮件文本内容的记事本文件都使用UTF8编码with open(txtFile, encoding='utf8') as fp:for line in fp:# 遍历每一行,删除两端的空白字符line = line.strip()# 过滤干扰字符或无效字符line = sub(r'[.【】0-9、—。,!~\*]', '', line)# 分词line = cut(line)# 过滤长度为1的词line = filter(lambda word: len(word)>1, line)# 把本行文本预处理得到的词语添加到words列表中words.extend(line)# 返回包含当前邮件文本中所有有效词语的列表return words
from os import listdir
from collections import Counter
from itertools import chain
from numpy import array
from sklearn.externals import joblib
from sklearn.naive_bayes import MultinomialNB
from get_words_from_file import getWordsFromFile# 存放所有文件中的单词
# 每个元素是一个子列表,其中存放一个文件中的所有单词
allWords = []
def getTopNWords(topN):# 按文件编号顺序处理当前文件夹中所有记事本文件# 训练集中共151封邮件内容,0.txt到126.txt是垃圾邮件内容# 127.txt到150.txt为正常邮件内容txtFiles = [str(i)+'.txt' for i in range(151)]# 获取训练集中所有邮件中的全部单词for txtFile in txtFiles:allWords.append(getWordsFromFile(txtFile))# 获取并返回出现次数最多的前topN个单词freq = Counter(chain(*allWords))return [w[0] for w in freq.most_common(topN)]# 全部训练集中出现次数最多的前600个单词
topWords = getTopNWords(600)# 获取特征向量,前600个单词的每个单词在每个邮件中出现的频率
vectors = []
for words in allWords:temp = list(map(lambda x: words.count(x), topWords))vectors.append(temp)
vectors = array(vectors)
# 训练集中每个邮件的标签,1表示垃圾邮件,0表示正常邮件
labels = array([1]*127 + [0]*24)# 创建模型,使用已知训练集进行训练
model = MultinomialNB()
model.fit(vectors, labels)joblib.dump(model, "垃圾邮件分类器.pkl")
print('保存模型和训练结果成功。')
with open('topWords.txt', 'w', encoding='utf8') as fp:fp.write(','.join(topWords))
print('保存topWords成功。')
from numpy import array
from sklearn.externals import joblib
from sklearn.naive_bayes import MultinomialNB
from get_words_from_file import getWordsFromFilemodel = joblib.load("垃圾邮件分类器.pkl")
print('加载模型和训练结果成功。')
with open('topWords.txt', encoding='utf8') as fp:topWords = fp.read().split(',')def predict(txtFile):# 获取指定邮件文件内容,返回分类结果words = getWordsFromFile(txtFile)currentVector = array(tuple(map(lambda x: words.count(x),topWords)))result = model.predict(currentVector.reshape(1, -1))[0]return '垃圾邮件' if result==1 else '正常邮件'# 151.txt至155.txt为测试邮件内容
for mail in ('%d.txt'%i for i in range(151, 156)):print(mail, predict(mail), sep=':')
151.txt:垃圾邮件
152.txt:垃圾邮件
153.txt:垃圾邮件
154.txt:垃圾邮件
155.txt:正常邮件

8.6决策树与随机森林算法原理与应用

基尼值 G i n i = 1 − ∑ i = 1 n P i 2 Gini=1-\sum_{i=1}^{n}P_i^{2} Gini=1i=1nPi2(考点)

使用python决策树算法实现学员的python水平

import numpy as np
from sklearn import treequestions = ('《Python程序设计与数据采集》','《Python数据分析、挖掘与可视化》','《Python程序设计基础(第3版)》','《Python程序设计基础与应用(第2版)》','《Python程序设计实例教程(第2版)》','《Python程序设计(第3版)》', '《Python网络程序设计》','《Python数据分析与数据可视化》','《大数据的Python基础(第2版)》','《Python程序设计开发宝典》','《Python可以这样学》', '《中学生可以这样学Python》','《Python编程基础与案例集锦(中学版)》','《Python程序设计实验指导书》','《Python程序设计入门与实践》','《Python程序设计实用教程》','微信公众号“Python小屋”的免费资料')
# 每个样本的数据含义:0没看过,1很多看不懂,2大部分可以看懂,3没压力
answers = [[3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3],[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],[1, 0, 2, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 2, 2, 2, 1],[2, 2, 3, 3, 3, 1, 1, 1, 3, 2, 2, 3, 3, 3, 0, 3, 2],[2, 2, 3, 2, 2, 1, 1, 3, 1, 2, 2, 3, 3, 2, 2, 2, 1],[3, 3, 3, 0, 3, 2, 2, 3, 3, 2, 3, 3, 3, 3, 3, 3, 2],[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3],[0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],[2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]]
labels = ['超级高手', '门外汉', '初级选手', '初级选手', '高级选手','中级选手', '高级选手', '超级高手', '初级选手', '初级选手']clf = tree.DecisionTreeClassifier().fit(answers, labels) # 训练yourAnswer = []
print('在下面的问卷中,''没看过输入0,很多看不懂输入1,大部分可以看懂输入2,没压力输入3')
# 显示调查问卷,并接收用户输入
for question in questions:print('=========\n你看过董付国老师的', question, '吗?')# 确保输入有效while True:try:answer = int(input('请输入:'))assert 0<=answer<=3breakexcept:print('输入无效,请重新输入。')passyourAnswer.append(answer)print(clf.predict(np.array(yourAnswer).reshape(1,-1)))   # 分类
在下面的问卷中,没看过输入0,很多看不懂输入1,大部分可以看懂输入2,没压力输入3
=========
你看过董付国老师的 《Python程序设计与数据采集》 吗?
请输入: 1
=========
你看过董付国老师的 《Python数据分析、挖掘与可视化》 吗?
请输入: 1
=========
你看过董付国老师的 《Python程序设计基础(第3版)》 吗?
请输入: 1
=========
你看过董付国老师的 《Python程序设计基础与应用(第2版)》 吗?
请输入: 1
=========
你看过董付国老师的 《Python程序设计实例教程(第2版)》 吗?
请输入: 1
=========
你看过董付国老师的 《Python程序设计(第3版)》 吗?
请输入: 1
=========
你看过董付国老师的 《Python网络程序设计》 吗?
请输入: 1
=========
你看过董付国老师的 《Python数据分析与数据可视化》 吗?
请输入: 1
=========
你看过董付国老师的 《大数据的Python基础(第2版)》 吗?
请输入: 1
=========
你看过董付国老师的 《Python程序设计开发宝典》 吗?
请输入: 1
=========
你看过董付国老师的 《Python可以这样学》 吗?
请输入: 1
=========
你看过董付国老师的 《中学生可以这样学Python》 吗?
请输入: 1
=========
你看过董付国老师的 《Python编程基础与案例集锦(中学版)》 吗?
请输入: 1
=========
你看过董付国老师的 《Python程序设计实验指导书》 吗?
请输入: 1
=========
你看过董付国老师的 《Python程序设计入门与实践》 吗?
请输入: 1
=========
你看过董付国老师的 《Python程序设计实用教程》 吗?
请输入: 1
=========
你看过董付国老师的 微信公众号“Python小屋”的免费资料 吗?
请输入: 1
['初级选手']

支持向量机(实现手写文子数字图像分类)

'''
from os import mkdir, listdir
from os.path import isdir, basename
from random import choice, randrange
from string import digits
from PIL import Image, ImageDraw   # pillow
from PIL.ImageFont import truetype
from sklearn import svm
from sklearn.model_selection import train_test_split# 图像尺寸、图片中的数字字体大小、噪点比例
width, height = 30, 60
fontSize = 40
noiseRate = 8def generateDigits(dstDir='datasets1', num=400):# 生成num个包含数字的图片文件存放于当前目录下的datasets子目录if not isdir(dstDir):mkdir(dstDir)# digits.txt用来存储每个图片对应的数字with open(dstDir+'/digits.txt', 'w') as fp:font = truetype('SimHei.ttf',fontSize)for i in range(num):# 随机选择一个数字,生成对应的彩色图像文件digit = choice(digits)im = Image.new('RGB', (width,height), (255,255,255))imDraw = ImageDraw.Draw(im)imDraw.text((0,0), digit, font=font, fill=(0,0,0))# 加入随机干扰for j in range(int(noiseRate*width*height)):w, h = randrange(1, width-1), randrange(height)# 水平交换两个相邻像素的颜色c1 = im.getpixel((w,h))c2 = im.getpixel((w+1,h))                imDraw.point((w,h), fill=c2)imDraw.point((w+1,h), fill=c1)im.save(dstDir+'/'+str(i)+'.jpg')fp.write(digit+'\n')def loadDigits(dstDir='datasets1'):# 获取所有图像文件名digitsFile = [dstDir+'/'+fn for fn in listdir(dstDir)if fn.endswith('.jpg')]# 按编号排序,1.jpg,10.jpg,100.jpgdigitsFile.sort(key=lambda fn: int(basename(fn)[:-4]))# digitsData用于存放读取的图片中数字信息# 每个图片中所有像素值存放于digitsData中的一行数据digitsData = []for fn in digitsFile:with Image.open(fn) as im:data = [sum(im.getpixel((w,h)))/len(im.getpixel((w,h)))for w in range(width)for h in range(height)]digitsData.append(data)# digitsLabel用于存放图片中数字的标准分类with open(dstDir+'/digits.txt') as fp:digitsLabel = fp.readlines()# digitsLabel = [label.strip() for label in digitsLabel]digitsLabel = list(map(str.strip, digitsLabel))return (digitsData, digitsLabel)# 生成图片文件
generateDigits(num=100)
# 加载数据
data = loadDigits()
print('数据加载完成。')# 随机划分训练集和测试集,其中参数test_size用来指定测试集大小
X_train, X_test, y_train, y_test = train_test_split(data[0],data[1],test_size=0.1)
# 创建并训练模型
svcClassifier = svm.SVC(kernel="linear", C=1000, gamma=0.001)
svcClassifier.fit(X_train, y_train)
print('模型训练完成。')# 使用测试集对模型进行评分
score = svcClassifier.score(X_test, y_test)
print('模型测试得分:', score)
'''

KNN算法原理与应用

使用KNN判断交通工具类型

from sklearn.neighbors import KNeighborsClassifier# X中存储交通工具的参数
# 总长度(米)、时速(km/h)、重量(吨)、座位数量
X = [[96, 85, 120, 400],        # 普通火车[144, 92, 200, 600],[240, 87, 350, 1000],[360, 90, 495, 1300],[384, 91, 530, 1405],[240, 360, 490, 800],      # 高铁[360, 380, 750, 1200],[290, 380, 480, 960],[120, 320, 160, 400],[384, 340, 520, 1280],[33.4, 918, 77, 180],      # 飞机[33.6, 1120, 170.5, 185],[39.5, 785, 230, 240],[33.84, 940, 150, 195],[44.5, 920, 275, 275],[75.3, 1050, 575, 490]]
# y中存储类别,0表示普通火车,1表示高铁,2表示飞机
y = [0]*5+[1]*5+[2]*6
# labels中存储对应的交通工具名称
labels = ('普通火车', '高铁', '飞机')# 创建并训练模型
knn = KNeighborsClassifier(n_neighbors=3,weights='distance')
knn.fit(X, y)# 对未知样本进行分类
unKnown = [[300, 79, 320, 900],[36.7, 800, 190, 220]]
result = knn.predict(unKnown)
for para, index in zip(unKnown, result):print(para, labels[index], sep=':')
[300, 79, 320, 900]:普通火车
[36.7, 800, 190, 220]:飞机

KMeans聚类分析算法原理与应用

颜色图像处理

import numpy as np
from sklearn.cluster import KMeans
from PIL import Image
import matplotlib.pyplot as plt
from copy import deepcopy# 打开并读取原始图像中像素颜色值,转换为三维数组
imOrigin = Image.open('颜色压缩测试图像.jpg')
dataOrigin = np.array(imOrigin)
# 然后再转换为二维数组,-1表示自动计算该维度的大小
data = dataOrigin.reshape(-1,3)n_clusters = 64
while n_clusters >= 4:plt.cla()print(n_clusters)    # 使用KMeans算法把所有像素的颜色值划分为4类kmeansPredicter = KMeans(n_clusters=n_clusters)kmeansPredicter.fit(data)# 使用每个像素所属类的中心值替换该像素的颜色# temp中存放每个数据所属类的标签temp = kmeansPredicter.labels_dataNew = kmeansPredicter.cluster_centers_[temp]data = deepcopy(dataNew)dataNew = np.uint8(dataNew)    dataNew.shape = dataOrigin.shapeplt.imshow(dataNew)plt.pause(0.01)n_clusters //= 2

KMeans聚类算法压缩图像颜色

import numpy as np
from sklearn.cluster import KMeans
from PIL import Image
import matplotlib.pyplot as plt# 打开并读取原始图像中像素颜色值,转换为三维数组
imOrigin = Image.open('颜色压缩测试图像.jpg')
dataOrigin = np.array(imOrigin)
# 然后再转换为二维数组,-1表示自动计算该维度的大小
data = dataOrigin.reshape(-1,3)# 使用KMeans算法把所有像素的颜色值划分为4类
kmeansPredicter = KMeans(n_clusters=4, n_init=10)
kmeansPredicter.fit(data)# 使用每个像素所属类的中心值替换该像素的颜色
# temp中存放每个数据所属类的标签
temp = kmeansPredicter.labels_
dataNew = kmeansPredicter.cluster_centers_[temp]
dataNew = np.uint8(dataNew)
dataNew.shape = dataOrigin.shape
plt.imshow(dataNew)
plt.imsave('结果图像.jpg', dataNew)
plt.show()

分层聚类算法原理与应用

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from sklearn.cluster import AgglomerativeClusteringdef AgglomerativeTest(n_clusters):assert 1 <= n_clusters <= 4predictResult = AgglomerativeClustering(n_clusters=n_clusters,linkage='ward').fit_predict(data)# 定义绘制散点图时使用的颜色和散点符号colors = 'rgby'markers = 'o*v+'# 依次使用不同的颜色和符号绘制每个类的散点图for i in range(n_clusters):subData = data[predictResult==i]plt.scatter(subData[:,0], subData[:,1], c=colors[i], marker=markers[i], s=40)plt.show()# 生成随机数据,200个点,分成4类,返回样本及标签
data, labels = make_blobs(n_samples=200, centers=4)
print(data)
AgglomerativeTest(4)

DBSCAN算法原理与应用

  • 基于密度相连对象的最大集合
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import DBSCAN
from sklearn.datasets import make_blobsdef DBSCANtest(data, eps=0.6, min_samples=8):# 聚类db = DBSCAN(eps=eps, min_samples=min_samples).fit(data)# 聚类标签(数组,表示每个样本所属聚类)和所有聚类的数量# 标签-1对应的样本表示噪点clusterLabels = db.labels_uniqueClusterLabels = set(clusterLabels)# 标记核心对象对应下标为TruecoreSamplesMask = np.zeros_like(db.labels_, dtype=bool)coreSamplesMask[db.core_sample_indices_] = True# 绘制聚类结果colors = ['red', 'green', 'blue', 'gray', '#88ff66','#ff00ff', '#ffff00', '#8888ff', 'black',]markers = ['v', '^', 'o', '*', 'h', 'd', 'D', '>', 'x']for label in uniqueClusterLabels:# 使用最后一种颜色和符号绘制噪声样本# clusterIndex是个True/False数组# 其中True表示对应样本为cluster类clusterIndex = (clusterLabels==label)# 绘制核心对象coreSamples = data[clusterIndex&coreSamplesMask]plt.scatter(coreSamples[:, 0], coreSamples[:, 1],c=colors[label], marker=markers[label],s=100)# 绘制非核心对象nonCoreSamples = data[clusterIndex & ~coreSamplesMask]plt.scatter(nonCoreSamples[:, 0], nonCoreSamples[:, 1],c=colors[label], marker=markers[label],s=20)plt.show()data, labels = make_blobs(n_samples=300, centers=5)
DBSCANtest(data)
#DBSCANtest(data, 0.8, 15)

协同过滤算法进行电影推荐(期末考试重点)

  • 协同过滤算法常用于商品推荐或者类似的场合,根据用户之间或商品之间的相似性进行精准推荐,可以分为基于用户的协同过滤算法和基于商品的协同过滤算法。
  • 以电影推荐为例,假设用户1喜欢看电影A、B、C、D、G,用户2喜欢看电影A、D、E、F,用户3喜欢看电影A、B、D,现在用户3想再看个没看过的电影,向用户1和用户2寻求推荐。简单分析易知,与用户2相比,用户1和用户3更相似,所以根据用户1喜欢的电影进行推荐,也就是用户1看过但用户3还没看过的电影C或G。

协同过滤算法是推荐系统中最常用的方法之一,以下是对您描述内容的进一步整理和分析:


协同过滤算法的基本概念

  • 协同过滤算法的核心思想是利用用户或商品之间的相似性,推荐用户可能感兴趣的内容。
  • 分类
    1. 基于用户的协同过滤:根据用户之间的相似性推荐商品。
    2. 基于商品的协同过滤:根据商品之间的相似性推荐商品。

以电影推荐为例

数据:
  • 用户1看过:A、B、C、D、G
  • 用户2看过:A、D、E、F
  • 用户3看过:A、B、D
  • 目标:为用户3推荐一部电影。
分析:
  1. 计算用户相似性

    • 用户3与用户1的共有电影:A、B、D,共3部。
    • 用户3与用户2的共有电影:A、D,共2部。
    • 结论:用户3与用户1更相似。
  2. 推荐过程

    • 找出用户1看过但用户3没看过的电影:C、G。
    • 推荐结果:C 或 G。

协同过滤算法的步骤

1. 数据表示

构建用户-商品偏好矩阵。例如:

        A   B   C   D   E   F   G
用户1    1   1   1   1   0   0   1
用户2    1   0   0   1   1   1   0
用户3    1   1   0   1   0   0   0

其中:

  • 1 表示用户看过某电影。
  • 0 表示用户没看过某电影。
2. 计算相似性
  • 使用相似性度量方法(如余弦相似度、皮尔逊相关系数)计算用户之间的相似性。
  • 例如,余弦相似度公式:

相似度 ( 用户 A , 用户 B ) = A和B的交集数 A的电影数 × B的电影数 \text{相似度}(用户A, 用户B) = \frac{\text{A和B的交集数}}{\sqrt{\text{A的电影数}} \times \sqrt{\text{B的电影数}}} 相似度(用户A,用户B)=A的电影数 ×B的电影数 AB的交集数

3. 推荐候选集
  • 找出与目标用户最相似的用户。
  • 从相似用户看过但目标用户未看过的商品中选择推荐。
4. 生成推荐
  • 对候选商品进行排序(例如根据相似用户的评分权重排序)。
  • 推荐排名靠前的商品。

优缺点

优点:
  • 简单易实现,推荐结果可解释性强。
  • 无需商品的具体内容信息,适用于各种类型的数据。
缺点:
  • 冷启动问题:对新用户或新商品,缺乏足够的数据支撑相似性计算。
  • 稀疏性问题:用户-商品矩阵通常非常稀疏,可能导致相似性难以计算准确。
  • 扩展性问题:随着用户和商品数量的增加,计算相似性可能变得非常耗时。

改进方向

  1. 结合内容信息:在协同过滤中加入商品的内容特征(如电影的类型、导演信息)。
  2. 矩阵分解:将用户-商品矩阵分解为低维的用户和商品向量,例如 SVD(奇异值分解)。
  3. 引入深度学习:使用神经网络建模用户和商品的关系,例如通过嵌入层学习用户和商品的隐式特征。

from random import randrange
#模拟历史电影打分数据,共10个用户,每个用户打分的电影数量不等
data = {'user'+str(i):{'film'+str(randrange(1, 15)):randrange(16)for j in range (randrange(310))}for i in range(10)}
# 寻求推荐的用户对电影打分的数据
user = {'film'+str (randrange (1, 15)):randrange (1, 6) for i in range (5)}
#最相似的用户及其对电影打分情况
#两个最相似的用户共同打分的电影最多,同时所有电影打分差值的平方和最小
rule = lambda item:(-len(item[1].keys ()&user)sum(((item[1].get(film) -user.get (film))**2for film in user.keys()&item[1].keys())))
similarUser, films = min(data.items (),key=rule)
#输出信息以便验证,每行数据有3列
#分别为该用户与当前用户共同打分的电影数量、打分差的平方和、该用户打分数据
print ('known data'.center(50,'='))
for item in data.items ():print (len(item[1].keys ()&user.keys())sum(((item[l].get(film) -user.get (film))**2for film in user.keys ()&item[l].keys())),item, sep=':')
print('current user'.center (50, '='),user, sep='ln')
print('most similar user and his films'.center (50, '='))
print(similarUser, films, sep=':')print ('recommended film'.center(50, '='))
#在当前用户没看过的电影中选择打分最高的进行推荐
print (max (films.keys ()-user.keys (), key=lanbda film: films[film]))

关联规则分析(期末考试重点)

常用概念:

  • 项集:包含若干物品或条目的集合。包含k的物品的集合称作k-项集。
  • 频繁项集:经常一起出现的物品的集合。如果某个项集是频繁的,那么它的所有子集都是频繁的;如果某个项集不是频繁的,那么它的所有超集都不是频繁的。这一点是避免页集数量过多的重要基础,使得快速计算频繁项集成为可能。
  • 关联规则:可以表示为一个蕴含式R:X==>Y,其中X&Y为空集。这样一条关联规则的含义是,如果X发生,那么Y很可能也会发生。

项集

  • 定义:项集是由若干物品(或条目)组成的集合。
  • k-项集:如果一个项集中包含 ( k ) 个物品,则称其为 ( k )-项集。
    • 例子:在购物篮分析中,{牛奶, 面包} 是一个 2-项集。

频繁项集

  • 定义:频繁项集是指在数据集中经常出现的项集,满足用户设定的最小支持度阈值。

    • 支持度:某个项集在数据集中出现的次数占总事务数的比例。
    • 例子:如果 {牛奶, 面包} 出现在 60% 的交易中,并且最小支持度设定为 50%,则该项集为频繁项集。
  • 性质

    1. 子集性质
      • 如果一个项集是频繁项集,则它的所有子集也是频繁项集。
    2. 剪枝性质
      • 如果一个项集不是频繁项集,则它的所有超集都不是频繁项集。
    • 作用:利用这些性质可以减少计算项集的数量,提高频繁项集挖掘的效率。

关联规则

  • 定义:关联规则是从频繁项集中挖掘出的规则,表示某些物品之间的关联关系。规则的形式为:
    R : X ⟹ Y R: X \implies Y R:XY

    • 解释:如果项集 ( X ) 发生,则 ( Y ) 很可能也会发生。
    • 例子:{牛奶} ⇒ {面包},表示购买牛奶的人很可能也会购买面包。
  • 指标

    1. 支持度 (Support)
    • 规则:
      

      X ⟹ Y X \implies Y XY的支持度是 X ∪ Y X \cup Y XY出现的概率。
      S u p p o r t ( X ⟹ Y ) = 事务中同时包含  X 和  Y 的置信度 X 发生时 Y 也发生的概率。 Support(X \implies Y )= \frac{\text{事务中同时包含 } X \text{ 和 } Y \text{的} 置信度 }{X 发生时 Y 也发生的概率。} Support(XY)=X发生时Y也发生的概率。事务中同时包含 X  Y置信度

      C o n f i d e n c e ( X ⟹ Y ) = 事务中同时包含  X 和  Y 的次数 事务表示 X 和 Y 是否独立。 Confidence(X \implies Y) = \frac{\text{事务中同时包含 } X \text{ 和 } Y \text{ 的次数}}{\text{事务表示 X 和 Y 是否独立。}} Confidence(XY)=事务表示 X  Y 是否独立。事务中同时包含 X  Y 的次数

      L i f t ( X ⟹ Y ) = C o n f i d e n c e ( X ⟹ Y ) S u p p o r t ( Y ) Lift(X \implies Y) = \frac{Confidence(X \implies Y)}{Support(Y)} Lift(XY)=Support(Y)Confidence(XY)

  • 例子

    • 给定事务数据:
      T1: {牛奶, 面包, 黄油}
      T2: {牛奶, 面包}
      T3: {牛奶, 黄油}
      T4: {面包, 黄油}
      
    • 规则 {牛奶} ⇒ {面包}:
      • 支持度:2/4 = 50%
      • 置信度:2/3 ≈ 66.7%

总结

  • 项集:物品的集合,包含 ( k ) 个物品的集合称为 ( k )-项集。
  • 频繁项集:满足最小支持度阈值,且具有子集和超集性质。
  • 关联规则:从频繁项集中挖掘的规则,描述物品之间的关联性,通常通过支持度、置信度和提升度来衡量规则的质量。

代码实现(例如 Apriori 或 FP-Growth 算法)

import pandas as pd
# 使用关联规则算法分析演员关系
ws = pd.read_excel('电影导演演员.xlsx')
print(ws.head())
  电影名称   导演               演员
0  电影1  导演1  演员1,演员2,演员3,演员4
1  电影2  导演2  演员3,演员2,演员4,演员5
2  电影3  导演3  演员1,演员5,演员3,演员6
3  电影4  导演1  演员1,演员4,演员3,演员7
4  电影5  导演2  演员1,演员2,演员3,演员8
from itertools import chain, combinations
from openpyxl import load_workbookdef loadDataSet():'''加载数据,返回包含若干集合的列表'''# 返回的数据格式为 [{1, 3, 4}, {2, 3, 5}, {1, 2, 3, 5}, {2, 5}]result = []# xlsx文件中有3列,分别为电影名称、导演名称、演员清单# 同一个电影的多个主演演员使用逗号分隔ws = load_workbook('电影导演演员.xlsx').worksheets[0]for index, row in enumerate(ws.rows):# 跳过第一行表头if index==0:continueresult.append(set(row[2].value.split(',')))return resultdef createC1(dataSet):'''dataSet为包含集合的列表,每个集合表示一个项集返回包含若干元组的列表,每个元组为只包含一个物品的项集,所有项集不重复'''return sorted(map(lambda i:(i,), set(chain(*dataSet))))def scanD(dataSet, Ck, Lk, minSupport):'''dataSet为包含集合的列表,每个集合表示一个项集ck为候选项集列表,每个元素为元组minSupport为最小支持度阈值返回Ck中支持度大于等于minSupport的那些项集'''# 数据集总数量total = len(dataSet)supportData = {}for candidate in Ck:# 加速,k-频繁项集的所有k-1子集都应该是频繁项集if Lk and (not all(map(lambda item: item in Lk,combinations(candidate,len(candidate)-1)))):continue# 遍历每个候选项集,统计该项集在所有数据集中出现的次数# 这里隐含了一个技巧:True在内部存储为1set_candidate = set(candidate)frequencies = sum(map(lambda item: set_candidate<=item,dataSet))# 计算支持度t = frequencies/total# 大于等于最小支持度,保留该项集及其支持度if t >= minSupport:supportData[candidate] = treturn supportDatadef aprioriGen(Lk, k):'''根据k项集生成k+1项集'''result = []for index, item1 in enumerate(Lk):for item2 in Lk[index+1:]:# 只合并前k-2项相同的项集,避免生成重复项集# 例如,(1,3)和(2,5)不会合并,# (2,3)和(2,5)会合并为(2,3,5),# (2,3)和(3,5)不会合并,# (2,3)、(2,5)、(3,5)只能得到一个项集(2,3,5)if sorted(item1[:k-2]) == sorted(item2[:k-2]):result.append(tuple(set(item1)|set(item2)))return resultdef apriori(dataSet, minSupport=0.5):'''根据给定数据集dataSet,返回所有支持度>=minSupport的频繁项集'''C1 = createC1(dataSet)supportData = scanD(dataSet, C1, None, minSupport)k = 2while True:# 获取满足最小支持度的k项集Lk = [key for key in supportData if len(key)==k-1]# 合并生成k+1项集Ck = aprioriGen(Lk, k)# 筛选满足最小支持度的k+1项集supK = scanD(dataSet, Ck, Lk, minSupport)# 无法再生成包含更多项的项集,算法结束if not supK:breaksupportData.update(supK)k = k+1return supportDatadef findRules(supportData, minConfidence=0.5):'''查找满足最小置信度的关联规则'''# 对频繁项集按长度降序排列supportDataL = sorted(supportData.items(),key=lambda item:len(item[0]),reverse=True)rules = []for index, pre in enumerate(supportDataL):for aft in supportDataL[index+1:]:# 只查找k-1项集到k项集的关联规则if len(aft[0]) < len(pre[0])-1:break# 当前项集aft[0]是pre[0]的子集# 且aft[0]==>pre[0]的置信度大于等于最小置信度阈值if set(aft[0])<set(pre[0]) and\pre[1]/aft[1]>=minConfidence:rules.append([pre[0],aft[0]])return rules# 加载数据
dataSet = loadDataSet()
# 获取所有支持度大于0.2的项集
supportData = apriori(dataSet, 0.2)
# 在所有频繁项集中查找并输出关系较好的演员二人组合
bestPair = [item for item in supportData if len(item)==2]
print(bestPair)# 查找支持度大于0.6的强关联规则
for item in findRules(supportData, 0.6):pre, aft = map(set, item)print(aft, pre-aft, sep='==>')
[('演员1', '演员3'), ('演员1', '演员4'), ('演员3', '演员4'), ('演员3', '演员5'), ('演员4', '演员9')]
{'演员1', '演员4'}==>{'演员3'}
{'演员1'}==>{'演员3'}
{'演员1'}==>{'演员4'}
{'演员3'}==>{'演员4'}
{'演员4'}==>{'演员3'}
{'演员5'}==>{'演员3'}
{'演员9'}==>{'演员4'}

数据降维

交叉验证、网格搜索、学习曲线

1.评估模型的泛化能力

from time import time
from os import listdir
from os.path import basename
from PIL import Image
from sklearn import svm
from sklearn.model_selection import cross_val_score,\ShuffleSplit, LeaveOneOut# 图像尺寸
width, height = 30, 60def loadDigits(dstDir='datasets'):# 获取所有图像文件名digitsFile = [dstDir+'/'+fn for fn in listdir(dstDir)if fn.endswith('.jpg')]# 按编号排序digitsFile.sort(key=lambda fn: int(basename(fn)[:-4]))# digitsData用于存放读取的图片中数字信息# 每个图片中所有像素值存放于digitsData中的一行数据digitsData = []for fn in digitsFile:with Image.open(fn) as im:data = [sum(im.getpixel((w,h)))/len(im.getpixel((w,h)))for w in range(width)for h in range(height)]digitsData.append(data)# digitsLabel用于存放图片中数字的标准分类with open(dstDir+'/digits.txt') as fp:digitsLabel = fp.readlines()digitsLabel = [label.strip() for label in digitsLabel]return (digitsData, digitsLabel)# 加载数据
data = loadDigits()
print('数据加载完成。')# 创建模型
svcClassifier = svm.SVC(kernel="linear", C=1000, gamma=0.001)# 交叉验证
start = time()
scores = cross_val_score(svcClassifier, data[0], data[1], cv=8)
print('交叉验证(k折叠)得分情况:\n', scores)
print('平均分:\n', scores.mean())
print('用时(秒):', time()-start)
print('='*20)start = time()
scores = cross_val_score(svcClassifier, data[0], data[1],cv=ShuffleSplit(test_size=0.3,train_size=0.7,n_splits=10))
print('交叉验证(随机拆分)得分情况:\n', scores)
print('平均分:\n', scores.mean())
print('用时(秒):', time()-start)
print('='*20)start = time()
scores = cross_val_score(svcClassifier, data[0], data[1],cv=LeaveOneOut())
print('交叉验证(逐个测试)得分情况:\n', scores)
print('平均分:\n', scores.mean())
print('用时(秒):', time()-start)

2.使用网格搜索确定最佳参数

from time import time
from os import listdir
from os.path import basename
from PIL import Image
from sklearn import svm
from sklearn.model_selection import GridSearchCV# 图像尺寸
width, height = 30, 60def loadDigits(dstDir='datasets'):# 获取所有图像文件名digitsFile = [dstDir+'/'+fn for fn in listdir(dstDir)if fn.endswith('.jpg')]# 按编号排序digitsFile.sort(key=lambda fn: int(basename(fn)[:-4]))# digitsData用于存放读取的图片中数字信息# 每个图片中所有像素值存放于digitsData中的一行数据digitsData = []for fn in digitsFile:with Image.open(fn) as im:data = [sum(im.getpixel((w,h)))/len(im.getpixel((w,h)))for w in range(width)for h in range(height)]digitsData.append(data)# digitsLabel用于存放图片中数字的标准分类with open(dstDir+'/digits.txt') as fp:digitsLabel = fp.readlines()digitsLabel = [label.strip() for label in digitsLabel]return (digitsData, digitsLabel)# 加载数据
data = loadDigits()
print('数据加载完成。')# 创建模型
svcClassifier = svm.SVC()
# 待测试的参数
parameters = {'kernel': ('linear', 'rbf'),'C': (0.001, 1, 1000),'gamma':(0.001, 1, 10)}# 网格搜索
start = time()
clf = GridSearchCV(svcClassifier, parameters)
clf.fit(data[0], data[1])
# 解除注释可以查看详细结果
# print(clf.cv_results_)
print(clf.best_params_)
print('得分:', clf.score(data[0], data[1]))
print('用时(秒):', time()-start)
数据加载完成。

3.绘制学习曲线

from os import listdir
from os.path import basename, join
import numpy as np
from PIL import Image
from sklearn import svm
from sklearn.model_selection import learning_curve, ShuffleSplit
import matplotlib.pyplot as plt# 图像尺寸
width, height = 30, 60
def loadDigits(dstDir='datasets'):# 获取所有图像文件名digitsFile = [join(dstDir,fn) for fn in listdir(dstDir)if fn.endswith('.jpg')]# 按编号排序digitsFile.sort(key=lambda fn: int(basename(fn)[:-4]))# digitsData用于存放读取的图片中数字信息# 每个图片中所有像素值存放于digitsData中的一行数据digitsData = []for fn in digitsFile:with Image.open(fn) as im:# 原始图像尺寸不一样,先调整成统一尺寸,确保每个子列表的长度相同digitsData.append(np.array(im.resize((width,height))).mean(axis=2).flatten('F').tolist())# digitsLabel用于存放图片中数字的标准分类with open(fr'{dstDir}/digits.txt') as fp:digitsLabel = fp.read().splitlines(keepends=False)return (digitsData, digitsLabel)# 加载数据
X, y = loadDigits()
print('数据加载完成。')svcClassifier = svm.SVC(kernel='linear', C=1000, gamma=0.001)
# 使用20%的样本进行测试,80%的样本进行训练,重复10次,计算每次的得分
cv = ShuffleSplit(test_size=0.2, train_size=0.8, n_splits=10)
# 使用交叉验证计算不同数量样本作为训练集时的模型平均得分
train_sizes, train_scores, test_scores = learning_curve(svcClassifier, X, y, cv=cv,train_sizes=np.linspace(0.1,1.0,10))
# 对于不同大小的训练集10次训练与测试结果得分求均值
train_scores = np.mean(train_scores, axis=1)
test_scores = np.mean(test_scores, axis=1)plt.plot(train_sizes, train_scores, 'r-o', lw=2, label='training score')
plt.plot(train_sizes, test_scores, 'g--v', lw=2, label='cross validation score')
plt.legend()plt.show()

相关文章:

  • Springboot项目的目录结构
  • AI赋能Automa二次开发
  • Spring @Qualifier,@Primary
  • 分布式ID实现方案实战示例总结
  • 【Zephyr 系列 18】分布式传感网络系统设计:从 BLE Mesh 到边缘网关的数据闭环
  • 看安科瑞分布式光伏解决方案如何破解光伏痛点?
  • 机器学习赋能的智能光子学器件系统研究与应用
  • 基于生成对抗网络(GAN)的图像生成与编辑:原理、应用与实践
  • Idea 2025 commit 关闭侧边栏 开启探框
  • SHA-1算法详解:原理、特点与应用
  • OctoPrint公网部署如何实现?3D打印远程控制一键部署过程!
  • 牛市与熊市:市场周期的双面镜
  • 记录下three.js学习过程中不理解问题----材质(material)⑤
  • NLP学习路线图(三十九):对话系统
  • 2025年渗透测试面试题总结-长亭科技[实习]安全服务工程师题目+回答)
  • 如何将文件从 iPhone 传输到闪存驱动器
  • GaussDB分布式数据库调优方法总结:从架构到实践的全链路优化指南
  • 增强现实—Flame: Learning to navigate with multimodal llm in urban environments
  • 安全生产管理是什么?安全生产管理主要管什么?
  • NLP学习路线图(四十):文本与图像结合
  • 汕头网站seo外包/百度的企业网站
  • centos 6.5 搭建wordpress/搜索引擎优化方式
  • 办公室装修效果图简约大气/网站优化网站
  • 给别人做网站去掉版权/百度快速收录3元一条
  • 大型网站的优化方法/seo排名优化推荐
  • 招聘网站html模板/网站推广途径