特征工程的力量

為什么你應該使用邏輯回歸來建模非線性決策邊界(使用 Python 代碼)

作為一名大數據從業者,復雜的機器學習技術非常具有吸引力。使用一些深度神經網絡 (DNN) 獲得額外的 1% 準確率,并在此過程中啟動 GPU 實例,這讓人非常滿意。然而,這些技術通常將思考留給計算機,讓我們對模型的工作原理了解甚少。所以,我想回到基礎知識。

在這里插入圖片描述

在本文中,我希望教你一些關于特征工程的知識,以及如何使用它來建模非線性決策邊界。我們將探討兩種技術的優缺點:邏輯回歸(帶有特征工程)和 NN 分類器。將提供用于擬合這些模型以及可視化其決策邊界的 Python 代碼。你可以在 Github1 上找到完整的項目代碼。最后,我希望讓你理解為什么特征工程可能是其他非線性建模技術的更好替代方案。

什么是特征工程

當你從原始數據創建特征或將現有特征的函數添加到數據集時,你就在進行特征工程。這通常使用特定領域的領域知識來完成2。例如,假設我們想要預測一個人從手術中恢復所需的時間(Y)。從之前的手術中,我們獲得了患者的康復時間、身高和體重。根據這些數據,我們還可以計算出每個患者的 BMI = 身高/體重2。通過計算 BMI 并將其納入數據集,我們正在進行特征工程。

我們為什么要進行特征工程

特征工程非常強大,因為它允許我們將非線性問題重新表述為線性問題。為了說明這一點,假設恢復時間與身高和體重有以下關系:

