オヌプン機械孊習コヌス。 テヌマ6.暙識の䜜成ず遞択

オヌプンデヌタサむ゚ンスコミュニティがコヌス参加者を歓迎したす


コヌスの䞀環ずしお、すでにいく぀かの重芁な機械孊習アルゎリズムに粟通しおいたす。 ただし、より掗緎されたアルゎリズムずアプロヌチに進む前に、䞀歩螏み蟌んで、モデルトレヌニング甚のデヌタの準備に぀いお話したいず思いたす。 ガベヌゞむン-ガベヌゞアりトのよく知られおいる原則は、すべおの機械孊習タスクに100適甚可胜です。 経隓豊富なアナリストであれば、定性的に準備されたデヌタでトレヌニングされた単玔なモデルが、䞍十分なクリヌンデヌタで構築されたunningなアンサンブルよりも優れおいるこずが刀明した堎合の実践䟋を思い出すこずができたす。


UPD珟圚、コヌスは英語で、 mlcourse.aiずいうブランド名で、Medium に関する蚘事 、Kaggle Dataset およびGitHubに関する資料がありたす 。





今日の蚘事のフレヌムワヌクでは、3぀の類䌌しおいるが異なるタスクを確認したす。



これずは別に、この蚘事では数匏はほずんどないこずに泚意しおください。ただし、比范的倚くのコヌドがありたす。


いく぀かの䟋では、 Two Sigma Connectで䜿甚されるRenthop デヌタセットを䜿甚したすKaggleでの競合物件の照䌚。 この問題では、䞍動産賃貞広告の人気を予枬する必芁がありたす。 分類問題を3぀のクラス['low', 'medium', 'high']たす。 ゜リュヌションを評䟡するには、ログ損倱メトリックが䜿甚されたす小さいほど良い。 Kaggleのアカりントをただお持ちでない方は登録する必芁がありたす。 たた、デヌタをダりンロヌドするには、競争ルヌルに同意する必芁がありたす。


 #        train.json.zip  Kaggle    import json import pandas as pd #     Renthop with open('train.json', 'r') as raw_data: data = json.load(raw_data) df = pd.DataFrame(data) 




特城抜出


人生では、デヌタが既補のマトリックスの圢で提䟛されるこずはめったにないため、すべおのタスクは属性の抜出から始たりたす。 もちろん、csvファむルを読み取っおnumpy.arrayに倉換するだけで十分な堎合もありたすが、これらは幞せな䟋倖です。 特性を抜出する䞀般的なデヌタ型を芋おみたしょう。


テキスト


テキストは、自由圢匏のデヌタの最も明癜な䟋です。 テキストを扱う方法は十分であるため、1぀の蚘事には収たりたせん。 それにもかかわらず、最も人気のあるものを芋おいきたす。


テキストを操䜜する前に、トヌクン化する必芁がありたす。 トヌクン化では、テキストをトヌクンに分割したす。最も単玔な堎合、これらは単なる単語です。 しかし、定期的なスケゞュヌル「額」を単玔にしすぎるず、「ニゞニノノゎロド」は2぀のトヌクンではなく、1぀の意味を倱う可胜性がありたす。 しかし、呌び出しは「スチヌルキル」です。 無駄に2぀のトヌクンに分割できたす。 蚀語の特性を考慮に入れた既補のトヌクナむザヌがありたすが、特に特定のテキスト専門甚語、専門甚語、タむプミスで䜜業しおいる堎合、間違っおいる可胜性がありたす。


ほずんどの堎合、トヌクン化の埌、通垞の圢匏に戻すこずを怜蚎する必芁がありたす。 私たちは語幹凊理および/たたは補題に぀いお話しおいる-これらは単語圢匏を凊理するために䜿甚される同様のプロセスです。 それらの違いに぀いおはこちらをご芧ください 。


したがっお、ドキュメントを䞀連の単語に倉換し、それらをベクトルに倉換し始めるこずができたす。 最も単玔なアプロヌチはBag of Wordsず呌ばれたす。蟞曞長のベクトルを䜜成し、各単語に察しおテキスト内の゚ントリの数をカりントし、この数をベクトル内の察応する䜍眮に眮き換えたす。 コヌドでは、これは蚀葉よりも簡単に芋えたす。


䜙分なラむブラリのないWord of Words
 from functools import reduce import numpy as np texts = [['i', 'have', 'a', 'cat'], ['he', 'have', 'a', 'dog'], ['he', 'and', 'i', 'have', 'a', 'cat', 'and', 'a', 'dog']] dictionary = list(enumerate(set(reduce(lambda x, y: x + y, texts)))) def vectorize(text): vector = np.zeros(len(dictionary)) for i, word in dictionary: num = 0 for w in text: if w == word: num += 1 if num: vector[i] = num return vector for t in texts: print(vectorize(t)) 

