监督学习(Supervised Learning)-局部线性回归(Locally Weighted Linear Regression)

线性回归的一个可能是由可能出现欠拟合现象,因为它求的是具有最小均方误差的无偏估计。显而易见,如果模型欠拟合将不能取得很好的预测效果,所以有些方法允许在估计中引入一些偏差,从而降低预测的均方误差。

其中一个方法就是lwlr,在这个方法中,给待预测点附近的每个点赋予一个权重,距离近的权重更大,然后就和之前提到的线性回归一样,求最小均方差来进行普通的回归。显而易见,这样子每次我们算的权重都会不一样(只要输入的参数不一样。)

算回归系数的式子为:

 

lmlr_e

其中:

lrlm

其中t是唯一需要我们去确认的参数,可以参考下图:

lmlr-func

 

图1是原始数据的情况,图2是t=0.5时,整个权重函数的分布情况,图3是t=0.1时,权重函数的分布情况,图4是t=0.01时,整个权重函数的分布情况。

可以看见,t越小,则离待预测点的权重影响越大,而远离预待测点的权重影响越小。

很明显,局部加权回归在每一次预测新样本时都会重新确定参数,以达到更好的预测效果。当数据规模比较大的时候计算量很大,学习效率很低。并且局部加权回归也不是一定就能避免欠拟合。

sklearn并没有提供局部加权线性回归可以直接使用的函数,所以我这里给大家提供一个python写的,数据集还是用的sklearn里面带的糖尿病人的那个数据:

__author__ = 'qing'
# -*- coding: utf8 -*-
# !/usr/bin/env python

from numpy import *
from sklearn import datasets
import matplotlib.pyplot as plt


def lwlr(testPoint, xArr, yArr, k):  #这里的k即上文的t, 为了与.T区分开
    xMat = mat(xArr); yMat = mat(yArr).T  #T是转置矩阵
    m = shape(xMat)[0]
    weights = mat(eye((m))) #创建一个单位矩阵
    for j in range(m):                      #根据该点建立权重
        diffMat = testPoint - xMat[j,:]
        weights[j,j] = exp(diffMat*diffMat.T/(-2.0*k**2))
    xTx = xMat.T * (weights * xMat)
    if linalg.det(xTx) == 0.0:#先检测行列式是否为0,0则不存在逆
        print "This matrix is singular, cannot do inverse"
        return
    ws = xTx.I * (xMat.T * (weights * yMat))  #I是矩阵的逆
    return testPoint * ws

def lwlrTest(testArr, xArr, yArr, k):  #loops over all the data points and applies lwlr to each one
    m = shape(testArr)[0]
    yHat = zeros(m)
    for i in range(m):
        yHat[i] = lwlr(testArr[i],xArr,yArr,k)
    return yHat

# 图形化显示局部加权线性回归结果, 包括数据集及它的最佳拟合直线
def lwlrPlot(xArr, yArr, yHat):
    xMat = mat(xArr)
    srtInd = xMat[:, 3].argsort(0)
    xSort = xMat[srtInd][:, 0, :]
    # 画线
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.plot(xSort[:, 3], yHat[srtInd])
    # 画点
    ax.scatter(xMat[:, 3].flatten().A[0],
               mat(yArr).T[:, 0].flatten().A[0],
               s=2, c='red')
    plt.show()

def rssError(yArr, yHat):
    return ((yArr - yHat)**2).sum()


if __name__ == "__main__":
    diabetes = datasets.load_diabetes()
    diabetes_X_train = diabetes.data[:-20]
    diabetes_X_test  = diabetes.data[-20:]
    diabetes_y_train = diabetes.target[:-20]
    diabetes_y_test  = diabetes.target[-20:]
    lwlrResult = lwlrTest(diabetes_X_test, diabetes_X_train, diabetes_y_train, 0.14)
    print diabetes_y_test
    print lwlrResult
    print corrcoef(lwlrResult, diabetes_y_test)
    print rssError(lwlrResult, diabetes_y_test)
    lwlrPlot(diabetes_X_test, diabetes_y_test, lwlrResult)

最后我们可以看到,相关性的结果以及差平方和是:

[[ 1. 0.75591378]
[ 0.75591378 1. ]]

55830.0971546

plot
以及可以看到lwlr得到的拟合效果(对未知数据的预测,这里我任意选取了输入的一个特征作为横坐标)

代码开放在:

 https://github.com/ching1221/machine-learning

 

监督学习(Supervised Learning)-线性回归(Linear Regression)

打算开个系列把机器学习的基础算法都用心走一遍,顺手记录点东西,配套使用python的scikit-learn包。

先简要介绍下这个包,http://scikit-learn.org/stable/

About scikit-learn:

  • Simple and efficient tools for data mining and data analysis
  • Accessible to everybody, and reusable in various contexts
  • Built on NumPy, SciPy, and matplotlib
  • Open source, commercially usable – BSD license

要义:开源,机器学习、数据分析工具包,需要预装numpy,scipy,matplotlib等模块

scikit-learn的基本功能主要被分为六个部分,分类,回归,聚类,数据降维,模型选择,数据预处理。

今天先介绍它回归这一部分的功能。

线性回归

优点:结果易理解,计算不复杂。

缺点:对非线性数据拟合地不好。

适用数据类型:数值型以及标称型。

比如:你可能这样子来预测一个人的学习的成效:

score = 0.7*timeSpendOnStudy + 0.3*Gift

这就是一个回归方程,0.7和0.3在这里称为回归系数,我们利用一堆已知输入输出来求回归系数的过程就叫回归。

有了这些回归系数后,用回归系数乘以输入值,再将结果加在一起,就可以得到预测值了。

回归的一般方法

1、收集数据。

2、准备数据,回归需要数值型数据,标称型数据需要先转成二值型数据。

3、分析数据,数据可视化将有助于对数据做出理解和分析,在采用缩减法(shrinkage)求得新回归系数之后可以将新旧曲线绘在图上作对比。

4、训练算法:找到回归系数。

5、测试算法:使用R^2或者预测值和数据的拟合度,来分析模型的效果。

6、使用算法。

算法:

关于线性回归的最小二乘法矩阵求法,参考这篇博文,不再造轮子:http://blog.csdn.net/acdreamers/article/details/44662633

