chore(i18n): sync translations with latest source changes (chunk 2/2, 199 changes)

pull/918/head
localizeflow[bot] 2 weeks ago
parent 53f31e2d20
commit 2944394ed4

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 502 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 494 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 425 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

@ -0,0 +1,596 @@
{
"1-Introduction/1-intro-to-ML/README.md": {
"original_hash": "69389392fa6346e0dfa30f664b7b6fec",
"translation_date": "2025-09-04T22:40:32+00:00",
"source_file": "1-Introduction/1-intro-to-ML/README.md",
"language_code": "fa"
},
"1-Introduction/1-intro-to-ML/assignment.md": {
"original_hash": "4c4698044bb8af52cfb6388a4ee0e53b",
"translation_date": "2025-09-03T23:38:44+00:00",
"source_file": "1-Introduction/1-intro-to-ML/assignment.md",
"language_code": "fa"
},
"1-Introduction/2-history-of-ML/README.md": {
"original_hash": "6a05fec147e734c3e6bfa54505648e2b",
"translation_date": "2025-09-04T22:41:05+00:00",
"source_file": "1-Introduction/2-history-of-ML/README.md",
"language_code": "fa"
},
"1-Introduction/2-history-of-ML/assignment.md": {
"original_hash": "eb6e4d5afd1b21a57d2b9e6d0aac3969",
"translation_date": "2025-09-03T23:42:42+00:00",
"source_file": "1-Introduction/2-history-of-ML/assignment.md",
"language_code": "fa"
},
"1-Introduction/3-fairness/README.md": {
"original_hash": "9a6b702d1437c0467e3c5c28d763dac2",
"translation_date": "2025-09-04T22:39:13+00:00",
"source_file": "1-Introduction/3-fairness/README.md",
"language_code": "fa"
},
"1-Introduction/3-fairness/assignment.md": {
"original_hash": "dbda60e7b1fe5f18974e7858eff0004e",
"translation_date": "2025-09-03T23:31:31+00:00",
"source_file": "1-Introduction/3-fairness/assignment.md",
"language_code": "fa"
},
"1-Introduction/4-techniques-of-ML/README.md": {
"original_hash": "9d91f3af3758fdd4569fb410575995ef",
"translation_date": "2025-09-04T22:40:01+00:00",
"source_file": "1-Introduction/4-techniques-of-ML/README.md",
"language_code": "fa"
},
"1-Introduction/4-techniques-of-ML/assignment.md": {
"original_hash": "70d65aeddc06170bc1aed5b27805f930",
"translation_date": "2025-09-03T23:35:27+00:00",
"source_file": "1-Introduction/4-techniques-of-ML/assignment.md",
"language_code": "fa"
},
"1-Introduction/README.md": {
"original_hash": "cf8ecc83f28e5b98051d2179eca08e08",
"translation_date": "2025-09-03T23:26:18+00:00",
"source_file": "1-Introduction/README.md",
"language_code": "fa"
},
"2-Regression/1-Tools/README.md": {
"original_hash": "fa81d226c71d5af7a2cade31c1c92b88",
"translation_date": "2025-09-04T22:33:17+00:00",
"source_file": "2-Regression/1-Tools/README.md",
"language_code": "fa"
},
"2-Regression/1-Tools/assignment.md": {
"original_hash": "74a5cf83e4ebc302afbcbc4f418afd0a",
"translation_date": "2025-09-03T22:36:30+00:00",
"source_file": "2-Regression/1-Tools/assignment.md",
"language_code": "fa"
},
"2-Regression/1-Tools/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-09-03T22:36:53+00:00",
"source_file": "2-Regression/1-Tools/solution/Julia/README.md",
"language_code": "fa"
},
"2-Regression/2-Data/README.md": {
"original_hash": "7c077988328ebfe33b24d07945f16eca",
"translation_date": "2025-09-04T22:33:56+00:00",
"source_file": "2-Regression/2-Data/README.md",
"language_code": "fa"
},
"2-Regression/2-Data/assignment.md": {
"original_hash": "4485a1ed4dd1b5647365e3d87456515d",
"translation_date": "2025-09-03T22:40:35+00:00",
"source_file": "2-Regression/2-Data/assignment.md",
"language_code": "fa"
},
"2-Regression/2-Data/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-09-03T22:40:56+00:00",
"source_file": "2-Regression/2-Data/solution/Julia/README.md",
"language_code": "fa"
},
"2-Regression/3-Linear/README.md": {
"original_hash": "40e64f004f3cb50aa1d8661672d3cd92",
"translation_date": "2025-09-04T22:31:20+00:00",
"source_file": "2-Regression/3-Linear/README.md",
"language_code": "fa"
},
"2-Regression/3-Linear/assignment.md": {
"original_hash": "cc471fa89c293bc735dd3a9a0fb79b1b",
"translation_date": "2025-09-03T22:22:20+00:00",
"source_file": "2-Regression/3-Linear/assignment.md",
"language_code": "fa"
},
"2-Regression/3-Linear/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-09-03T22:22:42+00:00",
"source_file": "2-Regression/3-Linear/solution/Julia/README.md",
"language_code": "fa"
},
"2-Regression/4-Logistic/README.md": {
"original_hash": "abf86d845c84330bce205a46b382ec88",
"translation_date": "2025-09-04T22:32:20+00:00",
"source_file": "2-Regression/4-Logistic/README.md",
"language_code": "fa"
},
"2-Regression/4-Logistic/assignment.md": {
"original_hash": "8af40209a41494068c1f42b14c0b450d",
"translation_date": "2025-09-03T22:31:27+00:00",
"source_file": "2-Regression/4-Logistic/assignment.md",
"language_code": "fa"
},
"2-Regression/4-Logistic/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-09-03T22:31:48+00:00",
"source_file": "2-Regression/4-Logistic/solution/Julia/README.md",
"language_code": "fa"
},
"2-Regression/README.md": {
"original_hash": "508582278dbb8edd2a8a80ac96ef416c",
"translation_date": "2025-09-03T22:15:39+00:00",
"source_file": "2-Regression/README.md",
"language_code": "fa"
},
"3-Web-App/1-Web-App/README.md": {
"original_hash": "e0b75f73e4a90d45181dc5581fe2ef5c",
"translation_date": "2025-09-04T22:41:40+00:00",
"source_file": "3-Web-App/1-Web-App/README.md",
"language_code": "fa"
},
"3-Web-App/1-Web-App/assignment.md": {
"original_hash": "a8e8ae10be335cbc745b75ee552317ff",
"translation_date": "2025-09-03T23:47:27+00:00",
"source_file": "3-Web-App/1-Web-App/assignment.md",
"language_code": "fa"
},
"3-Web-App/README.md": {
"original_hash": "9836ff53cfef716ddfd70e06c5f43436",
"translation_date": "2025-09-03T23:43:29+00:00",
"source_file": "3-Web-App/README.md",
"language_code": "fa"
},
"4-Classification/1-Introduction/README.md": {
"original_hash": "aaf391d922bd6de5efba871d514c6d47",
"translation_date": "2025-09-04T22:43:49+00:00",
"source_file": "4-Classification/1-Introduction/README.md",
"language_code": "fa"
},
"4-Classification/1-Introduction/assignment.md": {
"original_hash": "b2a01912beb24cfb0007f83594dba801",
"translation_date": "2025-09-04T00:04:16+00:00",
"source_file": "4-Classification/1-Introduction/assignment.md",
"language_code": "fa"
},
"4-Classification/1-Introduction/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-09-04T00:04:41+00:00",
"source_file": "4-Classification/1-Introduction/solution/Julia/README.md",
"language_code": "fa"
},
"4-Classification/2-Classifiers-1/README.md": {
"original_hash": "1a6e9e46b34a2e559fbbfc1f95397c7b",
"translation_date": "2025-09-04T22:42:21+00:00",
"source_file": "4-Classification/2-Classifiers-1/README.md",
"language_code": "fa"
},
"4-Classification/2-Classifiers-1/assignment.md": {
"original_hash": "de6025f96841498b0577e9d1aee18d1f",
"translation_date": "2025-09-03T23:54:16+00:00",
"source_file": "4-Classification/2-Classifiers-1/assignment.md",
"language_code": "fa"
},
"4-Classification/2-Classifiers-1/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-09-03T23:54:38+00:00",
"source_file": "4-Classification/2-Classifiers-1/solution/Julia/README.md",
"language_code": "fa"
},
"4-Classification/3-Classifiers-2/README.md": {
"original_hash": "49047911108adc49d605cddfb455749c",
"translation_date": "2025-09-04T22:43:29+00:00",
"source_file": "4-Classification/3-Classifiers-2/README.md",
"language_code": "fa"
},
"4-Classification/3-Classifiers-2/assignment.md": {
"original_hash": "58dfdaf79fb73f7d34b22bdbacf57329",
"translation_date": "2025-09-04T00:00:21+00:00",
"source_file": "4-Classification/3-Classifiers-2/assignment.md",
"language_code": "fa"
},
"4-Classification/3-Classifiers-2/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-09-04T00:00:56+00:00",
"source_file": "4-Classification/3-Classifiers-2/solution/Julia/README.md",
"language_code": "fa"
},
"4-Classification/4-Applied/README.md": {
"original_hash": "61bdec27ed2da8b098cd9065405d9bb0",
"translation_date": "2025-09-04T22:43:03+00:00",
"source_file": "4-Classification/4-Applied/README.md",
"language_code": "fa"
},
"4-Classification/4-Applied/assignment.md": {
"original_hash": "799ed651e2af0a7cad17c6268db11578",
"translation_date": "2025-09-03T23:57:38+00:00",
"source_file": "4-Classification/4-Applied/assignment.md",
"language_code": "fa"
},
"4-Classification/README.md": {
"original_hash": "74e809ffd1e613a1058bbc3e9600859e",
"translation_date": "2025-09-03T23:49:20+00:00",
"source_file": "4-Classification/README.md",
"language_code": "fa"
},
"5-Clustering/1-Visualize/README.md": {
"original_hash": "730225ea274c9174fe688b21d421539d",
"translation_date": "2025-09-04T22:36:14+00:00",
"source_file": "5-Clustering/1-Visualize/README.md",
"language_code": "fa"
},
"5-Clustering/1-Visualize/assignment.md": {
"original_hash": "589fa015a5e7d9e67bd629f7d47b53de",
"translation_date": "2025-09-03T23:09:26+00:00",
"source_file": "5-Clustering/1-Visualize/assignment.md",
"language_code": "fa"
},
"5-Clustering/1-Visualize/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-09-03T23:09:51+00:00",
"source_file": "5-Clustering/1-Visualize/solution/Julia/README.md",
"language_code": "fa"
},
"5-Clustering/2-K-Means/README.md": {
"original_hash": "7cdd17338d9bbd7e2171c2cd462eb081",
"translation_date": "2025-09-04T22:37:17+00:00",
"source_file": "5-Clustering/2-K-Means/README.md",
"language_code": "fa"
},
"5-Clustering/2-K-Means/assignment.md": {
"original_hash": "b8e17eff34ad1680eba2a5d3cf9ffc41",
"translation_date": "2025-09-03T23:13:02+00:00",
"source_file": "5-Clustering/2-K-Means/assignment.md",
"language_code": "fa"
},
"5-Clustering/2-K-Means/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-09-03T23:13:23+00:00",
"source_file": "5-Clustering/2-K-Means/solution/Julia/README.md",
"language_code": "fa"
},
"5-Clustering/README.md": {
"original_hash": "b28a3a4911584062772c537b653ebbc7",
"translation_date": "2025-09-03T22:56:19+00:00",
"source_file": "5-Clustering/README.md",
"language_code": "fa"
},
"6-NLP/1-Introduction-to-NLP/README.md": {
"original_hash": "1c2ec40cf55c98a028a359c27ef7e45a",
"translation_date": "2025-09-04T22:48:19+00:00",
"source_file": "6-NLP/1-Introduction-to-NLP/README.md",
"language_code": "fa"
},
"6-NLP/1-Introduction-to-NLP/assignment.md": {
"original_hash": "1d7583e8046dacbb0c056d5ba0a71b16",
"translation_date": "2025-09-04T00:49:22+00:00",
"source_file": "6-NLP/1-Introduction-to-NLP/assignment.md",
"language_code": "fa"
},
"6-NLP/2-Tasks/README.md": {
"original_hash": "5f3cb462e3122e1afe7ab0050ccf2bd3",
"translation_date": "2025-09-04T22:46:26+00:00",
"source_file": "6-NLP/2-Tasks/README.md",
"language_code": "fa"
},
"6-NLP/2-Tasks/assignment.md": {
"original_hash": "2efc4c2aba5ed06c780c05539c492ae3",
"translation_date": "2025-09-04T00:37:31+00:00",
"source_file": "6-NLP/2-Tasks/assignment.md",
"language_code": "fa"
},
"6-NLP/3-Translation-Sentiment/README.md": {
"original_hash": "be03c8182982b87ced155e4e9d1438e8",
"translation_date": "2025-09-04T22:48:48+00:00",
"source_file": "6-NLP/3-Translation-Sentiment/README.md",
"language_code": "fa"
},
"6-NLP/3-Translation-Sentiment/assignment.md": {
"original_hash": "9d2a734deb904caff310d1a999c6bd7a",
"translation_date": "2025-09-04T00:54:08+00:00",
"source_file": "6-NLP/3-Translation-Sentiment/assignment.md",
"language_code": "fa"
},
"6-NLP/3-Translation-Sentiment/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-09-04T00:54:52+00:00",
"source_file": "6-NLP/3-Translation-Sentiment/solution/Julia/README.md",
"language_code": "fa"
},
"6-NLP/3-Translation-Sentiment/solution/R/README.md": {
"original_hash": "81db6ff2cf6e62fbe2340b094bb9509e",
"translation_date": "2025-09-04T00:54:33+00:00",
"source_file": "6-NLP/3-Translation-Sentiment/solution/R/README.md",
"language_code": "fa"
},
"6-NLP/4-Hotel-Reviews-1/README.md": {
"original_hash": "8d32dadeda93c6fb5c43619854882ab1",
"translation_date": "2025-09-04T22:46:59+00:00",
"source_file": "6-NLP/4-Hotel-Reviews-1/README.md",
"language_code": "fa"
},
"6-NLP/4-Hotel-Reviews-1/assignment.md": {
"original_hash": "bf39bceb833cd628f224941dca8041df",
"translation_date": "2025-09-04T00:44:37+00:00",
"source_file": "6-NLP/4-Hotel-Reviews-1/assignment.md",
"language_code": "fa"
},
"6-NLP/4-Hotel-Reviews-1/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-09-04T00:45:17+00:00",
"source_file": "6-NLP/4-Hotel-Reviews-1/solution/Julia/README.md",
"language_code": "fa"
},
"6-NLP/4-Hotel-Reviews-1/solution/R/README.md": {
"original_hash": "81db6ff2cf6e62fbe2340b094bb9509e",
"translation_date": "2025-09-04T00:44:59+00:00",
"source_file": "6-NLP/4-Hotel-Reviews-1/solution/R/README.md",
"language_code": "fa"
},
"6-NLP/5-Hotel-Reviews-2/README.md": {
"original_hash": "2c742993fe95d5bcbb2846eda3d442a1",
"translation_date": "2025-09-04T22:49:36+00:00",
"source_file": "6-NLP/5-Hotel-Reviews-2/README.md",
"language_code": "fa"
},
"6-NLP/5-Hotel-Reviews-2/assignment.md": {
"original_hash": "daf144daa552da6a7d442aff6f3e77d8",
"translation_date": "2025-09-04T00:59:59+00:00",
"source_file": "6-NLP/5-Hotel-Reviews-2/assignment.md",
"language_code": "fa"
},
"6-NLP/5-Hotel-Reviews-2/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-09-04T01:00:41+00:00",
"source_file": "6-NLP/5-Hotel-Reviews-2/solution/Julia/README.md",
"language_code": "fa"
},
"6-NLP/5-Hotel-Reviews-2/solution/R/README.md": {
"original_hash": "81db6ff2cf6e62fbe2340b094bb9509e",
"translation_date": "2025-09-04T01:00:23+00:00",
"source_file": "6-NLP/5-Hotel-Reviews-2/solution/R/README.md",
"language_code": "fa"
},
"6-NLP/README.md": {
"original_hash": "1eb379dc2d0c9940b320732d16083778",
"translation_date": "2025-09-04T00:33:30+00:00",
"source_file": "6-NLP/README.md",
"language_code": "fa"
},
"6-NLP/data/README.md": {
"original_hash": "ee0670655c89e4719319764afb113624",
"translation_date": "2025-09-04T00:45:39+00:00",
"source_file": "6-NLP/data/README.md",
"language_code": "fa"
},
"7-TimeSeries/1-Introduction/README.md": {
"original_hash": "662b509c39eee205687726636d0a8455",
"translation_date": "2025-09-04T22:35:08+00:00",
"source_file": "7-TimeSeries/1-Introduction/README.md",
"language_code": "fa"
},
"7-TimeSeries/1-Introduction/assignment.md": {
"original_hash": "d1781b0b92568ea1d119d0a198b576b4",
"translation_date": "2025-09-03T22:51:03+00:00",
"source_file": "7-TimeSeries/1-Introduction/assignment.md",
"language_code": "fa"
},
"7-TimeSeries/1-Introduction/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-09-03T22:51:45+00:00",
"source_file": "7-TimeSeries/1-Introduction/solution/Julia/README.md",
"language_code": "fa"
},
"7-TimeSeries/1-Introduction/solution/R/README.md": {
"original_hash": "81db6ff2cf6e62fbe2340b094bb9509e",
"translation_date": "2025-09-03T22:51:27+00:00",
"source_file": "7-TimeSeries/1-Introduction/solution/R/README.md",
"language_code": "fa"
},
"7-TimeSeries/2-ARIMA/README.md": {
"original_hash": "917dbf890db71a322f306050cb284749",
"translation_date": "2025-09-04T22:34:29+00:00",
"source_file": "7-TimeSeries/2-ARIMA/README.md",
"language_code": "fa"
},
"7-TimeSeries/2-ARIMA/assignment.md": {
"original_hash": "1c814013e10866dfd92cdb32caaae3ac",
"translation_date": "2025-09-03T22:46:36+00:00",
"source_file": "7-TimeSeries/2-ARIMA/assignment.md",
"language_code": "fa"
},
"7-TimeSeries/2-ARIMA/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-09-03T22:47:16+00:00",
"source_file": "7-TimeSeries/2-ARIMA/solution/Julia/README.md",
"language_code": "fa"
},
"7-TimeSeries/2-ARIMA/solution/R/README.md": {
"original_hash": "81db6ff2cf6e62fbe2340b094bb9509e",
"translation_date": "2025-09-03T22:46:58+00:00",
"source_file": "7-TimeSeries/2-ARIMA/solution/R/README.md",
"language_code": "fa"
},
"7-TimeSeries/3-SVR/README.md": {
"original_hash": "482bccabe1df958496ea71a3667995cd",
"translation_date": "2025-09-04T22:35:42+00:00",
"source_file": "7-TimeSeries/3-SVR/README.md",
"language_code": "fa"
},
"7-TimeSeries/3-SVR/assignment.md": {
"original_hash": "94aa2fc6154252ae30a3f3740299707a",
"translation_date": "2025-09-03T22:55:17+00:00",
"source_file": "7-TimeSeries/3-SVR/assignment.md",
"language_code": "fa"
},
"7-TimeSeries/README.md": {
"original_hash": "61342603bad8acadbc6b2e4e3aab3f66",
"translation_date": "2025-09-03T22:41:38+00:00",
"source_file": "7-TimeSeries/README.md",
"language_code": "fa"
},
"8-Reinforcement/1-QLearning/README.md": {
"original_hash": "911efd5e595089000cb3c16fce1beab8",
"translation_date": "2025-09-04T22:45:00+00:00",
"source_file": "8-Reinforcement/1-QLearning/README.md",
"language_code": "fa"
},
"8-Reinforcement/1-QLearning/assignment.md": {
"original_hash": "68394b2102d3503882e5e914bd0ff5c1",
"translation_date": "2025-09-04T00:24:37+00:00",
"source_file": "8-Reinforcement/1-QLearning/assignment.md",
"language_code": "fa"
},
"8-Reinforcement/1-QLearning/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-09-04T00:25:39+00:00",
"source_file": "8-Reinforcement/1-QLearning/solution/Julia/README.md",
"language_code": "fa"
},
"8-Reinforcement/1-QLearning/solution/R/README.md": {
"original_hash": "81db6ff2cf6e62fbe2340b094bb9509e",
"translation_date": "2025-09-04T00:25:22+00:00",
"source_file": "8-Reinforcement/1-QLearning/solution/R/README.md",
"language_code": "fa"
},
"8-Reinforcement/2-Gym/README.md": {
"original_hash": "107d5bb29da8a562e7ae72262d251a75",
"translation_date": "2025-09-04T22:45:37+00:00",
"source_file": "8-Reinforcement/2-Gym/README.md",
"language_code": "fa"
},
"8-Reinforcement/2-Gym/assignment.md": {
"original_hash": "1f2b7441745eb52e25745423b247016b",
"translation_date": "2025-09-04T00:31:48+00:00",
"source_file": "8-Reinforcement/2-Gym/assignment.md",
"language_code": "fa"
},
"8-Reinforcement/2-Gym/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-09-04T00:32:44+00:00",
"source_file": "8-Reinforcement/2-Gym/solution/Julia/README.md",
"language_code": "fa"
},
"8-Reinforcement/2-Gym/solution/R/README.md": {
"original_hash": "81db6ff2cf6e62fbe2340b094bb9509e",
"translation_date": "2025-09-04T00:32:26+00:00",
"source_file": "8-Reinforcement/2-Gym/solution/R/README.md",
"language_code": "fa"
},
"8-Reinforcement/README.md": {
"original_hash": "20ca019012b1725de956681d036d8b18",
"translation_date": "2025-09-04T00:14:30+00:00",
"source_file": "8-Reinforcement/README.md",
"language_code": "fa"
},
"9-Real-World/1-Applications/README.md": {
"original_hash": "83320d6b6994909e35d830cebf214039",
"translation_date": "2025-09-04T22:37:44+00:00",
"source_file": "9-Real-World/1-Applications/README.md",
"language_code": "fa"
},
"9-Real-World/1-Applications/assignment.md": {
"original_hash": "fdebfcd0a3f12c9e2b436ded1aa79885",
"translation_date": "2025-09-03T23:19:47+00:00",
"source_file": "9-Real-World/1-Applications/assignment.md",
"language_code": "fa"
},
"9-Real-World/2-Debugging-ML-Models/README.md": {
"original_hash": "df2b538e8fbb3e91cf0419ae2f858675",
"translation_date": "2025-09-04T22:38:26+00:00",
"source_file": "9-Real-World/2-Debugging-ML-Models/README.md",
"language_code": "fa"
},
"9-Real-World/2-Debugging-ML-Models/assignment.md": {
"original_hash": "91c6a180ef08e20cc15acfd2d6d6e164",
"translation_date": "2025-09-03T23:25:34+00:00",
"source_file": "9-Real-World/2-Debugging-ML-Models/assignment.md",
"language_code": "fa"
},
"9-Real-World/README.md": {
"original_hash": "5e069a0ac02a9606a69946c2b3c574a9",
"translation_date": "2025-09-03T23:14:55+00:00",
"source_file": "9-Real-World/README.md",
"language_code": "fa"
},
"AGENTS.md": {
"original_hash": "93fdaa0fd38836e50c4793e2f2f25e8b",
"translation_date": "2025-10-03T10:58:53+00:00",
"source_file": "AGENTS.md",
"language_code": "fa"
},
"CODE_OF_CONDUCT.md": {
"original_hash": "c06b12caf3c901eb3156e3dd5b0aea56",
"translation_date": "2025-09-03T22:14:43+00:00",
"source_file": "CODE_OF_CONDUCT.md",
"language_code": "fa"
},
"CONTRIBUTING.md": {
"original_hash": "977ec5266dfd78ad1ce2bd8d46fccbda",
"translation_date": "2025-09-03T22:12:02+00:00",
"source_file": "CONTRIBUTING.md",
"language_code": "fa"
},
"README.md": {
"original_hash": "da2ceed62f16a0820259556e3a873c95",
"translation_date": "2026-01-29T17:41:26+00:00",
"source_file": "README.md",
"language_code": "fa"
},
"SECURITY.md": {
"original_hash": "5e1b8da31aae9cca3d53ad243fa3365a",
"translation_date": "2025-09-03T22:13:05+00:00",
"source_file": "SECURITY.md",
"language_code": "fa"
},
"SUPPORT.md": {
"original_hash": "09623d7343ff1c26ff4f198c1b2d3176",
"translation_date": "2025-10-03T11:39:50+00:00",
"source_file": "SUPPORT.md",
"language_code": "fa"
},
"TROUBLESHOOTING.md": {
"original_hash": "134d8759f0e2ab886e9aa4f62362c201",
"translation_date": "2025-10-03T12:37:28+00:00",
"source_file": "TROUBLESHOOTING.md",
"language_code": "fa"
},
"docs/_sidebar.md": {
"original_hash": "68dd06c685f6ce840e0acfa313352e7c",
"translation_date": "2025-09-03T23:14:07+00:00",
"source_file": "docs/_sidebar.md",
"language_code": "fa"
},
"for-teachers.md": {
"original_hash": "b37de02054fa6c0438ede6fabe1fdfb8",
"translation_date": "2025-09-03T22:14:05+00:00",
"source_file": "for-teachers.md",
"language_code": "fa"
},
"quiz-app/README.md": {
"original_hash": "6d130dffca5db70d7e615f926cb1ad4c",
"translation_date": "2025-09-03T23:48:23+00:00",
"source_file": "quiz-app/README.md",
"language_code": "fa"
},
"sketchnotes/LICENSE.md": {
"original_hash": "fba3b94d88bfb9b81369b869a1e9a20f",
"translation_date": "2025-09-04T00:11:51+00:00",
"source_file": "sketchnotes/LICENSE.md",
"language_code": "fa"
},
"sketchnotes/README.md": {
"original_hash": "a88d5918c1b9da69a40d917a0840c497",
"translation_date": "2025-09-04T00:05:08+00:00",
"source_file": "sketchnotes/README.md",
"language_code": "fa"
}
}

@ -0,0 +1,596 @@
{
"1-Introduction/1-intro-to-ML/README.md": {
"original_hash": "69389392fa6346e0dfa30f664b7b6fec",
"translation_date": "2025-09-06T08:53:11+00:00",
"source_file": "1-Introduction/1-intro-to-ML/README.md",
"language_code": "ur"
},
"1-Introduction/1-intro-to-ML/assignment.md": {
"original_hash": "4c4698044bb8af52cfb6388a4ee0e53b",
"translation_date": "2025-08-29T13:44:16+00:00",
"source_file": "1-Introduction/1-intro-to-ML/assignment.md",
"language_code": "ur"
},
"1-Introduction/2-history-of-ML/README.md": {
"original_hash": "6a05fec147e734c3e6bfa54505648e2b",
"translation_date": "2025-09-06T08:53:42+00:00",
"source_file": "1-Introduction/2-history-of-ML/README.md",
"language_code": "ur"
},
"1-Introduction/2-history-of-ML/assignment.md": {
"original_hash": "eb6e4d5afd1b21a57d2b9e6d0aac3969",
"translation_date": "2025-08-29T13:47:20+00:00",
"source_file": "1-Introduction/2-history-of-ML/assignment.md",
"language_code": "ur"
},
"1-Introduction/3-fairness/README.md": {
"original_hash": "9a6b702d1437c0467e3c5c28d763dac2",
"translation_date": "2025-09-06T08:51:44+00:00",
"source_file": "1-Introduction/3-fairness/README.md",
"language_code": "ur"
},
"1-Introduction/3-fairness/assignment.md": {
"original_hash": "dbda60e7b1fe5f18974e7858eff0004e",
"translation_date": "2025-08-29T13:38:50+00:00",
"source_file": "1-Introduction/3-fairness/assignment.md",
"language_code": "ur"
},
"1-Introduction/4-techniques-of-ML/README.md": {
"original_hash": "9d91f3af3758fdd4569fb410575995ef",
"translation_date": "2025-09-06T08:52:31+00:00",
"source_file": "1-Introduction/4-techniques-of-ML/README.md",
"language_code": "ur"
},
"1-Introduction/4-techniques-of-ML/assignment.md": {
"original_hash": "70d65aeddc06170bc1aed5b27805f930",
"translation_date": "2025-08-29T13:42:01+00:00",
"source_file": "1-Introduction/4-techniques-of-ML/assignment.md",
"language_code": "ur"
},
"1-Introduction/README.md": {
"original_hash": "cf8ecc83f28e5b98051d2179eca08e08",
"translation_date": "2025-08-29T13:35:37+00:00",
"source_file": "1-Introduction/README.md",
"language_code": "ur"
},
"2-Regression/1-Tools/README.md": {
"original_hash": "fa81d226c71d5af7a2cade31c1c92b88",
"translation_date": "2025-09-06T08:45:16+00:00",
"source_file": "2-Regression/1-Tools/README.md",
"language_code": "ur"
},
"2-Regression/1-Tools/assignment.md": {
"original_hash": "74a5cf83e4ebc302afbcbc4f418afd0a",
"translation_date": "2025-08-29T13:05:05+00:00",
"source_file": "2-Regression/1-Tools/assignment.md",
"language_code": "ur"
},
"2-Regression/1-Tools/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-08-29T13:05:27+00:00",
"source_file": "2-Regression/1-Tools/solution/Julia/README.md",
"language_code": "ur"
},
"2-Regression/2-Data/README.md": {
"original_hash": "7c077988328ebfe33b24d07945f16eca",
"translation_date": "2025-09-06T08:46:01+00:00",
"source_file": "2-Regression/2-Data/README.md",
"language_code": "ur"
},
"2-Regression/2-Data/assignment.md": {
"original_hash": "4485a1ed4dd1b5647365e3d87456515d",
"translation_date": "2025-08-29T13:08:12+00:00",
"source_file": "2-Regression/2-Data/assignment.md",
"language_code": "ur"
},
"2-Regression/2-Data/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-08-29T13:08:29+00:00",
"source_file": "2-Regression/2-Data/solution/Julia/README.md",
"language_code": "ur"
},
"2-Regression/3-Linear/README.md": {
"original_hash": "40e64f004f3cb50aa1d8661672d3cd92",
"translation_date": "2025-09-06T08:43:17+00:00",
"source_file": "2-Regression/3-Linear/README.md",
"language_code": "ur"
},
"2-Regression/3-Linear/assignment.md": {
"original_hash": "cc471fa89c293bc735dd3a9a0fb79b1b",
"translation_date": "2025-08-29T12:56:05+00:00",
"source_file": "2-Regression/3-Linear/assignment.md",
"language_code": "ur"
},
"2-Regression/3-Linear/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-08-29T12:56:23+00:00",
"source_file": "2-Regression/3-Linear/solution/Julia/README.md",
"language_code": "ur"
},
"2-Regression/4-Logistic/README.md": {
"original_hash": "abf86d845c84330bce205a46b382ec88",
"translation_date": "2025-09-06T08:44:16+00:00",
"source_file": "2-Regression/4-Logistic/README.md",
"language_code": "ur"
},
"2-Regression/4-Logistic/assignment.md": {
"original_hash": "8af40209a41494068c1f42b14c0b450d",
"translation_date": "2025-08-29T13:01:20+00:00",
"source_file": "2-Regression/4-Logistic/assignment.md",
"language_code": "ur"
},
"2-Regression/4-Logistic/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-08-29T13:01:38+00:00",
"source_file": "2-Regression/4-Logistic/solution/Julia/README.md",
"language_code": "ur"
},
"2-Regression/README.md": {
"original_hash": "508582278dbb8edd2a8a80ac96ef416c",
"translation_date": "2025-08-29T12:51:42+00:00",
"source_file": "2-Regression/README.md",
"language_code": "ur"
},
"3-Web-App/1-Web-App/README.md": {
"original_hash": "e0b75f73e4a90d45181dc5581fe2ef5c",
"translation_date": "2025-09-06T08:54:15+00:00",
"source_file": "3-Web-App/1-Web-App/README.md",
"language_code": "ur"
},
"3-Web-App/1-Web-App/assignment.md": {
"original_hash": "a8e8ae10be335cbc745b75ee552317ff",
"translation_date": "2025-08-29T13:50:30+00:00",
"source_file": "3-Web-App/1-Web-App/assignment.md",
"language_code": "ur"
},
"3-Web-App/README.md": {
"original_hash": "9836ff53cfef716ddfd70e06c5f43436",
"translation_date": "2025-08-29T13:47:43+00:00",
"source_file": "3-Web-App/README.md",
"language_code": "ur"
},
"4-Classification/1-Introduction/README.md": {
"original_hash": "aaf391d922bd6de5efba871d514c6d47",
"translation_date": "2025-09-06T08:56:19+00:00",
"source_file": "4-Classification/1-Introduction/README.md",
"language_code": "ur"
},
"4-Classification/1-Introduction/assignment.md": {
"original_hash": "b2a01912beb24cfb0007f83594dba801",
"translation_date": "2025-08-29T14:01:43+00:00",
"source_file": "4-Classification/1-Introduction/assignment.md",
"language_code": "ur"
},
"4-Classification/1-Introduction/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-08-29T14:02:06+00:00",
"source_file": "4-Classification/1-Introduction/solution/Julia/README.md",
"language_code": "ur"
},
"4-Classification/2-Classifiers-1/README.md": {
"original_hash": "1a6e9e46b34a2e559fbbfc1f95397c7b",
"translation_date": "2025-09-06T08:54:49+00:00",
"source_file": "4-Classification/2-Classifiers-1/README.md",
"language_code": "ur"
},
"4-Classification/2-Classifiers-1/assignment.md": {
"original_hash": "de6025f96841498b0577e9d1aee18d1f",
"translation_date": "2025-08-29T13:55:24+00:00",
"source_file": "4-Classification/2-Classifiers-1/assignment.md",
"language_code": "ur"
},
"4-Classification/2-Classifiers-1/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-08-29T13:55:44+00:00",
"source_file": "4-Classification/2-Classifiers-1/solution/Julia/README.md",
"language_code": "ur"
},
"4-Classification/3-Classifiers-2/README.md": {
"original_hash": "49047911108adc49d605cddfb455749c",
"translation_date": "2025-09-06T08:55:57+00:00",
"source_file": "4-Classification/3-Classifiers-2/README.md",
"language_code": "ur"
},
"4-Classification/3-Classifiers-2/assignment.md": {
"original_hash": "58dfdaf79fb73f7d34b22bdbacf57329",
"translation_date": "2025-08-29T13:59:19+00:00",
"source_file": "4-Classification/3-Classifiers-2/assignment.md",
"language_code": "ur"
},
"4-Classification/3-Classifiers-2/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-08-29T13:59:38+00:00",
"source_file": "4-Classification/3-Classifiers-2/solution/Julia/README.md",
"language_code": "ur"
},
"4-Classification/4-Applied/README.md": {
"original_hash": "61bdec27ed2da8b098cd9065405d9bb0",
"translation_date": "2025-09-06T08:55:31+00:00",
"source_file": "4-Classification/4-Applied/README.md",
"language_code": "ur"
},
"4-Classification/4-Applied/assignment.md": {
"original_hash": "799ed651e2af0a7cad17c6268db11578",
"translation_date": "2025-08-29T13:57:35+00:00",
"source_file": "4-Classification/4-Applied/assignment.md",
"language_code": "ur"
},
"4-Classification/README.md": {
"original_hash": "74e809ffd1e613a1058bbc3e9600859e",
"translation_date": "2025-08-29T13:51:45+00:00",
"source_file": "4-Classification/README.md",
"language_code": "ur"
},
"5-Clustering/1-Visualize/README.md": {
"original_hash": "730225ea274c9174fe688b21d421539d",
"translation_date": "2025-09-06T08:48:36+00:00",
"source_file": "5-Clustering/1-Visualize/README.md",
"language_code": "ur"
},
"5-Clustering/1-Visualize/assignment.md": {
"original_hash": "589fa015a5e7d9e67bd629f7d47b53de",
"translation_date": "2025-08-29T13:25:29+00:00",
"source_file": "5-Clustering/1-Visualize/assignment.md",
"language_code": "ur"
},
"5-Clustering/1-Visualize/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-08-29T13:25:50+00:00",
"source_file": "5-Clustering/1-Visualize/solution/Julia/README.md",
"language_code": "ur"
},
"5-Clustering/2-K-Means/README.md": {
"original_hash": "7cdd17338d9bbd7e2171c2cd462eb081",
"translation_date": "2025-09-06T08:49:43+00:00",
"source_file": "5-Clustering/2-K-Means/README.md",
"language_code": "ur"
},
"5-Clustering/2-K-Means/assignment.md": {
"original_hash": "b8e17eff34ad1680eba2a5d3cf9ffc41",
"translation_date": "2025-08-29T13:27:54+00:00",
"source_file": "5-Clustering/2-K-Means/assignment.md",
"language_code": "ur"
},
"5-Clustering/2-K-Means/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-08-29T13:28:12+00:00",
"source_file": "5-Clustering/2-K-Means/solution/Julia/README.md",
"language_code": "ur"
},
"5-Clustering/README.md": {
"original_hash": "b28a3a4911584062772c537b653ebbc7",
"translation_date": "2025-08-29T13:18:41+00:00",
"source_file": "5-Clustering/README.md",
"language_code": "ur"
},
"6-NLP/1-Introduction-to-NLP/README.md": {
"original_hash": "1c2ec40cf55c98a028a359c27ef7e45a",
"translation_date": "2025-09-06T09:01:56+00:00",
"source_file": "6-NLP/1-Introduction-to-NLP/README.md",
"language_code": "ur"
},
"6-NLP/1-Introduction-to-NLP/assignment.md": {
"original_hash": "1d7583e8046dacbb0c056d5ba0a71b16",
"translation_date": "2025-08-29T14:32:08+00:00",
"source_file": "6-NLP/1-Introduction-to-NLP/assignment.md",
"language_code": "ur"
},
"6-NLP/2-Tasks/README.md": {
"original_hash": "5f3cb462e3122e1afe7ab0050ccf2bd3",
"translation_date": "2025-09-06T08:58:58+00:00",
"source_file": "6-NLP/2-Tasks/README.md",
"language_code": "ur"
},
"6-NLP/2-Tasks/assignment.md": {
"original_hash": "2efc4c2aba5ed06c780c05539c492ae3",
"translation_date": "2025-08-29T14:22:27+00:00",
"source_file": "6-NLP/2-Tasks/assignment.md",
"language_code": "ur"
},
"6-NLP/3-Translation-Sentiment/README.md": {
"original_hash": "be03c8182982b87ced155e4e9d1438e8",
"translation_date": "2025-09-06T09:02:30+00:00",
"source_file": "6-NLP/3-Translation-Sentiment/README.md",
"language_code": "ur"
},
"6-NLP/3-Translation-Sentiment/assignment.md": {
"original_hash": "9d2a734deb904caff310d1a999c6bd7a",
"translation_date": "2025-08-29T14:35:10+00:00",
"source_file": "6-NLP/3-Translation-Sentiment/assignment.md",
"language_code": "ur"
},
"6-NLP/3-Translation-Sentiment/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-08-29T14:35:43+00:00",
"source_file": "6-NLP/3-Translation-Sentiment/solution/Julia/README.md",
"language_code": "ur"
},
"6-NLP/3-Translation-Sentiment/solution/R/README.md": {
"original_hash": "81db6ff2cf6e62fbe2340b094bb9509e",
"translation_date": "2025-08-29T14:35:30+00:00",
"source_file": "6-NLP/3-Translation-Sentiment/solution/R/README.md",
"language_code": "ur"
},
"6-NLP/4-Hotel-Reviews-1/README.md": {
"original_hash": "8d32dadeda93c6fb5c43619854882ab1",
"translation_date": "2025-09-06T09:00:38+00:00",
"source_file": "6-NLP/4-Hotel-Reviews-1/README.md",
"language_code": "ur"
},
"6-NLP/4-Hotel-Reviews-1/assignment.md": {
"original_hash": "bf39bceb833cd628f224941dca8041df",
"translation_date": "2025-08-29T14:29:12+00:00",
"source_file": "6-NLP/4-Hotel-Reviews-1/assignment.md",
"language_code": "ur"
},
"6-NLP/4-Hotel-Reviews-1/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-08-29T14:29:40+00:00",
"source_file": "6-NLP/4-Hotel-Reviews-1/solution/Julia/README.md",
"language_code": "ur"
},
"6-NLP/4-Hotel-Reviews-1/solution/R/README.md": {
"original_hash": "81db6ff2cf6e62fbe2340b094bb9509e",
"translation_date": "2025-08-29T14:29:27+00:00",
"source_file": "6-NLP/4-Hotel-Reviews-1/solution/R/README.md",
"language_code": "ur"
},
"6-NLP/5-Hotel-Reviews-2/README.md": {
"original_hash": "2c742993fe95d5bcbb2846eda3d442a1",
"translation_date": "2025-09-06T09:03:36+00:00",
"source_file": "6-NLP/5-Hotel-Reviews-2/README.md",
"language_code": "ur"
},
"6-NLP/5-Hotel-Reviews-2/assignment.md": {
"original_hash": "daf144daa552da6a7d442aff6f3e77d8",
"translation_date": "2025-08-29T14:38:51+00:00",
"source_file": "6-NLP/5-Hotel-Reviews-2/assignment.md",
"language_code": "ur"
},
"6-NLP/5-Hotel-Reviews-2/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-08-29T14:39:24+00:00",
"source_file": "6-NLP/5-Hotel-Reviews-2/solution/Julia/README.md",
"language_code": "ur"
},
"6-NLP/5-Hotel-Reviews-2/solution/R/README.md": {
"original_hash": "81db6ff2cf6e62fbe2340b094bb9509e",
"translation_date": "2025-08-29T14:39:09+00:00",
"source_file": "6-NLP/5-Hotel-Reviews-2/solution/R/README.md",
"language_code": "ur"
},
"6-NLP/README.md": {
"original_hash": "1eb379dc2d0c9940b320732d16083778",
"translation_date": "2025-08-29T14:19:12+00:00",
"source_file": "6-NLP/README.md",
"language_code": "ur"
},
"6-NLP/data/README.md": {
"original_hash": "ee0670655c89e4719319764afb113624",
"translation_date": "2025-08-29T14:29:53+00:00",
"source_file": "6-NLP/data/README.md",
"language_code": "ur"
},
"7-TimeSeries/1-Introduction/README.md": {
"original_hash": "662b509c39eee205687726636d0a8455",
"translation_date": "2025-09-06T08:47:30+00:00",
"source_file": "7-TimeSeries/1-Introduction/README.md",
"language_code": "ur"
},
"7-TimeSeries/1-Introduction/assignment.md": {
"original_hash": "d1781b0b92568ea1d119d0a198b576b4",
"translation_date": "2025-08-29T13:15:05+00:00",
"source_file": "7-TimeSeries/1-Introduction/assignment.md",
"language_code": "ur"
},
"7-TimeSeries/1-Introduction/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-08-29T13:15:48+00:00",
"source_file": "7-TimeSeries/1-Introduction/solution/Julia/README.md",
"language_code": "ur"
},
"7-TimeSeries/1-Introduction/solution/R/README.md": {
"original_hash": "81db6ff2cf6e62fbe2340b094bb9509e",
"translation_date": "2025-08-29T13:15:32+00:00",
"source_file": "7-TimeSeries/1-Introduction/solution/R/README.md",
"language_code": "ur"
},
"7-TimeSeries/2-ARIMA/README.md": {
"original_hash": "917dbf890db71a322f306050cb284749",
"translation_date": "2025-09-06T08:46:38+00:00",
"source_file": "7-TimeSeries/2-ARIMA/README.md",
"language_code": "ur"
},
"7-TimeSeries/2-ARIMA/assignment.md": {
"original_hash": "1c814013e10866dfd92cdb32caaae3ac",
"translation_date": "2025-08-29T13:11:54+00:00",
"source_file": "7-TimeSeries/2-ARIMA/assignment.md",
"language_code": "ur"
},
"7-TimeSeries/2-ARIMA/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-08-29T13:12:28+00:00",
"source_file": "7-TimeSeries/2-ARIMA/solution/Julia/README.md",
"language_code": "ur"
},
"7-TimeSeries/2-ARIMA/solution/R/README.md": {
"original_hash": "81db6ff2cf6e62fbe2340b094bb9509e",
"translation_date": "2025-08-29T13:12:14+00:00",
"source_file": "7-TimeSeries/2-ARIMA/solution/R/README.md",
"language_code": "ur"
},
"7-TimeSeries/3-SVR/README.md": {
"original_hash": "482bccabe1df958496ea71a3667995cd",
"translation_date": "2025-09-06T08:48:05+00:00",
"source_file": "7-TimeSeries/3-SVR/README.md",
"language_code": "ur"
},
"7-TimeSeries/3-SVR/assignment.md": {
"original_hash": "94aa2fc6154252ae30a3f3740299707a",
"translation_date": "2025-08-29T13:18:11+00:00",
"source_file": "7-TimeSeries/3-SVR/assignment.md",
"language_code": "ur"
},
"7-TimeSeries/README.md": {
"original_hash": "61342603bad8acadbc6b2e4e3aab3f66",
"translation_date": "2025-08-29T13:08:50+00:00",
"source_file": "7-TimeSeries/README.md",
"language_code": "ur"
},
"8-Reinforcement/1-QLearning/README.md": {
"original_hash": "911efd5e595089000cb3c16fce1beab8",
"translation_date": "2025-09-06T08:57:34+00:00",
"source_file": "8-Reinforcement/1-QLearning/README.md",
"language_code": "ur"
},
"8-Reinforcement/1-QLearning/assignment.md": {
"original_hash": "68394b2102d3503882e5e914bd0ff5c1",
"translation_date": "2025-08-29T14:14:05+00:00",
"source_file": "8-Reinforcement/1-QLearning/assignment.md",
"language_code": "ur"
},
"8-Reinforcement/1-QLearning/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-08-29T14:15:11+00:00",
"source_file": "8-Reinforcement/1-QLearning/solution/Julia/README.md",
"language_code": "ur"
},
"8-Reinforcement/1-QLearning/solution/R/README.md": {
"original_hash": "81db6ff2cf6e62fbe2340b094bb9509e",
"translation_date": "2025-08-29T14:14:57+00:00",
"source_file": "8-Reinforcement/1-QLearning/solution/R/README.md",
"language_code": "ur"
},
"8-Reinforcement/2-Gym/README.md": {
"original_hash": "107d5bb29da8a562e7ae72262d251a75",
"translation_date": "2025-09-06T08:58:16+00:00",
"source_file": "8-Reinforcement/2-Gym/README.md",
"language_code": "ur"
},
"8-Reinforcement/2-Gym/assignment.md": {
"original_hash": "1f2b7441745eb52e25745423b247016b",
"translation_date": "2025-08-29T14:18:07+00:00",
"source_file": "8-Reinforcement/2-Gym/assignment.md",
"language_code": "ur"
},
"8-Reinforcement/2-Gym/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-08-29T14:18:51+00:00",
"source_file": "8-Reinforcement/2-Gym/solution/Julia/README.md",
"language_code": "ur"
},
"8-Reinforcement/2-Gym/solution/R/README.md": {
"original_hash": "81db6ff2cf6e62fbe2340b094bb9509e",
"translation_date": "2025-08-29T14:18:37+00:00",
"source_file": "8-Reinforcement/2-Gym/solution/R/README.md",
"language_code": "ur"
},
"8-Reinforcement/README.md": {
"original_hash": "20ca019012b1725de956681d036d8b18",
"translation_date": "2025-08-29T14:07:54+00:00",
"source_file": "8-Reinforcement/README.md",
"language_code": "ur"
},
"9-Real-World/1-Applications/README.md": {
"original_hash": "83320d6b6994909e35d830cebf214039",
"translation_date": "2025-09-06T08:50:10+00:00",
"source_file": "9-Real-World/1-Applications/README.md",
"language_code": "ur"
},
"9-Real-World/1-Applications/assignment.md": {
"original_hash": "fdebfcd0a3f12c9e2b436ded1aa79885",
"translation_date": "2025-08-29T13:32:06+00:00",
"source_file": "9-Real-World/1-Applications/assignment.md",
"language_code": "ur"
},
"9-Real-World/2-Debugging-ML-Models/README.md": {
"original_hash": "df2b538e8fbb3e91cf0419ae2f858675",
"translation_date": "2025-09-06T08:50:55+00:00",
"source_file": "9-Real-World/2-Debugging-ML-Models/README.md",
"language_code": "ur"
},
"9-Real-World/2-Debugging-ML-Models/assignment.md": {
"original_hash": "91c6a180ef08e20cc15acfd2d6d6e164",
"translation_date": "2025-08-29T13:35:10+00:00",
"source_file": "9-Real-World/2-Debugging-ML-Models/assignment.md",
"language_code": "ur"
},
"9-Real-World/README.md": {
"original_hash": "5e069a0ac02a9606a69946c2b3c574a9",
"translation_date": "2025-08-29T13:29:08+00:00",
"source_file": "9-Real-World/README.md",
"language_code": "ur"
},
"AGENTS.md": {
"original_hash": "93fdaa0fd38836e50c4793e2f2f25e8b",
"translation_date": "2025-10-03T10:59:25+00:00",
"source_file": "AGENTS.md",
"language_code": "ur"
},
"CODE_OF_CONDUCT.md": {
"original_hash": "c06b12caf3c901eb3156e3dd5b0aea56",
"translation_date": "2025-08-29T12:51:12+00:00",
"source_file": "CODE_OF_CONDUCT.md",
"language_code": "ur"
},
"CONTRIBUTING.md": {
"original_hash": "977ec5266dfd78ad1ce2bd8d46fccbda",
"translation_date": "2025-08-29T12:49:28+00:00",
"source_file": "CONTRIBUTING.md",
"language_code": "ur"
},
"README.md": {
"original_hash": "da2ceed62f16a0820259556e3a873c95",
"translation_date": "2026-01-29T17:42:58+00:00",
"source_file": "README.md",
"language_code": "ur"
},
"SECURITY.md": {
"original_hash": "5e1b8da31aae9cca3d53ad243fa3365a",
"translation_date": "2025-08-29T12:50:02+00:00",
"source_file": "SECURITY.md",
"language_code": "ur"
},
"SUPPORT.md": {
"original_hash": "09623d7343ff1c26ff4f198c1b2d3176",
"translation_date": "2025-10-03T11:40:56+00:00",
"source_file": "SUPPORT.md",
"language_code": "ur"
},
"TROUBLESHOOTING.md": {
"original_hash": "134d8759f0e2ab886e9aa4f62362c201",
"translation_date": "2025-10-03T12:37:51+00:00",
"source_file": "TROUBLESHOOTING.md",
"language_code": "ur"
},
"docs/_sidebar.md": {
"original_hash": "68dd06c685f6ce840e0acfa313352e7c",
"translation_date": "2025-08-29T13:28:33+00:00",
"source_file": "docs/_sidebar.md",
"language_code": "ur"
},
"for-teachers.md": {
"original_hash": "b37de02054fa6c0438ede6fabe1fdfb8",
"translation_date": "2025-08-29T12:50:43+00:00",
"source_file": "for-teachers.md",
"language_code": "ur"
},
"quiz-app/README.md": {
"original_hash": "6d130dffca5db70d7e615f926cb1ad4c",
"translation_date": "2025-08-29T13:51:00+00:00",
"source_file": "quiz-app/README.md",
"language_code": "ur"
},
"sketchnotes/LICENSE.md": {
"original_hash": "fba3b94d88bfb9b81369b869a1e9a20f",
"translation_date": "2025-08-29T14:04:44+00:00",
"source_file": "sketchnotes/LICENSE.md",
"language_code": "ur"
},
"sketchnotes/README.md": {
"original_hash": "a88d5918c1b9da69a40d917a0840c497",
"translation_date": "2025-08-29T14:02:20+00:00",
"source_file": "sketchnotes/README.md",
"language_code": "ur"
}
}

@ -0,0 +1,596 @@
{
"1-Introduction/1-intro-to-ML/README.md": {
"original_hash": "69389392fa6346e0dfa30f664b7b6fec",
"translation_date": "2025-09-05T09:05:11+00:00",
"source_file": "1-Introduction/1-intro-to-ML/README.md",
"language_code": "zh-CN"
},
"1-Introduction/1-intro-to-ML/assignment.md": {
"original_hash": "4c4698044bb8af52cfb6388a4ee0e53b",
"translation_date": "2025-09-03T17:48:58+00:00",
"source_file": "1-Introduction/1-intro-to-ML/assignment.md",
"language_code": "zh-CN"
},
"1-Introduction/2-history-of-ML/README.md": {
"original_hash": "6a05fec147e734c3e6bfa54505648e2b",
"translation_date": "2025-09-05T09:05:36+00:00",
"source_file": "1-Introduction/2-history-of-ML/README.md",
"language_code": "zh-CN"
},
"1-Introduction/2-history-of-ML/assignment.md": {
"original_hash": "eb6e4d5afd1b21a57d2b9e6d0aac3969",
"translation_date": "2025-09-03T17:52:58+00:00",
"source_file": "1-Introduction/2-history-of-ML/assignment.md",
"language_code": "zh-CN"
},
"1-Introduction/3-fairness/README.md": {
"original_hash": "9a6b702d1437c0467e3c5c28d763dac2",
"translation_date": "2025-09-05T09:04:06+00:00",
"source_file": "1-Introduction/3-fairness/README.md",
"language_code": "zh-CN"
},
"1-Introduction/3-fairness/assignment.md": {
"original_hash": "dbda60e7b1fe5f18974e7858eff0004e",
"translation_date": "2025-09-03T17:41:11+00:00",
"source_file": "1-Introduction/3-fairness/assignment.md",
"language_code": "zh-CN"
},
"1-Introduction/4-techniques-of-ML/README.md": {
"original_hash": "9d91f3af3758fdd4569fb410575995ef",
"translation_date": "2025-09-05T09:04:44+00:00",
"source_file": "1-Introduction/4-techniques-of-ML/README.md",
"language_code": "zh-CN"
},
"1-Introduction/4-techniques-of-ML/assignment.md": {
"original_hash": "70d65aeddc06170bc1aed5b27805f930",
"translation_date": "2025-09-03T17:45:24+00:00",
"source_file": "1-Introduction/4-techniques-of-ML/assignment.md",
"language_code": "zh-CN"
},
"1-Introduction/README.md": {
"original_hash": "cf8ecc83f28e5b98051d2179eca08e08",
"translation_date": "2025-09-03T17:33:58+00:00",
"source_file": "1-Introduction/README.md",
"language_code": "zh-CN"
},
"2-Regression/1-Tools/README.md": {
"original_hash": "fa81d226c71d5af7a2cade31c1c92b88",
"translation_date": "2025-09-05T08:58:09+00:00",
"source_file": "2-Regression/1-Tools/README.md",
"language_code": "zh-CN"
},
"2-Regression/1-Tools/assignment.md": {
"original_hash": "74a5cf83e4ebc302afbcbc4f418afd0a",
"translation_date": "2025-09-03T16:40:46+00:00",
"source_file": "2-Regression/1-Tools/assignment.md",
"language_code": "zh-CN"
},
"2-Regression/1-Tools/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-09-03T16:41:15+00:00",
"source_file": "2-Regression/1-Tools/solution/Julia/README.md",
"language_code": "zh-CN"
},
"2-Regression/2-Data/README.md": {
"original_hash": "7c077988328ebfe33b24d07945f16eca",
"translation_date": "2025-09-05T08:58:47+00:00",
"source_file": "2-Regression/2-Data/README.md",
"language_code": "zh-CN"
},
"2-Regression/2-Data/assignment.md": {
"original_hash": "4485a1ed4dd1b5647365e3d87456515d",
"translation_date": "2025-09-03T16:45:08+00:00",
"source_file": "2-Regression/2-Data/assignment.md",
"language_code": "zh-CN"
},
"2-Regression/2-Data/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-09-03T16:45:35+00:00",
"source_file": "2-Regression/2-Data/solution/Julia/README.md",
"language_code": "zh-CN"
},
"2-Regression/3-Linear/README.md": {
"original_hash": "40e64f004f3cb50aa1d8661672d3cd92",
"translation_date": "2025-09-05T08:55:34+00:00",
"source_file": "2-Regression/3-Linear/README.md",
"language_code": "zh-CN"
},
"2-Regression/3-Linear/assignment.md": {
"original_hash": "cc471fa89c293bc735dd3a9a0fb79b1b",
"translation_date": "2025-09-03T16:25:06+00:00",
"source_file": "2-Regression/3-Linear/assignment.md",
"language_code": "zh-CN"
},
"2-Regression/3-Linear/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-09-03T16:25:33+00:00",
"source_file": "2-Regression/3-Linear/solution/Julia/README.md",
"language_code": "zh-CN"
},
"2-Regression/4-Logistic/README.md": {
"original_hash": "abf86d845c84330bce205a46b382ec88",
"translation_date": "2025-09-05T08:57:14+00:00",
"source_file": "2-Regression/4-Logistic/README.md",
"language_code": "zh-CN"
},
"2-Regression/4-Logistic/assignment.md": {
"original_hash": "8af40209a41494068c1f42b14c0b450d",
"translation_date": "2025-09-03T16:35:04+00:00",
"source_file": "2-Regression/4-Logistic/assignment.md",
"language_code": "zh-CN"
},
"2-Regression/4-Logistic/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-09-03T16:35:32+00:00",
"source_file": "2-Regression/4-Logistic/solution/Julia/README.md",
"language_code": "zh-CN"
},
"2-Regression/README.md": {
"original_hash": "508582278dbb8edd2a8a80ac96ef416c",
"translation_date": "2025-09-03T16:17:29+00:00",
"source_file": "2-Regression/README.md",
"language_code": "zh-CN"
},
"3-Web-App/1-Web-App/README.md": {
"original_hash": "e0b75f73e4a90d45181dc5581fe2ef5c",
"translation_date": "2025-09-05T09:06:07+00:00",
"source_file": "3-Web-App/1-Web-App/README.md",
"language_code": "zh-CN"
},
"3-Web-App/1-Web-App/assignment.md": {
"original_hash": "a8e8ae10be335cbc745b75ee552317ff",
"translation_date": "2025-09-03T17:57:46+00:00",
"source_file": "3-Web-App/1-Web-App/assignment.md",
"language_code": "zh-CN"
},
"3-Web-App/README.md": {
"original_hash": "9836ff53cfef716ddfd70e06c5f43436",
"translation_date": "2025-09-03T17:53:39+00:00",
"source_file": "3-Web-App/README.md",
"language_code": "zh-CN"
},
"4-Classification/1-Introduction/README.md": {
"original_hash": "aaf391d922bd6de5efba871d514c6d47",
"translation_date": "2025-09-05T09:08:05+00:00",
"source_file": "4-Classification/1-Introduction/README.md",
"language_code": "zh-CN"
},
"4-Classification/1-Introduction/assignment.md": {
"original_hash": "b2a01912beb24cfb0007f83594dba801",
"translation_date": "2025-09-03T18:15:53+00:00",
"source_file": "4-Classification/1-Introduction/assignment.md",
"language_code": "zh-CN"
},
"4-Classification/1-Introduction/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-09-03T18:16:22+00:00",
"source_file": "4-Classification/1-Introduction/solution/Julia/README.md",
"language_code": "zh-CN"
},
"4-Classification/2-Classifiers-1/README.md": {
"original_hash": "1a6e9e46b34a2e559fbbfc1f95397c7b",
"translation_date": "2025-09-05T09:06:37+00:00",
"source_file": "4-Classification/2-Classifiers-1/README.md",
"language_code": "zh-CN"
},
"4-Classification/2-Classifiers-1/assignment.md": {
"original_hash": "de6025f96841498b0577e9d1aee18d1f",
"translation_date": "2025-09-03T18:05:14+00:00",
"source_file": "4-Classification/2-Classifiers-1/assignment.md",
"language_code": "zh-CN"
},
"4-Classification/2-Classifiers-1/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-09-03T18:05:41+00:00",
"source_file": "4-Classification/2-Classifiers-1/solution/Julia/README.md",
"language_code": "zh-CN"
},
"4-Classification/3-Classifiers-2/README.md": {
"original_hash": "49047911108adc49d605cddfb455749c",
"translation_date": "2025-09-05T09:07:46+00:00",
"source_file": "4-Classification/3-Classifiers-2/README.md",
"language_code": "zh-CN"
},
"4-Classification/3-Classifiers-2/assignment.md": {
"original_hash": "58dfdaf79fb73f7d34b22bdbacf57329",
"translation_date": "2025-09-03T18:11:55+00:00",
"source_file": "4-Classification/3-Classifiers-2/assignment.md",
"language_code": "zh-CN"
},
"4-Classification/3-Classifiers-2/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-09-03T18:12:23+00:00",
"source_file": "4-Classification/3-Classifiers-2/solution/Julia/README.md",
"language_code": "zh-CN"
},
"4-Classification/4-Applied/README.md": {
"original_hash": "61bdec27ed2da8b098cd9065405d9bb0",
"translation_date": "2025-09-05T09:07:17+00:00",
"source_file": "4-Classification/4-Applied/README.md",
"language_code": "zh-CN"
},
"4-Classification/4-Applied/assignment.md": {
"original_hash": "799ed651e2af0a7cad17c6268db11578",
"translation_date": "2025-09-03T18:09:03+00:00",
"source_file": "4-Classification/4-Applied/assignment.md",
"language_code": "zh-CN"
},
"4-Classification/README.md": {
"original_hash": "74e809ffd1e613a1058bbc3e9600859e",
"translation_date": "2025-09-03T17:59:47+00:00",
"source_file": "4-Classification/README.md",
"language_code": "zh-CN"
},
"5-Clustering/1-Visualize/README.md": {
"original_hash": "730225ea274c9174fe688b21d421539d",
"translation_date": "2025-09-05T09:00:51+00:00",
"source_file": "5-Clustering/1-Visualize/README.md",
"language_code": "zh-CN"
},
"5-Clustering/1-Visualize/assignment.md": {
"original_hash": "589fa015a5e7d9e67bd629f7d47b53de",
"translation_date": "2025-09-03T17:16:31+00:00",
"source_file": "5-Clustering/1-Visualize/assignment.md",
"language_code": "zh-CN"
},
"5-Clustering/1-Visualize/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-09-03T17:17:00+00:00",
"source_file": "5-Clustering/1-Visualize/solution/Julia/README.md",
"language_code": "zh-CN"
},
"5-Clustering/2-K-Means/README.md": {
"original_hash": "7cdd17338d9bbd7e2171c2cd462eb081",
"translation_date": "2025-09-05T09:02:01+00:00",
"source_file": "5-Clustering/2-K-Means/README.md",
"language_code": "zh-CN"
},
"5-Clustering/2-K-Means/assignment.md": {
"original_hash": "b8e17eff34ad1680eba2a5d3cf9ffc41",
"translation_date": "2025-09-03T17:20:07+00:00",
"source_file": "5-Clustering/2-K-Means/assignment.md",
"language_code": "zh-CN"
},
"5-Clustering/2-K-Means/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-09-03T17:20:32+00:00",
"source_file": "5-Clustering/2-K-Means/solution/Julia/README.md",
"language_code": "zh-CN"
},
"5-Clustering/README.md": {
"original_hash": "b28a3a4911584062772c537b653ebbc7",
"translation_date": "2025-09-03T17:02:10+00:00",
"source_file": "5-Clustering/README.md",
"language_code": "zh-CN"
},
"6-NLP/1-Introduction-to-NLP/README.md": {
"original_hash": "1c2ec40cf55c98a028a359c27ef7e45a",
"translation_date": "2025-09-05T09:11:59+00:00",
"source_file": "6-NLP/1-Introduction-to-NLP/README.md",
"language_code": "zh-CN"
},
"6-NLP/1-Introduction-to-NLP/assignment.md": {
"original_hash": "1d7583e8046dacbb0c056d5ba0a71b16",
"translation_date": "2025-09-03T19:02:50+00:00",
"source_file": "6-NLP/1-Introduction-to-NLP/assignment.md",
"language_code": "zh-CN"
},
"6-NLP/2-Tasks/README.md": {
"original_hash": "5f3cb462e3122e1afe7ab0050ccf2bd3",
"translation_date": "2025-09-05T09:10:13+00:00",
"source_file": "6-NLP/2-Tasks/README.md",
"language_code": "zh-CN"
},
"6-NLP/2-Tasks/assignment.md": {
"original_hash": "2efc4c2aba5ed06c780c05539c492ae3",
"translation_date": "2025-09-03T18:50:07+00:00",
"source_file": "6-NLP/2-Tasks/assignment.md",
"language_code": "zh-CN"
},
"6-NLP/3-Translation-Sentiment/README.md": {
"original_hash": "be03c8182982b87ced155e4e9d1438e8",
"translation_date": "2025-09-05T09:12:24+00:00",
"source_file": "6-NLP/3-Translation-Sentiment/README.md",
"language_code": "zh-CN"
},
"6-NLP/3-Translation-Sentiment/assignment.md": {
"original_hash": "9d2a734deb904caff310d1a999c6bd7a",
"translation_date": "2025-09-03T19:08:10+00:00",
"source_file": "6-NLP/3-Translation-Sentiment/assignment.md",
"language_code": "zh-CN"
},
"6-NLP/3-Translation-Sentiment/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-09-03T19:08:59+00:00",
"source_file": "6-NLP/3-Translation-Sentiment/solution/Julia/README.md",
"language_code": "zh-CN"
},
"6-NLP/3-Translation-Sentiment/solution/R/README.md": {
"original_hash": "81db6ff2cf6e62fbe2340b094bb9509e",
"translation_date": "2025-09-03T19:08:36+00:00",
"source_file": "6-NLP/3-Translation-Sentiment/solution/R/README.md",
"language_code": "zh-CN"
},
"6-NLP/4-Hotel-Reviews-1/README.md": {
"original_hash": "8d32dadeda93c6fb5c43619854882ab1",
"translation_date": "2025-09-05T09:10:44+00:00",
"source_file": "6-NLP/4-Hotel-Reviews-1/README.md",
"language_code": "zh-CN"
},
"6-NLP/4-Hotel-Reviews-1/assignment.md": {
"original_hash": "bf39bceb833cd628f224941dca8041df",
"translation_date": "2025-09-03T18:57:44+00:00",
"source_file": "6-NLP/4-Hotel-Reviews-1/assignment.md",
"language_code": "zh-CN"
},
"6-NLP/4-Hotel-Reviews-1/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-09-03T18:58:30+00:00",
"source_file": "6-NLP/4-Hotel-Reviews-1/solution/Julia/README.md",
"language_code": "zh-CN"
},
"6-NLP/4-Hotel-Reviews-1/solution/R/README.md": {
"original_hash": "81db6ff2cf6e62fbe2340b094bb9509e",
"translation_date": "2025-09-03T18:58:09+00:00",
"source_file": "6-NLP/4-Hotel-Reviews-1/solution/R/README.md",
"language_code": "zh-CN"
},
"6-NLP/5-Hotel-Reviews-2/README.md": {
"original_hash": "2c742993fe95d5bcbb2846eda3d442a1",
"translation_date": "2025-09-05T09:13:02+00:00",
"source_file": "6-NLP/5-Hotel-Reviews-2/README.md",
"language_code": "zh-CN"
},
"6-NLP/5-Hotel-Reviews-2/assignment.md": {
"original_hash": "daf144daa552da6a7d442aff6f3e77d8",
"translation_date": "2025-09-03T19:14:24+00:00",
"source_file": "6-NLP/5-Hotel-Reviews-2/assignment.md",
"language_code": "zh-CN"
},
"6-NLP/5-Hotel-Reviews-2/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-09-03T19:15:08+00:00",
"source_file": "6-NLP/5-Hotel-Reviews-2/solution/Julia/README.md",
"language_code": "zh-CN"
},
"6-NLP/5-Hotel-Reviews-2/solution/R/README.md": {
"original_hash": "81db6ff2cf6e62fbe2340b094bb9509e",
"translation_date": "2025-09-03T19:14:49+00:00",
"source_file": "6-NLP/5-Hotel-Reviews-2/solution/R/README.md",
"language_code": "zh-CN"
},
"6-NLP/README.md": {
"original_hash": "1eb379dc2d0c9940b320732d16083778",
"translation_date": "2025-09-03T18:45:55+00:00",
"source_file": "6-NLP/README.md",
"language_code": "zh-CN"
},
"6-NLP/data/README.md": {
"original_hash": "ee0670655c89e4719319764afb113624",
"translation_date": "2025-09-03T18:58:52+00:00",
"source_file": "6-NLP/data/README.md",
"language_code": "zh-CN"
},
"7-TimeSeries/1-Introduction/README.md": {
"original_hash": "662b509c39eee205687726636d0a8455",
"translation_date": "2025-09-05T08:59:54+00:00",
"source_file": "7-TimeSeries/1-Introduction/README.md",
"language_code": "zh-CN"
},
"7-TimeSeries/1-Introduction/assignment.md": {
"original_hash": "d1781b0b92568ea1d119d0a198b576b4",
"translation_date": "2025-09-03T16:56:37+00:00",
"source_file": "7-TimeSeries/1-Introduction/assignment.md",
"language_code": "zh-CN"
},
"7-TimeSeries/1-Introduction/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-09-03T16:57:26+00:00",
"source_file": "7-TimeSeries/1-Introduction/solution/Julia/README.md",
"language_code": "zh-CN"
},
"7-TimeSeries/1-Introduction/solution/R/README.md": {
"original_hash": "81db6ff2cf6e62fbe2340b094bb9509e",
"translation_date": "2025-09-03T16:57:06+00:00",
"source_file": "7-TimeSeries/1-Introduction/solution/R/README.md",
"language_code": "zh-CN"
},
"7-TimeSeries/2-ARIMA/README.md": {
"original_hash": "917dbf890db71a322f306050cb284749",
"translation_date": "2025-09-05T08:59:15+00:00",
"source_file": "7-TimeSeries/2-ARIMA/README.md",
"language_code": "zh-CN"
},
"7-TimeSeries/2-ARIMA/assignment.md": {
"original_hash": "1c814013e10866dfd92cdb32caaae3ac",
"translation_date": "2025-09-03T16:51:48+00:00",
"source_file": "7-TimeSeries/2-ARIMA/assignment.md",
"language_code": "zh-CN"
},
"7-TimeSeries/2-ARIMA/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-09-03T16:52:35+00:00",
"source_file": "7-TimeSeries/2-ARIMA/solution/Julia/README.md",
"language_code": "zh-CN"
},
"7-TimeSeries/2-ARIMA/solution/R/README.md": {
"original_hash": "81db6ff2cf6e62fbe2340b094bb9509e",
"translation_date": "2025-09-03T16:52:15+00:00",
"source_file": "7-TimeSeries/2-ARIMA/solution/R/README.md",
"language_code": "zh-CN"
},
"7-TimeSeries/3-SVR/README.md": {
"original_hash": "482bccabe1df958496ea71a3667995cd",
"translation_date": "2025-09-05T09:00:24+00:00",
"source_file": "7-TimeSeries/3-SVR/README.md",
"language_code": "zh-CN"
},
"7-TimeSeries/3-SVR/assignment.md": {
"original_hash": "94aa2fc6154252ae30a3f3740299707a",
"translation_date": "2025-09-03T17:01:12+00:00",
"source_file": "7-TimeSeries/3-SVR/assignment.md",
"language_code": "zh-CN"
},
"7-TimeSeries/README.md": {
"original_hash": "61342603bad8acadbc6b2e4e3aab3f66",
"translation_date": "2025-09-03T16:46:16+00:00",
"source_file": "7-TimeSeries/README.md",
"language_code": "zh-CN"
},
"8-Reinforcement/1-QLearning/README.md": {
"original_hash": "911efd5e595089000cb3c16fce1beab8",
"translation_date": "2025-09-05T09:09:02+00:00",
"source_file": "8-Reinforcement/1-QLearning/README.md",
"language_code": "zh-CN"
},
"8-Reinforcement/1-QLearning/assignment.md": {
"original_hash": "68394b2102d3503882e5e914bd0ff5c1",
"translation_date": "2025-09-03T18:37:16+00:00",
"source_file": "8-Reinforcement/1-QLearning/assignment.md",
"language_code": "zh-CN"
},
"8-Reinforcement/1-QLearning/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-09-03T18:38:43+00:00",
"source_file": "8-Reinforcement/1-QLearning/solution/Julia/README.md",
"language_code": "zh-CN"
},
"8-Reinforcement/1-QLearning/solution/R/README.md": {
"original_hash": "81db6ff2cf6e62fbe2340b094bb9509e",
"translation_date": "2025-09-03T18:38:21+00:00",
"source_file": "8-Reinforcement/1-QLearning/solution/R/README.md",
"language_code": "zh-CN"
},
"8-Reinforcement/2-Gym/README.md": {
"original_hash": "107d5bb29da8a562e7ae72262d251a75",
"translation_date": "2025-09-05T09:09:36+00:00",
"source_file": "8-Reinforcement/2-Gym/README.md",
"language_code": "zh-CN"
},
"8-Reinforcement/2-Gym/assignment.md": {
"original_hash": "1f2b7441745eb52e25745423b247016b",
"translation_date": "2025-09-03T18:44:12+00:00",
"source_file": "8-Reinforcement/2-Gym/assignment.md",
"language_code": "zh-CN"
},
"8-Reinforcement/2-Gym/solution/Julia/README.md": {
"original_hash": "a39c15d63f3b2795ee2284a82b986b93",
"translation_date": "2025-09-03T18:45:14+00:00",
"source_file": "8-Reinforcement/2-Gym/solution/Julia/README.md",
"language_code": "zh-CN"
},
"8-Reinforcement/2-Gym/solution/R/README.md": {
"original_hash": "81db6ff2cf6e62fbe2340b094bb9509e",
"translation_date": "2025-09-03T18:44:53+00:00",
"source_file": "8-Reinforcement/2-Gym/solution/R/README.md",
"language_code": "zh-CN"
},
"8-Reinforcement/README.md": {
"original_hash": "20ca019012b1725de956681d036d8b18",
"translation_date": "2025-09-03T18:26:49+00:00",
"source_file": "8-Reinforcement/README.md",
"language_code": "zh-CN"
},
"9-Real-World/1-Applications/README.md": {
"original_hash": "83320d6b6994909e35d830cebf214039",
"translation_date": "2025-09-05T09:02:25+00:00",
"source_file": "9-Real-World/1-Applications/README.md",
"language_code": "zh-CN"
},
"9-Real-World/1-Applications/assignment.md": {
"original_hash": "fdebfcd0a3f12c9e2b436ded1aa79885",
"translation_date": "2025-09-03T17:27:15+00:00",
"source_file": "9-Real-World/1-Applications/assignment.md",
"language_code": "zh-CN"
},
"9-Real-World/2-Debugging-ML-Models/README.md": {
"original_hash": "df2b538e8fbb3e91cf0419ae2f858675",
"translation_date": "2025-09-05T09:03:02+00:00",
"source_file": "9-Real-World/2-Debugging-ML-Models/README.md",
"language_code": "zh-CN"
},
"9-Real-World/2-Debugging-ML-Models/assignment.md": {
"original_hash": "91c6a180ef08e20cc15acfd2d6d6e164",
"translation_date": "2025-09-03T17:33:11+00:00",
"source_file": "9-Real-World/2-Debugging-ML-Models/assignment.md",
"language_code": "zh-CN"
},
"9-Real-World/README.md": {
"original_hash": "5e069a0ac02a9606a69946c2b3c574a9",
"translation_date": "2025-09-03T17:22:09+00:00",
"source_file": "9-Real-World/README.md",
"language_code": "zh-CN"
},
"AGENTS.md": {
"original_hash": "93fdaa0fd38836e50c4793e2f2f25e8b",
"translation_date": "2025-10-03T10:59:57+00:00",
"source_file": "AGENTS.md",
"language_code": "zh-CN"
},
"CODE_OF_CONDUCT.md": {
"original_hash": "c06b12caf3c901eb3156e3dd5b0aea56",
"translation_date": "2025-09-03T16:16:28+00:00",
"source_file": "CODE_OF_CONDUCT.md",
"language_code": "zh-CN"
},
"CONTRIBUTING.md": {
"original_hash": "977ec5266dfd78ad1ce2bd8d46fccbda",
"translation_date": "2025-09-03T16:13:40+00:00",
"source_file": "CONTRIBUTING.md",
"language_code": "zh-CN"
},
"README.md": {
"original_hash": "da2ceed62f16a0820259556e3a873c95",
"translation_date": "2026-01-29T17:44:38+00:00",
"source_file": "README.md",
"language_code": "zh-CN"
},
"SECURITY.md": {
"original_hash": "5e1b8da31aae9cca3d53ad243fa3365a",
"translation_date": "2025-09-03T16:14:39+00:00",
"source_file": "SECURITY.md",
"language_code": "zh-CN"
},
"SUPPORT.md": {
"original_hash": "09623d7343ff1c26ff4f198c1b2d3176",
"translation_date": "2025-10-03T11:41:54+00:00",
"source_file": "SUPPORT.md",
"language_code": "zh-CN"
},
"TROUBLESHOOTING.md": {
"original_hash": "134d8759f0e2ab886e9aa4f62362c201",
"translation_date": "2025-10-03T12:38:25+00:00",
"source_file": "TROUBLESHOOTING.md",
"language_code": "zh-CN"
},
"docs/_sidebar.md": {
"original_hash": "68dd06c685f6ce840e0acfa313352e7c",
"translation_date": "2025-09-03T17:21:14+00:00",
"source_file": "docs/_sidebar.md",
"language_code": "zh-CN"
},
"for-teachers.md": {
"original_hash": "b37de02054fa6c0438ede6fabe1fdfb8",
"translation_date": "2025-09-03T16:15:43+00:00",
"source_file": "for-teachers.md",
"language_code": "zh-CN"
},
"quiz-app/README.md": {
"original_hash": "6d130dffca5db70d7e615f926cb1ad4c",
"translation_date": "2025-09-03T17:58:43+00:00",
"source_file": "quiz-app/README.md",
"language_code": "zh-CN"
},
"sketchnotes/LICENSE.md": {
"original_hash": "fba3b94d88bfb9b81369b869a1e9a20f",
"translation_date": "2025-09-03T18:22:05+00:00",
"source_file": "sketchnotes/LICENSE.md",
"language_code": "zh-CN"
},
"sketchnotes/README.md": {
"original_hash": "a88d5918c1b9da69a40d917a0840c497",
"translation_date": "2025-09-03T18:16:47+00:00",
"source_file": "sketchnotes/README.md",
"language_code": "zh-CN"
}
}

@ -0,0 +1,150 @@
# 机器学习简介
## [课前测验](https://ff-quizzes.netlify.app/en/ml/)
---
[![初学者的机器学习 - 机器学习入门](https://img.youtube.com/vi/6mSx_KJxcHI/0.jpg)](https://youtu.be/6mSx_KJxcHI "初学者的机器学习 - 机器学习入门")
> 🎥 点击上方图片观看本课相关的短视频。
欢迎来到这门面向初学者的经典机器学习课程!无论你是完全新手,还是一位希望复习某些领域的经验丰富的机器学习从业者,我们都很高兴你能加入我们!我们希望为你的机器学习学习提供一个友好的起点,并欢迎你提供[反馈](https://github.com/microsoft/ML-For-Beginners/discussions),我们会评估、回应并融入你的建议。
[![机器学习简介](https://img.youtube.com/vi/h0e2HAPTGF4/0.jpg)](https://youtu.be/h0e2HAPTGF4 "机器学习简介")
> 🎥 点击上方图片观看视频:麻省理工学院的 John Guttag 介绍机器学习
---
## 开始学习机器学习
在开始学习本课程之前,你需要确保你的电脑已经设置好并可以本地运行笔记本。
- **通过以下视频配置你的电脑**。使用以下链接学习[如何安装 Python](https://youtu.be/CXZYvNRIAKM)以及[设置文本编辑器](https://youtu.be/EU8eayHWoZg)进行开发。
- **学习 Python**。建议你对[Python](https://docs.microsoft.com/learn/paths/python-language/?WT.mc_id=academic-77952-leestott)有基本的了解,这是一种对数据科学家非常有用的编程语言,我们将在课程中使用它。
- **学习 Node.js 和 JavaScript**。我们在课程中会使用 JavaScript 构建一些网页应用,因此你需要安装 [node](https://nodejs.org) 和 [npm](https://www.npmjs.com/),以及为 Python 和 JavaScript 开发准备好 [Visual Studio Code](https://code.visualstudio.com/)。
- **创建 GitHub 账户**。既然你在 [GitHub](https://github.com) 找到了我们,你可能已经有一个账户了,但如果没有,请创建一个账户,然后 fork 本课程以供自己使用。(也可以给我们点个星星 😊)
- **探索 Scikit-learn**。熟悉 [Scikit-learn](https://scikit-learn.org/stable/user_guide.html),这是我们在课程中参考的一组机器学习库。
---
## 什么是机器学习?
“机器学习”是当今最流行和最常用的术语之一。如果你对技术有一定的了解,无论你从事哪个领域,都有很大可能至少听过一次这个术语。然而,机器学习的运作机制对大多数人来说仍然是一个谜。对于机器学习初学者来说,这个主题有时可能会让人感到不知所措。因此,了解机器学习的真正含义,并通过实际例子一步步学习它是非常重要的。
---
## 热度曲线
![机器学习热度曲线](../../../../1-Introduction/1-intro-to-ML/images/hype.png)
> Google Trends 显示了“机器学习”这一术语的近期热度曲线
---
## 神秘的宇宙
我们生活在一个充满迷人奥秘的宇宙中。像斯蒂芬·霍金、阿尔伯特·爱因斯坦等伟大的科学家们,毕生致力于寻找有意义的信息,以揭示我们周围世界的奥秘。这是人类学习的本质:一个孩子通过逐年成长,学习新事物并揭示其世界的结构。
---
## 孩子的大脑
孩子的大脑和感官感知周围环境的事实,并逐渐学习生活中隐藏的模式,这些模式帮助孩子制定逻辑规则以识别已学到的模式。人类大脑的学习过程使人类成为这个世界上最复杂的生物。通过发现隐藏模式并不断创新,我们能够在一生中不断提升自己。这种学习能力和进化能力与一个叫做[脑可塑性](https://www.simplypsychology.org/brain-plasticity.html)的概念有关。从表面上看,我们可以将人类大脑的学习过程与机器学习的概念进行一些激励性的类比。
---
## 人类大脑
[人类大脑](https://www.livescience.com/29365-human-brain.html)从现实世界中感知事物处理感知到的信息做出理性决策并根据情况采取某些行动。这就是我们所说的智能行为。当我们将智能行为过程的模拟编程到机器中时这就被称为人工智能AI
---
## 一些术语
尽管这些术语可能会混淆但机器学习ML是人工智能的重要子集。**机器学习关注的是使用专门的算法从感知到的数据中发现有意义的信息和隐藏模式,以支持理性决策过程**。
---
## AI、ML、深度学习
![AI、ML、深度学习、数据科学](../../../../1-Introduction/1-intro-to-ML/images/ai-ml-ds.png)
> 一张展示 AI、ML、深度学习和数据科学之间关系的图表。信息图由 [Jen Looper](https://twitter.com/jenlooper) 制作,灵感来源于[这张图](https://softwareengineering.stackexchange.com/questions/366996/distinction-between-ai-ml-neural-networks-deep-learning-and-data-mining)
---
## 涵盖的概念
在本课程中,我们将仅涵盖机器学习的核心概念,这些是初学者必须了解的内容。我们主要使用 Scikit-learn这是一款许多学生用来学习基础知识的优秀库来讲解我们称之为“经典机器学习”的内容。要理解人工智能或深度学习的更广泛概念扎实的机器学习基础知识是不可或缺的因此我们希望在这里提供这些知识。
---
## 在本课程中你将学习:
- 机器学习的核心概念
- 机器学习的历史
- 机器学习与公平性
- 回归机器学习技术
- 分类机器学习技术
- 聚类机器学习技术
- 自然语言处理机器学习技术
- 时间序列预测机器学习技术
- 强化学习
- 机器学习的实际应用
---
## 我们不会涵盖的内容
- 深度学习
- 神经网络
- 人工智能
为了提供更好的学习体验,我们将避免涉及神经网络的复杂性、“深度学习”(使用神经网络构建多层模型)以及人工智能,这些内容将在另一门课程中讨论。我们还将提供即将推出的数据科学课程,以专注于这一更广泛领域的相关内容。
---
## 为什么学习机器学习?
从系统的角度来看,机器学习被定义为创建能够从数据中学习隐藏模式以帮助做出智能决策的自动化系统。
这种动机在一定程度上受到人类大脑如何根据外界感知的数据学习某些事物的启发。
✅ 思考一下,为什么企业会选择使用机器学习策略,而不是创建一个基于硬编码规则的引擎?
---
## 机器学习的应用
机器学习的应用几乎无处不在,就像我们社会中流动的数据一样,这些数据由智能手机、连接设备和其他系统生成。考虑到最先进的机器学习算法的巨大潜力,研究人员一直在探索其解决多维度和多学科现实问题的能力,并取得了非常积极的成果。
---
## 应用机器学习的例子
**机器学习有许多用途**
- 根据患者的病史或报告预测疾病的可能性。
- 利用天气数据预测天气事件。
- 理解文本的情感。
- 检测虚假新闻以阻止宣传的传播。
金融、经济、地球科学、太空探索、生物医学工程、认知科学,甚至人文学科都已经适应了机器学习,以解决其领域中繁重的数据处理问题。
---
## 结论
机器学习通过从现实世界或生成的数据中发现有意义的洞察来自动化模式发现的过程。它已在商业、健康和金融等领域证明了其高度价值。
在不久的将来,由于机器学习的广泛应用,了解机器学习的基础知识将成为任何领域人士的必备技能。
---
# 🚀 挑战
用纸或在线应用(如 [Excalidraw](https://excalidraw.com/))绘制你对 AI、ML、深度学习和数据科学之间差异的理解。添加一些关于每种技术擅长解决的问题的想法。
# [课后测验](https://ff-quizzes.netlify.app/en/ml/)
---
# 复习与自学
要了解如何在云端使用机器学习算法,请参考此[学习路径](https://docs.microsoft.com/learn/paths/create-no-code-predictive-models-azure-machine-learning/?WT.mc_id=academic-77952-leestott)。
学习机器学习基础知识,请参考此[学习路径](https://docs.microsoft.com/learn/modules/introduction-to-machine-learning/?WT.mc_id=academic-77952-leestott)。
---
# 作业
[开始学习](assignment.md)
---
**免责声明**
本文档使用AI翻译服务[Co-op Translator](https://github.com/Azure/co-op-translator)进行翻译。尽管我们努力确保准确性,但请注意,自动翻译可能包含错误或不准确之处。应以原始语言的文档作为权威来源。对于关键信息,建议使用专业人工翻译。因使用本翻译而导致的任何误解或误读,我们概不负责。

@ -0,0 +1,14 @@
# 快速开始
## 说明
在这个非评分的任务中,你需要复习 Python 并设置好你的环境,以便能够运行笔记本。
请学习这个 [Python 学习路径](https://docs.microsoft.com/learn/paths/python-language/?WT.mc_id=academic-77952-leestott),然后通过以下入门视频设置你的系统:
https://www.youtube.com/playlist?list=PLlrxD0HtieHhS8VzuMCfQD4uJ9yne1mE6
---
**免责声明**
本文档使用AI翻译服务 [Co-op Translator](https://github.com/Azure/co-op-translator) 进行翻译。尽管我们努力确保翻译的准确性,但请注意,自动翻译可能包含错误或不准确之处。原始语言的文档应被视为权威来源。对于关键信息,建议使用专业人工翻译。我们不对因使用此翻译而产生的任何误解或误读承担责任。

@ -0,0 +1,155 @@
# 机器学习的历史
![机器学习历史的概述草图](../../../../sketchnotes/ml-history.png)
> 草图由 [Tomomi Imura](https://www.twitter.com/girlie_mac) 绘制
## [课前测验](https://ff-quizzes.netlify.app/en/ml/)
---
[![机器学习初学者 - 机器学习的历史](https://img.youtube.com/vi/N6wxM4wZ7V0/0.jpg)](https://youtu.be/N6wxM4wZ7V0 "机器学习初学者 - 机器学习的历史")
> 🎥 点击上方图片观看本课的简短视频。
在本课中,我们将回顾机器学习和人工智能历史上的重要里程碑。
人工智能AI作为一个领域的历史与机器学习的历史密不可分因为支撑机器学习的算法和计算进步也推动了人工智能的发展。需要注意的是尽管这些领域作为独立的研究方向在20世纪50年代开始成型但重要的[算法、统计、数学、计算和技术发现](https://wikipedia.org/wiki/Timeline_of_machine_learning)早在这一时期之前就已经出现并有所交集。事实上,人们已经思考这些问题[数百年](https://wikipedia.org/wiki/History_of_artificial_intelligence):这篇文章探讨了“会思考的机器”这一理念的历史性思想基础。
---
## 重要发现
- 1763年, 1812年 [贝叶斯定理](https://wikipedia.org/wiki/Bayes%27_theorem)及其前身。这一定理及其应用奠定了推断的基础,描述了基于先验知识事件发生的概率。
- 1805年 [最小二乘法](https://wikipedia.org/wiki/Least_squares)由法国数学家Adrien-Marie Legendre提出。这一理论你将在回归单元中学习有助于数据拟合。
- 1913年 [马尔可夫链](https://wikipedia.org/wiki/Markov_chain)以俄罗斯数学家Andrey Markov命名用于描述基于前一状态的一系列可能事件。
- 1957年 [感知机](https://wikipedia.org/wiki/Perceptron)一种由美国心理学家Frank Rosenblatt发明的线性分类器是深度学习进步的基础。
---
- 1967年 [最近邻算法](https://wikipedia.org/wiki/Nearest_neighbor),最初设计用于路径规划。在机器学习中,它被用来检测模式。
- 1970年 [反向传播算法](https://wikipedia.org/wiki/Backpropagation),用于训练[前馈神经网络](https://wikipedia.org/wiki/Feedforward_neural_network)。
- 1982年 [循环神经网络](https://wikipedia.org/wiki/Recurrent_neural_network),从前馈神经网络衍生而来,用于创建时间序列图。
✅ 做一些研究。还有哪些年份在机器学习和人工智能的历史上具有重要意义?
---
## 1950年会思考的机器
艾伦·图灵Alan Turing是一位真正杰出的人物他在[2019年被公众评选](https://wikipedia.org/wiki/Icons:_The_Greatest_Person_of_the_20th_Century)为20世纪最伟大的科学家。他被认为奠定了“会思考的机器”这一概念的基础。他通过创建[图灵测试](https://www.bbc.com/news/technology-18475646)来应对质疑者以及自己对这一概念的实证需求,你将在自然语言处理课程中进一步探索这一测试。
---
## 1956年达特茅斯夏季研究项目
“达特茅斯夏季人工智能研究项目是人工智能领域的一个开创性事件”,在这里,“人工智能”这一术语首次被提出([来源](https://250.dartmouth.edu/highlights/artificial-intelligence-ai-coined-dartmouth))。
> 学习的每一个方面或智能的任何其他特征原则上都可以被如此精确地描述,以至于可以制造出模拟它的机器。
---
该项目的首席研究员、数学教授John McCarthy希望“基于这样的假设学习的每一个方面或智能的任何其他特征原则上都可以被如此精确地描述以至于可以制造出模拟它的机器。”参与者中还包括该领域的另一位杰出人物Marvin Minsky。
该研讨会被认为启动并推动了多项讨论,包括“符号方法的兴起、专注于有限领域的系统(早期专家系统)以及演绎系统与归纳系统的对比”([来源](https://wikipedia.org/wiki/Dartmouth_workshop))。
---
## 1956 - 1974年“黄金时代”
从20世纪50年代到70年代中期人们对人工智能能够解决许多问题充满乐观。1967年Marvin Minsky自信地表示“在一代人的时间内……创造人工智能的问题将基本解决。”Minsky, Marvin (1967), Computation: Finite and Infinite Machines, Englewood Cliffs, N.J.: Prentice-Hall
自然语言处理研究蓬勃发展,搜索技术得到了改进并变得更强大,“微观世界”的概念被提出,在这种环境下,简单任务可以通过简单的语言指令完成。
---
政府机构为研究提供了充足的资金,计算和算法取得了进展,智能机器的原型被制造出来。这些机器包括:
* [Shakey机器人](https://wikipedia.org/wiki/Shakey_the_robot),它能够“智能地”移动并决定如何执行任务。
![Shakey一个智能机器人](../../../../1-Introduction/2-history-of-ML/images/shakey.jpg)
> 1972年的Shakey
---
* Eliza一个早期的“聊天机器人”能够与人对话并充当一个原始的“治疗师”。你将在自然语言处理课程中进一步了解Eliza。
![Eliza一个机器人](../../../../1-Introduction/2-history-of-ML/images/eliza.png)
> Eliza的一个版本一个聊天机器人
---
* “积木世界”是一个微观世界的例子,在这里积木可以被堆叠和排序,机器学习决策的实验可以在此进行。使用诸如[SHRDLU](https://wikipedia.org/wiki/SHRDLU)之类的库的进步推动了语言处理的发展。
[![SHRDLU的积木世界](https://img.youtube.com/vi/QAJz4YKUwqw/0.jpg)](https://www.youtube.com/watch?v=QAJz4YKUwqw "SHRDLU的积木世界")
> 🎥 点击上方图片观看视频SHRDLU的积木世界
---
## 1974 - 1980年“人工智能寒冬”
到70年代中期制造“智能机器”的复杂性被低估的事实变得显而易见而其承诺在当时的计算能力下被过度夸大。资金枯竭领域信心减弱。影响信心的一些问题包括
---
- **局限性**。计算能力过于有限。
- **组合爆炸**。随着对计算机要求的增加,需要训练的参数数量呈指数增长,而计算能力和性能却没有相应提升。
- **数据匮乏**。数据的匮乏阻碍了算法的测试、开发和优化过程。
- **我们是否在问正确的问题?**。研究者开始质疑他们提出的问题:
- 图灵测试因“中文房间理论”等观点受到质疑,该理论认为,“编程数字计算机可能使其看似理解语言,但无法产生真正的理解。”([来源](https://plato.stanford.edu/entries/chinese-room/)
- 将人工智能如“治疗师”ELIZA引入社会的伦理问题受到挑战。
---
与此同时,各种人工智能学派开始形成。“[粗放派](https://wikipedia.org/wiki/Neats_and_scruffies)”与“精确派”实践之间的二分法逐渐确立。_粗放派_实验室通过不断调整程序以获得所需结果而_精确派_实验室则“专注于逻辑和形式化问题解决”。ELIZA和SHRDLU是著名的_粗放派_系统。到了80年代随着对机器学习系统可重复性的需求增加_精确派_方法逐渐占据主导地位因为其结果更具可解释性。
---
## 1980年代 专家系统
随着领域的发展其对商业的益处变得更加明显1980年代“专家系统”的普及也随之而来。“专家系统是最早真正成功的人工智能AI软件形式之一。”[来源](https://wikipedia.org/wiki/Expert_system)
这种系统实际上是_混合型_的部分由定义业务需求的规则引擎组成部分由利用规则系统推导新事实的推理引擎组成。
这一时期还出现了对神经网络的日益关注。
---
## 1987 - 1993年人工智能“冷却期”
专用专家系统硬件的普及不幸导致其过于专用化。个人计算机的兴起也与这些大型、专用、集中化的系统形成了竞争。计算的民主化开始了,并最终为现代大数据的爆发铺平了道路。
---
## 1993 - 2011年
这一时期见证了机器学习和人工智能能够解决早期因数据和计算能力不足而导致的问题。数据量开始迅速增加并变得更易获取无论是好是坏尤其是在2007年左右智能手机的出现之后。计算能力呈指数级增长算法也随之演进。随着过去自由发展的日子逐渐凝聚成一个真正的学科这一领域开始走向成熟。
---
## 现在
如今机器学习和人工智能几乎触及我们生活的每一个部分。这一时代需要我们仔细理解这些算法对人类生活的风险和潜在影响。正如微软的Brad Smith所说“信息技术提出了一些问题这些问题触及了隐私和言论自由等基本人权保护的核心。这些问题加重了创造这些产品的科技公司的责任。在我们看来这也需要深思熟虑的政府监管以及围绕可接受用途的规范发展。”[来源](https://www.technologyreview.com/2019/12/18/102365/the-future-of-ais-impact-on-society/)
---
未来会如何发展仍未可知,但理解这些计算机系统及其运行的软件和算法是非常重要的。我们希望这门课程能帮助你更好地理解这些内容,从而让你自己做出判断。
[![深度学习的历史](https://img.youtube.com/vi/mTtDfKgLm54/0.jpg)](https://www.youtube.com/watch?v=mTtDfKgLm54 "深度学习的历史")
> 🎥 点击上方图片观看视频Yann LeCun在这次讲座中讨论了深度学习的历史
---
## 🚀挑战
深入研究这些历史时刻中的一个,了解背后的人物。这些人物非常有趣,没有任何科学发现是在文化真空中产生的。你发现了什么?
## [课后测验](https://ff-quizzes.netlify.app/en/ml/)
---
## 复习与自学
以下是一些可以观看和收听的内容:
[这期Amy Boyd讨论人工智能演变的播客](http://runasradio.com/Shows/Show/739)
[![Amy Boyd讲述人工智能的历史](https://img.youtube.com/vi/EJt3_bFYKss/0.jpg)](https://www.youtube.com/watch?v=EJt3_bFYKss "Amy Boyd讲述人工智能的历史")
---
## 作业
[创建一个时间线](assignment.md)
---
**免责声明**
本文档使用AI翻译服务 [Co-op Translator](https://github.com/Azure/co-op-translator) 进行翻译。尽管我们努力确保翻译的准确性,但请注意,自动翻译可能包含错误或不准确之处。原始语言的文档应被视为权威来源。对于关键信息,建议使用专业人工翻译。我们不对因使用此翻译而产生的任何误解或误读承担责任。

@ -0,0 +1,16 @@
# 创建时间轴
## 说明
使用[这个仓库](https://github.com/Digital-Humanities-Toolkit/timeline-builder),创建一个关于算法、数学、统计学、人工智能或机器学习历史某一方面的时间轴,或者结合这些主题。你可以专注于一个人、一个想法,或者一个长时间跨度的思想发展。确保添加多媒体元素。
## 评分标准
| 标准 | 卓越表现 | 合格表现 | 需要改进 |
| -------- | ------------------------------------------------- | --------------------------------------- | ---------------------------------------------------------------- |
| | 时间轴已部署为一个GitHub页面 | 代码不完整且未部署 | 时间轴不完整,研究不充分且未部署 |
---
**免责声明**
本文档使用AI翻译服务[Co-op Translator](https://github.com/Azure/co-op-translator)进行翻译。尽管我们努力确保翻译的准确性,但请注意,自动翻译可能包含错误或不准确之处。原始语言的文档应被视为权威来源。对于关键信息,建议使用专业人工翻译。我们不对因使用此翻译而产生的任何误解或误读承担责任。

@ -0,0 +1,161 @@
# 构建负责任的人工智能的机器学习解决方案
![机器学习中负责任人工智能的概要图](../../../../sketchnotes/ml-fairness.png)
> 由 [Tomomi Imura](https://www.twitter.com/girlie_mac) 绘制的概要图
## [课前测验](https://ff-quizzes.netlify.app/en/ml/)
## 简介
在本课程中,您将开始了解机器学习如何以及正在影响我们的日常生活。即使是现在,系统和模型已经参与了日常决策任务,例如医疗诊断、贷款审批或欺诈检测。因此,确保这些模型能够提供值得信赖的结果非常重要。与任何软件应用程序一样,人工智能系统可能会未达到预期或产生不理想的结果。这就是为什么理解和解释人工智能模型的行为至关重要。
想象一下,当您用于构建这些模型的数据缺乏某些人口统计信息(例如种族、性别、政治观点、宗教)或过度代表某些人口统计信息时会发生什么?如果模型的输出被解释为偏向某些人口统计信息,又会有什么后果?此外,当模型产生不良结果并对人们造成伤害时会发生什么?谁应该对人工智能系统的行为负责?这些是我们将在本课程中探讨的一些问题。
在本课中,您将:
- 提高对机器学习公平性及相关危害重要性的认识。
- 熟悉探索异常值和特殊场景以确保可靠性和安全性的实践。
- 了解设计包容性系统以赋能所有人的必要性。
- 探讨保护数据和个人隐私与安全的重要性。
- 认识到采用透明化方法解释人工智能模型行为的重要性。
- 意识到责任感对于建立人工智能系统信任的重要性。
## 前提条件
作为前提条件,请完成“负责任人工智能原则”学习路径并观看以下视频:
通过以下 [学习路径](https://docs.microsoft.com/learn/modules/responsible-ai-principles/?WT.mc_id=academic-77952-leestott) 了解更多关于负责任人工智能的信息。
[![微软的负责任人工智能方法](https://img.youtube.com/vi/dnC8-uUZXSc/0.jpg)](https://youtu.be/dnC8-uUZXSc "微软的负责任人工智能方法")
> 🎥 点击上方图片观看视频:微软的负责任人工智能方法
## 公平性
人工智能系统应公平对待每个人,避免对类似群体产生不同影响。例如,当人工智能系统提供医疗建议、贷款申请或就业指导时,它们应对具有类似症状、财务状况或专业资格的人做出相同的推荐。我们每个人作为人类,都携带着影响我们决策和行为的固有偏见。这些偏见可能会体现在我们用于训练人工智能系统的数据中。这种操控有时可能是无意的。通常很难有意识地知道何时在数据中引入了偏见。
**“不公平”** 包括对某些群体(例如按种族、性别、年龄或残疾状态定义的群体)造成的负面影响或“危害”。主要与公平性相关的危害可以分类为:
- **分配**:例如,如果某个性别或种族被优待于另一个。
- **服务质量**:如果您仅为一个特定场景训练数据,而现实情况更复杂,这会导致服务表现不佳。例如,一个无法识别深色皮肤的洗手液分配器。[参考](https://gizmodo.com/why-cant-this-soap-dispenser-identify-dark-skin-1797931773)
- **贬低**:不公平地批评或标记某事或某人。例如,一个图像标记技术曾错误地将深色皮肤人群的照片标记为猩猩。
- **过度或不足代表**:某些群体在某些职业中未被看到,而任何继续推广这种现象的服务或功能都在助长危害。
- **刻板印象**:将某个群体与预先分配的属性联系起来。例如,英语和土耳其语之间的语言翻译系统可能因与性别相关的刻板印象而出现不准确。
![翻译成土耳其语](../../../../1-Introduction/3-fairness/images/gender-bias-translate-en-tr.png)
> 翻译成土耳其语
![翻译回英语](../../../../1-Introduction/3-fairness/images/gender-bias-translate-tr-en.png)
> 翻译回英语
在设计和测试人工智能系统时,我们需要确保人工智能是公平的,并且不会被编程为做出偏见或歧视性的决策,这些决策也是人类被禁止做出的。确保人工智能和机器学习的公平性仍然是一个复杂的社会技术挑战。
### 可靠性与安全性
为了建立信任,人工智能系统需要在正常和意外情况下保持可靠、安全和一致。了解人工智能系统在各种情况下的行为尤其重要,特别是当它们处于异常值时。在构建人工智能解决方案时,需要重点关注如何处理人工智能解决方案可能遇到的各种情况。例如,一辆自动驾驶汽车需要将人的安全作为首要任务。因此,驱动汽车的人工智能需要考虑汽车可能遇到的所有可能场景,例如夜晚、雷暴或暴风雪、孩子跑过街道、宠物、道路施工等。人工智能系统在各种条件下可靠安全地处理问题的能力反映了数据科学家或人工智能开发人员在设计或测试系统时的预见水平。
> [🎥 点击此处观看视频:](https://www.microsoft.com/videoplayer/embed/RE4vvIl)
### 包容性
人工智能系统应设计为能够吸引和赋能所有人。在设计和实施人工智能系统时数据科学家和人工智能开发人员需要识别并解决系统中可能无意间排除某些人的潜在障碍。例如全球有10亿残疾人。随着人工智能的进步他们可以更轻松地获取广泛的信息和机会。通过解决这些障碍可以创造创新机会开发具有更好体验的人工智能产品从而惠及所有人。
> [🎥 点击此处观看视频:人工智能中的包容性](https://www.microsoft.com/videoplayer/embed/RE4vl9v)
### 安全与隐私
人工智能系统应安全并尊重个人隐私。人们对那些可能危及隐私、信息或生命的系统信任度较低。在训练机器学习模型时,我们依赖数据以获得最佳结果。在此过程中,必须考虑数据的来源和完整性。例如,数据是用户提交的还是公开可用的?接下来,在处理数据时,开发人工智能系统时必须能够保护机密信息并抵御攻击。随着人工智能的普及,保护隐私和确保重要的个人和商业信息的安全变得越来越重要和复杂。隐私和数据安全问题需要特别关注人工智能,因为数据访问对于人工智能系统做出准确和知情的预测以及关于人的决策至关重要。
> [🎥 点击此处观看视频:人工智能中的安全性](https://www.microsoft.com/videoplayer/embed/RE4voJF)
- 在行业中我们在隐私和安全方面取得了显著进展这在很大程度上得益于像GDPR通用数据保护条例这样的法规。
- 然而,对于人工智能系统,我们必须承认需要更多个人数据以使系统更个性化和有效——与隐私之间的紧张关系。
- 就像互联网连接的计算机诞生一样,我们也看到了与人工智能相关的安全问题数量的巨大增长。
- 同时,我们也看到人工智能被用于改善安全性。例如,大多数现代杀毒扫描器今天都由人工智能启发式驱动。
- 我们需要确保我们的数据科学流程与最新的隐私和安全实践和谐融合。
### 透明性
人工智能系统应易于理解。透明性的一个关键部分是解释人工智能系统及其组件的行为。提高对人工智能系统的理解需要利益相关者能够理解它们的功能和原因,以便识别潜在的性能问题、安全和隐私问题、偏见、排他性实践或意外结果。我们还认为,使用人工智能系统的人应该诚实并坦率地说明何时、为何以及如何选择部署它们,以及所使用系统的局限性。例如,如果一家银行使用人工智能系统来支持其消费者贷款决策,那么审查结果并了解哪些数据影响系统的推荐是很重要的。政府开始对各行业的人工智能进行监管,因此数据科学家和组织必须解释人工智能系统是否符合监管要求,特别是在出现不理想结果时。
> [🎥 点击此处观看视频:人工智能中的透明性](https://www.microsoft.com/videoplayer/embed/RE4voJF)
- 由于人工智能系统非常复杂,很难理解它们的工作原理并解释结果。
- 这种理解的缺乏影响了这些系统的管理、操作化和文档化方式。
- 更重要的是,这种理解的缺乏影响了使用这些系统产生的结果所做出的决策。
### 责任感
设计和部署人工智能系统的人必须对其系统的运行负责。责任感对于敏感技术的使用尤其重要,例如面部识别技术。最近,面部识别技术的需求不断增长,尤其是执法机构,他们看到了该技术在寻找失踪儿童等用途上的潜力。然而,这些技术可能会被政府用于威胁公民的基本自由,例如对特定个人进行持续监控。因此,数据科学家和组织需要对其人工智能系统对个人或社会的影响负责。
[![领先的人工智能研究人员警告面部识别可能导致大规模监控](../../../../1-Introduction/3-fairness/images/accountability.png)](https://www.youtube.com/watch?v=Wldt8P5V6D0 "微软的负责任人工智能方法")
> 🎥 点击上方图片观看视频:面部识别可能导致大规模监控的警告
最终,对于我们这一代人来说,作为将人工智能引入社会的第一代人,最大的一个问题是如何确保计算机始终对人类负责,以及如何确保设计计算机的人对其他人负责。
## 影响评估
在训练机器学习模型之前,进行影响评估以了解人工智能系统的目的、预期用途、部署地点以及与系统交互的人非常重要。这些评估有助于评审者或测试人员在识别潜在风险和预期后果时知道需要考虑哪些因素。
以下是进行影响评估时的重点领域:
* **对个人的不利影响**:意识到任何限制或要求、不支持的用途或任何已知限制影响系统性能至关重要,以确保系统不会以可能对个人造成伤害的方式使用。
* **数据要求**了解系统如何以及在哪里使用数据使评审者能够探索需要注意的任何数据要求例如GDPR或HIPPA数据法规。此外检查数据的来源或数量是否足够用于训练。
* **影响摘要**:收集使用系统可能产生的潜在危害列表。在机器学习生命周期中,审查是否解决或处理了识别的问题。
* **六项核心原则的适用目标**:评估每项原则的目标是否达成,以及是否存在任何差距。
## 使用负责任人工智能进行调试
与调试软件应用程序类似,调试人工智能系统是识别和解决系统问题的必要过程。许多因素会影响模型未按预期或负责任地运行。大多数传统模型性能指标是模型性能的定量汇总,这不足以分析模型如何违反负责任人工智能原则。此外,机器学习模型是一个黑箱,难以理解其结果的驱动因素或在出现错误时提供解释。在本课程后续部分,我们将学习如何使用负责任人工智能仪表板来帮助调试人工智能系统。该仪表板为数据科学家和人工智能开发人员提供了一个全面的工具,用于执行以下操作:
* **错误分析**:识别模型的错误分布,这可能影响系统的公平性或可靠性。
* **模型概览**:发现模型在不同数据群体中的性能差异。
* **数据分析**:了解数据分布并识别数据中可能导致公平性、包容性和可靠性问题的潜在偏见。
* **模型可解释性**:了解影响或驱动模型预测的因素。这有助于解释模型的行为,这对透明性和责任感至关重要。
## 🚀 挑战
为了防止危害的引入,我们应该:
- 确保参与系统开发的人员具有多样化的背景和观点
- 投资于反映社会多样性的数据集
- 在整个机器学习生命周期中开发更好的方法,以检测和纠正负责任人工智能问题
思考现实生活中模型在构建和使用过程中显现不可信的场景。我们还应该考虑什么?
## [课后测验](https://ff-quizzes.netlify.app/en/ml/)
## 复习与自学
在本课中,您已经学习了机器学习中公平性和不公平性概念的一些基础知识。
观看此研讨会,深入了解相关主题:
- 追求负责任的人工智能:将原则付诸实践,由 Besmira Nushi、Mehrnoosh Sameki 和 Amit Sharma 主讲
[![负责任的人工智能工具箱:构建负责任人工智能的开源框架](https://img.youtube.com/vi/tGgJCrA-MZU/0.jpg)](https://www.youtube.com/watch?v=tGgJCrA-MZU "RAI Toolbox: 构建负责任人工智能的开源框架")
> 🎥 点击上方图片观看视频RAI Toolbox: 构建负责任人工智能的开源框架,由 Besmira Nushi、Mehrnoosh Sameki 和 Amit Sharma 主讲
此外,阅读以下内容:
- 微软的负责任人工智能资源中心:[负责任人工智能资源 Microsoft AI](https://www.microsoft.com/ai/responsible-ai-resources?activetab=pivot1%3aprimaryr4)
- 微软的 FATE 研究团队:[FATE: 公平性、问责性、透明性和人工智能伦理 - Microsoft Research](https://www.microsoft.com/research/theme/fate/)
RAI 工具箱:
- [负责任人工智能工具箱 GitHub 仓库](https://github.com/microsoft/responsible-ai-toolbox)
了解 Azure 机器学习工具如何确保公平性:
- [Azure 机器学习](https://docs.microsoft.com/azure/machine-learning/concept-fairness-ml?WT.mc_id=academic-77952-leestott)
## 作业
[探索 RAI 工具箱](assignment.md)
---
**免责声明**
本文档使用AI翻译服务[Co-op Translator](https://github.com/Azure/co-op-translator)进行翻译。虽然我们努力确保翻译的准确性,但请注意,自动翻译可能包含错误或不准确之处。应以原始语言的文档作为权威来源。对于重要信息,建议使用专业人工翻译。我们不对因使用此翻译而产生的任何误解或误读承担责任。

@ -0,0 +1,16 @@
# 探索负责任的AI工具箱
## 说明
在本课程中您学习了负责任的AI工具箱这是一个“开源的、社区驱动的项目旨在帮助数据科学家分析和改进AI系统。” 在本次作业中请探索RAI工具箱的一个[笔记本](https://github.com/microsoft/responsible-ai-toolbox/blob/main/notebooks/responsibleaidashboard/getting-started.ipynb),并在论文或演示文稿中报告您的发现。
## 评分标准
| 标准 | 卓越 | 合格 | 需要改进 |
| -------- | --------- | -------- | ----------------- |
| | 提交了一篇论文或PowerPoint演示文稿讨论了Fairlearn的系统、运行的笔记本以及从中得出的结论 | 提交了一篇没有结论的论文 | 未提交论文 |
---
**免责声明**
本文档使用AI翻译服务 [Co-op Translator](https://github.com/Azure/co-op-translator) 进行翻译。尽管我们努力确保翻译的准确性,但请注意,自动翻译可能包含错误或不准确之处。应以原始语言的文档作为权威来源。对于关键信息,建议使用专业人工翻译。我们不对因使用此翻译而产生的任何误解或误读承担责任。

@ -0,0 +1,123 @@
# 机器学习技术
构建、使用和维护机器学习模型及其所需数据的过程,与许多其他开发工作流有很大的不同。在本课中,我们将揭开这一过程的神秘面纱,并概述您需要了解的主要技术。您将:
- 从高层次理解机器学习的基本流程。
- 探索诸如“模型”、“预测”和“训练数据”等基础概念。
## [课前测验](https://ff-quizzes.netlify.app/en/ml/)
[![机器学习入门 - 机器学习技术](https://img.youtube.com/vi/4NGM0U2ZSHU/0.jpg)](https://youtu.be/4NGM0U2ZSHU "机器学习入门 - 机器学习技术")
> 🎥 点击上方图片观看本课的简短视频。
## 介绍
从高层次来看创建机器学习ML流程的过程包括以下几个步骤
1. **确定问题**。大多数机器学习流程从提出一个无法通过简单条件程序或基于规则的引擎回答的问题开始。这些问题通常围绕基于数据集合的预测展开。
2. **收集和准备数据**。为了回答您的问题,您需要数据。数据的质量以及有时数据的数量将决定您能多好地回答最初的问题。可视化数据是这一阶段的重要部分。这一阶段还包括将数据分为训练集和测试集以构建模型。
3. **选择训练方法**。根据您的问题和数据的性质,您需要选择一种训练模型的方法,以便最好地反映数据并对其进行准确预测。这是机器学习流程中需要特定专业知识的部分,通常需要大量的实验。
4. **训练模型**。使用训练数据,您将使用各种算法训练模型以识别数据中的模式。模型可能会利用内部权重,这些权重可以调整以优先考虑数据的某些部分,从而构建更好的模型。
5. **评估模型**。使用从未见过的数据(测试数据)来检查模型的表现。
6. **参数调优**。根据模型的表现,您可以使用不同的参数或变量重新进行训练,这些参数或变量控制用于训练模型的算法的行为。
7. **预测**。使用新的输入测试模型的准确性。
## 提出什么问题
计算机特别擅长发现数据中的隐藏模式。这种能力对研究人员来说非常有用,他们可能会提出一些无法通过条件规则引擎轻松回答的问题。例如,在精算任务中,数据科学家可能能够围绕吸烟者与非吸烟者的死亡率构建手工规则。
然而,当许多其他变量被纳入考虑时,机器学习模型可能更高效地根据过去的健康历史预测未来的死亡率。一个更令人愉快的例子可能是基于纬度、经度、气候变化、靠近海洋、喷流模式等数据预测某地四月份的天气。
✅ 这份[幻灯片](https://www2.cisl.ucar.edu/sites/default/files/2021-10/0900%20June%2024%20Haupt_0.pdf)提供了使用机器学习进行天气分析的历史视角。
## 构建前的任务
在开始构建模型之前,您需要完成几个任务。为了测试您的问题并根据模型的预测形成假设,您需要识别并配置几个要素。
### 数据
为了以任何确定性回答您的问题,您需要足够数量的正确类型的数据。在这一点上,您需要完成以下两件事:
- **收集数据**。牢记上一课关于数据分析公平性的内容,谨慎收集数据。注意数据的来源、可能存在的内在偏见,并记录其来源。
- **准备数据**。数据准备过程包括多个步骤。如果数据来自不同来源,您可能需要整理并规范化数据。您可以通过各种方法提高数据的质量和数量,例如将字符串转换为数字(如我们在[聚类](../../5-Clustering/1-Visualize/README.md)中所做的)。您还可以基于原始数据生成新数据(如我们在[分类](../../4-Classification/1-Introduction/README.md)中所做的)。您可以清理和编辑数据(如我们在[Web 应用](../../3-Web-App/README.md)课程之前所做的)。最后,根据您的训练技术,您可能还需要随机化和打乱数据。
✅ 在收集和处理数据后,花点时间检查其形状是否能帮助您解决预期问题。可能会发现数据在给定任务中表现不佳,就像我们在[聚类](../../5-Clustering/1-Visualize/README.md)课程中发现的那样!
### 特征和目标
[特征](https://www.datasciencecentral.com/profiles/blogs/an-introduction-to-variable-and-feature-selection)是数据的可测量属性。在许多数据集中,它通常以列标题的形式表示,例如“日期”、“大小”或“颜色”。特征变量通常在代码中表示为`X`,代表用于训练模型的输入变量。
目标是您试图预测的内容。目标通常在代码中表示为`y`,代表您试图从数据中回答的问题:在十二月,哪种**颜色**的南瓜最便宜?在旧金山,哪些社区的房地产**价格**最好?有时目标也被称为标签属性。
### 选择特征变量
🎓 **特征选择和特征提取** 如何在构建模型时选择变量?您可能会经历特征选择或特征提取的过程,以选择最适合的变量来构建性能最佳的模型。然而,它们并不相同:“特征提取通过原始特征的函数创建新特征,而特征选择返回特征的子集。”([来源](https://wikipedia.org/wiki/Feature_selection)
### 可视化数据
数据科学家工具箱的重要组成部分是使用 Seaborn 或 MatPlotLib 等优秀库可视化数据的能力。通过可视化数据,您可能会发现可以利用的隐藏相关性。可视化还可能帮助您发现偏差或数据不平衡(如我们在[分类](../../4-Classification/2-Classifiers-1/README.md)中发现的那样)。
### 划分数据集
在训练之前,您需要将数据集划分为两个或更多不等大小的部分,同时确保它们能很好地代表数据。
- **训练集**。数据集的这一部分用于训练模型。它通常占原始数据集的大部分。
- **测试集**。测试数据集是一个独立的数据组,通常从原始数据中提取,用于验证模型的性能。
- **验证集**。验证集是一个较小的独立数据组,用于调整模型的超参数或架构以改进模型。根据数据的大小和您提出的问题,您可能不需要构建这个第三组(如我们在[时间序列预测](../../7-TimeSeries/1-Introduction/README.md)中提到的)。
## 构建模型
使用训练数据,您的目标是通过各种算法**训练**模型,构建数据的统计表示。训练模型使其接触数据,并让它对发现的模式进行假设、验证并接受或拒绝。
### 决定训练方法
根据您的问题和数据的性质,您将选择一种训练方法。通过浏览[Scikit-learn 的文档](https://scikit-learn.org/stable/user_guide.html)(我们在本课程中使用的工具),您可以探索多种训练模型的方法。根据您的经验,您可能需要尝试几种不同的方法来构建最佳模型。数据科学家通常会经历一个过程,通过向模型提供未见过的数据来评估其性能,检查准确性、偏差和其他质量问题,并选择最适合当前任务的训练方法。
### 训练模型
有了训练数据您可以开始“拟合”数据以创建模型。您会注意到在许多机器学习库中代码中会出现“model.fit”——此时您将特征变量作为值数组通常是`X`)和目标变量(通常是`y`)传入。
### 评估模型
一旦训练过程完成(对于大型模型可能需要多次迭代或“周期”),您可以使用测试数据评估模型的质量,以衡量其性能。这些数据是模型之前未分析过的原始数据的子集。您可以打印出关于模型质量的指标表。
🎓 **模型拟合**
在机器学习的背景下,模型拟合指的是模型底层函数在尝试分析未见过的数据时的准确性。
🎓 **欠拟合**和**过拟合**是常见问题,会降低模型质量。欠拟合的模型无法很好地分析训练数据或未见过的数据,而过拟合的模型过于贴合训练数据的细节和噪声。过拟合的模型对训练数据的预测过于精准,而欠拟合的模型则不够准确。
![过拟合模型](../../../../1-Introduction/4-techniques-of-ML/images/overfitting.png)
> 信息图由 [Jen Looper](https://twitter.com/jenlooper) 提供
## 参数调优
初步训练完成后,观察模型的质量,并通过调整其“超参数”来改进模型。阅读更多关于该过程的内容:[文档](https://docs.microsoft.com/en-us/azure/machine-learning/how-to-tune-hyperparameters?WT.mc_id=academic-77952-leestott)。
## 预测
这是您可以使用全新数据测试模型准确性的时刻。在“应用”机器学习场景中,例如构建用于生产的 Web 应用程序,这一过程可能涉及收集用户输入(例如按钮点击)以设置变量并将其发送到模型进行推断或评估。
在这些课程中,您将学习如何使用这些步骤来准备、构建、测试、评估和预测——这些都是数据科学家的基本操作,同时也将帮助您在成为“全栈”机器学习工程师的旅程中不断进步。
---
## 🚀挑战
绘制一张流程图,反映机器学习从业者的步骤。您认为自己目前处于哪个阶段?您预测在哪些方面会遇到困难?哪些部分对您来说似乎很容易?
## [课后测验](https://ff-quizzes.netlify.app/en/ml/)
## 复习与自学
在线搜索数据科学家讨论日常工作的访谈。这里有一个[示例](https://www.youtube.com/watch?v=Z3IjgbbCEfs)。
## 作业
[采访一位数据科学家](assignment.md)
---
**免责声明**
本文档使用AI翻译服务 [Co-op Translator](https://github.com/Azure/co-op-translator) 进行翻译。尽管我们努力确保翻译的准确性,但请注意,自动翻译可能包含错误或不准确之处。应以原始语言的文档作为权威来源。对于关键信息,建议使用专业人工翻译。我们不对因使用此翻译而产生的任何误解或误读承担责任。

@ -0,0 +1,16 @@
# 采访数据科学家
## 指导说明
在你的公司、用户组、朋友或同学中找一位专业从事数据科学工作的人员进行交流。撰写一篇简短的文章500字描述他们的日常工作内容。他们是专攻某一领域还是从事“全栈”工作
## 评分标准
| 标准 | 卓越表现 | 合格表现 | 需要改进 |
| -------- | ----------------------------------------------------------------------- | ------------------------------------------------------------- | -------------------- |
| | 提交一篇符合字数要求、带有明确来源的文章,并以 .doc 文件形式呈现 | 文章来源不明确或字数少于要求 | 未提交文章 |
---
**免责声明**
本文档使用AI翻译服务[Co-op Translator](https://github.com/Azure/co-op-translator)进行翻译。尽管我们努力确保翻译的准确性,但请注意,自动翻译可能包含错误或不准确之处。原始语言的文档应被视为权威来源。对于关键信息,建议使用专业人工翻译。我们不对因使用此翻译而产生的任何误解或误读承担责任。

@ -0,0 +1,28 @@
# 机器学习简介
在本课程部分中,您将了解机器学习领域的基本概念、它的定义,并学习它的历史以及研究人员使用的相关技术。让我们一起探索这个机器学习的新世界吧!
![globe](../../../translated_images/zh-CN/globe.59f26379ceb40428.webp)
> 图片由 <a href="https://unsplash.com/@bill_oxford?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Bill Oxford</a> 提供,来自 <a href="https://unsplash.com/s/photos/globe?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a>
### 课程
1. [机器学习简介](1-intro-to-ML/README.md)
1. [机器学习和人工智能的历史](2-history-of-ML/README.md)
1. [公平性与机器学习](3-fairness/README.md)
1. [机器学习的技术](4-techniques-of-ML/README.md)
### 致谢
《机器学习简介》由包括 [Muhammad Sakib Khan Inan](https://twitter.com/Sakibinan)、[Ornella Altunyan](https://twitter.com/ornelladotcom) 和 [Jen Looper](https://twitter.com/jenlooper) 在内的团队倾情创作。
《机器学习的历史》由 [Jen Looper](https://twitter.com/jenlooper) 和 [Amy Boyd](https://twitter.com/AmyKateNicho) 倾情创作。
《公平性与机器学习》由 [Tomomi Imura](https://twitter.com/girliemac) 倾情创作。
《机器学习的技术》由 [Jen Looper](https://twitter.com/jenlooper) 和 [Chris Noring](https://twitter.com/softchris) 倾情创作。
---
**免责声明**
本文档使用AI翻译服务[Co-op Translator](https://github.com/Azure/co-op-translator)进行翻译。尽管我们努力确保翻译的准确性,但请注意,自动翻译可能包含错误或不准确之处。原始语言的文档应被视为权威来源。对于关键信息,建议使用专业人工翻译。我们不对因使用此翻译而产生的任何误解或误读承担责任。

@ -0,0 +1,230 @@
# 使用 Python 和 Scikit-learn 构建回归模型
![回归模型的简要概述](../../../../sketchnotes/ml-regression.png)
> 由 [Tomomi Imura](https://www.twitter.com/girlie_mac) 绘制的手绘笔记
## [课前测验](https://ff-quizzes.netlify.app/en/ml/)
> ### [本课程也提供 R 版本!](../../../../2-Regression/1-Tools/solution/R/lesson_1.html)
## 简介
在这四节课中,您将学习如何构建回归模型。我们很快会讨论这些模型的用途。但在开始之前,请确保您已准备好正确的工具来进行学习!
在本课中,您将学习:
- 配置您的计算机以进行本地机器学习任务。
- 使用 Jupyter 笔记本。
- 安装并使用 Scikit-learn。
- 通过动手练习探索线性回归。
## 安装和配置
[![机器学习入门 - 配置工具以构建机器学习模型](https://img.youtube.com/vi/-DfeD2k2Kj0/0.jpg)](https://youtu.be/-DfeD2k2Kj0 "机器学习入门 - 配置工具以构建机器学习模型")
> 🎥 点击上方图片观看短视频,了解如何配置您的计算机以进行机器学习。
1. **安装 Python**。确保您的计算机上已安装 [Python](https://www.python.org/downloads/)。您将使用 Python 来完成许多数据科学和机器学习任务。大多数计算机系统已经预装了 Python。此外还有一些有用的 [Python 编码包](https://code.visualstudio.com/learn/educators/installers?WT.mc_id=academic-77952-leestott),可以简化某些用户的设置过程。
不过,某些 Python 的使用场景可能需要不同版本的软件。因此,建议您使用 [虚拟环境](https://docs.python.org/3/library/venv.html)。
2. **安装 Visual Studio Code**。确保您的计算机上已安装 Visual Studio Code。按照这些说明完成 [Visual Studio Code 的安装](https://code.visualstudio.com/)。在本课程中,您将使用 Python 在 Visual Studio Code 中进行开发,因此您可能需要了解如何 [配置 Visual Studio Code](https://docs.microsoft.com/learn/modules/python-install-vscode?WT.mc_id=academic-77952-leestott) 以进行 Python 开发。
> 通过学习这组 [模块](https://docs.microsoft.com/users/jenlooper-2911/collections/mp1pagggd5qrq7?WT.mc_id=academic-77952-leestott),熟悉 Python。
>
> [![使用 Visual Studio Code 设置 Python](https://img.youtube.com/vi/yyQM70vi7V8/0.jpg)](https://youtu.be/yyQM70vi7V8 "使用 Visual Studio Code 设置 Python")
>
> 🎥 点击上方图片观看视频:在 VS Code 中使用 Python。
3. **安装 Scikit-learn**,按照 [这些说明](https://scikit-learn.org/stable/install.html) 进行安装。由于需要确保使用 Python 3建议您使用虚拟环境。如果您在 M1 Mac 上安装此库,请参考上述页面中的特殊说明。
4. **安装 Jupyter Notebook**。您需要 [安装 Jupyter 包](https://pypi.org/project/jupyter/)。
## 您的机器学习开发环境
您将使用 **笔记本** 来开发 Python 代码并创建机器学习模型。这种文件类型是数据科学家常用的工具,其文件后缀为 `.ipynb`
笔记本是一种交互式环境,允许开发者编写代码并添加注释和文档,非常适合实验或研究项目。
[![机器学习入门 - 设置 Jupyter 笔记本以开始构建回归模型](https://img.youtube.com/vi/7E-jC8FLA2E/0.jpg)](https://youtu.be/7E-jC8FLA2E "机器学习入门 - 设置 Jupyter 笔记本以开始构建回归模型")
> 🎥 点击上方图片观看短视频,了解如何完成此练习。
### 练习 - 使用笔记本
在此文件夹中,您会找到文件 _notebook.ipynb_
1. 在 Visual Studio Code 中打开 _notebook.ipynb_
一个 Jupyter 服务器将启动,并使用 Python 3+。您会发现笔记本中可以运行的代码块。您可以通过选择播放按钮图标运行代码块。
2. 选择 `md` 图标并添加一些 markdown输入以下文本 **# 欢迎来到您的笔记本**。
接下来,添加一些 Python 代码。
3. 在代码块中输入 **print('hello notebook')**
4. 选择箭头运行代码。
您应该会看到打印的结果:
```output
hello notebook
```
![在 VS Code 中打开的笔记本](../../../../2-Regression/1-Tools/images/notebook.jpg)
您可以在代码中插入注释,以便自我记录笔记本内容。
✅ 思考一下,网页开发者的工作环境与数据科学家的工作环境有何不同。
## 使用 Scikit-learn 入门
现在Python 已在您的本地环境中设置完毕,并且您已经熟悉了 Jupyter 笔记本,接下来让我们熟悉一下 Scikit-learn发音为 `sci`,像 `science`。Scikit-learn 提供了一个 [广泛的 API](https://scikit-learn.org/stable/modules/classes.html#api-ref),帮助您完成机器学习任务。
根据其 [官网](https://scikit-learn.org/stable/getting_started.html) 的介绍“Scikit-learn 是一个开源机器学习库,支持监督学习和无监督学习。它还提供了各种工具,用于模型拟合、数据预处理、模型选择和评估,以及许多其他实用功能。”
在本课程中,您将使用 Scikit-learn 和其他工具构建机器学习模型以完成我们称为“传统机器学习”的任务。我们特意避开了神经网络和深度学习因为这些内容将在即将推出的“AI 入门”课程中详细介绍。
Scikit-learn 使构建模型并评估其使用变得简单。它主要专注于使用数值数据,并包含几个现成的数据集供学习使用。它还包括一些预构建的模型供学生尝试。让我们探索加载预打包数据并使用内置估算器构建第一个机器学习模型的过程。
## 练习 - 您的第一个 Scikit-learn 笔记本
> 本教程的灵感来源于 Scikit-learn 网站上的 [线性回归示例](https://scikit-learn.org/stable/auto_examples/linear_model/plot_ols.html#sphx-glr-auto-examples-linear-model-plot-ols-py)。
[![机器学习入门 - 您的第一个 Python 线性回归项目](https://img.youtube.com/vi/2xkXL5EUpS0/0.jpg)](https://youtu.be/2xkXL5EUpS0 "机器学习入门 - 您的第一个 Python 线性回归项目")
> 🎥 点击上方图片观看短视频,了解如何完成此练习。
在与本课相关的 _notebook.ipynb_ 文件中,按下“垃圾桶”图标清空所有单元格。
在本节中,您将使用 Scikit-learn 中内置的一个关于糖尿病的小型数据集进行学习。假设您想测试一种针对糖尿病患者的治疗方法。机器学习模型可能会帮助您根据变量的组合确定哪些患者对治疗的反应更好。即使是一个非常基础的回归模型,当可视化时,也可能显示有关变量的信息,帮助您组织理论临床试验。
✅ 回归方法有很多种,选择哪一种取决于您想要回答的问题。如果您想预测某个年龄段的人的可能身高,您可以使用线性回归,因为您在寻找一个 **数值**。如果您想确定某种菜肴是否应该被归类为素食,您在寻找一个 **类别分配**,因此您可以使用逻辑回归。稍后您将学习更多关于逻辑回归的内容。思考一下,您可以向数据提出哪些问题,以及哪种方法更适合回答这些问题。
让我们开始这个任务。
### 导入库
在此任务中,我们将导入一些库:
- **matplotlib**。这是一个有用的 [绘图工具](https://matplotlib.org/),我们将用它来创建折线图。
- **numpy**。 [numpy](https://numpy.org/doc/stable/user/whatisnumpy.html) 是一个处理 Python 数值数据的有用库。
- **sklearn**。这是 [Scikit-learn](https://scikit-learn.org/stable/user_guide.html) 库。
导入一些库以帮助完成任务。
1. 通过输入以下代码添加导入:
```python
import matplotlib.pyplot as plt
import numpy as np
from sklearn import datasets, linear_model, model_selection
```
上述代码导入了 `matplotlib``numpy`,并从 `sklearn` 中导入了 `datasets`、`linear_model` 和 `model_selection`。`model_selection` 用于将数据分割为训练集和测试集。
### 糖尿病数据集
内置的 [糖尿病数据集](https://scikit-learn.org/stable/datasets/toy_dataset.html#diabetes-dataset) 包括 442 个关于糖尿病的数据样本,包含 10 个特征变量,其中一些包括:
- age年龄以年为单位
- bmi身体质量指数
- bp平均血压
- s1 tcT 细胞(白细胞的一种)
✅ 此数据集包含“性别”这一特征变量,这在糖尿病研究中很重要。许多医学数据集都包含这种二元分类。思考一下,这种分类可能会如何将某些群体排除在治疗之外。
现在,加载 X 和 y 数据。
> 🎓 请记住这是监督学习我们需要一个名为“y”的目标变量。
在新的代码单元中,通过调用 `load_diabetes()` 加载糖尿病数据集。输入参数 `return_X_y=True` 表示 `X` 将是数据矩阵,而 `y` 将是回归目标。
1. 添加一些打印命令以显示数据矩阵的形状及其第一个元素:
```python
X, y = datasets.load_diabetes(return_X_y=True)
print(X.shape)
print(X[0])
```
您得到的响应是一个元组。您将元组的前两个值分别赋给 `X``y`。了解更多 [关于元组](https://wikipedia.org/wiki/Tuple)。
您可以看到这些数据有 442 个项目,每个项目是包含 10 个元素的数组:
```text
(442, 10)
[ 0.03807591 0.05068012 0.06169621 0.02187235 -0.0442235 -0.03482076
-0.04340085 -0.00259226 0.01990842 -0.01764613]
```
✅ 思考一下数据与回归目标之间的关系。线性回归预测特征 X 和目标变量 y 之间的关系。您能在文档中找到糖尿病数据集的 [目标](https://scikit-learn.org/stable/datasets/toy_dataset.html#diabetes-dataset) 吗?这个数据集展示了什么?
2. 接下来,通过选择数据集的第 3 列来绘制部分数据。您可以使用 `:` 操作符选择所有行然后使用索引2选择第 3 列。您还可以使用 `reshape(n_rows, n_columns)` 将数据重塑为二维数组(绘图所需)。如果其中一个参数为 -1则对应的维度会自动计算。
```python
X = X[:, 2]
X = X.reshape((-1,1))
```
✅ 随时打印数据以检查其形状。
3. 现在您已经准备好绘制数据可以看看机器是否能帮助确定数据集中的逻辑分割。为此您需要将数据X和目标y分割为测试集和训练集。Scikit-learn 提供了一种简单的方法,您可以在给定点分割测试数据。
```python
X_train, X_test, y_train, y_test = model_selection.train_test_split(X, y, test_size=0.33)
```
4. 现在您可以训练模型了!加载线性回归模型,并使用 `model.fit()` 用 X 和 y 训练集训练模型:
```python
model = linear_model.LinearRegression()
model.fit(X_train, y_train)
```
`model.fit()` 是一个您会在许多机器学习库(如 TensorFlow中看到的函数。
5. 然后,使用测试数据创建预测,使用 `predict()` 函数。这将用于绘制数据组之间的分割线。
```python
y_pred = model.predict(X_test)
```
6. 现在是时候用图表展示数据了。Matplotlib 是一个非常有用的工具。创建一个所有 X 和 y 测试数据的散点图,并使用预测结果在数据组之间绘制一条最合适的线。
```python
plt.scatter(X_test, y_test, color='black')
plt.plot(X_test, y_pred, color='blue', linewidth=3)
plt.xlabel('Scaled BMIs')
plt.ylabel('Disease Progression')
plt.title('A Graph Plot Showing Diabetes Progression Against BMI')
plt.show()
```
![显示糖尿病数据点的散点图](../../../../2-Regression/1-Tools/images/scatterplot.png)
✅ 想一想这里发生了什么。一条直线穿过许多小数据点,但它究竟在做什么?你能看出如何利用这条线来预测一个新的、未见过的数据点在图表的 y 轴上的位置吗?试着用语言描述这个模型的实际用途。
恭喜你!你已经构建了第一个线性回归模型,用它进行了预测,并将结果显示在图表中!
---
## 🚀挑战
绘制该数据集中不同变量的图表。提示:编辑这行代码:`X = X[:,2]`。根据该数据集的目标,你能发现关于糖尿病作为一种疾病的进展的什么信息?
## [课后测验](https://ff-quizzes.netlify.app/en/ml/)
## 复习与自学
在本教程中,你使用了简单线性回归,而不是单变量或多变量线性回归。阅读一些关于这些方法之间差异的内容,或者观看[这个视频](https://www.coursera.org/lecture/quantifying-relationships-regression-models/linear-vs-nonlinear-categorical-variables-ai2Ef)。
阅读更多关于回归的概念,并思考这种技术可以回答哪些类型的问题。通过[这个教程](https://docs.microsoft.com/learn/modules/train-evaluate-regression-models?WT.mc_id=academic-77952-leestott)来加深你的理解。
## 作业
[一个不同的数据集](assignment.md)
---
**免责声明**
本文档使用AI翻译服务[Co-op Translator](https://github.com/Azure/co-op-translator)进行翻译。尽管我们努力确保准确性,但请注意,自动翻译可能包含错误或不准确之处。应以原始语言的文档作为权威来源。对于关键信息,建议使用专业人工翻译。因使用本翻译而导致的任何误解或误读,我们概不负责。

@ -0,0 +1,18 @@
# 使用 Scikit-learn 进行回归分析
## 说明
查看 Scikit-learn 中的 [Linnerud 数据集](https://scikit-learn.org/stable/modules/generated/sklearn.datasets.load_linnerud.html#sklearn.datasets.load_linnerud)。这个数据集包含多个[目标变量](https://scikit-learn.org/stable/datasets/toy_dataset.html#linnerrud-dataset):“它由三项运动(数据)和三项生理指标(目标变量)组成,这些数据是从一家健身俱乐部的二十名中年男性中收集的。”
用你自己的话描述如何创建一个回归模型,以绘制腰围与完成仰卧起坐次数之间的关系。同样,针对该数据集中的其他数据点也进行类似的描述。
## 评分标准
| 标准 | 优秀 | 合格 | 需要改进 |
| ----------------------------- | --------------------------------- | ---------------------------- | ------------------------- |
| 提交描述性段落 | 提交了一段写得很好的描述性段落 | 提交了几句话 | 未提供任何描述 |
---
**免责声明**
本文档使用AI翻译服务[Co-op Translator](https://github.com/Azure/co-op-translator)进行翻译。尽管我们努力确保翻译的准确性,但请注意,自动翻译可能包含错误或不准确之处。原始语言的文档应被视为权威来源。对于关键信息,建议使用专业人工翻译。我们不对因使用此翻译而产生的任何误解或误读承担责任。

@ -0,0 +1,6 @@
---
**免责声明**
本文档使用AI翻译服务 [Co-op Translator](https://github.com/Azure/co-op-translator) 进行翻译。尽管我们努力确保翻译的准确性,但请注意,自动翻译可能包含错误或不准确之处。原始语言的文档应被视为权威来源。对于关键信息,建议使用专业人工翻译。我们不对因使用此翻译而产生的任何误解或误读承担责任。

@ -0,0 +1,447 @@
{
"nbformat": 4,
"nbformat_minor": 2,
"metadata": {
"colab": {
"name": "lesson_1-R.ipynb",
"provenance": [],
"collapsed_sections": [],
"toc_visible": true
},
"kernelspec": {
"name": "ir",
"display_name": "R"
},
"language_info": {
"name": "R"
},
"coopTranslator": {
"original_hash": "c18d3bd0bd8ae3878597e89dcd1fa5c1",
"translation_date": "2025-09-03T19:43:03+00:00",
"source_file": "2-Regression/1-Tools/solution/R/lesson_1-R.ipynb",
"language_code": "zh"
}
},
"cells": [
{
"cell_type": "markdown",
"source": [],
"metadata": {
"id": "YJUHCXqK57yz"
}
},
{
"cell_type": "markdown",
"source": [
"## 回归简介 - 第1课\n",
"\n",
"#### 放到实际情境中\n",
"\n",
"✅ 回归方法有很多种,选择哪一种取决于你想要得到的答案。如果你想预测某个年龄段的人可能的身高,你会使用 `线性回归`,因为你在寻找一个**数值结果**。如果你想知道某种菜肴是否应该被归类为素食,你是在寻找一个**类别分配**,因此你会使用 `逻辑回归`。稍后你会学习更多关于逻辑回归的内容。试着思考一些你可以从数据中提出的问题,以及哪种方法更适合这些问题。\n",
"\n",
"在本节中,你将使用一个[关于糖尿病的小型数据集](https://www4.stat.ncsu.edu/~boos/var.select/diabetes.html)。假设你想测试一种针对糖尿病患者的治疗方法。机器学习模型可能会帮助你根据变量的组合确定哪些患者对治疗的反应更好。即使是一个非常基础的回归模型,在可视化时也可能显示出一些关于变量的信息,这些信息可以帮助你组织理论上的临床试验。\n",
"\n",
"话不多说,让我们开始这项任务吧!\n",
"\n",
"<p >\n",
" <img src=\"../../images/encouRage.jpg\"\n",
" width=\"630\"/>\n",
" <figcaption>由 @allison_horst 创作的艺术作品</figcaption>\n",
"\n",
"<!--![由 \\@allison_horst 创作的艺术作品](../../../../../../translated_images/zh-CN/encouRage.e75d5fe0367fb913.webp)<br>由 @allison_horst 创作的艺术作品-->\n"
],
"metadata": {
"id": "LWNNzfqd6feZ"
}
},
{
"cell_type": "markdown",
"source": [
"## 1. 加载工具集\n",
"\n",
"在这个任务中,我们需要以下软件包:\n",
"\n",
"- `tidyverse` [tidyverse](https://www.tidyverse.org/) 是一个[由 R 软件包组成的集合](https://www.tidyverse.org/packages),旨在让数据科学更快速、更简单、更有趣!\n",
"\n",
"- `tidymodels` [tidymodels](https://www.tidymodels.org/) 框架是一个[由软件包组成的集合](https://www.tidymodels.org/packages/),用于建模和机器学习。\n",
"\n",
"你可以通过以下命令安装它们:\n",
"\n",
"`install.packages(c(\"tidyverse\", \"tidymodels\"))`\n",
"\n",
"下面的脚本会检查你是否拥有完成本模块所需的软件包,并在缺少某些软件包时为你安装它们。\n"
],
"metadata": {
"id": "FIo2YhO26wI9"
}
},
{
"cell_type": "code",
"execution_count": 2,
"source": [
"suppressWarnings(if(!require(\"pacman\")) install.packages(\"pacman\"))\n",
"pacman::p_load(tidyverse, tidymodels)"
],
"outputs": [
{
"output_type": "stream",
"name": "stderr",
"text": [
"Loading required package: pacman\n",
"\n"
]
}
],
"metadata": {
"id": "cIA9fz9v7Dss",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "2df7073b-86b2-4b32-cb86-0da605a0dc11"
}
},
{
"cell_type": "markdown",
"source": [
"现在,让我们加载这些超棒的包并使它们在我们当前的 R 会话中可用。(这只是为了说明,`pacman::p_load()` 已经为您完成了这一操作)\n"
],
"metadata": {
"id": "gpO_P_6f9WUG"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# load the core Tidyverse packages\r\n",
"library(tidyverse)\r\n",
"\r\n",
"# load the core Tidymodels packages\r\n",
"library(tidymodels)\r\n"
],
"outputs": [],
"metadata": {
"id": "NLMycgG-9ezO"
}
},
{
"cell_type": "markdown",
"source": [
"## 2. 糖尿病数据集\n",
"\n",
"在本次练习中,我们将通过对糖尿病数据集进行预测来展示我们的回归技能。[糖尿病数据集](https://www4.stat.ncsu.edu/~boos/var.select/diabetes.rwrite1.txt) 包含 `442 个样本`,数据包括 10 个预测特征变量:`年龄`、`性别`、`身体质量指数`、`平均血压`以及 `六项血清测量值`,还有一个结果变量 `y`:衡量基线后一年疾病进展的定量指标。\n",
"\n",
"|观察数量|442|\n",
"|----------------------|:---|\n",
"|预测变量数量|前 10 列为数值型预测变量|\n",
"|结果/目标|第 11 列为基线后一年疾病进展的定量指标|\n",
"|预测变量信息|- 年龄(以年为单位)\n",
"||- 性别\n",
"||- bmi 身体质量指数\n",
"||- bp 平均血压\n",
"||- s1 tc总血清胆固醇\n",
"||- s2 ldl低密度脂蛋白\n",
"||- s3 hdl高密度脂蛋白\n",
"||- s4 tch总胆固醇 / HDL\n",
"||- s5 ltg可能是血清甘油三酯水平的对数值\n",
"||- s6 glu血糖水平|\n",
"\n",
"> 🎓 记住,这是监督学习,我们需要一个名为 'y' 的目标变量。\n",
"\n",
"在使用 R 操作数据之前,您需要将数据导入 R 的内存,或者建立一个 R 可以用来远程访问数据的连接。\n",
"\n",
"> [readr](https://readr.tidyverse.org/) 包是 Tidyverse 的一部分,它提供了一种快速且友好的方式将矩形数据读入 R。\n",
"\n",
"现在,让我们加载来源 URL 提供的糖尿病数据集:<https://www4.stat.ncsu.edu/~boos/var.select/diabetes.html>\n",
"\n",
"此外,我们将使用 `glimpse()` 对数据进行基本检查,并使用 `slice()` 显示前 5 行。\n",
"\n",
"在继续之前,让我们介绍一个您在 R 代码中经常会遇到的东西 🥁🥁:管道操作符 `%>%`\n",
"\n",
"管道操作符 (`%>%`) 按逻辑顺序执行操作,将一个对象传递到函数或表达式中。您可以将管道操作符理解为代码中的“然后”。\n"
],
"metadata": {
"id": "KM6iXLH996Cl"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Import the data set\r\n",
"diabetes <- read_table2(file = \"https://www4.stat.ncsu.edu/~boos/var.select/diabetes.rwrite1.txt\")\r\n",
"\r\n",
"\r\n",
"# Get a glimpse and dimensions of the data\r\n",
"glimpse(diabetes)\r\n",
"\r\n",
"\r\n",
"# Select the first 5 rows of the data\r\n",
"diabetes %>% \r\n",
" slice(1:5)"
],
"outputs": [],
"metadata": {
"id": "Z1geAMhM-bSP"
}
},
{
"cell_type": "markdown",
"source": [
"`glimpse()` 命令显示,这个数据集有 442 行和 11 列,所有列的数据类型均为 `double`。\n",
"\n",
"<br>\n",
"\n",
"> `glimpse()` 和 `slice()` 是 [`dplyr`](https://dplyr.tidyverse.org/) 包中的函数。Dplyr 是 Tidyverse 的一部分,它是一种数据操作的语法,提供了一组一致的动词,帮助解决最常见的数据处理问题。\n",
"\n",
"<br>\n",
"\n",
"现在我们已经有了数据,接下来让我们聚焦于一个特征(`bmi`),作为本次练习的目标。为此,我们需要选择所需的列。那么,我们该如何操作呢?\n",
"\n",
"[`dplyr::select()`](https://dplyr.tidyverse.org/reference/select.html) 函数允许我们在数据框中*选择*(并可选地重命名)列。\n"
],
"metadata": {
"id": "UwjVT1Hz-c3Z"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Select predictor feature `bmi` and outcome `y`\r\n",
"diabetes_select <- diabetes %>% \r\n",
" select(c(bmi, y))\r\n",
"\r\n",
"# Print the first 5 rows\r\n",
"diabetes_select %>% \r\n",
" slice(1:10)"
],
"outputs": [],
"metadata": {
"id": "RDY1oAKI-m80"
}
},
{
"cell_type": "markdown",
"source": [
"## 3. 训练和测试数据\n",
"\n",
"在监督学习中,通常的做法是将数据*分割*成两个子集:一个(通常较大的)用于训练模型的集合,以及一个较小的“保留”集合,用于查看模型的表现如何。\n",
"\n",
"现在我们已经准备好了数据,可以看看机器是否能够帮助我们在这个数据集中找到一个合理的分割方式。我们可以使用 [rsample](https://tidymodels.github.io/rsample/) 包,它是 Tidymodels 框架的一部分,用来创建一个包含数据分割信息的对象,然后使用另外两个 rsample 函数提取生成的训练集和测试集:\n"
],
"metadata": {
"id": "SDk668xK-tc3"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"set.seed(2056)\r\n",
"# Split 67% of the data for training and the rest for tesing\r\n",
"diabetes_split <- diabetes_select %>% \r\n",
" initial_split(prop = 0.67)\r\n",
"\r\n",
"# Extract the resulting train and test sets\r\n",
"diabetes_train <- training(diabetes_split)\r\n",
"diabetes_test <- testing(diabetes_split)\r\n",
"\r\n",
"# Print the first 3 rows of the training set\r\n",
"diabetes_train %>% \r\n",
" slice(1:10)"
],
"outputs": [],
"metadata": {
"id": "EqtHx129-1h-"
}
},
{
"cell_type": "markdown",
"source": [
"## 4. 使用Tidymodels训练线性回归模型\n",
"\n",
"现在我们可以开始训练模型了!\n",
"\n",
"在Tidymodels中你可以通过`parsnip()`指定模型,主要涉及以下三个概念:\n",
"\n",
"- 模型**类型**区分了不同的模型,例如线性回归、逻辑回归、决策树模型等。\n",
"\n",
"- 模型**模式**包括常见选项如回归和分类;某些模型类型支持这两种模式,而有些仅支持其中一种。\n",
"\n",
"- 模型**引擎**是用于拟合模型的计算工具。通常这些是R包例如 **`\"lm\"`** 或 **`\"ranger\"`**。\n",
"\n",
"这些建模信息会被捕获到一个模型规范中,所以让我们来构建一个吧!\n"
],
"metadata": {
"id": "sBOS-XhB-6v7"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Build a linear model specification\r\n",
"lm_spec <- \r\n",
" # Type\r\n",
" linear_reg() %>% \r\n",
" # Engine\r\n",
" set_engine(\"lm\") %>% \r\n",
" # Mode\r\n",
" set_mode(\"regression\")\r\n",
"\r\n",
"\r\n",
"# Print the model specification\r\n",
"lm_spec"
],
"outputs": [],
"metadata": {
"id": "20OwEw20--t3"
}
},
{
"cell_type": "markdown",
"source": [
"在模型被*指定*之后,可以使用 [`fit()`](https://parsnip.tidymodels.org/reference/fit.html) 函数对模型进行`估计`或`训练`,通常使用公式和一些数据。\n",
"\n",
"`y ~ .` 表示我们将拟合 `y` 作为预测值/目标,由所有预测变量/特征解释,即 `.`(在这个例子中,我们只有一个预测变量:`bmi`)。\n"
],
"metadata": {
"id": "_oDHs89k_CJj"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Build a linear model specification\r\n",
"lm_spec <- linear_reg() %>% \r\n",
" set_engine(\"lm\") %>%\r\n",
" set_mode(\"regression\")\r\n",
"\r\n",
"\r\n",
"# Train a linear regression model\r\n",
"lm_mod <- lm_spec %>% \r\n",
" fit(y ~ ., data = diabetes_train)\r\n",
"\r\n",
"# Print the model\r\n",
"lm_mod"
],
"outputs": [],
"metadata": {
"id": "YlsHqd-q_GJQ"
}
},
{
"cell_type": "markdown",
"source": [
"从模型输出中,我们可以看到训练过程中学习到的系数。它们表示最佳拟合线的系数,该线使实际变量与预测变量之间的总体误差最小。\n",
"<br>\n",
"\n",
"## 5. 在测试集上进行预测\n",
"\n",
"现在我们已经训练了一个模型,可以使用它通过 [parsnip::predict()](https://parsnip.tidymodels.org/reference/predict.model_fit.html) 来预测测试数据集中的疾病进展 y。这将用于绘制数据组之间的分界线。\n"
],
"metadata": {
"id": "kGZ22RQj_Olu"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Make predictions for the test set\r\n",
"predictions <- lm_mod %>% \r\n",
" predict(new_data = diabetes_test)\r\n",
"\r\n",
"# Print out some of the predictions\r\n",
"predictions %>% \r\n",
" slice(1:5)"
],
"outputs": [],
"metadata": {
"id": "nXHbY7M2_aao"
}
},
{
"cell_type": "markdown",
"source": [
"哇哦!💃🕺 我们刚刚训练了一个模型,并用它进行了预测!\n",
"\n",
"在进行预测时tidymodels 的惯例是始终生成一个带有标准化列名的 tibble/数据框结果。这使得将原始数据和预测结果结合在一个可用的格式中变得非常简单,方便后续操作,例如绘图。\n",
"\n",
"`dplyr::bind_cols()` 可以高效地将多个数据框按列绑定在一起。\n"
],
"metadata": {
"id": "R_JstwUY_bIs"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Combine the predictions and the original test set\r\n",
"results <- diabetes_test %>% \r\n",
" bind_cols(predictions)\r\n",
"\r\n",
"\r\n",
"results %>% \r\n",
" slice(1:5)"
],
"outputs": [],
"metadata": {
"id": "RybsMJR7_iI8"
}
},
{
"cell_type": "markdown",
"source": [
"## 6. 绘制模型结果\n",
"\n",
"现在是时候用视觉化方式来看结果了 📈。我们将创建一个散点图,展示测试集中的所有 `y` 和 `bmi` 值,然后使用预测结果绘制一条线,将模型的数据分组之间连接起来,放在最合适的位置。\n",
"\n",
"R 有多种绘图系统,但 `ggplot2` 是其中最优雅且最灵活的一个。它允许你通过**组合独立组件**来构建图表。\n"
],
"metadata": {
"id": "XJbYbMZW_n_s"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Set a theme for the plot\r\n",
"theme_set(theme_light())\r\n",
"# Create a scatter plot\r\n",
"results %>% \r\n",
" ggplot(aes(x = bmi)) +\r\n",
" # Add a scatter plot\r\n",
" geom_point(aes(y = y), size = 1.6) +\r\n",
" # Add a line plot\r\n",
" geom_line(aes(y = .pred), color = \"blue\", size = 1.5)"
],
"outputs": [],
"metadata": {
"id": "R9tYp3VW_sTn"
}
},
{
"cell_type": "markdown",
"source": [
"✅ 想一想这里发生了什么。一条直线穿过了许多小数据点,但它究竟在做什么呢?你能看出如何利用这条直线来预测一个新的、未见过的数据点应该如何与图表的 y 轴相关联吗?试着用语言描述这个模型的实际用途。\n",
"\n",
"恭喜你!你已经构建了第一个线性回归模型,用它进行了预测,并在图表中展示了结果!\n"
],
"metadata": {
"id": "zrPtHIxx_tNI"
}
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**免责声明** \n本文档使用AI翻译服务[Co-op Translator](https://github.com/Azure/co-op-translator)进行翻译。尽管我们努力确保翻译的准确性,但请注意,自动翻译可能包含错误或不准确之处。原始语言的文档应被视为权威来源。对于关键信息,建议使用专业人工翻译。我们不对因使用此翻译而产生的任何误解或误读承担责任。\n"
]
}
]
}

File diff suppressed because one or more lines are too long

@ -0,0 +1,217 @@
# 使用 Scikit-learn 构建回归模型:准备和可视化数据
![数据可视化信息图](../../../../2-Regression/2-Data/images/data-visualization.png)
信息图作者:[Dasani Madipalli](https://twitter.com/dasani_decoded)
## [课前测验](https://ff-quizzes.netlify.app/en/ml/)
> ### [本课程也提供 R 版本!](../../../../2-Regression/2-Data/solution/R/lesson_2.html)
## 简介
现在你已经准备好使用 Scikit-learn 开始构建机器学习模型,可以开始向数据提出问题了。在处理数据并应用机器学习解决方案时,了解如何提出正确的问题以充分挖掘数据的潜力非常重要。
在本课中,你将学习:
- 如何为模型构建准备数据。
- 如何使用 Matplotlib 进行数据可视化。
## 向数据提出正确的问题
你需要回答的问题将决定你使用哪种类型的机器学习算法。而你得到答案的质量将很大程度上取决于数据的性质。
看看为本课提供的[数据](https://github.com/microsoft/ML-For-Beginners/blob/main/2-Regression/data/US-pumpkins.csv)。你可以在 VS Code 中打开这个 .csv 文件。快速浏览会发现其中有空白值还有字符串和数值数据的混合。此外还有一个名为“Package”的奇怪列其中的数据是“sacks”、“bins”和其他值的混合。事实上这些数据有点混乱。
[![机器学习入门 - 如何分析和清理数据集](https://img.youtube.com/vi/5qGjczWTrDQ/0.jpg)](https://youtu.be/5qGjczWTrDQ "机器学习入门 - 如何分析和清理数据集")
> 🎥 点击上方图片观看准备本课数据的简短视频。
事实上,很少会直接获得一个完全准备好用于创建机器学习模型的数据集。在本课中,你将学习如何使用标准 Python 库准备原始数据集。你还将学习各种数据可视化技术。
## 案例研究:“南瓜市场”
在本文件夹中,你会发现根目录 `data` 文件夹中有一个名为 [US-pumpkins.csv](https://github.com/microsoft/ML-For-Beginners/blob/main/2-Regression/data/US-pumpkins.csv) 的 .csv 文件,其中包含关于南瓜市场的 1757 行数据,这些数据按城市分组。这是从美国农业部发布的[特种作物终端市场标准报告](https://www.marketnews.usda.gov/mnp/fv-report-config-step1?type=termPrice)中提取的原始数据。
### 准备数据
这些数据属于公共领域。可以从 USDA 网站按城市下载多个单独的文件。为了避免过多的单独文件我们将所有城市数据合并到一个电子表格中因此我们已经对数据进行了部分_准备_。接下来让我们仔细看看这些数据。
### 南瓜数据 - 初步结论
你对这些数据有什么发现?你可能已经注意到其中有字符串、数字、空白和一些需要理解的奇怪值。
使用回归技术,你可以向这些数据提出什么问题?比如“预测某个月份出售南瓜的价格”。再次查看数据,你需要进行一些更改以创建适合任务的数据结构。
## 练习 - 分析南瓜数据
让我们使用 [Pandas](https://pandas.pydata.org/)(名称代表 `Python Data Analysis`),一个非常有用的数据处理工具,来分析和准备这些南瓜数据。
### 首先,检查缺失日期
你首先需要采取步骤检查是否有缺失日期:
1. 将日期转换为月份格式(这些是美国日期,格式为 `MM/DD/YYYY`)。
2. 提取月份到一个新列。
在 Visual Studio Code 中打开 _notebook.ipynb_ 文件,并将电子表格导入到一个新的 Pandas 数据框中。
1. 使用 `head()` 函数查看前五行。
```python
import pandas as pd
pumpkins = pd.read_csv('../data/US-pumpkins.csv')
pumpkins.head()
```
✅ 你会使用什么函数来查看最后五行?
1. 检查当前数据框中是否有缺失数据:
```python
pumpkins.isnull().sum()
```
存在缺失数据,但可能对当前任务没有影响。
1. 为了让数据框更易于操作,使用 `loc` 函数选择你需要的列。`loc` 函数从原始数据框中提取一组行(作为第一个参数传递)和列(作为第二个参数传递)。下面的表达式 `:` 表示“所有行”。
```python
columns_to_select = ['Package', 'Low Price', 'High Price', 'Date']
pumpkins = pumpkins.loc[:, columns_to_select]
```
### 其次,确定南瓜的平均价格
思考如何确定某个月份南瓜的平均价格。你会选择哪些列来完成这个任务?提示:你需要 3 列。
解决方案:取 `Low Price``High Price` 列的平均值来填充新的 Price 列,并将 Date 列转换为仅显示月份。幸运的是,根据上面的检查,日期和价格没有缺失数据。
1. 要计算平均值,添加以下代码:
```python
price = (pumpkins['Low Price'] + pumpkins['High Price']) / 2
month = pd.DatetimeIndex(pumpkins['Date']).month
```
✅ 随时使用 `print(month)` 打印任何数据以进行检查。
2. 现在,将转换后的数据复制到一个新的 Pandas 数据框中:
```python
new_pumpkins = pd.DataFrame({'Month': month, 'Package': pumpkins['Package'], 'Low Price': pumpkins['Low Price'],'High Price': pumpkins['High Price'], 'Price': price})
```
打印出你的数据框会显示一个干净整洁的数据集,你可以用它来构建新的回归模型。
### 等等!这里有些奇怪的地方
如果你查看 `Package`南瓜以许多不同的配置出售。有些以“1 1/9 bushel”计量有些以“1/2 bushel”计量有些按南瓜个数出售有些按磅出售还有些以不同宽度的大箱子出售。
> 南瓜似乎很难一致地称重
深入研究原始数据,发现 `Unit of Sale` 等于 'EACH' 或 'PER BIN' 的数据,其 `Package` 类型也为每英寸、每箱或“每个”。南瓜似乎很难一致地称重,因此我们通过选择 `Package` 列中包含字符串 'bushel' 的南瓜来进行过滤。
1. 在文件顶部的初始 .csv 导入下添加过滤器:
```python
pumpkins = pumpkins[pumpkins['Package'].str.contains('bushel', case=True, regex=True)]
```
如果现在打印数据,你会发现只剩下约 415 行按 bushel 销售的南瓜数据。
### 等等!还有一件事要做
你是否注意到每行的 bushel 数量不同?你需要对价格进行标准化,以显示每 bushel 的价格,因此需要进行一些数学计算来统一标准。
1. 在创建 new_pumpkins 数据框的代码块后添加以下代码:
```python
new_pumpkins.loc[new_pumpkins['Package'].str.contains('1 1/9'), 'Price'] = price/(1 + 1/9)
new_pumpkins.loc[new_pumpkins['Package'].str.contains('1/2'), 'Price'] = price/(1/2)
```
✅ 根据 [The Spruce Eats](https://www.thespruceeats.com/how-much-is-a-bushel-1389308)bushel 的重量取决于农产品的类型,因为它是一个体积测量单位。“例如,一 bushel 的番茄应该重 56 磅……叶子和绿叶占据更多空间但重量较轻,因此一 bushel 的菠菜只有 20 磅。”这非常复杂!我们不必进行 bushel 到磅的转换,而是按 bushel 定价。然而,所有这些关于南瓜 bushel 的研究表明,了解数据的性质是多么重要!
现在,你可以根据 bushel 测量分析每单位的定价。如果再打印一次数据,你会看到它已经标准化。
✅ 你是否注意到按半 bushel 销售的南瓜非常昂贵?你能找出原因吗?提示:小南瓜比大南瓜贵得多,可能是因为每 bushel 中小南瓜的数量更多,而大空心南瓜占据了更多未使用的空间。
## 可视化策略
数据科学家的部分职责是展示他们正在处理的数据的质量和性质。为此,他们通常会创建有趣的可视化,例如图表、图形和表格,展示数据的不同方面。通过这种方式,他们能够直观地展示关系和差距,这些关系和差距可能很难通过其他方式发现。
[![机器学习入门 - 如何使用 Matplotlib 可视化数据](https://img.youtube.com/vi/SbUkxH6IJo0/0.jpg)](https://youtu.be/SbUkxH6IJo0 "机器学习入门 - 如何使用 Matplotlib 可视化数据")
> 🎥 点击上方图片观看本课数据可视化的简短视频。
可视化还可以帮助确定最适合数据的机器学习技术。例如,一个看起来沿着一条线分布的散点图表明数据非常适合线性回归练习。
一个在 Jupyter 笔记本中表现良好的数据可视化库是 [Matplotlib](https://matplotlib.org/)(你在上一课中也见过它)。
> 在[这些教程](https://docs.microsoft.com/learn/modules/explore-analyze-data-with-python?WT.mc_id=academic-77952-leestott)中获得更多数据可视化经验。
## 练习 - 试验 Matplotlib
尝试创建一些基本图表来显示你刚刚创建的新数据框。基本折线图会显示什么?
1. 在文件顶部的 Pandas 导入下导入 Matplotlib
```python
import matplotlib.pyplot as plt
```
1. 重新运行整个笔记本以刷新。
1. 在笔记本底部添加一个单元格,将数据绘制为一个框图:
```python
price = new_pumpkins.Price
month = new_pumpkins.Month
plt.scatter(price, month)
plt.show()
```
![一个显示价格与月份关系的散点图](../../../../2-Regression/2-Data/images/scatterplot.png)
这是一个有用的图表吗?它是否让你感到惊讶?
它并不是特别有用,因为它只是显示了某个月份的数据点分布。
### 让它更有用
为了让图表显示有用的数据,你通常需要以某种方式对数据进行分组。让我们尝试创建一个图表,其中 y 轴显示月份,数据展示数据的分布。
1. 添加一个单元格以创建分组柱状图:
```python
new_pumpkins.groupby(['Month'])['Price'].mean().plot(kind='bar')
plt.ylabel("Pumpkin Price")
```
![一个显示价格与月份关系的柱状图](../../../../2-Regression/2-Data/images/barchart.png)
这是一个更有用的数据可视化!它似乎表明南瓜的最高价格出现在九月和十月。这符合你的预期吗?为什么?
---
## 🚀挑战
探索 Matplotlib 提供的不同类型的可视化。哪些类型最适合回归问题?
## [课后测验](https://ff-quizzes.netlify.app/en/ml/)
## 复习与自学
看看可视化数据的各种方法。列出可用的各种库,并记录哪些库最适合特定类型的任务,例如 2D 可视化与 3D 可视化。你发现了什么?
## 作业
[探索可视化](assignment.md)
---
**免责声明**
本文档使用AI翻译服务[Co-op Translator](https://github.com/Azure/co-op-translator)进行翻译。尽管我们努力确保准确性,但请注意,自动翻译可能包含错误或不准确之处。应以原始语言的文档作为权威来源。对于关键信息,建议使用专业人工翻译。因使用本翻译而导致的任何误解或误读,我们概不负责。

@ -0,0 +1,14 @@
# 探索可视化
有许多不同的库可用于数据可视化。在本课中使用南瓜数据,在示例笔记本中使用 matplotlib 和 seaborn 创建一些可视化。哪些库更容易使用?
## 评分标准
| 标准 | 卓越 | 合格 | 需要改进 |
| -------- | --------- | -------- | ----------------- |
| | 提交的笔记本包含两个探索/可视化 | 提交的笔记本包含一个探索/可视化 | 未提交笔记本 |
---
**免责声明**
本文档使用AI翻译服务[Co-op Translator](https://github.com/Azure/co-op-translator)进行翻译。尽管我们努力确保翻译的准确性,但请注意,自动翻译可能包含错误或不准确之处。原始语言的文档应被视为权威来源。对于关键信息,建议使用专业人工翻译。我们对因使用此翻译而产生的任何误解或误读不承担责任。

@ -0,0 +1,46 @@
{
"metadata": {
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.3-final"
},
"orig_nbformat": 2,
"kernelspec": {
"name": "python3",
"display_name": "Python 3",
"language": "python"
},
"coopTranslator": {
"original_hash": "1b2ab303ac6c604a34c6ca7a49077fc7",
"translation_date": "2025-09-03T19:44:44+00:00",
"source_file": "2-Regression/2-Data/notebook.ipynb",
"language_code": "zh"
}
},
"nbformat": 4,
"nbformat_minor": 2,
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**免责声明** \n本文档使用AI翻译服务[Co-op Translator](https://github.com/Azure/co-op-translator)进行翻译。尽管我们努力确保翻译的准确性,但请注意,自动翻译可能包含错误或不准确之处。原始语言的文档应被视为权威来源。对于关键信息,建议使用专业人工翻译。我们不对因使用此翻译而产生的任何误解或误读承担责任。\n"
]
}
]
}

@ -0,0 +1,6 @@
---
**免责声明**
本文档使用AI翻译服务[Co-op Translator](https://github.com/Azure/co-op-translator)进行翻译。尽管我们努力确保翻译的准确性,但请注意,自动翻译可能包含错误或不准确之处。原始语言的文档应被视为权威来源。对于关键信息,建议使用专业人工翻译。我们不对因使用此翻译而产生的任何误解或误读承担责任。

@ -0,0 +1,670 @@
{
"nbformat": 4,
"nbformat_minor": 2,
"metadata": {
"colab": {
"name": "lesson_2-R.ipynb",
"provenance": [],
"collapsed_sections": [],
"toc_visible": true
},
"kernelspec": {
"name": "ir",
"display_name": "R"
},
"language_info": {
"name": "R"
},
"coopTranslator": {
"original_hash": "f3c335f9940cfd76528b3ef918b9b342",
"translation_date": "2025-09-03T19:50:05+00:00",
"source_file": "2-Regression/2-Data/solution/R/lesson_2-R.ipynb",
"language_code": "zh"
}
},
"cells": [
{
"cell_type": "markdown",
"source": [
"# 构建回归模型:准备和可视化数据\n",
"\n",
"## **南瓜线性回归 - 第二课**\n",
"#### 介绍\n",
"\n",
"现在你已经准备好了使用Tidymodels和Tidyverse来构建机器学习模型的工具可以开始对数据提出问题了。在处理数据并应用机器学习解决方案时正确提出问题以充分挖掘数据的潜力是非常重要的。\n",
"\n",
"在本课中,你将学习:\n",
"\n",
"- 如何为模型构建准备数据。\n",
"\n",
"- 如何使用`ggplot2`进行数据可视化。\n",
"\n",
"你需要回答的问题将决定你使用哪种类型的机器学习算法。而你得到的答案质量将很大程度上取决于数据的性质。\n",
"\n",
"让我们通过一个实际练习来看看这一点。\n",
"\n",
"<p >\n",
" <img src=\"../../images/unruly_data.jpg\"\n",
" width=\"700\"/>\n",
" <figcaption>艺术作品由 @allison_horst 提供</figcaption>\n",
"\n",
"\n",
"<!--![艺术作品由 \\@allison_horst 提供](../../../../../../translated_images/zh-CN/unruly_data.0eedc7ced92d2d91.webp)<br>艺术作品由 \\@allison_horst 提供-->\n"
],
"metadata": {
"id": "Pg5aexcOPqAZ"
}
},
{
"cell_type": "markdown",
"source": [
"## 1. 导入南瓜数据并召唤 Tidyverse\n",
"\n",
"我们需要以下软件包来完成本课程的分析和处理:\n",
"\n",
"- `tidyverse` [tidyverse](https://www.tidyverse.org/) 是一个 [R 软件包集合](https://www.tidyverse.org/packages),旨在让数据科学更快速、更简单、更有趣!\n",
"\n",
"你可以通过以下方式安装它们:\n",
"\n",
"`install.packages(c(\"tidyverse\"))`\n",
"\n",
"下面的脚本会检查你是否已经安装了完成本模块所需的软件包,并在缺少时为你安装它们。\n"
],
"metadata": {
"id": "dc5WhyVdXAjR"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"suppressWarnings(if(!require(\"pacman\")) install.packages(\"pacman\"))\n",
"pacman::p_load(tidyverse)"
],
"outputs": [],
"metadata": {
"id": "GqPYUZgfXOBt"
}
},
{
"cell_type": "markdown",
"source": [
"现在,让我们启动一些软件包并加载为本课程提供的[数据](https://github.com/microsoft/ML-For-Beginners/blob/main/2-Regression/data/US-pumpkins.csv)\n"
],
"metadata": {
"id": "kvjDTPDSXRr2"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Load the core Tidyverse packages\n",
"library(tidyverse)\n",
"\n",
"# Import the pumpkins data\n",
"pumpkins <- read_csv(file = \"https://raw.githubusercontent.com/microsoft/ML-For-Beginners/main/2-Regression/data/US-pumpkins.csv\")\n",
"\n",
"\n",
"# Get a glimpse and dimensions of the data\n",
"glimpse(pumpkins)\n",
"\n",
"\n",
"# Print the first 50 rows of the data set\n",
"pumpkins %>% \n",
" slice_head(n =50)"
],
"outputs": [],
"metadata": {
"id": "VMri-t2zXqgD"
}
},
{
"cell_type": "markdown",
"source": [
"一个快速的 `glimpse()` 立即显示出数据中存在空值,并且混合了字符串 (`chr`) 和数值数据 (`dbl`)。`Date` 是字符类型,还有一个奇怪的列叫做 `Package`,其中数据是 `sacks`、`bins` 和其他值的混合。事实上,这些数据有点乱 😤。\n",
"\n",
"实际上,很少会直接获得一个完全准备好用于创建机器学习模型的数据集。但别担心,在本节课中,你将学习如何使用标准的 R 库来准备一个原始数据集 🧑‍🔧。你还将学习各种技术来可视化数据。📈📊\n",
"<br>\n",
"\n",
"> 温故知新:管道操作符 (`%>%`) 按逻辑顺序执行操作,将一个对象向前传递到函数或调用表达式中。你可以将管道操作符理解为代码中的“然后”。\n"
],
"metadata": {
"id": "REWcIv9yX29v"
}
},
{
"cell_type": "markdown",
"source": [
"## 2. 检查缺失数据\n",
"\n",
"数据科学家经常需要处理的一个常见问题是数据不完整或缺失。R使用特殊的哨兵值`NA`Not Available来表示缺失或未知的值。\n",
"\n",
"那么我们如何知道数据框中是否包含缺失值呢?\n",
"<br>\n",
"- 一个直接的方法是使用R的基础函数`anyNA`,它会返回逻辑对象`TRUE`或`FALSE`\n"
],
"metadata": {
"id": "Zxfb3AM5YbUe"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"pumpkins %>% \n",
" anyNA()"
],
"outputs": [],
"metadata": {
"id": "G--DQutAYltj"
}
},
{
"cell_type": "markdown",
"source": [
"太好了,看来有一些数据缺失!这是一个不错的起点。\n",
"\n",
"- 另一种方法是使用函数 `is.na()`,它通过逻辑值 `TRUE` 来指示哪些单个列元素是缺失的。\n"
],
"metadata": {
"id": "mU-7-SB6YokF"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"pumpkins %>% \n",
" is.na() %>% \n",
" head(n = 7)"
],
"outputs": [],
"metadata": {
"id": "W-DxDOR4YxSW"
}
},
{
"cell_type": "markdown",
"source": [
"对于如此大的数据框,逐行逐列地检查显然效率低下,几乎不可能完成😴。\n",
"\n",
"- 更直观的方法是计算每列中缺失值的总和:\n"
],
"metadata": {
"id": "xUWxipKYY0o7"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"pumpkins %>% \n",
" is.na() %>% \n",
" colSums()"
],
"outputs": [],
"metadata": {
"id": "ZRBWV6P9ZArL"
}
},
{
"cell_type": "markdown",
"source": [
"更棒了!虽然有些数据缺失,但可能对当前任务影响不大。让我们看看进一步的分析会带来什么结果。\n",
"\n",
"> 除了强大的包和函数集合R 还拥有非常优秀的文档支持。例如,可以使用 `help(colSums)` 或 `?colSums` 来了解更多关于该函数的信息。\n"
],
"metadata": {
"id": "9gv-crB6ZD1Y"
}
},
{
"cell_type": "markdown",
"source": [
"## 3. Dplyr数据操作的语法\n",
"\n",
"<p >\n",
" <img src=\"../../images/dplyr_wrangling.png\"\n",
" width=\"569\"/>\n",
" <figcaption>插图作者:@allison_horst</figcaption>\n",
"\n",
"\n",
"<!--![插图作者:\\@allison_horst](../../../../../../translated_images/zh-CN/dplyr_wrangling.f5f99c64fd4580f1.webp)<br/>插图作者:\\@allison_horst-->\n"
],
"metadata": {
"id": "o4jLY5-VZO2C"
}
},
{
"cell_type": "markdown",
"source": [
"[`dplyr`](https://dplyr.tidyverse.org/) 是 Tidyverse 中的一个包,它是一种数据操作的语法,提供了一组一致的动词,帮助你解决最常见的数据操作问题。在本节中,我们将探索一些 dplyr 的动词! \n",
"<br>\n"
],
"metadata": {
"id": "i5o33MQBZWWw"
}
},
{
"cell_type": "markdown",
"source": [
"#### dplyr::select()\n",
"\n",
"`select()` 是 `dplyr` 包中的一个函数,用于选择保留或排除特定的列。\n",
"\n",
"为了让数据框更易于操作,可以使用 `select()` 删除一些列,仅保留你需要的列。\n",
"\n",
"例如,在这个练习中,我们的分析将涉及 `Package`、`Low Price`、`High Price` 和 `Date` 这些列。让我们选择这些列吧。\n"
],
"metadata": {
"id": "x3VGMAGBZiUr"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Select desired columns\n",
"pumpkins <- pumpkins %>% \n",
" select(Package, `Low Price`, `High Price`, Date)\n",
"\n",
"\n",
"# Print data set\n",
"pumpkins %>% \n",
" slice_head(n = 5)"
],
"outputs": [],
"metadata": {
"id": "F_FgxQnVZnM0"
}
},
{
"cell_type": "markdown",
"source": [
"#### dplyr::mutate()\n",
"\n",
"`mutate()` 是 `dplyr` 包中的一个函数,用于创建或修改列,同时保留现有的列。\n",
"\n",
"`mutate` 的一般结构是:\n",
"\n",
"`data %>% mutate(new_column_name = what_it_contains)`\n",
"\n",
"让我们通过以下操作来尝试使用 `mutate` 对 `Date` 列进行处理:\n",
"\n",
"1. 将日期(目前是字符类型)转换为月份格式(这些是美国日期格式,因此格式为 `MM/DD/YYYY`)。\n",
"\n",
"2. 从日期中提取月份到一个新列。\n",
"\n",
"在 R 中,[lubridate](https://lubridate.tidyverse.org/) 包可以更轻松地处理日期时间数据。因此,让我们使用 `dplyr::mutate()`、`lubridate::mdy()` 和 `lubridate::month()` 来实现上述目标。我们可以删除 `Date` 列,因为在后续操作中不再需要它。\n"
],
"metadata": {
"id": "2KKo0Ed9Z1VB"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Load lubridate\n",
"library(lubridate)\n",
"\n",
"pumpkins <- pumpkins %>% \n",
" # Convert the Date column to a date object\n",
" mutate(Date = mdy(Date)) %>% \n",
" # Extract month from Date\n",
" mutate(Month = month(Date)) %>% \n",
" # Drop Date column\n",
" select(-Date)\n",
"\n",
"# View the first few rows\n",
"pumpkins %>% \n",
" slice_head(n = 7)"
],
"outputs": [],
"metadata": {
"id": "5joszIVSZ6xe"
}
},
{
"cell_type": "markdown",
"source": [
"哇哦!🤩\n",
"\n",
"接下来,让我们创建一个新的列 `Price`,表示南瓜的平均价格。现在,我们将 `Low Price` 和 `High Price` 列的平均值计算出来,用来填充新的 Price 列。\n",
"<br>\n"
],
"metadata": {
"id": "nIgLjNMCZ-6Y"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Create a new column Price\n",
"pumpkins <- pumpkins %>% \n",
" mutate(Price = (`Low Price` + `High Price`)/2)\n",
"\n",
"# View the first few rows of the data\n",
"pumpkins %>% \n",
" slice_head(n = 5)"
],
"outputs": [],
"metadata": {
"id": "Zo0BsqqtaJw2"
}
},
{
"cell_type": "markdown",
"source": [
"耶!💪\n",
"\n",
"“等等!”你可能会在用 `View(pumpkins)` 浏览整个数据集后说,“这里有点奇怪!”🤔\n",
"\n",
"如果你查看 `Package` 列,会发现南瓜是以多种不同的方式出售的。有些是按 `1 1/9 蒲式耳` 计量出售的,有些是按 `1/2 蒲式耳` 计量出售的,有些是按个数出售的,有些是按重量(磅)出售的,还有一些是装在宽度各异的大箱子里出售的。\n",
"\n",
"让我们来验证一下:\n"
],
"metadata": {
"id": "p77WZr-9aQAR"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Verify the distinct observations in Package column\n",
"pumpkins %>% \n",
" distinct(Package)"
],
"outputs": [],
"metadata": {
"id": "XISGfh0IaUy6"
}
},
{
"cell_type": "markdown",
"source": [
"太棒了!👏\n",
"\n",
"南瓜似乎很难保持一致的称重,因此我们可以通过筛选 `Package` 列中包含字符串 *bushel* 的南瓜来过滤它们,并将结果放入一个新的数据框 `new_pumpkins` 中。\n"
],
"metadata": {
"id": "7sMjiVujaZxY"
}
},
{
"cell_type": "markdown",
"source": [
"#### dplyr::filter() 和 stringr::str_detect()\n",
"\n",
"[`dplyr::filter()`](https://dplyr.tidyverse.org/reference/filter.html):创建一个数据子集,仅包含满足条件的**行**,在本例中是 `Package` 列中包含字符串 *bushel* 的南瓜。\n",
"\n",
"[stringr::str_detect()](https://stringr.tidyverse.org/reference/str_detect.html):检测字符串中是否存在某个模式。\n",
"\n",
"[`stringr`](https://github.com/tidyverse/stringr) 包提供了用于常见字符串操作的简单函数。\n"
],
"metadata": {
"id": "L8Qfcs92ageF"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Retain only pumpkins with \"bushel\"\n",
"new_pumpkins <- pumpkins %>% \n",
" filter(str_detect(Package, \"bushel\"))\n",
"\n",
"# Get the dimensions of the new data\n",
"dim(new_pumpkins)\n",
"\n",
"# View a few rows of the new data\n",
"new_pumpkins %>% \n",
" slice_head(n = 5)"
],
"outputs": [],
"metadata": {
"id": "hy_SGYREampd"
}
},
{
"cell_type": "markdown",
"source": [
"你可以看到我们已经缩小到大约415行左右的数据这些数据包含了按蒲式耳计算的南瓜。🤩 \n"
],
"metadata": {
"id": "VrDwF031avlR"
}
},
{
"cell_type": "markdown",
"source": [
"#### dplyr::case_when()\n",
"\n",
"**但等等!还有一件事要做**\n",
"\n",
"你是否注意到每行的蒲式耳数量是不同的你需要将价格标准化以显示每蒲式耳的价格而不是每1 1/9或1/2蒲式耳的价格。是时候做一些数学运算来进行标准化了。\n",
"\n",
"我们将使用函数[`case_when()`](https://dplyr.tidyverse.org/reference/case_when.html)根据一些条件来*变更*价格列的值。`case_when`允许你将多个`if_else()`语句向量化处理。\n"
],
"metadata": {
"id": "mLpw2jH4a0tx"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Convert the price if the Package contains fractional bushel values\n",
"new_pumpkins <- new_pumpkins %>% \n",
" mutate(Price = case_when(\n",
" str_detect(Package, \"1 1/9\") ~ Price/(1 + 1/9),\n",
" str_detect(Package, \"1/2\") ~ Price/(1/2),\n",
" TRUE ~ Price))\n",
"\n",
"# View the first few rows of the data\n",
"new_pumpkins %>% \n",
" slice_head(n = 30)"
],
"outputs": [],
"metadata": {
"id": "P68kLVQmbM6I"
}
},
{
"cell_type": "markdown",
"source": [
"现在,我们可以根据蒲式耳的测量来分析每单位的定价。然而,所有这些关于南瓜蒲式耳的研究都表明,`了解数据的本质`是多么`重要`\n",
"\n",
"> ✅ 根据 [The Spruce Eats](https://www.thespruceeats.com/how-much-is-a-bushel-1389308)蒲式耳的重量取决于农产品的类型因为它是一种体积测量单位。“例如一个番茄的蒲式耳应该重56磅……叶类和绿叶蔬菜占据更多空间但重量较轻所以一个菠菜的蒲式耳只有20磅。”这真的很复杂我们不必费心将蒲式耳转换为磅而是直接按蒲式耳定价。然而所有这些关于南瓜蒲式耳的研究都表明了解数据的本质是多么重要\n",
"\n",
"> ✅ 你注意到按半蒲式耳出售的南瓜非常贵吗?你能找出原因吗?提示:小南瓜比大南瓜贵得多,可能是因为每蒲式耳的小南瓜数量更多,而一个大的空心派南瓜占据了更多未使用的空间。\n"
],
"metadata": {
"id": "pS2GNPagbSdb"
}
},
{
"cell_type": "markdown",
"source": [
"现在最后,为了冒险的乐趣 💁我们还将“Month”列移动到第一个位置也就是在“Package”列之前。\n",
"\n",
"`dplyr::relocate()` 用于更改列的位置。\n"
],
"metadata": {
"id": "qql1SowfbdnP"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Create a new data frame new_pumpkins\n",
"new_pumpkins <- new_pumpkins %>% \n",
" relocate(Month, .before = Package)\n",
"\n",
"new_pumpkins %>% \n",
" slice_head(n = 7)"
],
"outputs": [],
"metadata": {
"id": "JJ1x6kw8bixF"
}
},
{
"cell_type": "markdown",
"source": [
"干得好!👌 现在你有一个干净整洁的数据集,可以用来构建新的回归模型! \n"
],
"metadata": {
"id": "y8TJ0Za_bn5Y"
}
},
{
"cell_type": "markdown",
"source": [
"## 4. 使用 ggplot2 进行数据可视化\n",
"\n",
"<p >\n",
" <img src=\"../../images/data-visualization.png\"\n",
" width=\"600\"/>\n",
" <figcaption>信息图表作者Dasani Madipalli</figcaption>\n",
"\n",
"\n",
"<!--![信息图表作者Dasani Madipalli](../../../../../../translated_images/zh-CN/data-visualization.54e56dded7c1a804.webp){width=\"600\"}-->\n",
"\n",
"有一句*智慧*的名言是这样说的:\n",
"\n",
"> “简单的图表比任何其他工具都能为数据分析师带来更多的信息。” --- John Tukey\n",
"\n",
"数据科学家的职责之一是展示他们所处理数据的质量和特性。为此,他们通常会创建有趣的可视化内容,比如图表、折线图和柱状图,来展示数据的不同方面。通过这种方式,他们能够直观地展示数据中的关系和差距,这些信息通常难以通过其他方式发现。\n",
"\n",
"可视化还可以帮助确定最适合数据的机器学习技术。例如,一个看起来沿着直线分布的散点图表明该数据非常适合线性回归分析。\n",
"\n",
"R 提供了多种绘图系统,而 [`ggplot2`](https://ggplot2.tidyverse.org/index.html) 是其中最优雅且最灵活的一个。`ggplot2` 允许你通过**组合独立组件**来构建图表。\n",
"\n",
"我们先从一个简单的散点图开始,展示 Price 和 Month 列的数据。\n",
"\n",
"在这个例子中,我们将从 [`ggplot()`](https://ggplot2.tidyverse.org/reference/ggplot.html) 开始,提供一个数据集和美学映射(使用 [`aes()`](https://ggplot2.tidyverse.org/reference/aes.html)),然后添加图层(例如用于散点图的 [`geom_point()`](https://ggplot2.tidyverse.org/reference/geom_point.html))。\n"
],
"metadata": {
"id": "mYSH6-EtbvNa"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Set a theme for the plots\n",
"theme_set(theme_light())\n",
"\n",
"# Create a scatter plot\n",
"p <- ggplot(data = new_pumpkins, aes(x = Price, y = Month))\n",
"p + geom_point()"
],
"outputs": [],
"metadata": {
"id": "g2YjnGeOcLo4"
}
},
{
"cell_type": "markdown",
"source": [
"这个图表有用吗🤷?有没有什么让你感到惊讶的地方?\n",
"\n",
"它并不是特别有用,因为它只是将你的数据以某个月的点状分布显示出来。\n",
"<br>\n"
],
"metadata": {
"id": "Ml7SDCLQcPvE"
}
},
{
"cell_type": "markdown",
"source": [
"### **如何让它更有用?**\n",
"\n",
"为了让图表显示有用的数据,通常需要以某种方式对数据进行分组。例如,在我们的案例中,计算每个月南瓜的平均价格可以为数据中的潜在模式提供更多洞察。这引导我们了解另一个 **dplyr** 的功能:\n",
"\n",
"#### `dplyr::group_by() %>% summarize()`\n",
"\n",
"在 R 中可以轻松计算分组聚合:\n",
"\n",
"`dplyr::group_by() %>% summarize()`\n",
"\n",
"- `dplyr::group_by()` 将分析单位从整个数据集更改为单个组,例如按月分组。\n",
"\n",
"- `dplyr::summarize()` 创建一个新的数据框,其中每个分组变量有一列,以及每个指定的汇总统计量有一列。\n",
"\n",
"例如,我们可以使用 `dplyr::group_by() %>% summarize()` 将南瓜按 **Month** 列分组,然后计算每个月的 **平均价格**。\n"
],
"metadata": {
"id": "jMakvJZIcVkh"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Find the average price of pumpkins per month\r\n",
"new_pumpkins %>%\r\n",
" group_by(Month) %>% \r\n",
" summarise(mean_price = mean(Price))"
],
"outputs": [],
"metadata": {
"id": "6kVSUa2Bcilf"
}
},
{
"cell_type": "markdown",
"source": [
"简洁明了!✨\n",
"\n",
"像月份这样的分类特征更适合用柱状图来表示 📊。负责绘制柱状图的图层是 `geom_bar()` 和 `geom_col()`。查看 `?geom_bar` 以了解更多信息。\n",
"\n",
"让我们来试试吧!\n"
],
"metadata": {
"id": "Kds48GUBcj3W"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Find the average price of pumpkins per month then plot a bar chart\r\n",
"new_pumpkins %>%\r\n",
" group_by(Month) %>% \r\n",
" summarise(mean_price = mean(Price)) %>% \r\n",
" ggplot(aes(x = Month, y = mean_price)) +\r\n",
" geom_col(fill = \"midnightblue\", alpha = 0.7) +\r\n",
" ylab(\"Pumpkin Price\")"
],
"outputs": [],
"metadata": {
"id": "VNbU1S3BcrxO"
}
},
{
"cell_type": "markdown",
"source": [
"🤩🤩这是一个更有用的数据可视化!它似乎表明南瓜的最高价格出现在九月和十月。这符合你的预期吗?为什么符合或不符合?\n",
"\n",
"恭喜你完成了第二课 👏!你已经为模型构建准备好了数据,并通过可视化发现了更多的洞察!\n"
],
"metadata": {
"id": "zDm0VOzzcuzR"
}
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**免责声明** \n本文档使用AI翻译服务 [Co-op Translator](https://github.com/Azure/co-op-translator) 进行翻译。尽管我们努力确保翻译的准确性,但请注意,自动翻译可能包含错误或不准确之处。原始语言的文档应被视为权威来源。对于关键信息,建议使用专业人工翻译。我们不对因使用此翻译而产生的任何误解或误读承担责任。\n"
]
}
]
}

File diff suppressed because one or more lines are too long

@ -0,0 +1,373 @@
# 使用 Scikit-learn 构建回归模型:四种回归方法
![线性回归与多项式回归信息图](../../../../2-Regression/3-Linear/images/linear-polynomial.png)
> 信息图由 [Dasani Madipalli](https://twitter.com/dasani_decoded) 提供
## [课前测验](https://ff-quizzes.netlify.app/en/ml/)
> ### [本课程也提供 R 版本!](../../../../2-Regression/3-Linear/solution/R/lesson_3.html)
### 介绍
到目前为止,您已经通过南瓜定价数据集的样本数据了解了什么是回归,并使用 Matplotlib 对其进行了可视化。
现在您可以深入学习机器学习中的回归。虽然可视化可以帮助您理解数据但机器学习的真正力量在于_训练模型_。模型通过历史数据进行训练自动捕捉数据之间的依赖关系并能够预测模型未见过的新数据的结果。
在本课程中您将进一步了解两种回归类型_基本线性回归_和_多项式回归_以及这些技术背后的部分数学原理。这些模型将帮助我们根据不同的输入数据预测南瓜价格。
[![机器学习入门 - 理解线性回归](https://img.youtube.com/vi/CRxFT8oTDMg/0.jpg)](https://youtu.be/CRxFT8oTDMg "机器学习入门 - 理解线性回归")
> 🎥 点击上方图片观看关于线性回归的简短视频概述。
> 在整个课程中,我们假设学生的数学知识较少,并努力使内容对来自其他领域的学生更易理解,因此请注意笔记、🧮 数学提示、图表和其他学习工具,以帮助理解。
### 前置知识
到目前为止您应该已经熟悉我们正在研究的南瓜数据的结构。您可以在本课程的_notebook.ipynb_文件中找到预加载和预清理的数据。在文件中南瓜价格以蒲式耳为单位显示在一个新的数据框中。确保您可以在 Visual Studio Code 的内核中运行这些笔记本。
### 准备工作
提醒一下,您正在加载这些数据以便提出问题:
- 什么时候是购买南瓜的最佳时机?
- 我可以预期一箱迷你南瓜的价格是多少?
- 我应该购买半蒲式耳篮子还是 1 1/9 蒲式耳箱?
让我们继续深入挖掘这些数据。
在上一课中,您创建了一个 Pandas 数据框,并用原始数据集的一部分填充它,将价格标准化为蒲式耳单位。然而,通过这样做,您只能收集到大约 400 个数据点,并且仅限于秋季月份。
查看本课程附带笔记本中预加载的数据。数据已预加载,并绘制了初始散点图以显示月份数据。也许通过进一步清理数据,我们可以更详细地了解数据的性质。
## 线性回归线
正如您在第一课中所学,线性回归的目标是绘制一条线以:
- **显示变量关系**。展示变量之间的关系
- **进行预测**。准确预测新数据点在该线上的位置
通常使用**最小二乘回归**来绘制这种类型的线。“最小二乘”意味着围绕回归线的所有数据点的误差平方后相加。理想情况下,最终的总和越小越好,因为我们希望误差较少,即`最小二乘`。
我们这样做是因为我们希望建模一条与所有数据点的累计距离最小的线。我们在相加之前对误差进行平方,因为我们关心的是误差的大小而不是方向。
> **🧮 数学展示**
>
> 这条线称为_最佳拟合线_可以通过[一个公式](https://en.wikipedia.org/wiki/Simple_linear_regression)表示:
>
> ```
> Y = a + bX
> ```
>
> `X` 是“解释变量”。`Y` 是“因变量”。线的斜率是 `b`,而 `a` 是 y 截距,表示当 `X = 0``Y` 的值。
>
>![计算斜率](../../../../2-Regression/3-Linear/images/slope.png)
>
> 首先,计算斜率 `b`。信息图由 [Jen Looper](https://twitter.com/jenlooper) 提供
>
> 换句话说,参考我们南瓜数据的原始问题:“根据月份预测每蒲式耳南瓜的价格”,`X` 表示价格,`Y` 表示销售月份。
>
>![完成公式](../../../../2-Regression/3-Linear/images/calculation.png)
>
> 计算 `Y` 的值。如果您支付大约 $4那一定是四月信息图由 [Jen Looper](https://twitter.com/jenlooper) 提供
>
> 计算线的数学公式必须展示线的斜率,这也取决于截距,即当 `X = 0``Y` 的位置。
>
> 您可以在 [Math is Fun](https://www.mathsisfun.com/data/least-squares-regression.html) 网站上观察这些值的计算方法。还可以访问[最小二乘计算器](https://www.mathsisfun.com/data/least-squares-calculator.html),观察数值如何影响线的形状。
## 相关性
另一个需要理解的术语是给定 X 和 Y 变量之间的**相关系数**。使用散点图,您可以快速可视化该系数。数据点整齐排列成一条线的图具有高相关性,而数据点在 X 和 Y 之间随意分布的图具有低相关性。
一个好的线性回归模型应该是使用最小二乘回归方法和回归线时,相关系数接近 1而不是 0
✅ 运行本课程附带的笔记本,查看月份与价格的散点图。根据您对散点图的视觉解释,南瓜销售的月份与价格之间的数据相关性是高还是低?如果您使用更细化的度量(例如*一年中的天数*,即从年初开始的天数),相关性是否会发生变化?
在下面的代码中,我们假设已经清理了数据,并获得了一个名为 `new_pumpkins` 的数据框,类似于以下内容:
ID | Month | DayOfYear | Variety | City | Package | Low Price | High Price | Price
---|-------|-----------|---------|------|---------|-----------|------------|-------
70 | 9 | 267 | PIE TYPE | BALTIMORE | 1 1/9 bushel cartons | 15.0 | 15.0 | 13.636364
71 | 9 | 267 | PIE TYPE | BALTIMORE | 1 1/9 bushel cartons | 18.0 | 18.0 | 16.363636
72 | 10 | 274 | PIE TYPE | BALTIMORE | 1 1/9 bushel cartons | 18.0 | 18.0 | 16.363636
73 | 10 | 274 | PIE TYPE | BALTIMORE | 1 1/9 bushel cartons | 17.0 | 17.0 | 15.454545
74 | 10 | 281 | PIE TYPE | BALTIMORE | 1 1/9 bushel cartons | 15.0 | 15.0 | 13.636364
> 清理数据的代码可在 [`notebook.ipynb`](../../../../2-Regression/3-Linear/notebook.ipynb) 中找到。我们执行了与上一课相同的清理步骤,并使用以下表达式计算了 `DayOfYear` 列:
```python
day_of_year = pd.to_datetime(pumpkins['Date']).apply(lambda dt: (dt-datetime(dt.year,1,1)).days)
```
现在您已经了解了线性回归背后的数学原理,让我们创建一个回归模型,看看是否可以预测哪种南瓜包装的价格最优。为节日南瓜园购买南瓜的人可能需要这些信息,以优化南瓜包装的购买。
## 寻找相关性
[![机器学习入门 - 寻找相关性:线性回归的关键](https://img.youtube.com/vi/uoRq-lW2eQo/0.jpg)](https://youtu.be/uoRq-lW2eQo "机器学习入门 - 寻找相关性:线性回归的关键")
> 🎥 点击上方图片观看关于相关性的简短视频概述。
从上一课中,您可能已经看到不同月份的平均价格如下所示:
<img alt="按月份的平均价格" src="../../../../translated_images/zh-CN/barchart.a833ea9194346d76.webp" width="50%"/>
这表明可能存在某种相关性,我们可以尝试训练线性回归模型来预测 `Month``Price``DayOfYear``Price` 之间的关系。以下是显示后者关系的散点图:
<img alt="价格与一年中的天数的散点图" src="../../../../translated_images/zh-CN/scatter-dayofyear.bc171c189c9fd553.webp" width="50%" />
让我们使用 `corr` 函数查看是否存在相关性:
```python
print(new_pumpkins['Month'].corr(new_pumpkins['Price']))
print(new_pumpkins['DayOfYear'].corr(new_pumpkins['Price']))
```
看起来相关性很小,`Month` 的相关性为 -0.15`DayOfYear` 的相关性为 -0.17,但可能存在另一个重要关系。看起来不同南瓜品种对应的价格存在不同的聚类。为了验证这一假设,让我们为每种南瓜类别绘制不同颜色的点。通过向 `scatter` 绘图函数传递 `ax` 参数,我们可以将所有点绘制在同一个图上:
```python
ax=None
colors = ['red','blue','green','yellow']
for i,var in enumerate(new_pumpkins['Variety'].unique()):
df = new_pumpkins[new_pumpkins['Variety']==var]
ax = df.plot.scatter('DayOfYear','Price',ax=ax,c=colors[i],label=var)
```
<img alt="价格与一年中的天数的散点图" src="../../../../translated_images/zh-CN/scatter-dayofyear-color.65790faefbb9d54f.webp" width="50%" />
我们的调查表明,品种对整体价格的影响比实际销售日期更大。我们可以通过柱状图看到这一点:
```python
new_pumpkins.groupby('Variety')['Price'].mean().plot(kind='bar')
```
<img alt="价格与品种的柱状图" src="../../../../translated_images/zh-CN/price-by-variety.744a2f9925d9bcb4.webp" width="50%" />
让我们暂时专注于一种南瓜品种——“馅饼型”,看看日期对价格的影响:
```python
pie_pumpkins = new_pumpkins[new_pumpkins['Variety']=='PIE TYPE']
pie_pumpkins.plot.scatter('DayOfYear','Price')
```
<img alt="价格与一年中的天数的散点图" src="../../../../translated_images/zh-CN/pie-pumpkins-scatter.d14f9804a53f927e.webp" width="50%" />
如果我们现在使用 `corr` 函数计算 `Price``DayOfYear` 之间的相关性,我们会得到类似 `-0.27` 的结果——这意味着训练预测模型是有意义的。
> 在训练线性回归模型之前,确保数据清洁非常重要。线性回归对缺失值的处理效果不好,因此清除所有空单元格是有意义的:
```python
pie_pumpkins.dropna(inplace=True)
pie_pumpkins.info()
```
另一种方法是用对应列的平均值填充这些空值。
## 简单线性回归
[![机器学习入门 - 使用 Scikit-learn 进行线性和多项式回归](https://img.youtube.com/vi/e4c_UP2fSjg/0.jpg)](https://youtu.be/e4c_UP2fSjg "机器学习入门 - 使用 Scikit-learn 进行线性和多项式回归")
> 🎥 点击上方图片观看关于线性和多项式回归的简短视频概述。
为了训练我们的线性回归模型,我们将使用 **Scikit-learn** 库。
```python
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_split
```
我们首先将输入值(特征)和预期输出(标签)分离到单独的 numpy 数组中:
```python
X = pie_pumpkins['DayOfYear'].to_numpy().reshape(-1,1)
y = pie_pumpkins['Price']
```
> 请注意,我们必须对输入数据执行 `reshape`,以便线性回归包能够正确理解它。线性回归需要一个二维数组作为输入,其中数组的每一行对应于输入特征的向量。在我们的例子中,由于我们只有一个输入——我们需要一个形状为 N×1 的数组,其中 N 是数据集的大小。
然后,我们需要将数据分为训练集和测试集,以便在训练后验证我们的模型:
```python
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
```
最后,训练实际的线性回归模型只需要两行代码。我们定义 `LinearRegression` 对象,并使用 `fit` 方法将其拟合到我们的数据:
```python
lin_reg = LinearRegression()
lin_reg.fit(X_train,y_train)
```
`LinearRegression` 对象在 `fit` 后包含所有回归系数,可以通过 `.coef_` 属性访问。在我们的例子中,只有一个系数,大约是 `-0.017`。这意味着价格似乎随着时间略有下降,但幅度不大,每天大约下降 2 美分。我们还可以通过 `lin_reg.intercept_` 访问回归线与 Y 轴的交点——在我们的例子中,大约是 `21`,表示年初的价格。
为了查看我们的模型有多准确我们可以预测测试数据集上的价格然后测量预测值与预期值的接近程度。这可以通过均方误差MSE指标完成它是所有预期值与预测值之间平方差的平均值。
```python
pred = lin_reg.predict(X_test)
mse = np.sqrt(mean_squared_error(y_test,pred))
print(f'Mean error: {mse:3.3} ({mse/np.mean(pred)*100:3.3}%)')
```
我们的错误似乎集中在两个点上,大约是 17%。表现不太理想。另一个衡量模型质量的指标是 **决定系数**,可以通过以下方式获得:
```python
score = lin_reg.score(X_train,y_train)
print('Model determination: ', score)
```
如果值为 0意味着模型没有考虑输入数据表现为*最差的线性预测器*,即结果的平均值。值为 1 表示我们可以完美预测所有期望的输出。在我们的案例中,决定系数约为 0.06,较低。
我们还可以将测试数据与回归线一起绘制,以更好地观察回归在我们案例中的表现:
```python
plt.scatter(X_test,y_test)
plt.plot(X_test,pred)
```
<img alt="线性回归" src="../../../../translated_images/zh-CN/linear-results.f7c3552c85b0ed1c.webp" width="50%" />
## 多项式回归
线性回归的另一种形式是多项式回归。有时变量之间存在线性关系——例如南瓜的体积越大,价格越高——但有时这些关系无法用平面或直线来表示。
✅ 这里有一些[更多示例](https://online.stat.psu.edu/stat501/lesson/9/9.8),展示了可以使用多项式回归的数据。
再看看日期和价格之间的关系。这个散点图看起来是否一定要用直线来分析?价格难道不会波动吗?在这种情况下,可以尝试使用多项式回归。
✅ 多项式是可能包含一个或多个变量和系数的数学表达式。
多项式回归会创建一条曲线,以更好地拟合非线性数据。在我们的案例中,如果将平方的 `DayOfYear` 变量包含在输入数据中,我们应该能够用抛物线拟合数据,该抛物线在一年中的某个点达到最低值。
Scikit-learn 提供了一个非常有用的 [pipeline API](https://scikit-learn.org/stable/modules/generated/sklearn.pipeline.make_pipeline.html?highlight=pipeline#sklearn.pipeline.make_pipeline),可以将数据处理的不同步骤组合在一起。**管道**是**估计器**的链条。在我们的案例中,我们将创建一个管道,首先向模型添加多项式特征,然后训练回归:
```python
from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import make_pipeline
pipeline = make_pipeline(PolynomialFeatures(2), LinearRegression())
pipeline.fit(X_train,y_train)
```
使用 `PolynomialFeatures(2)` 表示我们将包含输入数据中的所有二次多项式。在我们的案例中,这仅意味着 `DayOfYear`<sup>2</sup>,但如果有两个输入变量 X 和 Y这将添加 X<sup>2</sup>、XY 和 Y<sup>2</sup>。如果需要,我们也可以使用更高次的多项式。
管道可以像原始的 `LinearRegression` 对象一样使用,例如我们可以 `fit` 管道,然后使用 `predict` 获取预测结果。以下是显示测试数据和拟合曲线的图表:
<img alt="多项式回归" src="../../../../translated_images/zh-CN/poly-results.ee587348f0f1f60b.webp" width="50%" />
使用多项式回归,我们可以获得稍低的 MSE 和稍高的决定系数,但提升并不显著。我们需要考虑其他特征!
> 可以看到南瓜价格最低点大约出现在万圣节附近。你如何解释这一现象?
🎃 恭喜你!你刚刚创建了一个可以帮助预测南瓜派价格的模型。你可能可以对所有南瓜类型重复相同的过程,但这会很繁琐。现在让我们学习如何在模型中考虑南瓜品种!
## 分类特征
在理想情况下,我们希望能够使用同一个模型预测不同南瓜品种的价格。然而,`Variety` 列与 `Month` 等列有所不同,因为它包含非数值值。这类列被称为**分类特征**。
[![机器学习入门 - 使用线性回归预测分类特征](https://img.youtube.com/vi/DYGliioIAE0/0.jpg)](https://youtu.be/DYGliioIAE0 "机器学习入门 - 使用线性回归预测分类特征")
> 🎥 点击上方图片观看关于使用分类特征的简短视频概述。
以下是品种与平均价格的关系:
<img alt="按品种划分的平均价格" src="../../../../translated_images/zh-CN/price-by-variety.744a2f9925d9bcb4.webp" width="50%" />
为了考虑品种,我们首先需要将其转换为数值形式,或者说**编码**。有几种方法可以实现:
* 简单的**数值编码**会构建一个不同品种的表格,然后用表格中的索引替换品种名称。这对线性回归来说不是最好的选择,因为线性回归会将索引的实际数值考虑在内,并通过某个系数与结果相乘。在我们的案例中,索引号与价格之间的关系显然是非线性的,即使我们确保索引按某种特定方式排序。
* **独热编码**会将 `Variety` 列替换为 4 个不同的列,每个品种对应一个列。如果某行属于某个品种,该列值为 `1`,否则为 `0`。这意味着线性回归中会有四个系数,每个南瓜品种对应一个,负责该品种的“起始价格”(或“附加价格”)。
以下代码展示了如何对品种进行独热编码:
```python
pd.get_dummies(new_pumpkins['Variety'])
```
ID | FAIRYTALE | MINIATURE | MIXED HEIRLOOM VARIETIES | PIE TYPE
----|-----------|-----------|--------------------------|----------
70 | 0 | 0 | 0 | 1
71 | 0 | 0 | 0 | 1
... | ... | ... | ... | ...
1738 | 0 | 1 | 0 | 0
1739 | 0 | 1 | 0 | 0
1740 | 0 | 1 | 0 | 0
1741 | 0 | 1 | 0 | 0
1742 | 0 | 1 | 0 | 0
为了使用独热编码的品种作为输入训练线性回归,我们只需正确初始化 `X``y` 数据:
```python
X = pd.get_dummies(new_pumpkins['Variety'])
y = new_pumpkins['Price']
```
其余代码与我们之前用于训练线性回归的代码相同。如果尝试,你会发现均方误差差不多,但决定系数显著提高(约 77%)。为了获得更准确的预测,我们可以考虑更多分类特征以及数值特征,例如 `Month``DayOfYear`。为了获得一个大的特征数组,我们可以使用 `join`
```python
X = pd.get_dummies(new_pumpkins['Variety']) \
.join(new_pumpkins['Month']) \
.join(pd.get_dummies(new_pumpkins['City'])) \
.join(pd.get_dummies(new_pumpkins['Package']))
y = new_pumpkins['Price']
```
这里我们还考虑了 `City``Package` 类型,这使得 MSE 降至 2.8410%),决定系数提高到 0.94
## 综合起来
为了构建最佳模型,我们可以将上述示例中的组合数据(独热编码分类特征 + 数值特征)与多项式回归一起使用。以下是完整代码供参考:
```python
# set up training data
X = pd.get_dummies(new_pumpkins['Variety']) \
.join(new_pumpkins['Month']) \
.join(pd.get_dummies(new_pumpkins['City'])) \
.join(pd.get_dummies(new_pumpkins['Package']))
y = new_pumpkins['Price']
# make train-test split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
# setup and train the pipeline
pipeline = make_pipeline(PolynomialFeatures(2), LinearRegression())
pipeline.fit(X_train,y_train)
# predict results for test data
pred = pipeline.predict(X_test)
# calculate MSE and determination
mse = np.sqrt(mean_squared_error(y_test,pred))
print(f'Mean error: {mse:3.3} ({mse/np.mean(pred)*100:3.3}%)')
score = pipeline.score(X_train,y_train)
print('Model determination: ', score)
```
这应该能让我们获得接近 97% 的决定系数,以及 MSE=2.23(约 8% 的预测误差)。
| 模型 | MSE | 决定系数 |
|-------|-----|---------------|
| `DayOfYear` 线性 | 2.77 (17.2%) | 0.07 |
| `DayOfYear` 多项式 | 2.73 (17.0%) | 0.08 |
| `Variety` 线性 | 5.24 (19.7%) | 0.77 |
| 所有特征线性 | 2.84 (10.5%) | 0.94 |
| 所有特征多项式 | 2.23 (8.25%) | 0.97 |
🏆 做得好!你在一节课中创建了四个回归模型,并将模型质量提升至 97%。在回归的最后一部分中,你将学习如何使用逻辑回归来确定类别。
---
## 🚀挑战
在此笔记本中测试几个不同的变量,观察相关性如何影响模型准确性。
## [课后测验](https://ff-quizzes.netlify.app/en/ml/)
## 复习与自学
在本课中我们学习了线性回归。还有其他重要的回归类型。阅读关于逐步回归、岭回归、套索回归和弹性网络技术的内容。一个不错的学习课程是 [斯坦福统计学习课程](https://online.stanford.edu/courses/sohs-ystatslearning-statistical-learning)。
## 作业
[构建一个模型](assignment.md)
---
**免责声明**
本文档使用AI翻译服务[Co-op Translator](https://github.com/Azure/co-op-translator)进行翻译。尽管我们努力确保准确性,但请注意,自动翻译可能包含错误或不准确之处。应以原始语言的文档作为权威来源。对于关键信息,建议使用专业人工翻译。因使用本翻译而引起的任何误解或误读,我们概不负责。

@ -0,0 +1,16 @@
# 创建回归模型
## 说明
在本课中,你学习了如何使用线性回归和多项式回归来构建模型。利用这些知识,找到一个数据集或使用 Scikit-learn 内置的数据集来构建一个新的模型。在你的笔记本中解释你选择该技术的原因,并展示你的模型的准确性。如果模型不够准确,请解释原因。
## 评分标准
| 标准 | 卓越表现 | 合格表现 | 需要改进 |
| -------- | ------------------------------------------------------------ | -------------------------- | ------------------------------- |
| | 提供一个完整的笔记本,并包含详细记录的解决方案 | 解决方案不完整 | 解决方案存在缺陷或错误 |
---
**免责声明**
本文档使用AI翻译服务 [Co-op Translator](https://github.com/Azure/co-op-translator) 进行翻译。尽管我们努力确保翻译的准确性,但请注意,自动翻译可能包含错误或不准确之处。原始语言的文档应被视为权威来源。对于关键信息,建议使用专业人工翻译。我们不对因使用此翻译而产生的任何误解或误读承担责任。

@ -0,0 +1,128 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 南瓜定价\n",
"\n",
"加载所需的库和数据集。将数据转换为一个包含数据子集的数据框:\n",
"\n",
"- 仅获取按蒲式耳定价的南瓜\n",
"- 将日期转换为月份\n",
"- 计算价格为高价和低价的平均值\n",
"- 将价格转换为反映按蒲式耳数量定价\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"from datetime import datetime\n",
"\n",
"pumpkins = pd.read_csv('../data/US-pumpkins.csv')\n",
"\n",
"pumpkins.head()\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"pumpkins = pumpkins[pumpkins['Package'].str.contains('bushel', case=True, regex=True)]\n",
"\n",
"columns_to_select = ['Package', 'Variety', 'City Name', 'Low Price', 'High Price', 'Date']\n",
"pumpkins = pumpkins.loc[:, columns_to_select]\n",
"\n",
"price = (pumpkins['Low Price'] + pumpkins['High Price']) / 2\n",
"\n",
"month = pd.DatetimeIndex(pumpkins['Date']).month\n",
"day_of_year = pd.to_datetime(pumpkins['Date']).apply(lambda dt: (dt-datetime(dt.year,1,1)).days)\n",
"\n",
"new_pumpkins = pd.DataFrame(\n",
" {'Month': month, \n",
" 'DayOfYear' : day_of_year, \n",
" 'Variety': pumpkins['Variety'], \n",
" 'City': pumpkins['City Name'], \n",
" 'Package': pumpkins['Package'], \n",
" 'Low Price': pumpkins['Low Price'],\n",
" 'High Price': pumpkins['High Price'], \n",
" 'Price': price})\n",
"\n",
"new_pumpkins.loc[new_pumpkins['Package'].str.contains('1 1/9'), 'Price'] = price/1.1\n",
"new_pumpkins.loc[new_pumpkins['Package'].str.contains('1/2'), 'Price'] = price*2\n",
"\n",
"new_pumpkins.head()\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"一个基本的散点图提醒我们,我们只有从八月到十二月的月度数据。我们可能需要更多数据才能以线性方式得出结论。\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import matplotlib.pyplot as plt\n",
"plt.scatter('Month','Price',data=new_pumpkins)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"\n",
"plt.scatter('DayOfYear','Price',data=new_pumpkins)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**免责声明** \n本文档使用AI翻译服务[Co-op Translator](https://github.com/Azure/co-op-translator)进行翻译。尽管我们努力确保准确性,但请注意,自动翻译可能包含错误或不准确之处。应以原始语言的文档作为权威来源。对于关键信息,建议使用专业人工翻译。因使用本翻译而导致的任何误解或误读,我们概不负责。\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.3-final"
},
"orig_nbformat": 2,
"coopTranslator": {
"original_hash": "b032d371c75279373507f003439a577e",
"translation_date": "2025-09-03T19:16:27+00:00",
"source_file": "2-Regression/3-Linear/notebook.ipynb",
"language_code": "zh"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

@ -0,0 +1,6 @@
---
**免责声明**
本文档使用AI翻译服务 [Co-op Translator](https://github.com/Azure/co-op-translator) 进行翻译。尽管我们努力确保翻译的准确性,但请注意,自动翻译可能包含错误或不准确之处。原始语言的文档应被视为权威来源。对于重要信息,建议使用专业人工翻译。我们不对因使用此翻译而产生的任何误解或误读承担责任。

File diff suppressed because one or more lines are too long

@ -0,0 +1,414 @@
# 使用逻辑回归预测类别
![逻辑回归与线性回归信息图](../../../../2-Regression/4-Logistic/images/linear-vs-logistic.png)
## [课前测验](https://ff-quizzes.netlify.app/en/ml/)
> ### [本课程也提供 R 版本!](../../../../2-Regression/4-Logistic/solution/R/lesson_4.html)
## 简介
在本课程中,我们将学习逻辑回归,这是经典机器学习技术之一。你可以使用这种技术发现模式以预测二元类别。例如,这颗糖果是巧克力还是不是巧克力?这种疾病是否具有传染性?这个顾客会选择这个产品还是不会?
在本课程中,你将学习:
- 一个新的数据可视化库
- 逻辑回归的技术
✅ 在这个 [学习模块](https://docs.microsoft.com/learn/modules/train-evaluate-classification-models?WT.mc_id=academic-77952-leestott) 中深入了解如何使用这种回归方法。
## 前置知识
通过之前的南瓜数据集练习,我们已经足够熟悉它,并意识到其中有一个可以处理的二元类别:`Color`。
让我们构建一个逻辑回归模型来预测给定一些变量时_某个南瓜可能的颜色_橙色 🎃 或白色 👻)。
> 为什么在回归课程中讨论二元分类?仅仅是为了语言上的方便,因为逻辑回归实际上是[一种分类方法](https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression),尽管它是基于线性的。在下一组课程中,你将学习其他分类数据的方法。
## 定义问题
对于我们的目的,我们将问题表达为一个二元类别:“白色”或“非白色”。数据集中还有一个“条纹”类别,但实例较少,因此我们不会使用它。实际上,在移除数据集中的空值后,它也会消失。
> 🎃 有趣的事实:我们有时称白色南瓜为“幽灵”南瓜。它们不太容易雕刻,因此不像橙色南瓜那么受欢迎,但它们看起来很酷!所以我们也可以将问题重新表述为:“幽灵”或“非幽灵”。👻
## 关于逻辑回归
逻辑回归与之前学习的线性回归有几个重要的不同点。
[![机器学习初学者 - 理解逻辑回归用于分类](https://img.youtube.com/vi/KpeCT6nEpBY/0.jpg)](https://youtu.be/KpeCT6nEpBY "机器学习初学者 - 理解逻辑回归用于分类")
> 🎥 点击上方图片观看关于逻辑回归的简短视频概述。
### 二元分类
逻辑回归与线性回归的功能不同。前者预测二元类别例如“白色或非白色”而后者能够预测连续值例如根据南瓜的产地和收获时间_价格将上涨多少_。
![南瓜分类模型](../../../../2-Regression/4-Logistic/images/pumpkin-classifier.png)
> 信息图由 [Dasani Madipalli](https://twitter.com/dasani_decoded) 提供
### 其他分类
逻辑回归还有其他类型,包括多项式和有序分类:
- **多项式分类**:涉及多个类别,例如“橙色、白色和条纹”。
- **有序分类**:涉及有序类别,适用于逻辑排序的结果,例如按有限大小排序的南瓜(迷你、小、中、大、特大、超大)。
![多项式分类与有序分类](../../../../2-Regression/4-Logistic/images/multinomial-vs-ordinal.png)
### 变量不需要相关
还记得线性回归在变量相关性较高时效果更好吗?逻辑回归正好相反——变量不需要相关性。这适用于数据中相关性较弱的情况。
### 需要大量干净数据
逻辑回归在使用更多数据时会给出更准确的结果;我们的数据集较小,因此并不理想。
[![机器学习初学者 - 数据分析与准备用于逻辑回归](https://img.youtube.com/vi/B2X4H9vcXTs/0.jpg)](https://youtu.be/B2X4H9vcXTs "机器学习初学者 - 数据分析与准备用于逻辑回归")
> 🎥 点击上方图片观看关于准备线性回归数据的简短视频概述。
✅ 思考哪些类型的数据适合逻辑回归。
## 练习 - 整理数据
首先,清理数据,删除空值并选择部分列:
1. 添加以下代码:
```python
columns_to_select = ['City Name','Package','Variety', 'Origin','Item Size', 'Color']
pumpkins = full_pumpkins.loc[:, columns_to_select]
pumpkins.dropna(inplace=True)
```
你可以随时查看新的数据框:
```python
pumpkins.info
```
### 可视化 - 分类图
现在你已经加载了[起始笔记本](../../../../2-Regression/4-Logistic/notebook.ipynb),其中包含南瓜数据,并清理了数据以保留一些变量,包括 `Color`。让我们使用一个不同的库 [Seaborn](https://seaborn.pydata.org/index.html) 在笔记本中可视化数据框。Seaborn 是基于我们之前使用的 Matplotlib 构建的。
Seaborn 提供了一些很棒的方式来可视化数据。例如,你可以在分类图中比较 `Variety``Color` 数据的分布。
1. 使用 `catplot` 函数创建这样的图,使用南瓜数据 `pumpkins`,并为每个南瓜类别(橙色或白色)指定颜色映射:
```python
import seaborn as sns
palette = {
'ORANGE': 'orange',
'WHITE': 'wheat',
}
sns.catplot(
data=pumpkins, y="Variety", hue="Color", kind="count",
palette=palette,
)
```
![数据可视化网格](../../../../2-Regression/4-Logistic/images/pumpkins_catplot_1.png)
通过观察数据,你可以看到 `Color` 数据与 `Variety` 的关系。
✅ 根据这个分类图,你能想到哪些有趣的探索?
### 数据预处理:特征和标签编码
我们的南瓜数据集的所有列都包含字符串值。处理分类数据对人类来说很直观,但对机器来说却不然。机器学习算法更适合处理数字数据。这就是为什么编码是数据预处理阶段非常重要的一步,它使我们能够将分类数据转换为数值数据,而不会丢失任何信息。良好的编码有助于构建良好的模型。
对于特征编码,主要有两种编码器:
1. **有序编码器**:适用于有序变量,即数据具有逻辑顺序的分类变量,例如数据集中的 `Item Size` 列。它创建一个映射,使每个类别由一个数字表示,该数字是列中类别的顺序。
```python
from sklearn.preprocessing import OrdinalEncoder
item_size_categories = [['sml', 'med', 'med-lge', 'lge', 'xlge', 'jbo', 'exjbo']]
ordinal_features = ['Item Size']
ordinal_encoder = OrdinalEncoder(categories=item_size_categories)
```
2. **分类编码器**:适用于无序变量,即数据没有逻辑顺序的分类变量,例如数据集中除 `Item Size` 之外的所有特征。它是一种独热编码,这意味着每个类别由一个二进制列表示:如果南瓜属于该类别,则编码变量为 1否则为 0。
```python
from sklearn.preprocessing import OneHotEncoder
categorical_features = ['City Name', 'Package', 'Variety', 'Origin']
categorical_encoder = OneHotEncoder(sparse_output=False)
```
然后,使用 `ColumnTransformer` 将多个编码器合并为一个步骤,并将其应用于适当的列。
```python
from sklearn.compose import ColumnTransformer
ct = ColumnTransformer(transformers=[
('ord', ordinal_encoder, ordinal_features),
('cat', categorical_encoder, categorical_features)
])
ct.set_output(transform='pandas')
encoded_features = ct.fit_transform(pumpkins)
```
另一方面,为了编码标签,我们使用 scikit-learn 的 `LabelEncoder` 类,这是一个实用类,用于将标签标准化,使其仅包含 0 到 n_classes-1这里是 0 和 1之间的值。
```python
from sklearn.preprocessing import LabelEncoder
label_encoder = LabelEncoder()
encoded_label = label_encoder.fit_transform(pumpkins['Color'])
```
完成特征和标签编码后,我们可以将它们合并为一个新的数据框 `encoded_pumpkins`
```python
encoded_pumpkins = encoded_features.assign(Color=encoded_label)
```
✅ 使用有序编码器处理 `Item Size` 列有哪些优势?
### 分析变量之间的关系
现在我们已经对数据进行了预处理,可以分析特征和标签之间的关系,以了解模型在给定特征的情况下预测标签的能力。
分析这种关系的最佳方式是绘制数据。我们将再次使用 Seaborn 的 `catplot` 函数,以分类图的形式可视化 `Item Size`、`Variety` 和 `Color` 之间的关系。为了更好地绘制数据,我们将使用编码后的 `Item Size` 列和未编码的 `Variety` 列。
```python
palette = {
'ORANGE': 'orange',
'WHITE': 'wheat',
}
pumpkins['Item Size'] = encoded_pumpkins['ord__Item Size']
g = sns.catplot(
data=pumpkins,
x="Item Size", y="Color", row='Variety',
kind="box", orient="h",
sharex=False, margin_titles=True,
height=1.8, aspect=4, palette=palette,
)
g.set(xlabel="Item Size", ylabel="").set(xlim=(0,6))
g.set_titles(row_template="{row_name}")
```
![数据分类图](../../../../2-Regression/4-Logistic/images/pumpkins_catplot_2.png)
### 使用蜂群图
由于 `Color` 是一个二元类别(白色或非白色),它需要“[一种专门的方法](https://seaborn.pydata.org/tutorial/categorical.html?highlight=bar)来可视化”。还有其他方法可以可视化此类别与其他变量的关系。
你可以使用 Seaborn 图表并排可视化变量。
1. 尝试使用“蜂群图”来显示值的分布:
```python
palette = {
0: 'orange',
1: 'wheat'
}
sns.swarmplot(x="Color", y="ord__Item Size", data=encoded_pumpkins, palette=palette)
```
![数据蜂群图](../../../../2-Regression/4-Logistic/images/swarm_2.png)
**注意**:上述代码可能会生成警告,因为 Seaborn 无法在蜂群图中表示如此多的数据点。一个可能的解决方案是通过使用 `size` 参数减小标记的大小。然而,请注意,这会影响图表的可读性。
> **🧮 数学原理**
>
> 逻辑回归依赖于“最大似然”概念,使用[Sigmoid 函数](https://wikipedia.org/wiki/Sigmoid_function)。在图表上Sigmoid 函数看起来像一个“S”形。它将一个值映射到 0 和 1 之间的某个位置。它的曲线也被称为“逻辑曲线”。其公式如下:
>
> ![逻辑函数](../../../../2-Regression/4-Logistic/images/sigmoid.png)
>
> 其中Sigmoid 的中点位于 x 的 0 点L 是曲线的最大值k 是曲线的陡度。如果函数的结果大于 0.5则该标签将被归类为二元选择中的“1”。否则将被归类为“0”。
## 构建模型
在 Scikit-learn 中构建一个用于二元分类的模型非常简单。
[![机器学习初学者 - 用逻辑回归进行数据分类](https://img.youtube.com/vi/MmZS2otPrQ8/0.jpg)](https://youtu.be/MmZS2otPrQ8 "机器学习初学者 - 用逻辑回归进行数据分类")
> 🎥 点击上方图片观看关于构建线性回归模型的简短视频概述。
1. 选择你想在分类模型中使用的变量,并调用 `train_test_split()` 分割训练集和测试集:
```python
from sklearn.model_selection import train_test_split
X = encoded_pumpkins[encoded_pumpkins.columns.difference(['Color'])]
y = encoded_pumpkins['Color']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
```
2. 现在你可以通过调用 `fit()` 使用训练数据训练模型,并打印结果:
```python
from sklearn.metrics import f1_score, classification_report
from sklearn.linear_model import LogisticRegression
model = LogisticRegression()
model.fit(X_train, y_train)
predictions = model.predict(X_test)
print(classification_report(y_test, predictions))
print('Predicted labels: ', predictions)
print('F1-score: ', f1_score(y_test, predictions))
```
查看模型的评分。考虑到数据只有大约 1000 行,结果还不错:
```output
precision recall f1-score support
0 0.94 0.98 0.96 166
1 0.85 0.67 0.75 33
accuracy 0.92 199
macro avg 0.89 0.82 0.85 199
weighted avg 0.92 0.92 0.92 199
Predicted labels: [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 1 0 1 0 0 1 0 0 0 0 0 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0
0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
0 0 0 1 0 0 0 0 0 0 0 0 1 1]
F1-score: 0.7457627118644068
```
## 使用混淆矩阵更好地理解模型
虽然你可以通过打印上述项获得评分报告[术语](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.classification_report.html?highlight=classification_report#sklearn.metrics.classification_report),但使用[混淆矩阵](https://scikit-learn.org/stable/modules/model_evaluation.html#confusion-matrix)可能更容易理解模型的表现。
> 🎓 “[混淆矩阵](https://wikipedia.org/wiki/Confusion_matrix)”(或“误差矩阵”)是一个表格,用于表达模型的真实与预测的正负情况,从而评估预测的准确性。
1. 要使用混淆矩阵,调用 `confusion_matrix()`
```python
from sklearn.metrics import confusion_matrix
confusion_matrix(y_test, predictions)
```
查看模型的混淆矩阵:
```output
array([[162, 4],
[ 11, 22]])
```
在 Scikit-learn 中,混淆矩阵的行(轴 0是实际标签轴 1是预测标签。
| | 0 | 1 |
| :---: | :---: | :---: |
| 0 | TN | FP |
| 1 | FN | TP |
这里发生了什么?假设我们的模型被要求在两个二元类别之间对南瓜进行分类,“白色”和“非白色”。
- 如果模型预测南瓜为非白色而实际上属于“非白色”类别我们称之为真负True Negative显示在左上角。
- 如果模型预测南瓜为白色而实际上属于“非白色”类别我们称之为假负False Negative显示在左下角。
- 如果模型预测南瓜为非白色而实际上属于“白色”类别我们称之为假正False Positive显示在右上角。
- 如果模型预测南瓜为白色而实际上属于“白色”类别我们称之为真正True Positive显示在右下角。
正如你可能猜到的,较多的真正和真负以及较少的假正和假负表明模型表现更好。
混淆矩阵如何与精确率和召回率相关联?请记住,上面打印的分类报告显示精确率为 0.85,召回率为 0.67。
精确率 = tp / (tp + fp) = 22 / (22 + 4) = 0.8461538461538461
召回率 = tp / (tp + fn) = 22 / (22 + 11) = 0.6666666666666666
✅ 问:根据混淆矩阵,模型表现如何?
答:还不错;有相当多的真正例,但也有一些假负例。
让我们通过混淆矩阵中 TP/TN 和 FP/FN 的映射,重新回顾之前提到的术语:
🎓 精确率PrecisionTP/(TP + FP)
检索到的实例中,相关实例的比例(例如,哪些标签被正确标记)。
🎓 召回率RecallTP/(TP + FN)
相关实例中被检索到的比例,无论是否被正确标记。
🎓 F1 分数f1-score(2 * precision * recall)/(precision + recall)
精确率和召回率的加权平均值,最佳值为 1最差值为 0。
🎓 支持度Support
每个标签被检索到的次数。
🎓 准确率Accuracy(TP + TN)/(TP + TN + FP + FN)
样本中标签被正确预测的百分比。
🎓 宏平均Macro Avg
对每个标签的指标进行无权重平均的计算,不考虑标签的不平衡。
🎓 加权平均Weighted Avg
对每个标签的指标进行加权平均的计算,权重由支持度(每个标签的真实实例数)决定。
✅ 你能想到如果想减少假负例的数量,应该关注哪个指标吗?
## 可视化该模型的 ROC 曲线
[![机器学习入门 - 使用 ROC 曲线分析逻辑回归性能](https://img.youtube.com/vi/GApO575jTA0/0.jpg)](https://youtu.be/GApO575jTA0 "机器学习入门 - 使用 ROC 曲线分析逻辑回归性能")
> 🎥 点击上方图片观看关于 ROC 曲线的简短视频概述
让我们再做一个可视化看看所谓的“ROC”曲线
```python
from sklearn.metrics import roc_curve, roc_auc_score
import matplotlib
import matplotlib.pyplot as plt
%matplotlib inline
y_scores = model.predict_proba(X_test)
fpr, tpr, thresholds = roc_curve(y_test, y_scores[:,1])
fig = plt.figure(figsize=(6, 6))
plt.plot([0, 1], [0, 1], 'k--')
plt.plot(fpr, tpr)
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('ROC Curve')
plt.show()
```
使用 Matplotlib 绘制模型的 [接收者操作特性曲线ROC](https://scikit-learn.org/stable/auto_examples/model_selection/plot_roc.html?highlight=roc)。ROC 曲线通常用于查看分类器输出的真阳性与假阳性之间的关系。“ROC 曲线通常以真阳性率为 Y 轴,假阳性率为 X 轴。”因此,曲线的陡峭程度以及曲线与中线之间的空间很重要:你希望曲线迅速向上并越过中线。在我们的例子中,起初有一些假阳性,然后曲线正确地向上并越过中线:
![ROC](../../../../2-Regression/4-Logistic/images/ROC_2.png)
最后,使用 Scikit-learn 的 [`roc_auc_score` API](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.roc_auc_score.html?highlight=roc_auc#sklearn.metrics.roc_auc_score) 计算实际的“曲线下面积”AUC
```python
auc = roc_auc_score(y_test,y_scores[:,1])
print(auc)
```
结果是 `0.9749908725812341`。由于 AUC 的范围是 0 到 1你希望分数越大越好因为一个 100% 正确预测的模型的 AUC 为 1在这种情况下该模型表现“相当不错”。
在未来的分类课程中,你将学习如何迭代以提高模型的分数。但现在,恭喜你!你已经完成了这些回归课程!
---
## 🚀挑战
关于逻辑回归还有很多内容可以深入探讨!但最好的学习方式是动手实践。找到一个适合这种分析的数据集,并用它构建一个模型。你学到了什么?提示:试试 [Kaggle](https://www.kaggle.com/search?q=logistic+regression+datasets) 上的一些有趣数据集。
## [课后测验](https://ff-quizzes.netlify.app/en/ml/)
## 复习与自学
阅读 [斯坦福大学的这篇论文](https://web.stanford.edu/~jurafsky/slp3/5.pdf) 的前几页,了解逻辑回归的一些实际应用。思考哪些任务更适合我们到目前为止学习的回归类型。哪种方法效果更好?
## 作业
[重试这个回归任务](assignment.md)
---
**免责声明**
本文档使用AI翻译服务[Co-op Translator](https://github.com/Azure/co-op-translator)进行翻译。尽管我们努力确保准确性,但请注意,自动翻译可能包含错误或不准确之处。应以原始语言的文档作为权威来源。对于关键信息,建议使用专业人工翻译。对于因使用本翻译而引起的任何误解或误读,我们概不负责。

@ -0,0 +1,16 @@
# 重试一些回归
## 说明
在课程中,你使用了南瓜数据的一个子集。现在,请回到原始数据,尝试使用全部数据(经过清理和标准化)来构建一个逻辑回归模型。
## 评分标准
| 标准 | 卓越表现 | 合格表现 | 需要改进 |
| -------- | --------------------------------------------------------------------- | ------------------------------------------------------------ | ---------------------------------------------------------- |
| | 提交的笔记本包含一个解释清晰且表现良好的模型 | 提交的笔记本包含一个表现最低限度的模型 | 提交的笔记本包含一个表现不佳的模型或未提交模型 |
---
**免责声明**
本文档使用AI翻译服务 [Co-op Translator](https://github.com/Azure/co-op-translator) 进行翻译。尽管我们努力确保翻译的准确性,但请注意,自动翻译可能包含错误或不准确之处。应以原始语言的文档作为权威来源。对于重要信息,建议使用专业人工翻译。我们对因使用此翻译而产生的任何误解或误读不承担责任。

@ -0,0 +1,269 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 南瓜品种与颜色\n",
"\n",
"加载所需的库和数据集。将数据转换为包含数据子集的数据框:\n",
"\n",
"让我们来看看颜色与品种之间的关系\n"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>City Name</th>\n",
" <th>Type</th>\n",
" <th>Package</th>\n",
" <th>Variety</th>\n",
" <th>Sub Variety</th>\n",
" <th>Grade</th>\n",
" <th>Date</th>\n",
" <th>Low Price</th>\n",
" <th>High Price</th>\n",
" <th>Mostly Low</th>\n",
" <th>...</th>\n",
" <th>Unit of Sale</th>\n",
" <th>Quality</th>\n",
" <th>Condition</th>\n",
" <th>Appearance</th>\n",
" <th>Storage</th>\n",
" <th>Crop</th>\n",
" <th>Repack</th>\n",
" <th>Trans Mode</th>\n",
" <th>Unnamed: 24</th>\n",
" <th>Unnamed: 25</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>BALTIMORE</td>\n",
" <td>NaN</td>\n",
" <td>24 inch bins</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>4/29/17</td>\n",
" <td>270.0</td>\n",
" <td>280.0</td>\n",
" <td>270.0</td>\n",
" <td>...</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>E</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>BALTIMORE</td>\n",
" <td>NaN</td>\n",
" <td>24 inch bins</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>5/6/17</td>\n",
" <td>270.0</td>\n",
" <td>280.0</td>\n",
" <td>270.0</td>\n",
" <td>...</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>E</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>BALTIMORE</td>\n",
" <td>NaN</td>\n",
" <td>24 inch bins</td>\n",
" <td>HOWDEN TYPE</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>9/24/16</td>\n",
" <td>160.0</td>\n",
" <td>160.0</td>\n",
" <td>160.0</td>\n",
" <td>...</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>N</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>BALTIMORE</td>\n",
" <td>NaN</td>\n",
" <td>24 inch bins</td>\n",
" <td>HOWDEN TYPE</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>9/24/16</td>\n",
" <td>160.0</td>\n",
" <td>160.0</td>\n",
" <td>160.0</td>\n",
" <td>...</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>N</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>BALTIMORE</td>\n",
" <td>NaN</td>\n",
" <td>24 inch bins</td>\n",
" <td>HOWDEN TYPE</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>11/5/16</td>\n",
" <td>90.0</td>\n",
" <td>100.0</td>\n",
" <td>90.0</td>\n",
" <td>...</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>N</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>5 rows × 26 columns</p>\n",
"</div>"
],
"text/plain": [
" City Name Type Package Variety Sub Variety Grade Date \\\n",
"0 BALTIMORE NaN 24 inch bins NaN NaN NaN 4/29/17 \n",
"1 BALTIMORE NaN 24 inch bins NaN NaN NaN 5/6/17 \n",
"2 BALTIMORE NaN 24 inch bins HOWDEN TYPE NaN NaN 9/24/16 \n",
"3 BALTIMORE NaN 24 inch bins HOWDEN TYPE NaN NaN 9/24/16 \n",
"4 BALTIMORE NaN 24 inch bins HOWDEN TYPE NaN NaN 11/5/16 \n",
"\n",
" Low Price High Price Mostly Low ... Unit of Sale Quality Condition \\\n",
"0 270.0 280.0 270.0 ... NaN NaN NaN \n",
"1 270.0 280.0 270.0 ... NaN NaN NaN \n",
"2 160.0 160.0 160.0 ... NaN NaN NaN \n",
"3 160.0 160.0 160.0 ... NaN NaN NaN \n",
"4 90.0 100.0 90.0 ... NaN NaN NaN \n",
"\n",
" Appearance Storage Crop Repack Trans Mode Unnamed: 24 Unnamed: 25 \n",
"0 NaN NaN NaN E NaN NaN NaN \n",
"1 NaN NaN NaN E NaN NaN NaN \n",
"2 NaN NaN NaN N NaN NaN NaN \n",
"3 NaN NaN NaN N NaN NaN NaN \n",
"4 NaN NaN NaN N NaN NaN NaN \n",
"\n",
"[5 rows x 26 columns]"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import pandas as pd\n",
"import numpy as np\n",
"\n",
"full_pumpkins = pd.read_csv('../data/US-pumpkins.csv')\n",
"\n",
"full_pumpkins.head()\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**免责声明** \n本文档使用AI翻译服务[Co-op Translator](https://github.com/Azure/co-op-translator)进行翻译。尽管我们努力确保翻译的准确性,但请注意,自动翻译可能包含错误或不准确之处。原始语言的文档应被视为权威来源。对于关键信息,建议使用专业人工翻译。我们对因使用此翻译而产生的任何误解或误读不承担责任。\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.1"
},
"metadata": {
"interpreter": {
"hash": "70b38d7a306a849643e446cd70466270a13445e5987dfa1344ef2b127438fa4d"
}
},
"orig_nbformat": 2,
"coopTranslator": {
"original_hash": "dee08c2b49057b0de8b6752c4dbca368",
"translation_date": "2025-09-03T19:30:06+00:00",
"source_file": "2-Regression/4-Logistic/notebook.ipynb",
"language_code": "zh"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

@ -0,0 +1,6 @@
---
**免责声明**
本文档使用AI翻译服务[Co-op Translator](https://github.com/Azure/co-op-translator)进行翻译。尽管我们努力确保翻译的准确性,但请注意,自动翻译可能包含错误或不准确之处。原始语言的文档应被视为权威来源。对于关键信息,建议使用专业人工翻译。我们不对因使用此翻译而产生的任何误解或误读承担责任。

@ -0,0 +1,685 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 构建逻辑回归模型 - 第4课\n",
"\n",
"![逻辑回归与线性回归信息图](../../../../../../translated_images/zh-CN/linear-vs-logistic.ba180bf95e7ee667.webp)\n",
"\n",
"#### **[课前测验](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/15/)**\n",
"\n",
"#### 介绍\n",
"\n",
"在关于回归的最后一课中,我们将学习一种经典的机器学习技术——逻辑回归。你可以使用这种技术发现模式来预测二元分类。例如,这颗糖果是巧克力还是不是?这种疾病是否具有传染性?这个顾客是否会选择这个产品?\n",
"\n",
"在本课中,你将学习:\n",
"\n",
"- 逻辑回归的技术\n",
"\n",
"✅ 在这个 [学习模块](https://learn.microsoft.com/training/modules/introduction-classification-models/?WT.mc_id=academic-77952-leestott) 中深入了解如何使用这种回归方法。\n",
"\n",
"## 前置知识\n",
"\n",
"在之前使用南瓜数据的过程中,我们已经足够熟悉它,并意识到其中有一个可以使用的二元分类:`Color`。\n",
"\n",
"让我们构建一个逻辑回归模型,根据一些变量来预测*某个南瓜可能的颜色*(橙色 🎃 或白色 👻)。\n",
"\n",
"> 为什么我们在关于回归的课程中讨论二元分类?仅仅是为了语言上的方便,因为逻辑回归实际上是[一种分类方法](https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression),尽管它是基于线性的方法。在下一组课程中,你将学习其他分类数据的方法。\n",
"\n",
"在本课中,我们需要以下软件包:\n",
"\n",
"- `tidyverse` [tidyverse](https://www.tidyverse.org/) 是一个 [R 包集合](https://www.tidyverse.org/packages),旨在让数据科学更快、更简单、更有趣!\n",
"\n",
"- `tidymodels` [tidymodels](https://www.tidymodels.org/) 框架是一个 [包集合](https://www.tidymodels.org/packages),用于建模和机器学习。\n",
"\n",
"- `janitor` [janitor 包](https://github.com/sfirke/janitor) 提供了一些简单的小工具,用于检查和清理脏数据。\n",
"\n",
"- `ggbeeswarm` [ggbeeswarm 包](https://github.com/eclarke/ggbeeswarm) 提供了使用 ggplot2 创建蜜蜂群图的方法。\n",
"\n",
"你可以通过以下方式安装它们:\n",
"\n",
"`install.packages(c(\"tidyverse\", \"tidymodels\", \"janitor\", \"ggbeeswarm\"))`\n",
"\n",
"或者,下面的脚本会检查你是否已经安装了完成本模块所需的软件包,并在缺少时为你安装它们。\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"suppressWarnings(if (!require(\"pacman\"))install.packages(\"pacman\"))\n",
"\n",
"pacman::p_load(tidyverse, tidymodels, janitor, ggbeeswarm)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## **定义问题**\n",
"\n",
"在我们的场景中,我们将问题定义为一个二元分类:“白色”或“非白色”。我们的数据集中还有一个“条纹”类别,但它的样本数量很少,因此我们不会使用它。实际上,当我们从数据集中移除空值后,这个类别也会消失。\n",
"\n",
"> 🎃 有趣的事实:我们有时会把白色南瓜称为“幽灵”南瓜。它们不太容易雕刻,因此不像橙色南瓜那么受欢迎,但它们看起来很酷!所以我们也可以将问题重新表述为:“幽灵”或“非幽灵”。👻\n",
"\n",
"## **关于逻辑回归**\n",
"\n",
"逻辑回归与之前学习的线性回归在几个重要方面有所不同。\n",
"\n",
"#### **二元分类**\n",
"\n",
"逻辑回归不具备线性回归的相同功能。前者提供关于`二元类别`(例如“橙色或非橙色”)的预测,而后者能够预测`连续值`,例如根据南瓜的产地和收获时间,*预测其价格将上涨多少*。\n",
"\n",
"![Dasani Madipalli制作的信息图](../../../../../../translated_images/zh-CN/pumpkin-classifier.562771f104ad5436.webp)\n",
"\n",
"### 其他分类方式\n",
"\n",
"逻辑回归还有其他类型,包括多项式和有序分类:\n",
"\n",
"- **多项式分类**,涉及多个类别——例如“橙色、白色和条纹”。\n",
"\n",
"- **有序分类**,涉及有序的类别,这在我们需要逻辑地排列结果时很有用,例如按南瓜的有限尺寸(迷你、小、中、大、特大、超大)进行排序。\n",
"\n",
"![多项式分类 vs 有序分类](../../../../../../translated_images/zh-CN/multinomial-vs-ordinal.36701b4850e37d86.webp)\n",
"\n",
"#### **变量不需要相关**\n",
"\n",
"还记得线性回归在变量相关性较强时效果更好吗?逻辑回归正好相反——变量不需要相关性。这非常适合我们的数据,因为它的相关性较弱。\n",
"\n",
"#### **需要大量干净的数据**\n",
"\n",
"如果使用更多数据,逻辑回归会提供更准确的结果;我们的数据集较小,因此并不是完成这项任务的最佳选择,请记住这一点。\n",
"\n",
"✅ 思考哪些类型的数据适合逻辑回归\n",
"\n",
"## 练习 - 整理数据\n",
"\n",
"首先,稍微清理一下数据,删除空值并选择部分列:\n",
"\n",
"1. 添加以下代码:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Load the core tidyverse packages\n",
"library(tidyverse)\n",
"\n",
"# Import the data and clean column names\n",
"pumpkins <- read_csv(file = \"https://raw.githubusercontent.com/microsoft/ML-For-Beginners/main/2-Regression/data/US-pumpkins.csv\") %>% \n",
" clean_names()\n",
"\n",
"# Select desired columns\n",
"pumpkins_select <- pumpkins %>% \n",
" select(c(city_name, package, variety, origin, item_size, color)) \n",
"\n",
"# Drop rows containing missing values and encode color as factor (category)\n",
"pumpkins_select <- pumpkins_select %>% \n",
" drop_na() %>% \n",
" mutate(color = factor(color))\n",
"\n",
"# View the first few rows\n",
"pumpkins_select %>% \n",
" slice_head(n = 5)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"您可以随时使用 [*glimpse()*](https://pillar.r-lib.org/reference/glimpse.html) 函数来快速查看新的数据框,如下所示:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"pumpkins_select %>% \n",
" glimpse()\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"让我们确认一下,我们实际上是在处理一个二分类问题:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Subset distinct observations in outcome column\n",
"pumpkins_select %>% \n",
" distinct(color)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 可视化 - 分类图\n",
"到目前为止,您已经再次加载了南瓜数据并进行了清理,以保留包含一些变量(包括颜色)的数据集。现在让我们使用 ggplot 库在笔记本中可视化这个数据框。\n",
"\n",
"ggplot 库提供了一些很棒的方法来可视化您的数据。例如,您可以在分类图中比较每种品种和颜色的数据分布。\n",
"\n",
"1. 使用 geombar 函数创建这样的图表,使用我们的南瓜数据,并为每种南瓜类别(橙色或白色)指定颜色映射:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "python"
}
},
"outputs": [],
"source": [
"# Specify colors for each value of the hue variable\n",
"palette <- c(ORANGE = \"orange\", WHITE = \"wheat\")\n",
"\n",
"# Create the bar plot\n",
"ggplot(pumpkins_select, aes(y = variety, fill = color)) +\n",
" geom_bar(position = \"dodge\") +\n",
" scale_fill_manual(values = palette) +\n",
" labs(y = \"Variety\", fill = \"Color\") +\n",
" theme_minimal()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"通过观察数据,可以看到颜色数据与品种之间的关系。\n",
"\n",
"✅ 根据这个分类图,你能想到哪些有趣的探索方向?\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 数据预处理:特征编码\n",
"\n",
"我们的南瓜数据集的所有列都包含字符串值。处理分类数据对人类来说很直观,但对机器来说却不是这样。机器学习算法更擅长处理数字数据。这就是为什么编码是数据预处理阶段中非常重要的一步,因为它使我们能够将分类数据转换为数值数据,同时不丢失任何信息。良好的编码能够帮助我们构建一个优秀的模型。\n",
"\n",
"对于特征编码,主要有两种类型的编码器:\n",
"\n",
"1. **序数编码器Ordinal encoder**:适用于序数变量,这类变量是具有逻辑顺序的分类变量,比如我们数据集中的 `item_size` 列。它会创建一个映射,使每个类别用一个数字表示,这个数字对应类别在列中的顺序。\n",
"\n",
"2. **分类编码器Categorical encoder**:适用于名义变量,这类变量是没有逻辑顺序的分类变量,比如我们数据集中除了 `item_size` 以外的所有特征。这是一种独热编码one-hot encoding意味着每个类别都会用一个二进制列表示如果南瓜属于该类别则编码变量等于1否则为0。\n",
"\n",
"Tidymodels 提供了另一个非常实用的包:[recipes](https://recipes.tidymodels.org/),这是一个用于数据预处理的包。我们将定义一个 `recipe`,指定所有预测列都应该被编码为一组整数,然后通过 `prep` 来估算任何操作所需的量和统计数据,最后通过 `bake` 将这些计算应用到新数据上。\n",
"\n",
"> 通常情况下recipes 通常用作建模的预处理器,它定义了为了让数据集适合建模需要应用哪些步骤。在这种情况下,**强烈建议** 使用 `workflow()`,而不是手动通过 prep 和 bake 来估算 recipe。我们稍后会详细讲解这一点。\n",
">\n",
"> 不过目前,我们使用 recipes + prep + bake 来指定对数据集需要应用哪些步骤,以便让数据集准备好进行数据分析,然后提取应用了这些步骤的预处理数据。\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Preprocess and extract data to allow some data analysis\n",
"baked_pumpkins <- recipe(color ~ ., data = pumpkins_select) %>%\n",
" # Define ordering for item_size column\n",
" step_mutate(item_size = ordered(item_size, levels = c('sml', 'med', 'med-lge', 'lge', 'xlge', 'jbo', 'exjbo'))) %>%\n",
" # Convert factors to numbers using the order defined above (Ordinal encoding)\n",
" step_integer(item_size, zero_based = F) %>%\n",
" # Encode all other predictors using one hot encoding\n",
" step_dummy(all_nominal(), -all_outcomes(), one_hot = TRUE) %>%\n",
" prep(data = pumpkin_select) %>%\n",
" bake(new_data = NULL)\n",
"\n",
"# Display the first few rows of preprocessed data\n",
"baked_pumpkins %>% \n",
" slice_head(n = 5)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"✅ 使用序数编码器对 Item Size 列进行编码有哪些优势?\n",
"\n",
"### 分析变量之间的关系\n",
"\n",
"现在我们已经对数据进行了预处理,可以分析特征与标签之间的关系,以了解模型在给定特征的情况下预测标签的能力。这类分析的最佳方式是对数据进行可视化。 \n",
"我们将再次使用 ggplot 的 geom_boxplot_ 函数,以分类图的形式展示 Item Size、Variety 和 Color 之间的关系。为了更好地绘制数据,我们将使用编码后的 Item Size 列和未编码的 Variety 列。\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Define the color palette\n",
"palette <- c(ORANGE = \"orange\", WHITE = \"wheat\")\n",
"\n",
"# We need the encoded Item Size column to use it as the x-axis values in the plot\n",
"pumpkins_select_plot<-pumpkins_select\n",
"pumpkins_select_plot$item_size <- baked_pumpkins$item_size\n",
"\n",
"# Create the grouped box plot\n",
"ggplot(pumpkins_select_plot, aes(x = `item_size`, y = color, fill = color)) +\n",
" geom_boxplot() +\n",
" facet_grid(variety ~ ., scales = \"free_x\") +\n",
" scale_fill_manual(values = palette) +\n",
" labs(x = \"Item Size\", y = \"\") +\n",
" theme_minimal() +\n",
" theme(strip.text = element_text(size = 12)) +\n",
" theme(axis.text.x = element_text(size = 10)) +\n",
" theme(axis.title.x = element_text(size = 12)) +\n",
" theme(axis.title.y = element_blank()) +\n",
" theme(legend.position = \"bottom\") +\n",
" guides(fill = guide_legend(title = \"Color\")) +\n",
" theme(panel.spacing = unit(0.5, \"lines\"))+\n",
" theme(strip.text.y = element_text(size = 4, hjust = 0)) \n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 使用群集图\n",
"\n",
"由于颜色是一个二元类别(白色或非白色),它需要一种“[专门的方法](https://github.com/rstudio/cheatsheets/blob/main/data-visualization.pdf)”来进行可视化。\n",
"\n",
"尝试使用`群集图`来展示颜色相对于item_size的分布。\n",
"\n",
"我们将使用[ggbeeswarm包](https://github.com/eclarke/ggbeeswarm)该包提供了使用ggplot2创建蜂群式图的方法。蜂群图是一种将通常会重叠的点排列在彼此旁边的绘图方式。\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Create beeswarm plots of color and item_size\n",
"baked_pumpkins %>% \n",
" mutate(color = factor(color)) %>% \n",
" ggplot(mapping = aes(x = color, y = item_size, color = color)) +\n",
" geom_quasirandom() +\n",
" scale_color_brewer(palette = \"Dark2\", direction = -1) +\n",
" theme(legend.position = \"none\")\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"现在我们已经了解了颜色的二元分类与更大尺寸类别之间的关系,接下来让我们探索逻辑回归,以确定某个南瓜可能的颜色。\n",
"\n",
"## 构建模型\n",
"\n",
"选择您想在分类模型中使用的变量,并将数据分为训练集和测试集。[rsample](https://rsample.tidymodels.org/) 是 Tidymodels 中的一个包,它提供了高效的数据分割和重采样的基础设施:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Split data into 80% for training and 20% for testing\n",
"set.seed(2056)\n",
"pumpkins_split <- pumpkins_select %>% \n",
" initial_split(prop = 0.8)\n",
"\n",
"# Extract the data in each split\n",
"pumpkins_train <- training(pumpkins_split)\n",
"pumpkins_test <- testing(pumpkins_split)\n",
"\n",
"# Print out the first 5 rows of the training set\n",
"pumpkins_train %>% \n",
" slice_head(n = 5)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"🙌 我们现在准备通过将训练特征与训练标签(颜色)进行拟合来训练模型。\n",
"\n",
"我们将首先创建一个配方,用于指定对数据进行建模前的预处理步骤,例如:将分类变量编码为一组整数。就像 `baked_pumpkins` 一样,我们创建了一个 `pumpkins_recipe`,但不会立即 `prep` 和 `bake`,因为这些步骤会被整合到一个工作流中,稍后您会看到具体操作。\n",
"\n",
"在 Tidymodels 中,有很多方法可以指定逻辑回归模型。请参阅 `?logistic_reg()`。目前,我们将通过默认的 `stats::glm()` 引擎来指定一个逻辑回归模型。\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Create a recipe that specifies preprocessing steps for modelling\n",
"pumpkins_recipe <- recipe(color ~ ., data = pumpkins_train) %>% \n",
" step_mutate(item_size = ordered(item_size, levels = c('sml', 'med', 'med-lge', 'lge', 'xlge', 'jbo', 'exjbo'))) %>%\n",
" step_integer(item_size, zero_based = F) %>% \n",
" step_dummy(all_nominal(), -all_outcomes(), one_hot = TRUE)\n",
"\n",
"# Create a logistic model specification\n",
"log_reg <- logistic_reg() %>% \n",
" set_engine(\"glm\") %>% \n",
" set_mode(\"classification\")\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"现在我们已经有了一个配方和一个模型规范,我们需要找到一种方法将它们打包成一个对象。这个对象将首先对数据进行预处理(在幕后完成 prep 和 bake 操作),然后在预处理后的数据上拟合模型,同时还支持潜在的后处理操作。\n",
"\n",
"在 Tidymodels 中,这个方便的对象被称为 [`workflow`](https://workflows.tidymodels.org/),它能够方便地容纳你的建模组件。\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Bundle modelling components in a workflow\n",
"log_reg_wf <- workflow() %>% \n",
" add_recipe(pumpkins_recipe) %>% \n",
" add_model(log_reg)\n",
"\n",
"# Print out the workflow\n",
"log_reg_wf\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"在*指定*工作流程后,可以使用[`fit()`](https://tidymodels.github.io/parsnip/reference/fit.html)函数对模型进行`训练`。工作流程会估算配方并在训练前对数据进行预处理因此我们无需手动使用prep和bake来完成这些步骤。\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Train the model\n",
"wf_fit <- log_reg_wf %>% \n",
" fit(data = pumpkins_train)\n",
"\n",
"# Print the trained workflow\n",
"wf_fit\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"模型训练期间打印出的内容显示了学习到的系数。\n",
"\n",
"现在我们已经使用训练数据训练了模型,可以使用 [parsnip::predict()](https://parsnip.tidymodels.org/reference/predict.model_fit.html) 对测试数据进行预测。让我们从使用模型预测测试集的标签以及每个标签的概率开始。当概率大于 0.5 时,预测类别为 `WHITE`,否则为 `ORANGE`。\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Make predictions for color and corresponding probabilities\n",
"results <- pumpkins_test %>% select(color) %>% \n",
" bind_cols(wf_fit %>% \n",
" predict(new_data = pumpkins_test)) %>%\n",
" bind_cols(wf_fit %>%\n",
" predict(new_data = pumpkins_test, type = \"prob\"))\n",
"\n",
"# Compare predictions\n",
"results %>% \n",
" slice_head(n = 10)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"非常好!这为我们提供了更多关于逻辑回归工作原理的见解。\n",
"\n",
"### 通过混淆矩阵更好地理解\n",
"\n",
"将每个预测值与其对应的“真实值”进行比较并不是评估模型预测效果的高效方法。幸运的是Tidymodels 还有一些其他的技巧:[`yardstick`](https://yardstick.tidymodels.org/)——一个通过性能指标来衡量模型效果的工具包。\n",
"\n",
"与分类问题相关的一个性能指标是[`混淆矩阵`](https://wikipedia.org/wiki/Confusion_matrix)。混淆矩阵描述了分类模型的表现情况。它统计了模型对每个类别正确分类的样本数量。在我们的例子中,它会显示有多少橙色南瓜被正确分类为橙色,有多少白色南瓜被正确分类为白色;同时,混淆矩阵还会显示有多少样本被错误分类到**其他类别**。\n",
"\n",
"来自 yardstick 的 [**`conf_mat()`**](https://tidymodels.github.io/yardstick/reference/conf_mat.html) 函数可以计算观察值和预测值的交叉分类表。\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Confusion matrix for prediction results\n",
"conf_mat(data = results, truth = color, estimate = .pred_class)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"让我们来解读混淆矩阵。我们的模型需要将南瓜分类为两个二元类别:类别 `white` 和类别 `not-white`。\n",
"\n",
"- 如果你的模型预测南瓜为白色,并且它实际上属于类别 'white',我们称之为 `true positive`,显示在左上角的数字。\n",
"\n",
"- 如果你的模型预测南瓜为非白色,并且它实际上属于类别 'white',我们称之为 `false negative`,显示在左下角的数字。\n",
"\n",
"- 如果你的模型预测南瓜为白色,并且它实际上属于类别 'not-white',我们称之为 `false positive`,显示在右上角的数字。\n",
"\n",
"- 如果你的模型预测南瓜为非白色,并且它实际上属于类别 'not-white',我们称之为 `true negative`,显示在右下角的数字。\n",
"\n",
"| 实际情况 |\n",
"|:-----:|\n",
"\n",
"| | | |\n",
"|---------------|--------|-------|\n",
"| **预测结果** | WHITE | ORANGE |\n",
"| WHITE | TP | FP |\n",
"| ORANGE | FN | TN |\n",
"\n",
"正如你可能猜到的,理想情况下我们希望有更多的 `true positive` 和 `true negative`,以及更少的 `false positive` 和 `false negative`,这意味着模型表现更好。\n",
"\n",
"混淆矩阵非常有用,因为它可以衍生出其他指标,帮助我们更好地评估分类模型的性能。让我们来看看其中的一些指标:\n",
"\n",
"🎓 精确率Precision`TP/(TP + FP)`,定义为预测为正的样本中实际为正的比例。也称为[正预测值](https://en.wikipedia.org/wiki/Positive_predictive_value \"Positive predictive value\")。\n",
"\n",
"🎓 召回率Recall`TP/(TP + FN)`,定义为实际为正的样本中被正确预测为正的比例。也称为 `敏感性`。\n",
"\n",
"🎓 特异性Specificity`TN/(TN + FP)`,定义为实际为负的样本中被正确预测为负的比例。\n",
"\n",
"🎓 准确率Accuracy`TP + TN/(TP + TN + FP + FN)`,表示样本中预测正确的标签所占的百分比。\n",
"\n",
"🎓 F值F Measure精确率和召回率的加权平均值最佳值为1最差值为0。\n",
"\n",
"让我们来计算这些指标吧!\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Combine metric functions and calculate them all at once\n",
"eval_metrics <- metric_set(ppv, recall, spec, f_meas, accuracy)\n",
"eval_metrics(data = results, truth = color, estimate = .pred_class)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 可视化该模型的ROC曲线\n",
"\n",
"让我们进行另一个可视化操作,来查看所谓的[`ROC曲线`](https://en.wikipedia.org/wiki/Receiver_operating_characteristic)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Make a roc_curve\n",
"results %>% \n",
" roc_curve(color, .pred_ORANGE) %>% \n",
" autoplot()\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"ROC 曲线通常用于查看分类器输出的真阳性与假阳性之间的关系。ROC 曲线通常在 Y 轴上显示 `True Positive Rate`(真阳性率)/敏感性,在 X 轴上显示 `False Positive Rate`(假阳性率)/1-特异性。因此,曲线的陡峭程度以及曲线与对角线之间的空间很重要:你希望看到一条快速上升并越过对角线的曲线。在我们的例子中,起初存在一些假阳性,然后曲线正确地上升并越过对角线。\n",
"\n",
"最后,我们使用 `yardstick::roc_auc()` 来计算实际的曲线下面积AUC。AUC 的一种解释方式是:模型将一个随机正例排在一个随机负例之前的概率。\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "r"
}
},
"outputs": [],
"source": [
"# Calculate area under curve\n",
"results %>% \n",
" roc_auc(color, .pred_ORANGE)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"结果约为 `0.975`。由于 AUC 的范围是 0 到 1你希望分数越大越好因为一个模型如果能 100% 准确预测,其 AUC 将达到 1在这个例子中模型表现*相当不错*。\n",
"\n",
"在后续关于分类的课程中,你将学习如何提高模型的分数(例如在这种情况下处理数据不平衡的问题)。\n",
"\n",
"## 🚀挑战\n",
"\n",
"关于逻辑回归还有很多内容可以深入探讨!但学习的最佳方式是通过实践。寻找一个适合这种分析的数据集,并用它构建一个模型。你学到了什么?提示:可以尝试 [Kaggle](https://www.kaggle.com/search?q=logistic+regression+datasets) 上的有趣数据集。\n",
"\n",
"## 复习与自学\n",
"\n",
"阅读 [斯坦福大学这篇论文](https://web.stanford.edu/~jurafsky/slp3/5.pdf) 的前几页,了解逻辑回归的一些实际应用。思考哪些任务更适合我们到目前为止学习的不同回归类型。哪种方法效果最好?\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**免责声明** \n本文档使用AI翻译服务 [Co-op Translator](https://github.com/Azure/co-op-translator) 进行翻译。尽管我们努力确保翻译的准确性,但请注意,自动翻译可能包含错误或不准确之处。原始语言的文档应被视为权威来源。对于重要信息,建议使用专业人工翻译。我们不对因使用此翻译而产生的任何误解或误读承担责任。\n"
]
}
],
"metadata": {
"anaconda-cloud": "",
"kernelspec": {
"display_name": "R",
"langauge": "R",
"name": "ir"
},
"language_info": {
"codemirror_mode": "r",
"file_extension": ".r",
"mimetype": "text/x-r-source",
"name": "R",
"pygments_lexer": "r",
"version": "3.4.1"
},
"coopTranslator": {
"original_hash": "feaf125f481a89c468fa115bf2aed580",
"translation_date": "2025-09-03T19:36:22+00:00",
"source_file": "2-Regression/4-Logistic/solution/R/lesson_4-R.ipynb",
"language_code": "zh"
}
},
"nbformat": 4,
"nbformat_minor": 1
}

File diff suppressed because one or more lines are too long

@ -0,0 +1,45 @@
# 机器学习中的回归模型
## 区域主题:北美地区南瓜价格的回归模型 🎃
在北美,南瓜常被雕刻成恐怖的面孔用于庆祝万圣节。让我们一起来探索这些迷人的蔬菜吧!
![jack-o-lanterns](../../../translated_images/zh-CN/jack-o-lanterns.181c661a9212457d.webp)
> 图片由 <a href="https://unsplash.com/@teutschmann?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Beth Teutschmann</a> 提供,来自 <a href="https://unsplash.com/s/photos/jack-o-lanterns?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a>
## 你将学到什么
[![回归简介](https://img.youtube.com/vi/5QnJtDad4iQ/0.jpg)](https://youtu.be/5QnJtDad4iQ "回归简介视频 - 点击观看!")
> 🎥 点击上方图片观看本课的快速介绍视频
本节课程涵盖了机器学习中回归的类型。回归模型可以帮助确定变量之间的_关系_。这种模型可以预测诸如长度、温度或年龄等值从而在分析数据点时揭示变量之间的关系。
在这一系列课程中,你将了解线性回归和逻辑回归的区别,以及在什么情况下应该选择其中一种。
[![机器学习初学者 - 回归模型简介](https://img.youtube.com/vi/XA3OaoW86R8/0.jpg)](https://youtu.be/XA3OaoW86R8 "机器学习初学者 - 回归模型简介")
> 🎥 点击上方图片观看关于回归模型的简短介绍视频。
在这一组课程中,你将准备开始机器学习任务,包括配置 Visual Studio Code 来管理笔记本,这是数据科学家常用的环境。你将了解 Scikit-learn一个用于机器学习的库并在本章中构建你的第一个模型重点是回归模型。
> 有一些实用的低代码工具可以帮助你学习如何使用回归模型。试试 [Azure ML 来完成这个任务](https://docs.microsoft.com/learn/modules/create-regression-model-azure-machine-learning-designer/?WT.mc_id=academic-77952-leestott)
### 课程
1. [工具介绍](1-Tools/README.md)
2. [数据管理](2-Data/README.md)
3. [线性回归和多项式回归](3-Linear/README.md)
4. [逻辑回归](4-Logistic/README.md)
---
### 致谢
"回归中的机器学习" 由 [Jen Looper](https://twitter.com/jenlooper) ♥️ 编写
♥️ 测验贡献者包括:[Muhammad Sakib Khan Inan](https://twitter.com/Sakibinan) 和 [Ornella Altunyan](https://twitter.com/ornelladotcom)
南瓜数据集由 [Kaggle 上的这个项目](https://www.kaggle.com/usda/a-year-of-pumpkin-prices) 提供,其数据来源于美国农业部发布的 [Specialty Crops Terminal Markets Standard Reports](https://www.marketnews.usda.gov/mnp/fv-report-config-step1?type=termPrice)。我们根据品种添加了一些关于颜色的点以规范分布。这些数据属于公共领域。
---
**免责声明**
本文档使用AI翻译服务 [Co-op Translator](https://github.com/Azure/co-op-translator) 进行翻译。尽管我们努力确保翻译的准确性,但请注意,自动翻译可能包含错误或不准确之处。应以原始语言的文档作为权威来源。对于关键信息,建议使用专业人工翻译。我们对因使用此翻译而产生的任何误解或误读不承担责任。

@ -0,0 +1,350 @@
# 构建一个使用机器学习模型的网页应用
在本课中你将使用一个非常特别的数据集来训练一个机器学习模型_过去一个世纪的UFO目击事件_数据来源于NUFORC的数据库。
你将学习:
- 如何对训练好的模型进行“pickle”处理
- 如何在Flask应用中使用该模型
我们将继续使用notebook来清理数据并训练模型但你可以更进一步尝试在“真实世界”中使用模型也就是在一个网页应用中。
为此你需要使用Flask构建一个网页应用。
## [课前小测验](https://ff-quizzes.netlify.app/en/ml/)
## 构建一个应用
有多种方法可以构建网页应用来使用机器学习模型。你的网页架构可能会影响模型的训练方式。想象一下,你正在一个企业中工作,数据科学团队已经训练了一个模型,他们希望你在应用中使用它。
### 需要考虑的问题
你需要问自己许多问题:
- **这是一个网页应用还是一个移动应用?** 如果你正在构建一个移动应用,或者需要在物联网环境中使用模型,你可以使用 [TensorFlow Lite](https://www.tensorflow.org/lite/) 并在Android或iOS应用中使用该模型。
- **模型将存储在哪里?** 是在云端还是本地?
- **是否需要离线支持?** 应用是否需要在离线状态下运行?
- **训练模型使用了什么技术?** 所选技术可能会影响你需要使用的工具。
- **使用TensorFlow。** 如果你使用TensorFlow训练模型该生态系统提供了将TensorFlow模型转换为网页应用中使用的能力例如通过 [TensorFlow.js](https://www.tensorflow.org/js/)。
- **使用PyTorch。** 如果你使用 [PyTorch](https://pytorch.org/) 等库构建模型,你可以选择将其导出为 [ONNX](https://onnx.ai/)开放神经网络交换格式用于支持JavaScript网页应用的 [Onnx Runtime](https://www.onnxruntime.ai/)。在未来的课程中我们将探索如何将Scikit-learn训练的模型导出为ONNX格式。
- **使用Lobe.ai或Azure Custom Vision。** 如果你使用 [Lobe.ai](https://lobe.ai/) 或 [Azure Custom Vision](https://azure.microsoft.com/services/cognitive-services/custom-vision-service/?WT.mc_id=academic-77952-leestott) 等机器学习SaaS软件即服务系统来训练模型这类软件提供了多平台导出模型的方法包括构建一个定制的API通过云端供在线应用查询。
你还可以选择构建一个完整的Flask网页应用该应用能够在网页浏览器中自行训练模型。这也可以通过JavaScript环境中的TensorFlow.js实现。
对于我们的目的由于我们一直在使用基于Python的notebook让我们来探索将训练好的模型从notebook导出为Python构建的网页应用可读取的格式所需的步骤。
## 工具
完成此任务你需要两个工具Flask和Pickle它们都运行在Python上。
✅ 什么是 [Flask](https://palletsprojects.com/p/flask/)Flask被其创建者定义为一个“微框架”它使用Python和模板引擎来构建网页提供了网页框架的基本功能。可以参考 [这个学习模块](https://docs.microsoft.com/learn/modules/python-flask-build-ai-web-app?WT.mc_id=academic-77952-leestott) 来练习使用Flask构建应用。
✅ 什么是 [Pickle](https://docs.python.org/3/library/pickle.html)Pickle 🥒 是一个Python模块用于序列化和反序列化Python对象结构。当你对模型进行“pickle”处理时你会将其结构序列化或扁平化以便在网页上使用。需要注意的是Pickle本身并不安全因此在被提示“un-pickle”文件时要小心。Pickle文件的后缀为`.pkl`。
## 练习 - 清理数据
在本课中,你将使用来自 [NUFORC](https://nuforc.org)国家UFO报告中心的80,000条UFO目击数据。这些数据中包含一些有趣的UFO目击描述例如
- **长描述示例。** “一个人从夜晚草地上的一道光束中出现,跑向德州仪器的停车场。”
- **短描述示例。** “灯光追逐我们。”
[ufos.csv](../../../../3-Web-App/1-Web-App/data/ufos.csv) 表格包含关于目击发生的 `city`(城市)、`state`(州)和 `country`(国家),物体的 `shape`(形状),以及其 `latitude`(纬度)和 `longitude`(经度)的列。
在本课提供的空白 [notebook](../../../../3-Web-App/1-Web-App/notebook.ipynb) 中:
1. 像之前的课程一样,导入 `pandas`、`matplotlib` 和 `numpy`并导入ufos表格。你可以查看数据集的样本
```python
import pandas as pd
import numpy as np
ufos = pd.read_csv('./data/ufos.csv')
ufos.head()
```
1. 将ufos数据转换为一个小型数据框并重新命名列标题。检查 `Country` 字段中的唯一值。
```python
ufos = pd.DataFrame({'Seconds': ufos['duration (seconds)'], 'Country': ufos['country'],'Latitude': ufos['latitude'],'Longitude': ufos['longitude']})
ufos.Country.unique()
```
1. 现在你可以通过删除任何空值并仅导入1-60秒之间的目击事件来减少需要处理的数据量
```python
ufos.dropna(inplace=True)
ufos = ufos[(ufos['Seconds'] >= 1) & (ufos['Seconds'] <= 60)]
ufos.info()
```
1. 导入Scikit-learn的 `LabelEncoder` 库,将国家的文本值转换为数字:
✅ LabelEncoder 按字母顺序对数据进行编码
```python
from sklearn.preprocessing import LabelEncoder
ufos['Country'] = LabelEncoder().fit_transform(ufos['Country'])
ufos.head()
```
你的数据应如下所示:
```output
Seconds Country Latitude Longitude
2 20.0 3 53.200000 -2.916667
3 20.0 4 28.978333 -96.645833
14 30.0 4 35.823889 -80.253611
23 60.0 4 45.582778 -122.352222
24 3.0 3 51.783333 -0.783333
```
## 练习 - 构建模型
现在你可以准备通过将数据分为训练组和测试组来训练模型。
1. 选择三个特征作为你的X向量y向量将是 `Country`。你希望能够输入 `Seconds`、`Latitude` 和 `Longitude`并返回一个国家ID。
```python
from sklearn.model_selection import train_test_split
Selected_features = ['Seconds','Latitude','Longitude']
X = ufos[Selected_features]
y = ufos['Country']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
```
1. 使用逻辑回归训练模型:
```python
from sklearn.metrics import accuracy_score, classification_report
from sklearn.linear_model import LogisticRegression
model = LogisticRegression()
model.fit(X_train, y_train)
predictions = model.predict(X_test)
print(classification_report(y_test, predictions))
print('Predicted labels: ', predictions)
print('Accuracy: ', accuracy_score(y_test, predictions))
```
模型的准确率还不错 **大约95%**,这并不奇怪,因为 `Country``Latitude/Longitude` 是相关的。
你创建的模型并不是非常具有革命性,因为你应该能够从 `Latitude``Longitude` 推断出 `Country`,但这是一个很好的练习,可以尝试从清理过的原始数据中训练模型,导出模型,然后在网页应用中使用它。
## 练习 - 对模型进行“pickle”处理
现在是时候对你的模型进行“pickle”处理了你可以用几行代码完成这一步。一旦完成“pickle”处理加载你的Pickle模型并用一个包含秒数、纬度和经度值的样本数据数组进行测试
```python
import pickle
model_filename = 'ufo-model.pkl'
pickle.dump(model, open(model_filename,'wb'))
model = pickle.load(open('ufo-model.pkl','rb'))
print(model.predict([[50,44,-12]]))
```
模型返回了 **'3'**,这是英国的国家代码。太神奇了!👽
## 练习 - 构建一个Flask应用
现在你可以构建一个Flask应用来调用你的模型并以更直观的方式返回类似的结果。
1. 首先,在 _notebook.ipynb_ 文件旁边创建一个名为 **web-app** 的文件夹,其中存放你的 _ufo-model.pkl_ 文件。
1. 在该文件夹中再创建三个文件夹:**static**(其中包含一个名为 **css** 的文件夹)和 **templates**。你现在应该有以下文件和目录:
```output
web-app/
static/
css/
templates/
notebook.ipynb
ufo-model.pkl
```
✅ 参考解决方案文件夹以查看完成的应用
1. 在 _web-app_ 文件夹中创建第一个文件 **requirements.txt**。像JavaScript应用中的 _package.json_ 一样,此文件列出了应用所需的依赖项。在 **requirements.txt** 中添加以下内容:
```text
scikit-learn
pandas
numpy
flask
```
1. 现在,通过导航到 _web-app_ 运行此文件:
```bash
cd web-app
```
1. 在终端中输入 `pip install`,以安装 _requirements.txt_ 中列出的库:
```bash
pip install -r requirements.txt
```
1. 现在,你可以创建另外三个文件来完成应用:
1. 在根目录创建 **app.py**
2. 在 _templates_ 目录中创建 **index.html**
3. 在 _static/css_ 目录中创建 **styles.css**
1. 在 _styles.css_ 文件中添加一些样式:
```css
body {
width: 100%;
height: 100%;
font-family: 'Helvetica';
background: black;
color: #fff;
text-align: center;
letter-spacing: 1.4px;
font-size: 30px;
}
input {
min-width: 150px;
}
.grid {
width: 300px;
border: 1px solid #2d2d2d;
display: grid;
justify-content: center;
margin: 20px auto;
}
.box {
color: #fff;
background: #2d2d2d;
padding: 12px;
display: inline-block;
}
```
1. 接下来,构建 _index.html_ 文件:
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>🛸 UFO Appearance Prediction! 👽</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}">
</head>
<body>
<div class="grid">
<div class="box">
<p>According to the number of seconds, latitude and longitude, which country is likely to have reported seeing a UFO?</p>
<form action="{{ url_for('predict')}}" method="post">
<input type="number" name="seconds" placeholder="Seconds" required="required" min="0" max="60" />
<input type="text" name="latitude" placeholder="Latitude" required="required" />
<input type="text" name="longitude" placeholder="Longitude" required="required" />
<button type="submit" class="btn">Predict country where the UFO is seen</button>
</form>
<p>{{ prediction_text }}</p>
</div>
</div>
</body>
</html>
```
查看此文件中的模板语法。注意变量周围的“大括号”语法,例如预测文本:`{{}}`。还有一个表单会将预测结果发布到 `/predict` 路由。
最后你已经准备好构建驱动模型使用和预测显示的Python文件
1. 在 `app.py` 中添加:
```python
import numpy as np
from flask import Flask, request, render_template
import pickle
app = Flask(__name__)
model = pickle.load(open("./ufo-model.pkl", "rb"))
@app.route("/")
def home():
return render_template("index.html")
@app.route("/predict", methods=["POST"])
def predict():
int_features = [int(x) for x in request.form.values()]
final_features = [np.array(int_features)]
prediction = model.predict(final_features)
output = prediction[0]
countries = ["Australia", "Canada", "Germany", "UK", "US"]
return render_template(
"index.html", prediction_text="Likely country: {}".format(countries[output])
)
if __name__ == "__main__":
app.run(debug=True)
```
> 💡 提示当你在使用Flask运行网页应用时添加 [`debug=True`](https://www.askpython.com/python-modules/flask/flask-debug-mode),任何对应用的更改都会立即反映出来,而无需重启服务器。但要小心!不要在生产应用中启用此模式。
如果你运行 `python app.py``python3 app.py`你的网页服务器会在本地启动你可以填写一个简短的表单获取关于UFO目击地点的答案
在此之前,先看看 `app.py` 的各个部分:
1. 首先,加载依赖项并启动应用。
1. 然后,导入模型。
1. 接着,在主页路由上渲染 index.html。
`/predict` 路由上,当表单被提交时,会发生以下几件事:
1. 表单变量被收集并转换为一个numpy数组。然后将其发送到模型并返回一个预测结果。
2. 我们希望显示的国家代码被重新渲染为可读的文本值,并将该值发送回 index.html在模板中渲染。
通过Flask和Pickle模型以这种方式使用模型是相对简单的。最难的部分是理解必须发送到模型的数据形状以获得预测结果。这完全取决于模型的训练方式。这个模型需要输入三个数据点才能获得预测。
在专业环境中,你可以看到训练模型的团队和在网页或移动应用中使用模型的团队之间良好沟通的重要性。在我们的案例中,只有一个人,那就是你!
---
## 🚀 挑战
与其在notebook中工作并将模型导入Flask应用你可以直接在Flask应用中训练模型尝试将notebook中的Python代码转换为在应用中的 `train` 路由上训练模型。尝试这种方法的优缺点是什么?
## [课后小测验](https://ff-quizzes.netlify.app/en/ml/)
## 复习与自学
构建一个使用机器学习模型的网页应用有很多方法。列出你可以使用JavaScript或Python构建网页应用以利用机器学习的方法。考虑架构模型应该保留在应用中还是存储在云端如果是后者你将如何访问它绘制一个应用机器学习网页解决方案的架构模型。
## 作业
[尝试一个不同的模型](assignment.md)
---
**免责声明**
本文档使用AI翻译服务[Co-op Translator](https://github.com/Azure/co-op-translator)进行翻译。尽管我们努力确保准确性,但请注意,自动翻译可能包含错误或不准确之处。应以原始语言的文档作为权威来源。对于关键信息,建议使用专业人工翻译。对于因使用本翻译而引起的任何误解或误读,我们概不负责。

@ -0,0 +1,16 @@
# 尝试不同的模型
## 说明
现在您已经使用训练好的回归模型构建了一个网页应用,请使用之前回归课程中的一个模型重新制作这个网页应用。您可以保持原有的风格,也可以设计不同的样式以体现南瓜数据。请注意更改输入以匹配您模型的训练方法。
## 评分标准
| 标准 | 卓越表现 | 合格表现 | 需要改进 |
| -------------------------- | ------------------------------------------------------- | ------------------------------------------------------- | ------------------------------------- |
| | 网页应用运行正常并成功部署到云端 | 网页应用存在缺陷或表现出意外结果 | 网页应用无法正常运行 |
---
**免责声明**
本文档使用AI翻译服务[Co-op Translator](https://github.com/Azure/co-op-translator)进行翻译。尽管我们努力确保准确性,但请注意,自动翻译可能包含错误或不准确之处。应以原始语言的文档作为权威来源。对于关键信息,建议使用专业人工翻译。因使用本翻译而导致的任何误解或误读,我们概不负责。

@ -0,0 +1,267 @@
{
"metadata": {
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.0"
},
"orig_nbformat": 2,
"kernelspec": {
"name": "python37364bit8d3b438fb5fc4430a93ac2cb74d693a7",
"display_name": "Python 3.7.0 64-bit ('3.7')"
},
"metadata": {
"interpreter": {
"hash": "70b38d7a306a849643e446cd70466270a13445e5987dfa1344ef2b127438fa4d"
}
},
"coopTranslator": {
"original_hash": "5fa2e8f4584c78250ca9729b46562ceb",
"translation_date": "2025-09-03T20:19:40+00:00",
"source_file": "3-Web-App/1-Web-App/solution/notebook.ipynb",
"language_code": "zh"
}
},
"nbformat": 4,
"nbformat_minor": 2,
"cells": [
{
"source": [],
"cell_type": "markdown",
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" datetime city state country shape \\\n",
"0 10/10/1949 20:30 san marcos tx us cylinder \n",
"1 10/10/1949 21:00 lackland afb tx NaN light \n",
"2 10/10/1955 17:00 chester (uk/england) NaN gb circle \n",
"3 10/10/1956 21:00 edna tx us circle \n",
"4 10/10/1960 20:00 kaneohe hi us light \n",
"\n",
" duration (seconds) duration (hours/min) \\\n",
"0 2700.0 45 minutes \n",
"1 7200.0 1-2 hrs \n",
"2 20.0 20 seconds \n",
"3 20.0 1/2 hour \n",
"4 900.0 15 minutes \n",
"\n",
" comments date posted latitude \\\n",
"0 This event took place in early fall around 194... 4/27/2004 29.883056 \n",
"1 1949 Lackland AFB&#44 TX. Lights racing acros... 12/16/2005 29.384210 \n",
"2 Green/Orange circular disc over Chester&#44 En... 1/21/2008 53.200000 \n",
"3 My older brother and twin sister were leaving ... 1/17/2004 28.978333 \n",
"4 AS a Marine 1st Lt. flying an FJ4B fighter/att... 1/22/2004 21.418056 \n",
"\n",
" longitude \n",
"0 -97.941111 \n",
"1 -98.581082 \n",
"2 -2.916667 \n",
"3 -96.645833 \n",
"4 -157.803611 "
],
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>datetime</th>\n <th>city</th>\n <th>state</th>\n <th>country</th>\n <th>shape</th>\n <th>duration (seconds)</th>\n <th>duration (hours/min)</th>\n <th>comments</th>\n <th>date posted</th>\n <th>latitude</th>\n <th>longitude</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n <td>10/10/1949 20:30</td>\n <td>san marcos</td>\n <td>tx</td>\n <td>us</td>\n <td>cylinder</td>\n <td>2700.0</td>\n <td>45 minutes</td>\n <td>This event took place in early fall around 194...</td>\n <td>4/27/2004</td>\n <td>29.883056</td>\n <td>-97.941111</td>\n </tr>\n <tr>\n <th>1</th>\n <td>10/10/1949 21:00</td>\n <td>lackland afb</td>\n <td>tx</td>\n <td>NaN</td>\n <td>light</td>\n <td>7200.0</td>\n <td>1-2 hrs</td>\n <td>1949 Lackland AFB&amp;#44 TX. Lights racing acros...</td>\n <td>12/16/2005</td>\n <td>29.384210</td>\n <td>-98.581082</td>\n </tr>\n <tr>\n <th>2</th>\n <td>10/10/1955 17:00</td>\n <td>chester (uk/england)</td>\n <td>NaN</td>\n <td>gb</td>\n <td>circle</td>\n <td>20.0</td>\n <td>20 seconds</td>\n <td>Green/Orange circular disc over Chester&amp;#44 En...</td>\n <td>1/21/2008</td>\n <td>53.200000</td>\n <td>-2.916667</td>\n </tr>\n <tr>\n <th>3</th>\n <td>10/10/1956 21:00</td>\n <td>edna</td>\n <td>tx</td>\n <td>us</td>\n <td>circle</td>\n <td>20.0</td>\n <td>1/2 hour</td>\n <td>My older brother and twin sister were leaving ...</td>\n <td>1/17/2004</td>\n <td>28.978333</td>\n <td>-96.645833</td>\n </tr>\n <tr>\n <th>4</th>\n <td>10/10/1960 20:00</td>\n <td>kaneohe</td>\n <td>hi</td>\n <td>us</td>\n <td>light</td>\n <td>900.0</td>\n <td>15 minutes</td>\n <td>AS a Marine 1st Lt. flying an FJ4B fighter/att...</td>\n <td>1/22/2004</td>\n <td>21.418056</td>\n <td>-157.803611</td>\n </tr>\n </tbody>\n</table>\n</div>"
},
"metadata": {},
"execution_count": 23
}
],
"source": [
"import pandas as pd\n",
"import numpy as np\n",
"\n",
"ufos = pd.read_csv('../data/ufos.csv')\n",
"ufos.head()\n"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"array(['us', nan, 'gb', 'ca', 'au', 'de'], dtype=object)"
]
},
"metadata": {},
"execution_count": 24
}
],
"source": [
"\n",
"ufos = pd.DataFrame({'Seconds': ufos['duration (seconds)'], 'Country': ufos['country'],'Latitude': ufos['latitude'],'Longitude': ufos['longitude']})\n",
"\n",
"ufos.Country.unique()\n",
"\n",
"# 0 au, 1 ca, 2 de, 3 gb, 4 us"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"<class 'pandas.core.frame.DataFrame'>\nInt64Index: 25863 entries, 2 to 80330\nData columns (total 4 columns):\n # Column Non-Null Count Dtype \n--- ------ -------------- ----- \n 0 Seconds 25863 non-null float64\n 1 Country 25863 non-null object \n 2 Latitude 25863 non-null float64\n 3 Longitude 25863 non-null float64\ndtypes: float64(3), object(1)\nmemory usage: 1010.3+ KB\n"
]
}
],
"source": [
"ufos.dropna(inplace=True)\n",
"\n",
"ufos = ufos[(ufos['Seconds'] >= 1) & (ufos['Seconds'] <= 60)]\n",
"\n",
"ufos.info()"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" Seconds Country Latitude Longitude\n",
"2 20.0 3 53.200000 -2.916667\n",
"3 20.0 4 28.978333 -96.645833\n",
"14 30.0 4 35.823889 -80.253611\n",
"23 60.0 4 45.582778 -122.352222\n",
"24 3.0 3 51.783333 -0.783333"
],
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>Seconds</th>\n <th>Country</th>\n <th>Latitude</th>\n <th>Longitude</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>2</th>\n <td>20.0</td>\n <td>3</td>\n <td>53.200000</td>\n <td>-2.916667</td>\n </tr>\n <tr>\n <th>3</th>\n <td>20.0</td>\n <td>4</td>\n <td>28.978333</td>\n <td>-96.645833</td>\n </tr>\n <tr>\n <th>14</th>\n <td>30.0</td>\n <td>4</td>\n <td>35.823889</td>\n <td>-80.253611</td>\n </tr>\n <tr>\n <th>23</th>\n <td>60.0</td>\n <td>4</td>\n <td>45.582778</td>\n <td>-122.352222</td>\n </tr>\n <tr>\n <th>24</th>\n <td>3.0</td>\n <td>3</td>\n <td>51.783333</td>\n <td>-0.783333</td>\n </tr>\n </tbody>\n</table>\n</div>"
},
"metadata": {},
"execution_count": 26
}
],
"source": [
"from sklearn.preprocessing import LabelEncoder\n",
"\n",
"ufos['Country'] = LabelEncoder().fit_transform(ufos['Country'])\n",
"\n",
"ufos.head()"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [],
"source": [
"from sklearn.model_selection import train_test_split\n",
"\n",
"Selected_features = ['Seconds','Latitude','Longitude']\n",
"\n",
"X = ufos[Selected_features]\n",
"y = ufos['Country']\n",
"\n",
"\n",
"X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)\n"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stderr",
"text": [
"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:432: FutureWarning: Default solver will be changed to 'lbfgs' in 0.22. Specify a solver to silence this warning.\n",
" FutureWarning)\n",
"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/sklearn/linear_model/logistic.py:469: FutureWarning: Default multi_class will be changed to 'auto' in 0.22. Specify the multi_class option to silence this warning.\n",
" \"this warning.\", FutureWarning)\n",
" precision recall f1-score support\n",
"\n",
" 0 1.00 1.00 1.00 41\n",
" 1 1.00 0.02 0.05 250\n",
" 2 0.00 0.00 0.00 8\n",
" 3 0.94 1.00 0.97 131\n",
" 4 0.95 1.00 0.97 4743\n",
"\n",
" accuracy 0.95 5173\n",
" macro avg 0.78 0.60 0.60 5173\n",
"weighted avg 0.95 0.95 0.93 5173\n",
"\n",
"Predicted labels: [4 4 4 ... 3 4 4]\n",
"Accuracy: 0.9512855209742895\n",
"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/sklearn/metrics/classification.py:1437: UndefinedMetricWarning: Precision and F-score are ill-defined and being set to 0.0 in labels with no predicted samples.\n",
" 'precision', 'predicted', average, warn_for)\n"
]
}
],
"source": [
"from sklearn.model_selection import train_test_split\n",
"from sklearn.metrics import accuracy_score, classification_report \n",
"from sklearn.linear_model import LogisticRegression\n",
"model = LogisticRegression()\n",
"model.fit(X_train, y_train)\n",
"predictions = model.predict(X_test)\n",
"\n",
"print(classification_report(y_test, predictions))\n",
"print('Predicted labels: ', predictions)\n",
"print('Accuracy: ', accuracy_score(y_test, predictions))\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"[3]\n"
]
}
],
"source": [
"import pickle\n",
"model_filename = 'ufo-model.pkl'\n",
"pickle.dump(model, open(model_filename,'wb'))\n",
"\n",
"model = pickle.load(open('ufo-model.pkl','rb'))\n",
"print(model.predict([[50,44,-12]]))\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**免责声明** \n本文档使用AI翻译服务 [Co-op Translator](https://github.com/Azure/co-op-translator) 进行翻译。尽管我们努力确保翻译的准确性,但请注意,自动翻译可能包含错误或不准确之处。原始语言的文档应被视为权威来源。对于关键信息,建议使用专业人工翻译。我们不对因使用此翻译而产生的任何误解或误读承担责任。\n"
]
}
]
}

@ -0,0 +1,26 @@
# 构建一个使用您的机器学习模型的网页应用
在本课程的这一部分,您将学习一个应用型的机器学习主题:如何将您的 Scikit-learn 模型保存为一个文件,以便在网页应用中进行预测。一旦模型保存完成,您将学习如何在使用 Flask 构建的网页应用中使用它。您将首先使用一些关于 UFO 目击事件的数据创建一个模型!然后,您将构建一个网页应用,允许用户输入持续时间(秒数)、纬度和经度值,以预测哪个国家报告了看到 UFO。
![UFO 停车场](../../../translated_images/zh-CN/ufo.9e787f5161da9d4d.webp)
照片由 <a href="https://unsplash.com/@mdherren?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Michael Herren</a> 提供,来自 <a href="https://unsplash.com/s/photos/ufo?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a>
## 课程
1. [构建一个网页应用](1-Web-App/README.md)
## 致谢
“构建一个网页应用”由 [Jen Looper](https://twitter.com/jenlooper) 倾情撰写。
♥️ 测验由 Rohan Raj 编写。
数据集来源于 [Kaggle](https://www.kaggle.com/NUFORC/ufo-sightings)。
网页应用架构部分参考了 [这篇文章](https://towardsdatascience.com/how-to-easily-deploy-machine-learning-models-using-flask-b95af8fe34d4) 和 [这个仓库](https://github.com/abhinavsagar/machine-learning-deployment),作者为 Abhinav Sagar。
---
**免责声明**
本文档使用AI翻译服务[Co-op Translator](https://github.com/Azure/co-op-translator)进行翻译。尽管我们努力确保翻译的准确性,但请注意,自动翻译可能包含错误或不准确之处。原始语言的文档应被视为权威来源。对于关键信息,建议使用专业人工翻译。我们对因使用此翻译而产生的任何误解或误读不承担责任。

@ -0,0 +1,304 @@
# 分类简介
在这四节课中你将探索经典机器学习的一个核心主题——_分类_。我们将使用一个关于亚洲和印度各种美食的数据集逐步学习如何使用不同的分类算法。希望你已经准备好大快朵颐了
![just a pinch!](../../../../4-Classification/1-Introduction/images/pinch.png)
> 在这些课程中,庆祝泛亚洲美食吧!图片由 [Jen Looper](https://twitter.com/jenlooper) 提供
分类是一种[监督学习](https://wikipedia.org/wiki/Supervised_learning)方法与回归技术有许多相似之处。如果说机器学习的核心是通过数据集预测值或名称那么分类通常分为两类_二元分类_和_多类分类_。
[![分类简介](https://img.youtube.com/vi/eg8DJYwdMyg/0.jpg)](https://youtu.be/eg8DJYwdMyg "分类简介")
> 🎥 点击上方图片观看视频MIT 的 John Guttag 介绍分类
请记住:
- **线性回归** 帮助你预测变量之间的关系并准确预测新数据点在这条线上的位置。例如你可以预测_南瓜在九月和十二月的价格_。
- **逻辑回归** 帮助你发现“二元类别”在这个价格点上_这个南瓜是橙色还是非橙色_
分类使用各种算法来确定数据点的标签或类别。让我们通过这个美食数据集来看看,是否可以通过观察一组食材来确定它的美食来源。
## [课前测验](https://ff-quizzes.netlify.app/en/ml/)
> ### [本课程也提供 R 版本!](../../../../4-Classification/1-Introduction/solution/R/lesson_10.html)
### 简介
分类是机器学习研究者和数据科学家的基本活动之一。从简单的二元值分类(“这封邮件是垃圾邮件吗?”)到使用计算机视觉进行复杂的图像分类和分割,能够将数据分类并提出问题总是很有用的。
用更科学的方式表述,你的分类方法会创建一个预测模型,使你能够将输入变量与输出变量之间的关系映射出来。
![二元分类 vs. 多类分类](../../../../4-Classification/1-Introduction/images/binary-multiclass.png)
> 分类算法处理二元问题和多类问题的对比。信息图由 [Jen Looper](https://twitter.com/jenlooper) 提供
在开始清理数据、可视化数据并为机器学习任务做准备之前,让我们先了解一下机器学习分类数据的各种方式。
分类源自[统计学](https://wikipedia.org/wiki/Statistical_classification),使用经典机器学习进行分类时,会利用特征(如 `smoker`、`weight` 和 `age`来确定_患某种疾病的可能性_。作为一种类似于之前回归练习的监督学习技术你的数据是带标签的机器学习算法使用这些标签来分类和预测数据集的类别或“特征”并将其分配到某个组或结果中。
✅ 花点时间想象一个关于美食的数据集。一个多类模型可以回答什么问题?一个二元模型可以回答什么问题?如果你想确定某种美食是否可能使用葫芦巴呢?如果你想知道,给你一袋装满八角、洋蓟、花椰菜和辣根的杂货,你是否可以做出一道典型的印度菜呢?
[![疯狂的神秘篮子](https://img.youtube.com/vi/GuTeDbaNoEU/0.jpg)](https://youtu.be/GuTeDbaNoEU "疯狂的神秘篮子")
> 🎥 点击上方图片观看视频。节目《Chopped》的核心是“神秘篮子”厨师们必须用随机选择的食材制作一道菜。机器学习模型肯定能帮上忙
## 你好,“分类器”
我们想要从这个美食数据集中提出的问题实际上是一个**多类问题**,因为我们有多个潜在的国家美食类别可供选择。给定一组食材,这些数据会属于哪一类?
Scikit-learn 提供了多种算法来分类数据,具体取决于你想解决的问题类型。在接下来的两节课中,你将学习其中几种算法。
## 练习 - 清理并平衡数据
在开始这个项目之前,第一项任务是清理并**平衡**数据,以获得更好的结果。从本文件夹根目录中的空白 _notebook.ipynb_ 文件开始。
首先需要安装 [imblearn](https://imbalanced-learn.org/stable/)。这是一个 Scikit-learn 的扩展包,可以帮助你更好地平衡数据(稍后你会了解更多关于这个任务的内容)。
1. 安装 `imblearn`,运行以下命令:
```python
pip install imblearn
```
1. 导入所需的包以导入数据并进行可视化,同时从 `imblearn` 中导入 `SMOTE`
```python
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
from imblearn.over_sampling import SMOTE
```
现在你已经准备好导入数据了。
1. 接下来导入数据:
```python
df = pd.read_csv('../data/cuisines.csv')
```
使用 `read_csv()`_cusines.csv_ 文件的内容读取到变量 `df` 中。
1. 检查数据的形状:
```python
df.head()
```
前五行数据如下所示:
```output
| | Unnamed: 0 | cuisine | almond | angelica | anise | anise_seed | apple | apple_brandy | apricot | armagnac | ... | whiskey | white_bread | white_wine | whole_grain_wheat_flour | wine | wood | yam | yeast | yogurt | zucchini |
| --- | ---------- | ------- | ------ | -------- | ----- | ---------- | ----- | ------------ | ------- | -------- | --- | ------- | ----------- | ---------- | ----------------------- | ---- | ---- | --- | ----- | ------ | -------- |
| 0 | 65 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 1 | 66 | indian | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 2 | 67 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 3 | 68 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 4 | 69 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
```
1. 调用 `info()` 获取数据的信息:
```python
df.info()
```
输出类似于:
```output
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2448 entries, 0 to 2447
Columns: 385 entries, Unnamed: 0 to zucchini
dtypes: int64(384), object(1)
memory usage: 7.2+ MB
```
## 练习 - 了解美食
现在工作开始变得有趣了。让我们发现每种美食的数据分布情况。
1. 调用 `barh()` 将数据绘制为条形图:
```python
df.cuisine.value_counts().plot.barh()
```
![美食数据分布](../../../../4-Classification/1-Introduction/images/cuisine-dist.png)
美食的种类是有限的,但数据分布不均匀。你可以解决这个问题!在此之前,先多探索一下。
1. 找出每种美食的数据量并打印出来:
```python
thai_df = df[(df.cuisine == "thai")]
japanese_df = df[(df.cuisine == "japanese")]
chinese_df = df[(df.cuisine == "chinese")]
indian_df = df[(df.cuisine == "indian")]
korean_df = df[(df.cuisine == "korean")]
print(f'thai df: {thai_df.shape}')
print(f'japanese df: {japanese_df.shape}')
print(f'chinese df: {chinese_df.shape}')
print(f'indian df: {indian_df.shape}')
print(f'korean df: {korean_df.shape}')
```
输出如下所示:
```output
thai df: (289, 385)
japanese df: (320, 385)
chinese df: (442, 385)
indian df: (598, 385)
korean df: (799, 385)
```
## 探索食材
现在你可以更深入地挖掘数据,了解每种美食的典型食材。你需要清理那些在不同美食之间造成混淆的重复数据,因此让我们了解这个问题。
1. 在 Python 中创建一个函数 `create_ingredient()`,用于创建一个食材数据框。这个函数会先删除无用的列,然后按食材的数量进行排序:
```python
def create_ingredient_df(df):
ingredient_df = df.T.drop(['cuisine','Unnamed: 0']).sum(axis=1).to_frame('value')
ingredient_df = ingredient_df[(ingredient_df.T != 0).any()]
ingredient_df = ingredient_df.sort_values(by='value', ascending=False,
inplace=False)
return ingredient_df
```
现在你可以使用这个函数来了解每种美食中最受欢迎的前十种食材。
1. 调用 `create_ingredient()` 并通过调用 `barh()` 绘制图表:
```python
thai_ingredient_df = create_ingredient_df(thai_df)
thai_ingredient_df.head(10).plot.barh()
```
![泰国](../../../../4-Classification/1-Introduction/images/thai.png)
1. 对日本美食数据做同样的操作:
```python
japanese_ingredient_df = create_ingredient_df(japanese_df)
japanese_ingredient_df.head(10).plot.barh()
```
![日本](../../../../4-Classification/1-Introduction/images/japanese.png)
1. 接下来是中国美食的食材:
```python
chinese_ingredient_df = create_ingredient_df(chinese_df)
chinese_ingredient_df.head(10).plot.barh()
```
![中国](../../../../4-Classification/1-Introduction/images/chinese.png)
1. 绘制印度美食的食材:
```python
indian_ingredient_df = create_ingredient_df(indian_df)
indian_ingredient_df.head(10).plot.barh()
```
![印度](../../../../4-Classification/1-Introduction/images/indian.png)
1. 最后,绘制韩国美食的食材:
```python
korean_ingredient_df = create_ingredient_df(korean_df)
korean_ingredient_df.head(10).plot.barh()
```
![韩国](../../../../4-Classification/1-Introduction/images/korean.png)
1. 现在,通过调用 `drop()` 删除那些在不同美食之间造成混淆的最常见食材:
每个人都喜欢米饭、大蒜和生姜!
```python
feature_df= df.drop(['cuisine','Unnamed: 0','rice','garlic','ginger'], axis=1)
labels_df = df.cuisine #.unique()
feature_df.head()
```
## 平衡数据集
现在你已经清理了数据,使用 [SMOTE](https://imbalanced-learn.org/dev/references/generated/imblearn.over_sampling.SMOTE.html)(“合成少数类过采样技术”)来平衡数据。
1. 调用 `fit_resample()`,这种策略通过插值生成新样本。
```python
oversample = SMOTE()
transformed_feature_df, transformed_label_df = oversample.fit_resample(feature_df, labels_df)
```
通过平衡数据,你在分类时会获得更好的结果。想象一个二元分类问题。如果你的大部分数据属于一个类别,机器学习模型会更频繁地预测这个类别,仅仅因为它的数据更多。平衡数据可以消除这种不平衡。
1. 现在你可以检查每种食材的标签数量:
```python
print(f'new label count: {transformed_label_df.value_counts()}')
print(f'old label count: {df.cuisine.value_counts()}')
```
输出如下所示:
```output
new label count: korean 799
chinese 799
indian 799
japanese 799
thai 799
Name: cuisine, dtype: int64
old label count: korean 799
indian 598
chinese 442
japanese 320
thai 289
Name: cuisine, dtype: int64
```
数据现在干净、平衡,而且非常诱人!
1. 最后一步是将平衡后的数据(包括标签和特征)保存到一个新的数据框中,并导出到文件中:
```python
transformed_df = pd.concat([transformed_label_df,transformed_feature_df],axis=1, join='outer')
```
1. 你可以通过调用 `transformed_df.head()``transformed_df.info()` 再次查看数据。保存一份数据副本以供后续课程使用:
```python
transformed_df.head()
transformed_df.info()
transformed_df.to_csv("../data/cleaned_cuisines.csv")
```
这个新的 CSV 文件现在可以在根数据文件夹中找到。
---
## 🚀挑战
本课程包含多个有趣的数据集。浏览 `data` 文件夹,看看是否有适合二元或多类分类的数据集?你会对这个数据集提出什么问题?
## [课后测验](https://ff-quizzes.netlify.app/en/ml/)
## 复习与自学
探索 SMOTE 的 API。它最适合哪些用例它解决了哪些问题
## 作业
[探索分类方法](assignment.md)
---
**免责声明**
本文档使用AI翻译服务[Co-op Translator](https://github.com/Azure/co-op-translator)进行翻译。尽管我们努力确保准确性,但请注意,自动翻译可能包含错误或不准确之处。应以原始语言的文档作为权威来源。对于关键信息,建议使用专业人工翻译。因使用本翻译而导致的任何误解或误读,我们概不负责。

@ -0,0 +1,16 @@
# 探索分类方法
## 说明
在 [Scikit-learn 文档](https://scikit-learn.org/stable/supervised_learning.html) 中,你会发现大量用于分类数据的方法。请在这些文档中进行一次小型寻宝活动:你的目标是寻找分类方法,并将其与本课程中的一个数据集、一种可以提出的问题以及一种分类技术进行匹配。创建一个电子表格或 .doc 文件中的表格,并解释该数据集如何与分类算法配合使用。
## 评分标准
| 标准 | 卓越 | 合格 | 需要改进 |
| -------- | ----------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| | 提交的文档概述了 5 种算法及其分类技术。概述解释清晰且详细。 | 提交的文档概述了 3 种算法及其分类技术。概述解释清晰且详细。 | 提交的文档概述了少于 3 种算法及其分类技术,且概述既不清晰也不详细。 |
---
**免责声明**
本文档使用AI翻译服务[Co-op Translator](https://github.com/Azure/co-op-translator)进行翻译。尽管我们努力确保翻译的准确性,但请注意,自动翻译可能包含错误或不准确之处。应以原始语言的文档作为权威来源。对于关键信息,建议使用专业人工翻译。我们对因使用此翻译而产生的任何误解或误读不承担责任。

@ -0,0 +1,39 @@
{
"metadata": {
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": 3
},
"orig_nbformat": 2,
"coopTranslator": {
"original_hash": "d544ef384b7ba73757d830a72372a7f2",
"translation_date": "2025-09-03T20:33:39+00:00",
"source_file": "4-Classification/1-Introduction/notebook.ipynb",
"language_code": "zh"
}
},
"nbformat": 4,
"nbformat_minor": 2,
"cells": [
{
"source": [],
"cell_type": "markdown",
"metadata": {}
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**免责声明** \n本文档使用AI翻译服务 [Co-op Translator](https://github.com/Azure/co-op-translator) 进行翻译。尽管我们努力确保翻译的准确性,但请注意,自动翻译可能包含错误或不准确之处。原始语言的文档应被视为权威来源。对于关键信息,建议使用专业人工翻译。我们不对因使用此翻译而产生的任何误解或误读承担责任。\n"
]
}
]
}

@ -0,0 +1,6 @@
---
**免责声明**
本文档使用AI翻译服务 [Co-op Translator](https://github.com/Azure/co-op-translator) 进行翻译。尽管我们努力确保翻译的准确性,但请注意,自动翻译可能包含错误或不准确之处。应以原始语言的文档作为权威来源。对于重要信息,建议使用专业人工翻译。我们不对因使用此翻译而产生的任何误解或误读承担责任。

@ -0,0 +1,722 @@
{
"nbformat": 4,
"nbformat_minor": 2,
"metadata": {
"colab": {
"name": "lesson_10-R.ipynb",
"provenance": [],
"collapsed_sections": []
},
"kernelspec": {
"name": "ir",
"display_name": "R"
},
"language_info": {
"name": "R"
},
"coopTranslator": {
"original_hash": "2621e24705e8100893c9bf84e0fc8aef",
"translation_date": "2025-09-03T20:40:23+00:00",
"source_file": "4-Classification/1-Introduction/solution/R/lesson_10-R.ipynb",
"language_code": "zh"
}
},
"cells": [
{
"cell_type": "markdown",
"source": [
"# 构建分类模型:美味的亚洲和印度美食\n"
],
"metadata": {
"id": "ItETB4tSFprR"
}
},
{
"cell_type": "markdown",
"source": [
"## 分类简介:清理、准备和可视化数据\n",
"\n",
"在这四节课中,您将探索经典机器学习的一个核心主题——*分类*。我们将使用一个关于亚洲和印度美食的数据集,逐步学习各种分类算法的应用。希望您已经准备好大快朵颐!\n",
"\n",
"<p >\n",
" <img src=\"../../images/pinch.png\"\n",
" width=\"600\"/>\n",
" <figcaption>在这些课程中庆祝泛亚洲美食!图片由 Jen Looper 提供</figcaption>\n",
"\n",
"分类是一种[监督学习](https://wikipedia.org/wiki/Supervised_learning)形式,与回归技术有许多相似之处。在分类中,您训练一个模型来预测某个项目属于哪个`类别`。如果机器学习的核心是通过数据集预测事物的值或名称,那么分类通常分为两类:*二元分类*和*多类分类*。\n",
"\n",
"请记住:\n",
"\n",
"- **线性回归**帮助您预测变量之间的关系,并准确预测新数据点在该关系线上的位置。例如,您可以预测数值,比如*南瓜在九月和十二月的价格*。\n",
"\n",
"- **逻辑回归**帮助您发现“二元类别”:在这个价格点,*这个南瓜是橙色还是非橙色*\n",
"\n",
"分类使用各种算法来确定数据点的标签或类别。让我们使用这个美食数据集,看看通过观察一组食材,是否可以确定其美食的来源。\n",
"\n",
"### [**课前测验**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/19/)\n",
"\n",
"### **简介**\n",
"\n",
"分类是机器学习研究人员和数据科学家的基本活动之一。从简单的二元值分类(“这封邮件是垃圾邮件还是不是?”),到使用计算机视觉进行复杂的图像分类和分割,能够将数据分类并提出问题总是非常有用。\n",
"\n",
"用更科学的方式来说,您的分类方法会创建一个预测模型,使您能够将输入变量与输出变量之间的关系进行映射。\n",
"\n",
"<p >\n",
" <img src=\"../../images/binary-multiclass.png\"\n",
" width=\"600\"/>\n",
" <figcaption>分类算法处理二元问题与多类问题。信息图由 Jen Looper 提供</figcaption>\n",
"\n",
"在开始清理数据、可视化数据以及为机器学习任务准备数据之前,让我们先了解一下机器学习如何用于分类数据的各种方式。\n",
"\n",
"分类源自[统计学](https://wikipedia.org/wiki/Statistical_classification),使用经典机器学习进行分类时,会利用特征,例如`吸烟者`、`体重`和`年龄`,来确定*患某种疾病的可能性*。作为一种类似于您之前进行的回归练习的监督学习技术,您的数据是带标签的,机器学习算法使用这些标签来分类和预测数据集的类别(或“特征”),并将其分配到某个组或结果中。\n",
"\n",
"✅ 花点时间想象一个关于美食的数据集。多类模型可以回答什么问题?二元模型可以回答什么问题?如果您想确定某种美食是否可能使用葫芦巴怎么办?如果您想知道,假如收到一袋包含八角、洋蓟、花椰菜和辣根的杂货,是否可以制作一道典型的印度菜呢?\n",
"\n",
"### **你好,‘分类器’**\n",
"\n",
"我们想要从这个美食数据集中提出的问题实际上是一个**多类问题**,因为我们有多个潜在的国家美食类别可以选择。给定一组食材,这些数据会属于哪一个类别?\n",
"\n",
"Tidymodels 提供了几种不同的算法来分类数据,具体取决于您想解决的问题类型。在接下来的两节课中,您将学习其中几种算法。\n",
"\n",
"#### **前提条件**\n",
"\n",
"在本课程中,我们需要以下包来清理、准备和可视化数据:\n",
"\n",
"- `tidyverse` [tidyverse](https://www.tidyverse.org/) 是一个[集合的 R 包](https://www.tidyverse.org/packages),旨在让数据科学更快、更简单、更有趣!\n",
"\n",
"- `tidymodels` [tidymodels](https://www.tidymodels.org/) 框架是一个[建模和机器学习的包集合](https://www.tidymodels.org/packages/)。\n",
"\n",
"- `DataExplorer` [DataExplorer 包](https://cran.r-project.org/web/packages/DataExplorer/vignettes/dataexplorer-intro.html)旨在简化和自动化探索性数据分析过程和报告生成。\n",
"\n",
"- `themis` [themis 包](https://themis.tidymodels.org/)提供了处理不平衡数据的额外配方步骤。\n",
"\n",
"您可以通过以下方式安装它们:\n",
"\n",
"`install.packages(c(\"tidyverse\", \"tidymodels\", \"DataExplorer\", \"here\"))`\n",
"\n",
"或者,下面的脚本会检查您是否安装了完成本模块所需的包,并在缺少时为您安装。\n"
],
"metadata": {
"id": "ri5bQxZ-Fz_0"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"suppressWarnings(if (!require(\"pacman\"))install.packages(\"pacman\"))\r\n",
"\r\n",
"pacman::p_load(tidyverse, tidymodels, DataExplorer, themis, here)"
],
"outputs": [],
"metadata": {
"id": "KIPxa4elGAPI"
}
},
{
"cell_type": "markdown",
"source": [
"我们稍后会加载这些很棒的包,并使它们在我们当前的 R 会话中可用。(这只是为了说明,`pacman::p_load()` 已经为您完成了这一操作)\n"
],
"metadata": {
"id": "YkKAxOJvGD4C"
}
},
{
"cell_type": "markdown",
"source": [
"## 练习 - 清理并平衡数据\n",
"\n",
"在开始这个项目之前,首要任务是清理并**平衡**你的数据,以获得更好的结果。\n",
"\n",
"让我们来看看数据吧!🕵️\n"
],
"metadata": {
"id": "PFkQDlk0GN5O"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Import data\r\n",
"df <- read_csv(file = \"https://raw.githubusercontent.com/microsoft/ML-For-Beginners/main/4-Classification/data/cuisines.csv\")\r\n",
"\r\n",
"# View the first 5 rows\r\n",
"df %>% \r\n",
" slice_head(n = 5)\r\n"
],
"outputs": [],
"metadata": {
"id": "Qccw7okxGT0S"
}
},
{
"cell_type": "markdown",
"source": [
"有趣!从表面上看,第一列是一种`id`列。让我们获取一些关于数据的更多信息。\n"
],
"metadata": {
"id": "XrWnlgSrGVmR"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Basic information about the data\r\n",
"df %>%\r\n",
" introduce()\r\n",
"\r\n",
"# Visualize basic information above\r\n",
"df %>% \r\n",
" plot_intro(ggtheme = theme_light())"
],
"outputs": [],
"metadata": {
"id": "4UcGmxRxGieA"
}
},
{
"cell_type": "markdown",
"source": [
"从输出中我们可以直接看到,我们有 `2448` 行和 `385` 列,并且没有缺失值。此外,我们还有一个离散列,*cuisine*。\n",
"\n",
"## 练习 - 了解菜系\n",
"\n",
"现在工作开始变得更有趣了。让我们探索每种菜系的数据分布。\n"
],
"metadata": {
"id": "AaPubl__GmH5"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Count observations per cuisine\r\n",
"df %>% \r\n",
" count(cuisine) %>% \r\n",
" arrange(n)\r\n",
"\r\n",
"# Plot the distribution\r\n",
"theme_set(theme_light())\r\n",
"df %>% \r\n",
" count(cuisine) %>% \r\n",
" ggplot(mapping = aes(x = n, y = reorder(cuisine, -n))) +\r\n",
" geom_col(fill = \"midnightblue\", alpha = 0.7) +\r\n",
" ylab(\"cuisine\")"
],
"outputs": [],
"metadata": {
"id": "FRsBVy5eGrrv"
}
},
{
"cell_type": "markdown",
"source": [
"世界上的菜系种类有限,但数据分布却不均衡。你可以改变这一点!在此之前,先多探索一下吧。\n",
"\n",
"接下来,让我们将每种菜系分配到各自的 tibble 中,并找出每种菜系的数据量(行数和列数)。\n",
"\n",
"> [tibble](https://tibble.tidyverse.org/) 是一种现代化的数据框。\n",
"\n",
"<p >\n",
" <img src=\"../../images/dplyr_filter.jpg\"\n",
" width=\"600\"/>\n",
" <figcaption>由 @allison_horst 创作的艺术作品</figcaption>\n"
],
"metadata": {
"id": "vVvyDb1kG2in"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Create individual tibble for the cuisines\r\n",
"thai_df <- df %>% \r\n",
" filter(cuisine == \"thai\")\r\n",
"japanese_df <- df %>% \r\n",
" filter(cuisine == \"japanese\")\r\n",
"chinese_df <- df %>% \r\n",
" filter(cuisine == \"chinese\")\r\n",
"indian_df <- df %>% \r\n",
" filter(cuisine == \"indian\")\r\n",
"korean_df <- df %>% \r\n",
" filter(cuisine == \"korean\")\r\n",
"\r\n",
"\r\n",
"# Find out how much data is available per cuisine\r\n",
"cat(\" thai df:\", dim(thai_df), \"\\n\",\r\n",
" \"japanese df:\", dim(japanese_df), \"\\n\",\r\n",
" \"chinese_df:\", dim(chinese_df), \"\\n\",\r\n",
" \"indian_df:\", dim(indian_df), \"\\n\",\r\n",
" \"korean_df:\", dim(korean_df))"
],
"outputs": [],
"metadata": {
"id": "0TvXUxD3G8Bk"
}
},
{
"cell_type": "markdown",
"source": [
"## **练习 - 使用 dplyr 探索不同菜系的主要食材**\n",
"\n",
"现在你可以更深入地挖掘数据,了解每种菜系的典型食材。你需要清理一些会在菜系之间引起混淆的重复数据,所以让我们来学习如何解决这个问题。\n",
"\n",
"在 R 中创建一个名为 `create_ingredient()` 的函数,该函数返回一个食材数据框。这个函数将从删除一个无用的列开始,并根据食材的数量对其进行排序。\n",
"\n",
"R 中函数的基本结构如下:\n",
"\n",
"`myFunction <- function(arglist){`\n",
"\n",
"**`...`**\n",
"\n",
"**`return`**`(value)`\n",
"\n",
"`}`\n",
"\n",
"关于 R 函数的简洁介绍可以在[这里](https://skirmer.github.io/presentations/functions_with_r.html#1)找到。\n",
"\n",
"让我们直接开始吧!我们将使用之前课程中学习过的 [dplyr 动词](https://dplyr.tidyverse.org/)。回顾一下:\n",
"\n",
"- `dplyr::select()`:帮助你选择要保留或排除的**列**。\n",
"\n",
"- `dplyr::pivot_longer()`:帮助你“拉长”数据,增加行数并减少列数。\n",
"\n",
"- `dplyr::group_by()` 和 `dplyr::summarise()`:帮助你为不同组计算汇总统计数据,并将其整理成一个漂亮的表格。\n",
"\n",
"- `dplyr::filter()`:创建一个仅包含满足条件的行的数据子集。\n",
"\n",
"- `dplyr::mutate()`:帮助你创建或修改列。\n",
"\n",
"查看 Allison Horst 的这个充满[*艺术*](https://allisonhorst.shinyapps.io/dplyr-learnr/#section-welcome)的 learnr 教程,它介绍了一些 dplyrTidyverse 的一部分)中有用的数据整理函数。\n"
],
"metadata": {
"id": "K3RF5bSCHC76"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Creates a functions that returns the top ingredients by class\r\n",
"\r\n",
"create_ingredient <- function(df){\r\n",
" \r\n",
" # Drop the id column which is the first colum\r\n",
" ingredient_df = df %>% select(-1) %>% \r\n",
" # Transpose data to a long format\r\n",
" pivot_longer(!cuisine, names_to = \"ingredients\", values_to = \"count\") %>% \r\n",
" # Find the top most ingredients for a particular cuisine\r\n",
" group_by(ingredients) %>% \r\n",
" summarise(n_instances = sum(count)) %>% \r\n",
" filter(n_instances != 0) %>% \r\n",
" # Arrange by descending order\r\n",
" arrange(desc(n_instances)) %>% \r\n",
" mutate(ingredients = factor(ingredients) %>% fct_inorder())\r\n",
" \r\n",
" \r\n",
" return(ingredient_df)\r\n",
"} # End of function"
],
"outputs": [],
"metadata": {
"id": "uB_0JR82HTPa"
}
},
{
"cell_type": "markdown",
"source": [
"现在我们可以使用这个函数来了解每种菜系中最受欢迎的前十种食材。让我们用 `thai_df` 来试试吧。\n"
],
"metadata": {
"id": "h9794WF8HWmc"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Call create_ingredient and display popular ingredients\r\n",
"thai_ingredient_df <- create_ingredient(df = thai_df)\r\n",
"\r\n",
"thai_ingredient_df %>% \r\n",
" slice_head(n = 10)"
],
"outputs": [],
"metadata": {
"id": "agQ-1HrcHaEA"
}
},
{
"cell_type": "markdown",
"source": [
"在上一节中,我们使用了`geom_col()`,现在让我们看看如何使用`geom_bar`来创建条形图。使用`?geom_bar`了解更多信息。\n"
],
"metadata": {
"id": "kHu9ffGjHdcX"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Make a bar chart for popular thai cuisines\r\n",
"thai_ingredient_df %>% \r\n",
" slice_head(n = 10) %>% \r\n",
" ggplot(aes(x = n_instances, y = ingredients)) +\r\n",
" geom_bar(stat = \"identity\", width = 0.5, fill = \"steelblue\") +\r\n",
" xlab(\"\") + ylab(\"\")"
],
"outputs": [],
"metadata": {
"id": "fb3Bx_3DHj6e"
}
},
{
"cell_type": "markdown",
"source": [
"让我们对日语数据做同样的事情\n"
],
"metadata": {
"id": "RHP_xgdkHnvM"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Get popular ingredients for Japanese cuisines and make bar chart\r\n",
"create_ingredient(df = japanese_df) %>% \r\n",
" slice_head(n = 10) %>%\r\n",
" ggplot(aes(x = n_instances, y = ingredients)) +\r\n",
" geom_bar(stat = \"identity\", width = 0.5, fill = \"darkorange\", alpha = 0.8) +\r\n",
" xlab(\"\") + ylab(\"\")\r\n"
],
"outputs": [],
"metadata": {
"id": "019v8F0XHrRU"
}
},
{
"cell_type": "markdown",
"source": [
"关于中国菜肴呢?\n"
],
"metadata": {
"id": "iIGM7vO8Hu3v"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Get popular ingredients for Chinese cuisines and make bar chart\r\n",
"create_ingredient(df = chinese_df) %>% \r\n",
" slice_head(n = 10) %>%\r\n",
" ggplot(aes(x = n_instances, y = ingredients)) +\r\n",
" geom_bar(stat = \"identity\", width = 0.5, fill = \"cyan4\", alpha = 0.8) +\r\n",
" xlab(\"\") + ylab(\"\")"
],
"outputs": [],
"metadata": {
"id": "lHd9_gd2HyzU"
}
},
{
"cell_type": "markdown",
"source": [],
"metadata": {
"id": "ir8qyQbNH1c7"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Get popular ingredients for Indian cuisines and make bar chart\r\n",
"create_ingredient(df = indian_df) %>% \r\n",
" slice_head(n = 10) %>%\r\n",
" ggplot(aes(x = n_instances, y = ingredients)) +\r\n",
" geom_bar(stat = \"identity\", width = 0.5, fill = \"#041E42FF\", alpha = 0.8) +\r\n",
" xlab(\"\") + ylab(\"\")"
],
"outputs": [],
"metadata": {
"id": "ApukQtKjH5FO"
}
},
{
"cell_type": "markdown",
"source": [
"最后,绘制韩国食材。\n"
],
"metadata": {
"id": "qv30cwY1H-FM"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Get popular ingredients for Korean cuisines and make bar chart\r\n",
"create_ingredient(df = korean_df) %>% \r\n",
" slice_head(n = 10) %>%\r\n",
" ggplot(aes(x = n_instances, y = ingredients)) +\r\n",
" geom_bar(stat = \"identity\", width = 0.5, fill = \"#852419FF\", alpha = 0.8) +\r\n",
" xlab(\"\") + ylab(\"\")"
],
"outputs": [],
"metadata": {
"id": "lumgk9cHIBie"
}
},
{
"cell_type": "markdown",
"source": [
"从数据可视化中,我们现在可以使用 `dplyr::select()` 删除那些在不同菜系之间容易引起混淆的常见食材。\n",
"\n",
"大家都喜欢米饭、大蒜和姜!\n"
],
"metadata": {
"id": "iO4veMXuIEta"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Drop id column, rice, garlic and ginger from our original data set\r\n",
"df_select <- df %>% \r\n",
" select(-c(1, rice, garlic, ginger))\r\n",
"\r\n",
"# Display new data set\r\n",
"df_select %>% \r\n",
" slice_head(n = 5)"
],
"outputs": [],
"metadata": {
"id": "iHJPiG6rIUcK"
}
},
{
"cell_type": "markdown",
"source": [
"## 使用配方预处理数据 👩‍🍳👨‍🍳 - 处理数据不平衡 ⚖️\n",
"\n",
"<p >\n",
" <img src=\"../../images/recipes.png\"\n",
" width=\"600\"/>\n",
" <figcaption>图片由 @allison_horst 提供</figcaption>\n",
"\n",
"既然这节课是关于美食的,我们就需要将`recipes`放到具体的情境中。\n",
"\n",
"Tidymodels 提供了另一个非常实用的包:`recipes`——一个用于数据预处理的包。\n"
],
"metadata": {
"id": "kkFd-JxdIaL6"
}
},
{
"cell_type": "markdown",
"source": [
"让我们再来看看我们菜肴的分布情况。\n"
],
"metadata": {
"id": "6l2ubtTPJAhY"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Distribution of cuisines\r\n",
"old_label_count <- df_select %>% \r\n",
" count(cuisine) %>% \r\n",
" arrange(desc(n))\r\n",
"\r\n",
"old_label_count"
],
"outputs": [],
"metadata": {
"id": "1e-E9cb7JDVi"
}
},
{
"cell_type": "markdown",
"source": [
"如你所见,各种菜系的数量分布非常不均衡。韩国菜的数量几乎是泰国菜的三倍。不平衡的数据通常会对模型性能产生负面影响。想象一个二分类问题,如果你的数据大部分属于一个类别,机器学习模型可能会更频繁地预测这个类别,仅仅因为它的数据更多。平衡数据可以处理任何偏斜的数据,帮助消除这种不平衡。许多模型在观察数量相等时表现最佳,因此在处理不平衡数据时往往会遇到困难。\n",
"\n",
"处理不平衡数据集主要有两种方法:\n",
"\n",
"- 为少数类别添加观察值:`过采样`,例如使用 SMOTE 算法\n",
"\n",
"- 从多数类别中移除观察值:`欠采样`\n",
"\n",
"现在我们来演示如何使用一个`配方`来处理不平衡数据集。配方可以被看作是一个蓝图,描述了应该对数据集应用哪些步骤,以使其准备好进行数据分析。\n"
],
"metadata": {
"id": "soAw6826JKx9"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Load themis package for dealing with imbalanced data\r\n",
"library(themis)\r\n",
"\r\n",
"# Create a recipe for preprocessing data\r\n",
"cuisines_recipe <- recipe(cuisine ~ ., data = df_select) %>% \r\n",
" step_smote(cuisine)\r\n",
"\r\n",
"cuisines_recipe"
],
"outputs": [],
"metadata": {
"id": "HS41brUIJVJy"
}
},
{
"cell_type": "markdown",
"source": [
"让我们分解预处理步骤。\n",
"\n",
"- 使用公式调用 `recipe()` 告诉配方变量的*角色*,并以 `df_select` 数据作为参考。例如,`cuisine` 列被分配了 `outcome` 角色,而其他列则被分配了 `predictor` 角色。\n",
"\n",
"- [`step_smote(cuisine)`](https://themis.tidymodels.org/reference/step_smote.html) 创建了一个配方步骤的*规范*,通过使用这些案例的最近邻合成生成少数类的新样本。\n",
"\n",
"现在,如果我们想查看预处理后的数据,我们需要使用 [**`prep()`**](https://recipes.tidymodels.org/reference/prep.html) 和 [**`bake()`**](https://recipes.tidymodels.org/reference/bake.html) 来处理我们的配方。\n",
"\n",
"`prep()`:从训练集估算所需参数,这些参数可以稍后应用于其他数据集。\n",
"\n",
"`bake()`:将预处理过的配方应用于任何数据集。\n"
],
"metadata": {
"id": "Yb-7t7XcJaC8"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Prep and bake the recipe\r\n",
"preprocessed_df <- cuisines_recipe %>% \r\n",
" prep() %>% \r\n",
" bake(new_data = NULL) %>% \r\n",
" relocate(cuisine)\r\n",
"\r\n",
"# Display data\r\n",
"preprocessed_df %>% \r\n",
" slice_head(n = 5)\r\n",
"\r\n",
"# Quick summary stats\r\n",
"preprocessed_df %>% \r\n",
" introduce()"
],
"outputs": [],
"metadata": {
"id": "9QhSgdpxJl44"
}
},
{
"cell_type": "markdown",
"source": [
"现在让我们检查我们的菜系分布,并将其与不平衡数据进行比较。\n"
],
"metadata": {
"id": "dmidELh_LdV7"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Distribution of cuisines\r\n",
"new_label_count <- preprocessed_df %>% \r\n",
" count(cuisine) %>% \r\n",
" arrange(desc(n))\r\n",
"\r\n",
"list(new_label_count = new_label_count,\r\n",
" old_label_count = old_label_count)"
],
"outputs": [],
"metadata": {
"id": "aSh23klBLwDz"
}
},
{
"cell_type": "markdown",
"source": [
"嗯!数据干净整洁、平衡且非常棒,简直美味 😋!\n",
"\n",
"> 通常情况下配方recipe通常被用作建模的预处理器它定义了需要对数据集应用哪些步骤以使其为建模做好准备。在这种情况下通常会使用 `workflow()`(正如我们在之前的课程中已经看到的),而不是手动估算配方。\n",
">\n",
"> 因此,当你使用 tidymodels 时,通常不需要手动调用 **`prep()`** 和 **`bake()`** 来处理配方,但这些函数是非常有用的工具,可以用来确认配方是否按照你的预期运行,就像我们现在的情况一样。\n",
">\n",
"> 当你使用 **`new_data = NULL`** 来 **`bake()`** 一个已经预处理好的配方时,你会得到定义配方时提供的数据,但这些数据已经经过了预处理步骤。\n",
"\n",
"现在,让我们保存一份这个数据的副本,以便在后续课程中使用:\n"
],
"metadata": {
"id": "HEu80HZ8L7ae"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"# Save preprocessed data\r\n",
"write_csv(preprocessed_df, \"../../../data/cleaned_cuisines_R.csv\")"
],
"outputs": [],
"metadata": {
"id": "cBmCbIgrMOI6"
}
},
{
"cell_type": "markdown",
"source": [
"这个新的 CSV文件现在可以在根数据文件夹中找到。\n",
"\n",
"**🚀挑战**\n",
"\n",
"这个课程包含了几个有趣的数据集。浏览 `data` 文件夹,看看是否有适合二分类或多分类的数据集?你会对这个数据集提出哪些问题?\n",
"\n",
"## [**课后测验**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/20/)\n",
"\n",
"## **复习与自学**\n",
"\n",
"- 查看 [themis 包](https://github.com/tidymodels/themis)。我们还能使用哪些技术来处理数据不平衡问题?\n",
"\n",
"- Tidy models [参考网站](https://www.tidymodels.org/start/)。\n",
"\n",
"- H. Wickham 和 G. Grolemund, [*R for Data Science: 数据的可视化、建模、转换、整理和导入*](https://r4ds.had.co.nz/)。\n",
"\n",
"#### 感谢:\n",
"\n",
"[`Allison Horst`](https://twitter.com/allison_horst/) 创作了令人惊叹的插图,使 R 更加友好和吸引人。可以在她的 [画廊](https://www.google.com/url?q=https://github.com/allisonhorst/stats-illustrations&sa=D&source=editors&ust=1626380772530000&usg=AOvVaw3zcfyCizFQZpkSLzxiiQEM) 中找到更多插图。\n",
"\n",
"[Cassie Breviu](https://www.twitter.com/cassieview) 和 [Jen Looper](https://www.twitter.com/jenlooper) 创作了这个模块的原始 Python 版本 ♥️\n",
"\n",
"<p >\n",
" <img src=\"../../images/r_learners_sm.jpeg\"\n",
" width=\"600\"/>\n",
" <figcaption>插图作者 @allison_horst</figcaption>\n"
],
"metadata": {
"id": "WQs5621pMGwf"
}
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**免责声明** \n本文档使用AI翻译服务 [Co-op Translator](https://github.com/Azure/co-op-translator) 进行翻译。尽管我们努力确保翻译的准确性,但请注意,自动翻译可能包含错误或不准确之处。原始语言的文档应被视为权威来源。对于关键信息,建议使用专业人工翻译。我们不对因使用此翻译而产生的任何误解或误读承担责任。\n"
]
}
]
}

File diff suppressed because one or more lines are too long

@ -0,0 +1,244 @@
# 美食分类器 1
在本课中,您将使用上一课保存的数据集,该数据集包含关于美食的平衡且干净的数据。
您将使用这个数据集和多种分类器来_根据一组食材预测某种国家美食_。在此过程中您将进一步了解算法如何用于分类任务。
## [课前测验](https://ff-quizzes.netlify.app/en/ml/)
# 准备工作
假设您已完成[第1课](../1-Introduction/README.md),请确保在根目录的`/data`文件夹中存在一个名为_cleaned_cuisines.csv_的文件以供这四节课使用。
## 练习 - 预测国家美食
1. 在本课的_notebook.ipynb_文件夹中导入该文件以及Pandas库
```python
import pandas as pd
cuisines_df = pd.read_csv("../data/cleaned_cuisines.csv")
cuisines_df.head()
```
数据看起来如下:
| | Unnamed: 0 | cuisine | almond | angelica | anise | anise_seed | apple | apple_brandy | apricot | armagnac | ... | whiskey | white_bread | white_wine | whole_grain_wheat_flour | wine | wood | yam | yeast | yogurt | zucchini |
| --- | ---------- | ------- | ------ | -------- | ----- | ---------- | ----- | ------------ | ------- | -------- | --- | ------- | ----------- | ---------- | ----------------------- | ---- | ---- | --- | ----- | ------ | -------- |
| 0 | 0 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 1 | 1 | indian | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 2 | 2 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 3 | 3 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 4 | 4 | indian | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
1. 现在,导入更多的库:
```python
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.metrics import accuracy_score,precision_score,confusion_matrix,classification_report, precision_recall_curve
from sklearn.svm import SVC
import numpy as np
```
1. 将X和y坐标分成两个数据框用于训练。`cuisine`可以作为标签数据框:
```python
cuisines_label_df = cuisines_df['cuisine']
cuisines_label_df.head()
```
它看起来如下:
```output
0 indian
1 indian
2 indian
3 indian
4 indian
Name: cuisine, dtype: object
```
1. 使用`drop()`方法删除`Unnamed: 0`列和`cuisine`列,并将剩余的数据保存为可训练的特征:
```python
cuisines_feature_df = cuisines_df.drop(['Unnamed: 0', 'cuisine'], axis=1)
cuisines_feature_df.head()
```
您的特征看起来如下:
| | almond | angelica | anise | anise_seed | apple | apple_brandy | apricot | armagnac | artemisia | artichoke | ... | whiskey | white_bread | white_wine | whole_grain_wheat_flour | wine | wood | yam | yeast | yogurt | zucchini |
| ---: | -----: | -------: | ----: | ---------: | ----: | -----------: | ------: | -------: | --------: | --------: | ---: | ------: | ----------: | ---------: | ----------------------: | ---: | ---: | ---: | ----: | -----: | -------: |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 4 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
现在您可以开始训练模型了!
## 选择分类器
现在数据已经清理完毕并准备好训练,您需要决定使用哪种算法来完成任务。
Scikit-learn将分类归类为监督学习在这一类别中您会发现许多分类方法。[种类繁多](https://scikit-learn.org/stable/supervised_learning.html),初看可能会让人眼花缭乱。以下方法都包含分类技术:
- 线性模型
- 支持向量机
- 随机梯度下降
- 最近邻
- 高斯过程
- 决策树
- 集成方法(投票分类器)
- 多分类和多输出算法(多分类和多标签分类,多分类-多输出分类)
> 您也可以使用[神经网络进行数据分类](https://scikit-learn.org/stable/modules/neural_networks_supervised.html#classification),但这超出了本课的范围。
### 选择哪个分类器?
那么应该选择哪个分类器呢通常可以尝试多个分类器并寻找效果较好的结果。Scikit-learn提供了一个[并排比较](https://scikit-learn.org/stable/auto_examples/classification/plot_classifier_comparison.html)在一个创建的数据集上比较了KNeighbors、SVC两种方式、GaussianProcessClassifier、DecisionTreeClassifier、RandomForestClassifier、MLPClassifier、AdaBoostClassifier、GaussianNB和QuadraticDiscrinationAnalysis并以可视化方式展示结果
![分类器比较](../../../../4-Classification/2-Classifiers-1/images/comparison.png)
> 图表来自Scikit-learn文档
> AutoML可以通过在云端运行这些比较来轻松解决这个问题帮助您选择最适合数据的算法。试试[这里](https://docs.microsoft.com/learn/modules/automate-model-selection-with-azure-automl/?WT.mc_id=academic-77952-leestott)
### 更好的方法
比盲目猜测更好的方法是参考这个可下载的[机器学习备忘单](https://docs.microsoft.com/azure/machine-learning/algorithm-cheat-sheet?WT.mc_id=academic-77952-leestott)。在这里,我们发现对于我们的多分类问题,有一些选择:
![多分类问题备忘单](../../../../4-Classification/2-Classifiers-1/images/cheatsheet.png)
> 微软算法备忘单的一部分,详细说明了多分类选项
✅ 下载这个备忘单,打印出来,挂在墙上!
### 推理
让我们看看是否可以根据现有约束推理出不同的解决方法:
- **神经网络过于复杂**。考虑到我们的数据集虽然干净但规模较小,并且我们通过本地笔记本运行训练,神经网络对于这个任务来说过于复杂。
- **不使用二分类器**。我们不使用二分类器因此排除了一对多one-vs-all
- **决策树或逻辑回归可能有效**。决策树可能有效,或者逻辑回归适用于多分类数据。
- **多分类增强决策树解决不同问题**。多分类增强决策树最适合非参数任务,例如设计排名任务,因此对我们来说没有用。
### 使用Scikit-learn
我们将使用Scikit-learn来分析数据。然而在Scikit-learn中有许多方法可以使用逻辑回归。查看[可传递的参数](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html?highlight=logistic%20regressio#sklearn.linear_model.LogisticRegression)。
基本上有两个重要参数——`multi_class`和`solver`——需要指定当我们要求Scikit-learn执行逻辑回归时。`multi_class`值应用某种行为。`solver`值决定使用哪种算法。并非所有的`solver`都可以与所有的`multi_class`值配对。
根据文档,在多分类情况下,训练算法:
- **使用一对多OvR方案**,如果`multi_class`选项设置为`ovr`
- **使用交叉熵损失**,如果`multi_class`选项设置为`multinomial`。(目前`multinomial`选项仅支持lbfgssagsaganewton-cg求解器。
> 🎓 这里的“方案”可以是“ovr”一对多或“multinomial”。由于逻辑回归实际上是为支持二分类设计的这些方案使其能够更好地处理多分类任务。[来源](https://machinelearningmastery.com/one-vs-rest-and-one-vs-one-for-multi-class-classification/)
> 🎓 “求解器”定义为“用于优化问题的算法”。[来源](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html?highlight=logistic%20regressio#sklearn.linear_model.LogisticRegression)。
Scikit-learn提供了这个表格来解释求解器如何处理不同数据结构带来的挑战
![求解器](../../../../4-Classification/2-Classifiers-1/images/solvers.png)
## 练习 - 划分数据
我们可以专注于逻辑回归作为我们的第一次训练尝试,因为您在上一课中刚刚学习了它。
通过调用`train_test_split()`将数据划分为训练组和测试组:
```python
X_train, X_test, y_train, y_test = train_test_split(cuisines_feature_df, cuisines_label_df, test_size=0.3)
```
## 练习 - 应用逻辑回归
由于您使用的是多分类情况您需要选择使用什么_方案_以及设置什么_求解器_。使用LogisticRegression并设置多分类选项和**liblinear**求解器进行训练。
1. 创建一个逻辑回归multi_class设置为`ovr`solver设置为`liblinear`
```python
lr = LogisticRegression(multi_class='ovr',solver='liblinear')
model = lr.fit(X_train, np.ravel(y_train))
accuracy = model.score(X_test, y_test)
print ("Accuracy is {}".format(accuracy))
```
✅ 尝试使用其他求解器,例如默认设置的`lbfgs`
> 注意,在需要时可以使用 Pandas [`ravel`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.ravel.html) 函数来展平数据。
准确率超过 **80%**
1. 你可以通过测试一行数据(#50来查看此模型的实际效果
```python
print(f'ingredients: {X_test.iloc[50][X_test.iloc[50]!=0].keys()}')
print(f'cuisine: {y_test.iloc[50]}')
```
结果打印如下:
```output
ingredients: Index(['cilantro', 'onion', 'pea', 'potato', 'tomato', 'vegetable_oil'], dtype='object')
cuisine: indian
```
✅ 尝试不同的行号并检查结果
1. 更深入地分析,你可以检查此预测的准确性:
```python
test= X_test.iloc[50].values.reshape(-1, 1).T
proba = model.predict_proba(test)
classes = model.classes_
resultdf = pd.DataFrame(data=proba, columns=classes)
topPrediction = resultdf.T.sort_values(by=[0], ascending = [False])
topPrediction.head()
```
结果打印如下 - 印度菜是模型的最佳猜测,且概率较高:
| | 0 |
| -------: | -------: |
| indian | 0.715851 |
| chinese | 0.229475 |
| japanese | 0.029763 |
| korean | 0.017277 |
| thai | 0.007634 |
✅ 你能解释为什么模型非常确定这是印度菜吗?
1. 通过打印分类报告获取更多细节,就像你在回归课程中所做的一样:
```python
y_pred = model.predict(X_test)
print(classification_report(y_test,y_pred))
```
| | precision | recall | f1-score | support |
| ------------ | --------- | ------ | -------- | ------- |
| chinese | 0.73 | 0.71 | 0.72 | 229 |
| indian | 0.91 | 0.93 | 0.92 | 254 |
| japanese | 0.70 | 0.75 | 0.72 | 220 |
| korean | 0.86 | 0.76 | 0.81 | 242 |
| thai | 0.79 | 0.85 | 0.82 | 254 |
| accuracy | 0.80 | 1199 | | |
| macro avg | 0.80 | 0.80 | 0.80 | 1199 |
| weighted avg | 0.80 | 0.80 | 0.80 | 1199 |
## 🚀挑战
在本课中,你使用清理后的数据构建了一个机器学习模型,可以根据一系列食材预测国家菜系。花点时间阅读 Scikit-learn 提供的多种分类数据选项。深入了解“solver”的概念理解其背后的工作原理。
## [课后测验](https://ff-quizzes.netlify.app/en/ml/)
## 复习与自学
深入学习逻辑回归背后的数学原理:[这篇课件](https://people.eecs.berkeley.edu/~russell/classes/cs194/f11/lectures/CS194%20Fall%202011%20Lecture%2006.pdf)
## 作业
[研究 solvers](assignment.md)
---
**免责声明**
本文档使用AI翻译服务 [Co-op Translator](https://github.com/Azure/co-op-translator) 进行翻译。虽然我们尽力确保翻译的准确性,但请注意,自动翻译可能包含错误或不准确之处。原始语言的文档应被视为权威来源。对于重要信息,建议使用专业人工翻译。我们不对因使用此翻译而产生的任何误解或误读承担责任。

@ -0,0 +1,15 @@
# 研究求解器
## 说明
在本课中,你学习了将算法与机器学习过程相结合以创建准确模型的各种求解器。浏览课程中列出的求解器,并选择两个。在你自己的话中,比较和对比这两个求解器。它们解决什么样的问题?它们如何与各种数据结构协作?为什么你会选择其中一个而不是另一个?
## 评分标准
| 标准 | 卓越 | 合格 | 需要改进 |
| -------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------- | ---------------------------- |
| | 提交的 .doc 文件包含两段文字,每段分别对一个求解器进行深思熟虑的比较。 | 提交的 .doc 文件仅包含一段文字 | 作业未完成 |
---
**免责声明**
本文档使用AI翻译服务[Co-op Translator](https://github.com/Azure/co-op-translator)进行翻译。尽管我们努力确保翻译的准确性,但请注意,自动翻译可能包含错误或不准确之处。原始语言的文档应被视为权威来源。对于关键信息,建议使用专业人工翻译。我们不对因使用此翻译而产生的任何误解或误读承担责任。

@ -0,0 +1,41 @@
{
"metadata": {
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": 3
},
"orig_nbformat": 2,
"coopTranslator": {
"original_hash": "68829b06b4dcd512d3327849191f4d7f",
"translation_date": "2025-09-03T20:20:02+00:00",
"source_file": "4-Classification/2-Classifiers-1/notebook.ipynb",
"language_code": "zh"
}
},
"nbformat": 4,
"nbformat_minor": 2,
"cells": [
{
"source": [
"# 构建分类模型\n"
],
"cell_type": "markdown",
"metadata": {}
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**免责声明** \n本文档使用AI翻译服务 [Co-op Translator](https://github.com/Azure/co-op-translator) 进行翻译。尽管我们努力确保翻译的准确性,但请注意,自动翻译可能包含错误或不准确之处。原始语言的文档应被视为权威来源。对于关键信息,建议使用专业人工翻译。我们不对因使用此翻译而产生的任何误解或误读承担责任。\n"
]
}
]
}

@ -0,0 +1,6 @@
---
**免责声明**
本文档使用AI翻译服务 [Co-op Translator](https://github.com/Azure/co-op-translator) 进行翻译。尽管我们努力确保翻译的准确性,但请注意,自动翻译可能包含错误或不准确之处。原始语言的文档应被视为权威来源。对于关键信息,建议使用专业人工翻译。我们不对因使用此翻译而产生的任何误解或误读承担责任。

File diff suppressed because one or more lines are too long

@ -0,0 +1,281 @@
{
"cells": [
{
"source": [
"# 构建分类模型\n"
],
"cell_type": "markdown",
"metadata": {}
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" Unnamed: 0 cuisine almond angelica anise anise_seed apple \\\n",
"0 0 indian 0 0 0 0 0 \n",
"1 1 indian 1 0 0 0 0 \n",
"2 2 indian 0 0 0 0 0 \n",
"3 3 indian 0 0 0 0 0 \n",
"4 4 indian 0 0 0 0 0 \n",
"\n",
" apple_brandy apricot armagnac ... whiskey white_bread white_wine \\\n",
"0 0 0 0 ... 0 0 0 \n",
"1 0 0 0 ... 0 0 0 \n",
"2 0 0 0 ... 0 0 0 \n",
"3 0 0 0 ... 0 0 0 \n",
"4 0 0 0 ... 0 0 0 \n",
"\n",
" whole_grain_wheat_flour wine wood yam yeast yogurt zucchini \n",
"0 0 0 0 0 0 0 0 \n",
"1 0 0 0 0 0 0 0 \n",
"2 0 0 0 0 0 0 0 \n",
"3 0 0 0 0 0 0 0 \n",
"4 0 0 0 0 0 1 0 \n",
"\n",
"[5 rows x 382 columns]"
],
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>Unnamed: 0</th>\n <th>cuisine</th>\n <th>almond</th>\n <th>angelica</th>\n <th>anise</th>\n <th>anise_seed</th>\n <th>apple</th>\n <th>apple_brandy</th>\n <th>apricot</th>\n <th>armagnac</th>\n <th>...</th>\n <th>whiskey</th>\n <th>white_bread</th>\n <th>white_wine</th>\n <th>whole_grain_wheat_flour</th>\n <th>wine</th>\n <th>wood</th>\n <th>yam</th>\n <th>yeast</th>\n <th>yogurt</th>\n <th>zucchini</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n <td>0</td>\n <td>indian</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>1</th>\n <td>1</td>\n <td>indian</td>\n <td>1</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>2</th>\n <td>2</td>\n <td>indian</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>3</th>\n <td>3</td>\n <td>indian</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>4</th>\n <td>4</td>\n <td>indian</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>1</td>\n <td>0</td>\n </tr>\n </tbody>\n</table>\n<p>5 rows × 382 columns</p>\n</div>"
},
"metadata": {},
"execution_count": 1
}
],
"source": [
"import pandas as pd\n",
"cuisines_df = pd.read_csv(\"../../data/cleaned_cuisines.csv\")\n",
"cuisines_df.head()"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"from sklearn.linear_model import LogisticRegression\n",
"from sklearn.model_selection import train_test_split, cross_val_score\n",
"from sklearn.metrics import accuracy_score,precision_score,confusion_matrix,classification_report, precision_recall_curve\n",
"from sklearn.svm import SVC\n",
"import numpy as np"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"0 indian\n",
"1 indian\n",
"2 indian\n",
"3 indian\n",
"4 indian\n",
"Name: cuisine, dtype: object"
]
},
"metadata": {},
"execution_count": 3
}
],
"source": [
"cuisines_label_df = cuisines_df['cuisine']\n",
"cuisines_label_df.head()"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" almond angelica anise anise_seed apple apple_brandy apricot \\\n",
"0 0 0 0 0 0 0 0 \n",
"1 1 0 0 0 0 0 0 \n",
"2 0 0 0 0 0 0 0 \n",
"3 0 0 0 0 0 0 0 \n",
"4 0 0 0 0 0 0 0 \n",
"\n",
" armagnac artemisia artichoke ... whiskey white_bread white_wine \\\n",
"0 0 0 0 ... 0 0 0 \n",
"1 0 0 0 ... 0 0 0 \n",
"2 0 0 0 ... 0 0 0 \n",
"3 0 0 0 ... 0 0 0 \n",
"4 0 0 0 ... 0 0 0 \n",
"\n",
" whole_grain_wheat_flour wine wood yam yeast yogurt zucchini \n",
"0 0 0 0 0 0 0 0 \n",
"1 0 0 0 0 0 0 0 \n",
"2 0 0 0 0 0 0 0 \n",
"3 0 0 0 0 0 0 0 \n",
"4 0 0 0 0 0 1 0 \n",
"\n",
"[5 rows x 380 columns]"
],
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>almond</th>\n <th>angelica</th>\n <th>anise</th>\n <th>anise_seed</th>\n <th>apple</th>\n <th>apple_brandy</th>\n <th>apricot</th>\n <th>armagnac</th>\n <th>artemisia</th>\n <th>artichoke</th>\n <th>...</th>\n <th>whiskey</th>\n <th>white_bread</th>\n <th>white_wine</th>\n <th>whole_grain_wheat_flour</th>\n <th>wine</th>\n <th>wood</th>\n <th>yam</th>\n <th>yeast</th>\n <th>yogurt</th>\n <th>zucchini</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>0</th>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>1</th>\n <td>1</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>2</th>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>3</th>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n </tr>\n <tr>\n <th>4</th>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>...</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>0</td>\n <td>1</td>\n <td>0</td>\n </tr>\n </tbody>\n</table>\n<p>5 rows × 380 columns</p>\n</div>"
},
"metadata": {},
"execution_count": 4
}
],
"source": [
"cuisines_feature_df = cuisines_df.drop(['Unnamed: 0', 'cuisine'], axis=1)\n",
"cuisines_feature_df.head()"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"X_train, X_test, y_train, y_test = train_test_split(cuisines_feature_df, cuisines_label_df, test_size=0.3)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Accuracy is 0.8181818181818182\n"
]
}
],
"source": [
"lr = LogisticRegression(multi_class='ovr',solver='liblinear')\n",
"model = lr.fit(X_train, np.ravel(y_train))\n",
"\n",
"accuracy = model.score(X_test, y_test)\n",
"print (\"Accuracy is {}\".format(accuracy))"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"ingredients: Index(['artemisia', 'black_pepper', 'mushroom', 'shiitake', 'soy_sauce',\n 'vegetable_oil'],\n dtype='object')\ncuisine: korean\n"
]
}
],
"source": [
"# test an item\n",
"print(f'ingredients: {X_test.iloc[50][X_test.iloc[50]!=0].keys()}')\n",
"print(f'cuisine: {y_test.iloc[50]}')"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
" 0\n",
"korean 0.392231\n",
"chinese 0.372872\n",
"japanese 0.218825\n",
"thai 0.013427\n",
"indian 0.002645"
],
"text/html": "<div>\n<style scoped>\n .dataframe tbody tr th:only-of-type {\n vertical-align: middle;\n }\n\n .dataframe tbody tr th {\n vertical-align: top;\n }\n\n .dataframe thead th {\n text-align: right;\n }\n</style>\n<table border=\"1\" class=\"dataframe\">\n <thead>\n <tr style=\"text-align: right;\">\n <th></th>\n <th>0</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <th>korean</th>\n <td>0.392231</td>\n </tr>\n <tr>\n <th>chinese</th>\n <td>0.372872</td>\n </tr>\n <tr>\n <th>japanese</th>\n <td>0.218825</td>\n </tr>\n <tr>\n <th>thai</th>\n <td>0.013427</td>\n </tr>\n <tr>\n <th>indian</th>\n <td>0.002645</td>\n </tr>\n </tbody>\n</table>\n</div>"
},
"metadata": {},
"execution_count": 8
}
],
"source": [
"#rehsape to 2d array and transpose\n",
"test= X_test.iloc[50].values.reshape(-1, 1).T\n",
"# predict with score\n",
"proba = model.predict_proba(test)\n",
"classes = model.classes_\n",
"# create df with classes and scores\n",
"resultdf = pd.DataFrame(data=proba, columns=classes)\n",
"\n",
"# create df to show results\n",
"topPrediction = resultdf.T.sort_values(by=[0], ascending = [False])\n",
"topPrediction.head()"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
" precision recall f1-score support\n\n chinese 0.75 0.73 0.74 223\n indian 0.93 0.88 0.90 255\n japanese 0.78 0.78 0.78 253\n korean 0.87 0.86 0.86 236\n thai 0.76 0.84 0.80 232\n\n accuracy 0.82 1199\n macro avg 0.82 0.82 0.82 1199\nweighted avg 0.82 0.82 0.82 1199\n\n"
]
}
],
"source": [
"y_pred = model.predict(X_test)\r\n",
"print(classification_report(y_test,y_pred))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**免责声明** \n本文档使用AI翻译服务 [Co-op Translator](https://github.com/Azure/co-op-translator) 进行翻译。尽管我们努力确保翻译的准确性,但请注意,自动翻译可能包含错误或不准确之处。应以原始语言的文档作为权威来源。对于关键信息,建议使用专业人工翻译。我们不对因使用此翻译而产生的任何误解或误读承担责任。\n"
]
}
],
"metadata": {
"interpreter": {
"hash": "70b38d7a306a849643e446cd70466270a13445e5987dfa1344ef2b127438fa4d"
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3.7.0 64-bit ('3.7')"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.0"
},
"metadata": {
"interpreter": {
"hash": "70b38d7a306a849643e446cd70466270a13445e5987dfa1344ef2b127438fa4d"
}
},
"coopTranslator": {
"original_hash": "9408506dd864f2b6e334c62f80c0cfcc",
"translation_date": "2025-09-03T20:20:25+00:00",
"source_file": "4-Classification/2-Classifiers-1/solution/notebook.ipynb",
"language_code": "zh"
}
},
"nbformat": 4,
"nbformat_minor": 4
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save