たた、このアむデアは写真でよく瀺されおいたす。



これは非垞に単玔な実装です。 実際には、ストップワヌド、蟞曞の最倧サむズ、有効なデヌタ構造通垞、テキストデヌタはスパヌスベクトルに倉換されたすに泚意する必芁がありたす...


Bag of Wordsのようなアルゎリズムを䜿甚するず、テキスト内の語順が倱われたす。぀たり、「i、cow are no」ず「no、i have cows」ずいうテキストは、ベクトル化埌は意味的に反察ですが、同じになりたす。 この問題を回避するには、䞀歩䞋がっおトヌクン化のアプロヌチを倉曎したす。たずえば、N-gramN個の連続した甚語の組み合わせを䜿甚したす。


実際に確認したしょう
 In : from sklearn.feature_extraction.text import CountVectorizer In : vect = CountVectorizer(ngram_range=(1,1)) In : vect.fit_transform(['no i have cows', 'i have no cows']).toarray() Out: array([[1, 1, 1], [1, 1, 1]], dtype=int64) In : vect.vocabulary_ Out: {'cows': 0, 'have': 1, 'no': 2} In : vect = CountVectorizer(ngram_range=(1,2)) In : vect.fit_transform(['no i have cows', 'i have no cows']).toarray() Out: array([[1, 1, 1, 0, 1, 0, 1], [1, 1, 0, 1, 1, 1, 0]], dtype=int64) In : vect.vocabulary_ Out: {'cows': 0, 'have': 1, 'have cows': 2, 'have no': 3, 'no': 4, 'no cows': 5, 'no have': 6} 

たた、単語を操䜜する必芁がないこずにも泚意しおください。堎合によっおは、文字からN-gramを生成できたすたずえば、このようなアルゎリズムでは、関連する単語やタむプミスの類䌌性が考慮されたす。


 In : from scipy.spatial.distance import euclidean In : vect = CountVectorizer(ngram_range=(3,3), analyzer='char_wb') In : n1, n2, n3, n4 = vect.fit_transform(['', '', '', '']).toarray() In : euclidean(n1, n2) Out: 3.1622776601683795 In : euclidean(n2, n3) Out: 2.8284271247461903 In : euclidean(n3, n4) Out: 3.4641016151377544 

Bag of Wordsの抂念の開発コヌパス怜蚎䞭のこのデヌタセット内のすべおのドキュメントにはめったに芋られないが、この特定のドキュメントに存圚する単語は、より重芁かもしれたせん。 次に、䞀般的な䞻題の単語ず区別するために、より狭矩の䞻題の単語の重みを増やすこずは理にかなっおいたす。 このアプロヌチはTF-IDFず呌ばれ、10行で蚘述するこずはできたせん。したがっお、垌望する人はwikiなどの倖郚゜ヌスの詳现に慣れるこずができたす 。 デフォルトのオプションは次のようになりたす。


idft、D= log frac midD middfd、t+1


tfidft、d、D=tft、d timesidft、D


Bag of Wordsの類䌌物は、テキストタスク以倖でも芋぀けるこずができたす。たずえば、私たちが開催しおいるコンテストの Bag of Sites-Catch Me If You Canなどです。 他の䟋アプリの バッグ、むベントのバッグを怜玢できたす 。




このようなアルゎリズムを䜿甚するず、簡単な問題に察する完党に機胜する゜リュヌション、぀たりベヌスラむンを取埗できたす。 ただし、クラシックの愛奜家には、新しいアプロヌチがありたす。 新しいりェヌブの最も䞀般的な方法はWord2Vecですが、代替手段グロヌブ、ファストテキストなどもありたす。


Word2Vecは、Word埋め蟌みアルゎリズムの特殊なケヌスです。 Word2Vecおよび同様のモデルを䜿甚しお、単語を倧芏暡な空間通垞は数癟にベクトル化するだけでなく、それらのセマンティックな近接性を比范するこずもできたす。 ベクトル化されたビュヌの操䜜の叀兞的な䟋キング-男性+女性=クむヌン。




もちろん、このモデルは単語を理解しおいないこずを理解する䟡倀がありたすが、䞀般的なコンテキストで䜿甚される単語が互いに近くに配眮されるようにベクトルを配眮しようずしたす。 これが考慮されおいない堎合、倚くの面癜いこずが発明されたす。䟋えば、察応するベクトルに-1を掛けるこずでヒトラヌの反察を芋぀けたす。


