機(jī)器學(xué)習(xí)能夠幫助測試工作者做什么呢怜跑?答案一定有很多。隨著對機(jī)器學(xué)習(xí)的越來越熟悉锥腻,就一定能夠能將它應(yīng)用到更多測試領(lǐng)域嗦董。對于目前的我們團(tuán)隊(duì)來說,就有能夠根據(jù)一些特征值來預(yù)測迭代的BUG數(shù)量的需求瘦黑,甚至反過來可以幫助我們進(jìn)行迭代中特征值的最優(yōu)化京革,來達(dá)到更合理的故事分配、人員配比等幸斥。
首先我們的目標(biāo)是在需求達(dá)到共識的情況下匹摇,根據(jù)迭代需求故事數(shù)量、技術(shù)挑戰(zhàn)數(shù)量甲葬、迭代天數(shù)廊勃、人力數(shù)量等特征值預(yù)測某次迭代的BUG數(shù)量。當(dāng)然经窖,真正決定BUG數(shù)量的特征值絕不止這些坡垫,我們暫時采用MVP(最小化可行產(chǎn)品)的方式開始,可以讓我們先看到效果而不至于陷入太多的前置思考画侣,浪費(fèi)時間葛虐。
接下來就是模型選取,由于有很多特征值棉钧,我們暫時采用多元線性回歸模型來作為我們的假設(shè)模型:
最小化損失函數(shù)時屿脐,可以通過梯度下降法來一步步的迭代求解涕蚤。具體的內(nèi)容可以參考https://www.cnblogs.com/pinard/p/5970503.html,說實(shí)話的诵,這篇文章幫助了我普及了很多相關(guān)的數(shù)學(xué)知識万栅,真是全還給老師了。西疤。烦粒。
然后就是準(zhǔn)備數(shù)據(jù)了,我們目前已有的數(shù)據(jù)不多代赁,不過對于實(shí)驗(yàn)來說無所謂:
把數(shù)據(jù)搞到txt里面去(Iterationdata.txt)扰她,展示形式是:
數(shù)據(jù)準(zhǔn)備完,并定義好迭代次數(shù)(iterations)芭碍、學(xué)習(xí)率(alpha)徒役、模型參數(shù)初始值(theta),就可以運(yùn)行下面的代碼了:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu May 17 10:17:08 2018
@author: xingshulin
"""
#-*- coding: UTF-8 -*-
import numpy as np
#加載數(shù)據(jù)
def load_exdata(filename):
data = []
with open(filename, 'r') as f:
for line in f.readlines():
line = line.split(',')
current = [float(item) for item in line]
data.append(current)
return data
# 特征縮放
def featureNormalize(X):
X_norm = X;
mu = np.zeros((1, X.shape[1]))
sigma = np.zeros((1, X.shape[1]))
for i in range(X.shape[1]):
mu[0, i] = np.mean(X[:, i]) # 均值
sigma[0, i] = np.std(X[:, i]) # 標(biāo)準(zhǔn)差
X_norm = (X - mu) / sigma
return X_norm, mu, sigma
# 計算損失
def computeCost(X, y, theta):
m = y.shape[0]
# J = (np.sum((X.dot(theta) - y)**2)) / (2*m)
C = X.dot(theta) - y
J2 = (C.T.dot(C)) / (2 * m)
return J2
# 梯度下降
def gradientDescent(X, y, theta, alpha, num_iters):
m = y.shape[0]
# 存儲歷史誤差
J_history = np.zeros((num_iters, 1))
for iter in range(num_iters):
theta = theta - (alpha / m) * (X.T.dot(X.dot(theta) - y))
J_history[iter] = computeCost(X, y, theta)
return J_history, theta
# 預(yù)測y值
def predict(data):
testx = np.array(data)
testx = ((testx - mu) / sigma)
testx = np.hstack([testx, np.ones((testx.shape[0], 1))])
bugNum = testx.dot(theta)
print('predit value is %f ' % (bugNum))
# 加載數(shù)據(jù)
data = load_exdata('/Users/xingshulin/Downloads/Iterationdata.txt');
data = np.array(data,np.float64) #數(shù)據(jù)是浮點(diǎn)型
print('data value is: ')
print(data)
# 迭代次數(shù)
iterations = 100
# 學(xué)習(xí)率
alpha = 0.1
#數(shù)據(jù)特征輸入窖壕,采用數(shù)據(jù)集一行的忧勿,第1,2瞻讽,3,4個數(shù)據(jù)鸳吸,然后將其變成一行,所以用shape
x = data[:, ( 1,2,3,4)].reshape((-1, 4))
print('x value is: ')
print(x)
y = data[:, 5].reshape((-1, 1)) #輸出特征速勇,數(shù)據(jù)集的第5位
print('y value is: ')
print(y)
m = y.shape[0]
x, mu, sigma = featureNormalize(x)
X = np.hstack([x, np.ones((x.shape[0], 1))])
# 總共有4個特征值輸入晌砾,所以theta是5維(多一個θ0),θ0+θ1x1+...+θnxn烦磁;詳見https://www.cnblogs.com/pinard/p/5970503.html中的梯度下降法的矩陣方式描述
theta = np.zeros((5, 1))
#theta = np.array([[10],[10],[10],[10],[10]])
print('theta init value is: ')
print(theta)
J_history, theta = gradientDescent(X, y, theta, alpha, iterations)
# 打印最后10個損失值
print('J_history:')
print(J_history[-10:-1])
print('Theta found by gradient descent: ')
print(theta)
# 開始預(yù)測
predict([10,2,7,8]) #輸入為4維
最終運(yùn)行的結(jié)果為:
runfile('/Users/xingshulin/多元線性回歸預(yù)測.py', wdir='/Users/xingshulin')
data value is:
[[ 1. 9. 6. 10. 8. 64.]
[ 2. 7. 0. 15. 8. 89.]
[ 3. 9. 1. 12. 9. 42.]
[ 4. 7. 1. 10. 9. 33.]
[ 5. 5. 2. 5. 15. 44.]
[ 6. 6. 0. 4. 8. 16.]
[ 7. 10. 0. 3. 10. 17.]]
x value is:
[[ 9. 6. 10. 8.]
[ 7. 0. 15. 8.]
[ 9. 1. 12. 9.]
[ 7. 1. 10. 9.]
[ 5. 2. 5. 15.]
[ 6. 0. 4. 8.]
[10. 0. 3. 10.]]
y value is:
[[64.]
[89.]
[42.]
[33.]
[44.]
[16.]
[17.]]
theta init value is:
[[0.]
[0.]
[0.]
[0.]
[0.]]
J_history:
[[67.53350557]
[67.53239752]
[67.53137251]
[67.53042429]
[67.52954709]
[67.52873557]
[67.52798481]
[67.52729025]
[67.52664767]]
Theta found by gradient descent:
[[-2.87136585]
[ 5.72753034]
[20.87608252]
[ 3.92605147]
[43.57027125]]
predit value is 31.249887
可以看到养匈,打印結(jié)果中的theta初始值都是0,如果初始值不同个初,最終學(xué)習(xí)的模型參數(shù)也有可能不同乖寒,原因就是梯度下降求得的只是局部最小值猴蹂;當(dāng)然如果損失函數(shù)是凸函數(shù)則一定是最優(yōu)解院溺。由于有局部最優(yōu)解的風(fēng)險,需要多次用不同初始值運(yùn)行算法磅轻,關(guān)鍵損失函數(shù)的最小值珍逸,選擇損失函數(shù)最小化的初值。
還有一點(diǎn)聋溜,通過打印的J_history最后10個數(shù)據(jù)我們可以看到在目前迭代數(shù)和學(xué)習(xí)率情況下?lián)p失函數(shù)值的變化谆膳,從結(jié)果看已經(jīng)變化不大了,所以可以理解為目前已經(jīng)接近局部最小值了撮躁。當(dāng)然漱病,我們可以去改變迭代數(shù)和學(xué)習(xí)率(如改成10000和0.01),但對于目前數(shù)據(jù)量來說,影響不大杨帽。
記錄下未來會對此次學(xué)習(xí)結(jié)果造成影響的因素:
- 特征數(shù)量漓穿,如增加新的特征:開發(fā)人員級別
- 特征值數(shù)量,即樣本數(shù)量注盈,隨著樣本數(shù)量增多晃危,結(jié)果應(yīng)該更準(zhǔn)確
- 模型參數(shù)初始值
- 選擇其他模型,如多元非線性模型
具體的回歸預(yù)測方法可見下面鏈接中的“多元線性回歸分析預(yù)測法案例分析”部分:
http://wiki.mbalib.com/wiki/%E5%A4%9A%E5%85%83%E7%BA%BF%E6%80%A7%E5%9B%9E%E5%BD%92%E5%88%86%E6%9E%90%E9%A2%84%E6%B5%8B%E6%B3%95
學(xué)習(xí)率:http://baijiahao.baidu.com/s?id=1591531217345055627&wfr=spider&for=pc