1. 程式人生 > 其它 >插值法補齊缺失資料_資料探索與預處理

插值法補齊缺失資料_資料探索與預處理

技術標籤:插值法補齊缺失資料

一、資料探索

1. 資料質量分析

  • 檢查原始資料中是否存在髒資料
  • 缺失值
    • 使用簡單的統計分析,可以得到缺失值的屬性個數,以及每個屬性的未缺失數、缺失數與缺失率
    • 缺失值的處理分為刪除存在缺失值得記錄、對可能值進行插補和不處理3種情況
  • 異常值
    • 也稱離群點,可以使用簡單統計量分析、3δ原則、箱型圖分析
  • 不一致的值
    • 資料不一致性是指資料的矛盾性、不相容性
  • 重複資料及含有特殊符號(如#、¥、*)的資料

2. 資料特徵分析

  • 分佈分析
  • 定量資料的分佈分析
    • 求極差
    • 決定組距與組數
    • 決定分點
    • 列出頻率分佈表
    • 繪製頻率分佈直方圖
  • 定性資料的分佈分析
    • 餅圖和條形圖
  • 對比分析
  • 統計量分析
  • 集中趨勢度量
  • 離中趨勢度量
  • 週期性分析
  • 貢獻度分析(帕累託圖)
  • 相關性分析

3. 綜合程式碼

# -*- coding: utf-8 -*-
"""
Created on Sat Oct 14 17:03:39 2017
@author: wnma3
"""
import os
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

plt.rcParams['font.sans-serif'] = ['SimHei']  # 用來正常顯示中文標籤
plt.rcParams['axes.unicode_minus'] = False  # 用來正常顯示負號

"""
程式碼說明:
programmer_1: 製作箱線圖
data.boxplot-->資料轉為箱線圖的字典格式
plt.annotate-->繪圖

programmer_2: 計算資料
range-->極差
var-->方差
dis-->四分距

programmer_3: 畫出盈利圖(比例和數值)

programmer_4: 計算成對相關性
data.corr()-->dataframe中相互之間的相關性
data.corr()[u'百合醬蒸鳳爪'] -->dataframe某一項與其他項的相關性
"""
def programmer_1(file_name):
    catering_sale = file_name
    data = pd.read_excel(catering_sale, index_col=u'日期')
    plt.figure()
    # 畫箱線圖
    p = data.boxplot(return_type='dict')
    x = p['fliers'][0].get_xdata()
    y = p['fliers'][0].get_ydata()
    y.sort()
    for i in range(len(x)):
        # 處理臨界情況, i=0時
        temp = y[i] - y[i - 1] if i != 0 else -78 / 3
        print(temp)
        # 添加註釋, xy指定標註資料,xytext指定標註的位置(所以需要特殊處理)
        plt.annotate(y[i], xy=(x[i], y[i]), xytext=(x[i] + 0.05 - 0.8 / temp, y[i]))
    plt.show()


def programmer_2(file_name):
    catering_sale = file_name
    data = pd.read_excel(catering_sale, index_col=u'日期')
    data = data[(data[u'銷量'] > 400) & data[u'銷量'] < 5000]
    statistics = data.describe()[u'銷量']
    statistics['range'] = statistics['max'] - statistics['min']
    statistics['var'] = statistics['std'] / statistics['mean']
    statistics['dis'] = statistics['75%'] - statistics['25%']
    print(statistics)


def programmer_3(file_name):
    dish_profit = file_name #餐飲菜品盈利資料
    data = pd.read_excel(dish_profit, index_col=u'菜品名')
    data = data[u'盈利'].copy()
    data.sort_values(ascending=False)
    plt.figure()
    data.plot(kind='bar')
    plt.ylabel(u'盈利(元) ')
    p = 1.0 * data.cumsum() / data.sum()
    p.plot(color='r', secondary_y=True, style='-o', linewidth=2)
    plt.annotate(
    format(p[6], '.4%'),
    xy=(6, p[6]),
    xytext=(6 * 0.9, p[6] * 0.9),
    arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))
    plt.ylabel(u'盈利(比例) ')
    plt.show()


def programmer_4(file_name):
    catering_sale = file_name
    data = pd.read_excel(catering_sale, index_col=u'日期')
    print(data.corr())
    print(data.corr()[u'百合醬蒸鳳爪'])
    print(data[u'百合醬蒸鳳爪'].corr(data[u'翡翠蒸香茜餃']))


if __name__ == "__main__":
    # 獲取當前目錄的上一級目錄
    path = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
    # programmer_1(path + r'datacatering_sale.xls')
    # programmer_2(path + r'/data/catering_sale.xls')
    # programmer_3(path + r'/data/catering_dish_profit.xls')
    # programmer_4(path + r'/data/catering_sale_all.xls')

二、資料預處理

1. 資料清洗

  • 缺失值處理
  • 輸出記錄
  • 資料插補
    • 拉格朗日插值法
    • 牛頓插值法
  • 不處理
  • 異常值處理
  • 刪除含有異常值的記錄
  • 視為缺失值
  • 平均值修正
  • 不處理

2. 資料整合

  • 實體識別:指從不同資料來源識別出現實世界的實體,它的任務是統一不同源資料的矛盾之處
  • 冗餘屬性識別

