Merge branch 'master' into master

This commit is contained in:
ApacheCN
2017-03-09 15:07:08 +08:00
committed by GitHub
8 changed files with 424 additions and 2 deletions

2
.gitignore vendored
View File

@@ -88,5 +88,3 @@ ENV/
# Rope project settings
.ropeproject
.vscode

View File

@@ -11,9 +11,11 @@
* 3) 决策树
* [决策树](./docs/3.决策树.md)
* 4) 基于概率论的分类方法:朴素贝叶斯
* [朴素贝叶斯](./docs/4.朴素贝叶斯.md)
* 5) Logistic回归
* [Logistic回归](./docs/5.Logistic回归.md)
* 6) 支持向量机
* [支持向量机](./docs/6.支持向量机.md)
* 7) 利用AdaBoost元算法提高分类
## 第二部分 利用回归预测数值型数据

21
docs/10.k-means聚类.md Normal file
View File

@@ -0,0 +1,21 @@
# 10) k-means聚类
* 聚类介绍
* 聚类是一种无监督的学习,它将相似的对象归到一个簇中。
* 聚类分析试图将相似对象归入同一簇,将不相似对象归到不同簇。相似这一概念取决于所选择的相似度计算方法。
* K-均值聚类算法
* 优点 : 容易实现
* 缺点 : 可能收敛到局部最小值,在大规模数据集上收敛较慢。
* 使用数据类型 : 数值型数据。
* K-均值算法工作流程
* 首先,随机确定 k 个初始点作为质心。
* 然后,将数据集中的每个点分配到一个簇中。(为每个点找到距其最近的质心,并将其分配给该质心所对应的簇)
* 最后,每个簇的质心更新为该簇所有点的平均值。
* K-均值算法伪代码如下
* 创建 k 个点作为起始质心(通常是随机选择)
* 当任意一个点的簇分配结果发生改变时
* 对数据集中的每个数据点
* 对每个质心
* 计算质心与数据点之间的距离
* 将数据点分配到距其最近的簇
* 对每一个簇,计算簇中所有点的均值并将均值作为质心

50
docs/4.朴素贝叶斯.md Normal file
View File

