数据分析和数据挖掘

数据挖掘和机器学习
机器学习 — 预测的准 — 需要分割训练集和测试集

  • 聚类、分类、 回归

数据挖掘— 特征x和y之间的关系及其影响 一般不分割数据集

  • 聚类/分类/回归
  • 可选算法:
    • 线性回归,逻辑回归,决策树,贝叶斯,xgboost
    • 不能用knn,svm,神经网络 没有可解释性

聚类分析

分析方法

在这里插入图片描述
优势

  • 能够发现未知的重要特征

技术问题

  • 均值的问题 kmeans 更新中心点 均值点
    • 异常数据会影响均值 要去异常
    • 量纲的问题 —要做标准化 — 基于距离的
  • 数据量大的问题
    • m个样本,n个特征,k个中心点,t次迭代 算法复杂度 O(tkm*n)
    • mini-batch-kmeans来解决数据量大的问题
    • 结论:MiniBatchKMeans在基本保持了K-Means原有较高类别识别率的前提下,其计算效率的提升非常明显。因此,MiniBatchKMeans是一种能有效应对海量数据,尽量保持聚类准确性并且大幅度降低计算耗时的聚类算法
  • 聚类分析:分析聚类簇的中心点的特点
  • kmeans的作用:kmenas可以帮我们采样 假如有1亿数据
    • 先用minibatchkmeans聚成5w个类 得到5w个中心点
    • 拿着5w中心点去做后续的分类和回归任务

客户分群案例

from sklearn.cluster import KMeans
dataset = pd.read_csv('data/customers.csv')
dataset.head()

X = dataset.iloc[:, [3, 4]].values#全部行,第四第五列  Annual Income (k$) 和 Spending Score (1-100)
X.max(axis=0),X.min(axis=0) 

#实例化
km=KMeans(n_clusters=5)
y_label=km.fit_predict(X)
y_label

km.cluster_centers_

import matplotlib.pyplot as plt
plt.scatter(X[y_label==0,0],X[y_label==0,1],color='blue',label='A')
plt.scatter(X[y_label==1,0],X[y_label==1,1],color='red',label='B')
plt.scatter(X[y_label==2,0],X[y_label==2,1],color='green',label='C')
plt.scatter(X[y_label==3,0],X[y_label==3,1],color='cyan',label='D')
plt.scatter(X[y_label==4,0],X[y_label==4,1],color='magenta',label='E')
plt.scatter(km.cluster_centers_[:,0],km.cluster_centers_[:,1],color='black',label='center')
plt.title('Clusters of customers')
plt.xlabel('Annual Income (k$)')
plt.ylabel('Spending Score (1-100)')
plt.legend()
plt.show()

km.cluster_centers_

  import matplotlib.pyplot as plt
  wcss = []
  for i in range(1, 11): #循环使用不同k测试结果
      kmeans = KMeans(n_clusters = i, init = 'k-means++', random_state = 42)
      kmeans.fit(X)
      wcss.append(kmeans.inertia_) #inertia簇内误差平方和     所有样本点到对应簇中心点距离平方和
  plt.plot(range(1, 11), wcss)
  plt.title('The Elbow Method')
  plt.xlabel('Number of clusters')
  plt.ylabel('WCSS')
  plt.show()

年龄收入分群案例

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
#加载数据
ageinc_df=pd.read_csv('data/ageinc.csv')
ageinc_df.info()
#两列数据,年龄与收入

ageinc_df.describe()

#标准化
ageinc_df[['z_income','z_age']]=(ageinc_df-ageinc_df.mean())/ageinc_df.std()
ageinc_df.head()

import seaborn as sns
sns.scatterplot(x='income',y='age',data=ageinc_df)

#模型  聚3簇
km=KMeans(n_clusters=3)
km.fit(ageinc_df[['z_income','z_age']])
#获取标签
ageinc_df.loc[:,'cluster_3']=km.labels_
ageinc_df.head()

sns.scatterplot(x='age',y='income',hue='cluster_3',data=ageinc_df)
#横轴为年龄,纵轴为收入,分类为用户分群标签

#肘部法决定聚几个簇
wcss = []
for i in range(1, 11): #循环使用不同k测试结果
    kmeans = KMeans(n_clusters = i, init = 'k-means++', random_state = 42)
    kmeans.fit(ageinc_df[['z_income','z_age']])
    wcss.append(kmeans.inertia_) #inertia簇内误差平方和     所有样本点到对应簇中心点距离平方和
plt.plot(range(1, 11), wcss)
plt.title('The Elbow Method')
plt.xlabel('Number of clusters')
plt.ylabel('WCSS')
plt.show()

