|
以前沒寫過這么長的日志,人人網(wǎng)親情提示,不能超過12000個(gè)字符。好吧,那就另起一篇。
接著之前No.1,我們繼續(xù)。
之前的易懂的線性模型基本走了一遭,我們再看看,如果數(shù)據(jù)的特征因素是復(fù)合的,平方的,立方的(也就是多項(xiàng)式回歸會怎么樣?)。我覺得這種東西沒有定論,誰也不能確定特征組合會不會有道理,再說的直白點(diǎn),到底特征是不是幫助我們機(jī)器學(xué)習(xí)的有效利器,也沒有定論,但是至少目前看還是有效的。
1.1.15. Polynomial regression: extending linear models with basis functions
我們之前都是關(guān)注,怎么找到特征的線性組合,但是事實(shí)上,不可能都是線性組合,房價(jià)也許從某個(gè)特征(比如有一個(gè)特征是房子的平均面積,這個(gè)和價(jià)格有可能是線性關(guān)系;但是如果是這個(gè)地區(qū)的房子的數(shù)量,這個(gè)很難講,有可能就不是線性的,有可能是平方的,也有可能是其他復(fù)雜的關(guān)系,比如邏輯斯蒂關(guān)系,因?yàn)榄h(huán)境飽和有可能造成房價(jià)持平甚至下跌)。我們這里考慮這種多項(xiàng)式組合的特征關(guān)系。
這是原來的特征線性組合

這個(gè)就是特征的二項(xiàng)式組合,

我們來看看代碼上,怎么來處理,還是用房價(jià)的數(shù)據(jù)。
'''
Author: Miao Fan
Affiliation: Department of Computer Science and Technology, Tsinghua University, P.R.China.
Email: fanmiao.cslt.thu@gmail.com
'''
import sklearn.datasets
import sklearn.linear_model
import numpy.random
import numpy.linalg
import matplotlib.pyplot
import sklearn.preprocessing
if __name__ == "__main__":
# Load boston dataset
boston = sklearn.datasets.load_boston()
# Data tranform
polynominalData = sklearn.preprocessing.PolynomialFeatures(degree=2).fit_transform(boston.data)
# Split the dataset with sampleRatio
sampleRatio = 0.5
n_samples = len(boston.target)
sampleBoundary = int(n_samples * sampleRatio)
# Shuffle the whole data
shuffleIdx = range(n_samples)
numpy.random.shuffle(shuffleIdx)
# Make the training data
train_features = polynominalData[shuffleIdx[:sampleBoundary]]
train_targets = boston.target[shuffleIdx [:sampleBoundary]]
# Make the testing data
test_features = polynominalData[shuffleIdx[sampleBoundary:]]
test_targets = boston.target[shuffleIdx[sampleBoundary:]]
# Train
linearRegression = sklearn.linear_model.LinearRegression()
linearRegression.fit(train_features, train_targets)
# Predict
predict_targets = linearRegression.predict(test_features)
# Evaluation
n_test_samples = len(test_targets)
X = range(n_test_samples)
error = numpy.linalg.norm(predict_targets - test_targets, ord = 1) / n_test_samples
print "Polynomial Regression (Degree = 2) (Boston) Error: %.2f" %(error)
# Draw
matplotlib.pyplot.plot(X, predict_targets, 'r--', label = 'Predict Price')
matplotlib.pyplot.plot(X, test_targets, 'g:', label='True Price')
legend = matplotlib.pyplot.legend()
matplotlib.pyplot.title("Polynomial Regression (Degree = 2) (Boston)")
matplotlib.pyplot.ylabel("Price (1000 U.S.D)")
matplotlib.pyplot.savefig("Polynomial Regression (Degree = 2) (Boston).png", format='png')
matplotlib.pyplot.show()
這份代碼里,我使用的是二項(xiàng)式特征轉(zhuǎn)換,最高階次是2。然后使用普通的線性擬合,
輸出:
Polynomial Regression (Degree = 2) (Boston) Error: 3.26
誤差在3260美金上下,我記得之前的普通的線性回歸是3350。略好一點(diǎn)點(diǎn)。

