Python数据分析与挖掘实战笔记

(声明:这些代码只是看书的时候跟着敲一敲,留个印象,为的是以后用到有个方便快速查找看个思路,并没有真正运行。)

数据挖掘建模过程

  1. 数据挖掘建模过程:
    1. 定义挖掘目标:明确挖掘目标,弄清用户需求。
    2. 数据采样:
      1. 采样标准(相关性、可靠性、有效性)
      2. 采样方法:随机、分层、等距
    3. 数据探索:进行探索、审核和加工
      1. 异常值分析
      2. 缺失值分析
      3. 相关分析
      4. 周期性分析
    4. 数据预处理
      1. 数据筛选
      2. 数据变量转换
      3. 缺失值处理
      4. 坏数据处理
      5. 数据标准化
      6. 主成分分析
      7. 属性选择
      8. 数据规约
    5. 数据建模
    6. 数据评价

数据探索:

数据探索:通过检验数据集数据质量、绘制图表、计算某些特征等手段,对样本数据集的结构规律进行分析的过程。
数据分析主要任务是检查原始数据中是否存在脏数据,主要检查缺失值、异常值和一致性。

  1. 数据检查
    1. 缺失数据
      1. 原因
        1. 信息无法获取
        2. 信息被遗漏
        3. 属性值不存在
      2. 影响
        1. 丢失大量信息
        2. 增加不确定性
      3. 分析
        1. 每个属性未缺失数,缺失数和缺失率
    2. 异常值分析:也称离群点分析
      1. 统计量分析
      2. 3\(\sigma\)原则(正太分布)
      3. 箱型图分析(四分位法)
    3. 一致性分析
      1. 数据源不同,导致同一个属性值不同
  2. 数据特征分析
    1. 分布分析
      1. 定量分析:频率分布表、频率分布直方图、绘制茎叶图
      2. 定性分类数据:饼图、条形图
    2. 对比分析:相联系指标比较,常用于时间维度上的指标分析
      1. 绝对数比较
      2. 相对数比较
        1. 结构相对数:部分数值与总体比较
        2. 比例相对数:同一总体内不同部分数值对比
        3. 比较相对数:同一时期两个性质相同指标值对比
        4. 强度相对数:性质不同但有一定联系的总量指标进行对比
        5. 计划完成程度相对数:实际完成数与计划数对比
        6. 动态相对数:同一现象不同时期指标指数进行对比,说明方向和速度
    3. 统计量分析
      1. 集中趋势度量
        1. 均值
        2. 中位数
        3. 众数
      2. 离中趋势度量
        1. 极差
        2. 标准差
        3. 变异系数(\(\frac{s}{\bar{x}}*100%\)
        4. 四分位数间距
      3. 周期性分析:周期性分析是探索某个变量是否随着时间变化而呈现出某种周期变化趋势
      4. 贡献度分析:帕累托分析,又称2/8定律。
      5. 相关性分析:分析连续变量之间线性相关程度的强弱
        1. 散点图(散点矩阵图)
        2. 计算相关系数
          1. pearson相关系数:\(r=\frac{\sum_{i=1}^n(x_i-\bar{x})(y_i-\bar{y}))}{\sqrt{\sum_{i=1}^n(x_i-\bar{y})^2\sum_{i=1}^n(y_i-\bar{y})^2}}\)
          2. Spearman秩相关系数:\(r_s=1-\frac{6\sum_{i=1}^n(R_i-Q_i)^2}{n(n^2-1)}, R_i代表x_i的秩,Q_i代表y_i的秩次,R_i-Q_I为x_i和y_i的秩次差\)

定量分析

步骤:

  1. 求极差(最大与最小)

  2. 决定组距与组数

  3. 决定分点

  4. 列出频率分布表

  5. 绘制频率分布直方图
    原则:

  6. 组间相互互斥

  7. 包含所有数据

  8. 组宽相等

代码

异常值检测代码

import dandas as pd
import matplotlib.pyplot as plt

data = pd.DataFrame()
plt.rcParams['font.sans-serif'] = ['SimHei']  # 显示中文
plt.rcParams['axes.unicode_minus'] = False # 显示负号