# 分析聚类结果
#简单分析
#由于作了标准化  聚类中心点是标准化后的数据
#按照聚类标签分组  统计每一组原特征的均值
ageinc_df.groupby('cluster_4',as_index=False)[['income','age']].mean()

#分布差异分析
ageinc_df.groupby('cluster_4')[['income','age']].describe()
sns.boxplot(x='cluster_4',y='income',data=ageinc_df)
sns.boxplot(x='cluster_4',y='age',data=ageinc_df)

  • 量纲不一致—做标准化
  • 肘部法判断最优簇数 k值
  • 聚类结果分析
    • 简单均值比较
      • 按照聚类的标签分组,计算每一组原特征的均值差异
      • ageinc_df.groupby('cluster_4',as_index=False)[['income','age']].mean()
        
    • 分布分析
      • 按照聚类标签分组,查看每一组原特征的分布差异
        ageinc_df.groupby(‘cluster_4’)[[‘income’,‘age’]].describe()
    • 最终一般是绘图对比
      • 均值比较 — 雷达图
      • 分布比较— 箱线图

聚类分析总结

  • 数据处理上
    • 去异常
    • 标准化
    • 类别型数据—做onehot
    • 级别型数据 —编码 1,2,3
  • 模型构建
    • k取值 :肘部法、根据业务的需求来
  • 结果分析
    • 重点分析聚类簇的中心点
      • km.cluster_centers_ 输出的标准化后的数据
      • 按照聚类标签分组统计均值 得到原数据中心点
    • 分析中心点差异和特征分布差异

回归分析

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

步骤

  • 前提:数据应拿到
  • 分析流程:数据概况分析->单变量分析->相关性分析与可视化->回归模型
    • 数据概况分析
      • 数据行/列数量
      • 缺失值分布
    • 单变量分析
      • 数字值型变量的描述指标(平均值,最大最小值,标准差)
        • describe()
      • 类别型变量(多少个分类,各自占比)
        • value_counts()
    • 相关性分析与可视化
      • x离散y连续 --按类别交叉对比
        • 均值比较 — 方差分析
        • 做法: 按照x分组,计算每一组的y的均值,观察是否有差异
          • 有差异 代表有影响
          • 没有差异 代表没有影响
        • 柱形图(比均值)和箱线图(比分布)
      • x连续y连续— 变量之间的相关性分析
        • 皮尔森 斯皮尔曼
        • df.corr()
        • 散点图/热力图
    • 回归分析
      • 模型建立
      • 模型评估与优化

结果

  • revenue=1.75186122local_tv+2037.7933person+4.07672953*online-52678.6888
    • 表示local_tv每增加1块钱投入,销售额对应增长1.75
    • person每增加一个人,销售额增加2037
    • online每增加一块钱投入 销售额增加4.06
    • -52678.6888 偏置没有意思
    • 结论:适当提高online的投入 减少local_tv的投入,人员结合用工成本进行管控
  • 注意问题
    • 每次进行微调,收集新的数据,每个月对模型进行更新迭代,
      • 要注意是否产生了新的更重要的自变量
      • 如果搞了活动,这个因素要考虑
    • x的值不能超过训练数据的范围,否则模型会失效
      • 模型的局部有效性

总结

  • 变量少到1个自变量,直接画图
  • 如果特征有共线性
    • 判断共线性:vif方差膨胀系数,相关系数
    • 怎么解决:
      • 删掉共线性很强的特征
      • 岭回归
  • 高维:岭回归
  • 关注可解释性: 线性回归和多项式回归(多项式扩展+线性回归)

分类分析

  • 预测
    • 做模型预测准
  • 挖掘
    • 目标是离散
    • 决策树 提取规则 可视化 规则还给到业务部门

用户流失预测案例分析

在这里插入图片描述

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline 
churn=pd.read_csv('data/churn.csv')
churn.info()

#单变量分析
churn.describe()
#离散数据
churn['gender'].value_counts()
churn['Churn'].value_counts()
#相关性分析 目标是离散的
#离散特征和离散y的关系   -- 交叉表分析   卡方检验  看比例是否有差异
pd.crosstab(churn['gender'],churn['Churn'])
churn.groupby('Churn').mean()  #实际上是比例 
#验证交叉表
pd.crosstab(churn['Churn'],churn['Partner_att'])
#可视化
sns.barplot(x='Churn',y='Contract_Month',data=churn)
sns.countplot(y='Contract_Month',hue='Churn',data=churn)

