欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Python人工智能高级69(pandas,k-近邻算法)

程序员文章站 2022-03-13 12:06:18
...

1、缺失值处理

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

data = pd.read_csv('./data/IMDB-Movie-Data.csv')

# 判断是否有缺失
res = pd.isnull(data)   # 判断每个元素是否是NaN
# 判断res里是否有True
np.any(res)

res_2 = pd.notnull(data)   # 判断每个元素是否不是NaN
# 判断res里是否全部都是True
np.all(res_2)

# 1.删除缺失值
data.dropna()
# 2.填充(替换)缺失值
# data.fillna(value=data.mean())
data.fillna(value=data.median())

# 有特殊标记的缺失
wis = pd.read_csv("https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data")
# 把有特殊标记的缺失值替换成np.nan
wis.replace(to_replace='?',value=np.nan).head(50)

2、数据离散化

为什么要离散化:

       连续属性离散化的目的是为了简化数据结构,数据离散化技术可以用来减少给定连续属性值的个数。

什么是数据的离散化:

       连续属性的离散化就是在连续属性的值域上,将值域划分为若干个离散的区间,最后用不同的符号或整数值代表落在每个子区间中的属性值。

代码过程:

# 读取数据
data = pd.read_csv('./data/stock_day.csv')

# 获取某一列数据
p_change = data['p_change']

# 进行数据离散化   label 离散化之后每个类别的标记
res = pd.qcut(p_change, 3, labels=['A','B','C'])   # 1.把样本平均分到指定数量的类别中
res.value_counts()   # 统计各个类别的数量
res = pd.cut(p_change, 3)   # 2.把区间平均分
# res = pd.cut(p_change, [-100, -7, -5, -3, 0, 3, 5, 7, 100])   # 把区间平均分

one-hot编码

# one_hot编码
res = pd.get_dummies(res, prefix='abc')

数据合并:

# 1.把one_hot编码后的数据合并到数据集中
pd.concat([data, res], axis=1)

# 2.merge合并数据集
left = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],
                        'key2': ['K0', 'K1', 'K0', 'K1'],
                        'A': ['A0', 'A1', 'A2', 'A3'],
                        'B': ['B0', 'B1', 'B2', 'B3']})
right = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],
                        'key2': ['K0', 'K0', 'K0', 'K0'],
                        'C': ['C0', 'C1', 'C2', 'C3'],
                        'D': ['D0', 'D1', 'D2', 'D3']})
pd.merge(left=left, right=right, on=['key1','key2'], how='inner')
pd.merge(left=left, right=right, on=['key1','key2'], how='left')
pd.merge(left=left, right=right, on=['key1','key2'], how='right')
pd.merge(left=left, right=right, on=['key1','key2'], how='outer')

交叉表和透视表: 

# 探究股票的涨跌与星期几有关
# 获取每一行是周几的数据,生成新的一列数据
data['week'] = pd.to_datetime(data.index).weekday

# 创建涨跌特征列
data['rise'] = np.where(data['p_change'] > 0, 1, 0)

# 建立交叉表
temp = pd.crosstab(data['week'], data['rise'])

temp.sum(axis=1)
res = temp.div(temp.sum(axis=1), axis=0)
# 绘图
res.plot(kind='bar', stacked=True)
plt.show()

# 透视表
pd.pivot_table(data=data, index='week', values='rise', aggfunc='mean')

分组与聚合:

col =pd.DataFrame({'color': ['white','red','green','red','green'], 'object': ['pen','pencil','pencil','ashtray','pen'],'price1':[5.56,4.20,1.30,0.56,2.75],'price2':[4.75,4.12,1.60,0.75,3.15]})

# 第一种分组聚合的方式,按照color进行分组
col.groupby('color').count()
# col.groupby('color')['price1'].count()

# 第二种分组聚合的方式
col['price1'].groupby(col['color']).count()

# 读取星巴克店铺数据
data = pd.read_csv('./data/directory.csv')

# 按照Country进行分组
res = data.groupby(['Country']).count()

# 绘制柱状图
res.plot(kind='bar',figsize=(20,8))
plt.show()

3、k-近邻算法

概念:

       如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。

代码过程:

# 导入工具
from sklearn.neighbors import KNeighborsClassifier

# 1、获取数据
x = [[0], [1], [2], [3]]
y = [0, 0, 1, 1]

# 2、数据基本处(略)

# 3、特征工程(略)

# 4、机器学习
#  4.1 构建模型
estimator = KNeighborsClassifier(n_neighbors=2)
#  4.2 训练模型
estimator.fit(x, y)

# 5、模型评估(略)

# 预测
estimator.predict([[-1]])

k值的选择对模型的影响:

       1) 选择较小的K值,就相当于用较小的领域中的训练实例进行预测,“学习”近似误差会减小,只有与输入实例较近或相似的训练实例才会对预测结果起作用,与此同时带来的问题是“学习”的估计误差会增大,换句话说,K值的减小就意味着整体模型变得复杂,容易发生过拟合;

       2) 选择较大的K值,就相当于用较大领域中的训练实例进行预测,其优点是可以减少学习的估计误差,但缺点是学习的近似误差会增大。这时候,与输入实例较远(不相似的)训练实例也会对预测器作用,使预测发生错误,且K值的增大就意味着整体的模型变得简单。

       3) K=N(N为训练样本个数),则完全不足取,因为此时无论输入实例是什么,都只是简单的预测它属于在训练实例中最多的类,模型过于简单,忽略了训练实例中大量有用信息。

       近似误差:对现有训练集的训练误差,关注训练集,如果近似误差过小可能会出现过拟合的现象,对现有的训练集能有很好的预测,但是对未知的测试样本将会出现较大偏差的预测。模型本身不是最接近最佳模型。

       估计误差:可以理解为对测试集的测试误差,关注测试集,估计误差小说明对未知数据的预测能力好,模型本身最接近最佳模型。

kd树:

       为了避免每次都重新计算一遍距离,算法会把距离信息保存在一棵树里,这样在计算之前从树里查询距离信息,尽量避免重新计算。其基本原理是,如果A和B距离很远,B和C距离很近,那么A和C的距离也很远。有了这个信息,就可以在合适的时候跳过距离远的点。

       根节点 :没有父节点

       内部节点 :有父节点,也有子节点

       叶子节点 :只有父节点

       二叉树 :每个节点的分支数量最多是2