plt.figure()
p = data.boxplot() # 用pandas直接画箱线图

x = p['fliers'][0].get_xdata() # 'flies'异常值标签
y = p['fliers'][0].get_ydata()
y.sort()

# 用annotate添加注释
for i in range(len(x)):
    if i>0:
        plt.annotate(y[i], xy=(x[i], y[i]), xytext=(x[i] + 0.05 - 0.8 / (y[i] - y[i-1]),y[i]))
     else:
        plt.annotate(y[i], xy=(x[i], y[i]), xytext=(x[i] + 0.08 ,y[i]))
plt.show() # 展示箱线图

统计量分析

from __future__ import print_function
import pandas as pd

data = pd.DataFrame()
data = data[col_name]

statistics = data.describe() # 保存基本统计量

statistics.loc['range'] = statistics.loc['max'] - statistics.loc['min'] #极差
statistics.loc['var'] = statistics.loc['std'] / statistics.loc['mean'] # 变异系数
statistics.loc['dis'] = statistics.loc['75%'] - staticstics.loc['25%'] # 四分位数间距

帕累托图代码

from __future__ import print_function
import pandas as pd
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

data = pd.DataFrame()
data = data[col_name].copy()

data.sort_index(ascending = False)
plt.figure()
data.plot(kind='bar')
plt.ylabel('col_name')
p = 1 * data.cumsum() /data.sum()
p.plot(color='r', secondary_y=True, style='-o', linewidth=2)
plt.annotate(format(p[x],'.4%'), xy=(x, p[6]), xytext=(x*0.9, p[x]*0.9),arrowprops=dict(arrowstyle='->', connectionstyle="arc3, rad=.2")) # 添加注释,x表示第x处是0.85%,指定箭头样式
plt.ylabel('xxx')
plt.show()

相关性分析代码

from __future__ import print_function
import pandas as pd

data=pd.DataFrame()

data.corr(method='pearson|spearman|kendall') 相关系数矩阵
data.corr()['col_name'] # 某一个与其他相关系数
data['col_name1'].corr(data['col_name2'])  # 计算col_name1与2相关系数

数据预处理

数据预处理主要包括:数据清洗、数据集成、数据变换与数据规约。

  1. 数据清洗
    1. 缺失值处理
      1. 删除记录
      2. 数据插补
        1. 均值/中位数/众数插补
        2. 使用固定值
        3. 最近临插补
        4. 回归方法
        5. 插值法
      3. 不处理
    2. 异常值处理
      1. 删除含有异常值的记录
      2. 视为缺失值
      3. 平均值修正:用前后的平均值修正
      4. 不处理
  2. 数据集成(针对不同的数据源整合)
    1. 实体识别
      1. 同名异义:数据源甲的名字与乙的名字相同,含义不同,比如用户表的id与商品表的id就不同。
      2. 异名同义:数据源甲的名字与乙的名字不同,但是含义其实相同,比如用户表的id与商品表的uid就是同一个东西。
      3. 单位不统一:比如国际单位就与中华传统的计量单位不同。
    2. 冗余属性识别
      1. 同一属性多次出现
      2. 同一属性命名不一致导致重复
  3. 数据变换
    1. 简单函数变换:主要是为了非正太分布的数据变成正态分布,常用手法比如:平方、开方、取对数、差分运算
    2. 规范化:消除指标之间的量纲和取值范围差异的影响。
      1. 最大-最小规范化
      2. 零-均值规范化
      3. 小数定标规范化
    3. 连续属性离散化:取值范围内设定若干离散的划分点
      1. 等宽法
      2. 等频法
      3. 基于聚类分析
    4. 属性构造:利用以有的属性构造新的属性
    5. 小波变换
  4. 数据规约
    1. 属性规约方法
      1. 合并
      2. 逐步向前选择
      3. 逐步向后删除
      4. 决策树归纳
      5. 主成分分析
    2. 数值规约
      1. 直方图
      2. 聚类
      3. 抽样
      4. 聚类抽样
      5. 分层抽样

拉格朗日插值法

