AI学习---分类算法[K-近邻 + 朴素贝叶斯 + 决策树 + 随机森林 ]
分类算法:对目标值进行分类的算法
1、sklearn转换器(特征工程)和预估器(机器学习)
2、KNN算法(根据邻居确定类别 + 欧氏距离 + k的确定),时间复杂度高,适合小数据
3、模型选择与调优
4、朴素贝叶斯算法(假定特征互独立 + 贝叶斯公式(概率计算) + 拉普拉斯平滑系数),假定独立,对缺失数据不敏感,用于文本分类
5、决策树(找到最高效的决策顺序--信息增益(关键特征=信息熵-条件熵) + 可以可视化)
6、随机森林(bootstarp(又放回的抽取) + 特征随机(抽取小特征) + 多个决策树)
sklearn转换器(transfer)与估计器(estimeter)简介
1、转换器 - 特征工程的父类
转换器 - 特征工程的父类
1、API的实现过程:
1 实例化 (实例化的是一个转换器类(Transformer))
2 调用fit_transform(对于文档建立分类词频矩阵,不能同时调用)
2、sklearn的标准化:
计算公式:(x - mean) / std
x: 数据
mean: 该列的平均值
std: 标准差
我们调用fit_transform()实际上发生了2个步骤:
fit() 计算 每一列的平均值、标准差
transform() (x - mean) / std进行最终的转换
1 | # 转换器的实例讲解 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | import sklearn # 特征预处理 from sklearn.preprocessing import StandardScaler def stand_demo(): data = [[ 1 , 2 , 3 ], [ 4 , 5 , 6 ]] # 1 、实例化一个类 std = StandardScaler() # 2 、调用fit_transform() new_data = std.fit_transform(data) '' ' fit = std.fit(data): # 已经完成了列的平均值和标准差的计算 StandardScaler(copy=True, with_mean=True, with_std=True) std = std.transform(data): # 根据公式(x - mean) / std进行最终的转换 [[- 1 . - 1 . - 1 .] [ 1 . 1 . 1 .]] new_data = std.fit_transform(data): [[- 1 . - 1 . - 1 .] [ 1 . 1 . 1 .]] '' ' print(new_data) if __name__ == '__main__' : stand_demo() |
2、估计器--sklearn机器学习算法的实现
基于估计器的算法API
估计器的工作流程:
估计器(estimator)
1 实例化一个estimator
2 estimator.fit(x_train, y_train) --> 用于计算x_train: 训练集的特征值, y_train: 训练集的目标值
—— 调用完毕,模型生成
3 模型评估(有2种方法实现):
1)直接比对真实值和预测值
y_predict = estimator.predict(x_test) # x_test: 测试集的特征值, y_predict: 测试集的预测值y_test == y_predict # 对比测试集的预测值(y_predict)与测试集的目标值(y_test)是否一致
2)计算准确率
accuracy = estimator.score(x_test, y_test) # 传递测试集特征值和测试集目标值进行准确率计算
KNN算法(K-近邻算法)
KNN的核心算法: 通过计算A到邻居(B、C、D、E、F)的距离可以判断A属于哪个类别(区域)。K就是相似特征
距离计算公式:
0、欧式距离
1、曼哈顿距离 (绝对值距离)
2、明可夫斯基距离(基于0和1实现)
K-近邻算法对目标数据的处理:
无量纲化的处理,即【标准化】(归一化会受到异常数据影响)
如果取的最近的电影数量不一样?会是什么结果?
k 值取得过小(即1个样本点),容易受到异常点的影响
k 值取得过大(即取出多样本),样本不均衡的影响
K-近邻算法API
KNN算法案例1:鸢尾花种类预测
案例分析:
1. 获取数据(sklearn自带的数据即可)
2. 数据处理(可省略,数据已经处理的很好了,目的是取出不完整的数据)
3. 特征工程
1. 数据集的划分(训练数据 + 测试数据)
2. 特征抽取(可省略,4个特征)
3. 特征预处理(标准化) --》 训练数据和测试数据都需要
4. 降维(可省略,降维的目的是减少特征,这里就4个特征)
4. KNN预估计流程
5. 模型评估
基于KNN实现鸢尾花的分类完整Demo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.neighbors import KNeighborsClassifier def knn_demo(): '' ' 基于KNN实现鸢尾花的分类 : return : '' ' # 1 、获取数据 iris = load_iris() print( 'iris' , iris.data.shape) # 2 、数据划分 # 结果跟随机数种子random_state有关 x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state= 6 ) # 3 、特征工程: 标准化 stand_transfer = StandardScaler() '' ' 原则: 训练集的数据做的操作,测试集也是需要做同样的操作 实现: 训练集: stand_transfer对训练集进行了fit()和transfer(),即fit用于计算平均值和标准差,tranfer用于公式计算 测试集: stand_transfer对训练集进行了transfer(),即用训练集求出来的平均值和标准差进行最后的公式计算(标准化) 如果对测试集用了fit_tranform(),即对测试集测试的仅仅是自己的数据内容,与训练内容无关 '' ' x_train = stand_transfer.fit_transform(x_train) # 要对训练标准化 print( 'x_train' , x_train.shape) x_test = stand_transfer.transform(x_test) # 用训练集的平均值和标准差对测试集进行标准化 print( 'x_test' , x_test.shape) # 4 、KNN算法评估器 knn_estimater = KNeighborsClassifier(n_neighbors= 3 ) # 邻居数量,默认是 5 knn_estimater.fit(x_train, y_train) # 训练完成,产生模型;x_train: 训练集的特征值, y_train: 训练集的目标值 # 5 、模型评估 # 方法 1 ;直接对比真实值和预测值 y_predict = knn_estimater.predict(x_test) print( 'y_predict' , y_predict) print( '真实值和预测值:' , y_predict == y_test) # 方法 2 :计算准确率 score = knn_estimater.score(x_test, y_test) # 传递测试集特征值和测试集目标值进行准确率计算 print( '准确率:' ,score) return None if __name__ == '__main__' : knn_demo() |
KNN算法总结
附: 我们可以利用【模型与调优】进行K的确定
模型选择与调优
模型选择与调优的方案:
1、交叉验证(Cross Validate)
2、超参数搜索 –> 网格搜索(Grid Search)
方案一:交叉验证(cross validate, 即有限数据多次验证,被评估的模型更加可信)
方案二:超参数搜索--网格搜索(Grid Search)
模型选择与调优API
说明:GridSearchCV实际上也是一个评估器,用法与上面相同
基于KNN实现鸢尾花的分类,添加网格搜索和交叉验证,用于确定最优的K值完整Demo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.model_selection import GridSearchCV from sklearn.preprocessing import StandardScaler from sklearn.neighbors import KNeighborsClassifier def knn_gridSearch_demo(): '' ' 基于KNN实现鸢尾花的分类,添加网格搜索和交叉验证,用于确定最优的K值 : return : '' ' # 1 、获取数据 iris = load_iris() print( 'iris' , iris.data.shape) # 2 、数据划分 # 结果跟随机数种子random_state有关 x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state= 3 ) # 3 、特征工程: 标准化 stand_transfer = StandardScaler() '' ' 原则: 训练集的数据做的操作,测试集也是需要做同样的操作 实现: 训练集: stand_transfer对训练集进行了fit()和transfer(),即fit用于计算平均值和标准差,tranfer用于公式计算 测试集: stand_transfer对训练集进行了transfer(),即用训练集求出来的平均值和标准差进行最后的公式计算(标准化) 如果对测试集用了fit_tranform(),即对测试集测试的仅仅是自己的数据内容,与训练内容无关 '' ' x_train = stand_transfer.fit_transform(x_train) # 要对训练标准化 print( 'x_train' , x_train.shape) x_test = stand_transfer.transform(x_test) # 用训练集的平均值和标准差对测试集进行标准化 print( 'x_test' , x_test.shape) # 4 、KNN算法评估器 knn_estimater = KNeighborsClassifier() # 5 、加入网格搜索与交叉验证 param_dict = { "n_neighbors" : [ 1 , 3 , 5 , 7 , 9 , 11 ]} # 这里只能是字典 '' ' estimator : estimator object. param_grid : dict or list of dictionaries '' ' knn_estimater = GridSearchCV(estimator=knn_estimater, param_grid=param_dict, cv= 10 ) knn_estimater.fit(x_train, y_train) # 训练完成,产生模型;x_train: 训练集的特征值, y_train: 训练集的目标值 # 6 、模型评估 # 方法 1 ;直接对比真实值和预测值 y_predict = knn_estimater.predict(x_test) print( 'y_predict' , y_predict) print( '真实值和预测值:' , y_predict == y_test) # 方法 2 :计算准确率 score = knn_estimater.score(x_test, y_test) # 传递测试集特征值和测试集目标值进行准确率计算 print( '准确率:' , score) # 最佳参数:best_params print( "最佳参数:\n" , knn_estimater.best_params_) # 最佳结果:best_score_ print( "最佳结果:\n" , knn_estimater.best_score_) # 最佳估计器:best_estimator_ print( "最佳估计器:\n" , knn_estimater.best_estimator_) # 交叉验证结果:cv_results_ print( "交叉验证结果:\n" , knn_estimater.cv_results_) return None if __name__ == '__main__' : knn_gridSearch_demo() |
拓展:
Facebook的预测签到位置案例:
Facebook的预测签Demo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | import pandas as pd from sklearn.model_selection import train_test_split from sklearn.model_selection import GridSearchCV from sklearn.preprocessing import StandardScaler from sklearn.neighbors import KNeighborsClassifier def facebook_demo(): # 1 、获取数据 data = pd.read_csv( "F:\instacart\\train.csv" ) # 2 、基本的数据处理 # 1 )缩小数据范围 data = data.query( "x < 3 & x > 2 & y < 3 & y > 2" ) # 2 )处理时间特征 time_value = pd.to_datetime(data[ "time" ], unit= "s" ) date = pd.DatetimeIndex(time_value) data[ "day" ] = date.day data[ "weekday" ] = date.weekday data[ "hour" ] = date.hour # 3 )过滤签到次数少的地点 place_count = data.groupby( "place_id" ).count()[ "row_id" ] # 仅仅显示place_id的签到次数和row_id信息 # data_final --> pandas.core.frame.DataFrame类型 data_final = data[data[ "place_id" ].isin(place_count[place_count > 3 ].index.values)] # 过滤出来次数大于 3 的数据 # 4 )筛选特征值和目标值 x = data_final[[ "x" , "y" , "accuracy" , "day" , "weekday" , "hour" ]] y = data_final[ "place_id" ] # 5 )数据集划分 x_train, x_test, y_train, y_test = train_test_split(x, y) # 传入特征值和目标值 # 3 、特征工程:标准化 stand_transfer = StandardScaler() x_train = stand_transfer.fit_transform(x_train) # 要对训练标准化 print( 'x_train' , x_train.shape) x_test = stand_transfer.transform(x_test) # 用训练集的平均值和标准差对测试集进行标准化 print( 'x_test' , x_test.shape) # 4 、KNN算法评估器 knn_estimater = KNeighborsClassifier() # 5 、加入网格搜索与交叉验证 param_dict = { "n_neighbors" : [ 1 , 3 , 5 ]} # 这里只能是字典 '' ' estimator : estimator object. param_grid : dict or list of dictionaries '' ' knn_estimater = GridSearchCV(estimator=knn_estimater, param_grid=param_dict, cv= 5 ) knn_estimater.fit(x_train, y_train) # 训练完成,产生模型;x_train: 训练集的特征值, y_train: 训练集的目标值 # 6 、模型评估 # 方法 1 ;直接对比真实值和预测值 y_predict = knn_estimater.predict(x_test) print( 'y_predict' , y_predict) print( '真实值和预测值:' , y_predict == y_test) # 方法 2 :计算准确率 score = knn_estimater.score(x_test, y_test) # 传递测试集特征值和测试集目标值进行准确率计算 print( '准确率:' , score) # 最佳参数:best_params print( "最佳参数:\n" , knn_estimater.best_params_) # 最佳结果:best_score_ print( "最佳结果:\n" , knn_estimater.best_score_) # 最佳估计器:best_estimator_ print( "最佳估计器:\n" , knn_estimater.best_estimator_) # 交叉验证结果:cv_results_ print( "交叉验证结果:\n" , knn_estimater.cv_results_) return None if __name__ == '__main__' : facebook_demo() |
朴素贝叶斯算法
概率(Probability):
联合概率、条件概率与相互独立
联合概率:包含多个条件,且所有条件同时成立的概率
条件概率:就是事件A在另外一个事件B已经发生条件下的发生概率
相互独立: P(A, B) = P(A)P(B) <=> 事件A与事件B相互独立
朴素:
假设:特征与特征之间是相互独立朴素贝叶斯算法: 朴素 + 贝叶斯
应用场景:
文本分类
单词作为特征
概率
朴素贝叶斯
拉普拉斯平滑系数
朴素贝叶斯API(naive表示朴素的意思)
20类新闻分类DEMO
案例分析:20类新闻分类(sklean会从官网下载数据,约14M)
1)获取数据
2)划分数据集
3)特征工程 -->文本特征抽取(TF-IDF)
4)朴素贝叶斯预估器流程
5)模型评估
1 2 3 4 | from sklearn.datasets import fetch_20newsgroups from sklearn.model_selection import train_test_split from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.naive_bayes import MultinomialNB |
def nb_news():
"""
用朴素贝叶斯算法对新闻进行分类
:return:
"""
# 1)获取数据
news = fetch_20newsgroups(subset="all")
# 2)划分数据集
x_train, x_test, y_train, y_test = train_test_split(news.data, news.target)
# 3)特征工程:文本特征抽取-tfidf
transfer = TfidfVectorizer()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
# 4)朴素贝叶斯算法预估器流程
estimator = MultinomialNB()
estimator.fit(x_train, y_train)
# 5)模型评估
# 方法1:直接比对真实值和预测值
y_predict = estimator.predict(x_test)
print("y_predict:\n", y_predict)
print("直接比对真实值和预测值:\n", y_test == y_predict)
# 方法2:计算准确率
score = estimator.score(x_test, y_test)
print("准确率为:\n", score)
return None
if __name__ == '__main__':
nb_news()
决策树
简单讲,决策树就是我们Py语言中的if-elif-else语句,通过对特征的先后顺序进行选择,从而达到高效的决策
决策树的原理
信息论基础
1)信息(香农定义) :消除随机不定性的东西
小明 年龄 “我今年18岁” - 信息
小华 ”小明明年19岁” - 不是信息
2)信息的衡量 –》 信息量 -》 信息熵
信息的单位:比特(bit)
g(D,A) = H(D) - 条件熵H(D|A)
4 决策树的划分依据之一------信息增益
决策树的API
案例一: 鸢尾花决策树demo –> 结果表明KNN算法更好
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.tree import DecisionTreeClassifier, export_graphviz def decision_iris(): "" " 用决策树对鸢尾花进行分类 : return : "" " # 1 )获取数据集 iris = load_iris() # 2 )划分数据集 x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state= 22 ) # 3 )决策树预估器 estimator = DecisionTreeClassifier(criterion= "entropy" ) estimator.fit(x_train, y_train) # 4 )模型评估 # 方法 1 :直接比对真实值和预测值 y_predict = estimator.predict(x_test) print( "y_predict:\n" , y_predict) print( "直接比对真实值和预测值:\n" , y_test == y_predict) # 方法 2 :计算准确率 score = estimator.score(x_test, y_test) print( "准确率为:\n" , score) # 可视化决策树 export_graphviz(estimator, out_file= "iris_tree.dot" , feature_names=iris.feature_names) return None if __name__ == '__main__' : decision_iris() |
可视化:
案例二:泰坦尼克号乘客生存预测
流程分析:获取特征值&目标值
1)获取数据
2)数据处理
缺失值处理
特征值 -> 字典类型
3)准备好特征值 目标值
4)划分数据集
5)特征工程:字典特征抽取
6)决策树预估器流程
7)模型评估
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import pandas as pd def titanic_demo(): # 1 、获取数据 # titanic = pd.read_csv( "F:\instacart\\titanic_demo.txt" ) # 小数据,仅部分 titanic = pd.read_csv(path) # 大数据 # 筛选特征值和目标值 x = titanic[[ "pclass" , "age" , "sex" ]] y = titanic[ "survived" ] # 2 、数据处理 # 1 )缺失值处理 x[ "age" ].fillna(x[ "age" ].mean(), inplace=True) # 填补平均值,inplace表示填补数据到原数据 # 2 ) 转换成字典 x = x.to_dict(orient= "records" ) # x代表dataform, orient=”record”代表json格式 from sklearn.model_selection import train_test_split |
1 2 | # 3 、数据集划分 x_train, x_test, y_train, y_test = train_test_split(x, y, random_state= 22 ) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | # 4 、字典特征抽取 from sklearn.feature_extraction import DictVectorizer from sklearn.tree import DecisionTreeClassifier, export_graphviz transfer = DictVectorizer() x_train = transfer.fit_transform(x_train) x_test = transfer.transform(x_test) # 3 )决策树预估器 estimator = DecisionTreeClassifier(criterion= "entropy" , max_depth= 8 ) estimator.fit(x_train, y_train) # 4 )模型评估 # 方法 1 :直接比对真实值和预测值 y_predict = estimator.predict(x_test) print( "y_predict:\n" , y_predict) print( "直接比对真实值和预测值:\n" , y_test == y_predict) # 方法 2 :计算准确率 score = estimator.score(x_test, y_test) print( "准确率为:\n" , score) # 可视化决策树 export_graphviz(estimator, out_file= "titanic_tree.dot" , feature_names=transfer.get_feature_names()) if __name__ == '__main__' : titanic_demo() <a href= "https://img2018.cnblogs.com/blog/519608/201903/519608-20190310193433622-2026698693.png" ><img style= "background-image: none; border: 0; margin: 0; padding-left: 0; padding-right: 0; display: inline; padding-top: 0" title= "image" border= "0" alt= "image" src= "https://img2018.cnblogs.com/blog/519608/201903/519608-20190310193434109-601826324.png" width= "708" height= "347" ></a> |
随机森林
随机森林原理过程
训练集: N个样本,包含特征值+目标值
特征值: M个特征
随机 = 两个随机(训练随机 + 特征随机)
1、训练集随机 --》 从N个样本中随机有放回的抽样N个
bootstrap(随机有放回抽样)
假设有原始数据集合:[1, 2, 3, 4, 5],第一次抽取到了2,然后放回原数据集,抽到下一个数字还是2,放回后下个是3,以此类推,产生新的树的训练集[2, 2, 3, 1, 5]
2、特征随机 - 从M个特征中随机抽取m个特征
M >> m(M远远大于m),相当于我们之前的【降维】,特征数量减少了,
随机森林的API
随机森林-泰坦尼克号demo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | import pandas as pd from sklearn.feature_extraction import DictVectorizer from sklearn.tree import DecisionTreeClassifier, export_graphviz from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import GridSearchCV def random_tree_titanic_demo(): # 1 、获取数据 titanic = pd.read_csv( "F:\instacart\\titanic_demo.txt" ) # 小数据,仅部分 # titanic = pd.read_csv(path) # 大数据 # 筛选特征值和目标值 x = titanic[[ "pclass" , "age" , "sex" ]] y = titanic[ "survived" ] # 2 、数据处理 # 1 )缺失值处理 x[ "age" ].fillna(x[ "age" ].mean(), inplace=True) # 2 ) 转换成字典 x = x.to_dict(orient= "records" ) from sklearn.model_selection import train_test_split # 3 、数据集划分 x_train, x_test, y_train, y_test = train_test_split(x, y, random_state= 22 ) # 4 、字典特征抽取 transfer = DictVectorizer() x_train = transfer.fit_transform(x_train) x_test = transfer.transform(x_test) # 3 )决策树预估器 estimator = RandomForestClassifier() # 加入网格搜索与交叉验证 # 参数准备 param_dict = { "n_estimators" : [ 120 , 200 , 300 , 500 , 800 , 1200 ], "max_depth" : [ 5 , 8 , 15 , 25 , 30 ]} estimator = GridSearchCV(estimator, param_grid=param_dict, cv= 3 ) estimator.fit(x_train, y_train) # 5 )模型评估 # 方法 1 :直接比对真实值和预测值 y_predict = estimator.predict(x_test) print( "y_predict:\n" , y_predict) print( "直接比对真实值和预测值:\n" , y_test == y_predict) # 方法 2 :计算准确率 score = estimator.score(x_test, y_test) print( "准确率为:\n" , score) # 最佳参数:best_params_ print( "最佳参数:\n" , estimator.best_params_) # 最佳结果:best_score_ print( "最佳结果:\n" , estimator.best_score_) # 最佳估计器:best_estimator_ print( "最佳估计器:\n" , estimator.best_estimator_) # 交叉验证结果:cv_results_ print( "交叉验证结果:\n" , estimator.cv_results_) if __name__ == '__main__' : random_tree_titanic_demo() |
其他
资料链接:https://pan.baidu.com/s/1apbuwSIfSx7OqcFS9KqVBg
提取码:lvaq
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 字符编码:从基础到乱码解决