Y = β 0 + β 1 (高度) + β 2 (重量) + β 3 (高度 / 重 量 2 ) + 噪聲 Y = \beta_0 + \beta_1(高度)+ \beta_2(重量)+ \beta_3(高度/重量^2)+ 噪聲 Y=β0?+β1?(高度)+β2?(重量)+β3?(高度/2+噪聲

查看第 3 項,我們可以看到 Y 與身高和體重沒有線性關系。這意味著我們可能不會期望線性模型(例如線性回歸)能夠很好地估計 β 系數。你可以嘗試使用非線性模型(例如 DNN),或者我們可以通過進行一些特征工程來幫助我們的模型。如果我們決定將 BMI 作為一個特征,則關系將變為:

Y = β 0 + β 1 (高度) + β 2 (重量) + β 3 ( B M I ) + 噪聲 Y = \beta_0 + \beta_1(高度)+ \beta_2(重量)+ \beta_3(BMI)+ 噪聲 Y=β0?+β1?(高度)+β2?(重量)+β3?BMI+噪聲
Y 現在可以被建模為 3 個變量的線性關系。因此,我們期望線性回歸能夠更好地估計系數。稍后,我們將看到同樣的想法也適用于分類問題。

為什么不讓電腦來做這項工作

如果從技術角度來講,特征工程本質上就是核心技巧,因為我們將特征映射到更高的平面3。盡管使用核技巧通常不需要太多思考。核函數被視為超參數,可以使用蠻力找到最佳函數——嘗試大量不同的函數變體。使用正確的核函數,你可以建模非線性關系。給定正確數量的隱藏層 / 節點,DNN 還將自動構建特征的非線性函數2。那么,如果這些方法可以建模非線性關系,我們為什么還要費心進行特征工程呢?

我們上面解釋了特征工程如何讓我們即使在使用線性模型的情況下也能捕捉數據中的非線性關系。這意味著,根據問題的不同,我們可以實現與非線性模型類似的性能。我們將在本文后面詳細介紹一個示例。除此之外,使用特征工程還有其他好處,這使得這項技術很有價值。

在這里插入圖片描述

首先,你會更好地理解模型的工作原理。這是因為你確切地知道模型使用什么信息進行預測。此外,像邏輯回歸這樣的模型可以通過直接查看特征系數來輕松解釋。第二個原因與第一個原因相符,即模型更容易解釋。如果你在工業界工作,這一點尤其重要。你的同事也更有可能接觸到一些更簡單的模型。第三個原因是你的模型不太可能過度擬合訓練數據。通過強制加載不同的超參數,很容易導致對數據中噪聲建模。相比之下,有了深思熟慮的特征,你的模型將是直觀的,并且很可能模擬真實的潛在趨勢。

數據集

讓我們深入研究一個實際的例子。為了盡可能清晰,我們將使用人工生成的數據集。為了避免這個例子太枯燥,我們將圍繞它創建一個敘述。假設你的人力資源部門要求你創建一個模型來預測員工是否會晉升。該模型應該考慮員工的年齡和績效分數。

我們在下面的代碼中為 2000 名假設員工創建特征。員工的年齡可以在 18 到 60 歲之間。績效分數可以在 -10 到 10 之間(10 為最高)。這兩個特征都經過了打亂,因此它們不相關。然后我們使用以下年齡 (a) 和績效 § 函數來生成目標變量:

γ ( a , p ) = 100 ( a ) + 200 ( p ) + 500 ( a / p ) ? 10000 + 500 ( n o i s e ) \gamma(a,p)= 100(a)+ 200(p)+ 500(a / p)- 10000 + 500(noise) γap=100a+200p+500a/p?10000+500noise

γ ( a , p ) ≥ 0 \gamma(a,p)≥ 0 γ(a,p)0 時,員工會得到晉升;當 $\gamma(a,p) < 0 $?時,員工不會得到晉升。我們可以看到,上面的函數中包含了 a/p 項。這意味著決策邊界將不是年齡和績效的線性函數。還包括隨機噪聲,因此數據不是完全可分離的。換句話說,模型不可能 100% 準確。

import numpy as np
import pandas as pdn_points = 2000age = np.round(np.linspace(18, 60, n_points), 2) # age of employee
np.random.shuffle(age) # shuffleperformance = np.linspace(-10, 10, n_points) # performance score of employee
np.random.shuffle(performance) # shufflenoise = np.random.randn(n_points)g = (100 * age) + 200 * (performance) + 500 * age / performance - 10000 + 500 * noise
y = [1 if y >= 0 else 0 for y in g]data = pd.DataFrame(data = {'age': age, 'performance': performance, 'y': y})print(sum(y))
data.head()---
474age		performance	y
0	53.32	-6.098049	0
1	32.10	-7.848924	0
2	58.72	9.709855	1
3	59.52	4.387194	1
4	28.55	7.418709	0

如果上述步驟有點令人困惑,請不要擔心。我們可以通過使用以下代碼可視化數據集來使事情變得更清晰。在這里,我們創建了數據的散點圖,結果可以在圖 1 中看到。僅通過兩個特征,很容易準確地看到發生了什么。在 y 軸上,我們有員工的績效分數,在 x 軸上,我們有員工的年齡。晉升員工的分數為紅色,未晉升的員工分數為藍色。最終,2000 名員工中有 459 名(23%)獲得了晉升。對于不同的隨機樣本,該比例會略有變化。

plt.subplots(nrows = 1, ncols = 1, figsize = (15, 10))plt.scatter('age', 'performance', c = '#ff2121', s = 50, edgecolors = '#000000', data = data[data.y == 1])
plt.scatter('age', 'performance', c = '#2176ff', s = 50, edgecolors = '#000000', data = data[data.y == 0])
plt.ylabel('Performance Score', size = 20)
plt.xlabel('Age', size = 20)
plt.yticks(size = 12)
plt.xticks(size = 12)
plt.legend(['Promoted', 'Not Promoted'], loc = 2, prop = {'size': 20})
plt.savefig('../figures/article_feature_eng/figure1.png', format = 'png')

圖 1:數據散點圖

盡管這些數據是生成的,但我們仍然可以對該圖做出現實的解釋。在圖 1 中,我們可以看到 3 個不同的員工組。第一個是績效得分低于 0 的組。由于績效不佳,這些員工中的大多數都沒有得到晉升,我們還可以預期其中一些員工被解雇。我們可以預期得分高于 0 的員工要么得到晉升,要么接受其他公司的報價。得分特別高的員工往往會離開。這可能是因為他們的需求量很大,而且在其他地方得到了更好的報價。然而,隨著雇主年齡的增長,他們需要更高的績效分數才能離開。這可能是因為年長的員工在目前的職位上更舒服。

無論如何,很明顯,決策邊界不是線性的。換句話說,不可能畫出一條直線來很好地區分晉升組和未晉升組。因此,我們不會指望線性模型能做得很好。讓我們通過嘗試僅使用兩個特征(年齡和表現)來擬合邏輯回歸模型來證明這一點。

邏輯回歸

在下面的代碼中,我們將 2000 名員工分成訓練集(70%)和測試集(30%)。我們使用訓練集來訓練邏輯回歸模型。然后,使用該模型,我們對測試集進行預測。測試集的準確率為 82%。這似乎不算太糟糕,但我們應該考慮到只有不到 23% 的員工獲得了晉升。因此,如果我們只是猜測沒有員工會得到晉升,那么我們應該預期準確率約為 77%。

from sklearn.model_selection import train_test_split
import sklearn.metrics as metric
import statsmodels.api as smx = data[['age', 'performance']]
x = sm.add_constant(x)
y = data['y']
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.3, random_state = 2024)model = sm.Logit(y_train, x_train).fit() # fit logistic regression modelpredictions = np.around(model.predict(x_test))
accuracy = metric.accuracy_score(y_test, predictions)print(round(accuracy * 100, 2))---
Optimization terminated successfully.Current function value: 0.428402Iterations 7
81.83