このようなモデルは、ベクトルの座暙が実際に単語のセマンティクスを反映するように、非垞に倧きなデヌタセットでトレヌニングする必芁がありたす。 あなたの問題を解決するために、䟋えばここから事前に蚓緎されたモデルをダりンロヌドできたす。


ちなみに、他の分野バむオむンフォマティクスなどでも同様の方法が䜿甚されおいたす。 最も予期せぬ䜿甚法-food2vec 。


画像


画像の操䜜では、すべおが同時によりシンプルで耇雑になりたす。 より簡単です。倚くの堎合、よく考えられた事前トレヌニング枈みネットワヌクの1぀をたったく考えお䜿甚できないためです。 さらに耇雑なのは、ただ詳现に理解する必芁がある堎合は、このりサギの穎が非垞に深くなるからです。 ただし、最初にたず最初に。


GPUが匱く、「ニュヌラルネットワヌクのルネッサンス」がただ発生しおいなかった圓時、画像から機胜を生成するこずは別の耇雑な分野でした。 写真を䜿甚するには、角床、領域の境界などを定矩する䜎レベルで䜜業する必芁がありたした。 コンピュヌタヌビゞョンの経隓豊富な専門家は、叀いアプロヌチずニュヌラルネットワヌクヒップスタヌの間に倚くの類䌌点を描くこずができたす。特に、珟代のネットワヌクの畳み蟌み局は、 Haarカスケヌドに非垞に䌌おいたす。 この問題を経隓するこずなく、私は公的な情報源から知識を移そうずはしたせん。skimageずSimpleCVラむブラリぞのリンクをいく぀か残しお、私たちの時代に盎行したす。


倚くの堎合、写真に関連するタスクには、ある皮の畳み蟌みネットワヌクが䜿甚されたす。 アヌキテクチャを思い぀いたり、ネットワヌクをれロからトレヌニングしたりするこずはできたせんが、事前にトレヌニングされた最先端のネットワヌクを利甚できたす。その重みはオヌプン゜ヌスからダりンロヌドできたす。 それを圌らの仕事に適応させるために、科孊者たちはいわゆる 埮調敎ネットワヌクの最埌の完党に接続された局が「オフ」になり、それらの代わりに新しい局が远加され、特定のタスク甚に遞択され、ネットワヌクは新しいデヌタでトレヌニングされたす。 ただし、䜕らかの目的で画像を単玔にベクトル化する堎合たずえば、ある皮の非ネットワヌク分類子を䜿甚する堎合-最埌のレむダヌを切り取り、前のレむダヌの出力を䜿甚するだけです


 from keras.applications.resnet50 import ResNet50 from keras.preprocessing import image from scipy.misc import face import numpy as np resnet_settings = {'include_top': False, 'weights': 'imagenet'} resnet = ResNet50(**resnet_settings) img = image.array_to_img(face()) #   ! img = img.resize((224, 224)) #          x = image.img_to_array(img) x = np.expand_dims(x, axis=0) #   , ..        features = resnet.predict(x) 


あるデヌタセットで蚓緎され、最埌のレむダヌを「ティアリング」しお代わりに新しいレむダヌを远加するこずにより、別のデヌタセットに適応した分類子

ただし、ニュヌラルネットワヌクの方法にこだわらないでください。 手で生成される兆候のいく぀かは最近䟿利になりたす。たずえば、アパヌト賃貞広告の人気を予枬する堎合、明るいアパヌトがより泚目を集め、「平均ピクセル倀」の兆候を䜜るず想定できたす。 それぞれのラむブラリのドキュメントの䟋に觊発されたす 。


画像にテキストが必芁な堎合は、たずえばpytesseractを䜿甚しお、耇雑なニュヌラルネットワヌクを自分の手で展開するこずなく読むこずもできたす。


 In : import pytesseract In : from PIL import Image In : import requests In : from io import BytesIO In : img = 'http://ohscurrent.org/wp-content/uploads/2015/09/domus-01-google.jpg' #      In : img = requests.get(img) ...: img = Image.open(BytesIO(img.content)) ...: text = pytesseract.image_to_string(img) ...: In : text Out: 'Google' 

pytesseractは䞇胜薬ずはほど遠いこずを理解する必芁がありたす。


 #       Renthop In : img = requests.get('https://photos.renthop.com/2/8393298_6acaf11f030217d05f3a5604b9a2f70f.jpg') ...: img = Image.open(BytesIO(img.content)) ...: pytesseract.image_to_string(img) ...: Out: 'Cunveztible to 4}»' 

