第9章 逻辑回归
9-1 什么是逻辑回归
Notbook 示例
Notbook 源码
1 Sigmoid 函数 2 [1] 3 import numpy as np 4 import matplotlib.pyplot as plt 5 [2] 6 def sigmoid(t): 7 return 1 / (1 + np.exp(-t)) 8 [3] 9 X = np.linspace(-10,10,500) 10 y = sigmoid(X) 11 12 plt.plot(X,y) 13 [<matplotlib.lines.Line2D at 0x18b21371c40>]
9-2 逻辑回归的损失函数
9-3 逻辑回归损失函数的梯度
9-4 and 9-5 实现逻辑回归算法与决策边界
Notbook 示例
Notbook 源码
1 实现逻辑回归 2 [1] 3 import numpy as np 4 import matplotlib.pyplot as plt 5 from sklearn import datasets 6 7 iris = datasets.load_iris() 8 [2] 9 X = iris.data 10 y = iris.target 11 [3] 12 X = X[y<2, :2] 13 y = y[y<2] 14 [4] 15 X.shape 16 (100, 2) 17 [5] 18 y.shape 19 (100,) 20 [6] 21 plt.scatter(X[y==0,0], X[y==0,1],color="red") 22 plt.scatter(X[y==1,0], X[y==1,1],color="blue") 23 <matplotlib.collections.PathCollection at 0x18d15300d00> 24 25 使用逻辑回归 26 [7] 27 from playML.model_selection import train_test_split 28 29 X_train, X_test, y_train, y_test = train_test_split(X, y, seed=666) 30 [8] 31 from playML.LogistcRegression import LogisticRegression 32 33 log_reg = LogisticRegression() 34 log_reg.fit(X_train, y_train) 35 LogisticRegression() 36 [9] 37 log_reg.score(X_test, y_test) 38 1.0 39 [10] 40 log_reg.predict_proba(X_test) 41 array([9.62648257e-01, 9.95348774e-01, 1.00823761e-01, 6.17589825e-03, 42 1.67472308e-02, 6.93067583e-03, 2.43033667e-02, 9.99216051e-01, 43 9.92621004e-01, 7.93937643e-01, 2.16979735e-02, 8.39808132e-04, 44 2.12177556e-01, 1.67472308e-02, 8.93306850e-01, 8.47220912e-01, 45 8.78361232e-01, 2.82569244e-01, 3.56919294e-02, 1.55520124e-01]) 46 [11] 47 y_test 48 array([1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0]) 49 [12] 50 log_reg.predict(X_test) 51 array([1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0]) 52 决策边界 53 [13] 54 log_reg.coef_ 55 array([ 3.80096484, -6.28176101]) 56 [14] 57 log_reg.interception_ 58 -1.0912939737572598 59 [15] 60 def X2(X1): 61 return (-log_reg.coef_[0] * X1 - log_reg.interception_) / log_reg.coef_[1] 62 [16] 63 X1_plot = np.linspace(4, 8,1000) 64 X2_plot = X2(X1_plot) 65 [17] 66 plt.scatter(X[y==0,0], X[y==0,1],color="red") 67 plt.scatter(X[y==1,0], X[y==1,1],color="blue") 68 plt.plot(X1_plot,X2_plot) 69 [<matplotlib.lines.Line2D at 0x18d15ac2fd0>] 70 71 [18] 72 plt.scatter(X_test[y_test==0,0], X_test[y_test==0,1],color="red") 73 plt.scatter(X_test[y_test==1,0], X_test[y_test==1,1],color="blue") 74 plt.plot(X1_plot,X2_plot) 75 [<matplotlib.lines.Line2D at 0x18d15b4d2e0>] 76 77 [19] 78 # plot_decision_boundary()函数:绘制模型在二维特征空间的决策边界; 79 def plot_decision_boundary(model, axis): 80 # model:算法模型; 81 # axis:区域坐标轴的范围,其中 0,1,2,3 分别对应 x 轴和 y 轴的范围; 82 83 # 1)将坐标轴等分为无数的小点,将 x、y 轴分别等分 (坐标轴范围最大值 - 坐标轴范围最小值)*100 份, 84 # np.meshgrid(): 85 x0, x1 = np.meshgrid( 86 np.linspace(axis[0], axis[1], int((axis[1]-axis[0])*100)).reshape(-1,1), 87 np.linspace(axis[2], axis[3], int((axis[3]-axis[2])*100)).reshape(-1,1) 88 ) 89 # np.c_(): 90 X_new = np.c_[x0.ravel(), x1.ravel()] 91 92 # 2)model.predict(X_new):将分割出的所有的点,都使用模型预测 93 y_predict = model.predict(X_new) 94 zz = y_predict.reshape(x0.shape) 95 96 # 3)绘制预测结果 97 from matplotlib.colors import ListedColormap 98 custom_cmap = ListedColormap(['#EF9A9A','#FFF59D','#90CAF9']) 99 100 plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap) 101 [20] 102 plot_decision_boundary(log_reg, axis=[4, 7.5, 1.5, 4.5]) 103 plt.scatter(X[y==0, 0], X[y==0, 1] ) 104 plt.scatter(X[y==1, 0], X[y==1, 1]) 105 C:\Users\Administrator\AppData\Local\Temp\ipykernel_12716\2692106441.py:23: UserWarning: The following kwargs were not used by contour: 'linewidth' 106 plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap) 107 108 <matplotlib.collections.PathCollection at 0x18d15d601c0> 109 110 kNN的决策边界 111 [21] 112 from sklearn.neighbors import KNeighborsClassifier 113 114 knn_clf = KNeighborsClassifier() 115 knn_clf.fit(X_train,y_train) 116 KNeighborsClassifier() 117 [22] 118 knn_clf.score(X_test,y_test) 119 1.0 120 [23] 121 plot_decision_boundary(knn_clf, axis=[4, 7.5, 1.5, 4.5]) 122 plt.scatter(X[y==0, 0], X[y==0, 1] ) 123 plt.scatter(X[y==1, 0], X[y==1, 1]) 124 C:\Users\Administrator\AppData\Local\Temp\ipykernel_12716\2692106441.py:23: UserWarning: The following kwargs were not used by contour: 'linewidth' 125 plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap) 126 127 <matplotlib.collections.PathCollection at 0x18d15f68d90> 128 129 [24] 130 knn_clf_all = KNeighborsClassifier() 131 knn_clf_all.fit(iris.data[:,:2],iris.target) 132 KNeighborsClassifier() 133 [25] 134 plot_decision_boundary(knn_clf_all, axis=[4, 8, 1.5, 4.5]) 135 plt.scatter(iris.data[iris.target==0,0],iris.data[iris.target==0,1]) 136 plt.scatter(iris.data[iris.target==1,0],iris.data[iris.target==1,1]) 137 plt.scatter(iris.data[iris.target==2,0],iris.data[iris.target==2,1]) 138 C:\Users\Administrator\AppData\Local\Temp\ipykernel_12716\2692106441.py:23: UserWarning: The following kwargs were not used by contour: 'linewidth' 139 plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap) 140 141 <matplotlib.collections.PathCollection at 0x18d15fd9a30> 142 143 [26] 144 knn_clf_all = KNeighborsClassifier(n_neighbors=50) 145 knn_clf_all.fit(iris.data[:,:2],iris.target) 146 KNeighborsClassifier(n_neighbors=50) 147 [27] 148 plot_decision_boundary(knn_clf_all, axis=[4, 8, 1.5, 4.5]) 149 plt.scatter(iris.data[iris.target==0,0],iris.data[iris.target==0,1]) 150 plt.scatter(iris.data[iris.target==1,0],iris.data[iris.target==1,1]) 151 plt.scatter(iris.data[iris.target==2,0],iris.data[iris.target==2,1]) 152 C:\Users\Administrator\AppData\Local\Temp\ipykernel_12716\2692106441.py:23: UserWarning: The following kwargs were not used by contour: 'linewidth' 153 plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap) 154 155 <matplotlib.collections.PathCollection at 0x18d1606c8b0>
9-6 在逻辑回归中使用多项式特征
Notbook 示例
Notbook 源码
1 逻辑回归中添加多项式特征 2 [1] 3 import numpy as np 4 import matplotlib.pyplot as plt 5 [2] 6 np.random.seed(666) 7 X = np.random.normal(0,1,size=(200, 2)) 8 y = np.array(X[:,0]**2 + X[:,1]**2 < 1.5 ,dtype='int') 9 [3] 10 plt.scatter(X[y==0,0], X[y==0,1]) 11 plt.scatter(X[y==1,0], X[y==1,1]) 12 <matplotlib.collections.PathCollection at 0x22a90fd94f0> 13 14 使用逻辑回归 15 [4] 16 from playML.LogistcRegression import LogisticRegression 17 [5] 18 log_reg = LogisticRegression() 19 log_reg.fit(X,y) 20 LogisticRegression() 21 [6] 22 log_reg.score(X,y) 23 0.61 24 [7] 25 def plot_decision_boundary(model, axis): 26 27 x0, x1 = np.meshgrid( 28 np.linspace(axis[0], axis[1], int((axis[1]-axis[0])*100)).reshape(-1,1), 29 np.linspace(axis[2], axis[3], int((axis[3]-axis[2])*100)).reshape(-1,1) 30 ) 31 X_new = np.c_[x0.ravel(), x1.ravel()] 32 33 y_predict = model.predict(X_new) 34 zz = y_predict.reshape(x0.shape) 35 36 from matplotlib.colors import ListedColormap 37 custom_cmap = ListedColormap(['#EF9A9A','#FFF59D','#90CAF9']) 38 39 plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap) 40 [8] 41 plot_decision_boundary(log_reg, axis=[-4,4,-4,4]) 42 plt.scatter(X[y==0,0], X[y==0,1]) 43 plt.scatter(X[y==1,0], X[y==1,1]) 44 C:\Users\Administrator\AppData\Local\Temp\ipykernel_9172\3130018029.py:15: UserWarning: The following kwargs were not used by contour: 'linewidth' 45 plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap) 46 47 <matplotlib.collections.PathCollection at 0x22a92dbf580> 48 49 [9] 50 from sklearn.pipeline import Pipeline 51 from sklearn.preprocessing import PolynomialFeatures 52 from sklearn.preprocessing import StandardScaler 53 54 def PolynomialLogisticRegression(degree): 55 return Pipeline([ 56 ("poly",PolynomialFeatures(degree=degree)), 57 ("std_scaler",StandardScaler()), 58 ("log_reg",LogisticRegression()) 59 ]) 60 [10] 61 poly_log_reg = PolynomialLogisticRegression(degree=2) 62 poly_log_reg.fit(X,y) 63 Pipeline(steps=[('poly', PolynomialFeatures()), 64 ('std_scaler', StandardScaler()), 65 ('log_reg', LogisticRegression())]) 66 [11] 67 poly_log_reg.score(X,y) 68 0.97 69 [12] 70 plot_decision_boundary(poly_log_reg, axis=[-4,4,-4,4]) 71 plt.scatter(X[y==0,0], X[y==0,1]) 72 plt.scatter(X[y==1,0], X[y==1,1]) 73 C:\Users\Administrator\AppData\Local\Temp\ipykernel_9172\3130018029.py:15: UserWarning: The following kwargs were not used by contour: 'linewidth' 74 plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap) 75 76 <matplotlib.collections.PathCollection at 0x22a92aca6d0> 77 78 [13] 79 poly_log_reg2 = PolynomialLogisticRegression(degree=20) 80 poly_log_reg2.fit(X,y) 81 Pipeline(steps=[('poly', PolynomialFeatures(degree=20)), 82 ('std_scaler', StandardScaler()), 83 ('log_reg', LogisticRegression())]) 84 [14] 85 plot_decision_boundary(poly_log_reg2, axis=[-4,4,-4,4]) 86 plt.scatter(X[y==0,0], X[y==0,1]) 87 plt.scatter(X[y==1,0], X[y==1,1]) 88 C:\Users\Administrator\AppData\Local\Temp\ipykernel_9172\3130018029.py:15: UserWarning: The following kwargs were not used by contour: 'linewidth' 89 plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap) 90 91 <matplotlib.collections.PathCollection at 0x22a92ba6cd0>
9-7 scikit-learn中的逻辑回归
Notbook 示例
Notbook 源码
1 [1] 2 import numpy as np 3 import matplotlib.pyplot as plt 4 [2] 5 np.random.seed(666) 6 X = np.random.normal(0,1,size=(200, 2)) 7 y = np.array(X[:,0]**2 + X[:,1] < 1.5 ,dtype='int') 8 for _ in range(20): 9 y[np.random.randint(200)] = 1 10 [3] 11 plt.scatter(X[y==0,0], X[y==0,1]) 12 plt.scatter(X[y==1,0], X[y==1,1]) 13 <matplotlib.collections.PathCollection at 0x2397e35b220> 14 15 [4] 16 from sklearn.model_selection import train_test_split 17 X_train, X_test, y_train, y_test = train_test_split(X, y,random_state=666) 18 使用scikit-learn 中的逻辑回归 19 [5] 20 from sklearn.linear_model import LogisticRegression 21 22 log_reg = LogisticRegression() 23 log_reg.fit(X_train, y_train) 24 LogisticRegression() 25 [6] 26 log_reg.score(X_train,y_train) 27 0.7933333333333333 28 [7] 29 log_reg.score(X_test,y_test) 30 0.86 31 [8] 32 def plot_decision_boundary(model, axis): 33 34 x0, x1 = np.meshgrid( 35 np.linspace(axis[0], axis[1], int((axis[1]-axis[0])*100)).reshape(-1,1), 36 np.linspace(axis[2], axis[3], int((axis[3]-axis[2])*100)).reshape(-1,1) 37 ) 38 X_new = np.c_[x0.ravel(), x1.ravel()] 39 40 y_predict = model.predict(X_new) 41 zz = y_predict.reshape(x0.shape) 42 43 from matplotlib.colors import ListedColormap 44 custom_cmap = ListedColormap(['#EF9A9A','#FFF59D','#90CAF9']) 45 46 plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap) 47 [9] 48 plot_decision_boundary(log_reg, axis=[-4,4,-4,4]) 49 plt.scatter(X[y==0,0], X[y==0,1]) 50 plt.scatter(X[y==1,0], X[y==1,1]) 51 C:\Users\Administrator\AppData\Local\Temp\ipykernel_13668\3130018029.py:15: UserWarning: The following kwargs were not used by contour: 'linewidth' 52 plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap) 53 54 <matplotlib.collections.PathCollection at 0x23903dc3460> 55 56 [10] 57 from sklearn.pipeline import Pipeline 58 from sklearn.preprocessing import PolynomialFeatures 59 from sklearn.preprocessing import StandardScaler 60 61 def PolynomialLogisticRegression(degree): 62 return Pipeline([ 63 ("poly",PolynomialFeatures(degree=degree)), 64 ("std_scaler",StandardScaler()), 65 ("log_reg",LogisticRegression()) 66 ]) 67 [11] 68 poly_log_reg = PolynomialLogisticRegression(degree=2) 69 poly_log_reg.fit(X_train,y_train) 70 Pipeline(steps=[('poly', PolynomialFeatures()), 71 ('std_scaler', StandardScaler()), 72 ('log_reg', LogisticRegression())]) 73 [12] 74 poly_log_reg.score(X_train,y_train) 75 0.9066666666666666 76 [13] 77 poly_log_reg.score(X_test,y_test) 78 0.94 79 [14] 80 plot_decision_boundary(poly_log_reg, axis=[-4,4,-4,4]) 81 plt.scatter(X[y==0,0], X[y==0,1]) 82 plt.scatter(X[y==1,0], X[y==1,1]) 83 C:\Users\Administrator\AppData\Local\Temp\ipykernel_13668\3130018029.py:15: UserWarning: The following kwargs were not used by contour: 'linewidth' 84 plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap) 85 86 <matplotlib.collections.PathCollection at 0x23902a64790> 87 88 [15] 89 poly_log_reg2 = PolynomialLogisticRegression(degree=20) 90 poly_log_reg2.fit(X_train,y_train) 91 Pipeline(steps=[('poly', PolynomialFeatures(degree=20)), 92 ('std_scaler', StandardScaler()), 93 ('log_reg', LogisticRegression())]) 94 [16] 95 poly_log_reg2.score(X_train,y_train) 96 0.94 97 [17] 98 poly_log_reg2.score(X_test,y_test) 99 0.92 100 [18] 101 plot_decision_boundary(poly_log_reg2, axis=[-4,4,-4,4]) 102 plt.scatter(X[y==0,0], X[y==0,1]) 103 plt.scatter(X[y==1,0], X[y==1,1]) 104 C:\Users\Administrator\AppData\Local\Temp\ipykernel_13668\3130018029.py:15: UserWarning: The following kwargs were not used by contour: 'linewidth' 105 plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap) 106 107 <matplotlib.collections.PathCollection at 0x239034965b0> 108 109 [19] 110 def PolynomialLogisticRegression(degree, C): 111 return Pipeline([ 112 ("poly",PolynomialFeatures(degree=degree)), 113 ("std_scaler",StandardScaler()), 114 ("log_reg",LogisticRegression(C=C)) 115 ]) 116 [20] 117 poly_log_reg3 = PolynomialLogisticRegression(degree=20, C=0.1) 118 poly_log_reg3.fit(X_train,y_train) 119 Pipeline(steps=[('poly', PolynomialFeatures(degree=20)), 120 ('std_scaler', StandardScaler()), 121 ('log_reg', LogisticRegression(C=0.1))]) 122 [21] 123 poly_log_reg3.score(X_train,y_train) 124 0.84 125 [22] 126 poly_log_reg3.score(X_test,y_test) 127 0.92 128 [23] 129 plot_decision_boundary(poly_log_reg3, axis=[-4,4,-4,4]) 130 plt.scatter(X[y==0,0], X[y==0,1]) 131 plt.scatter(X[y==1,0], X[y==1,1]) 132 C:\Users\Administrator\AppData\Local\Temp\ipykernel_13668\3130018029.py:15: UserWarning: The following kwargs were not used by contour: 'linewidth' 133 plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap) 134 135 <matplotlib.collections.PathCollection at 0x23902feb970> 136 137 [24] 138 def PolynomialLogisticRegression(degree, C, penalty='l2'): 139 return Pipeline([ 140 ("poly",PolynomialFeatures(degree=degree)), 141 ("std_scaler",StandardScaler()), 142 ("log_reg",LogisticRegression(C=C)) 143 ]) 144 [25] 145 poly_log_reg4 = PolynomialLogisticRegression(degree=20,C=0.1,penalty='l1') 146 poly_log_reg4.fit(X_train,y_train) 147 Pipeline(steps=[('poly', PolynomialFeatures(degree=20)), 148 ('std_scaler', StandardScaler()), 149 ('log_reg', LogisticRegression(C=0.1))]) 150 [26] 151 poly_log_reg4.score(X_train,y_train) 152 0.84 153 [27] 154 poly_log_reg4.score(X_test,y_test) 155 0.92 156 [28] 157 plot_decision_boundary(poly_log_reg4, axis=[-4,4,-4,4]) 158 plt.scatter(X[y==0,0], X[y==0,1]) 159 plt.scatter(X[y==1,0], X[y==1,1]) 160 C:\Users\Administrator\AppData\Local\Temp\ipykernel_13668\3130018029.py:15: UserWarning: The following kwargs were not used by contour: 'linewidth' 161 plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap) 162 163 <matplotlib.collections.PathCollection at 0x23902b3c760>
9-8 OvR与OvO
Notbook 示例
Notbook 源码
1 OvR 和 OvO 2 [1] 3 import numpy as np 4 import matplotlib.pyplot as plt 5 from sklearn import datasets 6 7 iris = datasets.load_iris() 8 X = iris.data[:, :2] 9 y = iris.target 10 [2] 11 from sklearn.model_selection import train_test_split 12 13 X_train, X_test, y_train, y_test = train_test_split(X, y,random_state=7) 14 [3] 15 from sklearn.linear_model import LogisticRegression 16 17 log_reg = LogisticRegression(multi_class="ovr") 18 log_reg.fit(X_train,y_train) 19 LogisticRegression(multi_class='ovr') 20 [4] 21 log_reg.score(X_test,y_test) 22 0.6052631578947368 23 [5] 24 def plot_decision_boundary(model, axis): 25 26 x0, x1 = np.meshgrid( 27 np.linspace(axis[0], axis[1], int((axis[1]-axis[0])*100)).reshape(-1,1), 28 np.linspace(axis[2], axis[3], int((axis[3]-axis[2])*100)).reshape(-1,1) 29 ) 30 X_new = np.c_[x0.ravel(), x1.ravel()] 31 32 y_predict = model.predict(X_new) 33 zz = y_predict.reshape(x0.shape) 34 35 from matplotlib.colors import ListedColormap 36 custom_cmap = ListedColormap(['#EF9A9A','#FFF59D','#90CAF9']) 37 38 plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap) 39 [6] 40 plot_decision_boundary(log_reg, axis=[4,8.5,1.5,4.5]) 41 plt.scatter(X[y==0,0], X[y==0,1]) 42 plt.scatter(X[y==1,0], X[y==1,1]) 43 plt.scatter(X[y==2,0], X[y==2,1]) 44 C:\Users\Administrator\AppData\Local\Temp\ipykernel_8836\3130018029.py:15: UserWarning: The following kwargs were not used by contour: 'linewidth' 45 plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap) 46 47 <matplotlib.collections.PathCollection at 0x277418551f0> 48 49 [7] 50 log_reg2 = LogisticRegression(multi_class="multinomial", solver='newton-cg') 51 [8] 52 log_reg2.fit(X_train, y_train) 53 log_reg2.score(X_test,y_test) 54 0.6842105263157895 55 [9] 56 plot_decision_boundary(log_reg2, axis=[4,8.5,1.5,4.5]) 57 plt.scatter(X[y==0,0], X[y==0,1]) 58 plt.scatter(X[y==1,0], X[y==1,1]) 59 plt.scatter(X[y==2,0], X[y==2,1]) 60 C:\Users\Administrator\AppData\Local\Temp\ipykernel_8836\3130018029.py:15: UserWarning: The following kwargs were not used by contour: 'linewidth' 61 plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap) 62 63 <matplotlib.collections.PathCollection at 0x27741808880> 64 65 使用所有数据 66 [10] 67 X = iris.data 68 y = iris.target 69 70 from sklearn.model_selection import train_test_split 71 72 X_train, X_test, y_train, y_test = train_test_split(X, y,random_state=654) 73 [11] 74 log_reg = LogisticRegression(multi_class="ovr") 75 log_reg.fit(X_train, y_train) 76 log_reg.score(X_test,y_test) 77 0.9473684210526315 78 [12] 79 log_reg2 = LogisticRegression() 80 log_reg2.fit(X_train, y_train) 81 log_reg2.score(X_test,y_test) 82 0.9736842105263158 83 OvO and OvR 84 [13] 85 from sklearn.multiclass import OneVsRestClassifier 86 87 ovr =OneVsRestClassifier(log_reg) 88 ovr.fit(X_train,y_train) 89 ovr.score(X_test,y_test) 90 0.9473684210526315 91 [14] 92 from sklearn.multiclass import OneVsOneClassifier 93 94 ovo = OneVsOneClassifier(log_reg) 95 ovo.fit(X_train,y_train) 96 ovo.score(X_test,y_test) 97 0.9736842105263158
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?