#数据清洗
#需要把churn和gender转变为数字型变量,使用get_dummies
churn=pd.get_dummies(churn)
#删掉两列 Churn_No   gender_Male
churn=churn.drop(['Churn_No','gender_Male'],axis=1)
#变量大小写不规则,统一变成小写
churn.columns=churn.columns.str.lower()
#修改列名
churn=churn.rename(columns={'churn_yes':'flag'})

import numpy as np
#皮尔森相关性
corr=churn.corr()[['flag']].rename(columns={'flag':'r'})
#计算绝对值
corr.loc[:,'abs_r']=corr['r'].apply(np.fabs)
#按照绝对值排序
corr=corr.sort_values('abs_r',ascending=False)
corr

#模型训练
#利用选择的特征构建模型
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression

#拿到x和y
y=churn['flag']
x=churn[['contract_month','internet_other','paymentelectronic','totalcharges','monthlycharges']]

#分割数据集
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.3,random_state=100)
#模型训练
model=LogisticRegression()
model.fit(x_train,y_train)

#结果分析       y=2.01264249*contract_month+1.05076404*internet_other+0.64248053*paymentelectronic-3.21842661
# p=sigmoid(y)   y>0:正例   y<0:负例
model.coef_
model.intercept_
#评估  准确率
model.score(x_test,y_test)
#绘制roc
from sklearn.metrics import roc_curve,auc
#提取正例的概率
y_score=model.predict_proba(x_test)[:,1] #预测为1的概率
fpr,tpr,threshold=roc_curve(y_test,y_score)
#绘制曲线
plt.plot(fpr,tpr)
  • 提取数据
  • 导入数据
  • 数据清洗
  • 探索性分析
    • 单变量分析
      • 特征分析、 目标分析
    • 多变量分析
      • 特征跟目标之间的相关性
        • x离散y离散
          • 交叉表— 看比例是否差异
        • x连续y离散或者x离散y连续
          • 均值比较或者方差分析
            • 柱状图 箱线图
        • x连续y连续
          • 相关性分析 皮尔森 斯皮尔曼
          • 热力图
      • 特征和特征之间的相关性
        • 共线性
  • 特征筛选
  • 模型构建和优化
  • 评估和输出模型

附图:
1.交叉表
在这里插入图片描述
2.均值比较方差分析
在这里插入图片描述
3.热力图
在这里插入图片描述

分类分析方法总结

  • 分类分析作用
    • 提取规则— 数据挖掘
    • 提取变量— 特征选择
    • 缺失值填充— 拿没缺失的训练,对缺失的进行预测
  • 聚类和分类比较
    • 聚类无监督 分类有监督
    • 聚类没有y 分类有y
    • 聚类只能做探索性分析(模糊分析),分类可以做预测等精确分析
    • 结果解读
      • 聚类:比较各个簇的均值点的差异
      • 分类不需要解释 是/不是
    • 评价
      • 聚类没有准确率
      • 分类有准确率,auc等指标
  • 常用逻辑回归和决策树 xgboost 随机森林