ニュヌラルネットワヌクが圹に立たない別のケヌスは、メタ情報からの兆候の抜出です。 ただし、EXIFには、カメラのメヌカヌずモデル、解像床、フラッシュの䜿甚、撮圱の地理座暙、゜フトりェアの凊理に䜿甚されるものなど、倚くの有甚なものを保存できたす。


ゞオデヌタ


地理デヌタはタスクにはあたり芋られたせんが、特にこの領域には十分な既補の゜リュヌションがあるため、それらを操䜜するための基本的なテクニックを孊ぶこずも圹立ちたす。


ゞオデヌタは、ほずんどの堎合、䜏所たたは「緯床+経床」のペアの圢匏で衚瀺されたす。 ポむント。 タスクによっおは、ゞオコヌディング䜏所からポむントを埩元ずリバヌスゞオコヌディング逆の2぀の操䜜が必芁になる堎合がありたす。 どちらも、GoogleマップやOpenStreetMapなどの倖郚APIを䜿甚しお実行できたす。 さたざたなゞオコヌダヌには独自の特性があり、品質は地域によっお異なりたす。 幞いなこずに、倚くの倖郚サヌビスのラッパヌずしお機胜するgeopyのようなナニバヌサルラむブラリがありたす。


倧量のデヌタがある堎合、倖郚APIの制限に簡単に遭遇したす。 たた、HTTP経由で情報を受信するこずは、垞に最適な速床の゜リュヌションではありたせん。 したがっお、OpenStreetMapのロヌカルバヌゞョンを䜿甚する可胜性を念頭に眮く䟡倀がありたす。


デヌタが倚くなく、十分な時間があり、掗緎された暙識を取埗する必芁がない堎合、OpenStreetMapを䜿甚しおreverse_geocoderを䜿甚するこずはできたせん。


 In : import reverse_geocoder as revgc In : revgc.search((df.latitude, df.longitude)) Loading formatted geocoded file... Out: [OrderedDict([('lat', '40.74482'), ('lon', '-73.94875'), ('name', 'Long Island City'), ('admin1', 'New York'), ('admin2', 'Queens County'), ('cc', 'US')])] 

ゞオコヌディングを䜿甚する堎合、䜏所に入力ミスが含たれおいる可胜性があるこずを忘れないでください。そのため、時間をかけお敎理する䟡倀がありたす。 通垞、座暙のタむプミスは少なくなりたすが、すべおがうたくいくわけではありたせん。GPSは、デヌタの性質によっお、たた䞀郚の堎所トンネル、高局ビルの4分の1 ...で「ノむズ」を発生させるこずがありたす。 デヌタ゜ヌスがモバむルデバむスである堎合、ゞオロケヌションはGPSではなく、地区内のWiFiネットワヌクによっお決定される堎合があり、スペヌスやテレポヌテヌションに぀ながるこずを考慮する䟡倀がありたす。 。


テレポヌテヌション仮説

WiFiロケヌショントラッキングは、SSIDずMACアドレスの組み合わせに基づいおおり、完党に異なるポむントで䞀臎する堎合がありたすたずえば、連邊プロバむダヌはMACアドレスの粟床でルヌタヌのファヌムりェアを暙準化し、異なる郜垂に配眮したす。 ルヌタヌを䜿甚しお䌚瀟を別のオフィスに移動するなど、より䞀般的な理由がありたす。


ポむントは通垞、きれいな分野ではなく、むンフラストラクチャの䞭にありたす-ここでは、想像力を自由に操り、兆候を思い぀き、人生経隓ずドメむン領域の知識を適甚するこずができたす。 ポむントの地䞋鉄ぞの近さ、建物の階数、最寄りの店舗たでの距離、半埄内のATMの数-1぀のタスクの枠組みで、数十の暙識を芋぀けおさたざたな倖郚゜ヌスから取埗できたす。 郜垂むンフラ倖のタスクでは、高床などのより具䜓的な情報源からの暙識が圹立぀堎合がありたす。


2぀以䞊のポむントが盞互接続されおいる堎合、それらの間のルヌトからフィヌチャを抜出する䟡倀がありたす。 ここでは、距離が䟿利です倧圏距離ず、道路グラフに埓っお蚈算された「正盎な」距離を芋る䟡倀がありたす、巊折ず右折の比率に沿ったタヌン数、信号機、むンタヌチェンゞ、橋の数。 たずえば、私のタスクの1぀で、「道路の耇雑さ」ず呌ばれる兆候がよくわかりたした-グラフに埓っお蚈算され、GCDで陀算された距離。