有些喜歡質(zhì)疑的同學(xué)也許會問,我這代碼會不會有問題?沒關(guān)系,我們繼續(xù)延伸一個(gè)小話題,如果我們只修改一個(gè)地方:
# Data tranform
polynominalData = sklearn.preprocessing.PolynomialFeatures(degree=4).fit_transform(boston.data),改成4階的,會怎么樣呢?后果不堪設(shè)想。。。
輸出:
Polynomial Regression (Degree = 4) (Boston) Error: 30.19
誤差達(dá)到3W美金,這模型完全不能用了。
大家可以看到,預(yù)測價(jià)格(紅色虛線)的震動(dòng)非常強(qiáng)烈,而真實(shí)價(jià)格基本在30左右徘徊(綠色的虛線)。這說明你的模型在對測試數(shù)據(jù)的泛化能力上非常差。但是有人一定會問:“我設(shè)計(jì)的4階模型應(yīng)該比2階的考慮的特征組合要多得多啊,怎么會測試的時(shí)候這么差?” 是啊,考慮全面了,還這么差,我只能說“您想多了”。事實(shí)上,沒有那么多數(shù)據(jù)夠你合理地調(diào)整參數(shù),因?yàn)槟愕哪P瓦^于復(fù)雜。這種情況叫做過擬合(overfitting)。上面的圖片顯示的就是典型的過擬合。那么如果你的模型本身就是二次的,你用線性回歸,那么效果也會略差,這種情況叫做欠擬合(underfitting)
在大數(shù)據(jù)時(shí)代,深度學(xué)習(xí)的模型參數(shù)非常多,但是數(shù)據(jù)也多,這樣復(fù)雜模型本身的強(qiáng)大的表達(dá)能力得以展現(xiàn),這是我覺得為什么在圖像,語音這些領(lǐng)域 ,深度學(xué)習(xí)這么有效的簡單原因。
---------------------------------------------------------------------------------------------------------------------------------
1.2. Support Vector Machines
支持向量機(jī)的歷史命運(yùn)特別像諾基亞,曾經(jīng)輝煌很長一段時(shí)間,盡管現(xiàn)在已經(jīng)成為歷史,但是終究不能磨滅期偉大貢獻(xiàn)。應(yīng)該是上個(gè)世紀(jì)90年代,幾乎在學(xué)術(shù)界充斥了大量的關(guān)于SVM的話題論文。要是那個(gè)時(shí)候誰不知道SVM,就跟現(xiàn)在不知道深度學(xué)習(xí)似的,不知道要遭到多少鄙視:)。其實(shí)我也不懂深度學(xué)習(xí)。。。被鄙視習(xí)慣了,也就見慣不慣了。
我們的這個(gè)sklearn系列的討論帖不在于介紹數(shù)學(xué)細(xì)節(jié),更關(guān)注怎么用,什么情況下使用什么模型更適合。因此我同意下面的四條關(guān)于SVM的優(yōu)勢的總結(jié),這些總結(jié)從側(cè)面告訴你什么時(shí)候用SVM:
a. 高維度特征數(shù)據(jù)有效
b. 訓(xùn)練樣本數(shù)量小于特征維數(shù)的數(shù)據(jù)有效(這個(gè)特別霸氣)
c. 節(jié)約模型的存儲內(nèi)存(就那么幾個(gè)支持向量有用)
d. 還可以根據(jù)需要對特征進(jìn)行高維變化(核函數(shù)的方法)
1.2.1. Classification
SVM用來做Classification,縮寫就是SVC(Support Vector Classification)(SVM不僅僅能做分類,這個(gè)一定要說明)的基本思想非常直觀,也是要找一個(gè)超平面(2類分類),但是要找最好的那個(gè)。下圖來自博文:http://blog.csdn.net/marvin521/article/details/9286099。我們可以看到,類似B,C的分隔線可以有無數(shù)個(gè),都能分離藍(lán)色和紅色的兩個(gè)類別,但是貌似D的分類方式更讓人接受,好像如果有一個(gè)新的數(shù)據(jù),大體上像D這樣劃分更容易對,是吧。這里D的方式就是找到了已知數(shù)據(jù)分布的最大間隔,有充足的泛化空間讓給那些沒有看到的數(shù)據(jù),這樣模型的泛化能力達(dá)到了最大(機(jī)器學(xué)習(xí)的關(guān)鍵問題不在于模型在訓(xùn)練樣本上的契合程度,在于泛化能力如何,雖然這是很難評估的),這是為什么SVM在90年代的時(shí)候風(fēng)靡一時(shí)的原因,它也的確好使。
再來看,其實(shí)像D這樣的分隔線的確定貌似不太依賴那些遠(yuǎn)離分隔線的數(shù)據(jù)點(diǎn),只有那些距離分割線(如果是更多維度的特征,那就是分隔超平面)最近的一些點(diǎn)能夠支持分割線確定位置,因此叫支持向量機(jī)。而那些用來確定分割線的有效數(shù)據(jù)點(diǎn)(特征向量),叫做支持向量。