通過使用以下代碼可視化決策邊界,我們可以更好地理解模型正在做什么。在這里,我們在樣本空間內生成一百萬個點。然后,我們使用邏輯回歸模型對所有這些點進行預測。與圖 1 中的散點圖一樣,我們可以繪制每個點。每個點的顏色由模型的預測決定 — 如果模型預測晉升,則為粉紅色,否則為淺藍色。這為我們提供了決策邊界的良好近似值,可以在圖 2 中看到。然后,我們可以在這些點上繪制實際數據集。

n_points = 1000000 # use many point to visualise decision boundryage_db = np.linspace(18, 60, n_points)
np.random.shuffle(age_db)performance_db = np.linspace(-10, 10, n_points)
np.random.shuffle(performance_db)data_db = pd.DataFrame({'age': age_db, 'performance': performance_db})
data_db = sm.add_constant(data_db)# make predictions on the decision boundry points
predictions = model.predict(data_db)
y_db = [round(p) for p in predictions]
data_db['y'] = y_dbfig, ax = plt.subplots(nrows = 1, ncols = 1, figsize = (15, 10))# Plot decision boundry
plt.scatter('age', 'performance', c = '#ffbdbd', s = 1, data = data_db[data_db.y == 1])
plt.scatter('age', 'performance', c = '#b0c4ff', s = 1, data = data_db[data_db.y == 0])# Plot employee data points
plt.scatter('age', 'performance', c = '#ff2121', s = 50, edgecolors = '#000000', data = data[data.y == 1])
plt.scatter('age', 'performance', c = '#2176ff', s = 50, edgecolors = '#000000', data = data[data.y == 0])
plt.ylabel('Performance Score', size = 20)
plt.xlabel('Age', size = 20)
plt.yticks(size = 12)
plt.xticks(size = 12)plt.savefig('../figures/article_feature_eng/figure2.png', format = 'png')

從決策邊界來看,我們可以看到模型表現很糟糕。它預測會升職的員工中,大約有一半沒有升職。然后,對于大多數獲得晉升的員工,它預測他們沒有獲得晉升。請注意,決策邊界是一條直線。這強調了邏輯回歸是一個線性分類器。換句話說,該模型只能構建一個決策邊界,它是你賦予它的特征的線性函數。此時,我們可能會想嘗試不同的模型,但讓我們看看是否可以使用特征工程來提高性能。