日時


関連する機胜が普及しおいるため、日付ず時刻の凊理は暙準化する必芁がありたすが、萜ずし穎は残っおいたす。


曜日から始めたしょう-ワンホットコヌディングを䜿甚しお、簡単に7぀のダミヌ倉数に倉換できたす。 さらに、週末の別の特性を匷調衚瀺するず䟿利です。


 df['dow'] = df['created'].apply(lambda x: x.date().weekday()) df['is_weekend'] = df['created'].apply(lambda x: 1 if x.date().weekday() in (5, 6) else 0) 

䞀郚のタスクでは、远加のカレンダヌ機胜が必芁になる堎合がありたす。たずえば、珟金の匕き出しは絊料日に結び付けられ、旅行カヌドの賌入は月の初めに結び付けられたす。 たた、䞀時的なデヌタを凊理する堎合、祝日、異垞気象、その他の重芁なむベントを含むカレンダヌを手元に甚意する必芁がありたす。


プロの面癜い笑い
  • 䞭囜の旧正月、ニュヌペヌクマラ゜ン、ゲむプラむドパレヌド、トランプの就任の共通点は䜕ですか
  • それらはすべお、朜圚的な異垞のカレンダヌに远加する必芁がありたす。

しかし、時間分、月の日...ですべおがそれほどバラ色ではありたせん。 時間を実際の倉数ずしお䜿甚する堎合、デヌタの性質ず若干矛盟したす0 <23、ただし02.01 0:00:00> 01.01 23:00:00。 䞀郚のタスクでは、これが重芁になる堎合がありたす。 それらをカテゎリ倉数ずしお゚ンコヌドするず、倚数の蚘号を生成し、近接性に関する情報を倱う可胜性がありたす。22ず23の差は22ず7の差ず同じになりたす。


このようなデヌタには、より難解なアプロヌチがありたす。 たずえば、円ぞの投圱ずそれに続く2぀の座暙の䜿甚。


 def make_harmonic_features(value, period=24): value *= 2 * np.pi / period return np.cos(value), np.sin(value) 

このような倉換は、ポむント間の距離を保持したす。これは、いく぀かの距離ベヌスのアルゎリズムkNN、SVM、k-means ...にずっお重芁です。


 In : from scipy.spatial import distance In : euclidean(make_harmonic_features(23), make_harmonic_features(1)) Out: 0.5176380902050424 In : euclidean(make_harmonic_features(9), make_harmonic_features(11)) Out: 0.5176380902050414 In : euclidean(make_harmonic_features(9), make_harmonic_features(21)) Out: 2.0 

ただし、このような゚ンコヌド方匏の違いは、通垞、メトリックの小数点以䞋3桁でのみ怜出でき、それ以前では怜出できたせん。


時系列、りェブなど


私は時系列を扱うのがあたり楜しくなかったので、時系列からサむンを自動生成するためのラむブラリぞのリンクを残し、さらに先に進みたす。


Webを䜿甚する堎合、通垞、ナヌザヌのナヌザヌ゚ヌゞェントに関する情報がありたす。 これは情報の貯蔵庫です。
たず、そこから、たず、オペレヌティングシステムを抜出する必芁がありたす。 次に、蚘号is_mobileたす。 第䞉に、ブラりザを芋おください。


ナヌザヌ゚ヌゞェントから機胜を取埗する䟋
 In : ua = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/56.0.2924.76 Chrome/ ...: 56.0.2924.76 Safari/537.36' In : import user_agents In : ua = user_agents.parse(ua) In : ua.is_bot Out: False In : ua.is_mobile Out: False In : ua.is_pc Out: True In : ua.os.family Out: 'Ubuntu' In : ua.os.version Out: () In : ua.browser.family Out: 'Chromium' In : ua.os.version Out: () In : ua.browser.version Out: (56, 0, 2924) 

他のドメむンドメむンず同様に、デヌタの性質に関する掚枬に基づいお独自の属性を䜜成できたす。 この蚘事の執筆時点では、Chromium 56は新しく、しばらくしおから、このバヌゞョンのブラりザは、非垞に長い間このブラりザを再起動しおいない人のみが保存できたす。 では、なぜ「最新バヌゞョンのブラりザに遅れをずっおいる」ずいうサむンを導入しないのですか


OSずブラりザに加えお、リファラヌ垞に利甚可胜ずは限りたせん、 http_accept_language 、およびその他のメタ情報を確認できたす。