來,我們用代碼找找感覺:
這里需要說明一下:如果我們繼續(xù)使用Iris的數(shù)據(jù),這是一個(gè)多類別(3個(gè)類別)的分類問題,我覺得大家需要大致了解一下SVC這套工具是怎么處理多類分類的問題的(畢竟,我們給出的例子是2類分類的)。
大體上有兩種,將兩類分類器擴(kuò)展到多類分類問題,我這里強(qiáng)調(diào),不是只有兩種,而是,將兩類分類問題進(jìn)行擴(kuò)展,達(dá)到多(假設(shè)有n個(gè)類別) 分類的目的,這個(gè)思路有兩種:一種是訓(xùn)練n*(n-1)/ 2個(gè)二類分類器,兩兩類別之間訓(xùn)練一個(gè)分類器,用于專門處理;另外一種就是把其中一個(gè)類別拿出來作為正類別,其他的所有類別統(tǒng)一歸為負(fù)類,這樣會訓(xùn)練n個(gè)訓(xùn)練樣本。
用Iris的數(shù)據(jù)我們都來試試。
'''
Author: Miao Fan
Affiliation: Department of Computer Science and Technology, Tsinghua University, P.R.China.
Email: fanmiao.cslt.thu@gmail.com
'''
import sklearn.datasets
import sklearn.svm
import numpy.random
import matplotlib.pyplot
import matplotlib.colors
if __name__ == "__main__":
# Load iris dataset
iris = sklearn.datasets.load_iris()
# Split the dataset with sampleRatio
sampleRatio = 0.5
n_samples = len(iris.target)
sampleBoundary = int(n_samples * sampleRatio)
# Shuffle the whole data
shuffleIdx = range(n_samples)
numpy.random.shuffle(shuffleIdx)
# Make the training data
train_features = iris.data[shuffleIdx[:sampleBoundary]]
train_targets = iris.target[shuffleIdx [:sampleBoundary]]
# Make the testing data
test_features = iris.data[shuffleIdx[sampleBoundary:]]
test_targets = iris.target[shuffleIdx[sampleBoundary:]]
# Train
svc = sklearn.svm.SVC()
nusvc = sklearn.svm.NuSVC()
linearsvc = sklearn.svm.LinearSVC()
svc.fit(train_features, train_targets)
nusvc.fit(train_features, train_targets)
linearsvc.fit(train_features, train_targets)
predict_targets = svc.predict(test_features)
#SVC Evaluation
n_test_samples = len(test_targets)
X = range(n_test_samples)
correctNum = 0
for i in X:
if predict_targets[i] == test_targets[i]:
correctNum += 1
accuracy = correctNum * 1.0 / n_test_samples
print "SVC Accuracy: %.2f" %(accuracy)
predict_targets = nusvc.predict(test_features)
#NuSVC Evaluation
n_test_samples = len(test_targets)
X = range(n_test_samples)
correctNum = 0
for i in X:
if predict_targets[i] == test_targets[i]:
correctNum += 1
accuracy = correctNum * 1.0 / n_test_samples
print "NuSVC Accuracy: %.2f" %(accuracy)
predict_targets = linearsvc.predict(test_features)
#LinearSVC Evaluation
n_test_samples = len(test_targets)
X = range(n_test_samples)
correctNum = 0
for i in X:
if predict_targets[i] == test_targets[i]:
correctNum += 1
accuracy = correctNum * 1.0 / n_test_samples
print "LinearSVC Accuracy: %.2f" %(accuracy)
1.3. Stochastic Gradient Descent
1.4. Nearest Neighbors
1.4.2. Nearest Neighbors Classification
借著剛剛更新過的Logistic Regression 對 Iris做分類的余興,我們來看看使用近鄰法是怎么做分類(近鄰法不僅能做分類,還能回歸,我先介紹分類,這個(gè)比較好懂)的。這個(gè)算是基于實(shí)例的分類方法,和前面介紹的回歸啊,分類啊這些方法都不同,之前都是要訓(xùn)練出一個(gè)具體的數(shù)學(xué)函數(shù),對吧。這種近鄰法不需要預(yù)先訓(xùn)練出什么公式。近鄰法的思想很簡單,“物以類聚,人以群分”,特征相似的,類別最相近。KNN(K
Nearest Neighbor)的意思就是在某個(gè)待分類的樣本周圍找K個(gè)根據(jù)特征度量距離最近的K個(gè)已知類別的樣本,這K個(gè)樣本里面,如果某個(gè)類別個(gè)數(shù)最多,那么這個(gè)待分類的樣本就從屬于那個(gè)類別。意思就是,找特性最相近的朋黨,然后少數(shù)服從多數(shù)。
當(dāng)然,這個(gè)工具包也沒有那么簡單,除了KNN(KNeighborsClassifier)還有RNN(RadiusNeighborsClassifier),說白了,KNN不在乎那K個(gè)最近的點(diǎn)到底離你有多遠(yuǎn),反正總有相對最近的K個(gè)。但是RNN要考慮半徑Radius,在待測樣本以Radius為半徑畫個(gè)球(如果是二維特征就是圓,三維特征以上,你可以理解為一個(gè)超球面),這個(gè)球里面的都算進(jìn)來,這樣就不能保證每個(gè)待測樣本都能考慮相同數(shù)量的最近樣本。
同時(shí),我們也可以根據(jù)距離的遠(yuǎn)近來對這些已知類別的樣本的投票進(jìn)行加權(quán),這個(gè)想法當(dāng)然很自然。后面的代碼都會體現(xiàn)。
我們還是用Iris來測試一下,這次采樣比例弄得狠了點(diǎn),20%訓(xùn)練,80%用來預(yù)測測試,就是為了區(qū)別一下兩種距離加權(quán)方式[unifrom, distance]。
'''
Author: Miao Fan
Affiliation: Department of Computer Science and Technology, Tsinghua University, P.R.China.
Email: fanmiao.cslt.thu@gmail.com
'''
import sklearn.datasets
import sklearn.neighbors
import numpy.random
import matplotlib.pyplot
import matplotlib.colors
if __name__ == "__main__":
# Load iris dataset
iris = sklearn.datasets.load_iris()
# Split the dataset with sampleRatio
sampleRatio = 0.2
n_samples = len(iris.target)
sampleBoundary = int(n_samples * sampleRatio)
# Shuffle the whole data
shuffleIdx = range(n_samples)
numpy.random.shuffle(shuffleIdx)
# Make the training data
train_features = iris.data[shuffleIdx[:sampleBoundary]]
train_targets = iris.target[shuffleIdx [:sampleBoundary]]
# Make the testing data
test_features = iris.data[shuffleIdx[sampleBoundary:]]
test_targets = iris.target[shuffleIdx[sampleBoundary:]]
# Train
n_neighbors = 5 #選5個(gè)最近鄰
for weights in ['uniform', 'distance']: #這個(gè)地方采用兩種加權(quán)方式
kNeighborsClassifier = sklearn.neighbors.KNeighborsClassifier(n_neighbors, weights=weights)
kNeighborsClassifier.fit(train_features, train_targets)
# Test
predict_targets = kNeighborsClassifier.predict(test_features)
#Evaluation
n_test_samples = len(test_targets)
X = range(n_test_samples)
correctNum = 0
for i in X:
if predict_targets[i] == test_targets[i]:
correctNum += 1
accuracy = correctNum * 1.0 / n_test_samples
print "K Neighbors Classifier (Iris) Accuracy [weight = '%s']: %.2f" %(weights, accuracy)
# Draw
cmap_bold = matplotlib.colors.ListedColormap(['red', 'blue', 'green'])
X_test = test_features[:, 2:4]
X_train = train_features[:, 2:4]
matplotlib.pyplot.scatter(X_train[:, 0], X_train[:, 1], label = 'train samples', marker='o', c = train_targets, cmap=cmap_bold,)
matplotlib.pyplot.scatter(X_test[:,0], X_test[:, 1], label = 'test samples', marker='+', c = predict_targets, cmap=cmap_bold)
legend = matplotlib.pyplot.legend()
matplotlib.pyplot.title("K Neighbors Classifier (Iris) [weight = %s]" %(weights))
matplotlib.pyplot.savefig("K Neighbors Classifier (Iris) [weight = %s].png" %(weights), format='png')
matplotlib.pyplot.show()
輸出:
K Neighbors Classifier (Iris) Accuracy [weight = 'uniform']: 0.91
K Neighbors Classifier (Iris) Accuracy [weight = 'distance']: 0.93
加權(quán)方法略好一點(diǎn),大約提升2%的精度(注意這兩個(gè)圖,我只是采用了其中的兩個(gè)維度特征進(jìn)行的重建,事實(shí)上應(yīng)該有4個(gè)維度):
 
