离散与连续
数据–数据对象、样本、实例
离散属性–类别属性
- 用名称标注
- 用类别/类别号来标注
连续属性–连续的小数
- 在一个区间内连续,用浮点型数值表示
数据集
多个数据组合在一起–数据集合–数据集
- 行:代表样本
- 列:代表属性
一、机器学习
(一)概念
在历史数据中发现规律,然后利用规律,对新的数据进行预测与指导。
(二)数据分析与数据挖掘
人工智能的基础
想要一个好的机器学习结果,就必须有一个好的数据处理。
数据分析与数据挖掘的区别
数据分析主要偏向于业务。
数据挖掘主要偏向于对数据价值的挖掘。
(三)按照学习方式分类
1.监督学习
数据:既有特征值,又有目标值
研究:研究的是特征与目标之间的关系
数据集
训练集与测试集的划分
算法代表
1.分类算法:目标值是离散的
(1)KNN算法
特点
- k值不同,分类的结果不同
- 需要将所有的数据,加载到内存,不断计算每一个测试样本与训练样本的距离。时间、空间消耗比较大。
- 惰性学习算法
优化
(2)贝叶斯算法
2.回归算法:目标值是连续的
2.无监督学习
数据:只有特征值,无目标值数据
研究:研究的是样本和样本之间的关系
数据集
不需要划分
算法代表
1.聚类算法–K-Means算法
利用样本的特征,使最终的结果,同一类别内的样本具有较高的相似性,不同类别的样本具有较高的相异性。
3.半监督学习
隐马尔可夫模型
二、K-Means
应用场景
用于用户群体的划分。
(一)k-means原理自实现
# 科学计算库
import numpy as np
# 数据可视化库
import matplotlib.pyplot as plt
# 数据处理库
import pandas as pd
def bulid_data():
'''
构建数据
:return:数据
'''
# 加载数据
# 1.open
# 2.np.loadtxt/np.genfromtxt -- 文本类型的数组
# 3.pd.read_table
# sep和delimiter都可以指定分隔符
# header=None -- 不让它将第一行设为行标
data = pd.read_table('test.txt',sep='\t',header=None)
# 转化为矩阵(矩阵--特殊的数组)
# mat = asmatrix
# matrix -- 比mat多了一个拷贝内存的过程
# bmat -- 组合矩阵
data = np.mat(data.values)
return data
def center_init(data,k):
'''
聚类中心初始化
:param data: 数据
:param k: 聚类的类别数目
:return: center
'''
# 确定数据的行下标范围
index_num = data.shape[0]
# 确定数据的列数
column_num = data.shape[1]
# 使用全零数组为聚类中心占位
center = np.zeros((k,column_num))
# 随机选择所有样本中的k个样本作为最开始的聚类中心
# 计数器
i = 0
# 避免重复
r_list = []
while True:
r = np.random.randint(0,index_num-1)
if r in r_list:
continue
else:
r_list.append(r)
center[i,:] = data[r,:]
i+=1
if len(r_list) == k:
break
return center
def distance(v1,v2):
'''
距离计算
:param v1: 点1
:param v2: 点2
:return: 距离
'''
# # 方法1
# sum_ = 0
# # v1.shape -- 二维
# # v2.shape -- 一维
# # 将v1由2维降为1维
# # 将矩阵转换为数组:使用矩阵视图
# # 矩阵.A --> 数组
# v1 = v1.A[0]
# if v1.shape == v2.shape:
# for i in range(len(v1)):
# sum_ += (v1[i] - v2[i])**2
# return np.sqrt(sum_)
# 方法2
diff = v1 - v2
d = np.sqrt(np.sum(np.power(diff,2)))
return d
def k_means_owns(data,k):
'''
自实现k-means原理
:param data: 数据
:param k: 聚类的类别数目
:return: 各个样本最终的类别,最终的聚类中心
'''
# 初始化聚类中心--随机初始化
# 随机在所有样本中选取k个聚类中心
center = center_init(data,k)
# 数据行数
index_num = data.shape[0]
# 定义数组,保存距离样本最近的聚类中心及距离
new_data = np.zeros((index_num,2))
flag = True
while flag:
flag = False
# 计算每一个训练样本与聚类中心的距离
# 双层循环----外层 -- 训练样本
# 内层 -- 聚类中心
for i in range(index_num):
min_dist = 10000000000000000000
min_index = -1
for j in range(k):
# 计算距离
# 高纬度的数组使用下标,会进行降维度
# 矩阵是二维的特殊数组,使用索引不会降维度
d = distance(data[i, :], center[j, :])
# print(d)
if d < min_dist:
min_dist = d
min_index = j
# 如果当前的样本属于的簇与上一次的不一致
if new_data[i,0] != min_index:
new_data[i:] = min_index, min_dist
flag = True
if flag:
# 计算新的聚类中心
# 计算每一簇的均值 -- 每一簇的中心
# 使用bool数组索引
for p in range(k):
bool_index = new_data[:, 0] == p
# 选定簇
p_cluster = data[bool_index, :]
# 新的聚类中心
center[p, :] = p_cluster[:, 0].mean(), p_cluster[:, 1].mean()
# 如果新的聚类中心,与上一次的聚类中心重合--结束
# 改变思路:如果所有样本所属的聚类中心,与上一次所属的聚类中心相同--结束
return new_data,center
def show_res_owns(data,new_data,center):
'''
结果展示
:param data: 原始数据
:param new_data: 保存着各个样本最终的类别
:param center: 最终的聚类中心
:return: None
'''
# 1.创建画布
plt.figure()
# 显示中文,支持负号
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False
# 2.绘图
# 设置颜色列表
c_list = ['b','g','y','pink']
# 设置点形状列表
marker_list = ['*','o','^','D']
# 绘制散点图
for i in range(data.shape[0]):
plt.scatter(data[i,0],data[i,1],c=c_list[int(new_data[i,0])],marker=marker_list[int(new_data[i,0])])
# 绘制聚类中心
plt.plot(center[:,0],center[:,1],'bx',markersize=12)
# 增加名称
plt.title('聚类结果展示')
# 保存图片
plt.savefig('聚类结果展示')
# 3.绘图展示
plt.show()
def main():
# 1.构建数据
data = bulid_data()
# print(data)
# print(type(data))
# print(data.dtype)
# 2.自实现k-means算法原理
# 确定聚类的类别数目
k = 4
new_data,center = k_means_owns(data,k)
# 3.结果展示
show_res_owns(data,new_data,center)
if __name__ == '__main__':
main()
(二)使用sklearn
# 科学计算库
import numpy as np
# 数据可视化库
import matplotlib.pyplot as plt
# 数据处理库
import pandas as pd
from sklearn.cluster import KMeans
def bulid_data():
'''
构建数据
:return:数据
'''
# 加载数据
# 1.open
# 2.np.loadtxt/np.genfromtxt -- 文本类型的数组
# 3.pd.read_table
# sep和delimiter都可以指定分隔符
# header=None -- 不让它将第一行设为行标
data = pd.read_table('test.txt',sep='\t',header=None)
# 转化为矩阵(矩阵--特殊的数组)
# mat = asmatrix
# matrix -- 比mat多了一个拷贝内存的过程
# bmat -- 组合矩阵
data = np.mat(data.values)
return data
def show_res(data,y_predict,center):
'''
结果展示
:param data: 原始数据
:param y_predict:预测类别
:param center: 聚类中心
:return: None
'''
# 1.创建画布
plt.figure()
# 显示中文,支持负号
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False
# 2.绘图
# 设置颜色列表
c_list = ['b','g','y','pink']
# 设置点形状列表
marker_list = ['*','o','^','D']
# 绘制散点图
for i in range(data.shape[0]):
plt.scatter(data[i,0],data[i,1],c=c_list[y_predict[i]],marker=marker_list[y_predict[i]])
# 绘制聚类中心
plt.plot(center[:,0],center[:,1],'bx',markersize=12)
# 增加名称
plt.title('聚类结果展示')
# 保存图片
plt.savefig('聚类结果展示')
# 3.绘图展示
plt.show()
def main():
# 1.构建数据
data = bulid_data()
# 2.使用sklearn中的KMeans进行聚类分析
# 确定聚类的类别数目
k = 4
# (1)构建算法实力
# n_clusters--指定聚类的类别
km = KMeans(n_clusters=k)
# init='k-means++'--以一种更优的方式选取初始聚类中心
# (2)进行训练数据
km.fit(data)
# (3)验证模型的好坏,即得到预测值
y_predict = km.predict(data)
# k-means算法--得到聚类中心
center = km.cluster_centers_
print('预测类别:\n',y_predict)
print('聚类中心:\n',center)
# 3.结果可视化
show_res(data,y_predict,center)
if __name__ == '__main__':
main()
(三)实例–NBA球星(sklearn)
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
def show_res(data,y_predict,center):
'''
结果展示
:param data: 原始数据
:param y_predict:预测类别
:param center: 聚类中心
:return: None
'''
# 1.创建画布
plt.figure()
# 显示中文,支持负号
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False
# 2.绘图
# 设置颜色列表
c_list = ['b','g','y','pink','red']
# 设置点形状列表
marker_list = ['*','o','^','D','8']
# 绘制散点图
for i in range(data.shape[0]):
plt.scatter(data[i,0],data[i,1],c=c_list[y_predict[i]],marker=marker_list[y_predict[i]])
# 绘制聚类中心
plt.plot(center[:,0],center[:,1],'bx',markersize=12)
# 增加名称
plt.title('NBA球星聚类结果展示')
# 保存图片
plt.savefig('NBA球星聚类结果展示')
# 3.绘图展示
plt.show()
def build_data(data):
'''
数据预处理
:return:预处理后的数据
'''
# 2.数据合并
# 只有一个表
# 3.数据清洗
# (1)检测与处理缺失值
# 检测:pd.inull().sum()
# 处理:删除值、填充法、插值法
# 处理非NaN类型缺失值,先将这种数据转化为np.NaN类型,再进行处理
# res_null = pd.isnull(data).sum()
# print(res_null) # 无缺失值
# (2)处理异常值
# 3sigma原理、箱线图分析法
# 无异常值
# 4.筛选有用的特征
data = data.loc[:, ['时间', '助攻', '得分']]
# print(data.dtypes)
# 时间 object
# 助攻 float64
# 得分 float64
# 将时间这一列的空格缺失值,转换成np.NaN类型
data.loc[:, '时间'].replace(' ', np.NaN, inplace=True)
# res_null = pd.isnull(data).sum()
# print(res_null) # 时间列有393个空值
# 处理缺失值
# 使用上一个邻居来填充缺失值
data.loc[:'时间'].fillna(method='pad', inplace=True)
# res_null = pd.isnull(data).sum()
# print(res_null) # 无空值
# 将时间的数据类型转化为float类型
data.loc[:, '时间'] = data.loc[:, '时间'].astype(np.float64)
# print(data.dtypes)
# 构建最终的得分/分钟 助攻/分钟
data.loc[:, '得分/分钟'] = data.loc[:, '得分'] / data.loc[:, '时间']
data.loc[:, '助攻/分钟'] = data.loc[:, '助攻'] / data.loc[:, '时间']
data = data.loc[:, ['得分/分钟', '助攻/分钟']]
return data
def main():
# 1.加载、构建数据
data = pd.read_excel('nba_data.xlsx')
# print(data)
# print(data.columns)
data = build_data(data)
# [5].标准化?
# 做数据分析时,暂时不要做;要进行机器学习算法构建模型的时候,必须要做
# 无需消除量纲
# [6].构建模型--算法模型--进行训练数据--进行预测
# 确定聚类类别数量
k = 5
# 创建算法实例
km = KMeans(n_clusters=k)
# 训练数据
km.fit(data.values)
# 进行预测
y_predict = km.predict(data.values)
# 预测中心
center = km.cluster_centers_
print('预测值:\n',y_predict)
print('聚类中心:\n',center)
# 7.数据可视化--折线图、散点图、直方图、柱状图、饼图、箱线图
show_res(data.values,y_predict,center)
# 8.结论
if __name__ == '__main__':
main()
三、补充
(一)3sigma
异常值处理之3sigma
import pandas as pd
# 3sigma原则
# [mean-3*std,mean+s*std]
# 99.73%的数据
def three_sigma(data):
'''
进行3sigma异常值处理
:param data: 需要进行处理的数据--series
:return: bool数组
'''
# 下限
low = data.mean() - 3*data.std()
up = data.mean() + 3*data.std()
# 正常--True,异常--False
bool_index = (low <= data) & (data <= up)
return bool_index
# 验证异常值处理
detail = pd.read_excel('meal_order_detail.xlsx')
# print(detail)
# print(detail.columns)
print(detail.shape[0])
# 对菜品的单价数据进行异常值剔除
bool_index = three_sigma(detail.loc[:, "amounts"])
detail = detail.loc[bool_index,:]
# print('按照菜品单价剔除异常值之后的结果\n',detail)
print(detail.shape[0])
(二)标准化
量级相差过大,就需要进行标准化
1.离差标准化
x = (x-min)/(max-min)
2.标准差标准化(推荐)
x = (x-mean)/std
3.小数定标标准化
通过移动数据的小数点位置来进行标准化。
k --> int(np.ceil(np.log10(|x|.max())))
x = x/10^k
(三)维度
行的方向是行增大的方向,即向下
列的方向是列增大的方向,即向右
1.一维
shape:(9,)
一维的数组只有列维度
axis=0,axis=-1 – 代表列维度
2.二维(多个一维组成)
shape:(2,3)
行列维度
axis=0,axis=-2 – 代表行维度
axis=1,axis=-1 – 代表列维度
3.三维(多个二维组成)
shape:(1,2,3)
块行列维度
axis=0 – 代表块维度
axis=1 – 代表行维度
axis=2 – 代表列维度
4.四维(多个三维组成)
shape:(1,2,3,4)
堆块行列维度
……
……
mean()默认维度测试
import numpy as np
import pandas as pd
df = pd.DataFrame(data=np.array([[1,2,5],[1,3,4],[4,4,5]]))
print(df)
print(df.mean())
# 0 1 2
# 0 1 2 5
# 1 1 3 4
# 2 4 4 5
# 0 2.000000
# 1 3.000000
# 2 4.666667
# dtype: float64
发现最终的结果,求的是一列的平均值,即行增大的方向,也就是按行的方向求的。
即mean()默认的axis=0。
四、作业
- 将NBA实例的sklearn实现改为自实现
- 超市用户聚类案例
(一)NBA–自实现
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
def bulid_data(data):
data = data.loc[:,['时间','助攻','得分']]
# res_null = pd.isnull(data).sum()
# print(res_null)
data.loc[:,'时间'].replace(' ',np.NaN,inplace=True)
data.loc[:,'时间'].fillna(method='pad',inplace=True)
data.loc[:'时间'] = data.loc[:'时间'].astype(np.float64)
data.loc[:,'助攻/时间'] = data.loc[:,'助攻']/data.loc[:,'时间']
data.loc[:,'得分/时间'] = data.loc[:,'得分']/data.loc[:,'时间']
data = data.loc[:,['得分/时间','助攻/时间']]
return np.mat(data.values)
def center_init(data,k):
index_num = data.shape[0]
column_num = data.shape[1]
# print(index_num)
center = np.zeros((k,column_num))
r_list = []
i = 0
while True:
r = np.random.randint(0,index_num-1)
if r in r_list:
continue
else:
r_list.append(r)
center[i,:] = data[r,:]
i += 1
if len(r_list) == k:
break
return center
def distance(v1,v2):
diff = v1-v2
return np.sqrt(np.sum(np.power(diff,2)))
def k_means_owns(data,k):
# 随机选取k个聚类中心
center = center_init(data,k)
index_num = data.shape[0]
new_data = np.zeros((index_num,2))
flag = True
while flag:
flag = False
for i in range(index_num):
min_distence = 1000000000000000
min_index = -1
for j in range(k):
# 计算距离聚类中心距离
d = distance(data[i,:],center[j,:])
if d < min_distence:
min_distence = d
min_index = j
if new_data[i,0] != min_index:
flag = True
new_data[i,:] = min_index,min_distence
if flag:
# 计算新的聚类中心
for p in range(k):
bool_index = new_data[:,0] == p
p_cluster = data[bool_index,:]
center[p,:] = p_cluster[:,0].mean(),p_cluster[:,1].mean()
return new_data,center
def show_res(data,new_data,center):
plt.figure()
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False
c_list = ['c','g','y','pink','red']
marker_list = ['*','o','^','D','8']
# 绘制样本数据
for i in range(data.shape[0]):
plt.scatter(data[i,0],data[i,1],c=c_list[int(new_data[i,0])],marker=marker_list[int(new_data[i,0])])
# 绘制聚类中心
plt.plot(center[:, 0], center[:, 1], 'bx', markersize=12)
plt.title('NBA球星聚类分析结果')
plt.savefig('NBA球星聚类分析结果')
plt.show()
def main():
# 读取数据
data = pd.read_excel('../03.实例:基于k_means算法实现NBA球员聚类分析/nba_data.xlsx')
# print(data)
# 构建数据
data = bulid_data(data)
# k-means自实现
# 确定聚类中心个数
k = 5
new_data,center = k_means_owns(data, k)
show_res(data,new_data,center)
if __name__ == '__main__':
main()
(二)超市用户–sklearn
import numpy as np
import pandas as pd
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
def stand_sca(data):
'''
标准差标准化
:param data:需要标准化的数据
:return:标准化后的数据
'''
data = (data-data.mean())/data.std()
return data
def min_max_sca(data):
'''
离差标准化
:param data: 需要标准化的数据
:return: 标准化后的数据
'''
data = (data-data.min(axis=0))/(data.max(axis=0)-data.min(axis=0))
return data
def desc_sca(data):
'''
小数定标标准化
:param data: 需要标准化的数据
:return: 标准化之后的数据
'''
k = int(np.ceil(np.log10(data.abs().max())))
data = data / (10**k)
return data
def build_data():
# 1.构建数据
data = pd.read_table('company.csv', sep=',', encoding='gbk')
# 2.筛选特征值
data = data.loc[:,['平均每次消费金额','平均消费周期(天)']]
# 3.缺失值检测
# res_null = pd.isnull(data).sum()
# print(res_null)
# 4.处理异常值
# 无异常值
# 5.标准化
# (1)标准差标准化
# data = stand_sca(data)
# (2)离差标准化
data = min_max_sca(data)
return np.mat(data.values)
def k_means(data):
# 确定聚类中心个数
k = 3
# 1.创建算法实例
km = KMeans(n_clusters=k)
# 2.训练数据
km.fit(data)
# 3.进行预测
y_predict = km.predict(data)
# 获取聚类中心
center = km.cluster_centers_
# print('预测值:\n',y_predict)
# print('聚类中心:\n',center)
return y_predict,center
def show(data,y_predict,center):
plt.figure()
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False
c_list = ['pink','yellow','green','blue']
marker_list = ['*','>','^','o']
for i in range(data.shape[0]):
plt.scatter(data[i,0],data[i,1],c=c_list[y_predict[i]],marker=marker_list[y_predict[i]])
plt.plot(center[:,0],center[:,1],'bx',markersize=12)
plt.title('超市用户聚类结果')
plt.savefig('超市用户聚类结果')
plt.show()
def main():
data = build_data()
# print(data)
y_predict,center = k_means(data)
show(data,y_predict,center)
if __name__ == '__main__':
main()
(三)超市用户–自实现
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
def stand_sca(data):
'''
标准差标准化
'''
data = (data - data.mean())/data.std()
return data
def min_max_sca(data):
'''
离差标准化
'''
data = (data - data.min())/(data.max()-data.min())
return data
def build_data():
# 获取数据
data = pd.read_table('company.csv', sep=',', encoding='gbk')
# 获取有效数据
data = data.loc[:,['平均每次消费金额','平均消费周期(天)']]
# 检测缺失值
# res_null = pd.isnull(data).sum()
# print(res_null)
# 检测异常值
# 无异常值
# 标准化
data = min_max_sca(data)
return np.mat(data.values)
def center_init(data,k):
index_num = data.shape[0]
center = np.zeros((k,data.shape[1]))
r_list = []
i = 0
while True:
r = np.random.randint(0,index_num-1)
if r in r_list:
continue
else:
center[i,:] = data[r,:]
r_list.append(r)
i += 1
if len(r_list) == k:
break
return center
def distance(v1,v2):
diff = v1-v2
d = np.sqrt(np.sum(np.power(diff,2)))
return d
def k_means_owns(data,k):
center = center_init(data,k)
# print(center)
index_num = data.shape[0]
column_num = data.shape[1]
new_data = np.zeros((index_num,column_num))
for i in range(index_num):
min_dis = 1000000000000
min_index = -1
for j in range(k):
d = distance(data[i,:],center[j,:])
if d < min_dis:
min_dis = d
min_index = j
new_data[i,:] = min_index,min_dis
for p in range(k):
bool_index = new_data[:,0] == p
p_cluster = data[bool_index,:]
center[p,:] = p_cluster[:,0].mean(),p_cluster[:,1].mean()
return new_data,center
def show(data,new_data,center):
plt.figure()
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False
c_list = ['pink','yellow','green','blue']
marker_list = ['*','>','^','o']
for i in range(data.shape[0]):
plt.scatter(data[i,0],data[i,1],c=c_list[int(new_data[i,0])],marker=marker_list[int(new_data[i,0])])
plt.plot(center[:,0],center[:,1],'bx',markersize=12)
plt.title('超市用户聚类结果')
plt.savefig('超市用户聚类结果')
plt.show()
def main():
data = build_data()
print(data)
k = 3
new_data,center = k_means_owns(data,k)
show(data,new_data,center)
if __name__ == '__main__':
main()