次に有甚な情報は、少なくずも囜、できれば郜垂、プロバむダヌ、接続タむプモバむル/固定電話を抜出できるIPアドレスです。 さたざたなプロキシず叀いデヌタベヌスがあるため、蚘号にノむズが含たれおいる可胜性があるこずを理解する必芁がありたす。 ネットワヌク管理の達人は、はるかに掗緎された機胜を抜出しようずするこずもできたす 。たずえば、 VPNの䜿甚に぀いお想定するこずです。 ちなみに、IPアドレスのデヌタずhttp_accept_languageを組み合わせるこずをお勧めしたす。ナヌザヌがチリのプロキシに座っおいお、ブラりザヌのロケヌルがru_RUである堎合、テヌブルの察応する列 is_traveler_or_proxy_user にあるナニットに䞍適圓で䟡倀があるものがありたす。


䞀般的に、特定の領域には非垞に倚くのドメむン固有のものがあるため、1぀の頭に収たらない。 したがっお、私は芪愛なる読者に圌らの経隓を共有しお、圌らの仕事でサむンの抜出ず生成に぀いおコメントで䌝えるこずを勧めたす。


フィヌチャ倉換


正芏化ず分垃の倉化


特城の単調な倉換は、䞀郚のアルゎリズムにずっお重芁であり、他のアルゎリズムには圱響したせん。 ちなみに、これが決定朚ずすべおの掟生アルゎリズムランダムフォレスト、募配ブヌスティングの人気の理由の1぀です-誰もが倉換を台無しにする方法を知っおいる/したいわけではありたせんが、これらのアルゎリズムは異垞な分垃に耐性がありたす。


: np.log , np.float64 . , ; - . , . ( ).


, : , : (-1, 1), – .


: , – . 5, .


– Standart Scaling ( Z-score normalization).


z=x–Όσ


StandartScaling ...


 In : from sklearn.preprocessing import StandardScaler In : from scipy.stats import beta In : from scipy.stats import shapiro In : data = beta(1, 10).rvs(1000).reshape(-1, 1) In : shapiro(data) Out: (0.8783774375915527, 3.0409122263582326e-27) #  , p-value In : shapiro(StandardScaler().fit_transform(data)) Out: (0.8783774375915527, 3.0409122263582326e-27) #   p-value        


 -


 In : data = np.array([1, 1, 0, -1, 2, 1, 2, 3, -2, 4, 100]).reshape(-1, 1).astype(np.float64) In : StandardScaler().fit_transform(data) Out: array([[-0.31922662], [-0.31922662], [-0.35434155], [-0.38945648], [-0.28411169], [-0.31922662], [-0.28411169], [-0.24899676], [-0.42457141], [-0.21388184], [ 3.15715128]]) In : (data – data.mean()) / data.std() Out: array([[-0.31922662], [-0.31922662], [-0.35434155], [-0.38945648], [-0.28411169], [-0.31922662], [-0.28411169], [-0.24899676], [-0.42457141], [-0.21388184], [ 3.15715128]]) 

– MinMax Scaling, ( (0, 1)).


Xnorm=X–XminXmax−Xmin


 In : from sklearn.preprocessing import MinMaxScaler In : MinMaxScaler().fit_transform(data) Out: array([[ 0.02941176], [ 0.02941176], [ 0.01960784], [ 0.00980392], [ 0.03921569], [ 0.02941176], [ 0.03921569], [ 0.04901961], [ 0. ], [ 0.05882353], [ 1. ]]) In : (data – data.min()) / (data.max() – data.min()) Out: array([[ 0.02941176], [ 0.02941176], [ 0.01960784], [ 0.00980392], [ 0.03921569], [ 0.02941176], [ 0.03921569], [ 0.04901961], [ 0. ], [ 0.05882353], [ 1. ]]) 

StandartScaling MinMax Scaling - . , , – StandartScaling. MinMax Scaling , (0, 255).


, , , :


 In : from scipy.stats import lognorm In : data = lognorm(s=1).rvs(1000) In : shapiro(data) Out: (0.05714237689971924, 0.0) In : shapiro(np.log(data)) Out: (0.9980740547180176, 0.3150389492511749) 

, , , .. , – . , , , . - ( – -) - , ; , – np.log(x + const) .


-. , – QQ . , .



QQ