(为什么这样做,可以参考这片博文:http://blog.csdn.net/acdreamers/article/details/44662823

最后推导的结果:

lm_result

 

x为m组*n个自变量输入的m*n维矩阵,y为m*1的对应因变量输出,得到n*1的参数矩阵,即利用最小二乘法得到的最佳参数估计。

数据:

sklearn自带的糖尿病人的一些数据:

该数据集包含了442个病人的10项特征(年龄,性别,体重,血型等),以及一年后他们的疾病指数。

程序:

import numpy as np
from sklearn import linear_model
from sklearn import datasets


diabetes = datasets.load_diabetes()
diabetes_X_train = diabetes.data[:-20]
diabetes_X_test  = diabetes.data[-20:]
diabetes_y_train = diabetes.target[:-20]
diabetes_y_test  = diabetes.target[-20:]
lm = linear_model.LinearRegression()
lm.fit(diabetes_X_train, diabetes_y_train)
print(lm.coef_)
# The mean square error
print np.mean((lm.predict(diabetes_X_test)-diabetes_y_test)**2)

 # Explained variance score: 1 is perfect prediction
 # and 0 means that there is no linear relationship
 # between X and Y.
print lm.score(diabetes_X_test, diabetes_y_test)

结果:

系数:

[ 3.03499549e-01

-2.37639315e+02

5.10530605e+02

3.27736980e+02

-8.14131709e+02

4.92814588e+02

1.02848452e+02

1.84606489e+02
7.43519617e+02

7.60951722e+01]

方差:
2004.56760269

预测的准确率:

0.585075302269

 

再给一个有趣的测试,用线性回归来做图像处理:

数据:

uci提供的钢笔手写数字的图像(8*8图像矩阵, 0-16的像素值)和对应的识别结果

http://archive.ics.uci.edu/ml/datasets/Pen-Based+Recognition+of+Handwritten+Digits

程序:

from sklearn import datasets
from sklearn.linear_model import LinearRegression

digits = datasets.load_digits()  # 自带上述数据

trainingInput = digits.data[:1300]  # 数据一共有1797条,抽取前1300行作为训练数据
trainingOutput = digits.target[:1300]
testInput = digits.data[1300:]
testOutput = digits.target[1300:]
lm = LinearRegression()
lm.fit(trainingInput, trainingOutput).score(trainingInput, trainingOutput)  # 训练数据
print lm.predict(testInput) # 预测结果
print "the accurate is: " + str(lm.score(testInput, testOutput))  # 输出准确率

然而你会发现,这两个例子用线性回归做的效果并不好,准确率很低。后面将用其他机器学习的方法去做测试。

 

代码开放在:

 https://github.com/ching1221/machine-learning

一个零售业的数据分析分享(美特斯邦威)

其数据分析的业务架构:
数据清洗:
  ETL(传统业务数据)
  Kafka + Storm(实时日志清洗)
数据存储:
  关系型数据库(传统业务数据, oracle mysql……) 
  分布式存储(线上日志类数据,hdfs)
  内存存储(实时计算统计数据,redis)
数据分析:
  Spss/r/matlab(建模算法和离线计算)
  mahout(大数据的离线计算,mapreduce)
  Mblib*、spark(在线计算)
可视化:
  tableau(一套比较好用的bi)
数据决策系统
  drools*事件规则引擎
  精准营销
  商品预测
  个性化推荐

其建立了一个商品销售自动预测系统,考虑到的因素有:
  1、生命周期曲线(有历史数据的经验曲线)
  2、上市后的销售表现
  3、商品的价格变化(折扣等)
  4、门店的客流(节日)变化
  5、天气变化

根据这些因素得到了一个乘法的式子,所以做了取ln的处理,把数据变为线性的,做线性回归来拟合曲线。
并定期利用更新的销售数据做迭代,更新模型参数,再做预测(其采用oracle-r-oracle-bi报表)提供给运营作参考。

消费者大数据:
线上搜集点击、浏览、购买这些动作。
线下通过wifi探针(主动探测,扫描顾客的mac地址,用mac地址来作为guid),还提出了一种基于蓝牙的扫描方法,可以测出顾客的距离,判断其在店内的浏览区域(但因为蓝牙不常开,所以不好实施),在结账时利用摄像头做人脸识别(性别、年龄、vip客户的人脸和特征进行提取和存储)

标签:
内部标签(根据购买的记录):活跃度/高流失、购买价值、地域、时间偏好、颜色偏好、时尚度偏好、品类偏好
外部标签(数据共创):人口学、用户与门店位置关系、用户消费美邦的忠诚度(还在其他哪些商店买过东西),对其他非服装类品类的偏好(其他领域的应用,数据合作,比如跟滴滴打车共享数据,可以知道用户在哪个位置下车、得到门店地理位置因素)

构建一个完整的会员营销解决方案:

创建营销事件(活动)
	会员标签
	发布渠道(区域)
	发布内容
	发布时间

会员kpi诊断(分区域)
	kpi变化趋势
	kpi排名
	细分kpi

事件触发自动营销
	基于实时事件自动触发营销规划
	线下pos机购买后的优惠推送和商品推荐

个性化推荐
	介绍了美邦旗下的有范app(一款搭配app)
	结合基于内容和基于行为(协调过滤)的推荐,并结合消费者的偏好进行排序,提取搭配的特征
	(基于内容)利用商品特征、描述、标签和搭配的描述和标签构建搭配的各纬度特征来描述搭配的内容,其中通过lda等方法对文字特征进行降维获取搭配主题
	Mahout -得到基于行为的协同过滤;
	r/mahout得到lda推荐对象主题模型-得到内容推荐候选集;
	redis-计算流行度;
	 ——>推荐候选集融合/参数调整(规则引擎)
	
我的一些感受,结合腾讯视频业务,虽然不知道做没有做:
   1、对搜索事件进行监测,在短周期内查询那些用户搜索高但没有返回结果的影片,及时补充片源。
   2、客厅的服务要建立自己的独立系统,依赖洛子系统限制太多。
   3、采集的数据很多,但是要提取真正有效、可以用来提取用户特征的数据,做数据降维很重要
   4、可以尝试利用lda模型对现有影片资源的简介、标签等文字特征降维提取影片主题,做内容相似度推荐。
   5、路还很长.....

时间序列分析法

时间序列的构成要素

  • 现象所属的时间
  • 现象在各时间上的指标数值

时间序列分析的目的

  • 描述现象在过去时间的状态
  • 分析现象发展变化的规律性
  • 根据现象的过去行为预测其未来行为
  • 将相互联系的时间序列进行对比,研究有关现象之间的联系程度

时间序列的影响因素

  • 长期趋势
  • 季节变动
  • 循环变动
  • 不规则变动

时间序列的因素分析任务就是要正确确定时间序列性质,对构成时间序列各种因素加以分解,再分别测定其对时间序列变动的影响。

 

长期趋势:(t)

  • 现象在较长时期内持续发展变化的一种总态势
  • 由影响时间序列的根本性因素作用形成
  • 是时间序列中最基本的构成要素
  • 可分为上升趋势、下降趋势、水平趋势或分为:线性趋势和非线性趋势

从我们客厅日活的角度理解就是,有一个长期的增幅趋势,这个增幅可能随着时间降低。

 

季节变动:(s)

  • 通常表现为现象在一年内随着季节更替而发生的较有规律的增减变化,如由旺季和淡季之分
  • 是一种周期性的变化
  • 形成原因-有自然因素,也有社会因素

 

循环变动:(c)

这种因素的影响使现象呈现出以若干年(周、月、季)为一周期、涨落相间、扩展与紧缩、波峰与波谷相交替的波动。若经济危机就是循环变动,每一循环周期都要经历危机、萧条、复苏、高涨四个阶段。

  • 周期长度不同
  • 模型识别的难易程度不同
  • 形成原因不同

从日活理解就是,工作日和非工作日会有这种上升、下降的交替运动。

 

不规则变动(i)

包括随机变动和突然变动。

随机变动-现象受到各种偶然因素影响而呈现出方向不定、时起时伏、时大时小的变动。

突然变动-战争、自然灾害或其他社会因素等意外事件引起的变动。影响作用无法相互抵消,影响幅度很大。

一般只讨论有随机波动而不含突然异常变动的情况。随机变动与时间无关,是一种无规律的变动,难以测定,一般作为误差项处理。

 

按对四种因素的影响方式不同,可形成乘法模型加法模型两种。

 

乘法模型是假定四个因素对现象发展的影响是相互的,以长期趋势的绝对量为基础,其余成分均以比率表示。在现实中普遍运用的是乘法模型。

乘法模型:YT×S×C×I

式中Y为动态数列各发展水平, T、S、C、I分别表示四种变动因素。

  • 只有长期趋势是与Y同计量单位的绝对量;其余因素均为以长期趋势为基础的比率,通常以百分数表示。
  • 季节变动和循环变动的数值在各自的一个周期内平均为1(or 100%);不规则变动的数值从长时间来看,其平均也应为1(or 100%)。
  • 乘法模型中,各因素的分解是根据除法进行(如:Y / T = SCI)。

 

加法模型是假定四种因素的影响是独立的分别起作用,各成分都用绝对量表示。

加法模型:YTSCI

 

  长期趋势分析主要是指长期趋势的测定,采用一定的方法对时间序列进行修匀,使修匀后的数列排除季节变动、循环变动和无规则变动因素的影响,显示出现象变动的基本趋势,作为预测的依据。

测定长期趋势的方法:移动平均法,趋势方程拟合法(数学模型方法)

 

移动平均法

 

移动平均是选择一定的平均项数(常用 N 表示),采用逐项递移的方法对原时间序列计算一系列序时平均值;这些移动平均值消除或削弱了原数列中的不规则变动和其他变动,揭示出现象在较长时间内的基本发展趋势。

算法:

如果n是奇数,直接用除法就好。a1 ‘ =  (a1+a2+a3)/3

如果n是偶数,还需要二项移动平均。

pic1

移动平均法的特点

  • 移动平均对数列具有平滑修匀作用,平均项数(N)越大,对数列的平滑修匀作用越强;
  • 移动平均的数值应放在所平均时间的中间位置;
  • 当N 为奇数,只需一次移动平均;
  • 当N为偶数,需再进行二项移动平均即移正平均(或中心化);

移动间隔的长度应长短适中

  • 若数列包含周期性变动,为了消除周期变动而只反映T(长期趋势),应以周期长度作为移动间隔的长度,即: N=周期长度
  • 若是季度资料,应采用4项移动平均
  • 若为月份资料,应采用12项移动平均

总结:

移动平均法可以呈现出现象的长期趋势,但本身不能进行外推预测。只有当T为水平趋势时,才可用移动平均值作为最近一期的预测值。

 

趋势方程拟合法

 

当序列存在明显趋势时,采用趋势外推预测,利用数学中的某种曲线方程对原数列中的趋势进行拟合,以消除其他变动,揭示数列长期趋势,即该方法在数列中只包含T(趋势)、I(随机因素)中进行长期趋势的测定时应用较为广泛。

 

  • 直线趋势的测定
  • 抛物线趋势的测定
  • 指数曲线趋势的测定

 

趋势方程的选择

  • 定性分析:利用有关理论知识、结合现象变化的性质特点进行判断;
  • 绘制观测值散点图或时序图(折线图):这些图形常能很直观的表现出数列的趋势类型,是最常用也是比较有效的一种方法。
  • 根据数列的数据特征加以判断:若各个时期的变化量大体相同,即各时期的逐期增长量接近于一个常数,则趋势线近似于一条直线,这时拟和线性趋势方程;若各个时期的二级增长量大体相等,即各个时期的逐期增长量的增长量近似于一个常数,可以配合抛物线方程。

 

线性模型法

根据最小二乘法得到求解 a 和 b 的标准方程为:

pic2

实际运用中,为了计算方便,通常采用坐标平移的方法以时间序列的中点作为坐标原点,使得

则:

pic3

季节变动的测定

  • 季节变动
    • 现象在一年内随着季节更换形成的有规律变动;
    • 各年变化强度大体相同、且每年重现;
    • 扩展概念:对一年内由于社会、政治、经济、自然因素影响,形成的以一定时期为周期的有规则的重复变动;
  • 时间序列的又一个主要构成要素。
  • 测定目的
    • 确定现象过去的季节变化规律,帮助决策
    • 对未来现象季节变动作出预测
    • 消除时间序列中的季节因素

 

测定季节变动的基本方法

 

同期平均法

  • 假定 :Y=a.S.I 即假定时间序列为水平趋势(T=a,为常数) 且无循环波动(I=1)。
  • 根据原时间序列通过对同期数据求简单平均的方法来分离出季节变动因素,计算季节比率 S (或称为季节指数)。也可称为原始资料平均法 。

计算季节比例的步骤:

pic4

(可能大于1,如旺季)

 

趋势剔除法

假定:Y=T.S.I

基本思想:先将数列中的长期趋势予以消除,再计算

步骤:

  • 计算长期趋势;常用移动平均值作为T
  • 从原数列中提出趋势值,得季节变动和不规则变动相对数-Y/T  = S.I
  • 消除不规则变动I,得季节比率S
  • 调整季节比率,使季节比例的平均值为1。否则,计算一个调整系数(=1/季节比率的平均值),各期的季节比例乘以该调整系数,既得调整后的季节比率。

 

复合序列预测步骤

 

  • 确定并分离季节成分
    • 计算季节指数,以确定时间序列中的季节成分
    • 用每一个观测值除以相应的季节指数,以消除季节性
  • 建立预测模型病进行预测
    • 对消除季节成分的序列建立适当的预测模型,并根据这一模型进行预测
  • 计算最后的预测值
    • 用预测值乘以响应的季节指数,得到最终的预测值

季节因素分离后的序列反映了在没有季节因素影响的情况下时间序列的变化形态

 

循环变动和不规则变动的测定

 

循环变动分析一般要求有多年的时间序列资料通常采用两种方法:即剩余法和直接法。

  • 剩余法:是从动态数列中分别消除长期趋势、季节变动和不规则变动,其剩余的结果便是循环变动。按照关系式:Y=T·S·C·I,分别求得季节变动和长期趋势值,并把两者消除。
  • 直接法:将每年各季或各月的数值与上年同期进行对比,即求出年距发展速度来消除长期趋势和季节变动。

R在数据分析中应用的概括

r能做的可归纳为:数据分析,结果报告,发布结果;

 

1、探索性数据分析

画图,观察数据属性,数据模式;

频率直方图,时间序列;(分别从时域及频域的角度看)

不同分类结果,多图合并分析;

2、统计推断

由于抽样等各种因素带来的不准确性,所以我们得到的结论有可能是错的。所以做统计推断时我们强调得到推断结果+该结果可能错误的概率,即:

推断结果+结果的错误率(小于5%,则可以接受)

3、回归分析(线性模拟拟合数据)

预测量(因变量,如房屋面积、地理位置、卧室数目等)

变量(如房价)

得到预测量与变量关系,以做预测

4、机器学习

训练模型+预测

典型的分类问题 ,caret包

5、开发数据产品

工具:google vis  — r制作网页,调用google charts -> 交互式html

Manipulate — 人机交互

Rcharts — 使用r制作js交互式网页

Shinny —  制作交互式网页平台

一个发布shinny的网站:Shinnyapps.io

Slidify — 生成类似ppt的报告

 

其他:

发布项目的途径:Github, Rpubs

r下载 r: https://www.r-project.org/

Rstudio : http://www.rstudio.com/

包查看:cray.r-project.org

在rstudio中:

安装包:install.packages(“caret”)

载入包:library(caret),

一般包带有一些数据集可供使用:

查看载入包的数据包:data() ;查看数据详情:?Somedataname

浅谈Hive中索引、分区对查询的优化

索引:用户可以在某些列上创建索引来加速某些操作,给一个表创建的索引数据被保存在另外的表中。 但不是所有的查询都会受惠于Hive索引。可以使用EXPLAIN语法来分析HiveQL语句是否可以使用索引来提升用户查询的性能。像RDBMS中的索引一样,需要评估索引创建的是否合理,毕竟,索引需要更多的磁盘空间,并且创建维护索引也会有一定的代价。 用户必须要权衡从索引得到的好处和代价:
可以自己在hive上尝试一下先建立一张表,然后导入一些数据,再对数据的某一列建索引。
hive> create index your_index on table your_table(your_column)
> as ‘org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler’
> with deferred rebuild
> IN TABLE your_index_table;
hive> alter index your_index on your_table rebuild;
通过select * from your_table where your_column=’xxx’;
可以比较建立索引前后查询花费的时间。
分区:在Hive Select查询中一般会扫描整个表内容,会消耗很多时间做没必要的工作。有时候只需要扫描表中关心的一部分数据,因此建表时引入了partition概念。
这个具体是怎么工作的呢?我用一个实例来说明吧:
先在hive上建个带有分区的表:
hive> create table test (a string) partitioned by (b string, c string); //用b,c字段建立分区
OK
Time taken: 0.242 seconds
hive> alter table test add partition(b=’1′,c=’1′); //手动添加一个分区信息
OK
Time taken: 0.197 seconds
然后我插入一条数据:
hive> insert into test partition(b=’1′,c=’1′) values(‘1’);
可以看到hive的提示信息:
Moving data to: hdfs://localhost:9000/opt/hive/warehouse/test/b=1/c=1
我们再在hdfs上查看这个文件夹:
[hadoop@localhost Desktop]$ hadoop fs -ls /opt/hive/warehouse/test/b=1/c=1
Found 1 items
-rw-r–r– 1 root supergroup 2 2015-08-14 23:59 /opt/hive/warehouse/test/b=1/c=1/000000_0
ok,想必已经理解到了分区是怎么一回事了,我们事先对其进行分区,然后相应的数据根据对partition的指定就会被存到hdfs上相应的文件目录下。这样子在查询的时候就可以避免扫整个表,通过文件夹目录就对数据进行读取了。

用数据说话(一)数据指标

最近复习统计学的东西比较多,需要记录下来,与同事一起分享工程中的体会。

统计数据首先需要经过预处理和整理,以便人们对数据分布的类型和特点有了一个大概的了解。但这种了解并不能帮助我们准确地描述出统计数据的分布,还需要更深入的分析,找到能反映数据分布特征的各个代表值。对统计数据分布的特征和规律,可以从三个方面进行测度和描述:一是数据集位置的测度,反映各数据向其中心值靠拢或聚集的程度;二是数据集离散程度,反映各数据远离其中心值的趋势;三是数据集的峰度与偏度,反映数据分布的形状。这三个方面从不同侧面反映了数据分布特征。

data

集中趋势

众数:在统计分布上具有明显集中趋势点的数值,代表数据的一般水平(众数可以不存在或多于一个)。

简单的说,就是一组数据中占比例最多的那个数。

中数:把一组数从小到大排个序。正中间的那个数(数字个数为奇数)

 

离散程度

极差、方差、标准差

极差是指一组数据中最大数据与最小数据的差。方差是各个数据与平均数之差的平方的平均数(可以反应偏离平均值的程度)。标准差就是方差的算术平方根。

方差的计算公式为:

fc

 

 

分布的形状

fb

重点概念

偏度

  1. 数据分布偏斜程度的测度
  2. 偏度系数=0为对称分布
  3. 偏度系数> 0为右偏分布
  4. 偏度系数< 0为左偏分布
  5.  计算公式为pd

峰度(一般在spss类的软件中,会先减去3)

  1.  数据分布扁平程度的测度
  2. 峰度系数=3扁平程度适中
  3. 偏态系数<3为扁平分布
  4. 偏态系数>3为尖峰分布
  5.  计算公式为fd

 

我将分享的ppt供下载: 数据说话(一)

Mahout 安装及测试

Mahout 是一个很强大的数据挖掘工具,是一个分布式机器学习算法的集合,包括:被称为Taste的分布式协同过滤的实现、分类、聚类等。Mahout最大的优点就是基于hadoop实现,把很多以前运行于单机上的算法,转化为了MapReduce模式,这样大大提升了算法可处理的数据量和处理性能。

在Mahout实现的机器学习算法:
算法类 算法名 中文名
分类算法 Logistic Regression 逻辑回归
Bayesian 贝叶斯
SVM 支持向量机
Perceptron 感知器算法
Neural Network 神经网络
Random Forests 随机森林
Restricted Boltzmann Machines 有限波尔兹曼机
聚类算法 Canopy Clustering Canopy聚类
K-means Clustering K均值算法
Fuzzy K-means 模糊K均值
Expectation Maximization EM聚类(期望最大化聚类)
Mean Shift Clustering 均值漂移聚类
Hierarchical Clustering 层次聚类
Dirichlet Process Clustering 狄里克雷过程聚类
Latent Dirichlet Allocation LDA聚类
Spectral Clustering 谱聚类
关联规则挖掘 Parallel FP Growth Algorithm 并行FP Growth算法
回归 Locally Weighted Linear Regression 局部加权线性回归
降维/维约简 Singular Value Decomposition 奇异值分解
Principal Components Analysis 主成分分析
Independent Component Analysis 独立成分分析
Gaussian Discriminative Analysis 高斯判别分析
进化算法 并行化了Watchmaker框架
推荐/协同过滤 Non-distributed recommenders Taste(UserCF, ItemCF, SlopeOne)
Distributed Recommenders ItemCF
向量相似度计算 RowSimilarityJob 计算列间相似度
VectorDistanceJob 计算向量间距离
非Map-Reduce算法 Hidden Markov Models 隐马尔科夫模型
集合方法扩展 Collections 扩展了java的Collections类

 

二、Mahout安装、配置

一、下载Mahout

http://archive.apache.org/dist/mahout/
二、解压
tar -zxvf mahout-distribution-0.9.tar.gz
三、配置环境变量
3.1、配置Mahout环境变量
/etc/profile.d
mahout.sh
export MAHOUT_HOME=/home/yujianxin/mahout/mahout-distribution-0.9
export MAHOUT_CONF_DIR=$MAHOUT_HOME/conf
/etc
vim profile
export PATH=$MAHOUT_HOME/conf:$MAHOUT_HOME/bin:$PATH
3.2、配置Mahout所需的Hadoop环境变量
(安装hadoopshi3已经做过了,所以不再演示)
不过之前没有加过 hadoop_conf_dir的得加一个,为了之后mahout在hadoop上运行时使用
/etc/profile.d
vim hadoop.sh
export HADOOP_CONF_DIR=${HADOOP_HOME}/conf
source mahout.sh, profile
启动mahout, 如果出现

mahout_local is not set, 这个,不要以为是错误信息

MAHOUT_LOCAL:设置是否本地运行,如果设置这个参数就不会运行hadoop了,一旦设置这个参数,那HADOOP_CONF_DIR 和HADOOP_HOME 这两个参数的设置就自动失效了。

四、测试 
启动Hadoop
start-all.sh
下载测试数据
synthetic_control.data
上传测试数据到hdfs
1:将样本数据集放到hdfs中指定文件下,应该在testdata文件夹下
hadoop fs -put synthetic_control.data /user/hadoop/testdata
2:使用Mahout中的kmeans聚类算法,执行命令:
mahout -core  org.apache.mahout.clustering.syntheticcontrol.kmeans.Job
5.5 查看聚类结果
当然,此次安装我主要是为了实现协同过滤算法,所以之后我还会给的例子会是一个简单的实现了协调过滤算法的例子。待出新篇吧

centos 6.5 搭建hadoop伪分布服务器

做协同过滤,打算用apache mahout,首先得先搞个hadoop,之前一直说弄,都没机会,现在需要的时候,来弄一下。纪录一下全过程。

环境: centos 6.6 final 64bit

hadoop包:hadoop-1.2.1-bin.tag.gz (官网下不到了,可以自行搜,csdn上有)

jdk :jdk1.8.0_51

一、准备

jdk解压什么的..就不说了..

1. 设置jdk环境变量(根据自己安装的来)

/etc/profile.d

java.sh

export JAVA_HOME=/usr/lib/jvm/jdk1.8.0_51

export JRE_HOME=$JAVA_HOME/jre

export CLASSPATH=$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar jvm/jdk1.8.0_51

2.创建一个hadoop用户

groupadd hadoop

useradd hadoop -g hadoop

passwd hadoop

3.hadoop的准备

创建文件夹:

mkdir /hadoop
mkdir /hadoop/hdfs
mkdir /hadoop/hdfs/data
mkdir /hadoop/hdfs/name
mkdir /hadoop/mapred
mkdir /hadoop/mapred/local
mkdir /hadoop/mapred/system
mkdir /hadoop/tmp

更改owner:

chown -R hadoop /hadoop

4.设置Hadoop用户使之可以免密码ssh到localhost(很重要)

su – hadoop
ssh-keygen -t dsa -P ” -f ~/.ssh/id_dsa
cat ~/.ssh/id_dsa.pub>> ~/.ssh/authorized_keys

cd /home/hadoop/.ssh
chmod 600 authorized_keys

注意这里的权限问题,保证.ssh目录权限为700,authorized_keys为600

 

验证: ssh localhost 能连上去且不要密码就行了.

二、安装与配置

5. 安装hadoop

su 先切换到root

mkdir /opt/hadoop 创建一个文件夹用来装hadoop

把安装文件拷贝到/opt/hadoop

mv hadoop….tar.gz /opt/hadoop

cd /opt/hadoop

tar -zxvf hadoop-x…tar.gz

done.

更改owner

chown -R hadoop /opt/hadoop

6. 配置hadoop

su hadoop

cd /opt/hadoop/hadoop-1.2.1/conf

接下来的配置,跟上面第3步中创建的文件夹以及你安装hadoop以及java的目录有关,需要自己根据自己的创建情况来做。

core-site.xml

<configuration>
<property>
<name>fs.default.name</name>
<value>hdfs://localhost:9000</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/hadoop/tmp</value>   –tmp目录
</property>
</configuration>

hdfs-site.xml

<configuration>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
<property>
<name>dfs.name.dir</name>
<value>/hadoop/hdfs/name</value>  –name目录
</property>
<property>
<name>dfs.data.dir</name>
<value>/hadoop/hdfs/data</value>   –date目录
</property>
</configuration>

mapred-site.xml

<configuration>
<property>
<name>mapred.job.tracker</name>
<value>localhost:9001</value>
</property>
</configuration>

hadoop-env.sh
配置JAVA_HOME 与 HADOOP_HOME_WARN_SUPPRESS。
PS:HADOOP_HOME_WARN_SUPPRESS这个变量可以避免某些情况下出现这样的提醒 “WARM: HADOOP_HOME is deprecated”
export JAVA_HOME=/usr/lib/jvm/jdk1.8.0_51
export HADOOP_HOME_WARN_SUPPRESS=”TRUE”
重新配置 /etc/profile 文件,最终如:
export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
测试安装:
hadoop  version
ok。
三、启动
首次启动先格式化namenode,再启动
hadoop namenode -format
start-all.sh
验证: jps
如果看到以下进程,那么就ok了:
18596 JobTracker
18341 DataNode
18730 TaskTracker
18204 NameNode
18494 SecondaryNameNode
如果有什么问题,可以去/opt/hadoop/hadoop-1.2.1/logs查看相应的日志
最后就可以通过以下链接访问haddop服务了
localhost:50030/   for the Jobtracker
localhost:50070/   for the Namenode
localhost:50060/   for the Tasktracker
PS:完全分布式的安装与伪分布式的安装大同小异,注意如下几点即可
1.集群内ssh免用户登录
2.配置文件中指定具体的ip地址(或机器名),而不是localhost
3.配置masters和slaves文件,加入相关ip地址(或机器名)即可
以上配置需要在各个节点上保持一致。
安装中的问题:
可能遇到namenode启动不了的情况,建议查看是否hadoop-env.sh中启用了java_home的设置,以及可能是先没有格式化,就直接start-all.sh了,那么就先闪一下/hadoop/tmp这个文件夹,再重新生成一下:
stop-all.sh
rm -rf /hadoop/tmp
mkdir /hadoop/tmp
然后再:
hadoop namenode -format
start-all.sh

协同过滤,Collaborative Filtering

终于可以做做想做的事情啦,打算把基于item的协同过滤用在第一期推荐算法里面, 现先过一遍协调过滤的算法。

什么是协同过滤

协同过滤是利用集体智慧的一个典型方法。要理解什么是协同过滤,一个简单的问题就能够说明,如果你现在想看个电影,但你不知道具体看哪部,你会怎么做?大部分的人会问问周围的朋友,看看最近有什么好看的电影推荐,而我们一般更倾向于从口味比较类似的朋友那里得到推荐。这就是协同过滤的核心思想。

2 协同过滤的实现

要实现协同过滤的推荐算法,要进行以下三个步骤:

收集数据——找到相似用户和物品——进行推荐

收集数据

这里的数据指的都是用户的历史行为数据,比如用户的播放记录,收藏行为等等,这些都可以用来作为数据供推荐算法使用,服务于推荐算法。需要特别指出的在于,不同的数据准确性不同,粒度也不同,在使用时需要考虑到噪音所带来的影响。

下表是ibm给的一个比较常用的推荐引擎的参考指标:

表 1 用户行为和用户偏好
用户行为 类型 特征 作用
评分 显式 整数量化的偏好,可能的取值是 [0, n];n 一般取值为 5 或者是 10 通过用户对物品的评分,可以精确的得到用户的偏好
投票 显式 布尔量化的偏好,取值是 0 或 1 通过用户对物品的投票,可以较精确的得到用户的偏好
转发 显式 布尔量化的偏好,取值是 0 或 1 通过用户对物品的投票,可以精确的得到用户的偏好。
如果是站内,同时可以推理得到被转发人的偏好(不精确)
保存书签 显示 布尔量化的偏好,取值是 0 或 1 通过用户对物品的投票,可以精确的得到用户的偏好。
标记标签
(Tag)
显示 一些单词,需要对单词进行分析,得到偏好 通过分析用户的标签,可以得到用户对项目的理解,同时可以分析出用户的情感:喜欢还是讨厌
评论 显示 一段文字,需要进行文本分析,得到偏好 通过分析用户的评论,可以得到用户的情感:喜欢还是讨厌
点击流
( 查看 )
隐式 一组用户的点击,用户对物品感兴趣,需要进行分析,得到偏好 用户的点击一定程度上反映了用户的注意力,所以它也可以从一定程度上反映用户的喜好。
页面停留时间 隐式 一组时间信息,噪音大,需要进行去噪,分析,得到偏好 用户的页面停留时间一定程度上反映了用户的注意力和喜好,但噪音偏大,不好利用。
购买 隐式 布尔量化的偏好,取值是 0 或 1 用户的购买是很明确的说明这个项目它感兴趣。

以上列举的用户行为都是比较通用的,推荐引擎设计人员可以根据自己应用的特点添加特殊的用户行为,并用他们表示用户对物品的喜好。

在一般应用中,我们提取的用户行为一般都多于一种,关于如何组合这些不同的用户行为,基本上有以下两种方式:

  • 将不同的行为分组:一般可以分为“查看”和“购买”等等,然后基于不同的行为,计算不同的用户 / 物品相似度。类似于当当网或者 Amazon 给出的“购买了该图书的人还购买了 …”,“查看了图书的人还查看了 …”
  • 根据不同行为反映用户喜好的程度将它们进行加权,得到用户对于物品的总体喜好。一般来说,显式的用户反馈比隐式的权值大,但比较稀疏,毕竟进行显示反馈的用户是少数;同时相对于“查看”,“购买”行为反映用户喜好的程度更大,但这也因应用而异。

收集了用户行为数据,我们还需要对数据进行一定的预处理,其中最核心的工作就是:减噪和归一化。

  • 减噪:用户行为数据是用户在使用应用过程中产生的,它可能存在大量的噪音和用户的误操作,我们可以通过经典的数据挖掘算法过滤掉行为数据中的噪音,这样可以是我们的分析更加精确。
  • 归一化:如前面讲到的,在计算用户对物品的喜好程度时,可能需要对不同的行为数据进行加权。但可以想象,不同行为的数据取值可能相差很大,比如,用户的查看数据必然比购买数据大的多,如何将各个行为的数据统一在一个相同的取值范围中,从而使得加权求和得到的总体喜好更加精确,就需要我们进行归一化处理。最简单的归一化处理,就是将各类数据除以此类中的最大值,以保证归一化后的数据取值在 [0,1] 范围中。

进行的预处理后,根据不同应用的行为分析方法,可以选择分组或者加权处理,之后我们可以得到一个用户偏好的二维矩阵,一维是用户列表,另一维是物品列表,值是用户对物品的偏好,一般是 [0,1] 或者 [-1, 1] 的浮点数值。

 

找到相似用户和物品

这一步也很简单,其实就是计算用户间以及物品间的相似度。以下是几种计算相似度的方法:

  • 欧几里德距离(Euclidean Distance)

最初用于计算欧几里德空间中两个点的距离,假设 x,y 是 n 维空间的两个点,它们之间的欧几里德距离是:

13115033_4hDQ

可以看出,当 n=2 时,欧几里德距离就是平面上两个点的距离。

当用欧几里德距离表示相似度,一般采用以下公式进行转换:距离越小,相似度越大

13115034_im6Y

  • 皮尔逊相关系数(Pearson Correlation Coefficient)

皮尔逊相关系数一般用于计算两个定距变量间联系的紧密程度,它的取值在 [-1,+1] 之间。

13115034_QiXA

sx, sy是 x 和 y 的样品标准偏差。

  • Cosine 相似度(Cosine Similarity)

Cosine 相似度被广泛应用于计算文档数据的相似度:

13115035_Gxj6

  • Tanimoto 系数(Tanimoto Coefficient)

Tanimoto 系数也称为 Jaccard 系数,是 Cosine 相似度的扩展,也多用于计算文档数据的相似度:

13115035_toIe

相似邻居的计算

介绍完相似度的计算方法,下面我们看看如何根据相似度找到用户 – 物品的邻居,常用的挑选邻居的原则可以分为两类:图 1 给出了二维平面空间上点集的示意图。

  • 固定数量的邻居:K-neighborhoods 或者 Fix-size neighborhoods

不论邻居的“远近”,只取最近的 K 个,作为其邻居。如图 1 中的 A,假设要计算点 1 的 5- 邻居,那么根据点之间的距离,我们取最近的 5 个点,分别是点 2,点 3,点 4,点 7 和点 5。但很明显我们可以看出,这种方法对于孤立点的计算效果不好,因为要取固定个数的邻居,当它附近没有足够多比较相似的点,就被迫取一些不太相似的点作为邻居,这样就影响了邻居相似的程度,比如图 1 中,点 1 和点 5 其实并不是很相似。

  • 基于相似度门槛的邻居:Threshold-based neighborhoods

与计算固定数量的邻居的原则不同,基于相似度门槛的邻居计算是对邻居的远近进行最大值的限制,落在以当前点为中心,距离为 K 的区域中的所有点都作为当前点的邻居,这种方法计算得到的邻居个数不确定,但相似度不会出现较大的误差。如图 1 中的 B,从点 1 出发,计算相似度在 K 内的邻居,得到点 2,点 3,点 4 和点 7,这种方法计算出的邻居的相似度程度比前一种优,尤其是对孤立点的处理。

13115035_pXHo

计算推荐

 

基于用户的 CF(User CF)

基于用户的 CF 的基本思想相当简单,基于用户对物品的偏好找到相邻邻居用户,然后将邻居用户喜欢的推荐给当前用户。计算上,就是将一个用户对所有物品的偏好作为一个向量来计算用户之间的相似度,找到 K 邻居后,根据邻居的相似度权重以及他们对物品的偏好,预测当前用户没有偏好的未涉及物品,计算得到一个排序的物品列表作为推荐。图 2 给出了一个例子,对于用户 A,根据用户的历史偏好,这里只计算得到一个邻居 – 用户 C,然后将用户 C 喜欢的物品 D 推荐给用户 A。

13115036_UyUM

 

基于物品的 CF(Item CF)

基于物品的 CF 的原理和基于用户的 CF 类似,只是在计算邻居时采用物品本身,而不是从用户的角度,即基于用户对物品的偏好找到相似的物品,然后根据用户的历史偏好,推荐相似的物品给他。从计算的角度看,就是将所有用户对某个物品的偏好作为一个向量来计算物品之间的相似度,得到物品的相似物品后,根据用户历史的偏好预测当前用户还没有表示偏好的物品,计算得到一个排序的物品列表作为推荐。图 3 给出了一个例子,对于物品 A,根据所有用户的历史偏好,喜欢物品 A 的用户都喜欢物品 C,得出物品 A 和物品 C 比较相似,而用户 C 喜欢物品 A,那么可以推断出用户 C 可能也喜欢物品 C。

13115037_vWV9

User CF vs. Item CF

前面介绍了 User CF 和 Item CF 的基本原理,下面我们分几个不同的角度深入看看它们各自的优缺点和适用场景:

  • 计算复杂度

Item CF 和 User CF 是基于协同过滤推荐的两个最基本的算法,User CF 是很早以前就提出来了,Item CF 是从 Amazon 的论文和专利发表之后(2001 年左右)开始流行,大家都觉得 Item CF 从性能和复杂度上比 User CF 更优,其中的一个主要原因就是对于一个在线网站,用户的数量往往大大超过物品的数量,同时物品的数据相对稳定,因此计算物品的相似度不但计算量较小,同时也不必频繁更新。但我们往往忽略了这种情况只适应于提供商品的电子商务网站,对于新闻,博客或者微内容的推荐系统,情况往往是相反的,物品的数量是海量的,同时也是更新频繁的,所以单从复杂度的角度,这两个算法在不同的系统中各有优势,推荐引擎的设计者需要根据自己应用的特点选择更加合适的算法。

  • 适用场景

在非社交网络的网站中,内容内在的联系是很重要的推荐原则,它比基于相似用户的推荐原则更加有效。比如在购书网站上,当你看一本书的时候,推荐引擎会给你推荐相关的书籍,这个推荐的重要性远远超过了网站首页对该用户的综合推荐。可以看到,在这种情况下,Item CF 的推荐成为了引导用户浏览的重要手段。同时 Item CF 便于为推荐做出解释,在一个非社交网络的网站中,给某个用户推荐一本书,同时给出的解释是某某和你有相似兴趣的人也看了这本书,这很难让用户信服,因为用户可能根本不认识那个人;但如果解释说是因为这本书和你以前看的某本书相似,用户可能就觉得合理而采纳了此推荐。

相反的,在现今很流行的社交网络站点中,User CF 是一个更不错的选择,User CF 加上社会网络信息,可以增加用户对推荐解释的信服程度。

  • 推荐多样性和精度

研究推荐引擎的学者们在相同的数据集合上分别用 User CF 和 Item CF 计算推荐结果,发现推荐列表中,只有 50% 是一样的,还有 50% 完全不同。但是这两个算法确有相似的精度,所以可以说,这两个算法是很互补的。

关于推荐的多样性,有两种度量方法:

第一种度量方法是从单个用户的角度度量,就是说给定一个用户,查看系统给出的推荐列表是否多样,也就是要比较推荐列表中的物品之间两两的相似度,不难想到,对这种度量方法,Item CF 的多样性显然不如 User CF 的好,因为 Item CF 的推荐就是和以前看的东西最相似的。

第二种度量方法是考虑系统的多样性,也被称为覆盖率 (Coverage),它是指一个推荐系统是否能够提供给所有用户丰富的选择。在这种指标下,Item CF 的多样性要远远好于 User CF, 因为 User CF 总是倾向于推荐热门的,从另一个侧面看,也就是说,Item CF 的推荐有很好的新颖性,很擅长推荐长尾里的物品。所以,尽管大多数情况,Item CF 的精度略小于 User CF, 但如果考虑多样性,Item CF 却比 User CF 好很多。

如果你对推荐的多样性还心存疑惑,那么下面我们再举个实例看看 User CF 和 Item CF 的多样性到底有什么差别。首先,假设每个用户兴趣爱好都是广泛的,喜欢好几个领域的东西,不过每个用户肯定也有一个主要的领域,对这个领域会比其他领域更加关心。给定一个用户,假设他喜欢 3 个领域 A,B,C,A 是他喜欢的主要领域,这个时候我们来看 User CF 和 Item CF 倾向于做出什么推荐:如果用 User CF, 它会将 A,B,C 三个领域中比较热门的东西推荐给用户;而如果用 ItemCF,它会基本上只推荐 A 领域的东西给用户。所以我们看到因为 User CF 只推荐热门的,所以它在推荐长尾里项目方面的能力不足;而 Item CF 只推荐 A 领域给用户,这样他有限的推荐列表中就可能包含了一定数量的不热门的长尾物品,同时 Item CF 的推荐对这个用户而言,显然多样性不足。但是对整个系统而言,因为不同的用户的主要兴趣点不同,所以系统的覆盖率会比较好。

从上面的分析,可以很清晰的看到,这两种推荐都有其合理性,但都不是最好的选择,因此他们的精度也会有损失。其实对这类系统的最好选择是,如果系统给这个用户推荐 30 个物品,既不是每个领域挑选 10 个最热门的给他,也不是推荐 30 个 A 领域的给他,而是比如推荐 15 个 A 领域的给他,剩下的 15 个从 B,C 中选择。所以结合 User CF 和 Item CF 是最优的选择,结合的基本原则就是当采用 Item CF 导致系统对个人推荐的多样性不足时,我们通过加入 User CF 增加个人推荐的多样性,从而提高精度,而当因为采用 User CF 而使系统的整体多样性不足时,我们可以通过加入 Item CF 增加整体的多样性,同样同样可以提高推荐的精度。

  • 用户对推荐算法的适应度

前面我们大部分都是从推荐引擎的角度考虑哪个算法更优,但其实我们更多的应该考虑作为推荐引擎的最终使用者 — 应用用户对推荐算法的适应度。

对于 User CF,推荐的原则是假设用户会喜欢那些和他有相同喜好的用户喜欢的东西,但如果一个用户没有相同喜好的朋友,那 User CF 的算法的效果就会很差,所以一个用户对的 CF 算法的适应度是和他有多少共同喜好用户成正比的。

Item CF 算法也有一个基本假设,就是用户会喜欢和他以前喜欢的东西相似的东西,那么我们可以计算一个用户喜欢的物品的自相似度。一个用户喜欢物品的自相似度大,就说明他喜欢的东西都是比较相似的,也就是说他比较符合 Item CF 方法的基本假设,那么他对 Item CF 的适应度自然比较好;反之,如果自相似度小,就说明这个用户的喜好习惯并不满足 Item CF 方法的基本假设,那么对于这种用户,用 Item CF 方法做出好的推荐的可能性非常低。