300.000 satır veri, Kobe'nin 20 yıllık kariyerinin Python analizi | Güç Projesi

Yazar | Gao Yang Yang Yang Yang Yang Yang

Kaynak | CSDN Blogu

Baş resmi | Visual China'dan ücretli indirme

Üretildi | CSDN (ID: CSDNnews)

Bir süre önce, Lakers yıldızı Kobe Bryant maalesef öldürüldü. Bu kuşkusuz sayısız taraftar için bir yıldırım, sonunda kaderini değiştirmedi ama kaderi onu hiç değiştirmedi, Mamba ruhu devam edecek. Büyük veri çağının gelişiyle birlikte, her şey üç kelimelik büyük veriye bağlanabilir gibi görünüyor. Uzun zaman önce, büyük veri analizi sporcuların kariyer planlamasında, tıbbi bakımında, finansında vb. Yaygın olarak kullanılıyordu. Bu makalede, Python, yıldız Kobe'nin boyutluluğunu analiz etmek ve "patrona" saygı göstermek için kullanılacak!

Beklenti özeti

O gün, 27 Ocak 2020 sabahının erken sabahıydı. Uykusuzluk geçirdim. Saat 4'e kadar yatakta yuvarlandım ve hala uyuyamadım. Ekranın kilidini açtım, göz kamaştırıcı telefona baktım ve Weibo'yu taramaya çalıştım, ama şok edici bir yanıt aldım. Haber: Kobe yıldızı maalesef öldü. Her zamanki gibi değiştirdim tabii, Sanlian'ı rapor ettim, bu tür bir manşet partisi suçunu hak ediyordu ama resmi haberi görene kadar daha fazla benzer haberler aldım.

Metin yazarımın dediği gibi, Los Angeles'ı sabah dörtte görmedim, ama 1978-2020 sabahı dörtte öldüğünüzün haberini duydum.

Hayranlar olarak yapabileceğimiz tek şey pişmanlık duymak ve hatırlamak. Söylenti yok, "Mamba Ruhu" tüketimi yok

Veri toplama

Kaynak: Kobe Bryant'ın NBA tarafından sağlanan son 20 yıldaki kariyer verileri koleksiyonu (veri miktarı nispeten büyük, yaklaşık 30.000 satır)

veri işleme

Belgeye bakarken, birçok eksik değer olduğunu bulmak zor değildir.Basit ve kaba yol, boş değerleri olan satırları doğrudan silmektir, ancak numunenin bütünlüğü ve tahmin edilen sonuçların doğruluğu için.

Her şeyden önce, atış mesafesinde basit bir aykırı değer tespiti yapıyoruz, işte bir kutu çizimi sunumu

1 # - * - kodlama: utf-8 - * - 2catering_sale = '2.csv' 3data = pd.read_csv (catering_sale, index_col = 'shot_id') # Verileri okuyun ve dizin sütunu olarak "shot_id" sütununu belirtin 45import matplotlib.pyplot as plt #Import image library 6plt.rcParams = # Çince etiketleri normal şekilde görüntülemek için kullanılır 7plt.rcParams = False # Negatif işaretini normal şekilde görüntülemek için kullanılır 8 # 9plt.figure #Create image 10p = data.boxplot (return_type = 'dict') # Çizim kutusu grafiği, doğrudan DataFrame yöntemini kullanın 11x = p.get_xdata # 'sinekler' aykırı değerin etiketidir 12y = p.get_ydata 13y.sort # Küçükten büyüğe sıralama, bu yöntem doğrudan orijinal nesneyi değiştirir 14print ('Aykırı değerlerin sayısı () olan toplam 30687 veri'. Format (len (y))) 1516 # Açıklama ile açıklama ekleyin 17 # Benzer noktalardan bazıları ek açıklamalarda örtüşecektir, bu görülmesi zor ve kontrol edilmesi bazı beceriler gerektirir. 18 Aralıktaki i için (len (x)): 20 eğer ben > 0: 21 plt.annotate (y , xy = (x , y ), xytext = (x +0,05 -0,8 / (y -y), y )) 22 başka: 23 plt.annotate (y , xy = (x , y ), xytext = (x + 0,08, y )) yirmi dört 25plt.show # Show box plot

Bu sonucu alacağız:

Yargılamaya göre, bu veri sütununda 68 aykırı değer vardır Burada yapılan işlem, bu aykırı değerlerin bulunduğu satırların silinmesi ve diğer sütun özniteliklerinin aynı olmasıdır.

Veri Entegrasyonu

Verileri içe aktarın, verileri ihtiyaçlarımıza göre birleştirin ve yeni sütun adları ekleyin