如果有n个点,那么可以找到一条曲线,通过n-1个点找到第n个点,即\(y=a_0+a_1x+a_2x^2+...+a_{n-1}x^{n-1}\),然后通过n-1个点,计算出这个表达式。

代码

拉格朗日法插值

import pandas as pd
from scipy.interpolate import lagrange # 导入拉格朗日插值

data = pd.DataFrame()

def ployinterpColumn(s, n, k=5):
    y=s[list(range(n-k,n))+list(range(n+1, n+1+k))]  #取数
    y=y[y.notnull()] # 过滤空值
    return lagrange(y.index, list(y))(n)

for i in data.columns:
    for j in range(len(data)):
        if(data[i].isnull())[j]:
            data[i][j] = ployinterpColumn(data[i],j)

规范化代码

import pandas as pd

data = pd.DataFrame()

(data - data.min()) / (data.max() - data.min())
(data - data.mean()) / data.std()
data/10**np.ceil(np.log10(data.abs().max())))  # 小数定标规范化

数据离散化

import pandas as pd
from sklearn.cluster import KMeans # 引入KMeas

data = pd.Series()

k = 4
# 等宽
d1 = pd.cut(data, k, labels = range(k))

# 等频率离散化
w = [1*i/k for i in range(k+1)]
w = data.describe(percentiles = w)[4:4+k*1]
w[0] = w[0]*(1-1e-10)
d2 =  pd.cut(data,w,labels = range(k))

kmodel = KMeans(n_clusters=k, n_jobs = 4)
kmodel.fit(data, reshape((len(data), 1)))
c = pd.DataFrame(kmodel.cluster_centers_).sort(0)  #输出聚类中心并排序
w=c.rolling(2).mean().iloc[1:]  # 相邻两项求中点,作为边界点
w=[0] + list(w[0]) + [data.max()]) # 把首末边界点加上
d3 = pd.cut(data, w, labels=range(k))

def clusterPlot(d,k)
    import matplotlib.pyplot as plt
    plt.rcParams['font.sans-serif'] = ['SimHei']
    plt.rcParams['axes.unicode_minus'] = False
    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

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

小波变换

import pywt
coeffs = pywt.wavedec(signal, 'bior3.7', level=5)

挖掘建模

  1. 分类与回归
    1. 回归分析
      1. 线性回归
      2. 非线性回归
      3. Logistic回归
      4. 岭回归
      5. 主成分回归
    2. 决策树
      1. ID3
      2. C4.5
      3. CART算法
    3. 人工神经网络
      1. 激活函数
        1. 域值函数
        2. 分段线性函数
        3. 非线性转移函数
        4. Relu函数
      2. 网络算法
        1. BP
        2. LM
        3. RBF
        4. FNN
        5. GMDH
        6. ANFIS
    4. 贝叶斯网络
    5. 支持向量机
    6. 评价指标
      1. 回归
        1. 绝对误差AE/相对误差RE
        2. 平均绝对误差MAE
        3. 均方误差MSE
        4. 均方根误差RMSE
      2. 分类
        1. Kappa统计
        2. 准确度Accuracy:\(\frac{TP+FN}{TP+TN+FP+FN}\)
        3. 识别精确率Precision:\(\frac{TP}{TP+FP}\)
        4. 召回率:\(\frac{TP}{TP+TN}\)
        5. ROC
        6. 混淆矩阵
  2. 聚类分析
    1. 方法(sklearn.cluster)
      1. 划分方法
        1. K-Means
        2. K-MEDOIDS
        3. CLARANS
      2. 层次分析方法
        1. BIRCH算法
        2. CURE算法
        3. CHAMELEON算法
      3. 基于密度的方法
        1. DBSCAN算法
        2. DENCLUE算法
        3. OPTICS算法
      4. 基于网格方法
        1. STING算法
        2. CLIOUE算法
        3. WAVE-CLUSTER算法
      5. 基于模型的方法
        1. 统计学方法
        2. 神经网络方法
    2. 指标
      1. purtity评价法
      2. RI评价法
      3. F值评价法
  3. 关联规则
    1. 算法
      1. Apriori
      2. FP-tree
      3. Eclat
      4. 灰色关联法
  4. 时序模式(statsmodels)
    1. 算法
      1. 平滑法
      2. 趋势拟合法
      3. 组合模型
      4. AR模型
      5. MA模型
      6. ARMA模型
      7. ARIMA模型
      8. ARCH
      9. GARCH
    2. 预处理
      1. 平稳性检验
        1. 时序图检验
        2. 自相关图检验
      2. 纯随机性检验
  5. 离群点检测
    1. 算法
      1. 基于统计
      2. 基于邻近度
      3. 基于密度
      4. 基于聚类