圖2:邏輯回歸模型的決策邊界

具有特征工程的邏輯回歸

首先,如下面的代碼所示,我們添加了附加特征(即年齡與表現的比率)。從那時起,我們遵循與之前的模型相同的過程。訓練測試分割是相同的,因為我們對 “random_state” 使用相同的值。最后,這個模型的準確率達到了 98%,這是一個顯著的改進。

data['age_perf_ratio'] = age / performancex = data[['age', 'performance', 'age_perf_ratio']]
x = sm.add_constant(x)
y = data['y']x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.3, random_state = 2024)model = sm.Logit(y_train, x_train).fit() # fit new logistic regression modelpredictions = np.around(model.predict(x_test))
accuracy = metric.accuracy_score(y_test, predictions)print(round(accuracy * 100, 2))---
Optimization terminated successfully.Current function value: 0.039001Iterations 17
98.17

該模型仍然只需要員工的年齡和績效即可進行預測。這是因為附加特征是年齡和績效的函數。這使我們能夠以與以前相同的方式可視化決策邊界。即通過在樣本空間中的每個年齡-績效點使用模型的預測。我們可以看到,在圖 3 中,通過添加附加特征,邏輯回歸模型能夠對非線性決策邊界進行建模。從技術上講,這是年齡和績效的非線性函數,但它仍然是所有 3 個特征的線性函數。

圖 3:具有特征工程的邏輯回歸模型的決策邊界

使用邏輯回歸的另一個好處是模型是可解釋的。這意味著模型可以用人類的術語來解釋4。換句話說,我們可以直接查看模型系數來了解其工作原理。我們可以在表 1 中看到模型特征的系數及其 p 值。我們不會講得太詳細,但系數可以讓你根據晉升幾率的變化來解釋特征的變化5。如果特征具有正系數,則該特征值的增加會導致晉升幾率的增加。

在這里插入圖片描述

從表 1 可以看出,隨著年齡的增長,獲得晉升的可能性也會增加。另一方面,對于績效,這種關系并不那么明顯。績效的提高也會降低年齡/績效比率。這意味著,績效提高對幾率的影響取決于員工的年齡。這非常符合直覺,因為它與我們在散點圖中看到的一致。在這種情況下,可能沒有必要使用系數以這種方式解釋模型。僅僅可視化決策邊界就足夠了,但是,隨著我們增加特征數量,這樣做變得更加困難。在這種情況下,模型系數是理解模型如何工作的重要工具。

同樣,P 值也有助于我們對模型的理解。由于系數是統計估計值,因此具有一定的不確定性。換句話說,我們可以確定系數要么是正值,要么是負值。這一點非常重要,因為如果我們不能確定系數的符號,就很難用幾率的變化來解釋特征的變化。從表 1 中我們可以看出,所有系數在統計意義上都是顯著的。這并不奇怪,因為我們是利用特征函數生成數據的。

總體而言,當我們生成數據時,上述分析非常簡單。因為我們知道使用什么函數來生成數據,所以很明顯,附加特征會提高模型的準確性。實際上,事情不會這么簡單。如果你對數據沒有很好的理解,你可能需要與人力資源部門的某個人交談。他們可能會告訴你他們過去看到的任何趨勢。否則,通過使用各種圖表和匯總統計數據探索該數據,你可以了解哪些特征可能很重要。但是,假設我們不想做所有這些艱苦的工作。

神經網絡

為了進行比較,我們使用非線性模型。在下面的代碼中,我們使用 Keras 來擬合 NN。我們僅使用年齡和表現作為特征,因此 NN 的輸入層的維度為 2。有 2 個隱藏層,分別有 20 個和 15 個節點。兩個隱藏層都具有 relu 激活函數,輸出層具有 sigmoid 激活函數。為了訓練模型,我們使用 10 和 100 個 epoch 的批處理大小。訓練集大小為 1400,這給了我們 14000 個步驟。最后,該模型在測試集上的準確率達到了 96%。這與邏輯回歸模型的準確率略低,但是也相差不大,不過我們不必進行任何特征工程。