1 pandaları pd olarak içe aktar 23 4allData = pd.read_csv ('data.csv') 5data = allData.reset_index 67 # Yeni sütun adı ekleyin 8data = pd.to_datetime (veri) 9data = data.dt.dayofweek 10veri = data.dt.dayofyear 11veri = 60 * veri + veri 12 veri = 60 * (11 veri) + (60 veri) 13veri = (veri < = 4) .astype (int) * (veri-1) * 12 * 60 + ( 14 veri > 4) .astype (int) * ((data-4) * 5 * 60 + 3 * 12 * 60) + veri 1516 inç 17 tanesi: Bir periyodun bitiminden sonraki 18 saniye 19secondsFromPeriodStart Bir dönemin başındaki saniye 20secondsFromGameStart Bir oyunun başlamasından bu yana geçen saniye sayısı yirmi bir''' yirmi iki 23 # Verileri doğrulayın 24print (data.loc)

Operasyonun sonuçları şu şekildedir:

Hala normal görünüyor

Atış denemeleri çizin

Farklı zaman değişikliklerine göre (oyunun başından itibaren) şut girişimi çizelgesi çizmek

Burada matplotlib paketini kullanacağız

1 pandaları pd olarak içe aktar Np olarak 2import numpy 3import matplotlib.pyplot olarak plt 45 6plt.rcParams = (16, 16) 7plt.rcParams = 168binsSizes = 9plt.figure 1011for k, numaralandırmada binSizeInSeconds (binsSizes): 12 timeBins = np.arange (0, 60 * (4 * 12 + 3 * 5), binSizeInSeconds) + 0.0113 denemeAsFunctionOfTime, b = np.histogram (data, bins = timeBins) 1415 maxHeight = max (trytsAsFunctionOfTime) + 3016 barWidth = 0.999 * (timeBins-timeBins) 17 plt.subplot (uzunluk (binsSizes), 1, k + 1) 18 plt.bar (timeBins, trytsAsFunctionOfTime, align = 'edge', width = barWidth) 19 plt.title (str (binSizeInSeconds) + 'ikinci zaman bölmeleri') 20 plt.vlines (x =, ymin = 0, ymax = maxHeight, renkler = 'r') 22 plt.xlim ((- 20, 3200)) 23 plt.ylim ((0, maxHeight)) 24 plt.ylabel ('girişimler') 25plt.xlabel ('zaman') 26plt.show

Etkiye bakın:

Oyunun süresi ilerledikçe Kobe'nin şutlarının giderek artan bir durum gösterdiği görülmektedir.

İsabet oranının bir karşılaştırma tablosu çizin

Burada Kobenin isabet oranının nasıl olduğunu belirlemek için bir karşılaştırma yapacağız

1 # Oyunda, atış doğruluğu zamanın bir fonksiyonu olarak çizilmiştir. 2 # Zamanın bir fonksiyonu olarak doğruluğu çizme 3plt.rcParams = (15, 10) 4plt.rcParams = 165 6binSizeInSeconds = 207timeBins = np.arange (0, 60 * (4 * 12 + 3 * 5), binSizeInSeconds) + 0.018attemptsAsFunctionOfTime, b = np.histogram (data, bins = timeBins) 9madeAttemptsAsFunctionOfTime, b = np.histogram (data.loc, 10 kutu = timeBins) 11attemptsAsFunctionOfTime = 112accuracyAsFunctionOfTime = madeAttemptsAsFunctionOfTime.astype (float) / trytsAsFunctionOfTime 13accuracyAsFunctionOfTime = 0 # Yeterli örneğe sahip olmayan kutularda sıfır doğruluk 1415maxHeight = max (trytsAsFunctionOfTime) + 3016barWidth = 0.999 * (timeBins-timeBins) 1718plt.figure 19plt. Alt konu (2, 1, 1) 20plt.bar (timeBins, trytsAsFunctionOfTime, align = 'edge', width = barWidth); 21plt.xlim ((- 20, 3200)) 22plt.ylim ((0, maxHeight)) yirmi üç 24 # Yukarıdaki şeklin y eksenindeki çekim sayısı 25plt.ylabel ('girişimler') 26plt.title (str (binSizeInSeconds) + 'ikinci zaman bölmeleri') 27plt.vlines (x =, ymin = 0, ymax = maxHeight, renkler = 'r') 29plt. Alt konu (2, 1, 2) 30plt.bar (timeBins, doğrulukAsFunctionOfTime, align = 'kenar', genişlik = barWidth); 31plt.xlim ((- 20, 3200)) 32 # Aşağıdaki şeklin y ekseni isabet oranı 33plt.ylabel ('doğruluk') 34plt.xlabel ('zaman') 35plt.vlines (x =, ymin = 0.0, ymax = 0.7, renkler = 'r') 37plt.show

Nasıl çalıştığını gör

Analiz, Kobenin şut yüzdesinin 0,4 civarında olduğunu gösteriyor, ancak bu istediğimiz etki değil.

Verileri daha fazla araştırmak için bazı algoritmalar kullanmamız gerekiyor.

GMM kümeleme

Peki GMM kümelemesi nedir?

GMM, Gauss Karışım Modeli'nin (veya Gauss Karışım Modeli) kısaltmasıdır. Kaba anlam, tüm dağılımların birden çok Gauss dağılımının bir sonucu olarak kabul edilebilmesidir. Bu şekilde, herhangi bir dağıtım, temsil etmek için birden fazla Gauss dağılımına bölünebilir.