Apriori

相关知识

关联规则支持度:

\(Support(A\Rightarrow B)=P(A\cup B)=\frac{Count(A\cup B)}{Total}, Count(A\cup B) 表示A与B同时发生事件\)

关联规则置信度:

\(Confidence(A\Rightarrow B) = P(A|B) = \frac{Count(A \cup B)}{Total(A)}\)

算法

找出最大的频繁子项集

性质:

如果向不是频繁项的I加入事务A,那么其还是不会成为频率项集。

过程:
找出所有的频繁项集,最终找出最大频繁项集

先对1项候选集,计算支持度、置信度,取大于阈值的作为\(C_1\);二项候选集就用\(C_1\)\(C_1\)组合,计算支持度、置信度,取大于阈值的作为\(C_2\);第i项,用\(C_{i-1}\)\(C_1\)结合,计算支持度、置信度,取大于阈值的作为\(C_i\)

代码

LR算法

import pandas as pd
from sklearn.linear_model import LogisticRegression 
from sklearn.linear_model import RandomizedLogisticRegression 

rlr = RandomizedLogisticRegression()
rlr.fit(x,y)

rlr.get_support()  # 获取特征筛选结果,也可以通过.scores_方法获取各个特征分数

x=data[data.columns[rlr.get_support()]].as_matrix()

lr = LogisticRegression()
lr.fit(x,y)
print('训练结果:{}'.format(lr.score(x,y)))

决策树

import pandas as pd
from sklearn.tree import DecisionTreeClassifier
from sklearn.tree import export_graphviz
from sklearn.externals.six import StringIO

data = pd.DataFrame()

dtc=DecisionTreeClassifier(criterion='entropy')
dtc.fit(x,y)

with open('tree.dot', 'w') as f:
f = export_graphviz(dtc, feature_name=x.columns, out_file=f)  # 事后可以用Graphviz查看dot -Tpdf tree.dot -o tree.pdf

混淆矩阵

from cm_plot import
cm_plot(y, y_pre).show

Kmeans

import pandas as pd
from sklearn.cluster import KMeans

data = pd.DataFrame()

k = 3
iteration = 500
model = KMeans(n_clusters = k, n_jobs=4, max_iter=iteration)
model.fit(data)

r1 = pd.Series(model.labels_).value_counts() # 统计各个类别数目
r2 = pd.DataFrame(model.cluster_centers_)  # 找出聚类中心
r=pd.concat([r2,r1], axis=1)
print(r)

r=pd.concat([data, pd.Series(model.labels_, index = data.index)], axis=1)
r.columns = list(data.columns) + ['聚类类别']

import matplotlib.pyplot as plt
def densityPlot(data, title):
    plt.rcParams['font.sans-serif'] = ['SimHei']
    plt.rcParams['axes.unicode_minus'] = False
    plt.figure()
    for i in range(len(data.iloc[0])):
        (data.iloc[:,i]).plot(kind='kde', label=data.columns[i], linewidth=2)
    plt.ylabel('密度')
    plt.xlabel('人数')
    plt.title('聚类类别{}各属性密度曲线'.format(title))
    plt.legend()
    return plt

'''聚类后的概率密度图'''
def densityPlot(data):
    plt.rcParams['font.sans-serif'] = ['SimHei']
    plt.rcParams['axes.unicode_minus'] = False
    plt.figure()
    p = data.plot(kind='kde', linewidth=2, subplots = True, sharex = False)
    plt.ylabel('密度')
    plt.xlabel('人数')
    plt.title('聚类类别{}各属性密度曲线'.format(title))
    plt.legend()
    return plt