关联分析 -apirior - fp-growth

  • 作用:挖掘频繁项集
  • 相关概念
    • 支持度— 项集出现的次数/总次数
    • 置信度— 对规则而言
      • {豆奶} >>>{莴苣}的置信度 = 支持度({豆奶, 莴苣})/支持度({豆奶}),即3/4
      • {莴苣}>>>{豆奶}的置信度 = 支持度({豆奶, 莴苣})/支持度({莴苣}`),即3/4
      • 两者一般不相等
    • 频繁规则
      • 最小支持度
      • 最小置信度
      • 同时满足最小支持度和最小置信度的规则就是频繁规则(强关联规则)
    • 有效规则
      • 提升度: 应用规则结果/不应用规则的结果
        • =1 规则没有任何影响
        • 小于1 规则起到正的作用 有效规则
        • 大于1 规则是负作用 无效规则
  • apirior算法原理
    • 首先搜索一项集—>过滤一项集 —>得到频繁一项集
    • 有频繁一项集组合候选二项集—>重复动作
    • 知道不能再组合更高的频繁项集,程序终止

商品交叉销售分析(略)

在这里插入图片描述

# 导入库
import pandas as pd
import apriori
#加载数据文件
data = pd.read_csv('data/order_table.csv')
data.head()

order_ids=data['order_id'].unique()
records=[ data[data['order_id']==id]['product_name'].tolist() for id  in order_ids]
records=[d['product_name'].tolist() for key,d in data.groupby('order_id')]

#统计强关联规则
minS=0.05#最小支持度
minC=0.2#最小置信度
L,suppdata=apriori.apriori(records,minSupport=minS)

#筛选满足最小置信度的规则
rules=apriori.generateRules(records,L,suppdata,minConf=minC)
rules

# 关联结果报表评估
model_summary = 'data record: {1} \nassociation rules count: {0}'  # 展示数据集记录数和满足阀值定义的规则数量
print(model_summary.format(len(rules), len(records)),'\n','-'*60)  # 使用str.format做格式化输出
rules_all = pd.DataFrame(rules, columns=['item1', 'item2', 'instance', 'support', 'confidence','lift'])  # 创建频繁规则数据框
rules_sort = rules_all.sort_values(['lift'],ascending=False)
rules_sort.head(10)

异常检测分析

  • 常用算法
    • one-class SVM 一分类svm
      • svm天然抵抗不平衡
    • isolation forest 孤立森林
    • GMM 高斯混合模型
      • 底层思想是完整版EM kmeans是阉割版的EM
  • 重点:孤立森林
    • 什么是异常?
      • 离散: A:10000 B:1000 C:10
      • 连续: 过大或者过小是异常
    • 原理
      孤立森林算法通过对样本点的孤立来检测异常值
      • 该算法利用一种名为孤立树iTree的二叉搜索树结构来孤立样本
      • 异常值的数量较少且与大部分样本的特征不同
      • 异常值会被更早的孤立出来,也即异常值会距离的根节点更近,而正常值则会距离根节点有更远的距离
    • 特点:
      • 离散和连续都可以处理
      • 不需要调参
      • 对高维数据也可以处理

在这里插入图片描述
连续数据

  • 更大的概率将异常样本尽快分开,离根节点近
    离散
  • 少类的样本很快就不能分了,离根节点近

孤立森林案例

# 导入库
from sklearn.preprocessing import OrdinalEncoder
from sklearn.ensemble import IsolationForest
import pandas as pd 
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D  # 导入3D样式库
# 数据准备
raw_data = pd.read_csv('data/outlier.txt',sep=',')  # 读取数据
raw_data.shape

# 数据清洗
#取出全nan的列
# raw_data.isnull().all(axis=0)
data_dropna=raw_data.dropna(axis=1,how='all')
#删掉  clientId
data_dropna=data_dropna.drop(['clientId'],axis=1)
data_dropna.shape

#找到有空值的列
#判断有没有nan
cols_na=data_dropna.isnull().any(0)
#提取有nan的
cols_na=cols_na[cols_na]
cols_na.index
#查看空值列的类型
data_dropna[cols_na.index].dtypes
#填充空值
fill_rules = {'newVisits': 0, 'pageviews': 0, 'isVideoAd': False, 'isTrueDirect': False}
data_fillna=data_dropna.fillna(fill_rules)
data_fillna.info()
# -----------------------特征工程
# 拆分数值特征和字符串特征
str_or_num = (data_fillna.dtypes=='object')
#拆分数值和字符串
str_cols=str_or_num[str_or_num].index
num_cols=str_or_num[str_or_num==False].index
str_cols,num_cols

#挑出字符串数据和数值数据
str_data=data_fillna[str_cols]
num_data=data_fillna[num_cols]

#对字符串特征进行编码
ordinal=OrdinalEncoder()
temp=ordinal.fit_transform(str_data)#经过sklearn处理后都成了ndarray
string_data=pd.DataFrame(temp,columns=str_cols)
string_data.head()

#数据合并
data_merge=pd.concat([num_data,string_data],axis=1)
data_merge.shape

#模型训练
data_merge.index,data_fillna.index
#实例化孤立森林
forest=IsolationForest(n_estimators=50,n_jobs=-1)
data_fillna.loc[:,'outlier_label']=forest.fit_predict(data_merge)#预测标签直接保存到原数据中
outlier_count=data_fillna['outlier_label'].value_counts()
outlier_count
print('outliers: {0}/{1}'.format(outlier_count[-1], outlier_count.sum()))  # 输出异常的结果数量

# -----------统计结果
#分析不同渠道source 的正常样本和异常样本数量
result=pd.pivot_table(data_fillna,
                      index='source',
                      columns='outlier_label',
                      values='keyword',
                      aggfunc='count',
                      fill_value=0,
                      margins=True)
#修改列名
result.columns=['outlier_count','normal_count','total']
result.head()
#计算异常比例
result.loc[:,'outlier_rate']=result['outlier_count']/result['total']
result.head()
# --------可视化
# 异常点图形展示
plt.style.use('ggplot')  # 使用ggplot样式库
fig = plt.figure(figsize=(10, 8))  # 创建画布对象
# 画图
ax = fig.add_subplot(111, projection='3d')
ax.scatter(result['outlier_count'], result['total'], result['outlier_rate'],
           s=100, edgecolors='k', c='r', marker='o',alpha=0.5) 
ax.set_xlabel('outlier_count')
ax.set_ylabel('total_count')
ax.set_zlabel('outlier_rate')
plt.title('outlier point distribution')  # 设置图像标题
  • 获取数据 业务方提供
  • 明确需求: 缩小异常样本的搜索范围
  • 导入数据
  • 数据清洗
    • 删除全nan的列
    • 删除id列
    • 填充空值
  • 特征工程
    • 对字符串特征进行ordinalencoder编码 变成0,1,2,3,4,5,6…
  • 模型训练
    • #实例化孤立森林
      forest=IsolationForest(n_estimators=50,n_jobs=-1)
      data_fillna.loc[:,'outlier_label']=forest.fit_predict(data_merge)#预测标签直接保存到原数据中
      
  • 统计分析
    • 分析各渠道的异常样本比例
    • 异常比例较高的渠道需要重点关注
  • 可视化

非结构化数据分析与挖掘-词频/词云图(略)

  • 读取文本
  • 正则表达式去除特殊符号— 文本清洗
  • jieba分词
    • jieba.lcut 列表
    • jieba.cut 生成器
  • 去除停用词
  • Counter计数
  • wordcloud词云图展示

词性标注— jieba.posesg
关键词提取— jieba.analyse.extract_tags

# 导入库
import re  # 正则表达式库
import collections  # 词频统计库
import numpy as np  # numpy库
import jieba  # 结巴分词
import wordcloud  # 词云展示库
from PIL import Image  # 图像处理库
import matplotlib.pyplot as plt  # 图像展示库
文本清洗
# 读取文本文件
with open('data/article1.txt',encoding='gbk') as fn:
    string_data = fn.read()  # 使用read方法读取整段文本
# 文本预处理
pattern = re.compile(u'\t|\n|\.|-|:|;|\)|\(|\?|"')  # 建立正则表达式匹配模式
string_data = re.sub(pattern, '', string_data)  # 将符合模式的字符串替换掉
string_data
#分词
words=jieba.cut(string_data)
words
#去除停用词
remove_words = ['的', ',', '和', '是', '随着', '对于', ' ', '对', '等', '能', '都', '。', '、', '中', '与', '在', '其', '了', '可以', '进行', '有', '更', '需要', '提供', '多', '能力', '通过', '会', '不同', '一个', '这个', '我们', '将', '并', '同时', '看', '如果', '但', '到', '非常', '—', '一','如何', '包括', '这']  # 自定义去除词库
words=[word for word in words if word not in remove_words]
words

#统计词频
word_counts=collections.Counter(words)
word_counts

#展示前10名
word_counts_top10=word_counts.most_common(10)
for w, c in word_counts_top10:  # 分别读出每条词和出现从次数
    print(w, c)  # 打印输出

#词云图显示
# 词频展示
mask = np.array(Image.open('data/wordcloud.jpg'))  # 定义词频背景
wc = wordcloud.WordCloud(
    font_path='C:/Windows/Fonts/simhei.ttf',  # 设置字体格式,不设置将无法显示中文
    mask=mask,  # 设置背景图
    max_words=200,  # 设置最大显示的词数
    max_font_size=100,  # 设置字体最大值

)
wc.generate_from_frequencies(word_counts)  # 从字典生成词云
image_colors = wordcloud.ImageColorGenerator(mask)  # 从背景图建立颜色方案
wc.recolor(color_func=image_colors)  # 将词云颜色设置为背景图方案
plt.imshow(wc)  # 显示词云
plt.axis('off')  # 关闭坐标轴  stylecloud

# 词性标注-------------------------------------------------------------
# 导入库
import jieba.posseg as pseg
words=pseg.lcut(string_data)
words
#直接封装 
import pandas as pd
words=pd.DataFrame(words,columns=['word','type'])
words.head()

#词性的频率
words['type'].value_counts()

# 关键词提取 textrank谷歌pagerank排名算法
 #导入库
import jieba.analyse  # 导入关键字提取库
result=jieba.analyse.extract_tags(string_data,topK=5,withWeight=True,allowPOS=['ns', 'n', 'vn', 'v', 'nr'],withFlag=True)
result
tags_list = [(i[0].word, i[0].flag, i[1]) for i in result]  #
tags_pd = pd.DataFrame(tags_list, columns=['word', 'flag', 'weight'])  # 创建数据框
tags_pd  # 打印数据框
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值