Çünkü doğadaki pek çok fenomenin bir Gauss (yani normal) dağılımı takip ettiğini biliyoruz, ancak gerçekte, bir dağılımı etkileyen birçok neden vardır ve hatta bazıları yapaydır.Belki her bir etkileyen faktör birini belirler. Gauss dağılımı, çoklu etkilerin kombinasyonu çoklu Gauss dağılımlarıdır. (Kişisel anlayış)

Bu nedenle, karma Gauss modelinin kümelenmesi ilkesi: örnekler aracılığıyla K Gauss dağılımlarının beklentisini ve varyansını bulun, ardından K Gauss modeli belirlenir. Kümeleme sürecinde, bir numunenin hangi kategoriye ait olduğunu net olarak belirtmez, ancak bu numunenin belirli bir dağılımdaki olasılığını hesaplar.

Gauss dağılımı genellikle olasılık tahmin algoritması olarak EM algoritması ile birleştirilir.

1 '' ' 2 Şimdi, ön araştırmamıza devam edelim ve Kobe'nin çekimlerinin uzamsal konumunu inceleyelim. 3 Bunu, Kobe'nin atış pozisyonunu kısaca özetlemeye çalışan bir Gauss karışımı modeli oluşturarak başaracağız. 4 Kobe'nin atış pozisyonlarındaki atış girişimlerini kümelemek için GMM'yi kullanın 5 inç 67numGaussian = 138gaussianMixtureModel = mix.GaussianMixture (n_components = numGaussians, covariance_type = 'full', 9 init_params = 'k anlamına gelir', n_init = 50, 10 ayrıntılı = 0, random_state = 5) 11gaussianMixtureModel.fit (data.loc) 1213 # GMM kümesini veri kümesine bir alan olarak ekleyin 14data = gaussianMixtureModel.predict (data.loc)

Stadyum görselleştirme

Michael Krueger'in mükemmel betiğindeki draw_court işlevine bir referans burada.

draw_court işlevi

1def draw_court (ax = Yok, renk = 'siyah', lw = 2, dış_çizgiler = Yanlış): 2 # Çizim için eksen nesnesi sağlanmadıysa, mevcut nesneyi alın 3 balta Yok ise: 4 balta = plt.gca 56 # Bir NBA sahası oluşturun 7 # bir sepet inşa et 8 # Çap 18, yarıçap 9 Koordinat sisteminde 9 # 7.510 çember = Daire ((0, 0), yarıçap = 7,5, çizgi genişliği = lw, renk = renk, dolgu = Yanlış) 1112 # Sepet oluştur 13 arkalık = Dikdörtgen ((- 30, -7.5), 60, -1, linewidth = lw, color = color) 1415 # Boya 16 # Stadyumun dışını renklendirin, genişlik = 16ft, yükseklik = 19ft 17 external_box = Dikdörtgen ((- 80, -47.5), 160, 190, linewidth = lw, renk = renk, 18 doldurma = Yanlış) 19 # Stadyumun içini renklendirin, genişlik = 12ft, yükseklik = 19ft 20 inner_box = Dikdörtgen ((- 60, -47.5), 120, 190, linewidth = lw, renk = renk, 21 doldurma = Yanlış) yirmi iki yirmi üç 24 # Servisin en iyi yayını oluşturun 25 top_free_throw = Yay ((0, 142.5), 120, 120, theta1 = 0, theta2 = 180, 26 satır genişliği = lw, renk = renk, dolgu = Yanlış) 2728 # Alt hizmet yayını oluşturun 29 bottom_free_throw = Yay ((0, 142.5), 120, 120, theta1 = 180, theta2 = 0, 30 satır genişliği = lw, renk = renk, çizgi stili = 'kesikli') 3132 # Bu, sepetin merkezinden 4 fit yarıçaplı bir yaydır 33 kısıtlanmış = Yay ((0, 0), 80, 80, theta1 = 0, theta2 = 180, linewidth = lw, 34 renk = renk) 3536 # üç noktalı çizgi 37 # 14 fit uzunluğunda 3 punto yan çizgi oluşturun 38 corner_three_a = Dikdörtgen ((- 220, -47.5), 0, 140, linewidth = lw, 39 renk = renk) 40 corner_three_b = Dikdörtgen ((220, -47.5), 0, 140, linewidth = lw, renk = renk) 4142 # Dairenin ortasındaki yay bir halkadır, mesafe 23'9 " 43 # Metalin değerini üç nokta çizgisiyle hizalanana kadar ayarlayın 44 three_arc = Yay ((0, 0), 475, 475, theta1 = 22, theta2 = 158, linewidth = lw, 45 renk = renk) 464748 # Orta saha 49 center_outer_arc = Yay ((0, 422.5), 120, 120, theta1 = 180, theta2 = 0, 50 satır genişliği = lw, renk = renk) 51 center_inner_arc = Yay ((0, 422.5), 40, 40, theta1 = 180, theta2 = 0, 52 satır genişliği = lw, renk = renk) 535455 # Koordinat eksenine çizilecek mahkeme unsurlarının listesi 56 court_elements = 6061 dış_çatalar: 6263 # İlk yarı çizgisini, alt çizgiyi ve yan çizgiyi çizin 64 dış_çiziler = Dikdörtgen ((- 250, -47,5), 500, 470, satır genişliği = lw, 65 renk = renk, dolgu = Yanlış) 66 court_elements.append (dış_satışlar) 676869 # Mahkeme elemanını eksene ekleyin Court_elements içindeki öğe için 70: 71 ax.add_patch (öğe) 7273 dönüş baltası