TSNE数据降维

from sklearn.mainfold import TSNE
import matplotlib.pyplot as plt

tsne = TSNE()
tsne.fit_transform(data)
tsne = pd.DataFrame(tsne.embedding_, index = data.index)

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

d = tsne[r[u'聚类类别']==0]
plt.plot(d[0], d[1], 'r.')
d = tsne[r[u'聚类类别']==1]
plt.plot(d[0], d[1], 'go')
d = tsne[r[u'聚类类别']==2]
plt.plot(d[0], d[1], 'b*')

plt.show()

离群点检测

import numpy as np
import pandas as pd

from sklearn.cluster import KMeans

k = 3
threshold = 2
iteration =500
data = pd.DataFrame()
data_zs = 1.0 * (data - data.mean) / data.std()

model = KMeans(n_clusters = k, n_jobs = 4, max_iter = iteration)
model.fit(data_zs)

r = pd.concat([data_zs, pd.Series(model.labels_, index=data.index)], axis = 1)
r.columns = list(data.columns) + ['类别']

norm = []
for i in range(len(data_zs)):
    norm_tmp = data_zs[i][['r','f','m']] - model.cluster_centers_[model.labels_[i]]
    norm_tmp = norm_tmp.apply(np.linalg.norm, axis = 1)  # 求出绝对值
    norm.append(norm_tmp)

norm = pd.concat(norm)
data_sz['abnormal'] = (normal >= threshold).astype(int)

时序框架

import pandas as pd

from statsmodels.stats.diagnostic import acorr_ljungbox
from statsmodels.tsa.statools import adfuller as ADF
from statsmodels.tsa.arima_model import ARIMA
# 平衡性检验
data = pd.Series()
diff = []
adf = ADF(data)
while adf[1] >= 0.05 # p值小于0.05是平稳的
    diff = diff + 1
    adf = ADF(data.diff(diff).dropna())
print('原始序列经过{}队差分后平稳,p值为{}'.format(diff, adf[1]))

# 白噪声验证

[[lb], [p]] = acorr_ljungbox(data, lags=1)
if p< 0.05:
    print('原始序列为非白噪声序列,对应p值为{}'。format(p))
else:
    print('原始序列为白噪声序列,对应p值为{}'。format(p))
[[lb], [p]] = acorr_ljungbox(data.diff().dropna(), lags=1)
if p < 0.05:
    print('一阶差分序列为白噪声序列, p值为{}'.format(p))
else:
    print('一阶差分序列为非白噪声序列, p值为{}'.format(p))
 # 模型识别
pmax = int(len(data)/10)  # 一般除数不超过length/10
qmax = int(len(data)/10)  # 一般除数不超过length/10

bic_matrix = [] # bic矩阵
for p in range(pmax+1):
    tmp = []
    for q in range(qmax+1):
        try:
            tmp.append(ARIMA(data, (p,1,q))).fit().bic)
        except:
            tmp.append(None)
bic_matrix = pd.DataFrame(bic_matrix)
p,q = bic_matrix.stack().idxmin()
print('BIC最小值p和q值为'{}{}.format(p,q))

# 训练
arima = ARIMA(data, (0,1,1)).fit()
data_pred = arima.predict(typ = 'levels')
pred_error = (data_pred - data).dropna()

# 结果白噪声确认
lb, p = acorr_ljungbox(pred_error, lags = lagnum)
h = (p < 0.05).sum() 
if h > 0:
    print('不符白噪声检测')
else:
    print('符合白噪声检测')

# 计算误差
abs_ = (data['预测'] - data['实际']).abs()
mae_ = abs_.mean() #mea
rmse_ = ((abs_**2).mean())** 0.5
mape_ = (abs_/data['实际']).mean()
print('平均绝对误差:{}\n 圴方根误差为:{}\n,平均绝对百分误差为:{}'.forma(mae_,rmse_,mape_))

posted on 2023-05-07 16:46  复古猴子  阅读(80)  评论(0编辑  收藏  举报

导航