1.5. Gaussian Processes
1.6. Cross decomposition
1.7. Naive Bayes
1.8. Decision Trees
1.9. Ensemble methods
1.10. Multiclass and multilabel algorithms
1.11. Feature selection
1.12. Semi-Supervised
1.13. Linear and quadratic discriminant analysis
1.14. Isotonic regression
2. Unsupervised learning
然后讓我們開始無監(jiān)督學(xué)習(xí):(聚類啊,概率密度估計(jì)(離群點(diǎn)檢測)啊,數(shù)據(jù)降維?。┑鹊?。相對而言,這個(gè)部分的工具還是比起許多其他ML包要豐富地多!什么流形學(xué)習(xí)啊都有。
2.1. Gaussian mixture models
2.2. Manifold learning
2.3. Clustering
2.4. Biclustering
2.5. Decomposing signals in components (matrix factorization problems)
2.6. Covariance estimation
2.7. Novelty and Outlier Detection
2.8. Density Estimation
2.9. Neural network models (unsupervised)
3. Model selection and evaluation
模型選擇有的時(shí)候,特別是在使用ML創(chuàng)業(yè)的時(shí)候更需要把握。其實(shí)好多問題不同模型都差不多到80%精度,后面怎么提升才是重點(diǎn)。不止一個(gè)小伙伴想要用Deep Learning 這個(gè)話題作為噱頭準(zhǔn)備9月份的博士或者碩士開題,那玩意兒想做好,你還真得有耐心調(diào)參數(shù),回想起MSRA我那同一排的大嬸(神)們,都是NIPS?。。?!丫的,1%的提升都要尖叫了:),其實(shí)我想說,妹的,參數(shù)不一樣唄。。。這就是Black
Magic(黑魔法)。玩深度學(xué)習(xí)的多了,估計(jì)以后不是模型值錢,是參數(shù)值錢了。
另外就是特征選擇,這個(gè)玩意兒也有講究,如果真正用ML創(chuàng)業(yè),其實(shí)模型還是那些模型,特征和參數(shù)的選擇往往更能看出這個(gè)人的水平,別瞎試,千萬別。。。
3.1. Cross-validation: evaluating estimator performance
3.2. Grid Search: Searching for estimator parameters
3.3. Pipeline: chaining estimators
3.4. FeatureUnion: Combining feature extractors
3.5. Model evaluation: quantifying the quality of predictions
3.6. Model persistence
3.7. Validation curves: plotting scores to evaluate models
4. Dataset transformations
4.1. Feature extraction
4.2. Preprocessing data
4.3. Kernel Approximation
4.4. Random Projection
4.5. Pairwise metrics, Affinities and Kernels
5. Dataset loading utilities
5.1. General dataset API
5.2. Toy datasets
5.3. Sample images
5.4. Sample generators
5.5. Datasets in svmlight / libsvm format
5.6. The Olivetti faces dataset
5.7. The 20 newsgroups text dataset
5.8. Downloading datasets from the mldata.org repository
5.9. The Labeled Faces in the Wild face recognition dataset
5.10. Forest covertypes
6. Scaling Strategies
6.1. Scaling with instances using out-of-core learning
7.
Computational Performance
7.1. Prediction Latency
7.2. Prediction Throughput
7.3. Tips and Tricks
原文地址:http://blog.renren.com/blog/451761534/932140348?bfrom=010203055
|