İki boyutlu Gauss haritası

İki boyutlu bir Gauss diyagramı çizmek için bir fonksiyon oluşturun

Draw2DGausslular

1def Draw2DGaussians (gaussianMixtureModel, ellipseColors, ellipseTextMessages): 2 incir, h = plt. Alt çömlekler 3 i için, (ortalama, kovaryansMatrix) numaralandırmada (zip (gaussianMixtureModel.means_, gaussianMixtureModel.covariances_)): 4 # Kovaryans matrisinin özvektörünü ve özdeğerini alın 5 v, w = np.linalg.eigh (kovaryansMatrix) 6 v = 2.5 * np.sqrt (v) # varyans yerine standart sapma birimlerine git 78 # İki eksenin elips açısını ve uzunluğunu hesaplayın ve çizin 9 u = w / np.linalg.norm (w) 10 açı = np.arctan (u / u) 11 açı = 180 * açı / np.pi # dereceye dönüştür 12 currEllipse = mpl.patches.Ellipse (ortalama, v, v, 180 + açı, renk = elipsColors ) 13 currEllipse.set_alpha (0.5) 14 h.add_artist (currEllipse) 15 h.metin (ortalama + 7, ortalama-1, elipsTextMessages yazı tipi boyutu = 13, renk = 'mavi')

2D Gauss atış frekansı çizelgesi çizmeye başlayalım. Şekildeki her elips, Gauss dağılımının merkezinden 2,5 standart sapma sayılır. Her mavi sayı, Gauss dağılımından gözlemlerin yüzdesini temsil eder.

1 # Gauss karışımı elips atış denemelerini gösteriyor 2plt.rcParams = (13, 10) 3plt.rcParams = 154 5ellipseTextMessages = 6ellipseColors = 8Draw2DGaussians (gaussianMixtureModel, ellipseColors, ellipseTextMessages) 9draw_court (Outer_lines = True) 10plt.ylim (-60, 440) 11plt.xlim (270, -270) 12plt.title ('atış denemeleri') 13plt.show

Sonuçlara bir göz atın:

Renkli 2B Gauss haritasında Kobe'nin sahanın sol tarafında (veya kendi perspektifinden sağ tarafında) daha fazla atış denemesi yaptığını görebiliriz. Bunun nedeni sağ elini kullanması olabilir. Ayrıca çok sayıda (% 16,8) doğrudan potadan şut denemesi yapıldığını ve ek şut denemelerinin% 5,06'sının sepete çok yakından yapıldığını görebiliriz.

Mükemmel görünmüyor, ancak faydalı bir şey gösteriyor

Çizilen her Gauss kümesinin atış doğruluğu için, mavi sayılar bu kümeden elde edilen doğruluğu temsil edecektir, böylece hangisinin kolay ve hangisinin zor olduğunu anlayabiliriz.

Her küme için doğruluğunu ve grafiğini hesaplayın

1plt.rcParams = (13, 10) 2plt.rcParams = 153 4variableCategories = data.value_counts.index.tolist 56clusterAccuracy = {} 7 Değişken kategorilerindeki kategori için: 8 çekim Denendi = np.array (veri == kategori). Toplam 9 shotMade = np.array (data.loc == 1) .sum 10 clusterAccuracy = float (shotsMade) / shotAttempted 1112ellipseTextMessages = 13Draw2DGaussians (gaussianMixtureModel, ellipseColors, ellipseTextMessages) 14draw_court (dış_çizgiler = Doğru) 15plt.ylim (-60, 440) 16plt.xlim (270, -270) 17plt.title ('atış doğruluğu') 18plt.show

Görüntülere bir göz atın

Atış mesafesi ile isabet arasındaki ilişkiyi açıkça görebiliyoruz.

İki boyutlu bir uzay-zaman diyagramı çizin

Bir başka ilginç gerçek: Kobe sadece sağ tarafta (kendi bakış açısından) daha fazla atış denemesi yapmakla kalmadı, aynı zamanda bu atış girişimlerinde de daha iyi.

Şimdi Kobe'nin kariyerinin iki boyutlu bir uzay-zaman haritasını çizelim. X ekseninde, zaman oyunun başlangıcından itibaren zamanlanacaktır; y ekseninde Kobe'nin şutlarının küme indeksi vardır (küme doğruluğuna göre sıralanmıştır); resmin derinliği, Kobe'nin o belirli zamanda o kümeden kaç kez denediğini yansıtacaktır; Resimdeki kırmızı dikey çizgi oyunun her çeyreğini böler

