机器学习之文件的读取
1.知识补充
机器学习中,读取文件后要把读取到的内容存储在两个列表里(特征文件列表X和状态文件列表y),特征文件列表必须是多行一列,状态文件列表必须是多列一行,而且都要求是np.array类型的
即X是下面这样式的:
[[1000] [[8.32 5.36 3.69 ...]
[ 792] 或 [9.65 2.35 7.86...]
[1260] [4.56 1.32 7.89...]
... ....
] ]
而y是下面这样式的:
[168 184 197 220...]
例题一
一共有A、B、C、D、E 5个人的运动数据,每个人的数据有41列若干行,即41个特征值,每一个特征值代表一个人的此时的体温、此时的加速度、一个人所处环境磁场的数据等等,根据这些特征值可以预测这个人此时的运动状态(跑步,骑行,还是蹲着)。
这五个人的数据存储在featurePaths里面, featurePaths= [‘A/A.feature’,‘B/B.feature’,‘C/C.feature’,‘D/D.feature’,‘E/E.feature’]
这五个人的运动状态存储在labelPaths里面,labelPaths = [‘A/A.label’,‘B/B.label’,‘C/C.label’,‘D/D.label’,‘E/E.label’]
我们的目的是要把这些文件读取,将前四个人的数据作为训练集读入,将第五个人的数据作为测试集读入,读入后的文件被处理为feature,和label两个列表,feature列表样式是[[8.32 5.36 3.69 …] [9.65 2.35 7.86…] [4.56 1.32 7.89…] …]这种多行一列
label列表样式是这种[0 0 0 1 1 2 2 2]多列一行
#定义一个函数,用来读取特征文件列表和标签文件列表中的内容,归并到一个集合后返回
def load_datasets(feature_paths, label_paths):
feature = np.ndarray(shape=(0,41))#创建一个0行41列的空数组,用来读取特征文件列表里的内容
label = np.ndarray(shape=(0,1)) #创建一个0行1列的空数组,用来读取标签文件列表里的内容
for file in feature_paths:
df = pd.read_table(file, delimiter=',', na_values='?', header=None) #使用逗号分隔符读取特征数据,将问号替换标记为缺失值,文件不包含表头
feature = np.concatenate((feature, df)) #将数据加入feature
for file in label_paths:
df = pd.read_table(file, header=None) #读取标签数据,文件中不包含表头
label = np.concatenate((label, df))#将新读入的数据合并到标签集合中
#将标签归整为一维数组
label = np.ravel(label)
return feature, label
featurePaths =['A/A.feature','B/B.feature','C/C.feature','D/D.feature','E/E.feature']
labelPaths = ['A/A.label','B/B.label','C/C.label','D/D.label','E/E.label']
''' 调用函数,读入数据 '''
#将前4个数据集作为训练集读入
x_train,y_train = load_datasets(featurePaths[:4],labelPaths[:4])
#将最后1个数据作为测试集读入
x_test,y_test = load_datasets(featurePaths[4:],labelPaths[4:])
例题二
文件为:
#建立datasets_X和datasets_Y用来存储数据中的房屋尺寸和房屋成交价格。
datasets_X =[]
datasets_Y =[]
fr =open('F:/python数据/test4.txt','r')
lines =fr.readlines()
for line in lines:
items =line.strip().split(',')
datasets_X.append(int(items[0]))
datasets_Y.append(int(items[1]))
#此时的datasets_X为[1000, 792, 1260,,,]样式的
#此时的datasets_Y为[168, 184, 197,,,,]样式的
length =len(datasets_X) #求得datasets_X的长度,即为数据的总数。
datasets_X= np.array(datasets_X).reshape([length,1])#将datasets_X转化为数组, 并变为二维的多行一列的格式,以符合线性回 归拟合函数输入参数要求
datasets_Y=np.array(datasets_Y)#将datasets_Y转化为数组
'''
此时的datasets_X为
[[1000]
[ 792]
[1260]
...
]
样式的
此时的datasets_Y为[168 184 197 220...]样式的(没了逗号了)
'''
例题三
import numpy as np
data=np.array([[0,1,2,3,4],[9,8,7,6,5]])
X=data[:,:4]
y=data[:,4]
print(X)
print(y)
[[0 1 2 3]
[9 8 7 6]]
[4 5]
'''
我们看到,data[:,4]输出的y不是[[4],[5]]这样式的,否则还得y=np.ravel(y)这样处理一下使得y变成[4 5]这样多列一行的一维数组才能行
'''
已知real_X为
[[ 22 1558]
[ 12 40261]
[ 22 1721]
[ 23 351]
[ 16 23564]
[ 23 1162]
[ 22 3540]
...
]
X = real_X[:,0:1]
Y=real_X[:,0]
XX=real_X[:,1:]
YY=real_X[:,1]
'''
X为:
[[22]
[12]
[22]
[23]
[16]
[23]
[22]
...
]
Y为[22 12 22 23 16 23 22 ....]
XX为
[[ 1558]
[ 40261]
[ 1721]
[ 351]
[ 23564]
...
]
YY为[ 1558 40261 1721 351 23564 ...]
'''
a=pd.read_csv('F:/python数据/test5.csv')
data=np.array(a)
'''
data的样子是:
[[ 79 0 3 1 1 31]
[ 79 1 3 1 1 20]
...
[ 79 22 4 365 53 44]
[ 79 23 4 365 53 32]]
'''
#X用于保存0-5维数据,即属性
X=data[:,:5]
#y用于保存第6维数据,即车流量
y=data[:,5]
经过切片后,X已近符合多行一列的二维数组格式,y已经符合多列一行的一维数组格式,所以这就已经可以了
例题四
关于DBRHD数据集
实例(MLP神经网络实现手写识别实例编写)
此实例的数据集
(这是两个手写数据文件)
(每个数据文件里包含的内容)
假如trainingDigits里面有946份数据,那么我们就要做一个hwLabels矩阵,它包含10列数字946行。
我们知道文件“0_14"代表第14份文件的手写数字是0,
所以当读取到"0_14"时我们令hwLabels矩阵的第14行第0列标为1,而第14行的其他部分标注为0
这就是下面代码hwLabels[i][digit] = 1.0的原理
'''这个函数用来读取'trainingDigits'和'testDigits'里面的一个文件,将文件中的32x32的数字展开成一行'''
def img2vector(fileName):
retMat = np.zeros([1024],int) #定义返回的矩阵,大小为1*1024
fr = open(fileName) #打开包含32*32大小的数字文件
lines = fr.readlines() #读取文件的所有行
for i in range(32): #遍历文件所有行
for j in range(32): #将文件中的32x32的数字展开成一行
retMat[i*32+j] = lines[i][j]
return retMat
'''这个函数用来读取文件夹('trainingDigits'和'testDigits')'''
def readDataSet(path):
fileList = listdir(path) #获取文件夹下的所有文件
numFiles = len(fileList) #统计需要读取的文件的数目
dataSet = np.zeros([numFiles,1024],int) #用于存放所有的数字文件,int指明了里面是int类型
hwLabels = np.zeros([numFiles,10]) #设置一个有numFiles行10列的矩阵用于存放对应的one-hot标签
for i in range(numFiles): #遍历所有的文件
filePath = fileList[i] #获取文件名称/路径
digit = int(filePath.split('_')[0]) #通过文件名获取标签
hwLabels[i][digit] = 1.0 #将矩阵第i行第digit列标注为1
dataSet[i] = img2vector(path +'/'+filePath) #调用函数,读取文件内容
return dataSet,hwLabels
train_dataSet, train_hwLabels = readDataSet('trainingDigits') #调用函数
dataSet,hwLabels = readDataSet('testDigits') #调用函数
例题五
(数据举例:)
北京,2959.19,730.79,749.41,513.34,467.87,1141.82,478.42,457.64
天津,2459.77,495.47,697.33,302.87,284.19,735.97,570.84,305.08
河北,1495.63,515.90,362.37,285.32,272.95,540.58,364.91,188.63
山西,1406.33,477.77,290.15,208.57,201.50,414.72,281.84,212.10
…
def loadData(filePath):
fr = open(filePath,'r+',encoding='utf-8')
lines = fr.readlines()
retData = []
retCityName = []
for line in lines:
items = line.strip().split(",")
retCityName.append(items[0])
retData.append([float(items[i]) for i in range(1,len(items))])
return retData,retCityName
'''
retData大致的模样是:
[[2959.19, 730.79, 749.41, 513.34, 467.87, 1141.82, 478.42, 457.64],
[2459.77, 495.47, 697.33, 302.87, 284.19, 735.97, 570.84, 305.08]...]
'''
if __name__=='__main__':
filepath = r'E:\快乐的程序猿\city.txt'
data,cityName=loadData(filepath)
例题六
根据上网的时间(几点上的网)进行聚类
import numpy as np
mac2id = dict()
"""
在mac2id这个字典里:
键key是MAC地址
值value是字典里面对应的序号
"""
onlinetimes = []
f = open("F:/python数据/test1.txt",encoding='utf8')
for line in f:
data = line.split(',')
mac = data[2] #读取Mac地址
onlinetime = int(data[6]) #读取上网时长
starttime = int(data[4].split(' ')[1].split(':')[0]) #读取开始时间(我们只要年月日时分秒里的“时”)
mac2id[mac] = len(onlinetimes) #len(onlinetimes)就是此时对应的onlinetimes里面的元素个数,mac2id的内容见下面
onlinetimes.append((starttime,onlinetime))#onlinetimes里面的内容见下面
#onlinetimes里面的内容是[(22, 1558), (12, 40261), (22, 1721), (23, 351), (16, 23564),,,]
#mac2id这个字典里面是{'A417314EEA7B': 0, 'F0DEF1C78366': 1, '88539523E88D': 2,,,,'3CDFBD175878': 287, '002427FE3712': 288}
real_X = np.array(onlinetimes).reshape((-1,2)) #参数-1可以自动确定行数
X = real_X[:,0:1] # 截取第一列(也就是“上网时间”),我们是要根据上网的时间进行蔟类
'''
real_X为:
[[ 22 1558]
[ 12 40261]
[ 22 1721]
[ 23 351]
[ 16 23564]
[ 23 1162]
[ 22 3540]
...
]
X为:
[[22]
[12]
[22]
[23]
[16]
[23]
[22]
...
]
'''
例题七
已知降到2维后的鸢尾花数据集为reduced_X=
[[-2.68412563 0.31939725]
[-2.71414169 -0.17700123]
[-2.88899057 -0.14494943]
[-2.74534286 -0.31829898]
[-2.72871654 0.32675451]
...............
[ 1.90094161 0.11662796]
[ 1.39018886 -0.28266094]]
对应的标签为y=
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
2 2]
我们要根据标签y里面的数字将reduced_X分开存储到六个列表里
red_x, red_y = [], [] # 第一类数据点
blue_x, blue_y = [], [] # 第二类数据点
green_x, green_y = [], [] # 第三类数据点
for i in range(len(reduced_X)):
if y[i] == 0:
red_x.append(reduced_X[i][0])
red_y.append(reduced_X[i][1])
elif y[i] == 1:
blue_x.append(reduced_X[i][0])
blue_y.append(reduced_X[i][1])
else:
green_x.append(reduced_X[i][0])
green_y.append(reduced_X[i][1])
例题八
字典和列表的输出
- cityName=[‘北京’,‘上海’,…]是一个包含31个省份名字的列表
- label=[2 0 3 3 3 1 …]含有31个数字代表相应省份所在的蔟。
- label是根据省份消费水平划分的蔟,label里面的0代表第0个蔟,一共有0、1、2、3四个蔟
现在想要把每个蔟里面的省份输出来
CityCluster=[[],[],[],[]] #四个蔟
for i in range(len(cityName)):
CityCluster[label[i]].append(cityName[i])
for i in range(len(CityCluster)):
print(CityCluster[i])
统计np.array数组里的元素
1.set()函数
labels=[0, -1, 0, 1, -1, 1, 0, 1, 2, -1, 1, 0, 1, 1, 3, -1, -1, 3, -1, 1, 1, -1, 1, 3, 4, -1, 1, 1, 2, 0, 2, 2, -1, 0, 1, 0, 0, 0, 1, 3, -1, 0, 1, 1, 0, 0, 2, -1, 1, 3, 1, -1, 3, -1, 3, 0, 1, 1, 2, 3, 3, -1, -1, -1, 0, 1, 2, 1, -1, 3, 1, 1, 2, 3, 0, 1, -1, 2, 0, 0, 3, 2, 0, 1, -1, 1, 3, -1, 4, 2, -1, -1, 0, -1, 3, -1, 0, 2, 1, -1, -1, 2, 1, 1, 2, 0, 2, 1, 1, 3, 3, 0, 1, 2, 0, 1, 0, -1, 1, 1, 3, -1, 2, 1, 3, 1, 1, 1, 2, -1, 5, -1, 1, 3, -1, 0, 1, 0, 0, 1, -1, -1, -1, 2, 2, 0, 1, 1, 3, 0, 0, 0, 1, 4, 4, -1, -1, -1, -1, 4, -1, 4, 4, -1, 4, -1, 1, 2, 2, 3, 0, 1, 0, -1, 1, 0, 0, 1, -1, -1, 0, 2, 1, 0, 2, -1, 1, 1, -1, -1, 0, 1, 1, -1, 3, 1, 1, -1, 1, 1, 0, 0, -1, 0, -1, 0, 0, 2, -1, 1, -1, 1, 0, -1, 2, 1, 3, 1, 1, -1, 1, 0, 0, -1, 0, 0, 3, 2, 0, 0, 5, -1, 3, 2, -1, 5, 4, 4, 4, -1, 5, 5, -1, 4, 0, 4, 4, 4, 5, 4, 4, 5, 5, 0, 5, 4, -1, 4, 5, 5, 5, 1, 5, 5, 0, 5, 4, 4, -1, 4, 4, 5, 4, 0, 5, 4, -1, 0, 5, 5, 5, -1, 4, 5, 5, 5, 5, 4, 4]
print(set(labels))
'''
统计出了这个列表里面的包含的元素集合
{0, 1, 2, 3, 4, 5, -1}
'''
n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0) #减去噪声数据-1占的位置
print("Estimate number of clusters:%d"%n_clusters_)#输出蔟的个数
'''Estimate number of clusters:6'''
2.统计np.array数组里面某一元素的个数
import numpy as np
labels=[0, -1, 0, 1, -1, 1, 0, 1, 2, -1, 1, 0, 1, 1, 3, -1, -1, 3, -1, 1, 1, -1, 1, 3, 4, -1, 1, 1, 2, 0, 2, 2, -1, 0, 1, 0, 0, 0, 1, 3, -1, 0, 1, 1, 0, 0, 2, -1, 1, 3, 1, -1, 3, -1, 3, 0, 1, 1, 2, 3, 3, -1, -1, -1, 0, 1, 2, 1, -1, 3, 1, 1, 2, 3, 0, 1, -1, 2, 0, 0, 3, 2, 0, 1, -1, 1, 3, -1, 4, 2, -1, -1, 0, -1, 3, -1, 0, 2, 1, -1, -1, 2, 1, 1, 2, 0, 2, 1, 1, 3, 3, 0, 1, 2, 0, 1, 0, -1, 1, 1, 3, -1, 2, 1, 3, 1, 1, 1, 2, -1, 5, -1, 1, 3, -1, 0, 1, 0, 0, 1, -1, -1, -1, 2, 2, 0, 1, 1, 3, 0, 0, 0, 1, 4, 4, -1, -1, -1, -1, 4, -1, 4, 4, -1, 4, -1, 1, 2, 2, 3, 0, 1, 0, -1, 1, 0, 0, 1, -1, -1, 0, 2, 1, 0, 2, -1, 1, 1, -1, -1, 0, 1, 1, -1, 3, 1, 1, -1, 1, 1, 0, 0, -1, 0, -1, 0, 0, 2, -1, 1, -1, 1, 0, -1, 2, 1, 3, 1, 1, -1, 1, 0, 0, -1, 0, 0, 3, 2, 0, 0, 5, -1, 3, 2, -1, 5, 4, 4, 4, -1, 5, 5, -1, 4, 0, 4, 4, 4, 5, 4, 4, 5, 5, 0, 5, 4, -1, 4, 5, 5, 5, 1, 5, 5, 0, 5, 4, 4, -1, 4, 4, 5, 4, 0, 5, 4, -1, 0, 5, 5, 5, -1, 4, 5, 5, 5, 5, 4, 4]
labels=np.array(labels)
print(labels)
ratio = len(labels[labels[:]==-1]) / len(labels) # 判定噪声数据(label被打上-1)数据所占的比例
print("Noise ratio:{:.2f}".format(ratio)) #输出噪声数据所占的比例
'''
labels[:]==-1得到的是[False True False False True ...]这样的列表
labels[labels[:]==-1]得到的是[-1 -1 -1 -1...]这种所有等于-1的元素集合起来的列表
len(labels[labels[:]==-1])就是求出了在labels里面元素等于-1的个数
'''
总之,在np.array数组里面,有ratio = len(labels[labels[:]==-1]) / len(labels) 这样的用法来统计个数,你必须知道
3.典型例子
import numpy as np
city=['太原','北京','上海','成都','西安','南京','广州','西宁']
rank=[ 2, 0, 0, 1, 1, 1, 0, 2 ] #城市对应的排名
ranks=np.array(rank)
citys=np.array(city)
print(ranks[:]==2) #[False False False True True True False False]
print('----------------------------------------------------')
num=len( ranks[ranks[:]==2] ) #ranks里面元素等于2的元素的数量(也就是排名第二的城市的数量)
print(num)
print('----------------------------------------------------')
print( citys[ranks[:]==2] ) #输出排名第二的城市
print('----------------------------------------------------')
print( set(ranks) )
print('----------------------------------------------------')
for i in range( len(set(ranks)) ):
print('排名第',i,'的城市是:')
print( citys[ranks[:]==i] )
print('----------------------------------------------------')