1. 程式人生 > >sklearn之svm-葡糖酒質量預測(1)

sklearn之svm-葡糖酒質量預測(1)

1.基礎

支援向量機(SVMs)是一套用於分類、迴歸和異常值檢測的監督學習方法。

支援向量機的優點是:

在高維空間中有效。
在維度數量大於樣本數量的情況下仍然有效。
在決策函式中使用一個訓練點子集(稱為支援向量),因此它也是記憶體高效的。
通用的:可以為決策函式指定不同的核心函式。提供了通用的核心,但也可以指定定製的核心。
支援向量機的缺點包括:

如果特徵數遠大於樣本數,則在選擇核函式時避免過擬合,正則項至關重要。
如果特徵數遠大於樣本數,則在選擇核函式時避免過擬合,正則項至關重要。
SVMs不直接提供概率估計,這些估計是使用昂貴的五倍交叉驗證
scikit-learn中的支援向量機既支援密集(numpy)又支援密集(numpy)。ndarray和可轉換為它的numpy.asarray)和稀疏(任何scipy.稀疏)樣本向量作為輸入。然而,要使用支援向量機對稀疏資料進行預測,它必須與這些資料相匹配。為了獲得最佳效能,請使用C-ordered numpy。ndarray(稠密)或scipy.稀疏。csrmatrix(稀疏),dtype=float64。
SVC和NuSVC是相似的方法,但接受的引數集略有不同,有不同的數學公式(見數學公式部分)。另一方面,LinearSVC是線性核情況下支援向量分類的另一種實現。注意,LinearSVC不接受關鍵字kernel,因為這被認為是線性的。它也缺少一些SVC和NuSVC成員,比如support


作為其他分類器,SVC、NuSVC和LinearSVC以兩個陣列作為輸入:一個大小為[n_samples, n_features]的陣列X和一個類別標籤(字串或整數)的陣列y,大小為[n_samples]:

from sklearn import svm
X = [[0, 0], [1, 1]]
y = [0, 1]
clf = svm.SVC(gamma='scale')
clf.fit(X, y)  
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
  decision_function_shape='ovr', degree=3, gamma='scale', kernel='rbf',
  max_iter=-1, probability=False, random_state=None, shrinking=True,
  tol=0.001, verbose=False)

基礎
模型擬合後,可用於預測新的值:

>>> clf.predict([[2., 2.]])
array([1])

SVMs決策函式依賴於訓練資料的某個子集,稱為支援向量。這些支援向量的一些屬性可以在supportvectors、support_和n_support成員中找到:


 # get support vectors
clf.support_vectors_
​
array([[0., 0.],
       [1., 1.]])
# get indices of support vectors
clf.support_ 
array([0, 1], dtype=int32)
 # get number of support vectors for each class
clf.n_support_
array([1, 1], dtype=int32)

SVC和NuSVC實現了“one-against-one”方法(Knerr et al., 1990)用於多類分類。如果n_class是類的數量,則構造n_class * (n_class - 1) / 2分類器,每個分類器訓練來自兩個類的資料。為了與其他分類器提供一致的介面,decision_function_shape選項允許將“一對一”分類器的結果聚合到shape的決策函式(n_samples, n_classes):

>>> X = [[0], [1], [2], [3]]
>>> Y = [0, 1, 2, 3]
>>> clf = svm.SVC(gamma='scale', decision_function_shape='ovo')
>>> clf.fit(X, Y) 
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
    decision_function_shape='ovo', degree=3, gamma='scale', kernel='rbf',
    max_iter=-1, probability=False, random_state=None, shrinking=True,
    tol=0.001, verbose=False)
>>> dec = clf.decision_function([[1]])
>>> dec.shape[1] # 4 classes: 4*3/2 = 6
6
>>> clf.decision_function_shape = "ovr"
>>> dec = clf.decision_function([[1]])
>>> dec.shape[1] # 4 classes
4

另一方面,LinearSVC實現“一vs其他”多類策略,從而訓練n_class模型。如果只有兩個類,只培訓一個模型:

>>> lin_clf = svm.LinearSVC()
>>> lin_clf.fit(X, Y) 
LinearSVC(C=1.0, class_weight=None, dual=True, fit_intercept=True,
     intercept_scaling=1, loss='squared_hinge', max_iter=1000,
     multi_class='ovr', penalty='l2', random_state=None, tol=0.0001,
     verbose=0)
>>> dec = lin_clf.decision_function([[1]])
>>> dec.shape[1]
4

注意,LinearSVC還使用multi_class='crammer_singer'選項實現了另一種多類策略,即Crammer和Singer制定的所謂多類支援向量機。這種方法是一致的,但對於one-vs-rest分類則不是這樣。在實踐中,通常首選1 -vs-rest分類,因為結果大部分是相似的,但是執行時要少得多。

對於“one-vs-rest”LinearSVC的屬性coef_和intercept_分別具有形狀[n_class、n_features]和[n_class]。係數的每一行都對應於n_class中的一個“one-vs-rest”分類器,對於擷取程式也類似,順序是“one”類。