QQ
!
 In : import statsmodels.api as sm #   price   Renthop         In : price = df.price[(df.price <= 20000) & (df.price > 500)] In : price_log = np.log(price) In : price_mm = MinMaxScaler().fit_transform(price.values.reshape(-1, 1).astype(np.float64)).flatten() #  ,  sklearn   warning- In : price_z = StandardScaler().fit_transform(price.values.reshape(-1, 1).astype(np.float64)).flatten() In : sm.qqplot(price_log, loc=price_log.mean(), scale=price_log.std()).savefig('qq_price_log.png') In : sm.qqplot(price_mm, loc=price_mm.mean(), scale=price_mm.std()).savefig('qq_price_mm.png') In : sm.qqplot(price_z, loc=price_z.mean(), scale=price_z.std()).savefig('qq_price_z.png') 


QQ



QQ StandartScaler.



QQ MinMaxScaler.



QQ . !


, - . , Renthop, ( - ), .


 In : from demo import get_data In : x_data, y_data = get_data() In : x_data.head(5) Out: bathrooms bedrooms price dishwasher doorman pets \ 10 1.5 3 8.006368 0 0 0 10000 1.0 2 8.606119 0 1 1 100004 1.0 1 7.955074 1 0 1 100007 1.0 1 8.094073 0 0 0 100013 1.0 4 8.116716 0 0 0 air_conditioning parking balcony bike ... stainless \ 10 0 0 0 0 ... 0 10000 0 0 0 0 ... 0 100004 0 0 0 0 ... 0 100007 0 0 0 0 ... 0 100013 0 0 0 0 ... 0 simplex public num_photos num_features listing_age room_dif \ 10 0 0 5 0 278 1.5 10000 0 0 11 57 290 1.0 100004 0 0 8 72 346 0.0 100007 0 0 3 22 345 0.0 100013 0 0 3 7 335 3.0 room_sum price_per_room bedrooms_share 10 4.5 666.666667 0.666667 10000 3.0 1821.666667 0.666667 100004 2.0 1425.000000 0.500000 100007 2.0 1637.500000 0.500000 100013 5.0 670.000000 0.800000 [5 rows x 46 columns] In : x_data = x_data.values In : from sklearn.linear_model import LogisticRegression In : from sklearn.ensemble import RandomForestClassifier In : from sklearn.model_selection import cross_val_score In : from sklearn.feature_selection import SelectFromModel In : cross_val_score(LogisticRegression(), x_data, y_data, scoring='neg_log_loss').mean() /home/arseny/.pyenv/versions/3.6.0/lib/python3.6/site-packages/sklearn/linear_model/base.py:352: RuntimeWarning: overflow encountered in exp np.exp(prob, prob) # , -   ! -  ,    Out: -0.68715971821885724 In : from sklearn.preprocessing import StandardScaler In : cross_val_score(LogisticRegression(), StandardScaler().fit_transform(x_data), y_data, scoring='neg_log_loss').mean() /home/arseny/.pyenv/versions/3.6.0/lib/python3.6/site-packages/sklearn/linear_model/base.py:352: RuntimeWarning: overflow encountered in exp np.exp(prob, prob) Out: -0.66985167834479187 # !  ! In : from sklearn.preprocessing import MinMaxScaler In : cross_val_score(LogisticRegression(), MinMaxScaler().fit_transform(x_data), y_data, scoring='neg_log_loss').mean() ...: Out: -0.68522489913898188 # a    –  :( 

(Interactions)


, ; , .


Two Sigma Connect: Rental Listing Inquires. . , , – , .


 rooms = df["bedrooms"].apply(lambda x: max(x, .5)) #    ; .5      df["price_per_bedroom"] = df["price"] / rooms 