3. 資料變換

  • 簡單函式變換
  • 平方
  • 開方
  • 取對數
  • 差分
  • 規範化(歸一化)
  • 連續屬性離散化
  • 屬性構造:利用已有的屬性集構造出新的屬性,並加入到現有的屬性集合中
  • 小波變換

4. 資料規約

  • 屬性規約
  • 數值規約

5. Python主要資料預處理函式

cf04b384568133124bfd724cb2264566.png

6. 綜合程式碼

# -*- coding: utf-8 -*-
"""
Created on Sun Oct 15 19:42:13 2017
@author: wnma3
"""
import os
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import pywt
from pandas import DataFrame, Series
from scipy.interpolate import lagrange
from scipy.io import loadmat # mat是MATLAB的專用格式, 呼叫loadmat方法讀取
from sklearn.cluster import KMeans
from sklearn.decomposition import PCA

"""
程式碼說明:
ployinterp_column-->拉格朗日填充數值
programmer_1-->篩選異常資料( 包括NaN) 進行填充
programmer_2-->最小-最大規範化、 零-均值規範化、 小數定標規範化
programmer_4-->基本的dataframe操作
programmer_5-->利用小波分析( ? ? ? ) 進行特徵分析
programmer_6-->利用PCA計算特徵向量, 用於降維分析
"""

# 獲取當前目錄的上一級目錄
path = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
def programmer_1():
    inputfile = path + '/data/catering_sale.xls'
    outputfile = path + '/tmp/sales.xls'

    data = pd.read_excel(inputfile)

    data[(data[u'銷量'] < 400) | (data[u'銷量'] > 5000)] = None

    def ployinterp_column(index, df, k=5):
        y = df[list(range(index - k, index)) + list(range(index + 1, index + 1 + k))]
        y = y[y.notnull()]
        return lagrange(y.index, list(y))(index)

    df = data[data[u'銷量'].isnull()]

    index_list = df[u'銷量'].index

    for index in index_list:
        data[[u'銷量']][index] = ployinterp_column(index, data[u'銷量'])

    data.to_excel(outputfile)


def programmer_2():
    datafile = path + '/data/normalization_data.xls'
    data = pd.read_excel(datafile, header=None)

    print((data - data.min()) / (data.max() - data.min()))
    print((data - data.mean()) / data.std())
    print(data / 10**np.ceil(np.log10(data.abs().max())))


# 聚類畫圖
def programmer_3():
    datafile = path + '/data/discretization_data.xls'
    data = pd.read_excel(datafile)
    data = data[u'肝氣鬱結證型係數'].copy()
    k = 4

    # 方法一, 直接對陣列進行分類
    d1 = pd.cut(data, k, labels=range(k))

    # 方法二, 等頻率離散化
    w = [1.0 * i / k for i in range(k + 1)]
    # percentiles表示特定百分位數, 同四分位數
    w = data.describe(percentiles=w)[4:4 + k + 1]
    w[0] = w[0] * (1 - 1e-10)
    d2 = pd.cut(data, w, labels=range(k))

    # 方法三, 使用Kmeans
    kmodel = KMeans(n_clusters=k, n_jobs=4)

    kmodel.fit(data.values.reshape(len(data), 1))
    # 輸出聚類中心, 並且排序
    c = DataFrame(kmodel.cluster_centers_).sort_values(0)

    # 相鄰兩項求中點, 作為邊界點
    w = DataFrame.rolling(c, 2).mean().iloc[1:]
    # 加上首末邊界點
    w = [0] + list(w[0]) + [data.max()]
    d3 = pd.cut(data, w, labels=range(k))

    def cluster_plot(d, k):
        plt.figure(figsize=(8, 3))
        for j in range(0, k):
            plt.plot(data[d == j], [j for i in d[d == j]], 'o')
        plt.ylim(-0.5, k - 0.5)
        return plt

    cluster_plot(d1, k).show()
    cluster_plot(d2, k).show()
    cluster_plot(d3, k).show()


def programmer_4():
    inputfile = path + "/data/electricity_data.xls"
    outputfile = path + "/tmp/electricity_data.xls"
    data = pd.read_excel(inputfile)
    data[u"線損率"] = (data[u"供入電量"] - data[u"供出電量"]) / data[u"供入電量"]
    data.to_excel(outputfile, index=False)


def programmer_5():
    inputfile = path + "/data/leleccum.mat"
    mat = loadmat(inputfile)
    signal = mat["leleccum"][0]
    """
    處理資料
    返回結果為level+1個數字
    第一個陣列為逼近係數陣列
    後面的依次是細節係數陣列
    """
    coeffs = pywt.wavedec(signal, "bior3.7", level=5)
    print(coeffs)


def programmer_6():
    inputfile = path + "/data/principal_component.xls"
    outputfile = path + "/tmp/dimention_reducted.xls"
    data = pd.read_excel(inputfile, header=None)
    pca = PCA()
    pca.fit(data)
    # 返回各個模型的特徵向量
    pca.components_
    # 返回各個成分各自的方差百分比
    pca.explained_variance_ratio_
    data.to_excel(outputfile, index=False)


if __name__ == '__main__':
    # programmer_1()
    # programmer_2()
    # programmer_3()
    # programmer_4()
    # programmer_5()
    # programmer_6()
    pass