在“one vs-one”SVC中,屬性的佈局要稍微複雜一些。在具有線性核心的情況下,屬性coef_和intercept_分別具有[n_class (n_class - 1) / 2、n_features]和[n_class (n_class - 1) / 2]。這與上面描述的LinearSVC的佈局類似,每一行對應一個二進位制分類器。0到n的順序是“0 vs 1”、“0 vs 2”、“0 vs n”、“1 vs 2”、“1 vs 3”、“1 vs n”……“n - 1與n”。

dual_coef_的形狀是[n_class-1, n_SV],佈局有點難以把握。列對應於任何n_class * (n_class - 1) / 2“one-vs-one”分類器中涉及的支援向量。在n_class - 1分類器中使用每個支援向量。每一行中的n_class - 1項對應於這些分類器的對偶係數。

from sklearn import svm
clf = svm.LinearSVC()
x = [[0.], [1.], [0.2], [1.]]
y = [0,1,0,1] #5*x-2>0
clf.fit(x,y)
clf.predict([[0.3], [2.]])

線性svm分類:(5x-2>0=>1 | 5x-2<0=>0)

array([0, 1])

非線性SVM分類

import numpy as np
from sklearn import svm
clf = svm.SVC(gamma='scale')
x=np.random.random(size=(50,1))
y=5*pow(x,2)+3>5
clf.fit(x,y.ravel())
x_test=np.random.random(size=(5,1))
y_test=5*pow(x_test,2)+3>5
y_pred=clf.predict(x_test)
print y_pred
print y_test
[False  True False  True False]
[[False]
 [ True]
 [False]
 [ True]
 [False]]

讀取csv

import pandas as pd
df_list=[]
for df in pd.read_csv(
    "winequality-white.csv",
    sep=';',
    encoding="utf-8",
    chunksize=200,
    usecols=["fixedacidity","volatileacidity","citricacid","residualsugar","chlorides","freesulfurdioxide","totalsulfurdioxide","density","pH","sulphates","alcohol","quality"]
):
    df_list.append(df)