. , , , . , - : , ( )[ https://habrahabr.ru/company/ods/blog/322076/ ] (. sklearn.preprocessing.PolynomialFeatures ) .



" ", . , , . python : pandas.DataFrame.fillna sklearn.preprocessing.Imputer .


. :




- df = df.fillna(0) . : , ; .


(Feature selection)


? - , . : , . , – , . – ( ) , .



– , , .. . , , , . , .


 In : from sklearn.feature_selection import VarianceThreshold In : from sklearn.datasets import make_classification In : x_data_generated, y_data_generated = make_classification() In : x_data_generated.shape Out: (100, 20) In : VarianceThreshold(.7).fit_transform(x_data_generated).shape Out: (100, 19) In : VarianceThreshold(.8).fit_transform(x_data_generated).shape Out: (100, 18) In : VarianceThreshold(.9).fit_transform(x_data_generated).shape Out: (100, 15) 

, .


 In : from sklearn.feature_selection import SelectKBest, f_classif In : x_data_kbest = SelectKBest(f_classif, k=5).fit_transform(x_data_generated, y_data_generated) In : x_data_varth = VarianceThreshold(.9).fit_transform(x_data_generated) In : from sklearn.linear_model import LogisticRegression In : from sklearn.model_selection import cross_val_score In : cross_val_score(LogisticRegression(), x_data_generated, y_data_generated, scoring='neg_log_loss').mean() Out: -0.45367136377981693 In : cross_val_score(LogisticRegression(), x_data_kbest, y_data_generated, scoring='neg_log_loss').mean() Out: -0.35775228616521798 In : cross_val_score(LogisticRegression(), x_data_varth, y_data_generated, scoring='neg_log_loss').mean() Out: -0.44033042718359772 

, . , , , .



: - baseline , . : - "" (, Random Forest) Lasso , . : , .


 from sklearn.datasets import make_classification from sklearn.linear_model import LogisticRegression from sklearn.ensemble import RandomForestClassifier from sklearn.feature_selection import SelectFromModel from sklearn.model_selection import cross_val_score from sklearn.pipeline import make_pipeline x_data_generated, y_data_generated = make_classification() pipe = make_pipeline(SelectFromModel(estimator=RandomForestClassifier()), LogisticRegression()) lr = LogisticRegression() rf = RandomForestClassifier() print(cross_val_score(lr, x_data_generated, y_data_generated, scoring='neg_log_loss').mean()) print(cross_val_score(rf, x_data_generated, y_data_generated, scoring='neg_log_loss').mean()) print(cross_val_score(pipe, x_data_generated, y_data_generated, scoring='neg_log_loss').mean()) -0.184853179322 -0.235652626736 -0.158372952933 

, — .


Renthop.
 x_data, y_data = get_data() x_data = x_data.values pipe1 = make_pipeline(StandardScaler(), SelectFromModel(estimator=RandomForestClassifier()), LogisticRegression()) pipe2 = make_pipeline(StandardScaler(), LogisticRegression()) rf = RandomForestClassifier() print('LR + selection: ', cross_val_score(pipe1, x_data, y_data, scoring='neg_log_loss').mean()) print('LR: ', cross_val_score(pipe2, x_data, y_data, scoring='neg_log_loss').mean()) print('RF: ', cross_val_score(rf, x_data, y_data, scoring='neg_log_loss').mean()) LR + selection: -0.714208124619 LR: -0.669572736183 #   ! RF: -2.13486716798 


, , : "", , , . Exhaustive Feature Selection .


– , . N, N , , N+1 , , . , . Sequential Feature Selection .


: , .


!
 In : selector = SequentialFeatureSelector(LogisticRegression(), scoring='neg_log_loss', verbose=2, k_features=3, forward=False, n_jobs=-1) In : selector.fit(x_data_scaled, y_data) In : selector.fit(x_data_scaled, y_data) [2017-03-30 01:42:24] Features: 45/3 -- score: -0.682830838803 [2017-03-30 01:44:40] Features: 44/3 -- score: -0.682779463265 [2017-03-30 01:46:47] Features: 43/3 -- score: -0.682727480522 [2017-03-30 01:48:54] Features: 42/3 -- score: -0.682680521828 [2017-03-30 01:50:52] Features: 41/3 -- score: -0.68264297879 [2017-03-30 01:52:46] Features: 40/3 -- score: -0.682607753617 [2017-03-30 01:54:37] Features: 39/3 -- score: -0.682570678346 [2017-03-30 01:56:21] Features: 38/3 -- score: -0.682536314625 [2017-03-30 01:58:02] Features: 37/3 -- score: -0.682520258804 [2017-03-30 01:59:39] Features: 36/3 -- score: -0.68250862986 [2017-03-30 02:01:17] Features: 35/3 -- score: -0.682498213174 # ".      ..." ... [2017-03-30 02:21:09] Features: 10/3 -- score: -0.68657335969 [2017-03-30 02:21:18] Features: 9/3 -- score: -0.688405548594 [2017-03-30 02:21:26] Features: 8/3 -- score: -0.690213724719 [2017-03-30 02:21:32] Features: 7/3 -- score: -0.692383588303 [2017-03-30 02:21:36] Features: 6/3 -- score: -0.695321584506 [2017-03-30 02:21:40] Features: 5/3 -- score: -0.698519960477 [2017-03-30 02:21:42] Features: 4/3 -- score: -0.704095390444 [2017-03-30 02:21:44] Features: 3/3 -- score: -0.713788301404 #       

№6


, .


c UCI . Jupyter notebook - , .



Source: https://habr.com/ru/post/J325422/


All Articles