人工智能
机器学习是人工智能的一个发展途径
深度学习是机器学习的一个方法发展而来——人工神经网络
机器学习
概念
从 数据 中自动分析获得 模型 ,并利用模型对未知数据进行 预测。
数据集的构成
机器学算法分类
-
监督学习
- 目标值:类别-分类问题——k-近邻算法、贝叶斯分类、决策树、逻辑回归
- 预测天气阴晴雨雪
- 人脸识别
- 目标值:连续型的数据-回归问题——线性回归、岭回归
- 预测天气温度
-
无监督学习
开发流程
- 数据获取
- 数据处理
- 特征工程
- 机器学习算法训练-模型
- 模型评估
![屏幕截图 2023-10-18 165213](.\images\屏幕截图 2023-10-18 165213.png)
框架
数据集
kaggle网址:https://www.kaggle.com/datasets
UCI数据集:https://archive.ics.uci.edu/
scikit-learn
scikit-learn使用
from sklearn.datasets import load_iris
# load 与 fetch返回的数据为datasets.Base.Bunch(字典格式)
iris = load_iris()
# data 特征数据数组
# target 标签数组
# target_names 标签名
# feature_names 特征名,新闻数据,手写数字,回归数据集没有
# DESC: 数据描述
print(iris)
print(iris['DESCR'])
print(iris.feature_names)
划分
机器学习一般的数据集会划分为两个部分:
- 训练数据:用于训练,构建模型
- 测试数据:在模型检验时使用,用于评估模型是否有效——20%~30%
from sklearn.model_selection import train_test_split
# 数据集划分方法train_test_split
# x数据集的特征值
# y数据集的标签值
# test_size 测试数据集的大小,一般为float
# random_state 随机数种子,不同的种子会造成不同的随机采样结果,相同的种子采样结果一致
# return 训练集特征值,测试集特征值,训练集目标值,测试集目标值
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.25 )
print(x_train)
特征工程
使用专业背景知识和技巧处理数据,使得特征能在机器学习算法上发挥更好的作用的过程。
数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限
特征抽取/提取
机器学习算法——统计方法——数学公式
文本类型——>数值
类型——>数值
概念
将任意数据转换为可用于机器学习的数字特征
注:特征值化是为了计算机更好的去理解数据
- 字典特征提取——特征离散化
- 文本特征提取
- 图像特征提取——深度学习将介绍
from sklearn import feature_extraction
字典特征提取
from sklearn.feature_extraction import DictVectorizer
# 特征提取
# feature_extraction.DictVectorizer
# DictVectorizer = feature_extraction.DictVectorizer(sparse=True)
# DictVectorizer.fit_transform(X)x:字典或包含字典的迭代器返回值,返回sparse矩阵
# vector 数学:向量 物理:矢量
# 矩阵 matrix 二维数组
# 向量 vector 一维数组
# 返回sparse矩阵
# sparse 稀疏,将非零值按位置表示出来
dic = [{'city': '上海', 'temperature': 100},
{'city': '北京', 'temperature': 200},
{'city': '深圳', 'temperature': 300}]
# 实例化转换器类
transfer = DictVectorizer(sparse=False)
# 调用fit_transform
b = transfer.fit_transform(dic)
print(b)
print(transfer.get_feature_names_out())
# 将特征中的类别信息转换为one-hot编码
[[ 1. 0. 0. 100.]
[ 0. 1. 0. 200.]
[ 0. 0. 1. 300.]]
['city=上海' 'city=北京' 'city=深圳' 'temperature']
场景:
- 数据集中类别特征较多的
- 将数据集的特征——>字典类型
- DictVectorizer特征抽取
- 本身拿到的类型就是字典
文本特征处理
from sklearn.feature_extraction.text import CountVectorizer
def content_Vectorizer():
tex = ['life is short,I like like python. ', 'life is too long, I deslike python.']
transfer = CountVectorizer()
#返回sparse矩阵
new = transfer.fit_transform(tex)
print(new)
# 转换稀疏数组为二维数组
print(new.toarray())
print(transfer.get_feature_names_out())
CountVectorizer:统计样本特征词的个数
中文样本特征处理
单词 作为 特征
橘子、短语、单词、字母
特征:特征词
方法一:CountVectorizer
- 统计每个样本特征词出现的个数
- stop_words 停用的,停用字典
import jieba
from sklearn.feature_extraction.text import CountVectorizer
def jieba_split(contex):
"""
jieba分词,对文本内容进行分词,再通过文本特征提取,提取特征词
:param contex: 中文文本
:return:
"""
speg = "".join(list(jieba.cut(contex)))
return speg
def chines_content_jieba_Vectorizer():
"""
中文文本特征提取
:return:
"""
tex = ['北京欢迎你,为你开天辟地,流动中的魅力充满着朝气,北京欢迎你,在太阳下分享呼吸,在黄土地刷新成绩,我家大门常打开,开怀容纳天地,岁月绽放青春笑容,迎接这个日期,天大地大都是朋友请不用客气,画意诗情带笑意,只为等待你,北京欢迎你 像音乐感动你,让我们都加油去超越自己,北京欢迎你,有梦想谁都了不起',
'有勇气就会有奇迹,北京欢迎你,为你开天辟地,流动中的魅力充满着朝气,北京欢迎你,在太阳下分享呼吸',
'在黄土地刷新成绩,北京欢迎你,像音乐感动你,让我们都加油去超越自己']
transfer = CountVectorizer()
new_tex = list()
for record in tex:
new_tex.append(jieba_split(record))
# 返回sparse矩阵
new = transfer.fit_transform(new_tex)
print(new)
# 转换稀疏数组为二维数组
print(new.toarray())
print(transfer.get_feature_names_out())
(0, 2) 4
(0, 0) 1
(0, 12) 1
(0, 4) 1
(0, 5) 1
(0, 9) 1
(0, 8) 1
(0, 7) 1
(0, 15) 1
(0, 6) 1
(0, 13) 1
(0, 3) 1
(0, 1) 1
(0, 14) 1
(0, 11) 1
(1, 2) 2
(1, 0) 1
(1, 12) 1
(1, 4) 1
(1, 10) 1
(2, 2) 1
(2, 5) 1
(2, 1) 1
(2, 14) 1
[[1 1 4 1 1 1 1 1 1 1 0 1 1 1 1 1]
[1 0 2 0 1 0 0 0 0 0 1 0 1 0 0 0]
[0 1 1 0 0 1 0 0 0 0 0 0 0 0 1 0]]
['为你开天辟地' '像音乐感动你' '北京欢迎你' '只为等待你' '在太阳下分享呼吸' '在黄土地刷新成绩' '天大地大都是朋友请不用客气'
'岁月绽放青春笑容' '开怀容纳天地' '我家大门常打开' '有勇气就会有奇迹' '有梦想谁都了不起' '流动中的魅力充满着朝气'
'画意诗情带笑意' '让我们都加油去超越自己' '迎接这个日期']
关键词:在某一个类别的文章中,出现的次数很多,在其他类别的文章中出现次数很少
方法二:TfidfVectorizer
如果某个词或短语在一篇文章中出现的概率高,并且在其他文章中很少出现,则认为该词或短语具有很好的类别区分能力,适合用来分类
用以评估——字词对一个文件集或一个语料库中的其中一份文件的重要程度
TF-IDF——重要程度
TF:词频(term frequency, tf):某一个给定的词语在文章中的出现频率
IDF:逆向文档频率(inverse document frequency,idf):是一个词语普遍重要性的度量,某一特定词语的idf,可以由总文件数目除以包含该词语之文件的数目,再将得到的商取以10为底的对数得到
示例:
特征词“经济” “非常”
1000篇文章——语料库
100篇文章——“非常”
10篇文章——“经济”
两篇文章
文章A(100词):10次经济:TF-IDF:tf*idf=0.2
tf : 10/100=0.1
idf:log 10 (1000 / 10) =2
文章B(100词):10次非常:TF-IDF:tf*idf=0.1
tf:10/100=0.1
idf:log 10 (1000/100) = 1
import jieba
def jieba_split(contex):
"""
jieba分词,对文本内容进行分词,再通过文本特征提取,提取特征词
:param contex: 中文文本
:return:
"""
speg = "".join(list(jieba.cut(contex, cut_all=False)))
return speg
from sklearn.feature_extraction.text import TfidfVectorizer
def chines_content_jieba_TfidfVectorizer():
"""
TfidfVectorizer的方法进行中文文本特征提取
:return:
"""
tex = ['北京欢迎你,为你开天辟地,流动中的魅力充满着朝气,北京欢迎你,在太阳下分享呼吸,在黄土地刷新成绩,我家大门常打开,开怀容纳天地,岁月绽放青春笑容,迎接这个日期,天大地大都是朋友请不用客气,画意诗情带笑意,只为等待你,北京欢迎你 像音乐感动你,让我们都加油去超越自己,北京欢迎你,有梦想谁都了不起',
'有勇气就会有奇迹,北京欢迎你,为你开天辟地,流动中的魅力充满着朝气,北京欢迎你,在太阳下分享呼吸',
'在黄土地刷新成绩,北京欢迎你,像音乐感动你,让我们都加油去超越自己']
transfer = TfidfVectorizer()
new_tex = list()
for record in tex:
new_tex.append(jieba_split(record))
# 返回sparse矩阵
new = transfer.fit_transform(new_tex)
print(new)
# 转换稀疏数组为二维数组
print(new.toarray())
print(transfer.get_feature_names_out())
特征预处理
概念
通过一些转换函数将特征数据转换成更加适合算法模型的特征数据过程
内容
特征预处理API
sklearn.preprocessing
为什么需要进行归一化?
无量钢化
特征的单位或者大小相差较大,或者某特征的方差相比其他的特征要大出几个量级,容易影响(支配)目标结果,使得一些算法无法学习到其他的特征
归一化
计算公式:
x'=(x-min)/(max-min)
x''=x'*(mx-mi)+mi
from sklearn.datasets import load_iris
iris = load_iris()
from sklearn.preprocessing import MinMaxScaler
import pandas as pd
#本示例使用iris数据集
def minmaxscaler_demo():
"""
归一化
:return:
"""
# 获取数据
data = iris['data'][:,:3]
data = pd.DataFrame(data)
# data = data.iloc[:, :3]
# 实例化转换器类
transfer = MinMaxScaler()
# 调用fit_transform转换
data_new = transfer.fit_transform(data)
print(data_new)
标准化
归一化存在异常值:最大值,最小值
通过对原始数据进行变换,把数据变换到均值为0,标准差为1返回内
标准差——衡量离散程度:
x'=(x-mean)/σ
- 对于归一化来说:如果出现异常点,影响了最大值和最小值,那么会对结果产生影响
- 对于标准化来说:如果出现异常点,由于具有一定数据量,少量的异常点,对于平均值的影响并不大,从而方差改变较小
预处理API
from sklearn.datasets import load_iris
iris = load_iris()
from sklearn.preprocessing import ,StandardScaler
import pandas as pd
def standardScaler_demo():
"""
标准化
:return:
"""
# 获取数据
data = iris['data'][:,:3]
data = pd.DataFrame(data)
# data = data.iloc[:, :3]
# 实例化转换器类
transfer = StandardScaler()
# 调用fit_transform转换
data_new = transfer.fit_transform(data)
print(data_new)
print(transfer.get_feature_names_out())
应用场景:在已有样本足够多的情况下,比较稳定,适合现代嘈杂的大数据场景
特征降维
降维:降低纬度
-
ndarray:
- 维数:嵌套的层数
- 0维:标量
- 1维:向量
- 3维:
- ......
- n维:
-
二维数组
- 此处的降维:降低特征的个数
- 效果:特征与特征之间不相关(如果特征本身存在问题或者特征之间现相关性较强,对于算法学习预测会影响较大)
降维是指在某些限定条件下,降低随机变量(特征)个数,得到一组“不相关”主变量的过程
降维方式
- 特征选择
- 主成分分析(可以理解一种特征提取的方式)
特征选择
数据中包含冗余或相关变量(或称特征、属性、指标等),旨在从原有特征中找出主要特征
- filter(过滤式):主要探究特征本身特点,特征与特征和目标值之间的关联
- 方差选择法:低方差特征过滤
- 相关系数:特征与特征之间的相关性/程度
- embedden(嵌入式):算法自动选择特征(特征与目标值之间的关联)
- 决策树:信息熵,信息增益
- 正则化:L1、L2
- 深度学习:卷积等
方差选择法
删除低方差的一些特征
- 方差较小:某个特征大多样本的值比较接近
- 方差较大:某个特征很多样本的值都有差别
> API
from sklearn.feature_selection import VarianceThreshold
VarianceThreshold。
删除所有低方差特征
from sklearn.feature_selection import VarianceThreshold
from sklearn.datasets import load_breast_cancer
import pandas as pd
def varianceThreshold_demo():
"""
低方差特征过滤
:return:
"""
# 获取数据
breast_cancer = load_breast_cancer()
data = breast_cancer['data']
data = pd.DataFrame(data)
data.columns=breast_cancer['feature_names']
data = data.iloc[:,:5]
transfer = VarianceThreshold()
data_new = transfer.fit_transform(data)
print(data_new)
print(transfer.get_feature_names_out())
相关系数
皮尔逊相关系数
相关性的值介于-1到+1之间,即-1<=r<=+1:
-
r>0时,表示两变量之间正相关,r<0时,两变量为负相关
-
当|r|=1时,表示两变量完全相关,当r=0时,表示两变量完全不相关
-
当0<|r|<1时,表示两变量存在一定的相关性,且越接近1,两变量间的相关性越密切
-
一般按照三级划分:|r|小于0.4为低度相关,0.4<|r|<0.7为显著性相关,0.7<|r|<1为高度线性相关
当遇到特征与特征之间相关性较高的情况:
- 在较高相关性的特征之间任意选取一个
- 加权求和
- 主成分分析
> API
#scipy 第三方包
from scipy.stats import pearsonr
r = pearsonr(data['mean radius'], data['mean texture'])
print('相关系数:',r)
主成分分析——PCA
定义:将高维数据转换为低维数据的过程,在此过程中可能会涉及原有数据,创造新的变量
作用:是数据维数压缩,尽可能降低原数据的维数(复杂度),损失少量信息
场景:回归分析或者聚类分析当中
API
from sklearn.decomposition import PCA
# PCA(n_components=)
# n_components
# 小数:表示保留百分之多少的信息
# 证书:减少到多少特征
# transfer = PCA(n_components=1)
# transfer.fit_transform()
def PCA_demo():
"""
PCA降维
:return:
"""
data = [[2,8,4,5],[6,3,0,8],[5,4,9,1]]
transfer = PCA(n_components=3)
data_new = transfer.fit_transform(data)
print(data_new)
示例:instacart降维案例
import pandas as pd
from sklearn.decomposition import PCA
def instacart_demo():
# 需要将user_id和aisles放在同一个表中
# 找到user_id 和aisles——交叉表和透视表
# 特征冗余过多,PCA降维
# 读取数据
order_products = pd.read_csv('E:\\BaiduNetdiskDownload\\instacart-market-basket-analysis\\order_products__prior.csv')
orders = pd.read_csv('E:\\BaiduNetdiskDownload\\instacart-market-basket-analysis\\orders.csv')
aisles = pd.read_csv('E:\\BaiduNetdiskDownload\\instacart-market-basket-analysis\\aisles.csv')
products = pd.read_csv('E:\\BaiduNetdiskDownload\\instacart-market-basket-analysis\\products.csv')
# 合并aisles和products,使用merge
table_1 = pd.merge(aisles, products, on='aisle_id')
# print(table_1)
# 合并table_1和order_products
table_2 = pd.merge(table_1, order_products, on='product_id')
# 合并table_2和orders
table_3 = pd.merge(table_2, orders, on='order_id')
table = pd.crosstab(table_3['aisle_id'],table_3['user_id'])
table = table[:10000]
transfer = PCA(n_components=0.95)
data_new = transfer.fit_transform(table)
print(data_new)
print(transfer.get_feature_names_out())
# 合并表
# 找到user_id 和aisles的关系
# 数据PCA降维
sklearn转换器和估计器
转换器
我们把特征工程接口称之为转换器,其中转换器调用有这么几种形式
- fit_transform
- fit
- transform
以标准化为例
- fit:计算每一列的平均值、标准差
- transform:进行最终的转换
估计器(sklearn机器学习算法的实现)
- 实例化estimator
- estimator.fit(x_train, y_train)计算
- 模型评估
- 直接比对真实值和预测值
- y_predict= estimator.predict(x_test)
- y_test = y_predict
- 直接计算准确率
- accurary = estimator.score(x_test, y_test)
KNN算法——近邻算法
定义
根据你的邻居来推断你的类别
原理:
-
介绍:K Nearest Neighbor算法又叫KNN算法,这个算法是机器学习里面一个比较经典的算法,总体来说KNN算法是相对比较容易理解的算法
-
定义:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近的)的样本中大多数属于某一个类别,则该样本也属于这个类别
-
异常:如果k==1,并且该样本属于异常值,最终结果可能划分为异常值,容易受到异常值的影响
-
计算距离:
-
欧式距离计算
-
例如,a(a1,a2,a3) b(b1,b2,b3)
-
对每个特征相差结果平方和后开根号
-
曼哈顿距离
注意:当样本不均衡时,k值选择过大,会影响最终结果,导致结果错误
API
from sklearn.neighbors import KNeighborsClassifier
#estimator = KNeighborsClassifier(n_neighbors=5, algorithm='auto')
# n_neighbors:查询默认使用的邻居数
# algorithm:auto, ball_tree, kd_tree, brute,可用于计算最近邻居的算法,auto将尝试根据传递给fit方法的值来决定最合适的算法
#estimator.fit(x_train,y_train)
案例
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
def KNeighborsClassifier_demo():
"""
使用iris数据集进行knn机器学习算法
:return:
"""
# 获取数据
iris = load_iris()
# 数据划分
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=6)
# 特征工程-标准化
transfor = StandardScaler()
x_train = transfor.fit_transform(x_train)
# 使用与训练集相同的标准差进行转换
x_test = transfor.transform(x_test)
# 机器学习训练,knn估计器流程
estimator = KNeighborsClassifier(n_neighbors=3)
estimator.fit(x_train,y_train)
# 模型评估
# 直接比对真实值和预测值
y_predict = estimator.predict(x_test)
print(y_predict)
print('直接对比:\n',y_test == y_predict)
# 直接得出准确率
y_score = estimator.score(x_test, y_test)
print(y_score)
总结
优点:
缺点:
- 必须制定k值,k值选择的不当则分类精度不能保证
- 懒惰算法,对测试样本分类时的计算量大,内存开销大
使用场景:小数据场景,几千~几万样本,具体场景具体业务去测试
模型选择与调优
交叉验证
定义:将拿到的训练数据,分为训练集和验证集,每次更换不同的验证集和训练集,得到多组模型结果(一般四组),取平均值作为模型结果,又称4折交叉验证
交叉验证目的:为了让评估的模型更加准确可信
超参数搜索-网络搜索(Grid Search)
通常情况下,有很多参数是需要手动指定的(如k近邻算法的k值),这种叫超参数,但是手动过程复杂,所以需要对模型预设几种超参数组合,每组超参数都采用交叉验证来进行评估,最后选出最优参数组合建立模型
> API
from sklearn.model_selection import GridSearchCV
#gsc = GridSearchCV(estimator=,param_grid=,cv=)
#estimator:估计器对象
#param_grid:估计器参数(dict){"n_neighbors":[1,3,5]}
#cv:指定几折交叉验证
#fit:输入训练数据
#score():准确率
鸢尾花案例优化
from sklearn.model_selection import GridSearchCV
#gsc = GridSearchCV(estimator=,param_grid=,cv=)
#estimator:估计器对象
#param_grid:估计器参数(dict){"n_neighbors":[1,3,5]}
#cv:指定几折交叉验证
#fit:输入训练数据
#score():准确率
def KNeighborsClassifier_iris_gridsearchvc_demo():
"""
使用iris数据集进行knn机器学习算法,添加网格搜索和交叉验证
:return:
"""
# 获取数据
iris = load_iris()
# 数据划分
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=6)
# 特征工程-标准化
transfor = StandardScaler()
x_train = transfor.fit_transform(x_train)
# 使用与训练集相同的标准差进行转换
x_test = transfor.transform(x_test)
# 机器学习训练,knn估计器流程
estimator = KNeighborsClassifier(n_neighbors=3)
estimator = GridSearchCV(estimator=estimator, param_grid={"n_neighbors": [1, 3, 5, 7, 9, 11]}, cv=10)
# estimator.fit(x_train,y_train)
estimator.fit(x_train,y_train)
# 模型评估
# 直接比对真实值和预测值
y_predict = estimator.predict(x_test)
print(y_predict)
print('直接对比:\n',y_test == y_predict)
# 直接得出准确率
y_score = estimator.score(x_test, y_test)
print(y_score)
# 最佳参数
print(estimator.best_params_)
# 最佳结果
print(estimator.best_score_)
# 最佳估计器
print(estimator.best_estimator_)
# 交叉验证结果
print(estimator.cv_results_)