数据缺失值填充—KNN估计
运行环境
python3.6
jupyter notebook
一、基本思想
先将数据标准化,然后对缺失值的数据点做k邻近填充,计算含缺失值的数据点与其他不含缺失值的数据点的距离矩阵,选出欧氏距离最近的k个数据点。
用选中的k个近邻的数据点对应的字段均值来填充数据中的空缺值。
二、步骤
1.导入数据
import pandas as pd
data = pd.read_csv('iris-带空格数据.csv')
data['id'] = [i for i in range(0,150)] #加入id列
2.查看空缺值
index = [] #存放空缺值的位置
for i in data.columns:
a=data[data[i] == ' '].index.tolist()
index.append(a)
index#一共有七列数据,空缺值在第5列,第三行
输出结果为:[[], [], [], [], [2], [], []]
3.取出要分析的数据
data.iloc[2,4] = 0 #将空值变为0
new_data = data.iloc[:,1:4]#计算空缺值只需要前三列数据
4.计算平均值
#平均值
avg =[]#用来存放平均值
for i in new_data.columns:#遍历dataframe列名
a = new_data[i].values.tolist()#取出每一列的数据,转成列表
sum = 0
for i in range(0,len(a)):
sum = sum + float(a[i])#求每一列数据之和
avg.append(sum/len(a))#求平均
avg
结果为:[1.199333333333334, 3.7580000000000027, 3.057333333333334]
5.计算标准差
#标准差
all_value=[]
for i in new_data.columns:
a = new_data[i].values.tolist()#每一列的数据转成列表
all_value.append(a)#每一列的列表加入到all_value
biaozhuncha = []
for i in range(0,new_data.shape[1]):#一共三列,所以遍历三次。
sum = 0
for j in all_value[i]:
sum = sum + ((float(j)-avg[j])*(float(j)-avg[j]))#计算每一列数据减去对应列的平均值的平方之和
b = (sum/new_data.shape[0]) ** 0.5#计算每一列数据的标准差
biaozhuncha.append(b)#把标准差加入到biaozhuncha列表中
biaozhuncha
6.规范化
#z_score规范化
result = []
for i in range(0,new_data.shape[1]):#遍历三次,因为有三列数据
z_score=[]
for j in all_value[i]:#all_value列表,就是上面用到了存放所有列数据的二维列表
c = (float(j)-avg[i])/biaozhuncha[i]#计算出某一列规范化后的结果
z_score.append(c)#结果保存在z_score列表中
result.append(z_score)#把三列的结果汇总
new_data['Petal_width'] = result[0]#接着,把规范化得到的结果替换new_data中的值
new_data['Petal_length'] = result[1]
new_data['Sepal_width'] = result[2]
7.计算欧几里得距离
value_result=[]
for i in new_data.columns:
lie_value = []
for j in new_data[i].values.tolist():
lie_value.append(j)
value_result.append(lie_value)
#此处,将上面得到的规范化结果保存成二位列表,方便后面的计算。
d_list=[]
for i in range(0,new_data.shape[0]):
d = 0
for j in range(0,new_data.shape[1]):
d = d+((new_data.iloc[i,j]-new_data.iloc[2,j])*(new_data.iloc[i,j]-new_data.iloc[2,j]))
d_list.append(d**0.5) result = d_list
df = pd.DataFrame(d_list)#将结果转成dataframe方便我排序。
8.最优解
all_data_result = []
for i in range(3,20):
all_data=[]
for j in df.drop(2).sort_values(by=0).head(i).index:
all_data.append(data.iloc[j,4])
#print(all_data)
all_data_result.append(all_data)
b_list = []
for i in range(len(all_data_result)):
sum = 0
for j in all_data_result[i]:
sum = sum + float(j)
b = sum/len(all_data_result[i])
b_list.append(b)
9.画图
对3到50的预测结果进行可视化。
import matplotlib.pyplot as plt
%matplotlib inline
#把图插在网页里
plt.plot([i for i in range(3,50)],b_list)
总结
本次实验学习到了很多关于dataframe的操作,有一些对于列表的操作我不是很熟练,但是我可以把列表转成dataframe类型在进行操作。此外,我也很少调用一些对数据计算的函数,让我更加了解到计算平均、标准差和欧几里得距离的方法。对于k-means的算法也有了一定的认识,可以使用一些基本的方法来预测数据并填充空缺值。
数据和源码:链接:https://pan.baidu.com/s/1TPwte04gxkk0Rmna6BQ6iw
提取码:1025