from keras.models import Sequential
from keras.layers import Densex = data[['age', 'performance']]
y = data['y']
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.3, random_state = 2024)model = Sequential()model.add(Dense(20, input_dim = 2, activation = 'relu'))
model.add(Dense(15, activation = 'relu'))
model.add(Dense(1, activation = 'sigmoid'))
model.compile(loss = 'binary_crossentropy', optimizer = 'adam', metrics = ['accuracy'])model.fit(x_train, y_train, epochs = 100, batch_size = 10) # fit ANNaccuracy = model.evaluate(x_test, y_test)
print(round(accuracy[1] * 100, 2))---
Epoch 1/100
2024-06-30 22:31:06.692852: W tensorflow/core/platform/profile_utils/cpu_utils.cc:128] Failed to get CPU frequency: 0 Hz
2024-06-30 22:31:06.891137: I tensorflow/core/grappler/optimizers/custom_graph_optimizer_registry.cc:113] Plugin optimizer for device_type GPU is enabled.
140/140 [==============================] - 3s 4ms/step - loss: 0.5638 - accuracy: 0.7393
...
Epoch 100/100
140/140 [==============================] - 1s 6ms/step - loss: 0.0943 - accuracy: 0.9543
Output is truncated. View as a scrollable element or open in a text editor. Adjust cell output settings...
2024-06-30 22:32:14.638250: I tensorflow/core/grappler/optimizers/custom_graph_optimizer_registry.cc:113] Plugin optimizer for device_type GPU is enabled.
19/19 [==============================] - 1s 10ms/step - loss: 0.0848 - accuracy: 0.9617
96.17

通過查看圖 4 中的 NN 決策邊界,我們可以看出為什么它被認為是一種非線性分類算法。即使我們只給出了模型年齡和性能,它仍然能夠構建非線性決策邊界。因此,在一定程度上,模型已經為我們完成了艱苦的工作。你可以說模型的隱藏層已經自動完成了特征工程。那么,考慮到這個模型具有很高的準確性并且需要我們付出的努力較少,我們為什么還要考慮邏輯回歸呢?

在這里插入圖片描述

NN 的缺點是它只能解釋。這意味著,與邏輯回歸不同,我們不能直接查看模型的參數來了解其工作原理4。我們可以使用其他方法,但最終,理解 NN 的工作原理更加困難。向非技術人員(例如人力資源主管)解釋這一點更加困難。這使得邏輯回歸模型在行業環境中更有價值。

工業界和學術界都存在許多問題,其中大多數問題都比本文給出的示例更復雜。本文提出的方法顯然不是解決所有這些問題的最佳方法。例如,如果你嘗試進行圖像識別,那么使用邏輯回歸將無濟于事。對于較簡單的問題,邏輯回歸和對數據的良好理解通常就是你所需要的。

參考


  1. 茶桁的公共文章項目庫(2024 年),https://github.com/hivandu/public_articles ??

  2. T. Hastie, R. Tibshirani, J. Friedman, The Elements of Statistical Learning [pg 150] (2017), https://web.stanford.edu/~hastie/ElemStatLearn/ ?? ??

  3. Statinfer, The Non-Linear Decision Boundary (2017), https://statinfer.com/203-6-5-the-non-linear-decision-boundary/ ??

  4. R. Gall, Machine Learning Explainability vs Interpretability: Two concepts that could help restore trust in AI (2018), https://www.kdnuggets.com/2018/12/machine-learning-explainability-interpretability-ai.html ?? ??

  5. UCLA, How do I Interpret Odds Ratios in Logistic Regression? (2020), https://stats.idre.ucla.edu/stata/faq/how-do-i-interpret-odds-ratios-in-logistic-regression/ ??

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/37411.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/37411.shtml
英文地址,請注明出處:http://en.pswp.cn/web/37411.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【使用webrtc-streamer解析rtsp視頻流】

