この読み物の主な目標は、Pythonの機械学習アルゴリズムを活用できる十分な統計手法を理解することです。 scikit-learn ライブラリを作成し、この知識を適用して、古典的な機械学習の問題を解決します。
旅の最初の目的地は、機械学習の簡単な歴史です。次に、さまざまなアルゴリズムについて詳しく説明します。最後に、学んだことを使って解決します。 タイタニックの生存率予測問題 。
いくつかの免責事項:
それを踏まえて、飛び込みましょう!
この分野に足を踏み入れるとすぐに、 機械学習 あなたが思うよりロマンチックではありません。当初、私はもっと学んだ後、自分のJarvis AIを構築できるようになり、ソフトウェアのコーディングとお金の稼ぎに一日を費やして、屋外で本を読んだり、オートバイを運転したりできるようになることを望んでいました。私の個人的なジャービスが私のポケットをより深くしている間、無謀なライフスタイルを楽しんでいます。しかし、機械学習アルゴリズムの基盤は統計であることにすぐに気付きました。統計は、個人的には鈍くて面白くないと感じています。幸いなことに、「鈍い」統計には非常に魅力的なアプリケーションがいくつかあることがわかりました。
これらの魅力的なアプリケーションにアクセスするには、統計を十分に理解する必要があることがすぐにわかります。機械学習アルゴリズムの目標の1つは、提供されたデータの統計的依存関係を見つけることです。
提供されるデータは、年齢に対する血圧のチェックから、さまざまなピクセルの色に基づいた手書きのテキストの検索まで、何でもかまいません。
とはいえ、機械学習アルゴリズムを使用して暗号化ハッシュ関数(SHA、MD5など)の依存関係を見つけることができるかどうかを知りたいと思っていましたが、適切な暗号化プリミティブがそのように構築されているため、実際にはそれを行うことはできません。それらは依存関係を排除し、非常に予測が難しい出力を生成します。無限の時間が与えられると、機械学習アルゴリズムはあらゆる暗号モデルをクラックする可能性があると私は信じています。
残念ながら、私たちにはそれほど時間がないので、暗号通貨を効率的にマイニングする別の方法を見つける必要があります。今までどこまで起きたの?
良い継続のゲシュタルト法
機械学習アルゴリズムのルーツは、18世紀に住んでいた英国の統計学者であったトーマスベイズに由来します。彼の論文 偶然論における問題の解決に向けたエッセイ 支えている ベイズの定理 、統計の分野で広く適用されています。
19世紀に、ピエールシモンラプラスは出版しました 確率の分析理論 、ベイズの定理を拡張し、今日私たちが知っていることをベイズの定理として定義します。その少し前に、Adrien-Marie Legendreは、教師あり学習で今日も広く使用されている「最小二乗」法について説明していました。
20世紀は、この分野で公に知られている発見の大部分が行われた時期です。アンドレイ・マルコフは、詩を分析するために使用したマルコフ連鎖を発明しました。 Alan Turingは、人工知能になり、基本的に遺伝的アルゴリズムを予見できる学習マシンを提案しました。フランク・ローゼンブラットが発明した パーセプトロン 、メディアで大きな興奮と大きな報道を引き起こしました。
しかし、1970年代には、AIのアイデアに関して多くの悲観論が見られ、その結果、資金が削減されたため、この期間は AIの冬 。 1980年代にバックプロパゲーションが再発見されたことで、機械学習の研究が復活しました。そして今日、それは再びホットな話題です。
故レオ・ブレイマンは、データモデリングとアルゴリズムモデリングという2つの統計モデリングパラダイムを区別しました。 「アルゴリズムモデリング」とは、多かれ少なかれ、次のような機械学習アルゴリズムを意味します。 ランダムフォレスト 。
機械学習と統計は密接に関連する分野です。 マイケルI.ジョーダンによると 、方法論の原理から理論的なツールまで、機械学習のアイデアは、統計学において長い先史時代を持っていました。彼はまた提案した データサイエンス 機械学習の専門家と統計学者の両方が暗黙のうちに取り組んでいる全体的な問題のプレースホルダー用語として。
機械学習の分野は、次の2つの主要な柱に立っています。 教師あり学習 そして 教師なし学習 。新しい研究分野を検討する人もいます— ディープラーニング —教師あり学習と教師なし学習の問題とは別にすること。
教師あり学習 コンピューターに入力の例とそれらの望ましい出力が提示されるときです。コンピューターの目的は、入力を出力にマッピングする一般式を学習することです。これはさらに次のように分類できます。
対照的に、 教師なし学習 ラベルがまったく指定されておらず、入力内の構造を見つけるのはアルゴリズム次第です。教師なし学習は、隠れたパターンを発見するだけでよい場合、それ自体が目標になる可能性があります。
ディープラーニング は、人間の脳の構造と機能に触発され、単なる統計的概念ではなく人工ニューラルネットワークに基づいた新しい研究分野です。ディープラーニングは、教師ありアプローチと教師なしアプローチの両方で使用できます。
この記事では、より単純な教師あり機械学習アルゴリズムの一部のみを確認し、それらを使用して、タイタニック号の悲劇的な沈没における個人の生存率を計算します。ただし、一般的に、使用するアルゴリズムがわからない場合は、開始するのに適した場所です。 scikit-learnの機械学習アルゴリズムのチートシート 。
おそらく最も簡単なアルゴリズムは線形回帰です。これは直線としてグラフィカルに表現できる場合もありますが、その名前にもかかわらず、多項式の仮説がある場合、この線は代わりに曲線になる可能性があります。いずれにせよ、スカラー従属変数$ y $と$ x $で示される1つ以上の説明値の間の関係をモデル化します。
素人の言葉で言えば、これは線形回帰が既知の各$ x $と$ y $の間の依存関係を学習するアルゴリズムであることを意味し、後でそれを使用して$ x $の未知のサンプルの$ y $を予測できます。
最初の教師あり学習の例では、基本的な線形回帰モデルを使用して、年齢に応じて人の血圧を予測します。 この は、年齢と血圧という2つの意味のある機能を備えた非常に単純なデータセットです。
すでに上で述べたように、ほとんどの機械学習アルゴリズムは、提供されたデータの統計的依存関係を見つけることによって機能します。この依存関係は、 仮説 通常、$ h( theta)$で表されます。
仮説を理解するために、データを読み込んで調査することから始めましょう。
import matplotlib.pyplot as plt from pandas import read_csv import os # Load data data_path = os.path.join(os.getcwd(), 'data/blood-pressure.txt') dataset = read_csv(data_path, delim_whitespace=True) # We have 30 entries in our dataset and four features. The first feature is the ID of the entry. # The second feature is always 1. The third feature is the age and the last feature is the blood pressure. # We will now drop the ID and One feature for now, as this is not important. dataset = dataset.drop(['ID', 'One'], axis=1) # And we will display this graph %matplotlib inline dataset.plot.scatter(x='Age', y='Pressure') # Now, we will assume that we already know the hypothesis and it looks like a straight line h = lambda x: 84 + 1.24 * x # Let's add this line on the chart now ages = range(18, 85) estimated = [] for i in ages: estimated.append(h(i)) plt.plot(ages, estimated, 'b')
[]
上のグラフでは、すべての青い点がデータサンプルを表しており、青い線はアルゴリズムが学習する必要のある仮説です。では、とにかくこの仮説は正確には何ですか?
この問題を解決するには、$ x $と$ y $の間の依存関係を学習する必要があります。これは、$ y = f(x)$で表されます。したがって、$ f(x)$が理想的なターゲット関数です。機械学習アルゴリズムは、未知の$ f(x)$の最も近い近似である仮説関数$ h(x)$を推測しようとします。
線形回帰問題の最も単純な仮説の形式は、次のようになります。$ h_ theta(x)= theta_0 + theta_1 * x $。単一のスカラー変数$ y $を出力する単一の入力スカラー変数$ x $があります。ここで、$ theta_0 $と$ theta_1 $は学習する必要のあるパラメーターです。この青い線をデータに当てはめるプロセスは、線形回帰と呼ばれます。入力パラメーター$ x_1 $が1つしかないことを理解することが重要です。ただし、多くの仮説関数にはバイアス単位($ x_0 $)も含まれます。したがって、結果として得られる仮説は、$ h_ theta(x)= theta_0 * x_0 + theta_1 * x_1 $の形式になります。ただし、ほとんどの場合1に等しいため、$ x_0 $の記述を回避できます。
青い線に戻ります。私たちの仮説は$ h(x)= 84 + 1.24x $のように見えます。つまり、$ theta_0 = 84 $および$ theta_1 = 1.24 $です。これらの$ theta $値を自動的に導出するにはどうすればよいですか?
を定義する必要があります コスト関数 。基本的に、コスト関数が行うことは、モデル予測と実際の出力の間の二乗平均平方根誤差を計算することです。
[J( theta)= frac {1} {2m} sum_ {i = 1} ^ m(h_ theta(x ^ {(i)})-y ^ {(i)})^ 2 ]たとえば、私たちの仮説では、48歳の人の場合、血圧は$ h(48)= 84 + 1.24 * 48 = 143mmHg $であると予測しています。ただし、トレーニングサンプルでは、$ 130 mmHg $の値があります。したがって、エラーは$(143-130)^ 2 = 169 $です。次に、トレーニングデータセットのすべてのエントリについてこのエラーを計算し、それを合計する必要があります($ sum_ {i = 1} ^ m(h_ theta(x ^ {(i)})-y ^ {(i )})^ 2 $)そしてそれから平均値を取ります。
これにより、関数のコストを表す単一のスカラー数が得られます。私たちの目標は、コスト関数が最小になるような$ theta $値を見つけることです。つまり、コスト関数を最小化する必要があります。これは、うまくいけば直感的に見えるでしょう。コスト関数の値が小さい場合、これは予測の誤差も小さいことを意味します。
import numpy as np # Let's calculate the cost for the hypothesis above h = lambda x, theta_0, theta_1: theta_0 + theta_1 * x def cost(X, y, t0, t1): m = len(X) # the number of the training samples c = np.power(np.subtract(h(X, t0, t1), y), 2) return (1 / (2 * m)) * sum(c) X = dataset.values[:, 0] y = dataset.values[:, 1] print('J(Theta) = %2.2f' % cost(X, y, 84, 1.24))
J(Theta) = 1901.95
ここで、$ theta $の値を見つける必要があります。 コスト関数 値は最小です。しかし、どうすればそれを行うことができますか?
[minJ( theta)= frac {1} {2m} sum_ {i = 1} ^ m(h_ theta(x ^ {(i)})-y ^ {(i)})^ 2 ]考えられるアルゴリズムはいくつかありますが、最も一般的なのは 最急降下法 。最急降下法の背後にある直感を理解するために、最初にそれをグラフにプロットしましょう。簡単にするために、より単純な仮説$ h( theta)= theta_1 * x $を仮定します。次に、$ x $が$ theta $の値であり、$ y $がこの時点でのコスト関数である単純な2Dチャートをプロットします。
import matplotlib.pyplot as plt fig = plt.figure() # Generate the data theta_1 = np.arange(-10, 14, 0.1) J_cost = [] for t1 in theta_1: J_cost += [ cost(X, y, 0, t1) ] plt.plot(theta_1, J_cost) plt.xlabel(r'$ heta_1$') plt.ylabel(r'$J( heta)$') plt.show()
コスト関数は凸関数です。つまり、区間$ [a、b] $には最小値が1つだけあります。これもまた、最良の$ theta $パラメータは、コスト関数が最小になるポイントにあることを意味します。
基本的に、最急降下法は、関数を最小化するパラメーターのセットを見つけようとするアルゴリズムです。これは、パラメーターの初期セットから始まり、関数勾配の負の方向に繰り返しステップを実行します。
特定の点で仮説関数の導関数を計算すると、その点での曲線の接線の傾きが得られます。これは、グラフ上のすべての点で勾配を計算できることを意味します。
アルゴリズムが機能する方法は次のとおりです。
ここで、収束条件はアルゴリズムの実装に依存します。 50ステップ後、何らかのしきい値の後、またはその他の方法で停止する場合があります。
import math # Example of the simple gradient descent algorithm taken from Wikipedia cur_x = 2.5 # The algorithm starts at point x gamma = 0.005 # Step size multiplier precision = 0.00001 previous_step_size = cur_x df = lambda x: 2 * x * math.cos(x) # Remember the learning curve and plot it while previous_step_size > precision: prev_x = cur_x cur_x += -gamma * df(prev_x) previous_step_size = abs(cur_x - prev_x) print('The local minimum occurs at %f' % cur_x)
The local minimum occurs at 4.712194
この記事では、これらのアルゴリズムを実装しません。代わりに、広く採用されているオープンソースのPython機械学習ライブラリであるscikit-learn
を利用します。さまざまなデータマイニングや機械学習の問題に非常に役立つAPIを多数提供します。
from sklearn.linear_model import LinearRegression # LinearRegression uses the gradient descent method # Our data X = dataset[['Age']] y = dataset[['Pressure']] regr = LinearRegression() regr.fit(X, y) # Plot outputs plt.xlabel('Age') plt.ylabel('Blood pressure') plt.scatter(X, y, color='black') plt.plot(X, regr.predict(X), color='blue') plt.show() plt.gcf().clear()
print( 'Predicted blood pressure at 25 y.o. = ', regr.predict(25) ) print( 'Predicted blood pressure at 45 y.o. = ', regr.predict(45) ) print( 'Predicted blood pressure at 27 y.o. = ', regr.predict(27) ) print( 'Predicted blood pressure at 34.5 y.o. = ', regr.predict(34.5) ) print( 'Predicted blood pressure at 78 y.o. = ', regr.predict(78) )
Predicted blood pressure at 25 y.o. = [[ 122.98647692]] Predicted blood pressure at 45 y.o. = [[ 142.40388395]] Predicted blood pressure at 27 y.o. = [[ 124.92821763]] Predicted blood pressure at 34.5 y.o. = [[ 132.20974526]] Predicted blood pressure at 78 y.o. = [[ 174.44260555]]
機械学習の問題でデータを操作するときは、さまざまな種類のデータを認識することが重要です。数値(連続または離散)、カテゴリ、または順序データがある場合があります。
数値データ 測定としての意味があります。たとえば、年齢、体重、人が所有するビットコインの数、または人が1か月に書くことができる記事の数などです。数値データはさらに離散型と連続型に分類できます。
カテゴリデータ 人の性別、婚姻状況、国などの値を表します。このデータは数値を取ることができますが、これらの数値には数学的な意味はありません。それらを一緒に追加することはできません。
順序データ カテゴリは数学的に意味のある方法で番号を付けることができるという点で、他の2つのタイプを組み合わせることができます。一般的な例は評価です。多くの場合、1から10のスケールで評価するように求められ、整数のみが許可されます。これを数値的に使用することはできますが(たとえば、何かの平均評価を見つけるために)、機械学習手法を適用する場合、データをカテゴリであるかのように扱うことがよくあります。
線形回帰は、特定のサイズと部屋数の家の価格などの数値を予測するのに役立つ素晴らしいアルゴリズムです。ただし、次のような質問への回答を得るために、カテゴリデータを予測したい場合もあります。
あるいは:
これらの質問はすべて、 分類問題 。そして、最も単純な分類アルゴリズムはと呼ばれます ロジスティック回帰 、最終的にはと同じです 線形 異なる仮説があることを除いて、回帰。
まず、同じ線形仮説$ h_ theta(x)= theta ^ T X $を再利用できます(これはベクトル化された形式です)。線形回帰は区間$ [a、b] $内の任意の数を出力できますが、ロジスティック回帰は$ [-1、1] $の値のみを出力できます。これは、オブジェクトが特定のカテゴリに分類されるかどうかの確率です。
を使って シグモイド関数 、任意の数値を変換して、区間$ [-1、1] $の値を表すことができます。
[f(x)= frac {1} {1 + e ^ x} ]ここで、$ x $の代わりに、既存の仮説を渡す必要があるため、次のようになります。
[f(x)= frac {1} {1 + e ^ { theta_0 + theta_1 * x_1 + ... + theta_n * x_n}} ]その後、仮説がゼロより大きい場合、これは真の値であり、そうでない場合は偽であるという単純なしきい値を適用できます。
[h_ theta(x)= begin {cases} 1& mbox {if} theta ^ T X> 0 \ 0& mbox {else} end {cases} ]これは、同じものを使用できることを意味します コスト関数 ロジスティック回帰の仮説を学習するための同じ勾配降下アルゴリズム。
次の機械学習アルゴリズムの例では、スペースシャトルのパイロットに、自動または手動の着陸制御を使用するかどうかをアドバイスします。我々は持っています 非常に小さなデータセット —15サンプル—6つの機能と グラウンドトゥルース 。
機械学習アルゴリズムでは、「 グラウンドトゥルース 」とは、教師あり学習手法に対するトレーニングセットの分類の精度を指します。
データセットは完全です。つまり、不足している機能はありません。ただし、一部の機能にはカテゴリの代わりに「*」が付いています。これは、この機能が重要ではないことを意味します。このようなアスタリスクはすべてゼロに置き換えます。
from sklearn.linear_model import LogisticRegression # Data data_path = os.path.join(os.getcwd(), 'data/shuttle-landing-control.csv') dataset = read_csv(data_path, header=None, names=['Auto', 'Stability', 'Error', 'Sign', 'Wind', 'Magnitude', 'Visibility'], na_values='*').fillna(0) # Prepare features X = dataset[['Stability', 'Error', 'Sign', 'Wind', 'Magnitude', 'Visibility']] y = dataset[['Auto']].values.reshape(1, -1)[0] model = LogisticRegression() model.fit(X, y) # For now, we're missing one important concept. We don't know how well our model # works, and because of that, we cannot really improve the performance of our hypothesis. # There are a lot of useful metrics, but for now, we will validate how well # our algorithm performs on the dataset it learned from. 'Score of our model is %2.2f%%' % (model.score(X, y) * 100)
Score of our model is 73.33%
前の例では、学習データを使用してモデルのパフォーマンスを検証しました。ただし、アルゴリズムがデータを過適合または過適合にする可能性があることを考えると、これは現在、適切なオプションですか?家のサイズを表す1つの機能と、その価格を表す別の機能がある場合の、より簡単な例を見てみましょう。
from sklearn.pipeline import make_pipeline from sklearn.preprocessing import PolynomialFeatures from sklearn.linear_model import LinearRegression from sklearn.model_selection import cross_val_score # Ground truth function ground_truth = lambda X: np.cos(15 + np.pi * X) # Generate random observations around the ground truth function n_samples = 15 degrees = [1, 4, 30] X = np.linspace(-1, 1, n_samples) y = ground_truth(X) + np.random.randn(n_samples) * 0.1 plt.figure(figsize=(14, 5)) models = {} # Plot all machine learning algorithm models for idx, degree in enumerate(degrees): ax = plt.subplot(1, len(degrees), idx + 1) plt.setp(ax, xticks=(), yticks=()) # Define the model polynomial_features = PolynomialFeatures(degree=degree) model = make_pipeline(polynomial_features, LinearRegression()) models[degree] = model # Train the model model.fit(X[:, np.newaxis], y) # Evaluate the model using cross-validation scores = cross_val_score(model, X[:, np.newaxis], y) X_test = X plt.plot(X_test, model.predict(X_test[:, np.newaxis]), label='Model') plt.scatter(X, y, edgecolor='b', s=20, label='Observations') plt.xlabel('x') plt.ylabel('y') plt.ylim((-2, 2)) plt.title('Degree {}
MSE = {:.2e}'.format( degree, -scores.mean())) plt.show()
機械学習アルゴリズムモデルは アンダーフィッティング トレーニングデータも新しい観測も一般化できない場合。上記の例では、実際のトレーニングデータセットを実際には表しておらず、パフォーマンスが非常に低い単純な線形仮説を使用しています。通常、アンダーフィッティングは、適切なメトリックがあれば簡単に検出できるため、説明されていません。
アルゴリズムが表示されたすべての観測値を記憶している場合、トレーニングデータセット外の新しい観測値ではパフォーマンスが低下します。これは 過剰適合 。たとえば、30次多項式モデルはほとんどのポイントを通過し、トレーニングセットで非常に良いスコアを持ちますが、それ以外のものはパフォーマンスが低下します。
私たちのデータセットは1つの特徴で構成されており、2D空間で簡単にプロットできます。ただし、実際には、何百もの特徴を持つデータセットが存在する可能性があるため、ユークリッド空間で視覚的にプロットすることは不可能です。モデルが過適合か過適合かを確認するために、他にどのようなオプションがありますか?
の概念を紹介する時が来ました 学習曲線 。これは、トレーニングサンプルの数に対する平均二乗誤差をプロットした単純なグラフです。
学習教材では、通常、次のようなグラフが表示されます。
ただし、実際には、このような完璧な画像が得られない場合があります。各モデルの学習曲線をプロットしてみましょう。
from sklearn.model_selection import learning_curve, ShuffleSplit # Plot learning curves plt.figure(figsize=(20, 5)) for idx, degree in enumerate(models): ax = plt.subplot(1, len(degrees), idx + 1) plt.title('Degree {}'.format(degree)) plt.grid() plt.xlabel('Training examples') plt.ylabel('Score') train_sizes = np.linspace(.6, 1.0, 6) # Cross-validation with 100 iterations to get a smoother mean test and training # score curves, each time with 20% of the data randomly selected as a validation set. cv = ShuffleSplit(n_splits=100, test_size=0.2, random_state=0) model = models[degree] train_sizes, train_scores, test_scores = learning_curve( model, X[:, np.newaxis], y, cv=cv, train_sizes=train_sizes, n_jobs=4) train_scores_mean = np.mean(train_scores, axis=1) test_scores_mean = np.mean(test_scores, axis=1) plt.plot(train_sizes, train_scores_mean, 'o-', color='r', label='Training score') plt.plot(train_sizes, test_scores_mean, 'o-', color='g', label='Test score') plt.legend(loc = 'best') plt.show()
シミュレートされたシナリオでは、トレーニングスコアを表す青い線は直線のように見えます。実際には、それでもわずかに減少します。これは1次多項式グラフで実際に確認できますが、他のグラフでは微妙すぎてこの解像度で判断できません。少なくとも、「高バイアス」シナリオでのトレーニングとテスト観測の学習曲線の間に大きなギャップがあることがはっきりとわかります。
中央の「通常の」学習率グラフでは、トレーニングスコアとテストスコアの線がどのように組み合わされているかを確認できます。
また、「高分散」グラフでは、サンプル数が少ない場合、テストとトレーニングのスコアが非常に似ていることがわかります。ただし、サンプル数を増やすと、トレーニングスコアはほぼ完全なままですが、テストスコアはそれから離れていきます。
不適合モデル(モデルと呼ばれる)を修正できます 高バイアス )非線形仮説を使用する場合、たとえば、より多くの多項式特徴を持つ仮説。
私たちの過剰適合モデル( 高分散 )示されているすべての例を通過します。ただし、テストデータを導入すると、学習曲線間のギャップが広がります。正則化、交差検定、およびその他のデータサンプルを使用して、過剰適合モデルを修正できます。
過剰適合を回避するための一般的な方法の1つは、利用可能なデータの一部を保持し、それをテストセットとして使用することです。ただし、多項式の特徴の数など、さまざまなモデル設定を評価する場合、最適な推定量のパフォーマンスを達成するためにパラメーターを調整できるため、テストセットが過剰適合するリスクがあります。そのため、テストセットに関する知識がモデルに漏れます。この問題を解決するには、「検証セット」と呼ばれるデータセットのもう1つの部分を保持する必要があります。トレーニングはトレーニングセットで進行し、最適なモデルパフォーマンスが達成されたと判断した場合、検証セットを使用して最終評価を行うことができます。
ただし、使用可能なデータを3つのセットに分割することにより、モデルのトレーニングに使用できるサンプルの数が大幅に削減され、結果は、トレーニングと検証のセットのペアに対する特定のランダムな選択に依存する可能性があります。
この問題の1つの解決策は、相互検証と呼ばれる手順です。標準の$ k $フォールド交差検定では、データをフォールドと呼ばれる$ k $サブセットに分割します。次に、残りのフォールドをテストセットとして使用しながら、$ k-1 $フォールドでアルゴリズムを繰り返しトレーニングします(「ホールドアウトフォールド」と呼ばれます)。
相互検証により、元のトレーニングセットのみでパラメーターを調整できます。これにより、最終モデルを選択するための真に目に見えないデータセットとしてテストセットを保持できます。
次のような相互検証手法は他にもたくさんあります。 Pを除外する 、 層化$ k $ -fold 、 シャッフルして分割 などですが、この記事の範囲を超えています。
これは、モデルの過剰適合の問題を解決するのに役立つもう1つの手法です。ほとんどのデータセットには、パターンとノイズがあります。正則化の目的は、モデルに対するノイズの影響を減らすことです。
ラッソ、ティホノフ、エラスティックネットの3つの主要な正則化手法があります。
L1正則化 (または ラッソ正則化 )は、最終モデルで何の役割も果たさないように、ゼロに縮小するいくつかの機能を選択します。 L1は、重要な機能を選択する方法と見なすことができます。
L2正則化 (または ティホノフ正則化 )強制します すべて モデルへの影響が少ないように、機能を比較的小さくします。
エラスティックネット それは 組み合わせ L1とL2の。
特徴のスケーリングも、データを前処理する際の重要なステップです。データセットには、値が$ [- infty、 infty] $のフィーチャと、スケールが異なるその他のフィーチャが含まれている場合があります。これは、独立した値の範囲を標準化する方法です。
機能のスケーリングも、学習モデルのパフォーマンスを向上させるための重要なプロセスです。まず、すべてのフィーチャが同じ基準にスケーリングされている場合、最急降下法ははるかに速く収束します。また、サポートベクターマシン(SVM)などの多くのアルゴリズムは2点間の距離を計算することで機能し、フィーチャの1つに広い値がある場合、距離はこのフィーチャの影響を大きく受けます。
SVMは、分類と回帰の問題に使用できる、さらに広く普及している機械学習アルゴリズムです。 SVMでは、各観測値を$ n $次元空間内の点としてプロットします。ここで、$ n $は私たちが持っている特徴の数です。各フィーチャの値は、特定の座標の値です。次に、2つのクラスを十分に分離する超平面を見つけようとします。
最適な超平面を特定した後、マージンを追加します。これにより、2つのクラスがさらに分離されます。
ロボットのプログラミング方法
SVMは、特徴の数が非常に多い場合、または特徴の数がデータサンプルの数よりも多い場合に非常に効果的です。ただし、SVMはベクトルベースで動作するため、使用する前にデータを正規化することが重要です。
ニューラルネットワークアルゴリズムは、おそらく機械学習研究の最もエキサイティングな分野です。ニューラルネットワークは、脳のニューロンがどのように接続されているかを模倣しようとします。
これがニューラルネットワークの外観です。多くのノードを組み合わせて、各ノードが一連の入力を受け取り、それらにいくつかの計算を適用して、値を出力します。
教師あり学習と教師なし学習の両方に対応するニューラルネットワークアルゴリズムは多種多様です。ニューラルネットワークは、自動運転車の運転、ゲームのプレイ、飛行機の着陸、画像の分類などに使用できます。
RMSタイタニック号は、氷山と衝突した後、1912年4月15日に北大西洋に沈んだ英国の客船でした。約2,224人の乗組員と乗客がおり、1,500人以上が死亡し、史上最も致命的な商業海事災害の1つとなっています。
これで、分類問題に使用される最も基本的な機械学習アルゴリズムの背後にある直感を理解したので、知識を適用して、タイタニック号に搭乗している人の生存結果を予測できます。
私たちのデータセットはから借りられます Kaggleデータサイエンスコンテストプラットフォーム 。
import os from pandas import read_csv, concat # Load data data_path = os.path.join(os.getcwd(), 'data/titanic.csv') dataset = read_csv(data_path, skipinitialspace=True) dataset.head(5)
PassengerId | 生き残った | Pclass | 名前 | セックス | 年齢 | SibSp | 尊敬 | チケット | するために | キャビン | 着手 | |
0 | 1 | 0 | 3 | ブラウン、オーウェン・ハリス氏 | 男性 | 22.0 | 1 | 0 | A / 5 21171 | 7.2500 | NaN | S |
1 | 2 | 1 | 1 | カミングス、ジョン・ブラッドリー夫人(Florence Briggs Th .. .. | 女性 | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | C |
2 | 3 | 1 | 3 | ヘイッキネン、ミス。ローン | 女性 | 26.0 | 0 | 0 | STON / O2。 3101282 | 7.9250 | NaN | S |
3 | 4 | 1 | 1 | Futrelle、Mrs。JacquesHeath(Lily May Peel) | 女性 | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | S |
4 | 5 | 0 | 3 | アレン、ウィリアム・ヘンリー氏 | 男性 | 35.0 | 0 | 0 | 373450 | 8.0500 | NaN | S |
最初のステップは、データを読み込んで調査することです。 891件のテストレコードがあります。各レコードの構造は次のとおりです。
このデータセットには、数値データとカテゴリデータの両方が含まれています。通常、データをさらに深く掘り下げ、それに基づいて仮定を立てることをお勧めします。ただし、この場合、このステップをスキップして、予測に直接進みます。
import pandas as pd # We need to drop some insignificant features and map the others. # Ticket number and fare should not contribute much to the performance of our models. # Name feature has titles (e.g., Mr., Miss, Doctor) included. # Gender is definitely important. # Port of embarkation may contribute some value. # Using port of embarkation may sound counter-intuitive; however, there may # be a higher survival rate for passengers who boarded in the same port. dataset['Title'] = dataset.Name.str.extract(' ([A-Za-z]+).', expand=False) dataset = dataset.drop(['PassengerId', 'Ticket', 'Cabin', 'Name'], axis=1) pd.crosstab(dataset['Title'], dataset['Sex'])
タイトルセックス | 女性 | 男性 |
大尉 | 0 | 1 |
とともに | 0 | 2 |
伯爵夫人 | 1 | 0 |
ドン | 0 | 1 |
博士 | 1 | 6 |
ヨンクヘール | 0 | 1 |
レディ | 1 | 0 |
メジャー | 0 | 2 |
主人 | 0 | 40 |
お嬢 | 182 | 0 |
MS | 2 | 0 |
夫人 | 1 | 0 |
氏 | 0 | 517 |
夫人 | 125 | 0 |
MS | 1 | 0 |
改訂 | 0 | 6 |
お客様 | 0 | 1 |
# We will replace many titles with a more common name, English equivalent, # or reclassification dataset['Title'] = dataset['Title'].replace(['Lady', 'Countess','Capt', 'Col', 'Don', 'Dr', 'Major', 'Rev', 'Sir', 'Jonkheer', 'Dona'], 'Other') dataset['Title'] = dataset['Title'].replace('Mlle', 'Miss') dataset['Title'] = dataset['Title'].replace('Ms', 'Miss') dataset['Title'] = dataset['Title'].replace('Mme', 'Mrs') dataset[['Title', 'Survived']].groupby(['Title'], as_index=False).mean()
題名 | 生き残った | |
0 | 主人 | 0.575000 |
1 | お嬢 | 0.702703 |
2 | 氏 | 0.156673 |
3 | 夫人 | 0.793651 |
4 | その他 | 0.347826 |
# Now we will map alphanumerical categories to numbers title_mapping = { 'Mr': 1, 'Miss': 2, 'Mrs': 3, 'Master': 4, 'Other': 5 } gender_mapping = { 'female': 1, 'male': 0 } port_mapping = { 'S': 0, 'C': 1, 'Q': 2 } # Map title dataset['Title'] = dataset['Title'].map(title_mapping).astype(int) # Map gender dataset['Sex'] = dataset['Sex'].map(gender_mapping).astype(int) # Map port freq_port = dataset.Embarked.dropna().mode()[0] dataset['Embarked'] = dataset['Embarked'].fillna(freq_port) dataset['Embarked'] = dataset['Embarked'].map(port_mapping).astype(int) # Fix missing age values dataset['Age'] = dataset['Age'].fillna(dataset['Age'].dropna().median()) dataset.head()
生き残った | Pclass | セックス | 年齢 | SibSp | 尊敬 | するために | 着手 | 題名 | |
0 | 0 | 3 | 0 | 22.0 | 1 | 0 | 7.2500 | 0 | 1 |
1 | 1 | 1 | 1 | 38.0 | 1 | 0 | 71.2833 | 1 | 3 |
2 | 1 | 3 | 1 | 26.0 | 0 | 0 | 7.9250 | 0 | 2 |
3 | 1 | 1 | 1 | 35.0 | 1 | 0 | 53.1000 | 0 | 3 |
4 | 0 | 3 | 0 | 35.0 | 0 | 0 | 8.0500 | 0 | 1 |
この時点で、scikit-learn
を使用して、Pythonでさまざまなタイプの機械学習アルゴリズムをランク付けします。さまざまなモデルのセットを作成します。そうすれば、どれが最高のパフォーマンスを発揮するかを簡単に確認できます。
すべてのモデルについて、$ k $ -fold検証を使用します。
from sklearn.model_selection import KFold, train_test_split from sklearn.pipeline import make_pipeline from sklearn.preprocessing import PolynomialFeatures, StandardScaler from sklearn.neural_network import MLPClassifier from sklearn.svm import SVC # Prepare the data X = dataset.drop(['Survived'], axis = 1).values y = dataset[['Survived']].values X = StandardScaler().fit_transform(X) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state = None) # Prepare cross-validation (cv) cv = KFold(n_splits = 5, random_state = None) # Performance p_score = lambda model, score: print('Performance of the %s model is %0.2f%%' % (model, score * 100)) # Classifiers names = [ 'Logistic Regression', 'Logistic Regression with Polynomial Hypotheses', 'Linear SVM', 'RBF SVM', 'Neural Net', ] classifiers = [ LogisticRegression(), make_pipeline(PolynomialFeatures(3), LogisticRegression()), SVC(kernel='linear', C=0.025), SVC(gamma=2, C=1), MLPClassifier(alpha=1), ]
# iterate over classifiers models = [] trained_classifiers = [] for name, clf in zip(names, classifiers): scores = [] for train_indices, test_indices in cv.split(X): clf.fit(X[train_indices], y[train_indices].ravel()) scores.append( clf.score(X_test, y_test.ravel()) ) min_score = min(scores) max_score = max(scores) avg_score = sum(scores) / len(scores) trained_classifiers.append(clf) models.append((name, min_score, max_score, avg_score)) fin_models = pd.DataFrame(models, columns = ['Name', 'Min Score', 'Max Score', 'Mean Score'])
fin_models.sort_values(['Mean Score']).head()
名前 | 私の点数 | 最大スコア | 平均スコア | |
2 | 線形SVM | 0.793296 | 0.821229 | 0.803352 |
0 | ロジスティック回帰 | 0.826816 | 0.860335 | 0.846927 |
4 | ニューラルネット | 0.826816 | 0.860335 | 0.849162 |
1 | 多項式仮説によるロジスティック回帰 | 0.854749 | 0.882682 | 0.869274 |
3 | RBFSVM | 0.843575 | 0.888268 | 0.869274 |
さて、私たちの実験的研究によると、動径基底関数(RBF)カーネルを備えたSVM分類器が最高のパフォーマンスを発揮します。これで、モデルをシリアル化して、本番アプリケーションで再利用できます。
import pickle svm_model = trained_classifiers[3] data_path = os.path.join(os.getcwd(), 'best-titanic-model.pkl') pickle.dump(svm_model, open(data_path, 'wb'))
機械学習は複雑ではありませんが、非常に幅広い研究分野であり、そのすべての概念を理解するには、数学と統計の知識が必要です。
現在、機械学習とディープラーニングは、シリコンバレーで最も注目されているトピックのひとつであり、ほとんどすべての人にとって重要な役割を果たしています。 データサイエンス会社 、主に、音声認識、車両の運転、金融取引など、多くの反復タスクを自動化できるためです。 患者の世話 、 料理 、 マーケティング 、 等々。
これで、この知識を活用して、Kaggleの課題を解決できます。
これは、教師あり機械学習アルゴリズムのごく簡単な紹介でした。幸いなことに、機械学習アルゴリズムに関するオンラインコースや情報はたくさんあります。個人的には、CourseraのAndrewNgのコースから始めることをお勧めします。
機械学習アルゴリズムは、従来のハードコードされたアルゴリズムとは対照的に、統計分析を使用してモデルを自動的に形成します。これにより、データ内のパターンを探し、分類について予測を行うときに、時間の経過とともに進化することができます。
機械学習のアプリケーションはほぼ無限です。単純な天気予報やデータクラスタリングから複雑な特徴学習まで、あらゆるものに使用できます。自動運転と飛行;画像、音声、およびビデオ認識。検索およびレコメンデーションエンジン。患者の診断;もっと。
教師あり分類には、トレーニングデータ用のラベルが必要です。1つの写真は猫で、もう1つの写真は犬です。教師なし分類は、アルゴリズムが共通の特性を見つけてデータ自体を分離する場所です。画像が猫であることを明示的に示すことはありませんが、猫と犬を区別することはできます。
教師あり学習とは、正しい答えが何であるかをアルゴリズムに明示的に伝えることです。これにより、アルゴリズムは、以前に表示されなかったデータの答えを学習して予測できます。教師なし学習は、アルゴリズムがそれ自体で答えを見つけ出さなければならない場所です。
機械学習について学び始めるのに最適な場所は、記事の最後にあるリソースにリンクされている、CourseraのAndrewのNgコースを視聴することです。そこから、Kaggleに挑戦して、さまざまなフレームワークとアプローチについてより良い直感を身に付けてください。
適切なアルゴリズムを選択する際に考慮すべき要素はたくさんあります。データセットのサイズ、データの性質、速度と精度などです。独自の直感を開発するまでは、scikit-learnのような既存のチートシートを使用できます。提供します。