机器学习3

sklearn机器学习概述

使用scikit-learn的基本步骤通常包括:

  1. 数据准备:加载数据、数据清洗和特征工程。
  2. 模型选择:选择一个或多个机器学习模型。
  3. 模型训练:使用训练数据集训练模型。
  4. 模型评估:使用测试数据集评估模型性能。
  5. 模型优化:调整模型参数,进行交叉验证。
  6. 模型部署:将训练好的模型部署到生产环境中。

KNN算法-分类

KNN算法的核心思想是,一个样本的类别可以由其最近邻的样本决定。在分类问题中,KNN算法会根据训练集中的最近邻样本的类别,通过多数投票的方式来预测新样本的类别

KNN算法的工作原理:

  1. 距离度量:首先,KNN算法需要一个距离度量来计算样本之间的距离,常见的距离度量包括欧氏距离、曼哈顿距离和闵可夫斯基距离等。

  2. 寻找最近邻:对于一个新的样本点,KNN算法会在训练集中寻找与其距离最近的K个样本点。

  3. 多数投票:在分类问题中,KNN算法会根据这K个最近邻样本的类别进行多数投票,即选择出现次数最多的类别作为新样本的预测类别。

  4. 权重投票:在某些变体中,最近邻的类别可能会根据其距离的远近有不同的权重,距离越近的样本点对预测结果的影响越大。

缺点:

  1. KNN是一种基于实例的学习算法,它不需要显式的训练阶段。模型的训练实际上就是存储训练数据集。
  2. KNN属于惰性学习方法,它在训练阶段不进行模型学习,而是将学习推迟到预测阶段。
  3. 算法的核心是基于距离的度量,通常使用欧氏距离,但也可以使用其他距离度量。
  4. 在分类问题中,KNN使用多数投票机制来确定新样本的类别。
  5. K值的选择对算法的性能有重要影响,需要根据具体问题进行调整。
  6. KNN是一种非参数方法,它不假设数据的分布,也不对数据进行任何参数化的形式化。
  7. KNN算法易于理解和实现,不需要复杂的数学背景。
  8. 与其他需要假设数据分布的算法不同,KNN不对数据的分布做出任何假设。
  9. 由于KNN依赖于距离度量,因此对特征的缩放非常敏感。不同量纲的特征需要进行适当的缩放。
  10. 虽然KNN通常用于分类问题,但它也可以通过计算最近邻的平均值来用于回归问题。
  11. 在预测阶段,KNN需要计算待预测样本与所有训练样本之间的距离,这可能导致较高的计算成本。
  12. KNN需要存储整个训练数据集,这可能导致较高的存储成本。

优点:

  1. 简单易懂,无需训练阶段。
  2. 可用于非线性数据。
  3. 可用于多分类问题。
  4. 可用于回归问题。

API

from sklearn.neighbors import KNeighborsClassifier

KNeighborsClassifier()

构造函数参数

  • n_neighbors: int, 默认值为5。指定用于kneighbors查询的邻居数量。
  • weights: {‘uniform’, ‘distance’}, callable或None, 默认为‘uniform’。用于预测的权重函数。‘uniform’表示所有邻居的权重相同,‘distance’表示权重与距离成反比。
  • algorithm: {‘auto’, ‘ball_tree’, ‘kd_tree’, ‘brute’}, 默认为‘auto’。用于计算最近邻居的算法。‘ball_tree’和‘kd_tree’分别使用球树和KD树,‘brute’使用暴力搜索。
  • leaf_size: int, 默认值为30。传递给BallTree或KDTree的叶大小。这会影响构建和查询的速度,以及存储树所需的内存。
  • p: int, 默认值为2。与metric参数一起使用,是Minkowski距离中的指数参数。默认情况下,这等同于欧几里得距离。
  • metric: str或callable, 默认为‘minkowski’。用于计算距离的度量。
  • metric_params: dict, 默认为None。传递给度量函数的额外关键字参数。
  • n_jobs: int, 默认为None。并行运行的任务数。None意味着1,除非在全局并行上下文中设置了不同的值。

鸢尾花示例:

# 导入要使用的库
from sklearn.datasets import load_iris
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import StandardScaler

iris = load_iris()
# 查看键
print(iris.keys())
'''
dict_keys(['data', 'target', 'frame', 'target_names', 'DESCR', 'feature_names', 'filename', 'data_module'])
'''