webrtc-streamer WebRTC (Web Real-Time Communications) 是一項實時通訊技術&#xff0c;它允許網絡應用或者站點&#xff0c;在不借助中間媒介的情況下&#xff0c;建立瀏覽器之間點對點&#xff08;Peer-to-Peer&#xff09;的連接&#xff0c;實現視頻流和&#xff08;或&a…

了解 ZooKeeper:關鍵概念和架構

ZooKeeper 是一種分布式協調服務&#xff0c;廣泛用于分布式系統中&#xff0c;用于維護配置信息、命名、同步和組服務。它最初由雅虎開發&#xff0c;現在是一個 Apache 項目&#xff0c;已成為許多大型分布式應用程序不可或缺的一部分。本文深入探討 ZooKeeper 的關鍵概念和架…

【Android】Activity子類之間的區別

從底層往頂層的繼承順序依次是&#xff1a; Activity&#xff0c;最原始的Activity androidx.core.app.ComponentActivity&#xff0c;僅僅優化了一個關于KeyEvent的攔截問題&#xff0c;一般不繼承這個類 androidx.activity.ComponentActivity&#xff0c;支持和Android Arc…

Spark Join優化案例:Join Key 遠大于 Payload

在一個案例中&#xff0c;大表 100GB、小表 10GB&#xff0c;它們全都遠超廣播變量閾值&#xff08;默認 10MB&#xff09;。因為小表的尺寸已經超過 8GB&#xff0c;在大于 8GB 的數據集上創建廣播變量&#xff0c;Spark 會直接拋出異常&#xff0c;中斷任務執行&#xff0c;所…

C語言 求 n 個數的階乘之和

求n個數的階乘之和&#xff08;即求1&#xff01;2&#xff01;3&#xff01;…n!&#xff09; 這個程序讀取用戶輸入的正整數 n&#xff0c;計算并輸出 1! 2! 3! ... n! 的值。 #include <stdio.h>// 計算階乘的函數 long factorial(int num) {long result 1;for…

恢復 IntelliJ IDEA 中消失的菜單欄

要恢復 IntelliJ IDEA 中消失的菜單欄&#xff0c;可以按照以下簡單步驟操作&#xff1a; 使用快捷鍵打開搜索&#xff1a;首先&#xff0c;雙擊 Shift 鍵打開全局搜索對話框。 搜索“Menu”&#xff1a;在搜索框中輸入 menu&#xff0c;然后從搜索結果中選擇與“Main Menu”相…

python-基礎篇-選擇-是什么

文章目錄 定義一&#xff1a;Python 條件語句跟其他語言基本一致的&#xff0c;都是通過一條或多條語句的執行結果&#xff08; True 或者 False &#xff09;來決定執行的代碼塊。1、什么是條件語句2、if 語句的基本形式3、if 語句多個判斷條件的形式4、if 語句多個條件同時判…

次序統計量

內容來源 概率論與數理統計教程&#xff08;第三版&#xff09; 茆詩松 高等教育出版社 數理統計學導論&#xff08;原書第7版&#xff09; 機械工業出版社 定義 設 X 1 , X 2 , ? , X n X_1,X_2,\cdots,X_n X1?,X2?,?,Xn? 是來自連續分布的隨機樣本 此分布具有 p d f…

【機器學習】Python reversed 函數

目錄&#xff1a; reversed()函數初探應用于列表和元組實戰演練&#xff1a;山海經故事文本處理 Python中的內置函數——reversed()。 這個函數能夠幫助你高效地處理序列類型數據&#xff0c;比如列表、元組、字符串等&#xff0c;通過它你可以輕松地反轉這些序列中的元素順…

JSON 簡述與應用

1. JSON 簡述 JSON&#xff08;JavaScript Object Notation&#xff09;是一種輕量級的數據交換格式&#xff0c;常用于客戶端與服務器之間的數據傳遞。它基于JavaScript對象表示法&#xff0c;但獨立于語言&#xff0c;可以被多種編程語言解析和生成。 1.1 特點 輕量級&#…

JS對數據類型的檢測方式