print df_list
[     fixedacidity  volatileacidity  citricacid  residualsugar  chlorides  \
0             6.6            0.170        0.38           1.50      0.032   
1             6.3            0.480        0.04           1.10      0.046   
2             6.2            0.660        0.48           1.20      0.029   
3             7.4            0.340        0.42           1.10      0.033   
4             6.5            0.310        0.14           7.50      0.044   
5             6.2            0.660        0.48           1.20      0.029   
6             6.5            0.390        0.23           5.40      0.051   
7             7.0            0.330        0.32           1.20      0.053   
...
...
...
import pandas as pd
import StringIO
x="name,age,y\n'zhangsang',32,1\n'lisi',29,2\n'wangwu',30,1"
pd.read_csv(StringIO.StringIO(x))#StringIO — Read and write strings as files

在這裡插入圖片描述
當指定為dtype (GH10153)時,read_csv()函式現在支援解析類別(Categorical)列。根據資料的結構不同,與解析後轉換為category的方法相比,這會導致更快的解析時間和更低的記憶體使用量。請參閱這裡的io文件。

import pandas as pd
import StringIO
x="name,age,y\n'zhangsang',32,1\n'lisi',29,2\n'wangwu',30,1"
pd.read_csv(StringIO.StringIO(x))#StringIO — Read and write strings as files
pd.read_csv(StringIO.StringIO(x), dtype='category').dtypes
name    category
age     category
y       category
dtype: object
import pandas as pd
import StringIO
x="name,age,y\n'zhangsang',32,1\n'lisi',29,2\n'wangwu',30,1"
pd.read_csv(StringIO.StringIO(x))#StringIO — Read and write strings as files
pd.read_csv(StringIO.StringIO(x), dtype={'y': 'category'}).dtypes
name      object
age        int64
y       category
dtype: object
>>>df["y"].cat.categories
Index([u'1', u'2'], dtype='object')

>>>pd.to_numeric(df["y"].cat.categories)
Int64Index([1, 2], dtype='int64')

繼續讀取csv基礎

import pandas as pd
import StringIO
x="name,age,y\n'zhangsang',32,1\n'lisi',29,2\n'wangwu',30,1"
df=pd.read_csv(StringIO.StringIO(x), dtype={'y': 'category'})
df["name"],df["y"]
(0    'zhangsang'
 1         'lisi'
 2       'wangwu'
 Name: name, dtype: object, 0    1
 1    2
 2    1
 Name: y, dtype: category
 Categories (2, object): [1, 2])
pandas.read_csv(filepath_or_buffer, sep=’, ’, delimiter=None, header=’infer’, names=None, in- dex_col=None, usecols=None, squeeze=False, prefix=None, mangle_dupe_cols=True, dtype=None, engine=None, converters=None, true_values=None, false_values=None, skipinitialspace=False, skiprows=None, nrows=None, na_values=None, keep_default_na=True, na_filter=True, verbose=False, skip_blank_lines=True, parse_dates=False, infer_datetime_format=False, keep_date_col=False, date_parser=None, dayfirst=False, iterator=False, chunksize=None, compres- sion=’infer’, thousands=None, decimal=b’.’, lineterminator=None, quotechar=’"’, quoting=0, escapechar=None, comment=None, encoding=None, dialect=None, tupleize_cols=None, error_bad_lines=True, warn_bad_lines=True, skipfooter=0, dou- blequote=True, delim_whitespace=False, low_memory=True, memory_map=False,
float_precision=None)

Read CSV (comma-separated) file into DataFrame
還支援可選地迭代或分割檔案為塊。
panda I/O API是一組頂級讀取器函式,如pandas.read_csv(),通常返回一個panda物件。相應的writer函式是物件方法,可以像DataFrame.to_csv()那樣訪問。下面是一個包含可用readers 和 writers的表。
在這裡插入圖片描述
引數
filepath_or_buffer [str, pathlib.Path, py._path.local.LocalPath or any ]
具有read()方法的物件(如檔案控制代碼或StringIO)
字串可以是URL。有效的URL方案包括http、ftp、s3和檔案。對於檔案url,需要一臺主機。例如,一個本地檔案可以是 file://localhost/path/to/table. csv

sep : str, default ‘,’
分隔符使用。如果sep為空,C引擎無法自動檢測分離器,
但是Python解析引擎可以,這意味著後者將被自動使用。
通過Python的內建嗅探工具csv.Sniffer檢測分離器。此外,與'\s+'不同,大於1個字元的sep- arators將被解釋為正則表示式,並將強制使用Python解析引擎。注意,regex分隔符很容易忽略引用的資料。正則表示式的例子:“\ r \ t”
delimiter : str, default None
sep的替代引數名。
delim_whitespace : boolean, default False
指定是否使用空格(例如。' '或'\t')將用作sep.等效於設定sep='\s+'。如果將此選項設定為True,則不應該為分隔符引數傳遞任何內容。
0.18.1版的新特性:對Python解析器的支援。
header : int or list of ints, default ‘infer’
行號(行數)要用作列名和資料的頭。預設值是- havior,用於推斷列名:如果沒有傳遞列名,則行為與header=0相同,並且從檔案的第一行推斷列名,如果顯式傳遞列名,則行為與header=None相同。顯式傳遞header=0以替換現有名稱。頭可以是一個整數列表,它為列上的多個索引指定行位置,例如[0,1,3]。未指定的中間行將被跳過(例如,例如本例中跳過了2)。注意,如果skip_blank_lines=True,則該引數將忽略註釋的行和空行,因此header=0表示資料的第一行,而不是檔案的第一行。
names : array-like, default None
要使用的列名列表。如果檔案不包含頭行,那麼應該顯式地執行
通過header = None。此列表中的重複項將導致發出使用者警告。
index_col : int or sequence or False, default None
要用作DataFrame的行標籤的列。如果給定一個序列,則使用一個多索引。如果在每行末尾有一個帶分隔符的格式不正確的檔案,那麼可以考慮使用index_col=False強制panda _not_使用第一列作為索引(行名)
usecols : list-like or callable, default None
返回列的子集。如果類似於列表,則所有元素必須是位置的(即文件列中的整數索引),或者是與使用者提供的列名相對應的字串,或者是從文件頭行推斷出來的。例如,一個有效的類列表的usecols引數將是[0,1,2]或[' foo ', ' bar ', ' baz ']。元素順序被忽略,所以usecols=[0,1]與[1,0]相同。
用保留的順序從data例項化DataFrame元素
pd.read_csv(data, usecols=['foo', 'bar'])[['foo', 'bar']]
按照['foo', 'bar']的列順序,或pd.read_csv(data, usecols=['foo', 'bar'])[['bar', 'foo']]for['bar', 'foo']的順序
如果可呼叫,可呼叫函式將根據列名求值,返回可呼叫函式求值為True時的名稱。一個有效的可呼叫引數的例子是['AAA', 'BBB', 'DDD']中的lambda x: x.upper()。使用這個引數會導致更快的解析時間和更低的記憶體使用。
squeeze : boolean, default False
如果解析後的資料只包含一列,則返回一個系列
prefix : str, default None
在沒有標題的情況下向列數新增字首,例如“X”表示X0、X1、…
mangle_dupe_cols : boolean, default True
重複列將被指定為‘X’, ‘X.1’, . . . ’X.N’,而不是‘X’. . . ’X’。如果列中有重複的名稱,則False中的傳遞將導致資料覆蓋。
dtype : Type name or dict of column -> type, default None
資料或列的資料型別。{‘a’: np.float64, ‘b’: np.int32},使用str或物件以及適當的na_values設定來儲存和不解釋dtype。如果指定了轉換器,將應用dtype轉換的INSTEAD。
engine : {‘c’, ‘python’}, optional
要使用的解析器引擎。C引擎更快,而python引擎目前功能更完備。
converters : dict, default None
用於轉換某些列中的值的函式的字典。鍵可以是整數,也可以是列標籤