1 # Kobe'nin tüm kariyer oyununun iki boyutlu uzay-zaman histogramını yapın 2plt.rcParams = (18, 10) # Görüntü ekranının boyutunu ayarlayın 3plt.rcParams = 18 # yazı tipi boyutu 45 6 # Doğruluklarına göre sıralayın 7sortedClustersByAccuracyTuple = sıralı (clusterAccuracy.items, key = operator.itemgetter (1), reverse = True) 8sortedClustersByAccuracy = 910binSizeInSeconds = 1211timeInUnitsOfBins = ((veri + 0.0001) / binSizeInSeconds) .astype (int) 12locationInUintsOfClusters = np.array ( 13) 141516 # Kobe oyununun zaman ve mekan histogramını oluşturun 17shotAttempts = np.zeros ((gaussianMixtureModel.n_components, 1 + max (timeInUnitsOfBins))) 18 menzilde çekim için (data.shape): 19 atış Deneme + = 120 yirmi bir 22 # Y ekseninin daha geniş bir alana sahip olmasına izin verin, bu daha açık olacaktır 23shotAttempts = np.kron (shotAttempts, np.ones ((5, 1))) yirmi dört 25 # Her bölümün sonu 26vlinesList = 0,5001 + np.array (). Astype ( 27 int) / binSizeInSeconds 2829plt.figure (figsize = (13, 8)) # Genişliği ve yüksekliği ayarla 30plt.imshow (shotAttempts, cmap = 'copper', interpolation = "en yakın") # Sınırın bulanıklık derecesini veya resmin bulanıklık derecesini ayarlayın 31plt.xlim (0, float (4 * 12 * 60 + 6 * 60) / binSizeInSeconds) 32plt.vlines (x = vlinesList, ymin = -0.5, ymax = shotAttempts.shape-0.5, renkler = 'r') 33plt.xlabel ('oyunun başından itibaren geçen süre') 34plt.ylabel ('küme (doğruluğa göre sıralı)') 35plt.show

Çalışan sonuçlara bakın:

Kümeler azalan hassasiyet sırasına göre sıralanır. Yüksek isabetli atışlar en üstte ve düşük isabetli yarı saha atışları altta. Artık birinci, ikinci ve üçüncü çeyreklerdeki "son saniye atışlarının" aslında çok yüksek seviyelerden olduğunu görebiliyoruz Ancak "Lore" uzakta, ancak 4. çeyrekte, son saniye şutunun "irfanlı" bir şut grubu değil, normal 3 sayılık şut olması ilginçtir (vurulması daha da zor , Ama umutsuz değil).

Gelecek analizde, çekim özelliklerine (atış türü ve atış mesafesi gibi) göre çekimin zorluğunu değerlendireceğiz.

Aşağıdakiler, çekim zorluk modeli için yeni bir tablo oluşturacaktır

1def FactorizeCategoricalVariable (inputDB, categoricalVarName): 2 rakip kategorisi = inputDB.value_counts.index.tolist 34 outputDB = pd.DataFrame Rakip kategorilerdeki kategori için 56 featureName = categoricalVarName + ':' + str (kategori) 7 outputDB = (inputDB == kategori) .astype (int) 89 dönüş çıkışı DB 101112featuresDB = pd.DataFrame 13featuresDB = data.apply (lambda x: 1 if (x.find ('@') < 0) başka 0) 14featuresDB = pd.concat (, eksen = 1) 15featuresDB = pd.concat (, eksen = 1) 16featuresDB = pd.concat (, eksen = 1) 17featuresDB = pd.concat (, eksen = 1) 18featuresDB = pd.concat (, eksen = 1) 19featuresDB = pd.concat (, eksen = 1) 20featuresDB = pd.concat (, eksen = 1) 21featuresDB = pd.concat (, eksen = 1) yirmi iki 23featuresDB = veri 24featuresDB = veri 25featuresDB = veri 26featuresDB = veri 27featuresDB = veri 2829featuresDB = np.sin (2 * np.pi * (veri / 7)) 30featuresDB = np.cos (2 * np.pi * (veri / 7)) 31featuresDB = np.sin (2 * np.pi * (veri / 365)) 32featuresDB = np.cos (2 * np.pi * (veri / 365)) 3334labelsDB = veri

FeaturesDB tablosuna dayalı bir model oluşturun ve bunun üstesinden gelmediğinden emin olun (yani, eğitim hatası, test hatasıyla aynıdır)

Ek bir sınıflandırıcı kullanın

Basit bir model oluşturun ve aşırı yüklenmediğinden emin olun