from sklearn.model_selection import train_test_split
#鸢尾花load_iris已经将data和target分好了,直接使用即可
#得到训练集和测试集
x_train,x_test,y_train,y_test = train_test_split(iris.data,iris.target, test_size=0.1,random_state=22)
#创建StandardScaler实例
transfer = StandardScaler()
#使用fit计算均值和标准差
transfer.fit(x_train)
#使用transform将数据标准化
x_train = transfer.transform(x_train)
x_test = transfer.transform(x_test)
#创建KNeighborsClassifier 实例
knn = KNeighborsClassifier(n_neighbors=11)
#使用fit训练模型
knn.fit(x_train,y_train)
#评估模型
print(knn.score(x_test,y_test))
'''
1.0
'''

模型保存与加载

import joblib

#保存模型
joblib.dump(knn, 'knn.pkl')
# 加载模型
estimator = joblib.load("knn.pkl")
#使用模型预测
y_test = estimator.predict([[0.4, 0.2, 0.4, 0.7]])
print(y_test)

模型选择与调优

交叉验证

  1. 保留交叉验证HoldOut
    上面使用的训练集和测试集
    x_train,x_test,y_train,y_test

  2. K-折交叉验证(K-Fold Cross-Validation):

    • 将数据集随机分成K个大小相等的子集。
    • 进行K次训练和验证,每次选择不同的子集作为验证集,其余K-1个子集合并作为训练集。
    • 最终的性能评估通常是基于K次验证结果的平均值。
  3. 分层K-折交叉验证(Stratified K-Fold Cross-Validation):

    • 与K-折交叉验证类似,但确保每个折中各类别的比例与原始数据集中的相同,适用于类别不平衡的数据集。
  4. 留一交叉验证(Leave-One-Out Cross-Validation, LOOCV):

    • 每次只留下一个样本作为验证集,其余所有样本作为训练集。
    • 这种方法计算成本较高,但特别适合于小数据集。
  5. 自助采样(Bootstrap):

    • 通过有放回地随机抽样来创建多个训练集和验证集。
    • 这种方法不需要预先分割数据集,但可能会导致一些样本在训练过程中从未被使用。

StratifiedKFold 的一些关键参数和用法:

参数:

  • n_splits: int, 默认值为5。指定要将数据集分割成多少个子集(折)。
  • shuffle: bool, 默认值为False。指定在分割之前是否对每个类别的样本进行打乱。
  • random_state: int, RandomState实例或None, 默认值为None。当 shuffle 为True时,random_state 会影响索引的顺序,从而控制每个类别的每个折的随机性。

方法:

  • get_n_splits(X, y): 返回交叉验证器中的分割迭代次数。
  • split(X, y): 生成索引以将数据分为训练集和测试集。
from sklearn.datasets import load_wine
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import StandardScaler
#观察wine数据
wine = load_wine()
print(wine.keys())
print(wine.target_names)
print(wine.data.shape)
...
dict_keys(['data', 'target', 'frame', 'target_names', 'DESCR', 'feature_names'])
['class_0' 'class_1' 'class_2']
(178, 13)
...
from sklearn.model_selection import StratifiedKFold

x = wine.data
y = wine.target
#StratifiedKFold编写一个迭代器
strat_k_fold = StratifiedKFold(n_splits=10, random_state=7, shuffle=True)
index = strat_k_fold.split(x, y)
#创建一个knn实例
knn = KNeighborsClassifier(n_neighbors=7)
#得到下标进行迭代
for train_index, test_index in index:
    # 通过下标得到训练集和测试集
    x_train, x_test = x[train_index], x[test_index]
    y_train, y_test = y[train_index], y[test_index]
    #标准化数据
    scaler = StandardScaler()
    X_train_scaled = scaler.fit_transform(x_train)
    X_test_scaled = scaler.transform(x_test)
    #训练模型
    knn.fit(X_train_scaled, y_train)
    #评估模型
    score = knn.score(X_test_scaled, y_test)
    print(score)

超参数搜索

又叫网格搜索,在模型训练之前设置的参数,用于控制学习过程,如学习率、迭代次数等。

API

from sklearn.model_selection import GridSearchCV

GridSearchCV(estimator, param_grid)