@@ -0,0 +1,50 @@
# 4) 朴素贝叶斯
* 假设: 特征之间强(朴素)独立
* 概率模型
* P(C|F1F2...Fn) = P(F1F2...Fn|C)P(C) / P(F1F2...Fn)
* 由于对于所有类别P(F1F2...Fn)都是相同的比较P(C|F1F2...Fn)只用比较P(F1F2...Fn|C)P(C)就好了
* 朴素贝叶斯的特点
* 优点:在数据较少的情况下仍然有效,可以处理多类别问题
* 缺点:对于输入数据的准备方式较为敏感
* 适用数据类型:标称型数据
* 朴素贝叶斯的一般过程
* 收集数据:可以使用任何方法
* 准备数据:需要数值型或者布尔型数据
* 分析数据:有大量特征时,绘制特征作用不大,此时使用直方图效果更好。
* 训练算法:计算不同的独立特征的条件概率
* 测试算法:计算错误率
* 使用算法:文本分类等
* 优化
* 为了避免一个概率为0导致P(F1|C)*P(F2|C)....P(Fn|C)整个为0所以优化为将所有词的出现数都初始化为1并将分母初始化为2.
* 由于大部分因子比较小乘积之后得到的数不易比较程序误差较大。所以取对数后可将乘法转化为加法P(F1|C)*P(F2|C)....P(Fn|C)P(C) -> log(P(F1|C))+log(P(F2|C))+....+log(P(Fn|C))+log(P(C))
* 总结
* 这一块代码比较乱,最好先把公式理一理再看
* 可以参考一下[阮一峰的博客](http://www.ruanyifeng.com/blog/2013/12/naive_bayes_classifier.html)

25
docs/6.支持向量机.md Normal file
View File

@@ -0,0 +1,25 @@
# 6) 支持向量机
* 基本概念
* 假设有两组数据,我们可以用一条线将这两个数据集分隔开,这条直线称为分隔超平面
(当维数很高时称为分隔超平面)。
* 我们希望找到离分隔超平面最近的点,确保它们离分隔面的距离尽可能远。
* 支持向量就是离分隔超平面最近的那些点。
* 支持向量机特点
* 优点:泛化错误率低,计算开销不大,结果易解释。
* 缺点:对参数调节和核函数的选择敏感,原始分类器不加修改仅适用于处理二类问题。
* 适用数据类型:数值型和标称型数据。
* SVM应用的一般流程
1. 准备收集数据:可以使用任何方法。
2. 准备数据:需要数值型数据。
3. 分析数据:有助于可视化分隔超平面。
4. 训练算法SVM的大部分时间都花在训练上该过程主要实现两个参数的调优。
5. 测试算法:测试分类结果是否达到预期的目的。
6. 使用算法几乎所有分类问题都可以使用SVM值得一提的是SVM本身是一个二类分类器
对多类问题应用SVM需要对代码做一些修改。

View File

@@ -0,0 +1,18 @@
# 8)预测数值型数据:回归
* 线性回归的特点
* 优点:结果易于理解,计算上不复杂。
* 缺点:对非线性的数据拟合不好。
* 适用数据范围:数值型和标称型数据。
* 工作原理
* 回归的目的是预测数值型的目标值。最直接的办法是以及输入写出一个目标值的计算公式。
* 回归的一般流程
* 收集数据:任何方法
* 准备数据:回归需要数值型数据,标称型数据将被转成二值型数据。
* 分析数据:绘出数据的可视二维图将有助于对数据做出理解和分析,在采用缩减法求得新回归系数之后,可以将新拟合线绘在图上作为对比。
* 训练算法:找到回归系数。
* 测试数据使用R的平方或者预测值和数据的拟合度来分析模型的效果。
* 使用算法:使用回归,可以在给定输入的时候预测出一个数值,这是对分类方法的提升,因为这样可以预测连续型数据而不仅仅是离散的类别标签。
* 总结
* 求回归系数的过程就是回归。

View File

@@ -0,0 +1,258 @@
'''
Create by ApacheCN-xy
Date from 2017-02-27
'''
from numpy import *
def loadDataSet(fileName): #解析以tab键分隔的文件中的浮点数
numFeat = len(open(fileName).readline().split('\t')) - 1 #获得一行有几个字段
dataMat = []; labelMat = []
fr = open(fileName)
for line in fr.readlines(): #读取每一行
lineArr =[]
curLine = line.strip().split('\t') #删除每一行的开头和结尾的tab
for i in range(numFeat):#从0到3不包含3
lineArr.append(float(curLine[i]))#将数据添加到lineArr List中
dataMat.append(lineArr)
labelMat.append(float(curLine[-1]))
return dataMat,labelMat
def standRegres(xArr,yArr): #线性回归
xMat = mat(xArr); yMat = mat(yArr).T
xTx = xMat.T*xMat
if linalg.det(xTx) == 0.0:
print ("This matrix is singular, cannot do inverse")
return
ws = xTx.I * (xMat.T*yMat)
return ws
def lwlr(testPoint,xArr,yArr,k=1.0):
xMat = mat(xArr); yMat = mat(yArr).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:
print ("This matrix is singular, cannot do inverse")
return
ws = xTx.I * (xMat.T * (weights * yMat))
return testPoint * ws
def lwlrTest(testArr,xArr,yArr,k=1.0): #循环所有的数据点并将lwlr运用于所有的数据点
m = shape(testArr)[0]
yHat = zeros(m)
for i in range(m):
yHat[i] = lwlr(testArr[i],xArr,yArr,k)
return yHat
def lwlrTestPlot(xArr,yArr,k=1.0): #首先将 X 排序其余的都与lwlrTest相同这样更容易绘图
yHat = zeros(shape(yArr))
xCopy = mat(xArr)
xCopy.sort(0)
for i in range(shape(xArr)[0]):
yHat[i] = lwlr(xCopy[i],xArr,yArr,k)
return yHat,xCopy
def rssError(yArr,yHatArr): #yArr 和 yHatArr 两者都需要是数组
return ((yArr-yHatArr)**2).sum()
def ridgeRegres(xMat,yMat,lam=0.2): #岭回归
xTx = xMat.T*xMat
denom = xTx + eye(shape(xMat)[1])*lam
if linalg.det(denom) == 0.0:
print "This matrix is singular, cannot do inverse"
return
ws = denom.I * (xMat.T*yMat)
return ws
def ridgeTest(xArr,yArr):
xMat = mat(xArr); yMat=mat(yArr).T
yMean = mean(yMat,0)
yMat = yMat - yMean #Y取平均值以消除X0
#regularize X's正则化 X的
xMeans = mean(xMat,0) #计算平均值然后减去它
xVar = var(xMat,0) #然后计算除以 Xi的方差
xMat = (xMat - xMeans)/xVar
numTestPts = 30
wMat = zeros((numTestPts,shape(xMat)[1]))
for i in range(numTestPts):
ws = ridgeRegres(xMat,yMat,exp(i-10))
wMat[i,:]=ws.T
return wMat
def regularize(xMat):#按列进行规范化
inMat = xMat.copy()
inMeans = mean(inMat,0) #计算平均值然后减去它
inVar = var(inMat,0) #计算除以Xi的方差
inMat = (inMat - inMeans)/inVar
return inMat
def stageWise(xArr,yArr,eps=0.01,numIt=100):
xMat = mat(xArr); yMat=mat(yArr).T
yMean = mean(yMat,0)
yMat = yMat - yMean #也可以规则化ys但会得到更小的coef
xMat = regularize(xMat)
m,n=shape(xMat)
#returnMat = zeros((numIt,n)) #测试代码删除
ws = zeros((n,1)); wsTest = ws.copy(); wsMax = ws.copy()
for i in range(numIt):
print ws.T
lowestError = inf;
for j in range(n):
for sign in [-1,1]:
wsTest = ws.copy()
wsTest[j] += eps*sign
yTest = xMat*wsTest
rssE = rssError(yMat.A,yTest.A)
if rssE < lowestError:
lowestError = rssE
wsMax = wsTest
ws = wsMax.copy()
#returnMat[i,:]=ws.T
#return returnMat
#def scrapePage(inFile,outFile,yr,numPce,origPrc):
# from BeautifulSoup import BeautifulSoup
# fr = open(inFile); fw=open(outFile,'a') #a is append mode writing
# soup = BeautifulSoup(fr.read())
# i=1
# currentRow = soup.findAll('table', r="%d" % i)
# while(len(currentRow)!=0):
# title = currentRow[0].findAll('a')[1].text
# lwrTitle = title.lower()
# if (lwrTitle.find('new') > -1) or (lwrTitle.find('nisb') > -1):
# newFlag = 1.0
# else:
# newFlag = 0.0
# soldUnicde = currentRow[0].findAll('td')[3].findAll('span')
# if len(soldUnicde)==0:
# print "item #%d did not sell" % i
# else:
# soldPrice = currentRow[0].findAll('td')[4]
# priceStr = soldPrice.text
# priceStr = priceStr.replace('$','') #strips out $
# priceStr = priceStr.replace(',','') #strips out ,
# if len(soldPrice)>1:
# priceStr = priceStr.replace('Free shipping', '') #strips out Free Shipping
# print "%s\t%d\t%s" % (priceStr,newFlag,title)
# fw.write("%d\t%d\t%d\t%f\t%s\n" % (yr,numPce,newFlag,origPrc,priceStr))
# i += 1
# currentRow = soup.findAll('table', r="%d" % i)
# fw.close()
from time import sleep
import json
import urllib2
def searchForSet(retX, retY, setNum, yr, numPce, origPrc):
sleep(10)
myAPIstr = 'AIzaSyD2cR2KFyx12hXu6PFU-wrWot3NXvko8vY'
searchURL = 'https://www.googleapis.com/shopping/search/v1/public/products?key=%s&country=US&q=lego+%d&alt=json' % (myAPIstr, setNum)
pg = urllib2.urlopen(searchURL)
retDict = json.loads(pg.read())
for i in range(len(retDict['items'])):
try:
currItem = retDict['items'][i]
if currItem['product']['condition'] == 'new':
newFlag = 1
else: newFlag = 0
listOfInv = currItem['product']['inventories']
for item in listOfInv:
sellingPrice = item['price']
if sellingPrice > origPrc * 0.5:
print "%d\t%d\t%d\t%f\t%f" % (yr,numPce,newFlag,origPrc, sellingPrice)
retX.append([yr, numPce, newFlag, origPrc])
retY.append(sellingPrice)
except: print 'problem with item %d' % i
def setDataCollect(retX, retY):
searchForSet(retX, retY, 8288, 2006, 800, 49.99)
searchForSet(retX, retY, 10030, 2002, 3096, 269.99)
searchForSet(retX, retY, 10179, 2007, 5195, 499.99)
searchForSet(retX, retY, 10181, 2007, 3428, 199.99)
searchForSet(retX, retY, 10189, 2008, 5922, 299.99)
searchForSet(retX, retY, 10196, 2009, 3263, 249.99)
def crossValidation(xArr,yArr,numVal=10):
m = len(yArr)
indexList = range(m)
errorMat = zeros((numVal,30))#create error mat 30columns numVal rows创建error mat 30columns numVal 行
for i in range(numVal):
trainX=[]; trainY=[]
testX = []; testY = []
random.shuffle(indexList)
for j in range(m):#create training set based on first 90% of values in indexList
#基于indexList中的前90%的值创建训练集
if j < m*0.9:
trainX.append(xArr[indexList[j]])
trainY.append(yArr[indexList[j]])
else:
testX.append(xArr[indexList[j]])
testY.append(yArr[indexList[j]])
wMat = ridgeTest(trainX,trainY) #get 30 weight vectors from ridge
for k in range(30):#loop over all of the ridge estimates
matTestX = mat(testX); matTrainX=mat(trainX)
meanTrain = mean(matTrainX,0)
varTrain = var(matTrainX,0)
matTestX = (matTestX-meanTrain)/varTrain #regularize test with training params
yEst = matTestX * mat(wMat[k,:]).T + mean(trainY)#test ridge results and store
errorMat[i,k]=rssError(yEst.T.A,array(testY))
#print errorMat[i,k]
meanErrors = mean(errorMat,0)#calc avg performance of the different ridge weight vectors
minMean = float(min(meanErrors))
bestWeights = wMat[nonzero(meanErrors==minMean)]
#can unregularize to get model
#when we regularized we wrote Xreg = (x-meanX)/var(x)
#we can now write in terms of x not Xreg: x*w/var(x) - meanX/var(x) +meanY
xMat = mat(xArr); yMat=mat(yArr).T
meanX = mean(xMat,0); varX = var(xMat,0)
unReg = bestWeights/varX
print "the best model from Ridge Regression is:\n",unReg
print "with constant term: ",-1*sum(multiply(meanX,unReg)) + mean(yMat)
#test for xianxinghuigui
def regression1():
xArr, yArr = loadDataSet("ex0.txt")
xMat = mat(xArr)
yMat = mat(yArr)
ws = standRegres(xArr, yArr)
fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(xMat[:, 1].flatten(), yMat.T[:, 0].flatten().A[0])
xCopy = xMat.copy()
xCopy.sort(0)
yHat = xCopy * ws
ax.plot(xCopy[:, 1], yHat)
plt.show()
if __name__ == "__main__":
regression1()
#test for jiaquanhuigui
def regression1():
xArr, yArr = loadDataSet("ex0.txt")
yHat = lwlrTest(xArr, xArr, yArr, 0.003)
xMat = mat(xArr)
srtInd = xMat[:,1].argsort(0)
xSort=xMat[srtInd][:,0,:]
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(xSort[:,1], yHat[srtInd])
ax.scatter(xMat[:,1].flatten().A[0], mat(yArr).T.flatten().A[0] , s=2, c='red')
plt.show()
if __name__ == "__main__":
regression1()

View File

@@ -0,0 +1,50 @@
#!/usr/bin/python
# coding:utf8
from numpy import *
# 从文本中构建矩阵,加载文本文件,然后处理
def loadDataSet(fileName): # 通用函数,用来解析以 tab 键分隔的 floats浮点数
dataMat = [] # assume last column is target value
fr = open(fileName)
for line in fr.readlines():
curLine = line.strip().split('\t')
fltLine = map(float,curLine) # 映射所有的元素为 float浮点数类型
dataMat.append(fltLine)
return dataMat
# 计算两个向量的欧式距离(可根据场景选择)
def distEclud(vecA, vecB):
return sqrt(sum(power(vecA - vecB, 2))) # la.norm(vecA-vecB)
# 为给定数据集构建一个包含 k 个随机质心的集合。随机质心必须要在整个数据集的边界之内,这可以通过找到数据集每一维的最小和最大值来完成。然后生成 0~1.0 之间的随机数并通过取值范围和最小值,以便确保随机点在数据的边界之内。
def randCent(dataSet, k):
n = shape(dataSet)[1] # 列数
centroids = mat(zeros((k,n))) # 创建质心矩阵
for j in range(n): # 穿件随机簇质心,并且在每一维的边界内
minJ = min(dataSet[:,j])
rangeJ = float(max(dataSet[:,j]) - minJ)
centroids[:,j] = mat(minJ + rangeJ * random.rand(k,1)) # 随机生成
return centroids
# k-means 聚类算法
def kMeans(dataSet, k, distMeas=distEclud, createCent=randCent):
m = shape(dataSet)[0]
clusterAssment = mat(zeros((m,2))) # 创建矩阵来分配数据点到质心中
centroids = createCent(dataSet, k)
clusterChanged = True
while clusterChanged:
clusterChanged = False
for i in range(m): # 循环每一个数据点并分配到最近的质心中去
minDist = inf; minIndex = -1
for j in range(k):
distJI = distMeas(centroids[j,:],dataSet[i,:])
if distJI < minDist:
minDist = distJI; minIndex = j
if clusterAssment[i,0] != minIndex: clusterChanged = True
clusterAssment[i,:] = minIndex,minDist**2
print centroids
for cent in range(k): # 重新计算质心
ptsInClust = dataSet[nonzero(clusterAssment[:,0].A==cent)[0]] # 获取该簇中的所有点
centroids[cent,:] = mean(ptsInClust, axis=0) # 分配质心
return centroids, clusterAssment