1randomSeed = 12numFolds = 43 4stratifiedCV = model_selection.StratifiedKFold (n_splits = numFolds, shuffle = True, random_state = randomSeed) 56mainLearner = ensemble.ExtraTreesClassifier (n_estimators = 500, max_depth = 5, 7 min_samples_leaf = 120, max_features = 120, 8 ölçüt = 'entropi', önyükleme = Yanlış, 9 n_jobs = -1, random_state = randomSeed) 1011startTime = time.time 12trainAccuracy = 13validAccuracy = 14trainLogLosses = 15validLogLosses = StratifiedCV.split'de trainInds için, validInds (featuresDB, labelsDB): 17 # Bölünmüş eğitim ve etkili koleksiyon 18 X_train_CV = featuresDB.iloc 19 y_train_CV = labelsDB.iloc 20 X_valid_CV = featuresDB.iloc 21 y_valid_CV = labelsDB.iloc yirmi iki 23 # eğitim 24 mainLearner.fit (X_train_CV, y_train_CV) 2526 # tahmin yapmak 27 y_train_hat_mainLearner = mainLearner.predict_proba (X_train_CV) 28 y_valid_hat_mainLearner = mainLearner.predict_proba (X_valid_CV) 2930 # sonucu kaydet 31 trainAccuracy.append (doğruluk (y_train_CV, y_train_hat_mainLearner > 0.5)) 32 validAccuracy.append (doğruluk (y_valid_CV, y_valid_hat_mainLearner > 0.5)) 33 trainLogLosses.append (log_loss (y_train_CV, y_train_hat_mainLearner)) 34 validLogLosses.append (log_loss (y_valid_CV, y_valid_hat_mainLearner)) 3536baskı ("----------------------------------------------- ------ ") 37print ("toplam (tren, geçerli) Doğruluk = (% .5f,%. 5f).% .2f dakika aldı"% ( 38 np.mean (trainAccuracy), np.mean (validAccuracy), (time.time-startTime) / 60)) 39print ("toplam (tren, geçerli) Günlük Kaybı = (% .5f,%. 5f).% .2f dakika"% ( 40 np.mean (trainLogLosses), np.mean (validLogLosses), (time.time-startTime) / 60)) 41 baskı ("----------------------------------------------- ------ ") 4243mainLearner.fit (featuresDB, labelsDB) 44veri = mainLearner.predict_proba (featuresDB) 4546 # Derinlemesine anlayış için, özellik seçimine bir göz atalım 47featureInds = mainLearner.feature_importances_.argsort 48featureImportance = pd.DataFrame ( 49 np.concatenate ((featuresDB.columns, mainLearner.feature_importances_), 50 eksen = 1), 51 sütun =) 5253print (featureImportance.iloc) ** Nasıl çalıştığını görün **: 1 toplam (tren, geçerli) Doğruluk = (0.67912,0.67860). 0.29 dakika sürdü 2toplam (tren, geçerli) Günlük Kaybı = (0.60812,0.61100). 0.29 dakika sürdü 3 ------------------------------------------------- ---- 4 özellikAdı önemiET 50 action_type: Zıplamalı Atış 0,57803661 action_type: Düzen Çekimi 0.17327472 birleşik_ atış_türü: Dunk 0.11334183 ana oyun 0.028804394 action_type: Dunk Shot 0.0161591105 atış Konum Küme: 90,0136386116 birleşik_resim_türü: Düzen 0.00949568127 mesafeFromBasket 0.0084703138 atış_zone_range: 16-24 ft. 0,0072107149 action_type: Smaç Atışı 0.006903161510 birleşik_ atış_türü: Atlama Atışı 0.005925861611 saniye Başlangıç Periyod Sonu 0,005893911712 action_type: Jump Shot Çalıştırma 0,005449041813 çekim Konum Küme: 110,004491251914 lokY 0.003885092015 action_type: Sürüş Düzeni Çekimi 0,003647572116 shot_zone_range: 8 ft'den az 0,003496152217 birleşik_ atış_türü: Atış İpucu 0,002603992318 shot_zone_area: Merkez (C) 0.00115852419 rakip: DEN 0.0008821062520 action_type: Driving Dunk Shot 0.0008481562621 shot_zone_basic: Sınırlandırılmış Alan 0.0006500222722 atış Konum Küme: 20.0005134762823 action_type: İpucu Shot 0.0004899182924 shot_zone_basic: Orta Aralık 0.0004873063025 action_type: Pullup Jump shot 0.0004536413126 atış_zone_range: 8-16 ft. 0.0004525743227 timeOfYear_cycX 0.0004322673328 dayOfWeek_cycX 0.000396683429 atış Konum Küme: 80.0002540773536 İşlem 0 çıkış koduyla tamamlandı

Burada Kobe Bryant'ın karar verme sürecinden bahsetmek istiyorum; bunun için iki farklı render toplayıp aralarındaki farkları analiz edeceğiz:

  • Başarılı bir atıştan hemen sonra çekime devam edin

  • Başarısız bir atıştan hemen sonra ateş edin

Kobe'nin son golü attığını ya da kaçırdığını düşünerek bazı veriler topladım