构造函数参数:

  • estimator: 要优化的估计器(模型)。
  • param_grid: 一个字典,键是估计器的参数名,值是对应的参数值列表。GridSearchCV 将遍历所有参数值的组合。

重要参数:

  • cv: 交叉验证的折数或交叉验证分割策略,用于评估每个超参数组合的性能。
  • scoring: 用于评估模型性能的评分函数或指标。
  • n_jobs: 并行运行的任务数。默认情况下,n_jobs=1 表示串行运行。如果设置为 -1,则使用所有可用的CPU核心。
  • verbose: 控制日志的详细程度。数字越大,输出的日志越详细。
  • fit_params: 传递给 fit 方法的附加参数。
  • pre_dispatch: 控制并行运行时的调度行为。

方法:

  • fit(X, y=None, groups=None, **fit_params): 运行网格搜索以优化超参数。
  • score(X, y=None): 返回最佳估计器在给定数据上的分数。
  • predict(X): 使用最佳估计器对数据进行预测。
  • best_estimator_: 返回训练后的最佳估计器。
  • best_params_: 返回最佳估计器的参数。
  • best_score_: 返回最佳估计器的分数。
from sklearn.datasets import load_breast_cancer
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV
#读取乳腺癌数据集
data = load_breast_cancer()
x_train, x_test, y_train, y_test = train_test_split(data['data'], data['target'], random_state=0)
#标准化
tranfer = StandardScaler()
x_train = tranfer.fit_transform(x_train)
x_test = tranfer.transform(x_test)
#创建实例
knn = KNeighborsClassifier()
knn = GridSearchCV(knn, {'n_neighbors': [4,8,10,12]}, cv=5)
knn.fit(x_train, y_train)
#输出最好的分数和对应参数
print(knn.best_score_)
print(knn.best_params_)
'''
0.9648700410396718
{'n_neighbors': 12}
'''

作业

手搓TfidfVectorizer TF-IDF(文本特征词的重要程度特征提取)

要求最后输出和最后一行的数组一样

# re=math.log10(4)
# print(re)
import numpy as np

data = ['世界 你好 我 是 华清 远见 的 张 三', '你好 世界 我 是 李四 世界', '华清 远见 666']
# 作业  实现一个函数
# ['666' '世界' '你好' '华清' '李四' '远见']
# data_=mytool(data)#[[0.8,0.7,0.6,0.5,0.4,0.3],[0.2,0.3,0.4,0.5,0.6,0.7],[0.3,0.4,0.5,0.6,0.7,0.8]]

# 分词并创建词汇表
vocabulary = []
for document in data:
    words = document.split()
    for word in words:
        if len(word) > 1 and word not in vocabulary:
            vocabulary.append(word)
# print(vocabulary)

num = []
shape1 = shape2 = 0
for d in data:
    shape1 += 1
    shape2 = 0
    arr = []
    for w in vocabulary:
        shape2 += 1
        count = 0
        if w in d:
            count += 1
            arr.append(w)
        num = num + [count]
num = np.array(num)
num = num.reshape(shape1, shape2)
Nt = np.sum(num, axis=0)
Nt += 1
N = np.full_like(Nt, 3)
# 获得IDF
IDF = np.log10(Nt / N)


# print(IDF)


def len_num(data):
    len_arr = []
    for i in data:
        len = 0
        itme = i.split()
        for j in itme:
            len += 1
        len_arr.append(len)
    return len_arr


len_arr = len_num(data)
len_arr = np.array(len_arr)
# print(len_arr)
arrr = []

for i in vocabulary:
    cuont = 0
    for j in data:
        numm = 0
        itme = j.split()
        for k in itme:
            if i == k:
                numm += 1
        arrr.append(numm / len_arr[cuont])
        cuont += 1

arrr1 = [i for i in arrr[::3]]
arrr2 = [i for i in arrr[1::3]]
arrr3 = [i for i in arrr[2::3]]
arrrr = [arrr1, arrr2, arrr3]
# TF
TF = np.array(arrrr)
# print(TF)

# TF-IDF
TF_IDF = np.dot(TF, TF.T)
print(TF_IDF)
['世界', '你好', '华清', '远见', '李四', '666']
[[0.04938272 0.05555556 0.07407407]
 [0.05555556 0.16666667 0.        ]
 [0.07407407 0.         0.33333333]]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值