1. typeof()對于基本數據類型沒問題&#xff0c;遇到引用數據類型就不管用 console.log( typeof 666 ); // number console.log( typeof [1,2,3] ); // object 2. instanceof()只能判斷引用數據類型&#xff0c;不能判斷基本數據類型 console.log( [] instanceof Array ) // tr…

Unity--協程--Coroutine

Unity–協程–Coroutine 1. 協程的基本概念 基本概念:不是線程,將代碼按照劃分的時間來執行,這個時間可以是具體的多少秒,也可以是物理幀的時間,也可以是一幀的繪制結束的時間。 協程的寫法&#xff1a;通過返回IEnumerator的函數實現&#xff0c;使用yield return語句暫停執…

Golang | Leetcode Golang題解之第205題同構字符串

題目&#xff1a; 題解&#xff1a; func isIsomorphic(s, t string) bool {s2t : map[byte]byte{}t2s : map[byte]byte{}for i : range s {x, y : s[i], t[i]if s2t[x] > 0 && s2t[x] ! y || t2s[y] > 0 && t2s[y] ! x {return false}s2t[x] yt2s[y] …

python 查找輪廓

在Python中&#xff0c;查找圖像的輪廓通常使用OpenCV庫。以下是一個簡單的示例代碼&#xff0c;展示了如何使用OpenCV來查找并繪制圖像的輪廓&#xff1a; pythonimport cv2 import numpy as np# 讀取圖像 image cv2.imread(your_image.jpg, 0) # 請將your_image.jpg替換為您…

設備樹下的 platform 驅動編寫

設備樹下的 platform 驅動編寫 設備樹下的 platform 驅動簡介 platform 驅動框架分為總線、設備和驅動&#xff0c;其中總線不需要我們這些驅動程序員去管理&#xff0c;這個是 Linux 內核提供的&#xff0c;我們在編寫驅動的時候只要關注于設備和驅動的具體實現即可。在沒有…

《昇思25天學習打卡營第6天 | 函數式自動微分》

《昇思25天學習打卡營第6天 | 函數式自動微分》 目錄 《昇思25天學習打卡營第6天 | 函數式自動微分》函數式自動微分簡單的單層線性變換模型函數與計算圖微分函數與梯度計算Stop Gradient 函數式自動微分 神經網絡的訓練主要使用反向傳播算法&#xff0c;模型預測值&#xff0…

建站小記:遷移域名DNS到CloudFlare

CloudFlare一直有賽博菩薩之稱&#xff0c;據說用它做DNS解析服務又快又好又免費&#xff0c;還能防DDOS攻擊&#xff0c;并且可以提供頁面訪問統計功能。 正好我博客網頁打開略卡頓&#xff0c;所以決定將自己的DNS解析遷移到CloudFlare。 1.登錄CF控制臺&#xff0c;添加自己…

LeetCode-刷題記錄-二分法合集(本篇blog會持續更新哦~)

一、二分查找概述 二分查找&#xff08;Binary Search&#xff09;是一種高效的查找算法&#xff0c;適用于有序數組或列表。&#xff08;但其實只要滿足二段性&#xff0c;就可以使用二分法&#xff0c;本篇博客后面博主會持續更新一些題&#xff0c;來破除一下人們對“只有有…

(已解決)Adobe Flash Player已不再受支持

文章目錄 前言解決方案 前言 一般來說&#xff0c;很少遇到官方網站使用Adobe Flash Player來進行錄用名單公示了。但是&#xff0c;今天就偏偏遇到一次&#xff0c; 用谷歌瀏覽器打不開&#xff0c; 點了沒有反應&#xff0c;用其他的瀏覽器&#xff0c;例如windows自帶的那…

Golang | Leetcode Golang題解之第207題課程表

題目&#xff1a; 題解&#xff1a; func canFinish(numCourses int, prerequisites [][]int) bool {var (edges make([][]int, numCourses)indeg make([]int, numCourses)result []int)for _, info : range prerequisites {edges[info[1]] append(edges[info[1]], info[0]…