IT工房では機械学習の解説を行っています。
教師あり学習とは、説明変数から目的変数を予測するモデルを作成するために、正解の目的変数から学習する方法です。
そのため、必ず説明変数と同時に正解となるような目的変数を用意する必要があります。
ちなみに、教師なし学習は正解例となる目的変数がない学習のことです。
*パラメータの表はscikit-learnのドキュメントをGoogle翻訳しただけのものです。分かりにくい日本語のところは原文を読むなどしてください。
回帰問題
回帰問題は説明変数と目的変数で学習をして、ある説明変数から目的変数を予測するものです。
具体的には、部屋の間取りと築年数、駅までの距離などの説明変数から家賃という目的変数を予測するものです。
scikit-learnにある回帰問題用の、Bostonの家賃を予測するサンプルデータを使ってそれぞれの学習器の特徴と使い方のポイント(ハイパーパラメータ)をまとめています。
重回帰分析
機械学習というよりも統計学で使用され続けている手法です。
回帰問題ではまずこれを試すと良いでしょう。
ちなみに、説明変数がひとつの場合は単回帰分析、説明変数が複数の場合は重回帰分析です。
なお、scikit-learnで単回帰分析する際は注意しなければならない点があります。
「単回帰分析でSCIKIT-LEARNに説明変数を準備する際の注意点」を参考にしてください。
回帰分析では、説明変数と目的変数をグラフにすると線形(曲線ではなく直線)になることが大事です。
線形とは、つまり y = ax + b の式が成り立つということです。
回帰分析はScikit-learnに用意されている「sklearn.linear_model」を使うことで簡単に分析できます。
「sklearn.linear_model」を使うには事前にインポートしておく必要があります。
重回帰分析の場合は次のようにします。
「from sklearn.linear_model import LinearRegression」
次の例はBostonの物件の家賃を求める内容のものです。
回帰係数と切片を求めるには最小二乗法を用いています。
最小二乗法
参考:最小二乗法で傾きを求める方法を数学的に理解しよう
最小二乗法についてはGitHubを参照ください。
Bostonの物件の家賃
# ライブラリをロード from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.linear_model import LinearRegression from sklearn.datasets import load_boston from sklearn.metrics import mean_squared_error # データをロードし、特徴量を2つに制限 boston = load_boston() features = boston.data[:,0:2] target = boston.target # 特徴量を標準化 scaler = StandardScaler() X_standerd = scaler.fit_transform(features) X_train,X_test,y_train,y_test = train_test_split( X_standerd, target,random_state=0 ) # 線形回帰器を作成 regression = LinearRegression() # 線形回帰器を訓練 model = regression.fit(features, target) # 切片(intercept)を表示 print('切片',model.intercept_) # 特徴量の係数(coefficient)を表示 print('係数',model.coef_) # 決定係数 print('MSE train',mean_squared_error(y_train,model.predict(X_train))) print('MSE test',mean_squared_error(y_test,model.predict(X_test))) print('決定係数r2(train):{:.3f}'.format(model.score(X_train,y_train))) print('決定係数r2(test):{:.3f}'.format(model.score(X_test,y_test))) # 金額の単位は1000ドル単位 print('最初のターゲット金額',target[0]) # 最初の観測値のターゲット値を予測 print('予測値',model.predict(features)[0])
結果
切片 22.485628113468223
係数 [-0.35207832 0.11610909]
MSE train 82.07467637520038
MSE test 78.96548055826703
決定係数r2(train):0.038
決定係数r2(test):0.033
最初のターゲット金額 24.0
予測値 24.573366631705547
LinearRegressionパラメータ
scikit-learn LinearRegression ドキュメント
パラメータ | 内容 |
---|---|
fit_intercept | bool型で指定、オプション、デフォルトはTrue このモデルの切片を計算するかどうか。Falseに設定すると、計算でインターセプトは使用されません(つまり、データは中央に配置されることが期待されます)。 :boolの正規化、オプション、デフォルトはFalse fit_interceptがFalseに設定されている場合、このパラメーターは無視されます。Trueの場合、平均を減算してl2-normで除算することにより、回帰の前にリグレッサXが正規化されます。標準化する場合は、で見積もりをsklearn.preprocessing.StandardScaler呼び出す前に使用してください 。fitnormalize=False |
copy_X | bool型で指定、オプション、デフォルトはTrue Trueの場合、Xがコピーされます。それ以外の場合は上書きされます。 |
n_jobs | int型で指定またはNone、オプション(デフォルト= None) 計算に使用するジョブの数。これは、n_targets> 1および十分な大規模な問題に対してのみ高速化を提供します。 コンテキストにNoneない限り1を意味しjoblib.parallel_backendます。 -1すべてのプロセッサを使用することを意味します。詳細については、用語集 を参照してください。 |
Ridge
Ridge回帰とLasso回帰は回帰係数を推定する時に、損失関数に対して何らかのペナルティを加える仕組みのものです。
このような仕組みを正則化といいます。
正則化には、誤差を二乗する方法と絶対値をとる方法の2種類の方法があります。
ちなみに、絶対値で計算する方法をL1ノルムといい、二乗する方法のことをL2ノルムといいます。
Ridge回帰は正則化するときに二乗する方法です。
正則化の数学的な意味合いは別のサイトで詳細に書かれていますので、参考にすると良いでしょう。
正則化を行うことで、モデルの複雑さが抑えられる効果があります。
モデルの複雑さとは、つまり回帰問題の場合には回帰係数が大きくなる傾向のことをいいます。
回帰係数が大きくなると、それぞれの説明変数の値が大きく作用してしまう結果になります。
そして結果的に過学習になってしまう可能性が出てきます。
Bostonの物件の家賃
# ライブラリをロード from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.linear_model import Ridge from sklearn.datasets import load_boston from sklearn.metrics import mean_squared_error # データをロードし、特徴量を2つに制限 boston = load_boston() features = boston.data[:,0:2] target = boston.target # 特徴量を標準化 scaler = StandardScaler() X_standerd = scaler.fit_transform(features) X_train,X_test,y_train,y_test = train_test_split( X_standerd, target,random_state=0 ) # 線形回帰器を作成 regression = Ridge(alpha=10) # 線形回帰器を訓練 model = regression.fit(features, target) # 切片(intercept)を表示 print('切片',model.intercept_) # 特徴量の係数(coefficient)を表示 print('係数',model.coef_) # 決定係数 print('MSE train',mean_squared_error(y_train,model.predict(X_train))) print('MSE test',mean_squared_error(y_test,model.predict(X_test))) print('決定係数r2(train):{:.3f}'.format(model.score(X_train,y_train))) print('決定係数r2(test):{:.3f}'.format(model.score(X_test,y_test))) # 金額の単位は1000ドル単位 print('最初のターゲット金額',target[0]) # 最初の観測値のターゲット値を予測 print('予測値',model.predict(features)[0])
結果
切片 22.48524967920376
係数 [-0.35198256 0.11611194]
MSE train 82.07536292267763
MSE test 78.9659394680272
決定係数r2(train):0.038
決定係数r2(test):0.033
最初のターゲット金額 24.0
予測値 24.573040150990188
Ridgeのパラメータ
パラメータ | 内容 |
---|---|
alpha | float型で指定、デフォルト= 1.0 正則化強度; 正の浮動小数点数でなければなりません。正則化により、問題の条件付けが改善され、推定値の分散が減少します。値を大きくすると、より強い正則化が指定されます。アルファはC^-1、LogisticRegressionやLinearSVCなどの他の線形モデルに対応します。配列が渡される場合、ペナルティはターゲットに固有であると見なされます。したがって、それらは番号で対応している必要があります。 |
fit_intercept | bool値で指定、デフォルト= True このモデルの切片を計算するかどうか。falseに設定すると、インターセプトは計算に使用されません(つまり、データは中央に配置されます)。 |
:boolの正規化 | デフォルト=False fit_interceptがFalseに設定されている場合、このパラメーターは無視されます。Trueの場合、平均を減算してl2-normで除算することにより、回帰の前にリグレッサXが正規化されます。標準化する場合は、見積もりをsklearn.preprocessing.StandardScaler呼び出す前に使用してください 。fitnormalize=False |
copy_X | bool値で指定、デフォルト= True Trueの場合、Xがコピーされます。それ以外の場合は上書きされます。 |
max_iter | int型で指定 共役勾配ソルバーの最大反復回数。’sparse_cg’および ‘lsqr’ソルバーの場合、デフォルト値はscipy.sparse.linalgによって決定されます。’sag’ソルバーのデフォルト値は1000です。 |
tol | float型で指定、デフォルト= 1e-3 ソリューションの精度。 |
solver | {‘auto’、 ‘svd’、 ‘cholesky’、 ‘lsqr’、 ‘sparse_cg’、 ‘sag’、 ‘saga’} 計算ルーチンで使用するソルバー: ‘auto’は、データのタイプに基づいてソルバーを自動的に選択します。 ‘svd’は、Xの特異値分解を使用してリッジ係数を計算します。「cholesky」よりも特異行列に対してより安定しています。 ‘cholesky’は、標準のscipy.linalg.solve関数を使用して、閉形式の解を取得します。 ‘sparse_cg’は、scipy.sparse.linalg.cgにある共役勾配ソルバーを使用します。反復アルゴリズムとして、このソルバーは、大規模なデータ(設定tolおよび可能性max_iter)に’cholesky’よりも適切です。 ‘lsqr’は、専用の正規化された最小二乗ルーチンscipy.sparse.linalg.lsqrを使用します。これは最速であり、反復手順を使用します。 「sag」は確率的平均勾配降下を使用し、「saga」はSAGAという名前の改良された不偏バージョンを使用します。どちらの方法も反復手順を使用し、n_samplesとn_featuresの両方が大きい場合、多くの場合、他のソルバーよりも高速です。「sag」と「saga」の高速収束は、ほぼ同じスケールのフィーチャでのみ保証されることに注意してください。sklearn.preprocessingのスケーラーでデータを前処理できます。 最後の5つのソルバーはすべて、密データと疎データの両方をサポートしています。ただし、fit_interceptTrueの場合、「sparse_cg」のみがスパース入力をサポートします。 |
random_state | int型で指定、RandomStateインスタンスまたはNone、デフォルトNone データをシャッフルするときに使用する擬似乱数ジェネレーターのシード。intの場合、random_stateは乱数ジェネレーターが使用するシードです。RandomStateインスタンスの場合、random_stateは乱数ジェネレーターです。Noneの場合、乱数ジェネレーターはによって使用されるRandomStateインスタンスnp.randomです。solver== ‘sag’の場合に使用されます。 |
Lasso
Lassoは正則化にL1ノルムを使用してペナルティを付け加えています。
Lassoの特徴はハイパーパラメータのアルファー値を調整することで特定の説明変数の係数(重み)が0になる性質があり、次元削減の効果を生み出します。
Bostonの物件の家賃
# ライブラリをロード from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.linear_model import Lasso from sklearn.datasets import load_boston from sklearn.metrics import mean_squared_error # データをロードし、特徴量を2つに制限 boston = load_boston() features = boston.data[:,0:2] target = boston.target # 特徴量を標準化 scaler = StandardScaler() X_standerd = scaler.fit_transform(features) X_train,X_test,y_train,y_test = train_test_split( X_standerd, target,random_state=0 ) # 線形回帰器を作成 regression = Lasso(alpha=0.5) # 線形回帰器を訓練 model = regression.fit(features, target) # 切片(intercept)を表示 print('切片',model.intercept_) # 特徴量の係数(coefficient)を表示 print('係数',model.coef_) # 決定係数 print('MSE train',mean_squared_error(y_train,model.predict(X_train))) print('MSE test',mean_squared_error(y_test,model.predict(X_test))) print('決定係数r2(train):{:.3f}'.format(model.score(X_train,y_train))) print('決定係数r2(test):{:.3f}'.format(model.score(X_test,y_test))) # 金額の単位は1000ドル単位 print('最初のターゲット金額',target[0]) # 最初の観測値のターゲット値を予測 print('予測値',model.predict(features)[0])
結果
切片 22.466998019185223
係数 [-0.3455452 0.11567107]
MSE train 82.12474840506984
MSE test 79.00171605202223
決定係数r2(train):0.037
決定係数r2(test):0.033
最初のターゲット金額 24.0
予測値 24.546893490793508
Lassoのパラメータ
パラメータ | 内容 |
---|---|
alpha | float型で指定 L1項を乗算する定数。デフォルトは1.0です。 は、オブジェクトによって解決される通常の最小二乗に相当します。数値上の理由から、オブジェクトで使用することはお勧めしません。これを考えると、オブジェクトを使用する必要があります。alpha = 0LinearRegressionalpha = 0LassoLinearRegression |
fit_intercept | boolean型で指定, optional, default True このモデルの切片を計算するかどうか。Falseに設定すると、計算でインターセプトは使用されません(つまり、データは中央に配置されることが期待されます) |
normalize | boolean型で指定, default False fit_interceptがFalseに設定されている場合、このパラメーターは無視されます。Trueの場合、平均を減算してl2-normで除算することにより、回帰の前にregressorsXが正規化されます。標準化する場合 は、で見積もりをsklearn.preprocessing.StandardScaler呼び出す前に使用してください 。fitnormalize=False |
precomputeTrue | | False | array-like, default=False 計算を高速化するために事前計算されたGram行列を使用するかどうか。’auto’決定するように設定されている場合。Gram行列も引数として渡すことができます。スパース入力の場合、このオプションは常にTrueスパース性を保持します。 |
copy_X | boolean型で指定, default True Trueの場合、Xがコピーされます。それ以外の場合は上書きされます。 |
max_iter | int型で指定 反復の最大数 |
tol | float型で指定 最適化の許容範囲:更新がより小さい場合tol、最適化コードは二重ギャップの最適性をチェックし、それがより小さいまで継続しtolます。 |
warm_start | bool型で指定 Trueに設定すると、以前の呼び出しのソリューションを再利用して初期化に適合させます。それ以外の場合は、以前のソリューションを消去します。用語集を参照してください。 |
positive | bool型で指定 に設定するTrueと、係数が強制的に正になります。 |
random_state | int型で指定、RandomStateインスタンスまたはNone、オプション、デフォルトNone 更新するランダム機能を選択する擬似乱数ジェネレーターのシード。intの場合、random_stateは乱数ジェネレーターが使用するシードです。RandomStateインスタンスの場合、random_stateは乱数ジェネレーターです。Noneの場合、乱数ジェネレーターはによって使用されるRandomStateインスタンスnp.randomです。selection== ‘random’の場合に使用されます。 |
selection | str型で指定, default ‘cyclic’ 「ランダム」に設定すると、ランダム係数はデフォルトでフィーチャーを順番にループするのではなく、反復ごとに更新されます。これ(「ランダム」に設定)は、特にtolが1e-4よりも大きい場合に、収束を大幅に高速化することがよくあります。 |
決定木
決定木は分類問題で使われますが、DecisionTreeRegressorクラスを使用して、決定木を回帰問題に適用することもできます。
決定木の問題はツリーの最大深さ( max_depthパラメーター)の設定が高すぎる場合、決定木はノイズから学習してしまい、オーバーフィットする傾向があります。
決定木は回帰直線の傾きを求めているのではないため、傾きや切片の値は得られません。
Bostonの物件の家賃
# ライブラリをロード from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.tree import DecisionTreeRegressor from sklearn.datasets import load_boston from sklearn.metrics import mean_squared_error # データをロードし、特徴量を2つに制限 boston = load_boston() features = boston.data[:,0:2] target = boston.target # 特徴量を標準化 scaler = StandardScaler() X_standerd = scaler.fit_transform(features) X_train,X_test,y_train,y_test = train_test_split( X_standerd, target,random_state=0 ) # 線形回帰器を作成 regression = DecisionTreeRegressor(random_state=0) # 線形回帰器を訓練 model = regression.fit(features, target) # 決定係数 print('MSE train',mean_squared_error(y_train,model.predict(X_train))) print('MSE test',mean_squared_error(y_test,model.predict(X_test))) print('決定係数r2(train):{:.3f}'.format(model.score(X_train,y_train))) print('決定係数r2(test):{:.3f}'.format(model.score(X_test,y_test))) # 金額の単位は1000ドル単位 print('最初のターゲット金額',target[0]) # 最初の観測値のターゲット値を予測 print('予測値',model.predict(features)[0])
結果
MSE train 151.3282585751979
MSE test 136.86472440944883
決定係数r2(train):-0.774
決定係数r2(test):-0.675
最初のターゲット金額 24.0
予測値 24.0
DecisionTreeRegressorのパラメータ
scikit-learn DecisionTreeRegressor ドキュメント
パラメータ | 内容 |
---|---|
criterion | str型で指定, optional (default=”mse”) スプリットの品質を測定する機能。サポートされる基準は、平均2乗誤差の「mse」です。これは、特徴選択基準としての分散低減に等しく、潜在的なフリードマンの改善スコアを持つ平均2乗誤差を使用する各端末ノード「friedman_mse」各端末ノードの中央値を使用してL1損失を最小化する平均絶対誤差の「前」。 バージョン0.18の新機能:平均絶対誤差(MAE)基準。 |
splitter | str型で指定, optional (default=”best”) 各ノードで分割を選択するために使用される戦略。サポートされている戦略は、最適な分割を選択する「最良」と、最適なランダム分割を選択する「ランダム」です。 |
max_depth | int型で指定 or None, optional (default=None) ツリーの最大の深さ。Noneの場合、すべてのリーフが純粋になるか、すべてのリーフにmin_samples_splitサンプル未満が含まれるまで、ノードが展開されます。 |
min_samples_split | int型で指定, float, optional (default=2) 内部ノードを分割するために必要なサンプルの最小数: intの場合min_samples_split、最小数と見なされます。 floatの場合、それmin_samples_splitは分数で あり、各分割の最小サンプル数です。ceil(min_samples_split * n_samples) バージョン0.18で変更:分数にfloat値を追加しました。 |
min_samples_leaf | int型で指定, float, optional (default=1) リーフノードにあるために必要なサンプルの最小数。任意の深さの分割ポイントmin_samples_leafは、左右のブランチのそれぞれに少なくともトレーニングサンプルが残っている場合にのみ考慮されます。これは、特に回帰において、モデルを平滑化する効果があるかもしれません。 intの場合min_samples_leaf、最小数と見なされます。 floatの場合、それmin_samples_leafは分数で あり、各ノードの最小サンプル数です。ceil(min_samples_leaf * n_samples) バージョン0.18で変更:分数にfloat値を追加しました。 |
min_weight_fraction_leaf | float型で指定, optional (default=0.) リーフノードにある必要がある(すべての入力サンプルの)重みの合計の最小重み付き割合。sample_weightが指定されていない場合、サンプルの重みは等しくなります。 |
max_features | int, float, str or None, optional (default=None) 最適な分割を探すときに考慮する機能の数:intの場合max_features、各分割で機能を検討します。 フロートの場合max_features、分数であり、 フィーチャは各分割で考慮されます。int(max_features * n_features) そして、「自動」の場合max_features=n_features。 そして、「SQRT」の場合max_features=sqrt(n_features)。 そして、「LOG2」の場合max_features=log2(n_features)。 その後、なしの場合max_features=n_features。 注:複数のmax_features機能を効果的に検査する必要がある場合でも、ノードサンプルの有効なパーティションが少なくとも1つ検出されるまで、分割の検索は停止しません。 |
random_state | int型で指定, RandomState instance or None, optional (default=None) intの場合、random_stateは乱数ジェネレーターが使用するシードです。RandomStateインスタンスの場合、random_stateは乱数ジェネレーターです。Noneの場合、乱数ジェネレーターはによって使用されるRandomStateインスタンスnp.randomです。 |
max_leaf_nodes | int型で指定 or None, optional (default=None) max_leaf_nodes最高の方法で木を育てます。最良のノードは、不純物の相対的な減少として定義されます。なしの場合、リーフノードの数に制限はありません。 |
min_impurity_decrease | float型で指定, optional (default=0.) この分割がこの値以上の不純物の減少を引き起こす場合、ノードは分割されます。 重み付き不純物減少方程式は次のとおりです。 |
ccp_alphanon-negative | float型で指定, optional (default=0.0) 最小コスト複雑性プルーニングに使用される複雑性パラメーター。ccp_alpha選択されるよりも小さい最大のコスト複雑度を持つサブツリー 。デフォルトでは、プルーニングは実行されません。詳細については、 最小コストの複雑さのプルーニングを参照してください。 |
SVR
サポートベクター回帰(Support Vector Regression, SVR)はサンプル数が10000以下などの場合に有効です。サンプル数が多い場合は適していません。
Bostonの物件の家賃
# ライブラリをロード from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.svm import LinearSVR from sklearn.datasets import load_boston from sklearn.metrics import mean_squared_error # データをロードし、特徴量を2つに制限 boston = load_boston() features = boston.data[:,0:2] target = boston.target # 特徴量を標準化 scaler = StandardScaler() X_standerd = scaler.fit_transform(features) X_train,X_test,y_train,y_test = train_test_split( X_standerd, target,random_state=0 ) # 線形回帰器を作成 regression = LinearSVR(random_state=0) # 線形回帰器を訓練 model = regression.fit(features, target) # 切片(intercept)を表示 print('切片',model.intercept_) # 特徴量の係数(coefficient)を表示 print('係数',model.coef_) # 決定係数 print('MSE train',mean_squared_error(y_train,model.predict(X_train))) print('MSE test',mean_squared_error(y_test,model.predict(X_test))) print('決定係数r2(train):{:.3f}'.format(model.score(X_train,y_train))) print('決定係数r2(test):{:.3f}'.format(model.score(X_test,y_test))) # 金額の単位は1000ドル単位 print('最初のターゲット金額',target[0]) # 最初の観測値のターゲット値を予測 print('予測値',model.predict(features)[0])
結果
切片 [20.53771785]
係数 [-0.40514314 0.14280187]
MSE train 85.770926645609
MSE test 81.78661504401396
決定係数r2(train):-0.005
決定係数r2(test):-0.001
最初のターゲット金額 24.0
予測値 23.105590991250903
LinearSVRのパラメータ
パラメータ | 内容 |
---|---|
epsilon | float型で指定, optional (default=0.0) イプシロンに依存しない損失関数のイプシロンパラメーター。このパラメーターの値は、ターゲット変数yのスケールに依存することに注意してください。不明な場合は、を設定しepsilon=0ます。 |
tol | float型で指定, optional (default=1e-4) 停止基準の許容範囲。 |
C | float型で指定, optional (default=1.0)) 正則化パラメーター。正則化の強度はCに反比例します。厳密に正でなければなりません。 |
loss | string型で指定, optional (default=’epsilon_insensitive’) 損失関数を指定します。イプシロンに依存しない損失(標準SVR)はL1損失であり、イプシロンに依存しない損失( ‘squared_epsilon_insensitive’)はL2損失です。 |
fit_intercept | boolean型で指定, optional (default=True) このモデルの切片を計算するかどうか。falseに設定すると、計算でインターセプトは使用されません(つまり、データは既に中央に配置されていることが予想されます)。 |
intercept_scaling | float型で指定, optional (default=1) self.fit_interceptがTrueの場合、インスタンスベクトルxは[x、self.intercept_scaling]になります。つまり、intercept_scalingに等しい定数値を持つ「合成」機能がインスタンスベクトルに追加されます。インターセプトは、intercept_scaling *合成フィーチャの重みになります。合成特徴の重みは、他のすべての特徴と同様にl1 / l2正則化の対象となります。合成フィーチャの重み(したがって、インターセプト)に対する正則化の影響を軽減するには、intercept_scalingを増やす必要があります。 |
dual | bool型で指定, (default=True) アルゴリズムを選択して、デュアルまたはプライマル最適化問題を解決します。n_samples> n_featuresの場合はdual = Falseを優先します。 |
verbose | int型で指定, (default=0) 詳細出力を有効にします。この設定は、liblinearのプロセスごとのランタイム設定を利用します。これは、有効にすると、マルチスレッドコンテキストで適切に動作しない場合があります。 |
random_state | int型で指定, RandomState instance or None, optional (default=None) データをシャッフルするときに使用する擬似乱数ジェネレーターのシード。intの場合、random_stateは乱数ジェネレーターが使用するシードです。RandomStateインスタンスの場合、random_stateは乱数ジェネレーターです。Noneの場合、乱数ジェネレーターはによって使用されるRandomStateインスタンスnp.randomです。 |
max_iter | int型で指定, (default=1000) 実行される反復の最大数。 |
分類問題
分類問題は、2値、または複数値に目的変数を分類するものです。
分類問題では、アイリスの種類を分類するデータをそれぞれの学習器にかけてその使い方と特徴を説明します。
ロジスティック回帰
ロジスティック回帰は回帰となっていますが、分類問題で使うものです。
回帰問題には使えないので間違わないようにしましょう。
名前が回帰となっているのは、アルゴリズムに線形回帰モデルと同様のアルゴリズムを使っているからです。
そこで出された結果をロジット関数(シグモイド関数)で確率に変換します。
確率の値は0から1までの数値で表されますが、一定の閾値を決めておけば、0.5以上は陽性(1)それ以下は陰性(0)などとすることができます。
そのような仕組みから、ロジスティック回帰は2値分類が得意とされています。(多値分類ができないというのではありません)
ちなみに、シグモイド関数はディープラーニングでも頻繁に使用される関数です。
簡単な考え方ですので数学的に理解しておいて損はないと思いますので、勉強しておくと良いでしょう。
ロジスティック回帰が確率判定する様子を確認するために、説明変数を花弁の幅(Petal width)だけで学習させておいて、花弁の幅のサイズがどのサイズの時に「Virginica種」と判定するか決定境界を確認するコードです。
その結果はグラフとして表示されます。
花弁の幅でVirginica種を判定するモデルのコード
# 必要なライブラリの読み込み import numpy as np from scipy import sparse import matplotlib.pyplot as plt import pandas as pd from sklearn.datasets import load_iris iris_dataset = load_iris() X = iris_dataset['data'][:, 3:] #花弁の幅 y = (iris_dataset['target'] == 2).astype(np.int) #Virginica:1 from sklearn.linear_model import LogisticRegression model = LogisticRegression() model.fit(X, y) X_new = np.linspace(0, 3, 1000).reshape(-1, 1) y_proba = model.predict_proba(X_new) plt.plot(X_new, y_proba[:, 1],'r-', label='Iris-Verginica') plt.plot(X_new, y_proba[:, 0],'b--', label='Not Iris-Verginica') plt.legend() plt.xlabel('Petal width') plt.ylabel('Probability') plt.show()
結果のグラフからわかるように、花弁の幅が1.4センチくらいからVerginica種の存在感が出てきて、2センチ以上になるとかなりその確率が高くなってきています。
つまり、この分類器は確率50%のところを決定境界にして、1と0に分類していることが読めてきます。
ロジスティック回帰には標準でL2ペナルティが設定されている。ペナルティの強さはハイパーパラメータのCの値を変更することで調整できます。Cの値が大きくなると正則化は弱まります。
ロジスティック回帰でアイリスの種類を分類するモデルの例
# 必要なライブラリの読み込み import numpy as np from scipy import sparse import matplotlib.pyplot as plt import pandas as pd from sklearn.datasets import load_iris iris_dataset = load_iris() from sklearn.model_selection import train_test_split X_train,X_test,y_train,y_test = train_test_split( iris_dataset['data'],iris_dataset['target'],random_state=0 ) from sklearn.linear_model import LogisticRegression model = LogisticRegression(C=100, random_state=0, multi_class="ovr", penalty="l2") model.fit(X_train,y_train) print('------------精度--------------') print("Train set score: {:.2f}".format(model.score(X_train,y_train))) print("Test set score: {:.2f}".format(model.score(X_test,y_test))) X_new = np.array([[5,2.9,1,0.2]]) prediction = model.predict(X_new) print('------------予測--------------') print("Prediction: {}".format(prediction)) print("Predicted target name: {}".format(iris_dataset['target_names'][prediction]))
結果
————精度————–
Train set score: 0.99
Test set score: 0.97
————予測————–
Prediction: [0]
Predicted target name: [‘setosa’]
LogisticRegressionのパラメータ
scikit-learn LogisticRegression ドキュメント
パラメータ | 内容 |
---|---|
penalty | str型を指定、 ‘l1’、 ‘l2’、 ‘elasticnet’または ‘none’、オプション(デフォルト= ‘l2’) ペナルティに使用される基準を指定するために使用されます。’newton-cg’、 ‘sag’、および ‘lbfgs’ソルバーは、l2のペナルティーのみをサポートします。「elasticnet」は「saga」ソルバーによってのみサポートされます。’none’(liblinearソルバーでサポートされていない)の場合、正則化は適用されません。 |
dual | bool型を指定、オプション(デフォルト= False) デュアルまたはプライマル製剤。デュアル定式化は、liblinearソルバーを使用したl2ペナルティに対してのみ実装されます。n_samples> n_featuresの場合はdual = Falseを優先します。 |
tol | float型を指定、オプション(デフォルト= 1e-4) 停止基準の許容範囲。 |
C | float型を指定、オプション(デフォルト= 1.0) 正則化強度の逆数。正の浮動小数点数でなければなりません。サポートベクターマシンと同様に、値が小さいほど正則化が強くなります。 |
fit_intercept | bool型を指定、オプション(デフォルト= True) 定数(バイアスまたはインターセプト)を決定関数に追加するかどうかを指定します。 |
intercept_scaling | float型を指定、オプション(デフォルト= 1) ソルバー ‘liblinear’が使用され、self.fit_interceptがTrueに設定されている場合にのみ有用です。この場合、xは[x、self.intercept_scaling]になります。つまり、intercept_scalingに等しい定数値を持つ「合成」機能がインスタンスベクトルに追加されます。切片はになります。intercept_scaling * synthetic_feature_weight 注意!合成特徴の重みは、他のすべての特徴と同様にl1 / l2正則化の対象となります。合成フィーチャの重み(したがって、インターセプト)に対する正則化の影響を軽減するには、intercept_scalingを増やす必要があります。 |
class_weight | dict型を指定 または ‘balanced’、オプション(デフォルト=なし) フォーム内のクラスに関連付けられた重み。指定しない場合、すべてのクラスに重み1が割り当てられます。{class_label: weight} 「平衡」モードでは、yの値を使用して、入力データのクラス頻度に反比例する重みをとして自動的に調整します。n_samples / (n_classes * np.bincount(y)) sample_weightが指定されている場合、これらの重みはsample_weightで乗算されることに注意してください(fitメソッドを介して渡されます)。 |
random_state | int型を指定、RandomStateインスタンスまたはNone、オプション(デフォルト= None) データをシャッフルするときに使用する擬似乱数ジェネレーターのシード。intの場合、random_stateは乱数ジェネレーターが使用するシードです。RandomStateインスタンスの場合、random_stateは乱数ジェネレーターです。Noneの場合、乱数ジェネレーターはによって使用されるRandomStateインスタンスnp.randomです。solver== ‘sag’または ‘liblinear’の場合に使用されます。 |
solver | str型を指定、{‘newton-cg’、 ‘lbfgs’、 ‘liblinear’、 ‘sag’、 ‘saga’}、オプション(default = ‘lbfgs’) 最適化問題で使用するアルゴリズム。 小さなデータセットの場合、「liblinear」が適切な選択ですが、「sag」と「saga」は大きなデータセットの場合に高速です。 マルチクラス問題の場合、「newton-cg」、「sag」、「saga」、および「lbfgs」のみが多項損失を処理します。「liblinear」は、1対残りのスキームに制限されています。 「newton-cg」、「lbfgs」、「sag」、および「saga」はL2を処理するか、ペナルティなし 「liblinear」と「saga」もL1ペナルティを処理します 「saga」は「elasticnet」ペナルティもサポートしています 「liblinear」は設定をサポートしていません penalty=’none’ 「サグ」と「サガ」の高速収束は、ほぼ同じスケールのフィーチャでのみ保証されることに注意してください。sklearn.preprocessingのスケーラーでデータを前処理できます。 |
max_iter | int型を指定、オプション(デフォルト= 100) ソルバーが収束するために取られる反復の最大数。 |
multi_class | {‘ovr’、 ‘multinomial’、 ‘auto’}、default = ‘auto’ 選択したオプションが「ovr」の場合、バイナリ問題が各ラベルに適合します。「多項」の場合、最小化される損失は、データがbinaryであっても、確率分布全体にわたる多項損失適合です。solver = ‘liblinear’の場合、 ‘multinomial’は使用できません。’auto’は、データがバイナリの場合、またはsolver = ‘liblinear’の場合は ‘ovr’を選択し、それ以外の場合は ‘multinomial’を選択します。 |
verbose | int型を指定、オプション(デフォルト= 0) liblinearおよびlbfgsソルバーでは、冗長性のためにverboseを任意の正数に設定します。 |
warm_start | bool型を指定、オプション(デフォルト= False) Trueに設定すると、以前の呼び出しのソリューションを再利用して初期化に適合させます。それ以外の場合は、以前のソリューションを消去します。liblinearソルバーには役に立たない。用語集を参照してください。 |
n_jobs | int型を指定またはNone、オプション(デフォルト= None) multi_class = ‘ovr’”の場合、クラスを並列化するときに使用されるCPUコアの数。solver「multi_class」が指定されているかどうかに関係なく、が「liblinear」に設定されている場合、このパラメーターは無視されます。 コンテキストにNoneない限り1を意味しjoblib.parallel_backendます。-1すべてのプロセッサを使用することを意味します。 |
l1_ratio | float型を指定またはNone、オプション(デフォルト= None) Elastic-Netのミキシングパラメーター。がusingと同等の場合にのみ使用され、設定はusingと同等です。の場合、ペナルティはL1とL2の組み合わせです。0 <= l1_ratio <= 1penalty='elasticnet'`. Setting ``l1_ratio=0penalty='l2'l1_ratio=1penalty='l1'0 < l1_ratio <1 |
k-近傍法
k-近傍法は機械学習の中でも最も簡単な仕組みでできています。
k-近傍法の考え方は、分類したいデータのひとつがどの訓練データと同じクラスかを予測するには、訓練データの中から1番近い点つまり最近傍点を見つけることです。
次の例では、test pred0の最も近い点は青丸だからclass0に分類されることになります。
test pred1の最も近い点はオレンジ三角だからclass1に分類されることになります。
次の例では、近傍点は1つに限らず、任意の個数として考えます。
1つ以上の近傍点を扱う場合は多数決でラベルを決めます。
この例の場合は3つの近傍点を考慮しており、pred0、pred1どちらもオレンジ三角の数が多いのでどちらもclass1になります。
特徴と欠点
k-最近傍法はアルゴリズムとして理解しやすいという特徴があります。 また、多くの場合あまり調整の必要がなくても十分な性能が得られます。
欠点として、訓練セットが大きくなると予測に時間がかかります。 また、事前のデータ前処理が重要になります。さらに多くの特徴量(説明変数)をもつデータセットではうまく機能しません。 また、特徴量の多くが0になるようなデータセットでは性能が悪くなります。
従って、現実的にはあまり活用されないアルゴリズムになっています。
アイリスの分類
# 必要なライブラリの読み込み import numpy as np from scipy import sparse import matplotlib.pyplot as plt import pandas as pd from sklearn.datasets import load_iris iris_dataset = load_iris() from sklearn.model_selection import train_test_split X_train,X_test,y_train,y_test = train_test_split( iris_dataset['data'],iris_dataset['target'],random_state=0 ) from sklearn.neighbors import KNeighborsClassifier model = KNeighborsClassifier(n_neighbors=10) model.fit(X_train,y_train) print('------------精度--------------') print("Train set score: {:.2f}".format(model.score(X_train,y_train))) print("Test set score: {:.2f}".format(model.score(X_test,y_test))) X_new = np.array([[5,2.9,1,0.2]]) prediction = model.predict(X_new) print('------------予測--------------') print("Prediction: {}".format(prediction)) print("Predicted target name: {}".format(iris_dataset['target_names'][prediction]))
結果
————精度————–
Train set score: 0.97
Test set score: 0.97
————予測————–
Prediction: [0]
Predicted target name: [‘setosa’]
KNeighborsClassifierのパラメータ
scikit-learn KNeighborsClassifier ドキュメント
パラメータ | 内容 |
---|---|
n_neighbors | int型で指定 、オプション(デフォルト= 5) kneighborsクエリにデフォルトで使用するネイバーの数。 |
weights | str型で指定またはcallable、オプション(デフォルト= ‘uniform’) 予測で使用される重み関数。可能な値: 「均一」:均一な重み。各近傍のすべてのポイントは等しく重み付けされます。 ‘distance’:距離の逆数による重みポイント。この場合、クエリポイントのより近い隣人は、より遠くにある隣人よりも大きな影響力を持ちます。 [callable]:距離の配列を受け入れ、重みを含む同じ形状の配列を返すユーザー定義関数。 |
algorithm | {‘auto’、 ‘ball_tree’、 ‘kd_tree’、 ‘brute’}、オプション 最近傍の計算に使用されるアルゴリズム: 「ball_tree」は次を使用します BallTree ‘kd_tree’は使用します KDTree 「ブルート」はブルートフォース検索を使用します。 ‘auto’は、fitメソッドに渡された値に基づいて最も適切なアルゴリズムを決定しようとします。 注:スパース入力でフィッティングすると、ブルートフォースを使用してこのパラメーターの設定がオーバーライドされます。 |
leaf_size | int型で指定、オプション(デフォルト= 30) BallTreeまたはKDTreeに渡されるリーフサイズ。これは、ツリーの保存に必要なメモリだけでなく、構築とクエリの速度に影響を与える可能性があります。最適な値は、問題の性質によって異なります。 |
p | int型で指定、オプション(デフォルト= 2) ミンコフスキーメトリックのパワーパラメーター。p = 1の場合、これはmanhattan_distance(l1)とp = 2のeuclidean_distance(l2)を使用することと同等です。任意のpには、minkowski_distance(l_p)が使用されます。 |
metric | str型で指定または呼び出し可能、デフォルトは「minkowski」 ツリーに使用する距離メトリック。デフォルトのメトリックはminkowskiで、p = 2の場合、標準のユークリッドメトリックと同等です。使用可能なメトリックのリストについては、DistanceMetricクラスのドキュメントを参照してください。メトリックが「事前計算」されている場合、Xは距離行列と見なされ、フィット中は正方形でなければなりません。Xは用語集である場合があります。この場合、「非ゼロ」要素のみが近傍と見なされます。 |
metric_params | dict型で指定、オプション(デフォルト=なし) メトリック関数の追加のキーワード引数。 |
n_jobs | int型で指定またはNone、オプション(デフォルト= None) 近隣検索のために実行する並列ジョブの数。 コンテキストにNoneない限り1を意味しjoblib.parallel_backendます。 -1すべてのプロセッサを使用することを意味します。詳細については、用語集 を参照してください。fitメソッドには影響しません。 |
決定木
決定木は分類と回帰の両方で使えます。
けれども、scikit-learnでモデルを作成する時に、分類と回帰では読み込むライブラリが違いますので注意してください。
scikit-learnの決定木の種類
DecisionTreeRegressor : 回帰問題に使います。
DecisionClassifier : 分類問題に使います。
決定木の仕組みを理解するには簡単なモデルの例で考えるの一番良い方法です。
次に簡単な例で考えてみます。
「熊、鷹、ペンギン、イルカ」の4種類の動物がいます。
なるべく少ない質問で正確に、この動物を分類したいとします。
その時に次のようなTreeを描くことができます。
これが即ち決定木です。
機械学習で言えば、4クラス(熊、鷹、ペンギン、イルカ)を3つの特徴量(羽毛の有無、飛べるか 否か、ヒレの有る無し)で識別するモデルを作ったことになります。
ノードの描き方は、最上部の深さ0から始めます。この最上部のことをルートノードといいます。
木のノード(分岐点、接点)は「質問」か「答え」です。そして、答えは終点となり葉(leaf)と言われます。そして、Trueは左側に描くようにします。
データを分割する基準を決定するには、「情報利得」と「不純度」を使います。
- 情報利得とは、分割の良さを表したものです。
- 不純度とは、どれだけごちゃごちゃしているか、つまりノードの中に同じクラスのものばかりだと不純度は0になります。
式で表すと次のようになります。
ノードXを分割したことによる情報利得 = 分割前の不純度 – 分割後の不純度
2class分類例
- class0:黄色丸
- class1:青三角
頂点にあるノード(root)はデータ全体つまりclass0:10とclass1:10を示します。
X[1]とは説明変数の0から数えて1番目のものということ。
X[1]=0.0596で水平にデータセットを分割することで、最も情報量が多く、class0とclass1を分割できます。説明変数0番目のものは、0.0596という数字でy軸をほぼ半分に2等分するデータと考えてみるとわかりやすいです。
今度はX[0]番目の説明変数を使い今度はx軸方向のある数値を活用します。
さらに深く分離していくと最終的にはきれいに分離できるが、明らかに過学習になります。
決定木の弱点はあまり深く木を作ると過学習になることです。
それを防止するためには2つの方法が考えられます。
- 事前枝刈り:木の成長を早めに止める
- 事後枝刈り:木を構築後に情報の少ないノードを削除
ただし、Scikit-learnには事前枝刈りしか実装されていません。
max_depth=4のようなハイパーパラメータを使用します。
エントロピー
エントロピーはノードの不純度を図ることができます。
エントロピーは次の式で表されます。
$$
I_H(t)=−\sum_{i=1}^c p(i|t)log_2 p(i|t)\\
ただし,p(i|t)=\frac{n_i}{N}
$$
cは目的変数のクラス数,tは現在のノード,Nはトレーニングデータのサンプル数,$n_i$はクラスiに属するトレーニングデータの数を示しています。
不純度が最も低ければエントロピーの値は0,不純度が高くなればなるほどエントロピーの値が大きくなることになります。
エントロピーを使った方法は目的変数が離散値の場合で分類に対応しています。
ジニ係数を使った不純度
ジニ係数を使ったアルゴリズムをCARTと言います。
$$
I_G(t)=1−\sum_{i=1}^c p(i|t)^2\\
ただし,p(i|t)=\frac{n_i}{N}
$$
cは目的変数のクラス数,tは現在のノード,Nはトレーニングデータのサンプル数,niはクラスiに属するトレーニングデータの数を示しています。
不純度が最も低ければジニ係数の値は0,不純度が高くなればなるほどジニ係数の値が1に漸近します。
ジニ係数を使った方法は目的変数が離散値、または連続値で分類と回帰に対応しています。
決定木を使ったアイリスの分類の例
# 必要なライブラリの読み込み import numpy as np from scipy import sparse import matplotlib.pyplot as plt import pandas as pd from sklearn.datasets import load_iris iris_dataset = load_iris() from sklearn.model_selection import train_test_split X_train,X_test,y_train,y_test = train_test_split( iris_dataset['data'],iris_dataset['target'],random_state=0 ) from sklearn.tree import DecisionTreeClassifier model = DecisionTreeClassifier(max_depth = 5,random_state=0,criterion="gini") model.fit(X_train,y_train) print('------------精度--------------') print("Train set score: {:.2f}".format(model.score(X_train,y_train))) print("Test set score: {:.2f}".format(model.score(X_test,y_test))) X_new = np.array([[5,2.9,1,0.2]]) prediction = model.predict(X_new) print('------------予測--------------') print("Prediction: {}".format(prediction)) print("Predicted target name: {}".format(iris_dataset['target_names'][prediction]))
結果
————精度————–
Train set score: 1.00
Test set score: 0.97
————予測————–
Prediction: [0]
Predicted target name: [‘setosa’]
max_depthを調べてい場合は次のようにします。
depth_list = [i for i in range(1,11)] accuracy = [] for depth in range(1,11): model = DecisionTreeClassifier(max_depth = depth,random_state=0,criterion="gini") model.fit(X_train,y_train) accuracy.append(model.score(X_test,y_test)) plt.plot(depth_list,accuracy) plt.xlabel('max_depth') plt.ylabel('accuracy') plt.title('accuracy by changeing max_depth') plt.show()
DecisionTreeClassifierのパラメータ
scikit-learn DecisionTreeClassifier ドキュメント
パラメータ | 内容 |
---|---|
criterion | str型で指定、オプション(デフォルト=“ gini”) スプリットの品質を測定する機能。サポートされる基準は、Gini不純物の「gini」と情報ゲインの「エントロピー」です。 |
splitter | str型で指定、オプション(デフォルト=“ best”) 各ノードで分割を選択するために使用される戦略。サポートされている戦略は、最適な分割を選択する「最良」と、最適なランダム分割を選択する「ランダム」です。 |
max_depth | int型で指定またはNone、オプション(デフォルト= None) ツリーの最大の深さ。Noneの場合、すべてのリーフが純粋になるか、すべてのリーフにmin_samples_splitサンプル未満が含まれるまで、ノードが展開されます。 |
min_samples_split | int型で指定、float、オプション(デフォルト= 2) 内部ノードを分割するために必要なサンプルの最小数: intの場合min_samples_split、最小数と見なされます。 floatの場合、それmin_samples_splitは分数で あり、各分割の最小サンプル数です。ceil(min_samples_split * n_samples) |
min_samples_leaf | int型で指定、float、オプション(デフォルト= 1) リーフノードにあるために必要なサンプルの最小数。任意の深さの分割ポイントmin_samples_leafは、左右のブランチのそれぞれに少なくともトレーニングサンプルが残っている場合にのみ考慮されます。これは、特に回帰において、モデルを平滑化する効果があるかもしれません。 intの場合min_samples_leaf、最小数と見なされます。 floatの場合、それmin_samples_leafは分数で あり、各ノードの最小サンプル数です。ceil(min_samples_leaf * n_samples) |
min_weight_fraction_leaf | float型で指定、オプション(デフォルト= 0) リーフノードにある必要がある(すべての入力サンプルの)重みの合計の最小重み付き割合。sample_weightが指定されていない場合、サンプルの重みは等しくなります。 |
max_features | int型で指定、float、strまたはNone、オプション(デフォルト=なし) 最適な分割を探すときに考慮する機能の数: intの場合max_features、各分割で機能を検討します。 フロートの場合max_features、分数であり、 フィーチャは各分割で考慮されます。int(max_features * n_features) そして、「自動」の場合max_features=sqrt(n_features)。 そして、「SQRT」の場合max_features=sqrt(n_features)。 そして、「LOG2」の場合max_features=log2(n_features)。 その後、なしの場合max_features=n_features。 注:複数のmax_features機能を効果的に検査する必要がある場合でも、ノードサンプルの有効なパーティションが少なくとも1つ検出されるまで、分割の検索は停止しません。 |
random_state | int型で指定、RandomStateインスタンスまたはNone、オプション(デフォルト= None) intの場合、random_stateは乱数ジェネレーターが使用するシードです。RandomStateインスタンスの場合、random_stateは乱数ジェネレーターです。Noneの場合、乱数ジェネレーターはによって使用されるRandomStateインスタンスnp.randomです。 |
max_leaf_nodes | int型で指定またはNone、オプション(デフォルト= None) max_leaf_nodes最高の方法で木を育てます。最良のノードは、不純物の相対的な減少として定義されます。なしの場合、リーフノードの数に制限はありません。 |
min_impurity_decrease | float型で指定、オプション(デフォルト= 0) この分割がこの値以上の不純物の減少を引き起こす場合、ノードは分割されます。 重み付き不純物減少方程式は次のとおりです。 N_t / N * (impurity – N_t_R / N_t * right_impurity – N_t_L / N_t * left_impurity)ここNで、はサンプルの合計数、N_tは現在のノードN_t_Lのサンプル数、は左の子N_t_Rのサンプル数、は右の子のサンプル数です。 N、N_t、N_t_RとN_t_Lあればすべて、加重和を参照してくださいsample_weight渡されます。 |
min_impurity_split | float型で指定、デフォルト= 1e-7 木の成長の早期停止のしきい値。不純物がしきい値を超える場合、ノードは分割されます。それ以外の場合、ノードはリーフです。 バージョン0.19min_impurity_splitから非推奨:0.19に賛成して非推奨になりました min_impurity_decrease。のデフォルト値は min_impurity_split0.23で1e-7から0に変わり、0.25で削除されます。min_impurity_decrease代わりに使用してください。 |
class_weight | dict型で指定、dictsのリスト、「balanced」またはNone、default = None フォーム内のクラスに関連付けられた重み。指定しない場合、すべてのクラスに重み1が割り当てられます。複数出力の問題の場合、辞書のリストをyの列と同じ順序で提供できます。{class_label: weight} マルチ出力(マルチラベルを含む)の場合、独自の辞書のすべての列のクラスごとに重みを定義する必要があることに注意してください。たとえば、4クラスのマルチラベル分類の重みは、[{0:1、1:1}、{0:1、1:5}、{0:1、1:1}、{0:1、1: 1}] [{1:1}、{2:5}、{3:1}、{4:1}]の代わりに。 「平衡」モードでは、yの値を使用して、入力データのクラス頻度に反比例する重みを自動的に調整します。 n_samples / (n_classes * np.bincount(y)) マルチ出力の場合、yの各列の重みが乗算されます。 sample_weightが指定されている場合、これらの重みはsample_weightで乗算されることに注意してください(fitメソッドを介して渡されます)。 非推奨のpresort 、default = ‘deprecated’ このパラメーターは非推奨であり、v0.24で削除されます。 バージョン0.22から非推奨。 |
ccp_alpha | 非負のfloat型で指定、オプション(デフォルト= 0.0) 最小コスト複雑性プルーニングに使用される複雑性パラメーター。ccp_alpha選択されるよりも小さい最大のコスト複雑度を持つサブツリー 。デフォルトでは、プルーニングは実行されません。詳細については、 最小コストの複雑さのプルーニングを参照してください。 |
SVC
サポートベクターマシン(Support Vector Machine:SVM)は、線形分離、非線形分離、回帰問題、外れ値検出にも使える非常に優秀な機械学習モデルです。
マージン最大化と言われる基本概念に基づき2値分類問題に使われます。
計算コストが大きいため中小規模のデータセットで使われます。
マージン最大化とは、カテゴリを識別する境界線を、1本の線ではなく、マージンが最大になるように引く手法です。
- 線形分離可能:2クラス分類する場合、1本の直線で完全分離できるもの
- 線形分離不可能:2クラス分類する場合。1本の直線で完全分離することができないもの
線形分離可能なSVM
2クラスのデータを分類する場合1本の直線で分類する方法です。
そして、1本の直線を引くときにより多くマージンが取れる引き方を選択します。
そして、マージンに対して直接接するようなデータのことをサポートベクトルと呼びます。サポートベクトルマシンの呼び方はここから来ています。
マージン最大化の数式
$$
\min_{w,b}\frac{1}{2}||W||^2,\quad t_i(W^TX_i+b)\geq1,\quad i=1,2,…,n
$$
ちなみに、クラスAかクラスBかはっきり分かれることを前提としたマージンを「ハードマージン」と呼びます。
線形不可能な場合
2クラスのデータを分類する場合1本の直線で分類することができない場合、つまり、線形不可能な場合はソフトマージンを使います。
ソフトマージンは以下の2つを満たすようにします。
- 境界線とデータとはなるべく離れていたほうがいい
- 誤判別はなるべく少ないほうがいい
数式で簡単に書くと次のようになります。
$$
\min{\frac{1}{マージン(サポートベクトルと境界線の距離)+C×誤判別数}}
$$
パラメタ「C」は「誤判別をどこまで許容するか」を現すパラメタです。
パラメタCが大きければ、少しの誤判別も許さないし、逆にCが小さければ、誤判別に寛容になります。
パラメタCが∞に大きかった場合はハードマージンと変わらなくなります。
パラメタCはハイパーパラメータなので、あらかじめ決めてやる必要があります。
なお、Cの初期値は1です。
今後学習するグリッドサーチなどを使って「最も予測精度が高くなるようにパラメタをチューニングする」技術もあります。
SVCとLinearSVC
SVC(SVM Classification)は標準的なソフトマージン(エラーを許容する)SVMです。 一方LinearSVCはカーネルが線形カーネルの場合に特化したSVMです。線形で分離できない場合はソフトマージンを活用します。
アイリスの分類
# 必要なライブラリの読み込み import numpy as np from scipy import sparse import matplotlib.pyplot as plt import pandas as pd from sklearn.datasets import load_iris iris_dataset = load_iris() from sklearn.model_selection import train_test_split X_train,X_test,y_train,y_test = train_test_split( iris_dataset['data'],iris_dataset['target'],random_state=0 ) from sklearn.svm import SVC model = SVC(C=1.0, gamma=0.1, kernel='linear') model.fit(X_train,y_train) print('------------精度--------------') print("Train set score: {:.2f}".format(model.score(X_train,y_train))) print("Test set score: {:.2f}".format(model.score(X_test,y_test))) X_new = np.array([[5,2.9,1,0.2]]) prediction = model.predict(X_new) print('------------予測--------------') print("Prediction: {}".format(prediction)) print("Predicted target name: {}".format(iris_dataset['target_names'][prediction]))
結果
————精度————–
Train set score: 0.98
Test set score: 0.97
————予測————–
Prediction: [0]
Predicted target name: [‘setosa’]
sklearn.svm.SVC パラメータ
パラメータ | 内容 |
---|---|
C | フロート型で指定、オプション(デフォルト= 1.0) 正則化パラメーター。正則化の強度はCに反比例します。厳密に正でなければなりません。ペナルティは2乗のl2ペナルティです。 |
kernel | string型で指定、オプション(デフォルト= ‘rbf’) アルゴリズムで使用されるカーネルタイプを指定します。’linear’、 ‘poly’、 ‘rbf’、 ‘sigmoid’、 ‘precomputed’またはcallableのいずれかでなければなりません。何も指定しない場合、「rbf」が使用されます。callableが与えられた場合、それはデータ行列からカーネル行列を事前計算するために使用されます。その行列はshapeの配列でなければなりません。(n_samples, n_samples) |
degree | int型で指定、オプション(デフォルト= 3) 多項式カーネル関数の次数(「poly」)。他のすべてのカーネルでは無視されます。 |
gamma | {‘scale’、 ‘auto’}またはfloat型で指定、オプション(default = ‘scale’) 「rbf」、「poly」、および「sigmoid」のカーネル係数。 場合gamma=’scale’(デフォルト)が渡され、それは、ガンマの値として1 /(n_featuresを* X.var())を使用し ‘auto’の場合、1 / n_featuresを使用します。 バージョン0.22でgamma変更:デフォルト値が「auto」から「scale」に変更されました。 |
coef0 | float型で指定、オプション(デフォルト= 0.0) カーネル関数の独立した用語。「ポリ」と「シグモイド」でのみ重要です。 |
shrinking | bool型で指定、オプション(デフォルト= True) 縮小ヒューリスティックを使用するかどうか。 |
probability | bool型で指定、オプション(デフォルト=偽) 確率推定を有効にするかどうか。これは、従来の呼び出しに有効にする必要がありfit、それは内部的に5倍クロスバリデーションを使用し、として、そのメソッドを遅くするpredict_probaと一致しないことがあります predict。詳細については、ユーザーガイドをご覧ください。 |
tol | float型で指定、オプション(デフォルト= 1e-3) 停止基準の許容範囲。 |
cache_size | float型で指定、オプション カーネルキャッシュのサイズ(MB単位)を指定します。 |
class_weight | {dict、 ‘balanced’}、オプション SVCのクラスiのパラメーターCをclass_weight [i] * Cに設定します。指定しない場合、すべてのクラスに重み1が割り当てられます。「平衡」モードでは、yの値を使用して、入力データのクラス頻度に反比例する重みを自動的に調整します。n_samples / (n_classes * np.bincount(y)) |
verbose | bool型で指定、デフォルト:False 詳細出力を有効にします。この設定は、libsvmのプロセスごとのランタイム設定を利用することに注意してください。この設定を有効にすると、マルチスレッドコンテキストで適切に動作しない場合があります。 |
max_iter | int型で指定、オプション(デフォルト= -1) ソルバー内の反復のハード制限、または制限なしの場合は-1。 |
decision_function_shape | ‘ovo’、 ‘ovr’、default = ‘ovr’ 他のすべての分類子として形状(n_samples、n_classes)のone-vs-rest( ‘ovr’)決定関数を返すか、形状(n_samplesを持つlibsvmの元のone-vs-one( ‘ovo’)決定関数を返すか、n_classes *(n_classes-1)/ 2)。ただし、1対1(「ovo」)は常にマルチクラス戦略として使用されます。 バージョン0.19で変更: decision_function_shapeはデフォルトで「ovr」です。 バージョン0.17の新機能:decision_function_shape = ‘ovr’が推奨されます。 バージョン0.17での変更:非推奨のdecision_function_shape = ‘ovo’およびNone。 |
break_ties | bool型で指定、オプション(デフォルト= False) trueの場合decision_function_shape=’ovr’、クラス数が2 より大きい場合、 predictはdecision_functionの信頼値に従って関係を破り ます。それ以外の場合、関連付けられたクラスの最初のクラスが返されます。単純な予測と比較して、関係を壊すには比較的高い計算コストがかかることに注意してください。 |
random_state | int型で指定、RandomStateインスタンスまたはNone、オプション(デフォルト= None) 確率推定のためにデータをシャッフルするときに使用される擬似乱数ジェネレーターのシード。intの場合、random_stateは乱数ジェネレーターが使用するシードです。RandomStateインスタンスの場合、random_stateは乱数ジェネレーターです。Noneの場合、乱数ジェネレーターはによって使用されるRandomStateインスタンスnp.randomです。 |
コメントを投稿するにはログインしてください。