1timeBetweenShotsDict = {} 2timeBetweenShotsDict = 3timeBetweenShotsDict = 45changeInDistFromBasketDict = {} 6changeInDistFromBasketDict = 7changeInDistFromBasketDict = 89changeInShotDifficultyDict = {} 10changeInShotDifficultyDict = 11changeInShotDifficultyDict = 1213afterMadeShotsList = 14afterMissedShotsList = 1516 Aralıkta çekim için (1, data.shape): 1718 # Mevcut şutun ve son şutun aynı oyunun aynı zaman diliminde olduğundan emin olun 19 sameGame = data.loc == data.loc 20 samePeriod = data.loc == data.loc yirmi bir 22 eğer samePeriod ve sameGame: 23 madeLastShot = data.loc == 124 missedLastShot = data.loc == 02526 timeDifferenceFromLastShot = data.loc-data.loc 27 distDifferenceFromLastShot = data.loc-data.loc 28 shotDifficultyDifferenceFromLastShot = data.loc-data.loc 2930 # currupt veri noktaları için kontrol (tüm örneklerin kronolojik olarak sıralanması gerektiğini varsayarak) 31 # Verileri kontrol edin (tüm örneklerin zaman sırasına göre düzenlendiğini varsayarak) 32 eğer timeDifferenceFromLastShot < 0: 33 devam 3435 yapılırsa 36 timeBetweenShotsDict.append (timeDifferenceFromLastShot) 37 changeInDistFromBasketDict.append (distDifferenceFromLastShot) 38 changeInShotDifficultyDict.append (shotDifficultyDifferenceFromLastShot) 39 afterMadeShotsList.append (çekim) 4041 Cevapsızsa 42 timeBetweenShotsDict.append (timeDifferenceFromLastShot) 43 changeInDistFromBasketDict.append (distDifferenceFromLastShot) 44 changeInShotDifficultyDict.append (shotDifficultyDifferenceFromLastShot) 45 afterMissedShotsList.append (çekim) 4647afterMissedData = data.iloc 48afterMadeData = data.iloc 4950shotChancesListAfterMade = afterMadeData.tolist 51totalAttemptsAfterMade = afterMadeData.shape 52totalMadeAfterMade = np.array (afterMadeData == 1) .sum 5354shotChancesListAfterMissed = afterMissedData.tolist 55totalAttemptsAfterMissed = afterMissedData.shape 56totalMadeAfterMissed = np.array (afterMissedData == 1) .sum

Histogram

Onlar için "son çekimden bu yana geçen sürenin" histogramını çizin

1plt.rcParams = (13, 10) 23jointHist, timeBins = np.histogram (timeBetweenShotsDict + timeBetweenShotsDict, bins = 200) 4barWidth = 0.999 * (timeBins-timeBins) 56timeDiffHist_GivenMadeLastShot, b = np.histogram (timeBetweenShotsDict, bins = timeBins) 7timeDiffHist_GivenMissedLastShot, b = np.histogram (timeBetweenShotsDict, bins = timeBins) 8maxHeight = max (max (timeDiffHist_GivenMadeLastShot), max (timeDiffHist_GivenMissedLastShot)) + 309 10plt.figure 11plt. Alt konu (2, 1, 1) 12plt.bar (timeBins, timeDiffHist_GivenMadeLastShot, genişlik = barWidth) 13plt.xlim ((0, 500)) 14plt.ylim ((0, maxHeight)) 15plt.title ('son çekim yapıldı') 16plt.ylabel ('sayımlar') 17plt. Alt konu (2, 1, 2) 18plt.bar (timeBins, timeDiffHist_GivenMissedLastShot, genişlik = barWidth) 19plt.xlim ((0, 500)) 20plt.ylim ((0, maxHeight)) 21plt.title ('son çekimi kaçırdı') 22plt.xlabel ('son çekimden beri geçen süre') 23plt.ylabel ('sayımlar') 24plt.show

Çalışan sonuçlara bakın:

Şekilden, Kobe bir top attıktan sonra bir atış yapmak için biraz endişeli olduğu ve şekildeki nispeten düz değerlerden bazıları topun başka bir takımın elinde olması ve onu geri kazanmasının biraz zaman alması şeklinde görülebilmektedir.

Kümülatif histogram

Histogramlar arasındaki farkı daha iyi görselleştirmek için kümülatif histograma bakalım.

1plt.rcParams = (13, 6) 23timeDiffCumHist_GivenMadeLastShot = np.cumsum (timeDiffHist_GivenMadeLastShot) .astype (float) 4timeDiffCumHist_GivenMadeLastShot = timeDiffCumHist_GivenMadeLastShot / max (timeDiffCumHist_GivenMadeLastShot) 5timeDiffCumHist_GivenMissedLastShot = np.cumsum (timeDiffHist_GivenMissedLastShot) .astype (float) 6timeDiffCumHist_GivenMissedLastShot = timeDiffCumHist_GivenMissedLastShot / max (timeDiffCumHist_GivenMissedLastShot) 78maxHeight = max (timeDiffCumHist_GivenMadeLastShot, timeDiffCumHist_GivenMissedLastShot) 910plt.figure 11madePrev = plt.plot (timeBins, timeDiffCumHist_GivenMadeLastShot, label = 'yapılmış Önceki') 12plt.xlim ((0, 500)) 13missedPrev = plt.plot (timeBins, timeDiffCumHist_GivenMissedLastShot, label = 'missed Prev') 14plt.xlim ((0, 500)) 15plt.ylim ((0, 1)) 16plt.title ('kümülatif yoğunluk işlevi-CDF') 17plt.xlabel ('son çekimden beri geçen süre') 18plt.legend (loc = 'sağ alt') 19plt.show

