## 關(guān)于ExtraSensory 數(shù)據(jù)集的分析過程
> 在這一周的學(xué)習(xí)當(dāng)中,我進(jìn)行對UCSD的傳感器數(shù)據(jù)集進(jìn)行了分析和學(xué)習(xí),我對我學(xué)習(xí)和嘗試的過程,進(jìn)行復(fù)盤
我們首先先從需要解決的問題入手:?
- 我們需要對數(shù)據(jù)進(jìn)行了解和清洗?
- 清洗完成后我們需要對其做一個分類的問題
## 觀察數(shù)據(jù)
根據(jù)官網(wǎng)的描述,我們得知如下:
ExtraSensory 數(shù)據(jù)集由 UCSD 下 Yonatan Vaizman 和 Katherine Ellis 收集, 由手機(jī) APP --the
ExtraSensory App進(jìn)行收集,收集的信息為手機(jī)各類傳感器的數(shù)據(jù)和此時的人體狀態(tài)等一些數(shù)據(jù)。
該數(shù)據(jù)集有 60個'csv.gz'文件,文件的命名格式為[UUID].features_label.csv.gz。 UUID為每個用戶獨(dú)有的 ID, 使用 gzip 進(jìn)行壓縮。
我們打開其中一個UUID為 1155FF54-63D3-4AB2-9863-8385D0BD0A13 的單個數(shù)據(jù)集
進(jìn)行分析

我們對其進(jìn)行具體的觀察,我們得知在該數(shù)據(jù)集中以timestamp作為主鍵進(jìn)行排序,擁有221個feature,和51個label,和一個sourelabel(此不作為label進(jìn)行學(xué)習(xí))
我當(dāng)時第一個想法是將csv文件讀入后,將timestamp、feature、label三部分進(jìn)行劃分,單獨(dú)取出來?
```
# parse_header_of_csv函數(shù)將feature和label進(jìn)行區(qū)分歸類
# parse_body_of_csv函數(shù)將feature和label的具體數(shù)據(jù)進(jìn)行分割存儲
# read_user_data函數(shù)將csv文件讀入
def parse_header_of_csv(csv_str):
? ? headline = csv_str[:csv_str.index('\n')]
? ? column = headline.split(",")
? ? # 進(jìn)行assert測試
? ? assert column[0] == 'timestamp'
? ? assert column[-1] == 'label_source'
? ? # 找到label開始的位置
? ? for (ci,col) in enumerate(column):
? ? ? ? if col.startswith("label:"):
? ? ? ? ? ? first_start_lind = ci
? ? ? ? ? ? break
? ? ? ? pass
? ? feature_names = column[1:first_start_lind]
? ? label_names = column[first_start_lind:-1]
? ? ##去除多余無效的字符
? ? for (li,label) in enumerate(label_names):
? ? ? ? # assert
? ? ? ? assert label.startswith("label:")
? ? ? ? label_names[li] = label.replace('label:',"")
? ? ? ? pass
? ? return (feature_names, label_names)
def parse_body_of_csv(csv_str,n_feature):
? ? full_body = np.loadtxt(StringIO(csv_str),delimiter=',',skiprows=1)
? ? # 數(shù)據(jù)的主鍵為timestamp
? ? timestamps = full_body[:,0].astype(int)
? ? # 將特征和標(biāo)簽分開,前面的是特征即傳感器
? ? X = full_body[:,1:(n_feature+1)]
? ? #分離出所有l(wèi)abel數(shù)據(jù)
? ? trinary_labels_mat = full_body[:,(n_feature+1):-1]
? ? M = np.isnan(trinary_labels_mat)# 將其進(jìn)行判斷有哪些是nan值
? ? Y = np.where(M,0,trinary_labels_mat)>0.## 進(jìn)行判斷哪里有Nan值則將其轉(zhuǎn)化為0,則保留原來的數(shù)值
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ##并將其轉(zhuǎn)化為布爾值
? ? return (X,Y,M,timestamps)
# 輸出feature數(shù)據(jù)矩陣X,label數(shù)據(jù)矩陣Y,label的缺失數(shù)據(jù)分布矩陣M,feature_names,label_names? ?
def read_user_data(uiud):
? ? user_data_file = '%s.features_labels.csv.gz'%uuid
? ? with gzip.open(user_data_file,'r') as fid:
? ? ? ? csv_str = fid.read()
? ? ? ? csv_str = csv_str.decode(encoding = 'utf-8')
? ? ? ? pass
? ? (feature_names,label_names) = parse_header_of_csv(csv_str)
? ? n_feature = len(feature_names)
? ? (X,Y,M,timestamps) = parse_body_of_csv(csv_str, n_feature)
? ? return (X,Y,M,timestamps,feature_names,label_names)
```
在這段代碼中,主要有三個函數(shù)?
def read_user_data(uiud)讀入用戶數(shù)據(jù),并且其中將讀取數(shù)據(jù)的過程再次抽離出兩個函數(shù)進(jìn)行抽象。分別是:parse_header_of_csv()、 parse_body_of_csv().
> 值得注意的是在這里,我們使用的Python,Python在IO輸入的時候和Python2有所不同,我們進(jìn)行讀取之后需要對其進(jìn)行decode()操作,encoding為utf-8
parse_header_of_csv(csv_str)函數(shù):由于我們直接將csv文件整個進(jìn)行輸入,所以我們直接將其作為一個大的str進(jìn)行分析,我們通過判斷\n的位置,進(jìn)行對heading(column)的截取。為了更為嚴(yán)謹(jǐn),我們在其中插入了assert函數(shù)進(jìn)行判斷,截取之后再使用enumerate對column進(jìn)行從新標(biāo)號,判斷l(xiāng)abel開始的位置,得到位置之后在依舊使用enumrate對其進(jìn)行分析,對label標(biāo)簽進(jìn)行處理,return (feature_names, label_names)
parse_body_of_csv(csv_str,n_feature)函數(shù):我們使用使用numpy中的loadtxt進(jìn)行讀取,以StringIo進(jìn)行讀取,在將feature和label進(jìn)行分割。
```?
? ? #分離出所有l(wèi)abel數(shù)據(jù)
? ? trinary_labels_mat = full_body[:,(n_feature+1):-1]
? ? M = np.isnan(trinary_labels_mat)# 將其進(jìn)行判斷有哪些是nan值
? ? Y = np.where(M,0,trinary_labels_mat)>0.
? ? ##進(jìn)行判斷哪里有Nan值則將其轉(zhuǎn)化為0,則保留原來的數(shù)值
? ? ##并將其轉(zhuǎn)化為布爾值
```
由上我們得到狀態(tài)存在矩陣M,同時使用where函數(shù)對其進(jìn)行從新置換。