Operasyon etkisi aşağıdaki gibidir:

Yoğunluktaki fark gözlemlenebilse de, net görünmüyor, bu yüzden verileri görüntülemek için Gauss formatına çevirelim

1 # Bir gol yaptıktan ve yendikten sonra şut sayısını gösterir 2plt.rcParams = (13, 10) 34variableCategories = afterMadeData.value_counts.index.tolist 5clusterFrequency = {} 6 Değişken kategorilerindeki kategori için: 7 shotAttempted = np.array (afterMadeData == kategori) .sum 8 clusterFrequency = float (shotsAttempted) / afterMadeData.shape 910ellipseTextMessages = 11Draw2DGaussians (gaussianMixtureModel, ellipseColors, ellipseTextMessages) 12draw_court (Outer_lines = True) 13plt.ylim (-60, 440) 14plt.xlim (270, -270) 15plt.title ('çekimlerden sonra') 1617variableCategories = afterMissedData.value_counts.index.tolist 18clusterFrequency = {} 19 Değişken kategorilerindeki kategori için: 20 çekim Denendi = np.array (afterMissedData == kategori) .sum 21 clusterFrequency = float (shotsAttempted) / afterMissedData.shape yirmi iki 23ellipseTextMessages = 24Draw2DGaussians (gaussianMixtureModel, ellipseColors, ellipseTextMessages) 25draw_court (Outer_lines = True) 26plt.ylim (-60, 440) 27plt.xlim (270, -270) 28plt.title ('kaçırılan çekimlerden sonra') 29plt.show 30

Nihai sonuca bir göz atalım:

sonuç olarak

Kaçırılan bir şuttan sonra, Kobe'nin bir sonraki topu doğrudan potadan atma olasılığının daha yüksek olduğu artık açık. Kobe mavi bir gol attıktan sonra, bir sonraki topun üç sayılık atış yapmaya çalışmasının daha muhtemel olduğu, ancak bu durumda Kobe'nin sıcak bir el etkisi olduğunu kanıtlayacak hiçbir geçerli veri bulunmadığı şekilde de görülebilir. Kobe'nin hala baskette ve serbest atış çizgisi çevresinde kung fu'ya dikkat eden, kendine güvenen, patronumuza layık bir lider olduğunu görmek zor değil!

İyileştirme alanları

Bu sefer elde edilen veri seti çok büyük ve içindeki içerik de çok yeterli.Hatta her çekim pozisyonu ve diziliş duruşuyla ilgili detaylı verileri de içeriyor.Bu verilerde kazılmamış bilgiler için okuyucular ilgilenirlerse bunu yapabilirler. Deneyin, ödüllerle dolu olacağınıza inanıyorum!

Not: Bu analizde bazı problemler olabilir, lütfen beni düzeltin, okuduğunuz için teşekkür ederim.

Orijinal bağlantı: https://blog.csdn.net/weixin_43656359/article/details/104586776

Tokyo salgın verisi açık kaynak aynı gün 2 binin üzerinde yıldız kazandı ve GitHub salgın projeleri akmaya devam ediyor
önceki
Alibaba, Huawei ve Baidu üst üste duruyor, 5G tarifeleri yüksek, işletim sistemi Linux kraldır | Çinli IoT Geliştiricilerinin Gerçek Durum Raporu
Sonraki
Yüzyıllık bir değişimin altında yeniden canlanmanın yolunu keşfetmek - Çin BRICS Düşünce Kuruluşu İşbirliği Konseyi'nin üçüncü yıllık toplantısı yapıldı
Bir çift Çin yemek çubuğunun tetiklediği Çin-Mısır sınır ötesi aşk
"Özgün kalbi unutmayın, misyonu aklınızda tutun" temalı eğitim devam ediyor
Uluslararası toplum, Başkan Xi Jinpingin Yeni Yıl mesajını olumlu değerlendiriyor
"Yıkıcı bir intikam alacağız!"
Altının fiyatı yükselmeye devam ediyor ve altın için boğa piyasası mı geliyor? Biraz satın almak ister misin?
Soğuk dalga süpürüldü! Orta ve doğu bölgelerde uçurum tarzı soğutma, Pekin'in en düşük donma noktası
Fuzhou, Jiangxi, hoş bir bahar manzarasına sahiptir ve turizmi harekete geçirmek için düzenli olarak manzara noktalarının açılması
Lanzhou Sarı Nehir Su Otobüsü yelken açmaya devam ediyor, Minghao "Yüz Yıl Demir Köprü" nü geçiyor
Ne zamandır iyi uyumadın? Uzman: Uykusuzluk, hipertansiyon, anemi ve diğer hastalıkların klinik belirtileri
250 milyon yuan sahte Moutai 20'den fazla il ve şehre satıldı, Jiangmen polisi 26 kişiyi tutukladı
Wuhan'da kalan İtalyan akademisyenler: Riski tahmin edin ve dört kez eve dönmeyi reddedin. Komşular makarna mesajları gönderirken güçlü olmalıdır
To Top