├── .gitignore ├── LICENSE ├── README.md ├── code ├── Untitled2 (1).ipynb ├── cloud │ ├── kaggle_event │ │ ├── Kaggle event recommendation competition.ipynb │ │ └── Kaggle event推荐比赛思路.pdf │ ├── spark隐语义模型推荐 │ │ └── Movie_Recommendation_using_pyspark.py │ ├── zhaopin_demo.ipynb │ ├── zhilian_eda.ipynb │ └── 协同过滤案例 │ │ ├── collaborative_filtering.ipynb │ │ ├── data.rar │ │ ├── main.py │ │ └── predict.py ├── credit │ ├── task.ipynb │ ├── task3.ipynb │ └── task4.ipynb ├── decision_tree │ ├── DecisionTree.csv │ ├── decision_tree_demo.py │ └── decision_tree_iris.py ├── demo │ ├── iris_demo.md │ ├── pandas_demo.ipynb │ ├── train.csv │ └── 泰坦尼克号之灾.ipynb ├── desc.py ├── first_ml_project │ ├── dataset │ │ └── housing.csv │ └── house_prices_predict.ipynb ├── iris.py ├── keras │ ├── cnn_mnist.py │ ├── k_mnist.py │ ├── lr.py │ ├── lstm_regression.py │ ├── mymodel.h5 │ ├── rnn_mnist.py │ └── save_model.py ├── kesci_bank_precision │ ├── bank_predict.ipynb │ └── dataset │ │ ├── test_set.csv │ │ └── train_set.csv ├── knn │ ├── readme.md │ └── simpleKnn.py ├── lihongyi │ ├── homework1 │ │ ├── data │ │ │ ├── Homework1_introduction.txt │ │ │ ├── answer.csv │ │ │ ├── sampleSubmission.csv │ │ │ ├── test.csv │ │ │ └── train.csv │ │ └── task3.py │ ├── task1.py │ ├── task2.py │ ├── task6.py │ ├── task6_data.txt │ ├── task7.py │ ├── task8.py │ ├── task9.py │ └── watermelon_3a.csv ├── linear_regression │ ├── linear_regession_simple.py │ ├── linear_regression_multi.py │ ├── linear_regression_polynomial.py │ ├── m_lr.py │ └── sgd_regression.py ├── logistic_regression │ ├── data1.txt │ ├── data2.txt │ ├── logistic_regression_regularization.py │ └── logistic_regression_simple.py ├── mat.py ├── mnlp.py ├── nlp │ ├── demo.ipynb │ └── senti_analysis │ │ ├── data │ │ ├── 2000_neg.txt │ │ ├── 2000_pos.txt │ │ ├── BosonNLP_sentiment_score.txt │ │ ├── adverb_dict.txt │ │ ├── license.txt │ │ ├── not.txt │ │ ├── readme.txt │ │ └── stopwords.txt │ │ ├── sentiment.py │ │ └── sentiment_ml.py ├── pre.py ├── sentiment_analysis │ ├── demo.ipynb │ ├── sample_submission.csv │ ├── stopwords.txt │ ├── test_data.csv │ └── train_data.csv ├── test1.ipynb ├── test2.ipynb └── tf │ ├── imdb_demo.py │ └── mnist.py ├── images ├── 1.jpg ├── 1.png ├── 1.webp ├── 2.png ├── 2.webp ├── 3.png ├── 4.png ├── 5.png ├── drop_shadows_background.png ├── e1.png ├── e2.png ├── e3.png ├── e4.png ├── e5.png ├── e6.png ├── eucl_dist.png ├── knn.png └── net.png ├── notes ├── AndrewNg │ ├── K-均值.md │ ├── PCA.md │ ├── images │ │ ├── 1.png │ │ ├── 10.jpg │ │ ├── 10.png │ │ ├── 11.jpg │ │ ├── 11.png │ │ ├── 12.jpg │ │ ├── 12.png │ │ ├── 13.jpg │ │ ├── 13.png │ │ ├── 14.jpg │ │ ├── 14.png │ │ ├── 15.jpg │ │ ├── 15.png │ │ ├── 16.jpg │ │ ├── 16.png │ │ ├── 17.jpg │ │ ├── 17.png │ │ ├── 18.jpg │ │ ├── 18.png │ │ ├── 19.jpg │ │ ├── 19.png │ │ ├── 2.png │ │ ├── 20.jpg │ │ ├── 20.png │ │ ├── 21.jpg │ │ ├── 22.jpg │ │ ├── 23.jpg │ │ ├── 3.png │ │ ├── 4.png │ │ ├── 5.png │ │ ├── 6.png │ │ ├── 7.png │ │ ├── 8.png │ │ ├── 9.jpg │ │ └── 9.png │ ├── readme.md │ ├── 反向传播.md │ ├── 应用机器学习的建议.md │ ├── 推荐系统.md │ ├── 支持向量机.md │ ├── 机器学习系统设计.md │ ├── 正则化.md │ ├── 神经网络概述.md │ ├── 线性判别分析LDA.md │ ├── 线性回归.md │ └── 逻辑回归.md ├── Python机器学习.md ├── cs224n(2017) │ └── readme.md ├── latex.md ├── lihongyi │ ├── README.md │ ├── day1-3.md │ ├── day11-13.md │ ├── day14-16.md │ ├── day20-22.md │ ├── day23-26.md │ ├── day30-33.md │ ├── day4-7.md │ ├── images │ │ ├── 1.jpg │ │ ├── 1.png │ │ ├── 10.png │ │ ├── 2.jpg │ │ ├── 2.png │ │ ├── 3.png │ │ ├── 4.png │ │ ├── 5.png │ │ ├── 6.png │ │ ├── 7.png │ │ ├── 8.png │ │ └── 9.png │ └── 相关文章收藏.md ├── nlp │ ├── day1-3.md │ ├── day4-5.md │ ├── day6-7.md │ ├── day8.md │ ├── images │ │ ├── 1.jpg │ │ ├── 1.png │ │ ├── 2.jpg │ │ ├── 2.png │ │ ├── 3.png │ │ ├── 4.png │ │ ├── 5.png │ │ └── 6.png │ └── readme.md ├── questions │ ├── 1.缺失值处理.md │ └── 2.完整机器学习项目流程.md ├── tf-idf.md ├── 情感分析.md ├── 无量纲处理.md ├── 机器学习之损失.md ├── 机器学习相关算法.md ├── 模型融合.md ├── 特征工程.md ├── 知识图谱.md ├── 算法应用步骤.md ├── 自然语言处理.md └── 问答系统.md └── 工具.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | .pytest_cache/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | local_settings.py 57 | db.sqlite3 58 | 59 | # Flask stuff: 60 | instance/ 61 | .webassets-cache 62 | 63 | # Scrapy stuff: 64 | .scrapy 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | 69 | # PyBuilder 70 | target/ 71 | 72 | # Jupyter Notebook 73 | .ipynb_checkpoints 74 | 75 | # pyenv 76 | .python-version 77 | 78 | # celery beat schedule file 79 | celerybeat-schedule 80 | 81 | # SageMath parsed files 82 | *.sage.py 83 | 84 | # Environments 85 | .env 86 | .venv 87 | env/ 88 | venv/ 89 | ENV/ 90 | env.bak/ 91 | venv.bak/ 92 | 93 | # Spyder project settings 94 | .spyderproject 95 | .spyproject 96 | 97 | # Rope project settings 98 | .ropeproject 99 | 100 | # mkdocs documentation 101 | /site 102 | 103 | # mypy 104 | .mypy_cache/ 105 | .idea/ 106 | tests/ 107 | other/ 108 | imdb.npz 109 | imdb_word_index.json 110 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 MenQi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 机器学习笔记 2 | Python拥有大量的数据分析、统计和机器学习库,使其成为许多数据科学家的首选语言。 3 | 4 | 以下是基于Python的机器学习总结,包括一些广泛使用的机器学习方法和工具。 5 | 6 | **注:该项目所有的代码实现基于python3,文章中数学公式要在github上正常显示,需安装 chrome插件 [mathjax plugin for github]() 或者clone后离线使用markdown编辑器阅读。** 7 | 8 | ## 机器学习方法 9 | 10 | [从零开始掌握Python机器学习]() 11 | 12 | [机器学习相关算法]() 13 | 14 | [机器学习应用实现步骤](https://github.com/CrazyXiao/machine-learning/blob/master/notes/算法应用步骤.md) 15 | 16 | [特征工程](https://github.com/CrazyXiao/machine-learning/blob/master/notes/特征工程.md) 17 | 18 | [自然语言处理](https://github.com/CrazyXiao/machine-learning/blob/master/notes/自然语言处理.md) 19 | 20 | ## 笔记 21 | 22 | [吴恩达老师的机器学习课程个人笔记及python实现](https://github.com/CrazyXiao/machine-learning/tree/master/notes/AndrewNg) 23 | 24 | **[李宏毅机器学习任务30天]()** 25 | 26 | [NLP理论实践18天]() 27 | 28 | 机器学习实战 29 | 30 | 《统计学习方法》算法实现 31 | 32 | ## 实战 33 | 34 | [完整的入门级机器学习项目]() 35 | 36 | [练习项目之银行精准营销]() 37 | 38 | [特征工程及数据挖掘实战之信用卡逾期预测]() 39 | 40 | 简单的聊天机器人实现 41 | 42 | ## 基础 43 | 44 | - [pandas数据处理](../master/code/demo/pandas_demo.ipynb) 45 | - [seaborn绘图]() 46 | 47 | ## 入门 48 | 49 | | 知识 | 实现 | 50 | | :----------------------------------------------------------: | ------------------------------------------------------------ | 51 | | [线性回归(Linear Regression)](<../master/notes/AndrewNg/线性回归.md>) | [代码](<../master/code/linear_regression>) | 52 | | [逻辑回归(Logistic Regression)](<../master/notes/AndrewNg/逻辑回归.md>) | [代码](<../master/code/logistic_regression>) | 53 | | [正则化(Regularization)](<../master/notes/AndrewNg/正则化.md>) | [代码](<../master/code/logistic_regression/logistic_regression_regularization.py>) | 54 | | [决策树(Decision Tree)](https://github.com/CrazyXiao/machine-learning/blob/master/notes/lihongyi/day20-22.md) | [代码](<../master/code/decision_tree>) | 55 | | [K近邻(k-Nearest Neighbour)](<../master/code/knn>) | [代码](<../master/code/knn/simpleKnn.py>) | 56 | 57 | ------ 58 | 59 | #### 持续更新中... 60 | 61 | -------------------------------------------------------------------------------- /code/cloud/kaggle_event/Kaggle event推荐比赛思路.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/code/cloud/kaggle_event/Kaggle event推荐比赛思路.pdf -------------------------------------------------------------------------------- /code/cloud/spark隐语义模型推荐/Movie_Recommendation_using_pyspark.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 基于spark中ALS的推荐系统,针对movielens中电影打分数据做推荐 3 | # Edit:寒小阳(hanxiaoyang.ml@gmail.com) 4 | 5 | import sys 6 | import itertools 7 | from math import sqrt 8 | from operator import add 9 | from os.path import join, isfile, dirname 10 | 11 | from pyspark import SparkConf, SparkContext 12 | from pyspark.mllib.recommendation import ALS 13 | 14 | def parseRating(line): 15 | """ 16 | MovieLens的打分格式是userId::movieId::rating::timestamp 17 | 我们对格式做一个解析 18 | """ 19 | fields = line.strip().split("::") 20 | return long(fields[3]) % 10, (int(fields[0]), int(fields[1]), float(fields[2])) 21 | 22 | def parseMovie(line): 23 | """ 24 | 对应的电影文件的格式为movieId::movieTitle 25 | 解析成int id, 文本 26 | """ 27 | fields = line.strip().split("::") 28 | return int(fields[0]), fields[1] 29 | 30 | def loadRatings(ratingsFile): 31 | """ 32 | 载入得分 33 | """ 34 | if not isfile(ratingsFile): 35 | print "File %s does not exist." % ratingsFile 36 | sys.exit(1) 37 | f = open(ratingsFile, 'r') 38 | ratings = filter(lambda r: r[2] > 0, [parseRating(line)[1] for line in f]) 39 | f.close() 40 | if not ratings: 41 | print "No ratings provided." 42 | sys.exit(1) 43 | else: 44 | return ratings 45 | 46 | def computeRmse(model, data, n): 47 | """ 48 | 评估的时候要用的,计算均方根误差 49 | """ 50 | predictions = model.predictAll(data.map(lambda x: (x[0], x[1]))) 51 | predictionsAndRatings = predictions.map(lambda x: ((x[0], x[1]), x[2])) \ 52 | .join(data.map(lambda x: ((x[0], x[1]), x[2]))) \ 53 | .values() 54 | return sqrt(predictionsAndRatings.map(lambda x: (x[0] - x[1]) ** 2).reduce(add) / float(n)) 55 | 56 | if __name__ == "__main__": 57 | if (len(sys.argv) != 3): 58 | print "Usage: /path/to/spark/bin/spark-submit --driver-memory 2g " + \ 59 | "MovieLensALS.py movieLensDataDir personalRatingsFile" 60 | sys.exit(1) 61 | 62 | # 设定环境 63 | conf = SparkConf() \ 64 | .setAppName("MovieLensALS") \ 65 | .set("spark.executor.memory", "2g") 66 | sc = SparkContext(conf=conf) 67 | 68 | # 载入打分数据 69 | myRatings = loadRatings(sys.argv[2]) 70 | myRatingsRDD = sc.parallelize(myRatings, 1) 71 | 72 | movieLensHomeDir = sys.argv[1] 73 | 74 | # 得到的ratings为(时间戳最后一位整数, (userId, movieId, rating))格式的RDD 75 | ratings = sc.textFile(join(movieLensHomeDir, "ratings.dat")).map(parseRating) 76 | 77 | # 得到的movies为(movieId, movieTitle)格式的RDD 78 | movies = dict(sc.textFile(join(movieLensHomeDir, "movies.dat")).map(parseMovie).collect()) 79 | 80 | numRatings = ratings.count() 81 | numUsers = ratings.values().map(lambda r: r[0]).distinct().count() 82 | numMovies = ratings.values().map(lambda r: r[1]).distinct().count() 83 | 84 | print "Got %d ratings from %d users on %d movies." % (numRatings, numUsers, numMovies) 85 | 86 | # 根据时间戳最后一位把整个数据集分成训练集(60%), 交叉验证集(20%), 和评估集(20%) 87 | 88 | # 训练, 交叉验证, 测试 集都是(userId, movieId, rating)格式的RDD 89 | 90 | numPartitions = 4 91 | training = ratings.filter(lambda x: x[0] < 6) \ 92 | .values() \ 93 | .union(myRatingsRDD) \ 94 | .repartition(numPartitions) \ 95 | .cache() 96 | 97 | validation = ratings.filter(lambda x: x[0] >= 6 and x[0] < 8) \ 98 | .values() \ 99 | .repartition(numPartitions) \ 100 | .cache() 101 | 102 | test = ratings.filter(lambda x: x[0] >= 8).values().cache() 103 | 104 | numTraining = training.count() 105 | numValidation = validation.count() 106 | numTest = test.count() 107 | 108 | print "Training: %d, validation: %d, test: %d" % (numTraining, numValidation, numTest) 109 | 110 | # 训练模型,在交叉验证集上看效果 111 | 112 | ranks = [8, 12] 113 | lambdas = [0.1, 10.0] 114 | numIters = [10, 20] 115 | bestModel = None 116 | bestValidationRmse = float("inf") 117 | bestRank = 0 118 | bestLambda = -1.0 119 | bestNumIter = -1 120 | 121 | for rank, lmbda, numIter in itertools.product(ranks, lambdas, numIters): 122 | model = ALS.train(training, rank, numIter, lmbda) 123 | validationRmse = computeRmse(model, validation, numValidation) 124 | print "RMSE (validation) = %f for the model trained with " % validationRmse + \ 125 | "rank = %d, lambda = %.1f, and numIter = %d." % (rank, lmbda, numIter) 126 | if (validationRmse < bestValidationRmse): 127 | bestModel = model 128 | bestValidationRmse = validationRmse 129 | bestRank = rank 130 | bestLambda = lmbda 131 | bestNumIter = numIter 132 | 133 | testRmse = computeRmse(bestModel, test, numTest) 134 | 135 | # 在测试集上评估 交叉验证集上最好的模型 136 | print "The best model was trained with rank = %d and lambda = %.1f, " % (bestRank, bestLambda) \ 137 | + "and numIter = %d, and its RMSE on the test set is %f." % (bestNumIter, testRmse) 138 | 139 | # 我们把基线模型设定为每次都返回平均得分的模型 140 | meanRating = training.union(validation).map(lambda x: x[2]).mean() 141 | baselineRmse = sqrt(test.map(lambda x: (meanRating - x[2]) ** 2).reduce(add) / numTest) 142 | improvement = (baselineRmse - testRmse) / baselineRmse * 100 143 | print "The best model improves the baseline by %.2f" % (improvement) + "%." 144 | 145 | # 个性化的推荐(针对某个用户) 146 | 147 | myRatedMovieIds = set([x[1] for x in myRatings]) 148 | candidates = sc.parallelize([m for m in movies if m not in myRatedMovieIds]) 149 | predictions = bestModel.predictAll(candidates.map(lambda x: (0, x))).collect() 150 | recommendations = sorted(predictions, key=lambda x: x[2], reverse=True)[:50] 151 | 152 | print "Movies recommended for you:" 153 | for i in xrange(len(recommendations)): 154 | print ("%2d: %s" % (i + 1, movies[recommendations[i][1]])).encode('ascii', 'ignore') 155 | 156 | # clean up 157 | sc.stop() 158 | -------------------------------------------------------------------------------- /code/cloud/协同过滤案例/data.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/code/cloud/协同过滤案例/data.rar -------------------------------------------------------------------------------- /code/cloud/协同过滤案例/main.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | import numpy as np 3 | import var 4 | import predict as pre 5 | import utils 6 | 7 | print('初始化变量...') 8 | names = ['user_id', 'item_id', 'rating', 'timestamp'] 9 | direct = 'dataset/ml-100k/' 10 | trainingset_files = (direct + name for name in ('u1.base', 'u2.base', 'u3.base', 'u4.base', 'u5.base')) 11 | testset_files = (direct + name for name in ('u1.test', 'u2.test', 'u3.test', 'u4.test', 'u5.test')) 12 | 13 | if __name__ == '__main__': 14 | 15 | rmse_baseline = [] 16 | rmse_itemCF = [] 17 | rmse_userCF = [] 18 | rmse_itemCF_baseline = [] 19 | rmse_userCF_baseline = [] 20 | rmse_itemCF_bias = [] 21 | rmse_topkCF_item = [] 22 | rmse_topkCF_user = [] 23 | rmse_normCF_item = [] 24 | rmse_normCF_user = [] 25 | rmse_blend = [] 26 | i = 0 27 | nums = 5 28 | for trainingset_file, testset_file in zip(trainingset_files, testset_files): 29 | i += 1 30 | print('------ 第%d/%d组样本 ------' % (i, nums)) 31 | df = pd.read_csv(trainingset_file, sep='\t', names=names) 32 | 33 | var.ratings = np.zeros((var.n_users, var.n_items)) 34 | print('载入训练集' + trainingset_file) 35 | for row in df.itertuples(): 36 | var.ratings[row[1]-1, row[2]-1] = row[3] 37 | 38 | print('训练集规模为 %d' % len(df)) 39 | 40 | sparsity = utils.cal_sparsity() 41 | print('训练集矩阵密度为 {:4.2f}%'.format(sparsity)) 42 | 43 | print('计算训练集各项统计数据...') 44 | utils.cal_mean() 45 | 46 | print('计算相似度矩阵...') 47 | var.user_similarity = utils.cal_similarity(kind='user') 48 | var.item_similarity = utils.cal_similarity(kind='item') 49 | var.user_similarity_norm = utils.cal_similarity_norm(kind='user') 50 | var.item_similarity_norm = utils.cal_similarity_norm(kind='item') 51 | print('计算完成') 52 | 53 | print('载入测试集' + testset_file) 54 | test_df = pd.read_csv(testset_file, sep='\t', names=names) 55 | predictions_baseline = [] 56 | predictions_itemCF = [] 57 | predictions_userCF = [] 58 | predictions_itemCF_baseline = [] 59 | predictions_userCF_baseline = [] 60 | predictions_itemCF_bias = [] 61 | predictions_topkCF_item = [] 62 | predictions_topkCF_user = [] 63 | predictions_normCF_item = [] 64 | predictions_normCF_user = [] 65 | predictions_blend = [] 66 | targets = [] 67 | print('测试集规模为 %d' % len(test_df)) 68 | print('测试中...') 69 | for row in test_df.itertuples(): 70 | user, item, actual = row[1]-1, row[2]-1, row[3] 71 | predictions_baseline.append(pre.predict_baseline(user, item)) 72 | predictions_itemCF.append(pre.predict_itemCF(user, item)) 73 | predictions_userCF.append(pre.predict_userCF(user, item)) 74 | predictions_itemCF_baseline.append(pre.predict_itemCF_baseline(user, item)) 75 | predictions_userCF_baseline.append(pre.predict_userCF_baseline(user, item)) 76 | predictions_itemCF_bias.append(pre.predict_itemCF_bias(user, item)) 77 | predictions_topkCF_item.append(pre.predict_topkCF_item(user, item, 20)) 78 | predictions_topkCF_user.append(pre.predict_topkCF_user(user, item, 30)) 79 | predictions_normCF_item.append(pre.predict_normCF_item(user, item, 20)) 80 | predictions_normCF_user.append(pre.predict_normCF_user(user, item, 30)) 81 | predictions_blend.append(pre.predict_blend(user, item, 20, 30, 0.7)) 82 | targets.append(actual) 83 | 84 | rmse_baseline.append(utils.rmse(np.array(predictions_baseline), np.array(targets))) 85 | rmse_itemCF.append(utils.rmse(np.array(predictions_itemCF), np.array(targets))) 86 | rmse_userCF.append(utils.rmse(np.array(predictions_userCF), np.array(targets))) 87 | rmse_itemCF_baseline.append(utils.rmse(np.array(predictions_itemCF_baseline), np.array(targets))) 88 | rmse_userCF_baseline.append(utils.rmse(np.array(predictions_userCF_baseline), np.array(targets))) 89 | rmse_itemCF_bias.append(utils.rmse(np.array(predictions_itemCF_bias), np.array(targets))) 90 | rmse_topkCF_item.append(utils.rmse(np.array(predictions_topkCF_item), np.array(targets))) 91 | rmse_topkCF_user.append(utils.rmse(np.array(predictions_topkCF_user), np.array(targets))) 92 | rmse_normCF_item.append(utils.rmse(np.array(predictions_normCF_item), np.array(targets))) 93 | rmse_normCF_user.append(utils.rmse(np.array(predictions_normCF_user), np.array(targets))) 94 | rmse_blend.append(utils.rmse(np.array(predictions_blend), np.array(targets))) 95 | print('测试完成') 96 | print('------ 测试结果 ------') 97 | print('各方法在交叉验证下的RMSE值:') 98 | print('baseline: %.4f' % np.mean(rmse_baseline)) 99 | print('itemCF: %.4f' % np.mean(rmse_itemCF)) 100 | print('userCF: %.4f' % np.mean(rmse_userCF)) 101 | print('itemCF_baseline: %.4f' % np.mean(rmse_itemCF_baseline)) 102 | print('userCF_baseline: %.4f' % np.mean(rmse_userCF_baseline)) 103 | print('itemCF_bias: %.4f' % np.mean(rmse_itemCF_bias)) 104 | print('topkCF(item, k=20): %.4f' % np.mean(rmse_topkCF_item)) 105 | print('topkCF(user, k=30): %.4f' % np.mean(rmse_topkCF_user)) 106 | print('normCF(item, k=20): %.4f' % np.mean(rmse_normCF_item)) 107 | print('normCF(user, k=30): %.4f' % np.mean(rmse_normCF_user)) 108 | print('blend (alpha=0.7): %.4f' % np.mean(rmse_blend)) 109 | print('交叉验证运行完成') 110 | -------------------------------------------------------------------------------- /code/cloud/协同过滤案例/predict.py: -------------------------------------------------------------------------------- 1 | import var 2 | import numpy as np 3 | 4 | def predict_baseline(user, item): 5 | '''baseline''' 6 | prediction = var.item_mean[item] + var.user_mean[user] - var.all_mean 7 | return prediction 8 | 9 | def predict_itemCF(user, item): 10 | '''item-item协同过滤算法''' 11 | nzero = var.ratings[user].nonzero()[0] 12 | prediction = var.ratings[user, nzero].dot(var.item_similarity[item, nzero])\ 13 | / sum(var.item_similarity[item, nzero]) 14 | return prediction 15 | 16 | def predict_userCF(user, item): 17 | '''user-user协同过滤算法''' 18 | nzero = var.ratings[:,item].nonzero()[0] 19 | prediction = (var.ratings[nzero, item]).dot(var.user_similarity[user, nzero])\ 20 | / sum(var.user_similarity[user, nzero]) 21 | if np.isnan(prediction): 22 | baseline = var.user_mean + var.item_mean[item] - var.all_mean 23 | prediction = baseline[user] 24 | return prediction 25 | 26 | def predict_itemCF_baseline(user, item): 27 | '''结合baseline的item-item CF算法''' 28 | nzero = var.ratings[user].nonzero()[0] 29 | baseline = var.item_mean + var.user_mean[user] - var.all_mean 30 | prediction = (var.ratings[user, nzero] - baseline[nzero]).dot(var.item_similarity[item, nzero])\ 31 | / sum(var.item_similarity[item, nzero]) + baseline[item] 32 | return prediction 33 | 34 | def predict_userCF_baseline(user, item): 35 | '''结合baseline的user-user协同过滤算法,预测rating''' 36 | nzero = var.ratings[:,item].nonzero()[0] 37 | baseline = var.user_mean + var.item_mean[item] - var.all_mean 38 | prediction = (var.ratings[nzero, item] - baseline[nzero]).dot(var.user_similarity[user, nzero])\ 39 | / sum(var.user_similarity[user, nzero]) + baseline[user] 40 | if np.isnan(prediction): prediction = baseline[user] 41 | return prediction 42 | 43 | def predict_itemCF_bias(user, item): 44 | '''结合baseline的item-item CF算法,预测rating''' 45 | nzero = var.ratings[user].nonzero()[0] 46 | baseline = var.item_mean + var.user_mean[user] - var.all_mean 47 | prediction = (var.ratings[user, nzero] - baseline[nzero]).dot(var.item_similarity[item, nzero])\ 48 | / sum(var.item_similarity[item, nzero]) + baseline[item] 49 | if prediction > 5: prediction = 5 50 | if prediction < 1: prediciton = 1 51 | return prediction 52 | 53 | def predict_topkCF_item(user, item, k=20): 54 | '''top-k CF算法,以item-item协同过滤为基础,结合baseline,预测rating''' 55 | nzero = var.ratings[user].nonzero()[0] 56 | baseline = var.item_mean + var.user_mean[user] - var.all_mean 57 | choice = nzero[var.item_similarity[item, nzero].argsort()[::-1][:k]] 58 | prediction = (var.ratings[user, choice] - baseline[choice]).dot(var.item_similarity[item, choice])\ 59 | / sum(var.item_similarity[item, choice]) + baseline[item] 60 | if prediction > 5: prediction = 5 61 | if prediction < 1: prediction = 1 62 | return prediction 63 | 64 | def predict_topkCF_user(user, item, k=30): 65 | '''top-k CF算法,以user-user协同过滤为基础,结合baseline,预测rating''' 66 | nzero = var.ratings[:,item].nonzero()[0] 67 | choice = nzero[var.user_similarity[user, nzero].argsort()[::-1][:k]] 68 | baseline = var.user_mean + var.item_mean[item] - var.all_mean 69 | prediction = (var.ratings[choice, item] - baseline[choice]).dot(var.user_similarity[user, choice])\ 70 | / sum(var.user_similarity[user, choice]) + baseline[user] 71 | if np.isnan(prediction): prediction = baseline[user] 72 | if prediction > 5: prediction = 5 73 | if prediction < 1: prediction = 1 74 | return prediction 75 | 76 | def predict_normCF_item(user, item, k=20): 77 | '''在topK的基础上对item采用归一化的相似度矩阵''' 78 | nzero = var.ratings[user].nonzero()[0] 79 | baseline = var.item_mean + var.user_mean[user] - var.all_mean 80 | choice = nzero[var.item_similarity_norm[item, nzero].argsort()[::-1][:k]] 81 | prediction = (var.ratings[user, choice] - baseline[choice]).dot(var.item_similarity_norm[item, choice])\ 82 | / sum(var.item_similarity_norm[item, choice]) + baseline[item] 83 | if prediction > 5: prediction = 5 84 | if prediction < 1: prediction = 1 85 | return prediction 86 | 87 | def predict_normCF_user(user, item, k=30): 88 | '''在topK的基础上对user采用归一化的相似度矩阵''' 89 | nzero = var.ratings[:,item].nonzero()[0] 90 | choice = nzero[var.user_similarity_norm[user, nzero].argsort()[::-1][:k]] 91 | baseline = var.user_mean + var.item_mean[item] - var.all_mean 92 | prediction = (var.ratings[choice, item] - baseline[choice]).dot(var.user_similarity_norm[user, choice])\ 93 | / sum(var.user_similarity_norm[user, choice]) + baseline[user] 94 | if np.isnan(prediction): prediction = baseline[user] 95 | if prediction > 5: prediction = 5 96 | if prediction < 1: prediction = 1 97 | return prediction 98 | 99 | def predict_blend(user, item, k1=20, k2=30, alpha=0.6): 100 | '''融合模型''' 101 | prediction1 = predict_topkCF_item(user, item, k1) 102 | prediction2 = predict_topkCF_user(user, item, k2) 103 | prediction = alpha * prediction1 + (1-alpha) * prediction2 104 | if prediction > 5: prediction = 5 105 | if prediction < 1: prediction = 1 106 | return prediction -------------------------------------------------------------------------------- /code/decision_tree/decision_tree_demo.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | from sklearn import preprocessing 3 | from sklearn import tree 4 | from sklearn.model_selection import train_test_split 5 | from sklearn.metrics import accuracy_score 6 | from sklearn.ensemble import RandomForestClassifier 7 | 8 | """ 9 | 决策树 10 | 完成分类问题 11 | """ 12 | # load data 13 | adult_data = pd.read_csv('./DecisionTree.csv') 14 | 15 | feature_columns = ['workclass', 'education', 'marital-status', 'occupation', 'relationship', 'race', 'gender', 'native-country'] 16 | label_column = ['income'] 17 | 18 | #区分特征和目标列 19 | features = adult_data[feature_columns] 20 | label = adult_data[label_column] 21 | 22 | features = pd.get_dummies(features) 23 | print(features.shape) 24 | print(label.shape) 25 | # 训练集和测试集 26 | X_train, X_test, y_train, y_test = train_test_split(features.values, label.values.ravel(), test_size=0.2) 27 | 28 | #初始化一个决策树分类器 29 | classifier = tree.DecisionTreeClassifier(criterion='entropy', max_depth=4) 30 | # 随机森林分类器 31 | # classifier = RandomForestClassifier(n_estimators=30) 32 | #用决策树分类器拟合数据 33 | classifier.fit(X_train, y_train) 34 | 35 | predictions = classifier.predict(X_test) 36 | # 准确率 37 | print(accuracy_score(y_test, predictions)) -------------------------------------------------------------------------------- /code/decision_tree/decision_tree_iris.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | iris 决策树 5 | """ 6 | 7 | from sklearn.datasets import load_iris 8 | from sklearn import tree 9 | from sklearn.model_selection import train_test_split 10 | from sklearn.metrics import accuracy_score 11 | 12 | 13 | # 加载数据 14 | iris = load_iris() 15 | X = iris.data 16 | y = iris.target 17 | 18 | # 训练集和测试集 19 | X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2) 20 | 21 | print(X_train.shape) 22 | # 构造分类器 23 | classifier = tree.DecisionTreeClassifier() 24 | classifier.fit(X_train, y_train) 25 | 26 | # 测试集预测值 27 | predictions = classifier.predict(X_test) 28 | print(predictions) 29 | 30 | # 准确率 31 | print(accuracy_score(y_test, predictions)) 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /code/demo/iris_demo.md: -------------------------------------------------------------------------------- 1 | #### 例子 2 | 3 | 本例中,我们在 Iris 数据集 上训练一个简单的分类器,它与scikit-learn捆绑在一起。 4 | 5 | 数据集具有花的四个特征:萼片长度,萼片宽度,花瓣长度和花瓣宽度,并将它们分为三个花种 (标签):setosa、versicolor或virginica。 标签已经被表示为数据集中的数字: 0(setosa),1(versicolor)和2(virginica)。 6 | 7 | 我们清洗Iris数据集,并将其分为独立的训练和测试集:保留最后10个数据点进行测试, 剩余的进行训练。然后我们在训练集训练分类器,并对测试集进行预测。 8 | 9 | ``` 10 | #!/usr/bin/env python 11 | 12 | from sklearn.datasets import load_iris 13 | from sklearn import tree 14 | from sklearn.metrics import accuracy_score 15 | import numpy as np 16 | 17 | #loading the iris dataset 18 | iris = load_iris() 19 | 20 | x = iris.data #array of the data 21 | y = iris.target #array of labels (i.e answers) of each data entry 22 | 23 | #getting label names i.e the three flower species 24 | y_names = iris.target_names 25 | 26 | #taking random indices to split the dataset into train and test 27 | test_ids = np.random.permutation(len(x)) 28 | 29 | #splitting data and labels into train and test 30 | #keeping last 10 entries for testing, rest for training 31 | 32 | x_train = x[test_ids[:-10]] 33 | x_test = x[test_ids[-10:]] 34 | 35 | y_train = y[test_ids[:-10]] 36 | y_test = y[test_ids[-10:]] 37 | 38 | #classifying using decision tree 39 | clf = tree.DecisionTreeClassifier() 40 | 41 | #training (fitting) the classifier with the training set 42 | clf.fit(x_train, y_train) 43 | 44 | #predictions on the test dataset 45 | pred = clf.predict(x_test) 46 | 47 | print(pred) #predicted labels i.e flower species 48 | print(y_test) #actual labels 49 | print((accuracy_score(pred, y_test))*100) #prediction accuracy 50 | ``` 51 | 52 | 由于我们在每次迭代中随机分割和分类训练,所以准确性可能会有所不同。运行上面的代码得到: 53 | 54 | ``` 55 | [0 1 1 1 0 2 0 2 2 2] 56 | [0 1 1 1 0 2 0 2 2 2] 57 | 100.0 58 | ``` 59 | 60 | 第一行包含由我们的分类器预测的测试数据的标签(即花种),第二行包含数据集中给出的实际花种。 我们这次准确率达到100%。 -------------------------------------------------------------------------------- /code/desc.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf8 -*- 3 | """ 4 | 描述性统计 5 | 描述性统计是容易操作,直观简洁的数据分析手段。 6 | 但是由于简单,对多元变量的关系难以描述。 7 | 现实生活中,自变量通常是多元的:决定体重不仅有身高,还有饮食习惯,肥胖基因等等因素。 8 | 通过一些高级的数据处理手段,我们可以对多元变量进行处理, 9 | 例如特征工程中,可以使用互信息方法来选择多个对因变量有较强相关性的自变量作为特征, 10 | 还可以使用主成分分析法来消除一些冗余的自变量来降低运算复杂度。 11 | """ 12 | from numpy import array, cov, corrcoef 13 | from numpy import mean, median, ptp, var, std 14 | from scipy.stats import mode 15 | from numpy.random import normal, randint 16 | 17 | data1 = randint(0, 10, size=10) 18 | print(data1) 19 | print('平均值', mean(data1)) 20 | print('众数', mode(data1)) 21 | print('中位数', median(data1)) 22 | print('极差', ptp(data1)) 23 | print('方法', var(data1)) 24 | print('标准差', std(data1)) 25 | print('变异系数', mean(data1) / std(data1)) 26 | # 偏差程度 定义z-分数(Z-Score)为测量值距均值相差的标准差数目 27 | print('偏差程度:', (data1 -mean(data1)) / std(data1)) 28 | 29 | print('---------------------------------') 30 | data2 = randint(0, 10, size=10) 31 | data3 = randint(0, 10, size=10) 32 | data = array([data1, data2, data3]) 33 | print(data) 34 | 35 | #计算两组数的协方差 36 | #参数bias=1表示结果需要除以N,否则只计算了分子部分 37 | #返回结果为矩阵,第i行第j列的数据表示第i组数与第j组数的协方差。对角线为方差 38 | print('协方差', cov(data, bias=1)) 39 | 40 | #计算两组数的相关系数 41 | #返回结果为矩阵,第i行第j列的数据表示第i组数与第j组数的相关系数。对角线为1 42 | print('相关系数', corrcoef(data)) 43 | 44 | 45 | -------------------------------------------------------------------------------- /code/iris.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | 4 | """ 5 | iris数据集 6 | 特征工程 7 | 8 | """ 9 | 10 | from sklearn.datasets import load_iris 11 | 12 | #导入IRIS数据集 13 | iris = load_iris() 14 | 15 | #特征矩阵 16 | print(iris.data) 17 | 18 | #目标向量 19 | print(iris.target) 20 | print(iris.target.shape) 21 | 22 | # from sklearn.preprocessing import StandardScaler 23 | # print(StandardScaler().fit_transform(iris.data)) 24 | 25 | # from sklearn.preprocessing import Binarizer 26 | #二值化,阈值设置为3,返回值为二值化后的数据 27 | # print(Binarizer(threshold=3).fit_transform(iris.data)) 28 | 29 | from sklearn.preprocessing import OneHotEncoder 30 | print(OneHotEncoder().fit_transform(iris.target.reshape((-1,1))).toarray()) 31 | 32 | from numpy import vstack, array, nan 33 | from sklearn.preprocessing import Imputer 34 | #缺失值计算,返回值为计算缺失值后的数据 35 | #参数missing_value为缺失值的表示形式,默认为NaN 36 | #参数strategy为缺失值填充方式,默认为mean(均值) 37 | print(Imputer().fit_transform(vstack((array([nan, nan, nan, nan]), iris.data)))) 38 | -------------------------------------------------------------------------------- /code/keras/cnn_mnist.py: -------------------------------------------------------------------------------- 1 | """ 2 | 卷积神经网络 3 | 4 | """ 5 | 6 | from keras.datasets import mnist 7 | import matplotlib.pyplot as plt 8 | from keras.models import Sequential 9 | from keras.layers import Dense, Activation, Conv2D, MaxPool2D, Flatten 10 | from keras.optimizers import Adam 11 | from keras.utils import np_utils 12 | 13 | # 加载数据 14 | (x_train, y_train),(x_test, y_test) = mnist.load_data() 15 | 16 | # 可视化 17 | plt.title('Example %d. Label: %d' % (0, y_train[0])) 18 | plt.imshow(x_train[0].reshape((28,28)), ) 19 | plt.show() 20 | 21 | # 数据预处理 22 | x_train = x_train.reshape(-1, 1, 28, 28) # channel 1 代表黑白照片 23 | x_test = x_test.reshape(-1, 1, 28, 28) 24 | y_train = np_utils.to_categorical(y_train, num_classes=10) 25 | y_test = np_utils.to_categorical(y_test, num_classes=10) 26 | 27 | # 构建模型 28 | model = Sequential() 29 | # 卷积层 30 | model.add(Conv2D( 31 | filters=32, # 滤波器 32 | kernel_size=(5,5), # 2D 卷积窗口的宽度和高度 33 | padding='same', 34 | input_shape=(1,28,28) 35 | )) 36 | model.add(Activation('relu')) 37 | # 池化层 向下取样 -- 池化不会压缩层高度 38 | model.add(MaxPool2D( 39 | pool_size=(2,2), # 沿(垂直,水平)方向缩小比例的因数 40 | strides=(2,2), # 步长 41 | padding='same', 42 | )) 43 | # output shape (32,14,14) 44 | 45 | # 卷积层 46 | model.add(Conv2D( 47 | filters=64, # 滤波器 48 | kernel_size=(5,5), # 2D 卷积窗口的宽度和高度 49 | padding='same', 50 | )) 51 | model.add(Activation('relu')) 52 | # 池化层 向下取样 53 | model.add(MaxPool2D( 54 | pool_size=(2,2), # 沿(垂直,水平)方向缩小比例的因数 55 | strides=(2,2), # 步长 56 | padding='same', 57 | )) 58 | # output shape (64,7,7) 59 | 60 | # 全连接层 61 | model.add(Flatten()) # 3维转1维 62 | model.add(Dense(1024,)) 63 | model.add(Activation('relu')) 64 | 65 | # 全连接层2 66 | model.add(Dense(10,)) 67 | # softmax 用于分类 68 | model.add(Activation('softmax')) 69 | adam = Adam(lr=0.0001) 70 | 71 | # 激活模型 72 | model.compile(optimizer=adam, loss='categorical_crossentropy', metrics=['accuracy']) 73 | # 训练模型 74 | model.fit(x_train, y_train, epochs=1, batch_size=32) 75 | # 评估模型 76 | loss, accuracy = model.evaluate(x_test, y_test) 77 | print('loss: %s, accuracy: %s' % (loss, accuracy)) 78 | -------------------------------------------------------------------------------- /code/keras/k_mnist.py: -------------------------------------------------------------------------------- 1 | """ 2 | 分类器 3 | 神经网络 4 | """ 5 | from keras.datasets import mnist 6 | import matplotlib.pyplot as plt 7 | from keras.models import Sequential 8 | from keras.layers import Dense, Activation 9 | from keras.optimizers import RMSprop 10 | from keras.utils import np_utils 11 | 12 | # 加载数据 13 | (x_train, y_train),(x_test, y_test) = mnist.load_data() 14 | 15 | # 可视化 16 | plt.title('Example %d. Label: %d' % (0, y_train[0])) 17 | plt.imshow(x_train[0].reshape((28,28)), ) 18 | plt.show() 19 | 20 | x_train = x_train.reshape(x_train.shape[0], -1) /255 21 | x_test = x_test.reshape(x_test.shape[0], -1) /255 22 | y_train = np_utils.to_categorical(y_train, num_classes=10) 23 | y_test = np_utils.to_categorical(y_test, num_classes=10) 24 | 25 | model = Sequential([ 26 | Dense(32, input_dim=784,), 27 | Activation('relu'), 28 | Dense(10), 29 | Activation('softmax') 30 | ]) 31 | 32 | rmsprop = RMSprop(lr=0.001, rho=0.9, epsilon=1e-08,decay=0.0) 33 | 34 | model.compile(optimizer=rmsprop, loss='categorical_crossentropy', metrics=['accuracy']) 35 | 36 | model.fit(x_train, y_train, epochs=5, batch_size=32) 37 | 38 | loss, accuracy = model.evaluate(x_test, y_test) 39 | 40 | print('loss: %s, accuracy: %s' % (loss, accuracy)) 41 | 42 | -------------------------------------------------------------------------------- /code/keras/lr.py: -------------------------------------------------------------------------------- 1 | """ 2 | 回归神经网络 3 | 简单实现 4 | """ 5 | 6 | import numpy as np 7 | import matplotlib.pyplot as plt 8 | from keras.models import Sequential 9 | from keras.layers import Dense 10 | from keras.optimizers import SGD 11 | 12 | 13 | def MaxMinNormalization(x): 14 | """ 15 | 归一化 16 | """ 17 | Min = np.min(x) 18 | Max = np.max(x) 19 | x = (x - Min) / (Max - Min) 20 | return x 21 | 22 | # 自己构造测试集 23 | X = 100 * np.random.rand(200) 24 | X = MaxMinNormalization(X) 25 | y = 0.5*X + 2 + np.random.normal(0,0.01,(200,)) 26 | 27 | # training set 28 | X_train = X[:160] 29 | y_train = y[:160] 30 | # test set 31 | X_test = X[160:] 32 | y_test = y[160:] 33 | 34 | model = Sequential() 35 | # 添加神经层 36 | model.add(Dense(1, input_shape=(1,))) 37 | 38 | # 激活模型 选择误差和优化方法 39 | # MSE 均方误差 MSE 40 | model.compile(optimizer=SGD(lr=0.1), loss='mse') 41 | 42 | # 训练模型 43 | for i in range(1000): 44 | model.train_on_batch(X_train, y_train) 45 | 46 | cost = model.evaluate(X_test, y_test, batch_size=40) 47 | print('误差:', cost) 48 | 49 | # 预测测试集 50 | y_predict = model.predict(X_test) 51 | 52 | W, b = model.layers[0].get_weights() 53 | print('Weights=', W, ' biases=', b) 54 | 55 | plt.scatter(X, y, color='black') 56 | plt.xlabel('x') 57 | plt.ylabel('y') 58 | plt.plot(X_test, y_predict) 59 | plt.show() 60 | 61 | -------------------------------------------------------------------------------- /code/keras/lstm_regression.py: -------------------------------------------------------------------------------- 1 | """ 2 | LSTM 3 | """ 4 | import numpy as np 5 | import matplotlib.pyplot as plt 6 | from keras.models import Sequential 7 | from keras.layers import Dense, LSTM, TimeDistributed 8 | from keras.optimizers import Adam 9 | 10 | np.random.seed(1337) 11 | 12 | BATCH_START = 0 13 | TIME_STEPS = 20 14 | BATCH_SIZE = 50 15 | INPUT_SIZE = 1 16 | OUTPUT_SIZE = 1 17 | CELL_SIZE = 20 18 | LR = 0.006 19 | 20 | 21 | def get_batch(): 22 | global BATCH_START, TIME_STEPS 23 | xs = np.arange(BATCH_START, BATCH_START+TIME_STEPS*BATCH_SIZE).reshape((BATCH_SIZE, TIME_STEPS)) / (10*np.pi) 24 | seq = np.sin(xs) 25 | res = np.cos(xs) 26 | BATCH_START += TIME_STEPS 27 | # plt.plot(xs[0, :], res[0, :], 'r', xs[0, :], seq[0, :], 'b--') 28 | # plt.show() 29 | return [seq[:, :, np.newaxis], res[:, :, np.newaxis], xs] 30 | 31 | model = Sequential() 32 | 33 | model.add(LSTM( 34 | batch_input_shape=(BATCH_SIZE, TIME_STEPS, INPUT_SIZE), 35 | units=CELL_SIZE, 36 | return_sequences=True, 37 | stateful=True, 38 | )) 39 | 40 | model.add(TimeDistributed(Dense(OUTPUT_SIZE))) 41 | adam = Adam(lr=0.001) 42 | 43 | model.compile(optimizer=adam, loss='mse') 44 | 45 | print('Training ------------') 46 | for step in range(501): 47 | # data shape = (batch_num, steps, inputs/outputs) 48 | X_batch, Y_batch, xs = get_batch() 49 | cost = model.train_on_batch(X_batch, Y_batch) 50 | pred = model.predict(X_batch, BATCH_SIZE) 51 | plt.plot(xs[0, :], Y_batch[0].flatten(), 'r', xs[0, :], pred.flatten()[:TIME_STEPS], 'b--') 52 | plt.ylim((-1.2, 1.2)) 53 | plt.draw() 54 | plt.pause(0.1) 55 | if step % 10 == 0: 56 | print('train cost: ', cost) 57 | -------------------------------------------------------------------------------- /code/keras/mymodel.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/code/keras/mymodel.h5 -------------------------------------------------------------------------------- /code/keras/rnn_mnist.py: -------------------------------------------------------------------------------- 1 | """ 2 | 循环神经网络 3 | """ 4 | from keras.datasets import mnist 5 | import matplotlib.pyplot as plt 6 | from keras.models import Sequential 7 | from keras.layers import Dense, Activation, SimpleRNN 8 | from keras.optimizers import Adam 9 | from keras.utils import np_utils 10 | 11 | 12 | # 加载数据 13 | (x_train, y_train),(x_test, y_test) = mnist.load_data() 14 | 15 | # 可视化 16 | plt.title('Example %d. Label: %d' % (0, y_train[0])) 17 | plt.imshow(x_train[0].reshape((28,28)), ) 18 | plt.show() 19 | 20 | x_train = x_train.reshape(-1, 28, 28) /255 21 | x_test = x_test.reshape(-1, 28, 28) /255 22 | y_train = np_utils.to_categorical(y_train, num_classes=10) 23 | y_test = np_utils.to_categorical(y_test, num_classes=10) 24 | 25 | model = Sequential() 26 | model.add(SimpleRNN( 27 | batch_input_shape=(None, 28, 28), # 批次 和 输入尺寸 28 | units= 50, # 输出 29 | )) 30 | model.add(Dense(10)) 31 | model.add(Activation('softmax')) 32 | 33 | adam = Adam(lr=0.001) 34 | 35 | model.compile(optimizer=adam, loss='categorical_crossentropy', metrics=['accuracy']) 36 | 37 | model.fit(x_train, y_train, epochs=3, batch_size=50) 38 | 39 | loss, accuracy = model.evaluate(x_test, y_test) 40 | 41 | print('loss: %s, accuracy: %s' % (loss, accuracy)) 42 | 43 | 44 | -------------------------------------------------------------------------------- /code/keras/save_model.py: -------------------------------------------------------------------------------- 1 | """ 2 | 保存训练后的模型 3 | """ 4 | 5 | import numpy as np 6 | import matplotlib.pyplot as plt 7 | from keras.models import Sequential 8 | from keras.layers import Dense 9 | from keras.optimizers import SGD 10 | from keras.models import load_model 11 | 12 | def MaxMinNormalization(x): 13 | """ 14 | 归一化 15 | """ 16 | Min = np.min(x) 17 | Max = np.max(x) 18 | x = (x - Min) / (Max - Min) 19 | return x 20 | 21 | # 自己构造测试集 22 | X = 100 * np.random.rand(200) 23 | X = MaxMinNormalization(X) 24 | y = 0.5*X + 2 + np.random.normal(0,0.01,(200,)) 25 | 26 | # training set 27 | X_train = X[:160] 28 | y_train = y[:160] 29 | # test set 30 | X_test = X[160:] 31 | y_test = y[160:] 32 | 33 | model = Sequential() 34 | # 添加神经层 35 | model.add(Dense(1, input_shape=(1,))) 36 | 37 | # 激活模型 选择误差和优化方法 38 | # MSE 均方误差 MSE 39 | model.compile(optimizer=SGD(lr=0.1), loss='mse') 40 | 41 | # 训练模型 42 | for i in range(1000): 43 | model.train_on_batch(X_train, y_train) 44 | 45 | cost = model.evaluate(X_test, y_test, batch_size=40) 46 | print('误差:', cost) 47 | 48 | # 预测测试集 49 | y_predict = model.predict(X_test) 50 | 51 | print('test before save:', y_predict) 52 | 53 | model.save('mymodel.h5') 54 | 55 | del model 56 | 57 | model = load_model('mymodel.h5') 58 | 59 | y_predict = model.predict(X_test) 60 | 61 | print('test after save:', y_predict) -------------------------------------------------------------------------------- /code/knn/readme.md: -------------------------------------------------------------------------------- 1 | ## K近邻(k-Nearest Neighbour) 2 | 3 | ### 简介 4 | 5 | ![img](../../images/knn.png) 6 | 7 | - 对于一个测试点,看它最近的邻居属于那个类别 8 | - 考虑最近邻居的时候,我们可以综合考虑与这个点距离最近的K个点,看它们中有多少输入类别A,多少属于类别B 9 | - 距离:两点间的直线距离(Euclidean Distance) 10 | 11 | ![img](../../images/eucl_dist.png) 12 | 13 | - 即考虑各个feature之间差异的平方和 14 | 15 | ### 实现 16 | 17 | - fit:用于训练,将训练集的feature和label作为输入 18 | - predict: prediction,将测试集的feature作为输入,输出预测的label 19 | - 设置k=1,也就是我们只考虑最近的那个点属于那个类别 20 | - 用scipy.spatial.distance来计算距离 21 | - 返回测试点最近邻的label 22 | 23 | ### 总结 24 | 25 | - 优点:简单 26 | 27 | - 缺点:不能进行复杂的计算 -------------------------------------------------------------------------------- /code/knn/simpleKnn.py: -------------------------------------------------------------------------------- 1 | from scipy.spatial import distance 2 | from sklearn import datasets 3 | from sklearn.model_selection import train_test_split 4 | from sklearn.metrics import accuracy_score 5 | 6 | """ 7 | 实现简单knn 8 | """ 9 | def euc(a, b): 10 | return distance.euclidean(a, b) 11 | 12 | class SimpleKNN(): 13 | def __init__(self): 14 | pass 15 | 16 | def fit(self, X_train, y_train): 17 | self.X_train = X_train 18 | self.y_train = y_train 19 | 20 | def predict(self, X_test): 21 | predictions = [] 22 | for row in X_test: 23 | label = self.closest(row) 24 | predictions.append(label) 25 | return predictions 26 | 27 | def closest(self, row): 28 | best_dist = euc(row, self.X_train[0]) 29 | best_index = 0 30 | for i in range(1, len(self.X_train)): 31 | dist = euc(row, self.X_train[i]) 32 | if dist < best_dist: 33 | best_dist = dist 34 | best_index = i 35 | return self.y_train[best_index] 36 | 37 | 38 | # 加载数据 39 | iris = datasets.load_iris() 40 | X = iris.data 41 | y = iris.target 42 | 43 | # 训练集和测试集 44 | X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2) 45 | 46 | # 构造分类器 47 | classifier = SimpleKNN() 48 | classifier.fit(X_train, y_train) 49 | 50 | # 测试集预测值 51 | predictions = classifier.predict(X_test) 52 | print(predictions) 53 | 54 | # 准确率 55 | print(accuracy_score(y_test, predictions)) -------------------------------------------------------------------------------- /code/lihongyi/homework1/data/Homework1_introduction.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/code/lihongyi/homework1/data/Homework1_introduction.txt -------------------------------------------------------------------------------- /code/lihongyi/homework1/data/answer.csv: -------------------------------------------------------------------------------- 1 | id,value 2 | id_0,33 3 | id_1,60 4 | id_2,16 5 | id_3,33 6 | id_4,5 7 | id_5,41 8 | id_6,46 9 | id_7,25 10 | id_8,38 11 | id_9,26 12 | id_10,31 13 | id_11,59 14 | id_12,41 15 | id_13,45 16 | id_14,23 17 | id_15,18 18 | id_16,51 19 | id_17,30 20 | id_18,19 21 | id_19,20 22 | id_20,16 23 | id_21,31 24 | id_22,44 25 | id_23,4 26 | id_24,63 27 | id_25,48 28 | id_26,26 29 | id_27,1 30 | id_28,21 31 | id_29,48 32 | id_30,31 33 | id_31,15 34 | id_32,21 35 | id_33,4 36 | id_34,14 37 | id_35,39 38 | id_36,15 39 | id_37,28 40 | id_38,12 41 | id_39,54 42 | id_40,47 43 | id_41,20 44 | id_42,59 45 | id_43,17 46 | id_44,54 47 | id_45,51 48 | id_46,62 49 | id_47,37 50 | id_48,54 51 | id_49,42 52 | id_50,39 53 | id_51,29 54 | id_52,43 55 | id_53,21 56 | id_54,30 57 | id_55,43 58 | id_56,17 59 | id_57,19 60 | id_58,39 61 | id_59,27 62 | id_60,10 63 | id_61,25 64 | id_62,27 65 | id_63,66 66 | id_64,52 67 | id_65,24 68 | id_66,49 69 | id_67,54 70 | id_68,25 71 | id_69,39 72 | id_70,68 73 | id_71,43 74 | id_72,51 75 | id_73,12 76 | id_74,13 77 | id_75,25 78 | id_76,66 79 | id_77,4 80 | id_78,43 81 | id_79,36 82 | id_80,13 83 | id_81,34 84 | id_82,7 85 | id_83,24 86 | id_84,10 87 | id_85,7 88 | id_86,15 89 | id_87,6 90 | id_88,16 91 | id_89,19 92 | id_90,42 93 | id_91,11 94 | id_92,14 95 | id_93,17 96 | id_94,38 97 | id_95,11 98 | id_96,19 99 | id_97,6 100 | id_98,9 101 | id_99,5 102 | id_100,7 103 | id_101,17 104 | id_102,6 105 | id_103,8 106 | id_104,5 107 | id_105,37 108 | id_106,31 109 | id_107,0 110 | id_108,20 111 | id_109,20 112 | id_110,21 113 | id_111,14 114 | id_112,10 115 | id_113,27 116 | id_114,13 117 | id_115,13 118 | id_116,4 119 | id_117,40 120 | id_118,34 121 | id_119,0 122 | id_120,2 123 | id_121,12 124 | id_122,16 125 | id_123,21 126 | id_124,6 127 | id_125,27 128 | id_126,28 129 | id_127,9 130 | id_128,23 131 | id_129,25 132 | id_130,0 133 | id_131,34 134 | id_132,11 135 | id_133,17 136 | id_134,25 137 | id_135,27 138 | id_136,6 139 | id_137,26 140 | id_138,71 141 | id_139,53 142 | id_140,21 143 | id_141,19 144 | id_142,27 145 | id_143,11 146 | id_144,12 147 | id_145,17 148 | id_146,11 149 | id_147,4 150 | id_148,17 151 | id_149,10 152 | id_150,43 153 | id_151,21 154 | id_152,18 155 | id_153,13 156 | id_154,11 157 | id_155,13 158 | id_156,20 159 | id_157,38 160 | id_158,10 161 | id_159,28 162 | id_160,47 163 | id_161,17 164 | id_162,70 165 | id_163,14 166 | id_164,35 167 | id_165,31 168 | id_166,17 169 | id_167,6 170 | id_168,63 171 | id_169,24 172 | id_170,18 173 | id_171,70 174 | id_172,14 175 | id_173,11 176 | id_174,18 177 | id_175,0 178 | id_176,9 179 | id_177,18 180 | id_178,25 181 | id_179,20 182 | id_180,43 183 | id_181,34 184 | id_182,27 185 | id_183,17 186 | id_184,11 187 | id_185,54 188 | id_186,32 189 | id_187,27 190 | id_188,12 191 | id_189,32 192 | id_190,9 193 | id_191,14 194 | id_192,37 195 | id_193,76 196 | id_194,26 197 | id_195,16 198 | id_196,62 199 | id_197,19 200 | id_198,23 201 | id_199,27 202 | id_200,170 203 | id_201,16 204 | id_202,67 205 | id_203,4 206 | id_204,74 207 | id_205,48 208 | id_206,12 209 | id_207,7 210 | id_208,63 211 | id_209,7 212 | id_210,40 213 | id_211,84 214 | id_212,14 215 | id_213,99 216 | id_214,47 217 | id_215,91 218 | id_216,106 219 | id_217,88 220 | id_218,29 221 | id_219,7 222 | id_220,29 223 | id_221,65 224 | id_222,35 225 | id_223,27 226 | id_224,43 227 | id_225,13 228 | id_226,8 229 | id_227,69 230 | id_228,32 231 | id_229,0 232 | id_230,35 233 | id_231,11 234 | id_232,14 235 | id_233,4 236 | id_234,14 237 | id_235,20 238 | id_236,20 239 | id_237,0 240 | id_238,18 241 | id_239,3 242 | -------------------------------------------------------------------------------- /code/lihongyi/homework1/data/sampleSubmission.csv: -------------------------------------------------------------------------------- 1 | id,value 2 | id_0,0 3 | id_1,0 4 | id_2,0 5 | id_3,0 6 | id_4,0 7 | id_5,0 8 | id_6,0 9 | id_7,0 10 | id_8,0 11 | id_9,0 12 | id_10,0 13 | id_11,0 14 | id_12,0 15 | id_13,0 16 | id_14,0 17 | id_15,0 18 | id_16,0 19 | id_17,0 20 | id_18,0 21 | id_19,0 22 | id_20,0 23 | id_21,0 24 | id_22,0 25 | id_23,0 26 | id_24,0 27 | id_25,0 28 | id_26,0 29 | id_27,0 30 | id_28,0 31 | id_29,0 32 | id_30,0 33 | id_31,0 34 | id_32,0 35 | id_33,0 36 | id_34,0 37 | id_35,0 38 | id_36,0 39 | id_37,0 40 | id_38,0 41 | id_39,0 42 | id_40,0 43 | id_41,0 44 | id_42,0 45 | id_43,0 46 | id_44,0 47 | id_45,0 48 | id_46,0 49 | id_47,0 50 | id_48,0 51 | id_49,0 52 | id_50,0 53 | id_51,0 54 | id_52,0 55 | id_53,0 56 | id_54,0 57 | id_55,0 58 | id_56,0 59 | id_57,0 60 | id_58,0 61 | id_59,0 62 | id_60,0 63 | id_61,0 64 | id_62,0 65 | id_63,0 66 | id_64,0 67 | id_65,0 68 | id_66,0 69 | id_67,0 70 | id_68,0 71 | id_69,0 72 | id_70,0 73 | id_71,0 74 | id_72,0 75 | id_73,0 76 | id_74,0 77 | id_75,0 78 | id_76,0 79 | id_77,0 80 | id_78,0 81 | id_79,0 82 | id_80,0 83 | id_81,0 84 | id_82,0 85 | id_83,0 86 | id_84,0 87 | id_85,0 88 | id_86,0 89 | id_87,0 90 | id_88,0 91 | id_89,0 92 | id_90,0 93 | id_91,0 94 | id_92,0 95 | id_93,0 96 | id_94,0 97 | id_95,0 98 | id_96,0 99 | id_97,0 100 | id_98,0 101 | id_99,0 102 | id_100,0 103 | id_101,0 104 | id_102,0 105 | id_103,0 106 | id_104,0 107 | id_105,0 108 | id_106,0 109 | id_107,0 110 | id_108,0 111 | id_109,0 112 | id_110,0 113 | id_111,0 114 | id_112,0 115 | id_113,0 116 | id_114,0 117 | id_115,0 118 | id_116,0 119 | id_117,0 120 | id_118,0 121 | id_119,0 122 | id_120,0 123 | id_121,0 124 | id_122,0 125 | id_123,0 126 | id_124,0 127 | id_125,0 128 | id_126,0 129 | id_127,0 130 | id_128,0 131 | id_129,0 132 | id_130,0 133 | id_131,0 134 | id_132,0 135 | id_133,0 136 | id_134,0 137 | id_135,0 138 | id_136,0 139 | id_137,0 140 | id_138,0 141 | id_139,0 142 | id_140,0 143 | id_141,0 144 | id_142,0 145 | id_143,0 146 | id_144,0 147 | id_145,0 148 | id_146,0 149 | id_147,0 150 | id_148,0 151 | id_149,0 152 | id_150,0 153 | id_151,0 154 | id_152,0 155 | id_153,0 156 | id_154,0 157 | id_155,0 158 | id_156,0 159 | id_157,0 160 | id_158,0 161 | id_159,0 162 | id_160,0 163 | id_161,0 164 | id_162,0 165 | id_163,0 166 | id_164,0 167 | id_165,0 168 | id_166,0 169 | id_167,0 170 | id_168,0 171 | id_169,0 172 | id_170,0 173 | id_171,0 174 | id_172,0 175 | id_173,0 176 | id_174,0 177 | id_175,0 178 | id_176,0 179 | id_177,0 180 | id_178,0 181 | id_179,0 182 | id_180,0 183 | id_181,0 184 | id_182,0 185 | id_183,0 186 | id_184,0 187 | id_185,0 188 | id_186,0 189 | id_187,0 190 | id_188,0 191 | id_189,0 192 | id_190,0 193 | id_191,0 194 | id_192,0 195 | id_193,0 196 | id_194,0 197 | id_195,0 198 | id_196,0 199 | id_197,0 200 | id_198,0 201 | id_199,0 202 | id_200,0 203 | id_201,0 204 | id_202,0 205 | id_203,0 206 | id_204,0 207 | id_205,0 208 | id_206,0 209 | id_207,0 210 | id_208,0 211 | id_209,0 212 | id_210,0 213 | id_211,0 214 | id_212,0 215 | id_213,0 216 | id_214,0 217 | id_215,0 218 | id_216,0 219 | id_217,0 220 | id_218,0 221 | id_219,0 222 | id_220,0 223 | id_221,0 224 | id_222,0 225 | id_223,0 226 | id_224,0 227 | id_225,0 228 | id_226,0 229 | id_227,0 230 | id_228,0 231 | id_229,0 232 | id_230,0 233 | id_231,0 234 | id_232,0 235 | id_233,0 236 | id_234,0 237 | id_235,0 238 | id_236,0 239 | id_237,0 240 | id_238,0 241 | id_239,0 242 | -------------------------------------------------------------------------------- /code/lihongyi/homework1/task3.py: -------------------------------------------------------------------------------- 1 | """ 2 | 预测pm2.5 3 | 这里我们用前九个小时pm2.5来预测第10小时的pm2.5 4 | 基于AdaGrad 5 | """ 6 | 7 | import pandas as pd 8 | import numpy as np 9 | import matplotlib.pyplot as plt 10 | 11 | 12 | def get_train_data(): 13 | """ 14 | 从训练数据中提取出连续十个小时的观测数据, 15 | 最后一个小时的PM2.5作为该条数据的类标签, 16 | 而前九个小时的PM2.5值作为特征。 17 | 一天24个小时,一天内总共有24-10+1 =15条记录 18 | """ 19 | data = pd.read_csv("data/train.csv") 20 | pm2_5 = data[data['observation'] == 'PM2.5'].iloc[:, 3:] # 获取所有的pm2.5信息 21 | pm2_5 = pm2_5.apply(pd.to_numeric, axis=0) 22 | xlist=[] 23 | ylist=[] 24 | for i in range(15): 25 | tempx = pm2_5.iloc[:,i:i+9] 26 | tempx.columns = np.array(range(9)) 27 | tempy=pm2_5.iloc[:,i+9] 28 | tempy.columns=[1] 29 | xlist.append(tempx) 30 | ylist.append(tempy) 31 | xdata = pd.concat(xlist) 32 | ydata = pd.concat(ylist) 33 | # 去除异常值 34 | xdata, ydata = filter(xdata,ydata) 35 | X = np.array(xdata, float) 36 | # 加上bias 37 | X = np.c_[np.ones((X.shape[0], 1)), X] 38 | y = np.array(ydata, float) 39 | return X, y 40 | 41 | 42 | def get_test_data(): 43 | data = pd.read_csv("data/test.csv") 44 | pm2_5 = data[data['AMB_TEMP'] == 'PM2.5'].iloc[:, 2:] 45 | X = np.array(pm2_5, float) 46 | X = np.c_[np.ones((X.shape[0], 1)), X] 47 | return X 48 | 49 | def filter(X, y): 50 | """ 51 | 这里过滤掉存在异常数值的行 52 | """ 53 | cond1 = X.apply(lambda x: x > 0).all(axis=1) 54 | X = X[cond1] 55 | y = y[cond1] 56 | cond2 = y.apply(lambda x: x > 0) 57 | X = X[cond2] 58 | y = y[cond2] 59 | return X, y 60 | 61 | 62 | class AdaGrad(): 63 | def __init__(self, lr=20, epochs=20000): 64 | self.lr = lr 65 | self.epochs = epochs 66 | 67 | def costFunction(self, X, y, theta): 68 | """ 69 | 损失函数 70 | 这里的cost不同于直接意义上的mse 71 | """ 72 | m = y.size 73 | h = X.dot(theta) 74 | J = 1.0 / (2 * m) * (np.sum(np.square(h - y))) 75 | return J 76 | 77 | def fit(self, X, y): 78 | """ 79 | """ 80 | self.X = X 81 | self.y = y 82 | m = y.size 83 | w = np.zeros(X.shape[1]) 84 | s_grad = np.zeros(X.shape[1]) 85 | cost = [] 86 | for j in range(self.epochs): 87 | h = X.dot(w) 88 | grad = X.T.dot(h - y) 89 | s_grad += grad ** 2 90 | ada = np.sqrt(s_grad) 91 | w = w - self.lr * (1.0 / m) * grad / ada 92 | J = self.costFunction(X,y,w) 93 | self.cost = J 94 | cost.append(J) 95 | self.w = w 96 | return w, cost 97 | 98 | # 1 获取训练集 99 | X_train, y_train = get_train_data() 100 | 101 | # 2 训练数据 输出模型 102 | gd = AdaGrad() 103 | w, cost = gd.fit(X_train, y_train) 104 | print('cost:', cost[-1]) 105 | 106 | # 3 获取测试集 107 | X_test = get_test_data() 108 | real= pd.read_csv('data/answer.csv') 109 | # 4 模型评估 110 | y_hat = np.dot(X_test,w) 111 | 112 | sse = ((y_hat - real.value)**2).sum() 113 | # mse = ((y_hat - real.value)**2).mean() 114 | ssr = ((y_hat- real.value.mean())**2).sum() 115 | sst = ((real.value- real.value.mean())**2).sum() 116 | 117 | r2 = 1 - sse / sst 118 | print('r2系数为:', r2) # 0.86 119 | 120 | # 可视化损失函数下降趋势 121 | plt.title("linear regression") 122 | plt.plot(cost) 123 | plt.xlabel('x') 124 | plt.ylabel('y') 125 | plt.show() 126 | -------------------------------------------------------------------------------- /code/lihongyi/task1.py: -------------------------------------------------------------------------------- 1 | """ 2 | 自己实现 3 | 梯度下降解决线性回归问题 4 | """ 5 | 6 | 7 | 8 | import numpy as np 9 | import matplotlib.pyplot as plt 10 | 11 | 12 | def costFunction(X, y, theta=[0, 0]): 13 | """ 14 | 损失函数 15 | """ 16 | m = y.size 17 | h = X.dot(theta) 18 | J = 1.0 / (2 * m) * (np.sum(np.square(h - y))) 19 | return J 20 | 21 | def gradientDescent(X, y, theta=[0, 0], alpha=0.01, num_iters=1500): 22 | """ 23 | 梯度下降 24 | """ 25 | m = y.size 26 | J_history = np.zeros(num_iters) 27 | for iter in np.arange(num_iters): 28 | h = X.dot(theta) 29 | theta = theta - alpha * (1.0 / m) * (X.T.dot(h - y)) 30 | J_history[iter] = costFunction(X, y, theta) 31 | return (theta, J_history) 32 | 33 | 34 | def MaxMinNormalization(x): 35 | """ 36 | 归一化 37 | """ 38 | Min = np.min(x) 39 | Max = np.max(x) 40 | x = (x - Min) / (Max - Min) 41 | return x 42 | 43 | # 使用外部训练集 44 | # data = np.loadtxt('linear_regression_data1.txt', delimiter=',') 45 | # X = np.c_[np.ones(data.shape[0]),data[:,0]] 46 | # y = data[:,1] 47 | 48 | # 自己构造数据集 49 | X_row = 100 * np.random.rand(100) 50 | X = MaxMinNormalization(X_row) 51 | y = 0.5*X + 2 + np.random.normal(0,0.01,(100,)) 52 | 53 | # 数据可视化 54 | plt.subplot(1, 2, 1) 55 | plt.scatter(X_row, y, color='black') 56 | plt.xlabel('x') 57 | plt.ylabel('y') 58 | 59 | 60 | X = np.c_[np.ones((X.shape[0],1)), X] 61 | 62 | 63 | # training set 64 | X_train = X[:80] 65 | y_train = y[:80] 66 | # test set 67 | X_test = X[80:] 68 | y_test = y[80:] 69 | 70 | 71 | 72 | print(costFunction(X,y)) 73 | 74 | b = 0 75 | w = 0 76 | lr = 0.01 77 | iteration = 10000 78 | 79 | # 画出每一次迭代和损失函数变化 80 | theta , Cost_J = gradientDescent(X_train, y_train, theta=[b, w], alpha= lr, num_iters= iteration) 81 | 82 | print('最终b, w结果: ',theta) 83 | testCost = costFunction(X_test, y_test, theta) 84 | print('测试集误差: ',testCost) 85 | 86 | h = X.dot(theta) 87 | plt.plot(X_row, h, "b--") 88 | plt.subplot(1, 2, 2) 89 | plt.plot(Cost_J) 90 | plt.ylabel('Cost J') 91 | plt.xlabel('Iterations') 92 | plt.show() 93 | -------------------------------------------------------------------------------- /code/lihongyi/task2.py: -------------------------------------------------------------------------------- 1 | """ 2 | 实现 SGD 和 mini-batch 3 | """ 4 | import numpy as np 5 | import matplotlib.pyplot as plt 6 | 7 | class LinearRegressionGD(): 8 | def __init__(self, lr=0.0001, epochs=100): 9 | self.lr = lr 10 | self.epochs = epochs 11 | 12 | def forward(self, x): 13 | """ 14 | 预测模型 15 | """ 16 | return np.dot(x, self.w.T) + self.b 17 | 18 | def SGD(self, x, y): 19 | """ 随机梯度下降 20 | """ 21 | self.w = np.zeros((1, x.shape[1])) 22 | self.b = np.zeros((1, 1)) 23 | self.cost = [] 24 | for j in range(self.epochs): 25 | for i in range(x.shape[0]): 26 | y_hat = self.forward(x[i]) 27 | error = y_hat - y[i] 28 | self.w -= self.lr * error * x[i] 29 | self.b -= self.lr * error 30 | J = 1.0 / 2 * (np.sum(np.square(error))) 31 | self.cost.append(J) 32 | return self.w, self.b, self.cost 33 | 34 | def miniBatch(self, x, y, batch_size=20): 35 | """ 36 | 小批量梯度下降 37 | 这里每次随机获取batch_size个样本 38 | 下次获取的数据集不变是不严谨的 39 | """ 40 | self.w = np.zeros((1, x.shape[1])) 41 | self.b = np.zeros((1, 1)) 42 | self.cost = [] 43 | num = max(x.shape[0] // batch_size, 1) 44 | print(num) 45 | for i in range(self.epochs): 46 | # 将总样本划分成num个mini-batch 47 | for j in range(num): 48 | # 随机选取样本更新参数 49 | choose = np.random.choice(x.shape[0], batch_size, replace=False) 50 | x_ = x[choose] 51 | y_hat = self.forward(x_) 52 | error = y_hat - y[choose] 53 | self.w -= self.lr * np.dot(x_.T, error) 54 | self.b -= self.lr * error.sum() 55 | J = 1.0 / (2 * batch_size) * (np.sum(np.square(error))) 56 | self.cost.append(J) 57 | return self.w, self.b, self.cost 58 | 59 | X = np.linspace(0, 10, 100).reshape(100,1) 60 | y = 1+2*X + np.random.normal(0,0.5,(100,1)) 61 | 62 | 63 | gd = LinearRegressionGD(epochs=1000) 64 | # w, b, cost = gd.miniBatch(X, y, batch_size=30) 65 | w, b, cost= gd.SGD(X, y) 66 | h = b + w*X 67 | print(w, b, cost[-1]) 68 | 69 | plt.title("simple linear regression") 70 | plt.scatter(X, y, color='black') 71 | plt.plot(X, h, color='blue') 72 | plt.xlabel('x') 73 | plt.ylabel('y') 74 | plt.show() 75 | 76 | 77 | -------------------------------------------------------------------------------- /code/lihongyi/task6.py: -------------------------------------------------------------------------------- 1 | """ 2 | 自己实现逻辑回归 3 | 基于python3 4 | """ 5 | 6 | 7 | import numpy as np 8 | import matplotlib.pyplot as plt 9 | from sklearn.metrics import accuracy_score # 用于计算准备率,可以自己实现 10 | 11 | 12 | def sigmoid(z): 13 | """ sigmoid函数 14 | """ 15 | return(1 / (1 + np.exp(-z))) 16 | 17 | 18 | def costFunction(theta, X, y): 19 | """ 损失函数 20 | """ 21 | m = y.size 22 | h = sigmoid(X.dot(theta)) 23 | J = -1.0 * (1.0 / m) * (np.log(h).T.dot(y) + np.log(1 - h).T.dot(1 - y)) 24 | if np.isnan(J): 25 | return (np.inf) 26 | return J 27 | 28 | 29 | def gradient(theta, X, y): 30 | """ 求解梯度 31 | """ 32 | m = y.size 33 | h = sigmoid(X.dot(theta)) 34 | grad = (1.0 / m) * X.T.dot(h - y) 35 | return (grad) 36 | 37 | def predict(theta, X, threshold=0.5): 38 | """ 预测 39 | """ 40 | p = sigmoid(X.dot(theta)) >= threshold 41 | return (p.astype('int')) 42 | 43 | def loaddata(file, delimeter): 44 | """ 45 | 加载数据 46 | """ 47 | data = np.loadtxt(file, delimiter=delimeter) 48 | return data 49 | 50 | 51 | def gradientDescent(X, y, theta, alpha=0.01, num_iters=1500): 52 | """ 53 | 梯度下降 54 | """ 55 | J_history = np.zeros(num_iters) 56 | for iter in np.arange(num_iters): 57 | theta = theta - alpha * gradient(theta, X, y) 58 | J_history[iter] = costFunction(theta, X, y) 59 | return (theta, J_history) 60 | 61 | 62 | def MaxMinNormalization(x): 63 | """ 64 | 归一化 65 | """ 66 | Min = np.min(x) 67 | Max = np.max(x) 68 | x = (x - Min) / (Max - Min) 69 | return x 70 | 71 | def plot(X, y,res): 72 | """ 73 | 数据的分布 74 | 画出决策边界 75 | """ 76 | plt.scatter(X[y == 0, 1], X[y == 0, 2]) 77 | plt.scatter(X[y == 1, 1], X[y == 1, 2]) 78 | x1_min, x1_max = X[:, 1].min(), X[:, 1].max(), 79 | x2_min, x2_max = X[:, 2].min(), X[:, 2].max(), 80 | xx1, xx2 = np.meshgrid(np.linspace(x1_min, x1_max), np.linspace(x2_min, x2_max)) 81 | h = sigmoid(np.c_[np.ones((xx1.ravel().shape[0], 1)), xx1.ravel(), xx2.ravel()].dot(res)) 82 | h = h.reshape(xx1.shape) 83 | plt.contour(xx1, xx2, h, 1, linewidths=1, colors='b') 84 | plt.show() 85 | 86 | # 数据集每行前两列为学生两门考试的成绩,第三列为学生是否通过考试 87 | # 0 表示不通过 1 表示通过 88 | # 数据以','号隔开 89 | data = loaddata('task6_data.txt', ',') 90 | 91 | # 打乱数据 92 | # 并做归一化 93 | data = np.random.permutation(data) 94 | X_raw = data[:,0:2] 95 | X = MaxMinNormalization(X_raw) 96 | 97 | X= np.c_[np.ones((data.shape[0],1)), X] 98 | y = data[:,2] 99 | 100 | print(X, y) 101 | 102 | # 初始化参数 103 | # b = initial_theta[0] w = initial_theta[1:] 104 | initial_theta = np.zeros(X.shape[1]) 105 | lr = 0.1 106 | iteration = 30000 107 | theta , Cost_J = gradientDescent(X, y, initial_theta, alpha= lr, num_iters= iteration) 108 | print('最终b, w结果:',theta) 109 | print('准确率:', accuracy_score(y, predict(theta, X))) 110 | 111 | # 绘制损失函数下降趋势 112 | plt.plot(Cost_J) 113 | plt.ylabel('Cost J') 114 | plt.xlabel('Iterations') 115 | plt.show() 116 | 117 | # 绘制决策边界 118 | plot(X, y, theta) 119 | 120 | 121 | -------------------------------------------------------------------------------- /code/lihongyi/task6_data.txt: -------------------------------------------------------------------------------- 1 | 34.62365962451697,78.0246928153624,0 2 | 30.28671076822607,43.89499752400101,0 3 | 35.84740876993872,72.90219802708364,0 4 | 60.18259938620976,86.30855209546826,1 5 | 79.0327360507101,75.3443764369103,1 6 | 45.08327747668339,56.3163717815305,0 7 | 61.10666453684766,96.51142588489624,1 8 | 75.02474556738889,46.55401354116538,1 9 | 76.09878670226257,87.42056971926803,1 10 | 84.43281996120035,43.53339331072109,1 11 | 95.86155507093572,38.22527805795094,0 12 | 75.01365838958247,30.60326323428011,0 13 | 82.30705337399482,76.48196330235604,1 14 | 69.36458875970939,97.71869196188608,1 15 | 39.53833914367223,76.03681085115882,0 16 | 53.9710521485623,89.20735013750205,1 17 | 69.07014406283025,52.74046973016765,1 18 | 67.94685547711617,46.67857410673128,0 19 | 70.66150955499435,92.92713789364831,1 20 | 76.97878372747498,47.57596364975532,1 21 | 67.37202754570876,42.83843832029179,0 22 | 89.67677575072079,65.79936592745237,1 23 | 50.534788289883,48.85581152764205,0 24 | 34.21206097786789,44.20952859866288,0 25 | 77.9240914545704,68.9723599933059,1 26 | 62.27101367004632,69.95445795447587,1 27 | 80.1901807509566,44.82162893218353,1 28 | 93.114388797442,38.80067033713209,0 29 | 61.83020602312595,50.25610789244621,0 30 | 38.78580379679423,64.99568095539578,0 31 | 61.379289447425,72.80788731317097,1 32 | 85.40451939411645,57.05198397627122,1 33 | 52.10797973193984,63.12762376881715,0 34 | 52.04540476831827,69.43286012045222,1 35 | 40.23689373545111,71.16774802184875,0 36 | 54.63510555424817,52.21388588061123,0 37 | 33.91550010906887,98.86943574220611,0 38 | 64.17698887494485,80.90806058670817,1 39 | 74.78925295941542,41.57341522824434,0 40 | 34.1836400264419,75.2377203360134,0 41 | 83.90239366249155,56.30804621605327,1 42 | 51.54772026906181,46.85629026349976,0 43 | 94.44336776917852,65.56892160559052,1 44 | 82.36875375713919,40.61825515970618,0 45 | 51.04775177128865,45.82270145776001,0 46 | 62.22267576120188,52.06099194836679,0 47 | 77.19303492601364,70.45820000180959,1 48 | 97.77159928000232,86.7278223300282,1 49 | 62.07306379667647,96.76882412413983,1 50 | 91.56497449807442,88.69629254546599,1 51 | 79.94481794066932,74.16311935043758,1 52 | 99.2725269292572,60.99903099844988,1 53 | 90.54671411399852,43.39060180650027,1 54 | 34.52451385320009,60.39634245837173,0 55 | 50.2864961189907,49.80453881323059,0 56 | 49.58667721632031,59.80895099453265,0 57 | 97.64563396007767,68.86157272420604,1 58 | 32.57720016809309,95.59854761387875,0 59 | 74.24869136721598,69.82457122657193,1 60 | 71.79646205863379,78.45356224515052,1 61 | 75.3956114656803,85.75993667331619,1 62 | 35.28611281526193,47.02051394723416,0 63 | 56.25381749711624,39.26147251058019,0 64 | 30.05882244669796,49.59297386723685,0 65 | 44.66826172480893,66.45008614558913,0 66 | 66.56089447242954,41.09209807936973,0 67 | 40.45755098375164,97.53518548909936,1 68 | 49.07256321908844,51.88321182073966,0 69 | 80.27957401466998,92.11606081344084,1 70 | 66.74671856944039,60.99139402740988,1 71 | 32.72283304060323,43.30717306430063,0 72 | 64.0393204150601,78.03168802018232,1 73 | 72.34649422579923,96.22759296761404,1 74 | 60.45788573918959,73.09499809758037,1 75 | 58.84095621726802,75.85844831279042,1 76 | 99.82785779692128,72.36925193383885,1 77 | 47.26426910848174,88.47586499559782,1 78 | 50.45815980285988,75.80985952982456,1 79 | 60.45555629271532,42.50840943572217,0 80 | 82.22666157785568,42.71987853716458,0 81 | 88.9138964166533,69.80378889835472,1 82 | 94.83450672430196,45.69430680250754,1 83 | 67.31925746917527,66.58935317747915,1 84 | 57.23870631569862,59.51428198012956,1 85 | 80.36675600171273,90.96014789746954,1 86 | 68.46852178591112,85.59430710452014,1 87 | 42.0754545384731,78.84478600148043,0 88 | 75.47770200533905,90.42453899753964,1 89 | 78.63542434898018,96.64742716885644,1 90 | 52.34800398794107,60.76950525602592,0 91 | 94.09433112516793,77.15910509073893,1 92 | 90.44855097096364,87.50879176484702,1 93 | 55.48216114069585,35.57070347228866,0 94 | 74.49269241843041,84.84513684930135,1 95 | 89.84580670720979,45.35828361091658,1 96 | 83.48916274498238,48.38028579728175,1 97 | 42.2617008099817,87.10385094025457,1 98 | 99.31500880510394,68.77540947206617,1 99 | 55.34001756003703,64.9319380069486,1 100 | 74.77589300092767,89.52981289513276,1 101 | -------------------------------------------------------------------------------- /code/lihongyi/task7.py: -------------------------------------------------------------------------------- 1 | """ 2 | 计算信息熵 3 | """ 4 | 5 | import numpy as np 6 | import pandas as pd 7 | from collections import Counter 8 | 9 | def calcShannonEnt(data): 10 | """ 计算信息熵 11 | """ 12 | # 获取最后一列的数据 13 | labels = data[data.columns.values[-1]] 14 | # 统计所有类别对应出现的次数 15 | labelCounts = Counter(labels) 16 | # 数据已准备好,计算熵 17 | shannonEnt = 0.0 18 | dataLen = len(data) 19 | for key in labelCounts: 20 | pro = labelCounts[key] / dataLen 21 | shannonEnt -= pro * np.log2(pro) 22 | return shannonEnt 23 | 24 | data = pd.read_csv("watermelon_3a.csv") 25 | res = calcShannonEnt(data) 26 | print("香浓熵为:", res) -------------------------------------------------------------------------------- /code/lihongyi/task8.py: -------------------------------------------------------------------------------- 1 | """ 2 | 实现简单的决策树 3 | """ 4 | 5 | import numpy as np 6 | import pandas as pd 7 | from collections import Counter 8 | 9 | def calcShannonEnt(dataSet): 10 | """ 计算信息熵 11 | """ 12 | # 获取最后一列的数据 13 | labels = dataSet[:,-1] 14 | # 统计所有类别对应出现的次数 15 | labelCounts = Counter(labels) 16 | # 数据已准备好,计算熵 17 | shannonEnt = 0.0 18 | dataLen = len(dataSet) 19 | for key in labelCounts: 20 | pro = labelCounts[key] / dataLen 21 | shannonEnt -= pro * np.log2(pro) 22 | return shannonEnt 23 | 24 | def chooseFeature(dataSet): 25 | """ 26 | 选择最优属性 27 | gain = baseEntropy - newEntropy 28 | """ 29 | baseEntropy = calcShannonEnt(dataSet) # 整个数据集的信息熵 30 | bestInfoGain = 0.0 31 | bestFeature = -1 32 | # 遍历所有属性 33 | for i in range(len(dataSet[0]) -1): 34 | splitDict = Counter(dataSet[:, i]) 35 | newEntropy = 0.0 36 | for v in splitDict: 37 | subDataSet = dataSet[dataSet[:, i]==v] 38 | prob = splitDict[v]/float(len(dataSet)) 39 | newEntropy += prob * calcShannonEnt(subDataSet) 40 | gain = baseEntropy - newEntropy 41 | if gain > bestInfoGain: 42 | bestInfoGain = gain 43 | bestFeature = i 44 | return bestFeature 45 | 46 | 47 | def createTree(dataSet, feature_labels): 48 | """ 49 | 生成决策树 50 | 返回字典树 51 | dataSet: 数据集 52 | feature_labels: 属性标签 53 | """ 54 | labels = dataSet[:, -1] 55 | # 数据集样本类别相同 56 | if len(set(labels)) == 1: 57 | return labels[0] 58 | # 属性值为空或者唯一属性值相同,返回样本数最多的类别 59 | if len(dataSet[0]) == 1 or (len(dataSet[0]) == 2 and len(set(dataSet[:, 0])) == 1): 60 | resDict = dict(Counter(labels)) 61 | sortedClassCount = sorted(resDict.items(), key=lambda item: item[1], reverse=True) 62 | return sortedClassCount[0][0] 63 | 64 | # 选择最优属性 65 | bestFeat = chooseFeature(dataSet) 66 | bestFeatLabel = feature_labels[bestFeat] 67 | myTree = {bestFeatLabel:{}} 68 | del(feature_labels[bestFeat]) 69 | # 对选择属性进行划分 70 | for v in Counter(dataSet[:, bestFeat]): 71 | # 划分后的子集不应该包含我们选择属性对应的列 72 | subDataSet = np.delete(dataSet[dataSet[:, bestFeat]==v], bestFeat, axis=1) 73 | subLabels = feature_labels[:] 74 | # 生成子树 75 | myTree[bestFeatLabel][v] = createTree(subDataSet,subLabels) 76 | return myTree 77 | 78 | 79 | if __name__ == '__main__': 80 | # 读取数据集,这里忽略 ids 及 连续属性列 81 | dataset = pd.read_csv("watermelon_3a.csv", usecols=['color', 'root', 'knocks', 'texture', 'navel', 'touch', 'label']) 82 | feature_labels = list(dataset.columns) 83 | dataset = dataset.values 84 | res = createTree(dataset, feature_labels) 85 | print(res) -------------------------------------------------------------------------------- /code/lihongyi/task9.py: -------------------------------------------------------------------------------- 1 | """ 2 | 绘制树图形 3 | 4 | """ 5 | import pandas as pd 6 | from task8 import createTree 7 | import matplotlib.pyplot as plt 8 | 9 | 10 | def plotNode(text, centerPt, parentPt, nodeType): 11 | """ 12 | 绘制注解,带箭头 13 | annotate 函数用来绘制注解 14 | parentPt: 父节点位置 15 | centerPt: 被指向的位置 16 | nodeType: 节点类型 17 | """ 18 | createPlot.ax1.annotate(text, xy=parentPt, xycoords='axes fraction', 19 | xytext=centerPt, textcoords='axes fraction', 20 | va="center", ha="center", bbox=nodeType, arrowprops= {'arrowstyle': '<-'} ) 21 | 22 | 23 | # 内部节点文本框样式 24 | decisionNode = dict(boxstyle="sawtooth", fc="0.8") 25 | # 叶节点文本框样式 26 | leafNode = dict(boxstyle="round4", fc="0.8") 27 | 28 | def getNumLeafs(myTree): 29 | """ 30 | 获取叶节点的数目 31 | 确定横轴x的长度 32 | """ 33 | numLeafs = 0 34 | firstStr = list(myTree.keys())[0] 35 | secondDict = myTree[firstStr] 36 | for key in secondDict: 37 | if isinstance(secondDict[key], dict): 38 | numLeafs += getNumLeafs(secondDict[key]) 39 | else: 40 | numLeafs +=1 41 | return numLeafs 42 | 43 | 44 | def getTreeDepth(myTree): 45 | """ 46 | 获取树的深度 47 | 确定纵轴y的长度 48 | """ 49 | maxDepth = 0 50 | firstStr = list(myTree.keys())[0] 51 | secondDict = myTree[firstStr] 52 | for key in secondDict: 53 | if isinstance(secondDict[key], dict): 54 | thisDepth = 1 + getTreeDepth(secondDict[key]) 55 | else: 56 | thisDepth = 1 57 | if thisDepth > maxDepth: 58 | maxDepth = thisDepth 59 | return maxDepth 60 | 61 | 62 | def createPlot(tree): 63 | """ 64 | 创建画布 65 | """ 66 | fig = plt.figure(1, facecolor='gray') 67 | fig.clf() 68 | axprops = dict(xticks=[], yticks=[]) 69 | createPlot.ax1 = plt.subplot(111, frameon=False, **axprops) 70 | plotTree.totalW = float(getNumLeafs(tree)) 71 | plotTree.totalD = float(getTreeDepth(tree)) 72 | plotTree.xOff = -0.5/plotTree.totalW 73 | plotTree.yOff = 1.0 74 | plotTree(tree, (0.5,1.0), '') 75 | plt.show() 76 | 77 | 78 | def plotMidText(cntrPt, parentPt, txtString): 79 | """ 80 | 连线添加文字 81 | """ 82 | xMid = (parentPt[0]-cntrPt[0])/2.0 + cntrPt[0] 83 | yMid = (parentPt[1]-cntrPt[1])/2.0 + cntrPt[1] 84 | createPlot.ax1.text(xMid, yMid, txtString, va="center", ha="center", rotation=0) 85 | 86 | 87 | def plotTree(myTree, parentPt, text): 88 | """ 89 | 绘制决策树 90 | """ 91 | numLeafs = getNumLeafs(myTree) 92 | firstStr = list(myTree.keys())[0] 93 | cntrPt = (plotTree.xOff + (1.0 + float(numLeafs))/2.0/plotTree.totalW, plotTree.yOff) 94 | plotMidText(cntrPt, parentPt, text) 95 | plotNode(firstStr, cntrPt, parentPt, decisionNode) 96 | secondDict = myTree[firstStr] 97 | plotTree.yOff = plotTree.yOff - 1.0/plotTree.totalD 98 | for key in secondDict: 99 | if isinstance(secondDict[key], dict): 100 | plotTree(secondDict[key],cntrPt,str(key)) 101 | else: 102 | plotTree.xOff = plotTree.xOff + 1.0/plotTree.totalW 103 | plotNode(secondDict[key], (plotTree.xOff, plotTree.yOff), cntrPt, leafNode) 104 | plotMidText((plotTree.xOff, plotTree.yOff), cntrPt, str(key)) 105 | plotTree.yOff = plotTree.yOff + 1.0/plotTree.totalD 106 | 107 | 108 | if __name__ == '__main__': 109 | # 读取数据集,这里忽略 ids 及 连续属性列 110 | dataset = pd.read_csv("watermelon_3a.csv", usecols=['color', 'root', 'knocks', 'texture', 'navel', 'touch', 'label']) 111 | feature_labels = list(dataset.columns) 112 | dataset = dataset.values 113 | res = createTree(dataset, feature_labels) 114 | print(res) 115 | createPlot(res) -------------------------------------------------------------------------------- /code/lihongyi/watermelon_3a.csv: -------------------------------------------------------------------------------- 1 | Idx,color,root,knocks,texture,navel,touch,density,sugar_ratio,label 2 | 1,dark_green,curl_up,little_heavily,distinct,sinking,hard_smooth,0.697,0.46,1 3 | 2,black,curl_up,heavily,distinct,sinking,hard_smooth,0.774,0.376,1 4 | 3,black,curl_up,little_heavily,distinct,sinking,hard_smooth,0.634,0.264,1 5 | 4,dark_green,curl_up,heavily,distinct,sinking,hard_smooth,0.608,0.318,1 6 | 5,light_white,curl_up,little_heavily,distinct,sinking,hard_smooth,0.556,0.215,1 7 | 6,dark_green,little_curl_up,little_heavily,distinct,little_sinking,soft_stick,0.403,0.237,1 8 | 7,black,little_curl_up,little_heavily,little_blur,little_sinking,soft_stick,0.481,0.149,1 9 | 8,black,little_curl_up,little_heavily,distinct,little_sinking,hard_smooth,0.437,0.211,1 10 | 9,black,little_curl_up,heavily,little_blur,little_sinking,hard_smooth,0.666,0.091,0 11 | 10,dark_green,stiff,clear,distinct,even,soft_stick,0.243,0.267,0 12 | 11,light_white,stiff,clear,blur,even,hard_smooth,0.245,0.057,0 13 | 12,light_white,curl_up,little_heavily,blur,even,soft_stick,0.343,0.099,0 14 | 13,dark_green,little_curl_up,little_heavily,little_blur,sinking,hard_smooth,0.639,0.161,0 15 | 14,light_white,little_curl_up,heavily,little_blur,sinking,hard_smooth,0.657,0.198,0 16 | 15,black,little_curl_up,little_heavily,distinct,little_sinking,soft_stick,0.36,0.37,0 17 | 16,light_white,curl_up,little_heavily,blur,even,hard_smooth,0.593,0.042,0 18 | 17,dark_green,curl_up,heavily,little_blur,little_sinking,hard_smooth,0.719,0.103,0 19 | -------------------------------------------------------------------------------- /code/linear_regression/linear_regession_simple.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | scikit-learn 5 | 一元线性回归 6 | 举例: 7 | 经典房价问题 8 | x 房子平方英尺 9 | y 价格 10 | """ 11 | 12 | import numpy as np 13 | import matplotlib.pyplot as plt 14 | from sklearn.linear_model import LinearRegression 15 | 16 | x = [[150], [200], [250], [300], [350], [400], [600]] 17 | y = [6450,7450,8450,9540,11450,12450,17450] 18 | 19 | # training set 20 | x_train = x[:-2] 21 | y_train = y[:-2] 22 | 23 | # test set 24 | x_test = x[-2:] 25 | y_test = y[-2:] 26 | 27 | # training 28 | model = LinearRegression() 29 | model.fit(x_train, y_train) 30 | print("系数:{} 截距:{} 方差:{}".format(model.coef_, model.intercept_, np.mean((model.predict(x_test)-y_test)**2))) 31 | print("预测结果:{} 得分:{}".format(model.predict(x_test), model.score(x_test, y_test))) 32 | 33 | plt.title("simple linear regression") 34 | plt.scatter(x, y, color='black') 35 | plt.plot(x, model.predict(x), color='blue') 36 | plt.xlabel('x') 37 | plt.ylabel('price') 38 | plt.show() 39 | 40 | -------------------------------------------------------------------------------- /code/linear_regression/linear_regression_multi.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | scikit-learn 5 | 多元线性回归 6 | 7 | """ 8 | 9 | import numpy as np 10 | from numpy.linalg import inv 11 | from numpy import dot, transpose 12 | import matplotlib.pyplot as plt 13 | from sklearn.linear_model import LinearRegression 14 | 15 | def get_ceot(x,y): 16 | """ 17 | 根据x,y求解多元线性方程 18 | """ 19 | return dot(inv(dot(transpose(x), x)), dot(transpose(x),y)) 20 | 21 | x = 100 * np.random.rand(100,3) 22 | y = dot(x, [1,2,3]) + np.random.randn(100) 23 | 24 | # training set 25 | x_train = x[:-2] 26 | y_train = y[:-2] 27 | 28 | # test set 29 | x_test = x[-2:] 30 | y_test = y[-2:] 31 | 32 | # training 33 | model = LinearRegression() 34 | model.fit(x_train, y_train) 35 | print("系数:{} 截距:{} 方差:{}".format(model.coef_, model.intercept_, np.mean((model.predict(x_test)-y_test)**2))) 36 | print("预测结果:{} 得分:{}".format(model.predict(x_test), model.score(x_test, y_test))) 37 | 38 | plt.title("multi linear regression") 39 | plt.scatter(x[:,2], y, color='black') 40 | plt.xlabel('x') 41 | plt.ylabel('y') 42 | plt.show() 43 | 44 | 45 | -------------------------------------------------------------------------------- /code/linear_regression/linear_regression_polynomial.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | 多项式回归问题 5 | 可以通过调整degree参数来比较训练后的结果 6 | 并以此判断哪种是最合适的模型 7 | 但是要防止过拟合现象 8 | """ 9 | 10 | import numpy as np 11 | import matplotlib.pyplot as plt 12 | from sklearn.linear_model import LinearRegression 13 | from sklearn.preprocessing import PolynomialFeatures 14 | 15 | # 代表使用几次多项式回归模型 16 | degree = 2 17 | 18 | # 自己构造数据集 19 | x = np.linspace(5, 30, 20) 20 | y = (5+ x**2) + np.random.randn(20) * 5 21 | x = x[:,np.newaxis] 22 | 23 | # training set 24 | x_train = x[:-2] 25 | y_train = y[:-2] 26 | 27 | # test set 28 | x_test = x[-2:] 29 | y_test = y[-2:] 30 | 31 | # 用多项式对x做变换 degree代表 n次多项式 32 | quadratic_featurizer = PolynomialFeatures(degree=degree) 33 | x_quadratic = quadratic_featurizer.fit_transform(x) 34 | x_train_quadratic = x_quadratic[:-2] 35 | x_test_quadratic = x_quadratic[-2:] 36 | regressor_quadratic = LinearRegression() 37 | regressor_quadratic.fit(x_train_quadratic, y_train) 38 | 39 | print("系数:{} 误差:{}".format(regressor_quadratic.coef_, regressor_quadratic.intercept_)) 40 | print("预测结果:{} 得分:{}".format(regressor_quadratic.predict(x_test_quadratic), regressor_quadratic.score(x_test_quadratic, y_test))) 41 | 42 | 43 | plt.scatter(x, y, color='black') 44 | plt.plot(x, regressor_quadratic.predict(x_quadratic), 'g-') 45 | plt.show() # 展示图像 -------------------------------------------------------------------------------- /code/linear_regression/m_lr.py: -------------------------------------------------------------------------------- 1 | """ 2 | 自己实现 3 | 梯度下降解决线性回归问题 4 | """ 5 | 6 | 7 | 8 | import numpy as np 9 | import matplotlib.pyplot as plt 10 | 11 | 12 | def costFunction(X, y, theta=[0, 0]): 13 | """ 14 | 损失函数 15 | """ 16 | m = y.size 17 | h = X.dot(theta) 18 | J = 1.0 / (2 * m) * (np.sum(np.square(h - y))) 19 | return J 20 | 21 | def gradientDescent(X, y, theta=[0, 0], alpha=0.01, num_iters=1500): 22 | """ 23 | 梯度下降 24 | """ 25 | m = y.size 26 | J_history = np.zeros(num_iters) 27 | for iter in np.arange(num_iters): 28 | h = X.dot(theta) 29 | theta = theta - alpha * (1.0 / m) * (X.T.dot(h - y)) 30 | J_history[iter] = costFunction(X, y, theta) 31 | return (theta, J_history) 32 | 33 | 34 | def MaxMinNormalization(x): 35 | """ 36 | 归一化 37 | """ 38 | Min = np.min(x) 39 | Max = np.max(x) 40 | x = (x - Min) / (Max - Min) 41 | return x 42 | 43 | # 使用外部训练集 44 | # data = np.loadtxt('linear_regression_data1.txt', delimiter=',') 45 | # X = np.c_[np.ones(data.shape[0]),data[:,0]] 46 | # y = data[:,1] 47 | 48 | # 自己构造数据集 49 | X_row = 100 * np.random.rand(100) 50 | X = MaxMinNormalization(X_row) 51 | y = 0.5*X + 2 + np.random.normal(0,0.01,(100,)) 52 | 53 | # 数据可视化 54 | plt.subplot(1, 2, 1) 55 | plt.scatter(X_row, y, color='black') 56 | plt.xlabel('x') 57 | plt.ylabel('y') 58 | 59 | 60 | X = np.c_[np.ones((X.shape[0],1)), X] 61 | 62 | 63 | # training set 64 | X_train = X[:80] 65 | y_train = y[:80] 66 | # test set 67 | X_test = X[80:] 68 | y_test = y[80:] 69 | 70 | 71 | 72 | print(costFunction(X,y)) 73 | 74 | b = 0 75 | w = 0 76 | lr = 0.01 77 | iteration = 10000 78 | 79 | # 画出每一次迭代和损失函数变化 80 | theta , Cost_J = gradientDescent(X_train, y_train, theta=[b, w], alpha= lr, num_iters= iteration) 81 | 82 | print('最终b, w结果: ',theta) 83 | testCost = costFunction(X_test, y_test, theta) 84 | print('测试集误差: ',testCost) 85 | 86 | h = X.dot(theta) 87 | plt.plot(X_row, h, "b--") 88 | plt.subplot(1, 2, 2) 89 | plt.plot(Cost_J) 90 | plt.ylabel('Cost J') 91 | plt.xlabel('Iterations') 92 | plt.show() 93 | -------------------------------------------------------------------------------- /code/linear_regression/sgd_regression.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | scikit-learn 5 | 随机梯度下降 6 | 随机梯度下降法相比批量梯度下降,每次用一个样本调整参数,逐渐逼近,效率高 7 | """ 8 | 9 | import numpy as np 10 | import matplotlib.pyplot as plt 11 | from sklearn.linear_model import SGDRegressor 12 | from sklearn.preprocessing import StandardScaler 13 | 14 | # 数据多才可以更好的拟合 15 | x = [[150], [200], [250], [300], [350], [400], [600]] * 100 16 | y = [[6450],[7450],[8450],[9540],[11450],[12450],[17450]] * 100 17 | 18 | # 正则化 将特征映射到方差为1 均值为0的标准正太分布中去 19 | x_scaler = StandardScaler() 20 | y_scaler = StandardScaler() 21 | x = x_scaler.fit_transform(x) 22 | y = y_scaler.fit_transform(y) 23 | 24 | # training set 25 | x_train = x[:-2] 26 | y_train = y[:-2] 27 | 28 | # test set 29 | x_test = x[-2:] 30 | y_test = y[-2:] 31 | 32 | # training 33 | model = SGDRegressor() 34 | model.fit(x_train, y_train.ravel()) 35 | print("系数:{} 截距:{} 方差:{}".format(model.coef_, model.intercept_, np.mean((model.predict(x_test)-y_test)**2))) 36 | print("预测结果:{} 得分:{}".format(model.predict(x_test), model.score(x_test, y_test))) 37 | 38 | plt.title("simple linear regression") 39 | plt.scatter(x, y, color='black') 40 | plt.plot(x, model.predict(x), color='blue') 41 | plt.xlabel('x') 42 | plt.ylabel('price') 43 | plt.show() -------------------------------------------------------------------------------- /code/logistic_regression/data1.txt: -------------------------------------------------------------------------------- 1 | 34.62365962451697,78.0246928153624,0 2 | 30.28671076822607,43.89499752400101,0 3 | 35.84740876993872,72.90219802708364,0 4 | 60.18259938620976,86.30855209546826,1 5 | 79.0327360507101,75.3443764369103,1 6 | 45.08327747668339,56.3163717815305,0 7 | 61.10666453684766,96.51142588489624,1 8 | 75.02474556738889,46.55401354116538,1 9 | 76.09878670226257,87.42056971926803,1 10 | 84.43281996120035,43.53339331072109,1 11 | 95.86155507093572,38.22527805795094,0 12 | 75.01365838958247,30.60326323428011,0 13 | 82.30705337399482,76.48196330235604,1 14 | 69.36458875970939,97.71869196188608,1 15 | 39.53833914367223,76.03681085115882,0 16 | 53.9710521485623,89.20735013750205,1 17 | 69.07014406283025,52.74046973016765,1 18 | 67.94685547711617,46.67857410673128,0 19 | 70.66150955499435,92.92713789364831,1 20 | 76.97878372747498,47.57596364975532,1 21 | 67.37202754570876,42.83843832029179,0 22 | 89.67677575072079,65.79936592745237,1 23 | 50.534788289883,48.85581152764205,0 24 | 34.21206097786789,44.20952859866288,0 25 | 77.9240914545704,68.9723599933059,1 26 | 62.27101367004632,69.95445795447587,1 27 | 80.1901807509566,44.82162893218353,1 28 | 93.114388797442,38.80067033713209,0 29 | 61.83020602312595,50.25610789244621,0 30 | 38.78580379679423,64.99568095539578,0 31 | 61.379289447425,72.80788731317097,1 32 | 85.40451939411645,57.05198397627122,1 33 | 52.10797973193984,63.12762376881715,0 34 | 52.04540476831827,69.43286012045222,1 35 | 40.23689373545111,71.16774802184875,0 36 | 54.63510555424817,52.21388588061123,0 37 | 33.91550010906887,98.86943574220611,0 38 | 64.17698887494485,80.90806058670817,1 39 | 74.78925295941542,41.57341522824434,0 40 | 34.1836400264419,75.2377203360134,0 41 | 83.90239366249155,56.30804621605327,1 42 | 51.54772026906181,46.85629026349976,0 43 | 94.44336776917852,65.56892160559052,1 44 | 82.36875375713919,40.61825515970618,0 45 | 51.04775177128865,45.82270145776001,0 46 | 62.22267576120188,52.06099194836679,0 47 | 77.19303492601364,70.45820000180959,1 48 | 97.77159928000232,86.7278223300282,1 49 | 62.07306379667647,96.76882412413983,1 50 | 91.56497449807442,88.69629254546599,1 51 | 79.94481794066932,74.16311935043758,1 52 | 99.2725269292572,60.99903099844988,1 53 | 90.54671411399852,43.39060180650027,1 54 | 34.52451385320009,60.39634245837173,0 55 | 50.2864961189907,49.80453881323059,0 56 | 49.58667721632031,59.80895099453265,0 57 | 97.64563396007767,68.86157272420604,1 58 | 32.57720016809309,95.59854761387875,0 59 | 74.24869136721598,69.82457122657193,1 60 | 71.79646205863379,78.45356224515052,1 61 | 75.3956114656803,85.75993667331619,1 62 | 35.28611281526193,47.02051394723416,0 63 | 56.25381749711624,39.26147251058019,0 64 | 30.05882244669796,49.59297386723685,0 65 | 44.66826172480893,66.45008614558913,0 66 | 66.56089447242954,41.09209807936973,0 67 | 40.45755098375164,97.53518548909936,1 68 | 49.07256321908844,51.88321182073966,0 69 | 80.27957401466998,92.11606081344084,1 70 | 66.74671856944039,60.99139402740988,1 71 | 32.72283304060323,43.30717306430063,0 72 | 64.0393204150601,78.03168802018232,1 73 | 72.34649422579923,96.22759296761404,1 74 | 60.45788573918959,73.09499809758037,1 75 | 58.84095621726802,75.85844831279042,1 76 | 99.82785779692128,72.36925193383885,1 77 | 47.26426910848174,88.47586499559782,1 78 | 50.45815980285988,75.80985952982456,1 79 | 60.45555629271532,42.50840943572217,0 80 | 82.22666157785568,42.71987853716458,0 81 | 88.9138964166533,69.80378889835472,1 82 | 94.83450672430196,45.69430680250754,1 83 | 67.31925746917527,66.58935317747915,1 84 | 57.23870631569862,59.51428198012956,1 85 | 80.36675600171273,90.96014789746954,1 86 | 68.46852178591112,85.59430710452014,1 87 | 42.0754545384731,78.84478600148043,0 88 | 75.47770200533905,90.42453899753964,1 89 | 78.63542434898018,96.64742716885644,1 90 | 52.34800398794107,60.76950525602592,0 91 | 94.09433112516793,77.15910509073893,1 92 | 90.44855097096364,87.50879176484702,1 93 | 55.48216114069585,35.57070347228866,0 94 | 74.49269241843041,84.84513684930135,1 95 | 89.84580670720979,45.35828361091658,1 96 | 83.48916274498238,48.38028579728175,1 97 | 42.2617008099817,87.10385094025457,1 98 | 99.31500880510394,68.77540947206617,1 99 | 55.34001756003703,64.9319380069486,1 100 | 74.77589300092767,89.52981289513276,1 101 | -------------------------------------------------------------------------------- /code/logistic_regression/data2.txt: -------------------------------------------------------------------------------- 1 | 0.051267,0.69956,1 2 | -0.092742,0.68494,1 3 | -0.21371,0.69225,1 4 | -0.375,0.50219,1 5 | -0.51325,0.46564,1 6 | -0.52477,0.2098,1 7 | -0.39804,0.034357,1 8 | -0.30588,-0.19225,1 9 | 0.016705,-0.40424,1 10 | 0.13191,-0.51389,1 11 | 0.38537,-0.56506,1 12 | 0.52938,-0.5212,1 13 | 0.63882,-0.24342,1 14 | 0.73675,-0.18494,1 15 | 0.54666,0.48757,1 16 | 0.322,0.5826,1 17 | 0.16647,0.53874,1 18 | -0.046659,0.81652,1 19 | -0.17339,0.69956,1 20 | -0.47869,0.63377,1 21 | -0.60541,0.59722,1 22 | -0.62846,0.33406,1 23 | -0.59389,0.005117,1 24 | -0.42108,-0.27266,1 25 | -0.11578,-0.39693,1 26 | 0.20104,-0.60161,1 27 | 0.46601,-0.53582,1 28 | 0.67339,-0.53582,1 29 | -0.13882,0.54605,1 30 | -0.29435,0.77997,1 31 | -0.26555,0.96272,1 32 | -0.16187,0.8019,1 33 | -0.17339,0.64839,1 34 | -0.28283,0.47295,1 35 | -0.36348,0.31213,1 36 | -0.30012,0.027047,1 37 | -0.23675,-0.21418,1 38 | -0.06394,-0.18494,1 39 | 0.062788,-0.16301,1 40 | 0.22984,-0.41155,1 41 | 0.2932,-0.2288,1 42 | 0.48329,-0.18494,1 43 | 0.64459,-0.14108,1 44 | 0.46025,0.012427,1 45 | 0.6273,0.15863,1 46 | 0.57546,0.26827,1 47 | 0.72523,0.44371,1 48 | 0.22408,0.52412,1 49 | 0.44297,0.67032,1 50 | 0.322,0.69225,1 51 | 0.13767,0.57529,1 52 | -0.0063364,0.39985,1 53 | -0.092742,0.55336,1 54 | -0.20795,0.35599,1 55 | -0.20795,0.17325,1 56 | -0.43836,0.21711,1 57 | -0.21947,-0.016813,1 58 | -0.13882,-0.27266,1 59 | 0.18376,0.93348,0 60 | 0.22408,0.77997,0 61 | 0.29896,0.61915,0 62 | 0.50634,0.75804,0 63 | 0.61578,0.7288,0 64 | 0.60426,0.59722,0 65 | 0.76555,0.50219,0 66 | 0.92684,0.3633,0 67 | 0.82316,0.27558,0 68 | 0.96141,0.085526,0 69 | 0.93836,0.012427,0 70 | 0.86348,-0.082602,0 71 | 0.89804,-0.20687,0 72 | 0.85196,-0.36769,0 73 | 0.82892,-0.5212,0 74 | 0.79435,-0.55775,0 75 | 0.59274,-0.7405,0 76 | 0.51786,-0.5943,0 77 | 0.46601,-0.41886,0 78 | 0.35081,-0.57968,0 79 | 0.28744,-0.76974,0 80 | 0.085829,-0.75512,0 81 | 0.14919,-0.57968,0 82 | -0.13306,-0.4481,0 83 | -0.40956,-0.41155,0 84 | -0.39228,-0.25804,0 85 | -0.74366,-0.25804,0 86 | -0.69758,0.041667,0 87 | -0.75518,0.2902,0 88 | -0.69758,0.68494,0 89 | -0.4038,0.70687,0 90 | -0.38076,0.91886,0 91 | -0.50749,0.90424,0 92 | -0.54781,0.70687,0 93 | 0.10311,0.77997,0 94 | 0.057028,0.91886,0 95 | -0.10426,0.99196,0 96 | -0.081221,1.1089,0 97 | 0.28744,1.087,0 98 | 0.39689,0.82383,0 99 | 0.63882,0.88962,0 100 | 0.82316,0.66301,0 101 | 0.67339,0.64108,0 102 | 1.0709,0.10015,0 103 | -0.046659,-0.57968,0 104 | -0.23675,-0.63816,0 105 | -0.15035,-0.36769,0 106 | -0.49021,-0.3019,0 107 | -0.46717,-0.13377,0 108 | -0.28859,-0.060673,0 109 | -0.61118,-0.067982,0 110 | -0.66302,-0.21418,0 111 | -0.59965,-0.41886,0 112 | -0.72638,-0.082602,0 113 | -0.83007,0.31213,0 114 | -0.72062,0.53874,0 115 | -0.59389,0.49488,0 116 | -0.48445,0.99927,0 117 | -0.0063364,0.99927,0 118 | 0.63265,-0.030612,0 -------------------------------------------------------------------------------- /code/logistic_regression/logistic_regression_regularization.py: -------------------------------------------------------------------------------- 1 | """ 2 | 逻辑回归 3 | 正则化 4 | """ 5 | import numpy as np 6 | import matplotlib.pyplot as plt 7 | from scipy.optimize import minimize 8 | from sklearn.preprocessing import PolynomialFeatures 9 | 10 | 11 | def loaddata(file, delimeter): 12 | """ 13 | 加载数据 14 | """ 15 | data = np.loadtxt(file, delimiter=delimeter) 16 | return data 17 | 18 | #定义sigmoid函数 19 | def sigmoid(z): 20 | return(1.0 / (1 + np.exp(-z))) 21 | 22 | 23 | # 定义损失函数 24 | def costFunction(theta, reg, X, y): 25 | m = y.size 26 | h = sigmoid(X.dot(theta)) 27 | J = -1.0 * (1.0 / m) * (np.log(h).T.dot(y) + np.log(1 - h).T.dot(1 - y)) + (reg/(2.0*m))*np.sum(np.square(theta[1:])) 28 | if np.isnan(J): 29 | return (np.inf) 30 | return J 31 | 32 | # 求解梯度 33 | def gradient(theta, reg, X, y): 34 | m = y.size 35 | h = sigmoid(X.dot(theta)) 36 | temp = np.zeros(theta.shape[0]) 37 | temp[0] = 0 38 | temp[1:] = theta[1:] 39 | grad = (1.0 / m) * X.T.dot(h - y) + (reg / m) * temp 40 | return (grad) 41 | 42 | def predict(theta, X, threshold=0.5): 43 | """ 44 | 预测 45 | """ 46 | p = sigmoid(X.dot(theta.T)) >= threshold 47 | return(p.astype('int')) 48 | 49 | def plot(X, y, axes=None): 50 | """ 51 | 数据的分布 52 | """ 53 | if axes == None: 54 | axes = plt.gca() 55 | axes.scatter(X[y == 0, 1], X[y == 0, 2]) 56 | axes.scatter(X[y == 1, 1], X[y == 1, 2]) 57 | 58 | 59 | data = loaddata('data2.txt', ',') 60 | 61 | X = np.c_[np.ones((data.shape[0],1)), data[:,0:2]] 62 | y = data[:,2] 63 | 64 | # plt.scatter(X[y == 0, 1], X[y == 0, 2]) 65 | # plt.scatter(X[y == 1, 1], X[y == 1, 2]) 66 | # plt.show() 67 | 68 | poly = PolynomialFeatures(6) 69 | XX = poly.fit_transform(data[:,0:2]) 70 | 71 | initial_theta = np.zeros(XX.shape[1]) 72 | cost = costFunction(initial_theta,1, XX, y) 73 | print(cost) 74 | 75 | fig, axes = plt.subplots(1, 3, sharey=True, figsize=(17, 5)) 76 | 77 | # Lambda = 0 : 没有正则化,过拟合 78 | # Lambda = 1 : 正常 79 | # Lambda = 100 : 正则化项太大,没拟合出决策边界 80 | for i, C in enumerate([0.0, 1.0, 100.0]): 81 | # 最优化 costFunctionReg 82 | res = minimize(costFunction, initial_theta, args=(C, XX, y), jac=gradient, options={'maxiter': 3000}) 83 | 84 | print(res.x) 85 | # 准确率 86 | accuracy = 100.0 * sum(predict(res.x, XX) == y.ravel()) / y.size 87 | # 对X,y的散列绘图 88 | plot(X, y, axes.flatten()[i]) 89 | # 画出决策边界 90 | x1_min, x1_max = X[:, 1].min(), X[:, 1].max(), 91 | x2_min, x2_max = X[:, 2].min(), X[:, 2].max(), 92 | xx1, xx2 = np.meshgrid(np.linspace(x1_min, x1_max), np.linspace(x2_min, x2_max)) 93 | h = sigmoid(poly.fit_transform(np.c_[xx1.ravel(), xx2.ravel()]).dot(res.x)) 94 | h = h.reshape(xx1.shape) 95 | axes.flatten()[i].contour(xx1, xx2, h, [0.5], linewidths=1, colors='g') 96 | axes.flatten()[i].set_title('Train accuracy {}% with Lambda = {}'.format(np.round(accuracy, decimals=2), C)) 97 | plt.show() -------------------------------------------------------------------------------- /code/logistic_regression/logistic_regression_simple.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | 逻辑回归用于线性模型 5 | """ 6 | 7 | import numpy as np 8 | import matplotlib.pyplot as plt 9 | from scipy.optimize import minimize 10 | 11 | #定义sigmoid函数 12 | def sigmoid(z): 13 | return(1 / (1 + np.exp(-z))) 14 | 15 | 16 | # 定义损失函数 17 | def costFunction(theta, X, y): 18 | m = y.size 19 | h = sigmoid(X.dot(theta)) 20 | J = -1.0 * (1.0 / m) * (np.log(h).T.dot(y) + np.log(1 - h).T.dot(1 - y)) 21 | if np.isnan(J): 22 | return (np.inf) 23 | return J 24 | 25 | 26 | # 求解梯度 27 | def gradient(theta, X, y): 28 | m = y.size 29 | h = sigmoid(X.dot(theta)) 30 | grad = (1.0 / m) * X.T.dot(h - y) 31 | return (grad) 32 | 33 | def predict(theta, X, threshold=0.5): 34 | """ 35 | 预测 36 | """ 37 | p = sigmoid(X.dot(theta.T)) >= threshold 38 | return(p.astype('int')) 39 | 40 | 41 | def loaddata(file, delimeter): 42 | """ 43 | 加载数据 44 | """ 45 | data = np.loadtxt(file, delimiter=delimeter) 46 | return data 47 | 48 | def plot(X, y,res): 49 | """ 50 | 数据的分布 51 | """ 52 | plt.scatter(X[y == 0, 1], X[y == 0, 2]) 53 | plt.scatter(X[y == 1, 1], X[y == 1, 2]) 54 | 55 | plt.scatter(45, 85, s=60, c='r', marker='v', label='(45, 85)') 56 | x1_min, x1_max = X[:, 1].min(), X[:, 1].max(), 57 | x2_min, x2_max = X[:, 2].min(), X[:, 2].max(), 58 | xx1, xx2 = np.meshgrid(np.linspace(x1_min, x1_max), np.linspace(x2_min, x2_max)) 59 | 60 | h = sigmoid(np.c_[np.ones((xx1.ravel().shape[0], 1)), xx1.ravel(), xx2.ravel()].dot(res.x)) 61 | h = h.reshape(xx1.shape) 62 | plt.contour(xx1, xx2, h, 1, linewidths=1, colors='b') 63 | 64 | plt.show() 65 | 66 | # 考试1成绩 考试2成绩 是否通过 67 | data = loaddata('data1.txt', ',') 68 | 69 | X = np.c_[np.ones((data.shape[0],1)), data[:,0:2]] 70 | y = data[:,2] 71 | 72 | 73 | 74 | initial_theta = np.zeros(X.shape[1]) 75 | cost = costFunction(initial_theta, X, y) 76 | grad = gradient(initial_theta, X, y) 77 | # print('Cost: \n', cost) 78 | # print('Grad: \n', grad) 79 | 80 | res = minimize(costFunction, initial_theta, args=(X,y), jac=gradient, options={'maxiter':400}) 81 | print(res.x) 82 | 83 | plot(X,y,res) 84 | -------------------------------------------------------------------------------- /code/mat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding:utf8 -*- 3 | 4 | """ 5 | 画图分析 6 | 定性数据说明的是事物的品质特征,是不能用数值表示的,通常表现为类别. 7 | 定量数据说明的是现象的数量特征,是必须用数值来表现的. 8 | """ 9 | 10 | from numpy import array 11 | from numpy.random import normal 12 | from matplotlib import pyplot 13 | 14 | def genData(): 15 | heights = [] 16 | weights = [] 17 | grades = [] 18 | N = 10000 19 | 20 | for i in range(N): 21 | while True: 22 | #身高服从均值172,标准差为6的正态分布 23 | height = normal(172, 6) 24 | if 0 < height: break 25 | while True: 26 | #体重由身高作为自变量的线性回归模型产生,误差服从标准正态分布 27 | weight = (height - 80) * 0.7 + normal(0, 1) 28 | if 0 < weight: break 29 | while True: 30 | #分数服从均值为70,标准差为15的正态分布 31 | score = normal(70, 15) 32 | if 0 <= score and score <= 100: 33 | grade = 'E' if score < 60 else ('D' if score < 70 else ('C' if score < 80 else ('B' if score < 90 else 'A'))) 34 | break 35 | heights.append(height) 36 | weights.append(weight) 37 | grades.append(grade) 38 | return array(heights), array(weights), array(grades) 39 | 40 | heights, weights, grades = genData() 41 | print(grades) 42 | 43 | 44 | #绘制柱状图 45 | def drawBar(grades): 46 | xticks = ['A', 'B', 'C', 'D', 'E'] 47 | gradeGroup = {} 48 | #对每一类成绩进行频数统计 49 | for grade in grades: 50 | gradeGroup[grade] = gradeGroup.get(grade, 0) + 1 51 | #创建柱状图 52 | #第一个参数为柱的横坐标 53 | #第二个参数为柱的高度 54 | #参数align为柱的对齐方式,以第一个参数为参考标准 55 | pyplot.bar(range(5), [gradeGroup.get(xtick, 0) for xtick in xticks], align='center') 56 | 57 | #设置柱的文字说明 58 | #第一个参数为文字说明的横坐标 59 | #第二个参数为文字说明的内容 60 | pyplot.xticks(range(5), xticks) 61 | 62 | #设置横坐标的文字说明 63 | pyplot.xlabel('Grade') 64 | #设置纵坐标的文字说明 65 | pyplot.ylabel('Frequency') 66 | #设置标题 67 | pyplot.title('Grades Of Male Students') 68 | #绘图 69 | pyplot.show() 70 | 71 | 72 | #绘制饼形图 73 | def drawPie(grades): 74 | labels = ['A', 'B', 'C', 'D', 'E'] 75 | gradeGroup = {} 76 | for grade in grades: 77 | gradeGroup[grade] = gradeGroup.get(grade, 0) + 1 78 | #创建饼形图 79 | #第一个参数为扇形的面积 80 | #labels参数为扇形的说明文字 81 | #autopct参数为扇形占比的显示格式 82 | pyplot.pie([gradeGroup.get(label, 0) for label in labels], labels=labels, autopct='%1.1f%%') 83 | pyplot.title('Grades Of Male Students') 84 | pyplot.show() 85 | 86 | # 绘制直方图 87 | def drawHist(heights): 88 | # 创建直方图 89 | # 第一个参数为待绘制的定量数据,不同于定性数据,这里并没有事先进行频数统计 90 | # 第二个参数为划分的区间个数 91 | pyplot.hist(heights, 100) 92 | pyplot.xlabel('Heights') 93 | pyplot.ylabel('Frequency') 94 | pyplot.title('Heights Of Male Students') 95 | pyplot.show() 96 | 97 | # drawHist(heights) 98 | 99 | 100 | # 绘制散点图 -- 关系分析 101 | def drawScatter(heights, weights): 102 | # 创建散点图 103 | # 第一个参数为点的横坐标 104 | # 第二个参数为点的纵坐标 105 | pyplot.scatter(heights, weights) 106 | pyplot.xlabel('Heights') 107 | pyplot.ylabel('Weights') 108 | pyplot.title('Heights & Weights Of Male Students') 109 | pyplot.show() 110 | 111 | # drawScatter(heights, weights) 112 | 113 | #绘制箱形图 114 | def drawBox(heights): 115 | #创建箱形图 116 | #第一个参数为待绘制的定量数据 117 | #第二个参数为数据的文字说明 118 | pyplot.boxplot([heights], labels=['Heights']) 119 | pyplot.title('Heights Of Male Students') 120 | pyplot.show() 121 | 122 | drawBox(heights) 123 | 124 | # drawBar(grades) 125 | # drawPie(grades) -------------------------------------------------------------------------------- /code/mnlp.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | nltk为我们提供了一些内建语料库 5 | 1 孤立语料库 6 | gutenberg 7 | webtext: 网络文本语料库,网络和聊天文本 8 | 2 分类语料库 9 | brown: 布朗语料库,按照文本分类好的500个不同来源的文本 10 | 3 重叠语料库 11 | reuters: 路透社语料库,1万多个新闻文档 12 | 4 时序语料库 13 | inaugural: 就职演说语料库,55个总统的演说 14 | 15 | 通用接口: 16 | fileids():返回语料库中的文件 17 | 18 | categories():返回语料库中的分类 19 | 20 | raw():返回语料库的原始内容 21 | 22 | words():返回语料库中的词汇 23 | 24 | sents():返回语料库句子 25 | 26 | abspath():指定文件在磁盘上的位置 27 | 28 | open():打开语料库的文件流 29 | 30 | 31 | """ 32 | 33 | import nltk 34 | 35 | print(nltk.corpus.gutenberg.fileids()) 36 | 37 | # 输出文章的原始内容 38 | data = nltk.corpus.gutenberg.raw('chesterton-brown.txt') 39 | print(data) 40 | 41 | # 输出文章的单词列表 42 | data = nltk.corpus.gutenberg.words('chesterton-brown.txt') 43 | print(data) 44 | 45 | # 输出文章的句子列表 46 | data = nltk.corpus.gutenberg.sents('chesterton-brown.txt') 47 | print(data) -------------------------------------------------------------------------------- /code/nlp/senti_analysis/data/adverb_dict.txt: -------------------------------------------------------------------------------- 1 | 超级 2 2 | 超 2 3 | 都 1.75 4 | 还 1.5 5 | 实在 1.75 6 | 越来越 2 7 | 再也 2 8 | 完全 2 9 | 真是 1.75 10 | 足足 1.75 11 | 大大的 1.75 12 | 巨 2 13 | 最最 2 14 | 老是 1.75 15 | 压根 1.75 16 | 明显 1.5 17 | 18 | 19 | 最 2 20 | 最为 2 21 | 太 2 22 | 极 2 23 | 极为 2 24 | 极其 2 25 | 极度 2 26 | 极端 2 27 | 至 2 28 | 至为 2 29 | 顶 2 30 | 过于 2 31 | 过分 2 32 | 分外 2 33 | 万分 2 34 | 根本 2 35 | 更 1.75 36 | 更加 1.75 37 | 更其 1.75 38 | 越 1.75 39 | 越发 1.75 40 | 备加 1.75 41 | 愈 1.75 42 | 愈加 1.75 43 | 愈发 1.75 44 | 愈为 1.75 45 | 愈益 1.75 46 | 越加 1.75 47 | 格外 1.75 48 | 益发 1.75 49 | 很 1.75 50 | 挺 1.75 51 | 怪 1.75 52 | 非常 1.75 53 | 特别 1.75 54 | 相当 1.75 55 | 十分 1.75 56 | 好不 1.75 57 | 甚 1.75 58 | 甚为 1.75 59 | 颇 1.75 60 | 颇为 1.75 61 | 异常 1.75 62 | 深为 1.75 63 | 满 1.75 64 | 蛮 1.75 65 | 够 1.75 66 | 多 1.75 67 | 多么 1.75 68 | 殊特 1.75 69 | 大 1.75 70 | 大为 1.75 71 | 何等 1.75 72 | 何其 1.75 73 | 尤其 1.75 74 | 无比尤为 1.75 75 | 不胜 1.75 76 | 较 1.5 77 | 蛮 1.5 78 | 比较 1.5 79 | 较比 1.5 80 | 较为 1.5 81 | 不大 1.5 82 | 不太 1.5 83 | 不很 1.5 84 | 不甚 1.5 85 | 稍 0.8 86 | 稍稍 0.8 87 | 稍微 0.8 88 | 稍为 0.8 89 | 稍许 0.8 90 | 略 0.8 91 | 略略 0.8 92 | 略微 0.8 93 | 略为 0.8 94 | 些微 0.8 95 | 多少 0.8 96 | 有点 0.8 97 | 有些 0.8 -------------------------------------------------------------------------------- /code/nlp/senti_analysis/data/license.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/code/nlp/senti_analysis/data/license.txt -------------------------------------------------------------------------------- /code/nlp/senti_analysis/data/not.txt: -------------------------------------------------------------------------------- 1 | 不大 2 | 不丁点儿 3 | 不甚 4 | 不怎么 5 | 聊 6 | 没怎么 7 | 不可以 8 | 怎么不 9 | 几乎不 10 | 从来不 11 | 从不 12 | 不用 13 | 不曾 14 | 不该 15 | 不必 16 | 不会 17 | 不好 18 | 不能 19 | 很少 20 | 极少 21 | 没有 22 | 不是 23 | 难以 24 | 放下 25 | 扼杀 26 | 终止 27 | 停止 28 | 放弃 29 | 反对 30 | 缺乏 31 | 缺少 32 | 不 33 | 甭 34 | 勿 35 | 别 36 | 未 37 | 反 38 | 没 39 | 否 40 | 木有 41 | 非 42 | 无 43 | 请勿 44 | 无须 45 | 并非 46 | 毫无 47 | 决不 48 | 休想 49 | 永不 50 | 不要 51 | 未尝 52 | 未曾 53 | 毋 54 | 莫 55 | 从未 56 | 从未有过 57 | 尚未 58 | 一无 59 | 并未 60 | 尚无 61 | 从没 62 | 绝非 63 | 远非 64 | 切莫 65 | 绝不 66 | 毫不 67 | 禁止 68 | 忌 69 | 拒绝 70 | 杜绝 71 | 弗 72 | -------------------------------------------------------------------------------- /code/nlp/senti_analysis/data/readme.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/code/nlp/senti_analysis/data/readme.txt -------------------------------------------------------------------------------- /code/nlp/senti_analysis/sentiment.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | 自然语言处理之中文 5 | 基于情感字典的情感分析 6 | 7 | 缺陷: 8 | 1 段落的得分是其所有句子得分的平均值,这一方法并不符合实际情况。 9 | 正如文章中先后段落有重要性大小之分,一个段落中前后句子也同样有重要性的差异。 10 | 2 有一类文本使用贬义词来表示正向意义,这类情况常出现与宣传文本中 11 | """ 12 | 13 | from collections import defaultdict 14 | import re 15 | import jieba 16 | 17 | 18 | def read_lines(filename): 19 | """ 20 | 读取文件,每行为元素,返回列表 21 | """ 22 | data = [] 23 | with open(filename, encoding='utf8') as f: 24 | for line in f: 25 | line = line.strip() 26 | if not line: 27 | continue 28 | data.append(line) 29 | return data 30 | 31 | 32 | 33 | def sent2word(sentence): 34 | """ 35 | 分词 36 | """ 37 | segList = jieba.cut(sentence.strip()) 38 | stopwords = read_lines('data/stopwords.txt') 39 | return [w for w in segList if w and w not in stopwords] 40 | 41 | 42 | def list_to_dict(word_list): 43 | """将分词后的列表转为字典,key为单词,value为单词在列表中的索引,索引相当于词语在文档中出现的位置""" 44 | data = {} 45 | for x in range(len(word_list)): 46 | data[word_list[x]] = x 47 | return data 48 | 49 | 50 | def classify_words(word_dict): 51 | """词语分类,找出情感词、否定词、程度副词""" 52 | # 读取情感字典文件 53 | sen_list = read_lines('data/BosonNLP_sentiment_score.txt') 54 | sen_dict = defaultdict() 55 | for s in sen_list: 56 | sen_dict[s.split(' ')[0]] = s.split(' ')[1] 57 | 58 | # 读取否定词文件 59 | not_word_list = read_lines('data/not.txt') 60 | 61 | # 读取程度副词文件 62 | degree_list = read_lines('data/adverb_dict.txt') 63 | degree_dic = defaultdict() 64 | for d in degree_list: 65 | values = re.split('\s+', d) 66 | degree_dic[values[0]] = values[1] 67 | 68 | # 分类结果,词语的index作为key,词语的分值作为value,否定词分值设为-1 69 | sen_word = dict() 70 | not_word = dict() 71 | degree_word = dict() 72 | 73 | # 分类 74 | for word in word_dict.keys(): 75 | if word in sen_dict.keys() and word not in not_word_list and word not in degree_dic.keys(): 76 | sen_word[word_dict[word]] = float(sen_dict[word]) 77 | elif word in not_word_list and word not in degree_dic.keys(): 78 | not_word[word_dict[word]] = -1 79 | elif word in degree_dic.keys(): 80 | degree_word[word_dict[word]] = float(degree_dic[word]) 81 | 82 | # 将分类结果返回 83 | return sen_word, not_word, degree_word 84 | 85 | 86 | def socre_sentiment(sen_word, not_word, degree_word, seg_result): 87 | """计算得分""" 88 | W = 1 89 | score = 0 90 | for i in range(len(seg_result)): 91 | if i in not_word.keys(): 92 | W *= -1 93 | elif i in degree_word.keys(): 94 | W *= degree_word[i] 95 | elif i in sen_word.keys(): 96 | score += W * sen_word[i] 97 | W = 1 98 | return score 99 | 100 | def get_score(sententce): 101 | seg_list = sent2word(sententce) 102 | print(seg_list) 103 | sen_word, not_word, degree_word = classify_words(list_to_dict(seg_list)) 104 | print(sen_word, not_word, degree_word) 105 | score = socre_sentiment(sen_word, not_word, degree_word, seg_list) 106 | return score 107 | 108 | 109 | print(get_score('我的心很痛')) 110 | 111 | 112 | -------------------------------------------------------------------------------- /code/nlp/senti_analysis/sentiment_ml.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | 自然语言处理之中文 5 | 基于机器学习 6 | """ 7 | import re 8 | import jieba 9 | 10 | def read_lines(filename): 11 | """ 12 | 读取文件,每行为元素,返回列表 13 | """ 14 | data = [] 15 | with open(filename, encoding='utf8') as f: 16 | for line in f: 17 | line = line.strip() 18 | if not line: 19 | continue 20 | data.append(line) 21 | return data 22 | 23 | 24 | def sent2word(sentence): 25 | """ 26 | 分词 27 | """ 28 | seg_list = jieba.cut(sentence.strip(), cut_all=False) 29 | # 去除停用词 30 | stopwords = read_lines('data/stopwords.txt') 31 | return [w for w in seg_list if w and w not in stopwords] 32 | 33 | 34 | def clear_text(line): 35 | """ 清洗文本 """ 36 | if line: 37 | line = line.strip() 38 | line = re.sub("[a-zA-Z0-9]", "", line) # 去除文本中的英文和数字 39 | line = re.sub("[\s+\.\!\/_,$%^*(+\"\';:“”.]+|[+——!,。??、~@#¥%……&*()]+", "", line) # 去除文本中的中文符号和英文符号 40 | return line 41 | 42 | 43 | def prepare_data(sourceFile, targetFile): 44 | """ 45 | 处理文本 46 | """ 47 | with open(sourceFile, 'r', encoding='utf-8') as f: 48 | with open(targetFile, 'w', encoding='utf-8') as target: 49 | target_lines = [] 50 | for line in f: 51 | line = clear_text(line) 52 | if not line: 53 | continue 54 | seg_line = ' '.join(sent2word(line)) 55 | target_lines.append(seg_line) 56 | target.write('\n'.join(target_lines)) 57 | 58 | 59 | def process_input(): 60 | sourceFile = 'data/2000_neg.txt' 61 | targetFile = 'data/2000_neg_cut.txt' 62 | prepare_data(sourceFile, targetFile) 63 | 64 | sourceFile = 'data/2000_pos.txt' 65 | targetFile = 'data/2000_pos_cut.txt' 66 | prepare_data(sourceFile, targetFile) 67 | 68 | 69 | if __name__ == '__main__': 70 | process_input() -------------------------------------------------------------------------------- /code/pre.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | 无量纲处理 5 | 6 | """ 7 | import numpy as np 8 | 9 | 10 | """ 11 | 在进行特征选择之前,一般会先进行数据无量纲化处理,这样,表征不同属性(单位不同)的各特征之间才有可比性, 12 | 如1cm 与 0.1kg 你怎么比?无量纲处理方法很多,使用不同的方法,对最终的机器学习模型会产生不同的影响。 13 | """ 14 | # 归一化 15 | from sklearn.preprocessing import MinMaxScaler 16 | x = np.array([[1,-1,2],[2,0,0],[0,1,-1]]) 17 | x1 = MinMaxScaler().fit_transform(x) 18 | print(x1) 19 | 20 | # 标准化 21 | from sklearn.preprocessing import StandardScaler 22 | x = np.array([[1,2,3],[4,5,6],[1,2,1]]) 23 | x1 = StandardScaler().fit_transform(x) 24 | print(x1) 25 | scaler = StandardScaler().fit(x) 26 | # print(scaler) 27 | print(scaler.mean_) 28 | 29 | # 正则化 30 | from sklearn import preprocessing 31 | normalizer = preprocessing.Normalizer().fit(x) 32 | print(normalizer.transform(x)) 33 | -------------------------------------------------------------------------------- /code/tf/imdb_demo.py: -------------------------------------------------------------------------------- 1 | """ 2 | tensorflow 入门 3 | """ 4 | 5 | import tensorflow as tf 6 | from tensorflow import keras 7 | import numpy as np 8 | 9 | imdb = keras.datasets.imdb 10 | 11 | (train_data, train_labels), (test_data, test_labels) = imdb.load_data(path="./dataset/imdb.npz", num_words=10000) 12 | 13 | print("Training entries: {}, labels: {}".format(len(train_data), len(train_labels))) 14 | 15 | print(train_data[1]) 16 | 17 | print(len(train_data[0]), len(train_data[1])) 18 | 19 | word_index = imdb.get_word_index(path="./dataset/imdb_word_index.json") 20 | 21 | # The first indices are reserved 22 | word_index = {k:(v+3) for k,v in word_index.items()} 23 | word_index[""] = 0 24 | word_index[""] = 1 25 | word_index[""] = 2 # unknown 26 | word_index[""] = 3 27 | 28 | reverse_word_index = dict([(value, key) for (key, value) in word_index.items()]) 29 | 30 | def decode_review(text): 31 | return ' '.join([reverse_word_index.get(i, '?') for i in text]) 32 | 33 | print(decode_review(train_data[0])) 34 | # 35 | # train_data = keras.preprocessing.sequence.pad_sequences(train_data, 36 | # value=word_index[""], 37 | # padding='post', 38 | # maxlen=256) 39 | # 40 | # test_data = keras.preprocessing.sequence.pad_sequences(test_data, 41 | # value=word_index[""], 42 | # padding='post', 43 | # maxlen=256) 44 | # 45 | # print(train_data[0]) 46 | # 47 | # # input shape is the vocabulary count used for the movie reviews (10,000 words) 48 | # vocab_size = 10000 49 | # 50 | # model = keras.Sequential() 51 | # model.add(keras.layers.Embedding(vocab_size, 16)) 52 | # model.add(keras.layers.GlobalAveragePooling1D()) 53 | # model.add(keras.layers.Dense(16, activation=tf.nn.relu)) 54 | # model.add(keras.layers.Dense(1, activation=tf.nn.sigmoid)) 55 | # 56 | # model.summary() 57 | # 58 | # model.compile(optimizer=tf.train.AdamOptimizer(), 59 | # loss='binary_crossentropy', 60 | # metrics=['accuracy']) 61 | # 62 | # # 验证集 63 | # x_val = train_data[:10000] 64 | # partial_x_train = train_data[10000:] 65 | # 66 | # y_val = train_labels[:10000] 67 | # partial_y_train = train_labels[10000:] 68 | # 69 | # history = model.fit(partial_x_train, 70 | # partial_y_train, 71 | # epochs=40, 72 | # batch_size=512, 73 | # validation_data=(x_val, y_val), 74 | # verbose=1) 75 | # 76 | # results = model.evaluate(test_data, test_labels) 77 | # 78 | # print(results) 79 | # 80 | # import matplotlib.pyplot as plt 81 | # 82 | # acc = history.history['acc'] 83 | # val_acc = history.history['val_acc'] 84 | # loss = history.history['loss'] 85 | # val_loss = history.history['val_loss'] 86 | # 87 | # epochs = range(1, len(acc) + 1) 88 | # 89 | # # "bo" is for "blue dot" 90 | # plt.plot(epochs, loss, 'bo', label='Training loss') 91 | # # b is for "solid blue line" 92 | # plt.plot(epochs, val_loss, 'b', label='Validation loss') 93 | # plt.title('Training and validation loss') 94 | # plt.xlabel('Epochs') 95 | # plt.ylabel('Loss') 96 | # plt.legend() 97 | # 98 | # plt.show() 99 | # 100 | # acc_values = history.history['acc'] 101 | # val_acc_values = history.history['val_acc'] 102 | # 103 | # plt.plot(epochs, acc, 'bo', label='Training acc') 104 | # plt.plot(epochs, val_acc, 'b', label='Validation acc') 105 | # plt.title('Training and validation accuracy') 106 | # plt.xlabel('Epochs') 107 | # plt.ylabel('Accuracy') 108 | # plt.legend() 109 | # plt.show() 110 | 111 | 112 | -------------------------------------------------------------------------------- /code/tf/mnist.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import matplotlib.pyplot as plt 3 | import tensorflow as tf 4 | mnist = tf.keras.datasets.mnist 5 | 6 | # 加载数据 7 | (x_train, y_train),(x_test, y_test) = mnist.load_data() 8 | 9 | # 可视化 10 | plt.title('Example %d. Label: %d' % (0, y_train[0])) 11 | plt.imshow(x_train[0].reshape((28,28)), ) 12 | plt.show() 13 | 14 | x_train, x_test = x_train / 255.0, x_test / 255.0 15 | 16 | model = tf.keras.models.Sequential([ 17 | tf.keras.layers.Flatten(input_shape=(28, 28)), 18 | tf.keras.layers.Dense(512, activation=tf.nn.relu), 19 | tf.keras.layers.Dropout(0.2), 20 | tf.keras.layers.Dense(10, activation=tf.nn.softmax) 21 | ]) 22 | model.compile(optimizer='adam', 23 | loss='sparse_categorical_crossentropy', 24 | metrics=['accuracy']) 25 | 26 | model.fit(x_train, y_train, epochs=5) 27 | model.evaluate(x_test, y_test) -------------------------------------------------------------------------------- /images/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/images/1.jpg -------------------------------------------------------------------------------- /images/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/images/1.png -------------------------------------------------------------------------------- /images/1.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/images/1.webp -------------------------------------------------------------------------------- /images/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/images/2.png -------------------------------------------------------------------------------- /images/2.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/images/2.webp -------------------------------------------------------------------------------- /images/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/images/3.png -------------------------------------------------------------------------------- /images/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/images/4.png -------------------------------------------------------------------------------- /images/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/images/5.png -------------------------------------------------------------------------------- /images/drop_shadows_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/images/drop_shadows_background.png -------------------------------------------------------------------------------- /images/e1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/images/e1.png -------------------------------------------------------------------------------- /images/e2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/images/e2.png -------------------------------------------------------------------------------- /images/e3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/images/e3.png -------------------------------------------------------------------------------- /images/e4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/images/e4.png -------------------------------------------------------------------------------- /images/e5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/images/e5.png -------------------------------------------------------------------------------- /images/e6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/images/e6.png -------------------------------------------------------------------------------- /images/eucl_dist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/images/eucl_dist.png -------------------------------------------------------------------------------- /images/knn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/images/knn.png -------------------------------------------------------------------------------- /images/net.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/images/net.png -------------------------------------------------------------------------------- /notes/AndrewNg/K-均值.md: -------------------------------------------------------------------------------- 1 | ## K-均值 2 | 3 | **K-均值**是一个迭代算法,假设我们想要将数据聚类成n个组,其方法为: 4 | 5 | 首先选择个随机的点,称为**聚类中心**(**cluster centroids**); 6 | 7 | 对于数据集中的每一个数据,按照距离个中心点的距离,将其与距离最近的中心点关联起来,与同一个中心点关联的所有点聚成一类。 8 | 9 | 计算每一个组的平均值,将该组所关联的中心点移动到平均值的位置。 10 | 11 | 只有数据集中样本分类有变化,即对数据集中每一个数据重新归类,然后移动中心点。 12 | 13 | 在运行K-均值算法的之前,我们首先要随机初始化所有的聚类中心点,下面介绍怎样做: 14 | 15 | 1. 我们应该选择,即聚类中心点的个数要小于所有训练集实例的数量 16 | 2. 随机选择个训练实例,然后令个聚类中心分别与这个训练实例相等 17 | 18 | **K-均值**的一个问题在于,它有可能会停留在一个局部最小值处,而这取决于初始化的情况。 19 | 20 | 为了解决这个问题,我们通常需要多次运行**K-均值**算法,每一次都重新进行随机初始化,最后再比较多次运行**K-均值**的结果,选择代价函数最小的结果。这种方法在较小的时候(2--10)还是可行的,但是如果较大,这么做也可能不会有明显地改善。 21 | 22 | 没有所谓最好的选择聚类数的方法,通常是需要根据不同的问题,人工进行选择的。选择的时候思考我们运用**K-均值**算法聚类的动机是什么,然后选择能最好服务于该目的标聚类数。 23 | 24 | 当人们在讨论,选择聚类数目的方法时,有一个可能会谈及的方法叫作“肘部法则”。关于“肘部法则”,我们所需要做的是改变$K$值,也就是聚类类别数目的总数。我们用一个聚类来运行**K均值**聚类方法。这就意味着,所有的数据都会分到一个聚类里,然后计算成本函数或者计算畸变函数$J$。$K$代表聚类数字。 25 | 26 | ![img](../../notes/AndrewNg/images/18.png) 27 | 28 | 我们可能会得到一条类似于这样的曲线。像一个人的肘部。这就是“肘部法则”所做的,让我们来看这样一个图,看起来就好像有一个很清楚的肘在那儿。好像人的手臂,如果你伸出你的胳膊,那么这就是你的肩关节、肘关节、手。这就是“肘部法则”。你会发现这种模式,它的畸变值会迅速下降,从1到2,从2到3之后,你会在3的时候达到一个肘点。在此之后,畸变值就下降的非常慢,看起来就像使用3个聚类来进行聚类是正确的,这是因为那个点是曲线的肘点,畸变值下降得很快,$K=3$之后就下降得很慢,那么我们就选$K=3$。当你应用“肘部法则”的时候,如果你得到了一个像上面这样的图,那么这将是一种用来选择聚类个数的合理方法。 29 | 30 | -------------------------------------------------------------------------------- /notes/AndrewNg/PCA.md: -------------------------------------------------------------------------------- 1 | ## 主成分分析(PCA) 2 | 3 | ### 降维的目的 4 | 5 | 1. 压缩数据 6 | 2. 可视化数据 7 | 8 | ### PCA 9 | 10 | 在一般的特征选择问题中,剔除的特征主要是和类标签无关的特征,而这里的特征很多是和类标签有关的,但里面存在噪声或者冗余。在这种情况下,需要一种特征降维的方法来减少特征数,减少噪音和冗余,减少过度拟合的可能性。**主成分分析法(PCA)**就是属于这类降维的方法。 11 | 12 | PCA的思想是将n维特征映射到k维上(k) 72 | 73 | [一篇深入剖析PCA的好文](https://www.cnblogs.com/hadoop2015/p/7419087.html) 74 | 75 | [详细解释主成分分析]() 76 | 77 | -------------------------------------------------------------------------------- /notes/AndrewNg/images/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/AndrewNg/images/1.png -------------------------------------------------------------------------------- /notes/AndrewNg/images/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/AndrewNg/images/10.jpg -------------------------------------------------------------------------------- /notes/AndrewNg/images/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/AndrewNg/images/10.png -------------------------------------------------------------------------------- /notes/AndrewNg/images/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/AndrewNg/images/11.jpg -------------------------------------------------------------------------------- /notes/AndrewNg/images/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/AndrewNg/images/11.png -------------------------------------------------------------------------------- /notes/AndrewNg/images/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/AndrewNg/images/12.jpg -------------------------------------------------------------------------------- /notes/AndrewNg/images/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/AndrewNg/images/12.png -------------------------------------------------------------------------------- /notes/AndrewNg/images/13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/AndrewNg/images/13.jpg -------------------------------------------------------------------------------- /notes/AndrewNg/images/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/AndrewNg/images/13.png -------------------------------------------------------------------------------- /notes/AndrewNg/images/14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/AndrewNg/images/14.jpg -------------------------------------------------------------------------------- /notes/AndrewNg/images/14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/AndrewNg/images/14.png -------------------------------------------------------------------------------- /notes/AndrewNg/images/15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/AndrewNg/images/15.jpg -------------------------------------------------------------------------------- /notes/AndrewNg/images/15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/AndrewNg/images/15.png -------------------------------------------------------------------------------- /notes/AndrewNg/images/16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/AndrewNg/images/16.jpg -------------------------------------------------------------------------------- /notes/AndrewNg/images/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/AndrewNg/images/16.png -------------------------------------------------------------------------------- /notes/AndrewNg/images/17.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/AndrewNg/images/17.jpg -------------------------------------------------------------------------------- /notes/AndrewNg/images/17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/AndrewNg/images/17.png -------------------------------------------------------------------------------- /notes/AndrewNg/images/18.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/AndrewNg/images/18.jpg -------------------------------------------------------------------------------- /notes/AndrewNg/images/18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/AndrewNg/images/18.png -------------------------------------------------------------------------------- /notes/AndrewNg/images/19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/AndrewNg/images/19.jpg -------------------------------------------------------------------------------- /notes/AndrewNg/images/19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/AndrewNg/images/19.png -------------------------------------------------------------------------------- /notes/AndrewNg/images/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/AndrewNg/images/2.png -------------------------------------------------------------------------------- /notes/AndrewNg/images/20.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/AndrewNg/images/20.jpg -------------------------------------------------------------------------------- /notes/AndrewNg/images/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/AndrewNg/images/20.png -------------------------------------------------------------------------------- /notes/AndrewNg/images/21.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/AndrewNg/images/21.jpg -------------------------------------------------------------------------------- /notes/AndrewNg/images/22.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/AndrewNg/images/22.jpg -------------------------------------------------------------------------------- /notes/AndrewNg/images/23.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/AndrewNg/images/23.jpg -------------------------------------------------------------------------------- /notes/AndrewNg/images/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/AndrewNg/images/3.png -------------------------------------------------------------------------------- /notes/AndrewNg/images/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/AndrewNg/images/4.png -------------------------------------------------------------------------------- /notes/AndrewNg/images/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/AndrewNg/images/5.png -------------------------------------------------------------------------------- /notes/AndrewNg/images/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/AndrewNg/images/6.png -------------------------------------------------------------------------------- /notes/AndrewNg/images/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/AndrewNg/images/7.png -------------------------------------------------------------------------------- /notes/AndrewNg/images/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/AndrewNg/images/8.png -------------------------------------------------------------------------------- /notes/AndrewNg/images/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/AndrewNg/images/9.jpg -------------------------------------------------------------------------------- /notes/AndrewNg/images/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/AndrewNg/images/9.png -------------------------------------------------------------------------------- /notes/AndrewNg/readme.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 吴恩达老师的机器学习笔记 4 | 5 | 课程地址: 6 | 7 | 8 | 9 | ## 什么是机器学习? 10 | 11 | 你可能每天都会使用几十次学习算法知道它。每次使用Google或Bing等网络搜索引擎时搜索互联网,其中一个有效的原因是因为学习 算法,由谷歌或微软实施,已经学会了如何排名网络 页面。每次你使用Facebook或Apple的照片打字应用程序和它识别你朋友的照片,这也是机器学习。每次你读您的电子邮件和垃圾邮件过滤器可以帮助您避免涉及大量垃圾邮件 电子邮件,这也是一种学习算法。机器学习是一个从人工智能或人工智能领域发展而来的领域。我们可以编程一台机器来完成如何找到从A到B的最短路径。 但在大多数情况下,我们不知道如何编写AI程序来做更多有趣的事情,如网页搜索或照片标记或电子邮件反垃圾邮件。我们应该意识到做这些事情的唯一方法就是让机器学习自己做。 12 | 13 | 亚瑟·塞缪尔将其描述为:“研究领域使计算机无需明确编程即可学习。” 这是一个较旧的非正式定义。 14 | 15 | Tom Mitchell提供了一个更现代的定义:“据说计算机程序从经验E中学习某些任务T和绩效测量P,如果它在T中的任务中的表现,由P测量,随经验E而改善。 “ 16 | 17 | 示例:玩跳棋。 18 | 19 | E =玩许多跳棋游戏的经验 20 | 21 | T =玩跳棋的任务。 22 | 23 | P =程序赢得下一场比赛的概率。 24 | 25 | 通常,任何机器学习问题都可以分配到两个广泛的分类之一: 26 | 27 | **监督学习**和**无监督学习**。 28 | 29 | 机器学习的核心是“**使用算法解析数据,从中学习,然后对世界上的某件事情做出决定或预测**”。这意味着,与其显式地编写程序来执行某些任务,不如教计算机如何开发一个算法来完成任务。 30 | 31 | ### 监督学习 32 | 33 | 在有监督的学习中,我们得到一个数据集,并且已经知道我们的正确输出应该是什么样的,并且认为输入和输出之间存在关系。 34 | 35 | 监督学习问题分为“回归”和“分类”问题。在回归问题中,我们试图在连续输出中预测结果,这意味着我们正在尝试将输入变量映射到某个连续函数。在分类问题中,我们试图在离散输出中预测结果。换句话说,我们正在尝试将输入变量映射到离散类别。 36 | 37 | **例1:** 38 | 39 | 鉴于有关房地产市场房屋面积的数据,请尝试预测房价。作为大小函数的价格是连续输出,因此这是一个回归问题。 40 | 41 | **例2**: 42 | 43 | (a)回归 - 鉴于一个人的照片,我们必须根据给定的图片预测他们的年龄 44 | 45 | (b)分类 - 鉴于患有肿瘤的患者,我们必须预测肿瘤是恶性的还是良性的。 46 | 47 | ### 无监督学习 48 | 49 | 无监督学习使我们能够在很少或根本不知道我们的结果应该是什么样的情况下处理问题。我们可以从数据中导出结构,我们不一定知道变量的影响。 50 | 51 | 我们可以通过基于数据中变量之间的关系对数据进行聚类来推导出这种结构。 52 | 53 | 在无监督学习的情况下,没有基于预测结果的反馈。 54 | 55 | **例:** 56 | 57 | 聚类:收集1,000,000个不同基因的集合,并找到一种方法将这些基因自动分组成不同的相似或相关的不同变量组,如寿命,位置,角色等。 58 | 59 | 非聚类:“鸡尾酒会算法”允许您在混乱的环境中查找结构。(即在鸡尾酒会上从声音网格中识别个别声音和音乐)。 60 | 61 | ### 强化学习 62 | 63 | 与监督和非监督学习不同,强化学习不涉及提供“正确的”答案或输出。相反,它只关注性能。强化学习的经典应用是玩游戏。这反映了人类是如何根据积极和消极的结果学习的。很快就学会了不要重复这一动作。同样的道理,一台下棋的电脑可以学会不把它的国王移到对手的棋子可以进入的空间。然后,国际象棋的这一基本教训就可以被扩展和推断出来,直到机器能够打(并最终击败)人类顶级玩家为止。 64 | 65 | 66 | 67 | ---- 68 | 69 | 其他笔记: 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /notes/AndrewNg/反向传播.md: -------------------------------------------------------------------------------- 1 | ## 反向传播 2 | 3 | -------------------------------------------------------------------------------- /notes/AndrewNg/应用机器学习的建议.md: -------------------------------------------------------------------------------- 1 | ## 应用机器学习的建议 2 | 3 | 以预测房价为例,假如你已经完成了正则化线性回归,也就是最小化代价函数$J$的值,假如,在你得到你的学习参数以后,如果你要将你的假设函数放到一组新的房屋样本上进行测试,假如说你发现在预测房价时产生了巨大的误差,现在你的问题是要想改进这个算法,接下来应该怎么办?这就是接下来我们需要探讨的问题。 4 | 5 | ### 评估假设 6 | 7 | 将数据分成训练集和测试集,训练集用于训练模型,输出的模型用于测试集计算误差。 8 | 9 | 有以下两种方式计算误差: 10 | 11 | 1. 对于线性回归模型,我们利用测试集数据计算代价函数 12 | 13 | 2. 对于逻辑回归模型,我们除了可以利用测试数据集来计算代价函数外,还可以利用误分类的比率,对于每一个测试集样本,计算: 14 | 15 | ![img](../../notes/AndrewNg/images/14.png) 16 | 17 | 然后对计算结果求平均。 18 | 19 | ### 模型选择 20 | 21 | 我们需要使用交叉验证集来帮助选择模型。使用60%的数据作为训练集,使用 20%的数据作为交叉验证集,使用20%的数据作为测试集。通过交叉验证集选出的模型,用于测试集计算误差。 22 | 23 | ### 诊断方差和偏差 24 | 25 | 当你运行一个学习算法时,如果这个算法的表现不理想,那么多半是出现两种情况:要么是偏差比较大,要么是方差比较大。换句话说,出现的情况要么是欠拟合,要么是过拟合问题。那么这两种情况,哪个和偏差有关,哪个和方差有关,或者是不是和两个都有关? 26 | 27 | 对于上面问题,我们通常会通过将训练集和交叉验证集的代价函数误差与多项式的次数绘制在同一张图表上来帮助分析: 28 | 29 | ![img](../../notes/AndrewNg/images/15.png) 30 | 31 | **Training error:** $J_{train}(\theta) = \frac{1}{2m}\sum_\limits{i=1}^{m}(h_{\theta}(x^{(i)})-y^{(i)})^2$ 32 | 33 | **Cross Validation error:** $J_{cv}(\theta) = \frac{1}{2m_{cv}}\sum_\limits{i=1}^{m}(h_{\theta}(x^{(i)}_{cv})-y^{(i)}_{cv})^2$ 34 | 35 | 对于训练集,当 $d$ 较小时,模型拟合程度更低,误差较大;随着 $d$ 的增长,拟合程度提高,误差减小。 36 | 37 | 对于交叉验证集,当 $d$ 较小时,模型拟合程度低,误差较大;但是随着 $d$ 的增长,误差呈现先减小后增大的趋势,转折点是我们的模型开始过拟合训练数据集的时候。 38 | 39 | 如果我们的交叉验证集误差较大,我们如何判断是方差还是偏差呢? 40 | 41 | 训练集误差和交叉验证集误差近似时:偏差/欠拟合 42 | 43 | 交叉验证集误差远大于训练集误差时:方差/过拟合 44 | 45 | ### 正则化和偏差/方差 46 | 47 | 选择λ的方法为: 48 | 49 | 1. 使用训练集训练出12个不同程度正则化的模型 50 | 51 | 2. 用12个模型分别对交叉验证集计算出交叉验证误差 52 | 53 | 3. 选择得出交叉验证误差**最小**的模型 54 | 55 | 4. 运用步骤3中选出模型对测试集计算得出推广误差,我们也可以同时将训练集和交叉验证集模型的代价函数误差与λ的值绘制在一张图表上: 56 | 57 | ![img](../../notes/AndrewNg/images/16.png) 58 | 59 | 当 $\lambda$ 较小时,训练集误差较小(过拟合)而交叉验证集误差较大(高方差); 60 | 61 | 随着 $\lambda$ 的增加,训练集误差不断增加(欠拟合),而交叉验证集误差则是先减小后增加(高偏差)。 62 | 63 | ### 学习曲线 64 | 65 | 学习曲线是学习算法的一个很好的**合理检验**(**sanity check**)。学习曲线是将训练集误差和交叉验证集误差作为训练集样本数量($m​$)的函数绘制的图表。 66 | 67 | ![img](../../notes/AndrewNg/images/21.jpg) 68 | 69 | 如上,在高偏差/欠拟合的情况下,增加数据到训练集不一定能有帮助。 70 | 71 | ![img](../../notes/AndrewNg/images/22.jpg) 72 | 73 | 如上,在高方差/过拟合的情况下,增加更多数据到训练集可能可以提高算法效果。 74 | 75 | ### 决定接下来做什么 76 | 77 | 1. 获得更多的训练样本——解决高方差 78 | 2. 尝试减少特征的数量——解决高方差 79 | 3. 尝试获得更多的特征——解决高偏差 80 | 4. 尝试增加多项式特征——解决高偏差 81 | 5. 尝试减少正则化程度λ——解决高偏差 82 | 6. 尝试增加正则化程度λ——解决高方差 83 | 84 | -------------------------------------------------------------------------------- /notes/AndrewNg/推荐系统.md: -------------------------------------------------------------------------------- 1 | ## 推荐系统 2 | 3 | -------------------------------------------------------------------------------- /notes/AndrewNg/支持向量机.md: -------------------------------------------------------------------------------- 1 | ## 支持向量机 2 | 3 | -------------------------------------------------------------------------------- /notes/AndrewNg/机器学习系统设计.md: -------------------------------------------------------------------------------- 1 | ## 机器学习系统设计 2 | 3 | ### 误差分析 4 | 5 | 构建一个学习算法的推荐方法为: 6 | 7 | 1. 从一个简单的能快速实现的算法开始,实现该算法并用交叉验证集数据测试这个算法。 8 | 2. 绘制学习曲线,决定是增加更多数据,或者添加更多特征,还是其他选择。 9 | 3. 进行误差分析:人工检查交叉验证集中我们算法中产生预测误差的样本,看看这些样本是否有某种系统化的趋势。 10 | 11 | ### 类偏斜的误差度量 12 | 13 | 类偏斜情况表现为我们的训练集中有非常多的同一种类的样本,只有很少或没有其他类的样本。这时,误差的大小是不能视为评判算法效果的依据的。 14 | 15 | **查准率**(**Precision**)和**查全率**(**Recall**) 我们将算法预测的结果分成四种情况: 16 | 17 | 1. **正确肯定**(**True Positive,TP**):预测为真,实际为真, 真阳性。 18 | 19 | 2.**正确否定**(**True Negative,TN**):预测为假,实际为假,真阴性。 20 | 21 | 3.**错误肯定**(**False Positive,FP**):预测为真,实际为假,假阳性。 22 | 23 | 4.**错误否定**(**False Negative,FN**):预测为假,实际为真,假阴性。 24 | 25 | 则:查准率=**TP/(TP+FP)**。例,在所有我们预测有恶性肿瘤的病人中,实际上有恶性肿瘤的病人的百分比,越高越好。 26 | 27 | 查全率=**TP/(TP+FN)**。例,在所有实际上有恶性肿瘤的病人中,成功预测有恶性肿瘤的病人的百分比,越高越好。 28 | 29 | ### 查准率和查全率之间的权衡 30 | 31 | ![img](../../notes/AndrewNg/images/17.png) 32 | 33 | 我们希望有一个帮助我们选择这个阀值的方法。一种方法是计算**F1 值**(**F1 Score**),其计算公式为: 34 | 35 | $F_1Score=2\frac{PR}{P+R}$ 36 | 37 | -------------------------------------------------------------------------------- /notes/AndrewNg/正则化.md: -------------------------------------------------------------------------------- 1 | ## 正则化 2 | 3 | ### 过拟合 4 | 5 | 过于强调拟合原始数据,而丢失了算法的本质:预测新数据。若给出一个新的值使之预测,它将表现的很差。 6 | 7 | 我们来看一个过拟合的例子: 8 | 9 | ![img](../../notes/AndrewNg/images/15.jpg) 10 | 11 | 第一个模型是一个线性模型,欠拟合,不能很好地适应我们的训练集;第三个模型是一个四次方的模型,过于强调拟合原始数据,如果给出一个新的值来预测,则明显预测效果会很差,这就是过拟合。 12 | 13 | 问题是,如果我们发现了过拟合问题,应该如何处理? 14 | 15 | 1. 丢弃一些不能帮助我们正确预测的特征。可以是手工选择保留哪些特征,或者使用一些模型选择的算法来帮忙(例如**PCA**) 16 | 2. 正则化。 保留所有的特征,但是减少参数的大小。 17 | 18 | ### 正则化 19 | 20 | #### 基本思想 21 | 22 | 高次项导致了过拟合的产生,所以如果我们能让这些高次项的系数接近于0的话,就可以很好的拟合了, 所以我们要做的就是在一定程度上减小这些参数$θ ​$的值。 23 | 24 | 但是一般情况下我们有很多的特征,我们并不知道其中哪些特征我们要惩罚,我们将对所有的特征进行惩罚,并且让代价函数最优化的软件来选择这些惩罚的程度。这样的结果是得到了一个较为简单的能防止过拟合问题的假设: 25 | $$ 26 | J\left( \theta \right)=\frac{1}{2m}[\sum\limits_{i=1}^{m}{{{({h_\theta}({{x}^{(i)}})-{{y}^{(i)}})}^{2}}+\lambda \sum\limits_{j=1}^{n}{\theta_{j}^{2}}]} 27 | $$ 28 | 其中$\lambda $又称为正则化参数(**Regularization Parameter**)。 29 | 30 | 如果选择的正则化参数$\lambda$ 过大,则会把所有的参数都最小化了,导致模型变成 ${h_\theta}\left( x \right)={\theta_{0}}$,也就是上图中红色直线所示的情况,造成欠拟合。 31 | 那为什么增加的一项$\lambda =\sum\limits_{j=1}^{n}{\theta_j^{2}}$ 可以使$\theta $的值减小呢? 32 | 因为如果我们令 $\lambda$ 的值很大的话,为了使**Cost Function** 尽可能的小,所有的 $\theta $ 的值(不包括${\theta_{0}}$)都会在一定程度上减小。 33 | 但若$\lambda$ 的值太大了,那么$\theta $(不包括${\theta_{0}}$)都会趋近于0,这样我们所得到的只能是一条平行于$x$轴的直线。 34 | 所以对于正则化,我们要取一个合理的 $\lambda$ 的值,这样才能更好的应用正则化。 35 | 36 | #### 正规化线性回归 37 | 38 | 对于线性回归的求解,我们之前推导了两种学习算法:一种基于梯度下降,一种基于正规方程。 39 | 40 | 正则化线性回归的代价函数为: 41 | 42 | $J\left( \theta \right)=\frac{1}{2m}\sum\limits_{i=1}^{m}{[({{({h_\theta}({{x}^{(i)}})-{{y}^{(i)}})}^{2}}+\lambda \sum\limits_{j=1}^{n}{\theta _{j}^{2}})]}​$ 43 | 44 | 如果我们要使用梯度下降法令这个代价函数最小化,因为我们未对$\theta_0​$进行正则化,所以梯度下降算法将分两种情形: 45 | 46 | $Repeat$ $until$ $convergence${ 47 | 48 | ​ ${\theta_0}:={\theta_0}-a\frac{1}{m}\sum\limits_{i=1}^{m}{(({h_\theta}({{x}^{(i)}})-{{y}^{(i)}})x_{0}^{(i)}})$ 49 | 50 | ${\theta_j}:={\theta_j}(1-a\frac{\lambda }{m})-a\frac{1}{m}\sum\limits_{i=1}^{m}{({h_\theta}({{x}^{(i)}})-{{y}^{(i)}})x_{j}^{\left( i \right)}}$ $for j=1,2,...n$ 51 | 52 | } 53 | 54 | 可以看出,正则化线性回归的梯度下降算法的变化在于,每次都在原有算法更新规则的基础上令$\theta ​$值减少了一个额外的值。 55 | 56 | 利用正规方程来求解正则化线性回归模型,方法如下所示: 57 | 58 | ![img](../../notes/AndrewNg/images/11.png) 59 | 60 | 图中的矩阵尺寸为 $(n+1)*(n+1)​$。 61 | 62 | #### 正则化逻辑回归 63 | 64 | 针对逻辑回归问题,我们也给代价函数增加一个正则化的表达式,得到代价函数: 65 | 66 | $J\left( \theta \right)=\frac{1}{m}\sum\limits_{i=1}^{m}{[-{{y}^{(i)}}\log \left( {h_\theta}\left( {{x}^{(i)}} \right) \right)-\left( 1-{{y}^{(i)}} \right)\log \left( 1-{h_\theta}\left( {{x}^{(i)}} \right) \right)]}+\frac{\lambda }{2m}\sum\limits_{j=1}^{n}{\theta _{j}^{2}}$ 67 | 68 | **Python**代码: 69 | 70 | ```python 71 | import numpy as np 72 | def costReg(theta, X, y, learningRate): 73 | theta = np.matrix(theta) 74 | X = np.matrix(X) 75 | y = np.matrix(y) 76 | first = np.multiply(-y, np.log(sigmoid(X*theta.T))) 77 | second = np.multiply((1 - y), np.log(1 - sigmoid(X*theta.T))) 78 | reg = (learningRate / (2 * len(X))* np.sum(np.power(theta[:,1:theta.shape[1]],2)) 79 | return np.sum(first - second) / (len(X)) + reg 80 | ``` 81 | 82 | 要最小化该代价函数,通过求导,得出梯度下降算法为: 83 | 84 | $Repeat​$ $until​$ $convergence​${ 85 | 86 | ​ ${\theta_0}:={\theta_0}-a\frac{1}{m}\sum\limits_{i=1}^{m}{(({h_\theta}({{x}^{(i)}})-{{y}^{(i)}})x_{0}^{(i)}})​$ 87 | 88 | ${\theta_j}:={\theta_j}-a[\frac{1}{m}\sum\limits_{i=1}^{m}{({h_\theta}({{x}^{(i)}})-{{y}^{(i)}})x_{j}^{\left( i \right)}}+\frac{\lambda }{m}{\theta_j}]​$ $for j=1,2,...n​$ 89 | 90 | } 91 | 92 | -------------------------------------------------------------------------------- /notes/AndrewNg/神经网络概述.md: -------------------------------------------------------------------------------- 1 | ## 神经网络概述 2 | 3 | ### 为什么要使用神经网络? 4 | 5 | 无论是线性回归还是逻辑回归都有这样一个缺点,即:当特征太多时,计算的成本会非常大。 6 | 7 | 而事实证明,使用神经网络可以很好的解决这个问题。 8 | 9 | ### 背景 10 | 11 | 神经网络是一种模拟人脑的神经网络以期能够实现类人工智能的机器学习技术。神经网络最初产生的目的是制造能模拟大脑的机器,其逐渐兴起于二十世纪八九十年代,应用得非常广泛。但由于各种原因,在90年代的后期应用减少了。但是最近,神经网络又东山再起了。其中一个原因是:神经网络是计算量有些偏大的算法。然而大概由于近些年计算机的运行速度变快,才足以真正运行起大规模的神经网络。正是由于这个原因和技术方面的突破,如今的神经网络对于许多应用来说是最先进的技术。 12 | 13 | ### 模型表示 14 | 15 | 如图是简单的神经网络: 16 | 17 | ![img](../../notes/AndrewNg/images/12.png) 18 | 19 | 图为三层神经网络,第一层成为输入层(**Input Layer**),最后一层称为输出层(**Output Layer**),中间一层成为隐藏层(**Hidden Layers**)。其中$x_1$, $x_2$, $x_3$是输入单元(**input units**),我们将原始数据输入给它们。$a_1$, $a_2$, $a_3$是中间单元,它们负责将数据进行处理,然后呈递到下一层。最后是输出单元,它负责计算${h_\theta}\left( x \right)$。 20 | 21 | 另外有如下标注: 22 | $a_{i}^{\left( j \right)}$ 代表第$j$ 层的第 $i$ 个激活单元。${{\theta }^{\left( j \right)}}$代表从第 $j$ 层映射到第$ j+1$ 层时的**权重矩阵**,例如${{\theta }^{\left( 1 \right)}}$代表从第一层映射到第二层的权重的矩阵。其尺寸为:以第 $j+1$层的激活单元数量为行数,以第 $j$ 层的激活单元数加一为列数的矩阵。例如:上图所示的神经网络中${{\theta }^{\left( 1 \right)}}​$的尺寸为 3*4。 23 | 24 | 对于上图所示的模型,激活单元和输出分别表达为: 25 | 26 | $a_{1}^{(2)}=g(\Theta _{10}^{(1)}{{x}_{0}}+\Theta _{11}^{(1)}{{x}_{1}}+\Theta _{12}^{(1)}{{x}_{2}}+\Theta _{13}^{(1)}{{x}_{3}})$ 27 | $a_{2}^{(2)}=g(\Theta _{20}^{(1)}{{x}_{0}}+\Theta _{21}^{(1)}{{x}_{1}}+\Theta _{22}^{(1)}{{x}_{2}}+\Theta _{23}^{(1)}{{x}_{3}})$ 28 | $a_{3}^{(2)}=g(\Theta _{30}^{(1)}{{x}_{0}}+\Theta _{31}^{(1)}{{x}_{1}}+\Theta _{32}^{(1)}{{x}_{2}}+\Theta _{33}^{(1)}{{x}_{3}})$ 29 | ${{h}_{\Theta }}(x)=g(\Theta _{10}^{(2)}a_{0}^{(2)}+\Theta _{11}^{(2)}a_{1}^{(2)}+\Theta _{12}^{(2)}a_{2}^{(2)}+\Theta _{13}^{(2)}a_{3}^{(2)})$ 30 | 31 | 上面进行的讨论中只是将特征矩阵中的一行(一个训练实例)喂给了神经网络,我们需要将整个训练集都喂给我们的神经网络算法来学习模型。 32 | 33 | 我们把上图左半部分遮住,得到: 34 | 35 | ![img](../../notes/AndrewNg/images/13.png) 36 | 37 | 不难发现,右半部分其实就是以$a_0, a_1, a_2, a_3$, 按照**Logistic Regression**的方式输出$h_\theta(x)$ 38 | 39 | 其实神经网络就像是**logistic regression**,只不过我们把**logistic regression**中的输入向量$\left[ x_1\sim {x_3} \right]$ 变成了中间层的$\left[ a_1^{(2)}\sim a_3^{(2)} \right]$, 即: $h_\theta(x)=g\left( \Theta_0^{\left( 2 \right)}a_0^{\left( 2 \right)}+\Theta_1^{\left( 2 \right)}a_1^{\left( 2 \right)}+\Theta_{2}^{\left( 2 \right)}a_{2}^{\left( 2 \right)}+\Theta_{3}^{\left( 2 \right)}a_{3}^{\left( 2 \right)} \right)$ 40 | 我们可以把$a_0, a_1, a_2, a_3$看成更为高级的特征值,也就是$x_0, x_1, x_2, x_3$的进化体,并且它们是由 $x$与$\theta$决定的,使用这些训练出来的特征值,可以更好的预测新数据。这就是神经网络相比于逻辑回归和线性回归的优势。这里我们将第一层到输出层的计算过程称为**前向传播**。 41 | 42 | ### 举例 43 | 44 | 下图的神经元(三个权重分别为-30,20,20)可以被视为作用同于逻辑与(**AND**): 45 | 46 | ![img](../../notes/AndrewNg/images/16.jpg) 47 | 48 | 下图的神经元(三个权重分别为-10,20,20)可以被视为作用等同于逻辑或(**OR**): 49 | 50 | ![img](../../notes/AndrewNg/images/17.jpg) 51 | 52 | 下图的神经元(两个权重分别为 10,-20)可以被视为作用等同于逻辑非(**NOT**): 53 | 54 | ![img](../../notes/AndrewNg/images/18.jpg) 55 | 56 | 我们可以利用神经元来组合成更为复杂的神经网络以实现更复杂的运算。例如我们要实现**XNOR** 功能(输入的两个值必须一样,均为1或均为0),即 $\text{XNOR}=( \text{x}_1\, \text{AND}\, \text{x}_2 )\, \text{OR} \left( \left( \text{NOT}\, \text{x}_1 \right) \text{AND} \left( \text{NOT}\, \text{x}_2 \right) \right)$ 57 | 首先构造一个能表达$\left( \text{NOT}\, \text{x}_1 \right) \text{AND} \left( \text{NOT}\, \text{x}_2 \right)​$部分的神经元: 58 | 59 | ![img](../../notes/AndrewNg/images/19.jpg) 60 | 61 | 然后将表示 **AND** 的神经元和表示$\left( \text{NOT}\, \text{x}_1 \right) \text{AND} \left( \text{NOT}\, \text{x}_2 \right)$的神经元以及表示 OR 的神经元进行组合: 62 | 63 | ![img](../../notes/AndrewNg/images/20.jpg) 64 | 65 | 我们就得到了一个能实现 $\text{XNOR}$ 运算符功能的神经网络。 66 | 67 | 按这种方法我们可以逐渐构造出越来越复杂的函数,也能得到更加厉害的特征值。 68 | 69 | -------------------------------------------------------------------------------- /notes/AndrewNg/线性判别分析LDA.md: -------------------------------------------------------------------------------- 1 | ## 线性判别分析(LDA) 2 | 3 | ### LDA与PCA 4 | 5 | 我们知道,PCA(主成分分析)是有效的数据降维的方法,与之相同的是LDA也是一种将数据降维的方法。 6 | 7 | 那既然有了PCA,我们为什么还要LDA呢? 8 | 9 | 下面我们就来看看PCA与LDA之间的区别与联系。 10 | 11 | **PCA是一种无监督的数据降维方法,与之不同的是LDA是一种有监督的数据降维方法**。我们知道即使在训练样本上,我们提供了类别标签,在使用PCA模型的时候,我们是不利用类别标签的,而LDA在进行数据降维的时候是利用数据的类别标签提供的信息的。 12 | 13 | 从几何的角度来看,PCA和LDA都是讲数据投影到新的相互正交的坐标轴上。只不过在投影的过程中他们使用的约束是不同的,也可以说目标是不同的。PCA是将数据投影到方差最大的几个相互正交的方向上,以期待保留最多的样本信息,即**PCA降维的目标:将数据投影到方差最大的几个相互正交的方向上**。而**LDA降维的目标:尽可能多地保留数据样本的信息,同时满足投影后使得同类样本尽可能近,不同类样本尽可能远**。比如下图: 14 | 15 | ![img](../../notes/AndrewNg/images/20.png) 16 | 17 | 针对这个数据集,如果同样选择使用PCA,选择方差最大的方向作为投影方向,来对数据进行降维。那么PCA选出的最佳投影方向,将是图中红色直线所示的方向。不难发现,这样做投影之后两类数据样本将混合在一起,将不再线性可分,甚至是不可分的。这对我们来说简直就是地狱,本来线性可分的样本被我们亲手变得不再可分。 但是图中还有一条耀眼的黄色直线,向这条直线做投影即能使数据降维,同时还能保证两类数据仍然是线性可分的。上面的这个数据集如果使用LDA降维,找出的投影方向就是黄色直线所在的方向。 18 | 19 | 总体来说,LDA模型实现基本思想是和PCA相同的,都是**高维向低维空间做投影**。 20 | 21 | ### LDA模型 22 | 23 | -------------------------------------------------------------------------------- /notes/AndrewNg/逻辑回归.md: -------------------------------------------------------------------------------- 1 | ## 逻辑回归 2 | 3 | ### 引子 4 | 5 | 在分类问题中,你要预测的变量 y 是离散的值,我们将学习一种叫做逻辑回归 (**Logistic Regression**) 的算法,这是目前最流行使用最广泛的一种学习算法。 6 | 7 | 如果我们要用线性回归算法来解决一个分类问题,对于分类, y 取值为 0 或者1,但如果你使用的是线性回归,那么假设函数的输出值可能远大于 1,或者远小于0,即使所有训练样本的标签 y 都等于 0 或 1。所以为了解决这个问题,我们引入了逻辑回归算法,这个算法的性质是:它的输出值永远在0到 1 之间。 8 | 9 | ### 假说表示 10 | 11 | 我们可以忽略y是离散值的事实来处理分类问题,并使用我们的旧线性回归算法来尝试预测给定x。但是,很容易构建此方法执行得非常差的示例。 12 | 13 | 我们引入一个新的模型,逻辑回归,该模型的输出变量范围始终在0和1之间。 14 | 逻辑回归模型的假设是: $h_\theta \left( x \right)=g\left(\theta^{T}X \right)$ 15 | 其中: 16 | $X$ 代表特征向量 17 | $g$ 代表逻辑函数(**logistic function**)是一个常用的逻辑函数为**S**形函数(**Sigmoid function**),公式为: $g\left( z \right)=\frac{1}{1+{{e}^{-z}}}$。 18 | 19 | 该函数的图像为: 20 | 21 | ![img](../../notes/AndrewNg/images/12.jpg) 22 | 23 | ### 决策边界 24 | 25 | 在逻辑回归中,我们预测: 26 | 27 | 当${h_\theta}\left( x \right)>=0.5$时,预测 $y=1$。 28 | 29 | 当${h_\theta}\left( x \right)<0.5$时,预测 $y=0$ 。 30 | 31 | 根据上面绘制出的 **S** 形函数图像,我们知道当 32 | 33 | $z=0$ 时 $g(z)=0.5$ 34 | 35 | $z>0$ 时 $g(z)>0.5$ 36 | 37 | $z<0$ 时 $g(z)<0.5$ 38 | 39 | 又 $z={\theta^{T}}x$ ,即: 40 | ${\theta^{T}}x>=0$ 时,预测 $y=1$ 41 | ${\theta^{T}}x<0$ 时,预测 $y=0$ 42 | 43 | 现在假设我们有一个模型: 44 | 45 | ![img](../../notes/AndrewNg/images/9.png) 46 | 47 | 并且参数$\theta$ 是向量[-3 1 1]。 则当$-3+{x_1}+{x_2} \geq 0$,即${x_1}+{x_2} \geq 3$时,模型将预测 $y=1$。 48 | 我们可以绘制直线${x_1}+{x_2} = 3$,这条线便是我们模型的分界线,将预测为1的区域和预测为 0的区域分隔开。 49 | 50 | ![img](../../notes/AndrewNg/images/13.jpg) 51 | 52 | 而这条线就是决策边界,同样我们可以用逻辑回归模型来适应非常复杂形状的判定边界,不仅仅限于线性回归问题。 53 | 54 | ### 逻辑回归模型 55 | 56 | 线性回归的代价函数为:$J\left( \theta \right)=\frac{1}{m}\sum\limits_{i=1}^{m}{\frac{1}{2}{{\left( {h_\theta}\left({x}^{\left( i \right)} \right)-{y}^{\left( i \right)} \right)}^{2}}}$ 。 57 | 我们重新定义逻辑回归的代价函数为:$J\left( \theta \right)=\frac{1}{m}\sum\limits_{i=1}^{m}{{Cost}\left( {h_\theta}\left( {x}^{\left( i \right)} \right),{y}^{\left( i \right)} \right)}​$,其中 58 | 59 | ![img](../../notes/AndrewNg/images/10.png) 60 | 61 | ${h_\theta}\left( x \right)$与 $Cost\left( {h_\theta}\left( x \right),y \right)$之间的关系如下图所示: 62 | 63 | ![img](../../notes/AndrewNg/images/14.jpg) 64 | 65 | 这样构建的$Cost\left( {h_\theta}\left( x \right),y \right)$函数的特点是:当实际的 $y=1$ 且${h_\theta}\left( x \right)$也为 1 时误差为 0,当 $y=1$ 但${h_\theta}\left( x \right)$不为1时误差随着${h_\theta}\left( x \right)$变小而变大;当实际的 $y=0$ 且${h_\theta}\left( x \right)$也为 0 时代价为 0,当$y=0$ 但${h_\theta}\left( x \right)$不为 0时误差随着 ${h_\theta}\left( x \right)$的变大而变大。 66 | 将构建的 $Cost\left( {h_\theta}\left( x \right),y \right)$简化如下: 67 | $Cost\left( {h_\theta}\left( x \right),y \right)=-y\times log\left( {h_\theta}\left( x \right) \right)-(1-y)\times log\left( 1-{h_\theta}\left( x \right) \right)$ 68 | 带入代价函数得到: 69 | $J\left( \theta \right)=-\frac{1}{m}\sum\limits_{i=1}^{m}{[{{y}^{(i)}}\log \left( {h_\theta}\left( {{x}^{(i)}} \right) \right)+\left( 1-{{y}^{(i)}} \right)\log \left( 1-{h_\theta}\left( {{x}^{(i)}} \right) \right)]}$ 70 | 71 | 在得到这样一个代价函数以后,我们便可以用梯度下降算法来求得能使代价函数最小的参数了。算法为: 72 | 73 | **Repeat** { 74 | $\theta_j := \theta_j - \alpha \frac{\partial}{\partial\theta_j} J(\theta)$ 75 | (**simultaneously update all** ) 76 | } 77 | 78 | 求导后得到: 79 | 80 | **Repeat** { 81 | $\theta_j := \theta_j - \alpha \frac{1}{m}\sum\limits_{i=1}^{m}{{\left( {h_\theta}\left( \mathop{x}^{\left( i \right)} \right)-\mathop{y}^{\left( i \right)} \right)}}\mathop{x}_{j}^{(i)}$ 82 | **(simultaneously update all** ) 83 | } 84 | 85 | 那么,线性回归和逻辑回归是同一个算法吗?要回答这个问题,我们要观察逻辑回归看看发生了哪些变化。实际上,假设的定义发生了变化。 86 | 87 | 对于线性回归假设函数: 88 | 89 | ${h_\theta}\left( x \right)={\theta^T}X={\theta_{0}}{x_{0}}+{\theta_{1}}{x_{1}}+{\theta_{2}}{x_{2}}+...+{\theta_{n}}{x_{n}}$ 90 | 91 | 而现在逻辑函数假设函数: 92 | 93 | ${h_\theta}\left( x \right)=\frac{1}{1+{{e}^{-{\theta^T}X}}}$ 94 | 95 | 因此,即使更新参数的规则看起来基本相同,但由于假设的定义发生了变化,所以逻辑函数的梯度下降,跟线性回归的梯度下降实际上是两个完全不同的东西。 96 | 97 | -------------------------------------------------------------------------------- /notes/latex.md: -------------------------------------------------------------------------------- 1 | ## 行内与独行 2 | 3 | 1. 行内公式:将公式插入到本行内,符号:`$公式内容$`,如:$xyz$ 4 | 2. 独行公式:将公式插入到新的一行内,并且居中,符号:`$$公式内容$$`,如:$$xyz$$ 5 | 6 | ## 上标、下标与组合 7 | 8 | 1. 上标符号,符号:`^`,如:$x^4$ 9 | 2. 下标符号,符号:`_`,如:$x_1$ 10 | 3. 组合符号,符号:`{}`,如:${16}_{8}O{2+}_{2}$ 11 | 12 | ## 汉字、字体与格式 13 | 14 | 1. 汉字形式,符号:`\mbox{}`,如:$V_{\mbox{初始}}$ 15 | 2. 字体控制,符号:`\displaystyle`,如:$\displaystyle \frac{x+y}{y+z}$ 16 | 3. 下划线符号,符号:`\underline`,如:$\underline{x+y}$ 17 | 4. 标签,符号`\tag{数字}`,如:$\tag{11}$ 18 | 5. 上大括号,符号:`\overbrace{算式}`,如:$\overbrace{a+b+c+d}^{2.0}$ 19 | 6. 下大括号,符号:`\underbrace{算式}`,如:$a+\underbrace{b+c}_{1.0}+d$ 20 | 7. 上位符号,符号:`\stacrel{上位符号}{基位符号}`,如:$\vec{x}\stackrel{\mathrm{def}}{=}{x_1,\dots,x_n}$ 21 | 22 | ## 占位符 23 | 24 | 1. 两个quad空格,符号:`\qquad`,如:$x \qquad y$ 25 | 2. quad空格,符号:`\quad`,如:$x \quad y$ 26 | 3. 大空格,符号`\`,如:$x \ y$ 27 | 4. 中空格,符号`\:`,如:$x : y$ 28 | 5. 小空格,符号`\,`,如:$x , y$ 29 | 6. 没有空格,符号``,如:$xy$ 30 | 7. 紧贴,符号`\!`,如:$x ! y$ 31 | 32 | ## 定界符与组合 33 | 34 | 1. 括号,符号:`()\big(\big) \Big(\Big) \bigg(\bigg) \Bigg(\Bigg)`,如:$()\big(\big) \Big(\Big) \bigg(\bigg) \Bigg(\Bigg)$ 35 | 2. 中括号,符号:`[]`,如:$[x+y]​$ 36 | 3. 大括号,符号:`\{ \}`,如:${x+y}​$ 37 | 4. 自适应括号,符号:`\left \right`,如:$\left(x\right)​$,$\left(x{yz}\right)​$ 38 | 5. 组合公式,符号:`{上位公式 \choose 下位公式}`,如:${n+1 \choose k}={n \choose k}+{n \choose k-1}$ 39 | 6. 组合公式,符号:`{上位公式 \atop 下位公式}`,如:$\sum_{k_0,k_1,\ldots>0 \atop k_0+k_1+\cdots=n}A_{k_0}A_{k_1}\cdots​$ 40 | 41 | ## 四则运算 42 | 43 | 1. 加法运算,符号:`+`,如:$x+y=z$ 44 | 2. 减法运算,符号:`-`,如:$x-y=z$ 45 | 3. 加减运算,符号:`\pm`,如:$x \pm y=z$ 46 | 4. 减甲运算,符号:`\mp`,如:$x \mp y=z$ 47 | 5. 乘法运算,符号:`\times`,如:$x \times y=z$ 48 | 6. 点乘运算,符号:`\cdot`,如:$x \cdot y=z$ 49 | 7. 星乘运算,符号:`\ast`,如:$x \ast y=z$ 50 | 8. 除法运算,符号:`\div`,如:$x \div y=z$ 51 | 9. 斜法运算,符号:`/`,如:$x/y=z$ 52 | 10. 分式表示,符号:`\frac{分子}{分母}`,如:$\frac{x+y}{y+z}$ 53 | 11. 分式表示,符号:`{分子} \voer {分母}`,如:${x+y} \over {y+z}$ 54 | 12. 绝对值表示,符号:`||`,如:$|x+y|$ 55 | 56 | ## 高级运算 57 | 58 | 1. 平均数运算,符号:`\overline{算式}`,如:$\overline{xyz}$ 59 | 2. 开二次方运算,符号:`\sqrt`,如:$\sqrt x$ 60 | 3. 开方运算,符号:`\sqrt[开方数]{被开方数}`,如:$\sqrt[3]{x+y}$ 61 | 4. 对数运算,符号:`\log`,如:$\log(x)$ 62 | 5. 极限运算,符号:`\lim`,如:$\lim^{x \to \infty}_{y \to 0}{\frac{x}{y}}$ 63 | 6. 极限运算,符号:`\displaystyle \lim`,如:$\displaystyle \lim^{x \to \infty}_{y \to 0}{\frac{x}{y}}$ 64 | 7. 求和运算,符号:`\sum`,如:$\sum^{x \to \infty}_{y \to 0}{\frac{x}{y}}​$ 65 | 8. 求和运算,符号:`\displaystyle \sum`,如:$\displaystyle \sum^{x \to \infty}_{y \to 0}{\frac{x}{y}}$ 66 | 9. 积分运算,符号:`\int`,如:$\int^{\infty}_{0}{xdx}​$ 67 | 10. 积分运算,符号:`\displaystyle \int`,如:$\displaystyle \int^{\infty}_{0}{xdx}​$ 68 | 11. 微分运算,符号:`\partial`,如:$\frac{\partial x}{\partial y}$ 69 | 12. 矩阵表示,符号:`\begin{matrix} \end{matrix}`,如:$\left[ \begin{matrix} 1 &2 &\cdots &4\5 &6 &\cdots &8\\vdots &\vdots &\ddots &\vdots\13 &14 &\cdots &16\end{matrix} \right]$ 70 | 71 | ## 逻辑运算 72 | 73 | 1. 等于运算,符号:`=`,如:$x+y=z$ 74 | 2. 大于运算,符号:`>`,如:$x+y>z$ 75 | 3. 小于运算,符号:`<`,如:$x+y) 9 | - **《白话大数据与机器学习》** 10 | - **周志华《机器学习》** 11 | - **《统计学习方法》** 12 | - **《机器学习实战》** 13 | - **吴恩达机器学习教程** 14 | 15 | ### 第1-3天:线性回归任务一 16 | 17 | **学习视频内容** 18 | 19 | - 观看李宏毅课程内容:P1、P2。 20 | 21 | - 视频地址:[**点我**]() 22 | 23 | **学习打卡任务内容** 24 | 25 | - 了解什么是Machine learning 26 | 27 | - 学习中心极限定理,学习正态分布,学习最大似然估计 28 | 29 | - 推导回归Loss function 30 | 31 | - 学习损失函数与凸函数之间的关系 32 | 33 | - 了解全局最优和局部最优 34 | 35 | - 学习导数,泰勒展开 36 | 37 | - 推导梯度下降公式 38 | 39 | - 写出梯度下降的代码 40 | 41 | - 学习L2-Norm,L1-Norm,L0-Norm 42 | 43 | - 推导正则化公式 44 | 45 | - 说明为什么用L1-Norm代替L0-Norm 46 | 47 | - 学习为什么只对w/Θ做限制,不对b做限制 48 | 49 | **我的打卡** 50 | 51 | [线性回归任务一]() 52 | 53 | ### 第4-7天:线性回归任务二 54 | 55 | **学习视频内容:** 56 | 57 | - **观看**李宏毅课程内容:P4、P5、P6、P7。 58 | 59 | - 视频地址:[**点我**]() 60 | 61 | **学习打卡内容:** 62 | 63 | - 理解偏差和方差 64 | 65 | - 学习误差为什么是偏差和方差而产生的,并且推导数学公式 66 | 67 | - 过拟合,欠拟合,分别对应bias和variance什么情况 68 | 69 | - 学习鞍点,复习上次任务学习的全局最优和局部最优 70 | 71 | - 解决办法有哪些 72 | 73 | - 梯度下降 74 | 75 | - 学习Mini-Batch与SGD 76 | 77 | - 学习Batch与Mini-Batch,SGD梯度下降的区别 78 | 79 | - 如何根据样本大小选择哪个梯度下降(批量梯度下降,Mini-Batch) 80 | 81 | - 写出SGD和Mini-Batch的代码 82 | 83 | - 学习交叉验证 84 | 85 | - 学习归一化 86 | 87 | - 学习回归模型评价指标 88 | 89 | **更多的对梯度下降优化将在《李宏毅深度学习》中会有学习任务介绍(指数加权平均,动量梯度下降等)** 90 | 91 | **我的打卡** 92 | 93 | [线性回归任务二]() 94 | 95 | ### 第8-10天:线性回归任务三 96 | 97 | **学习打卡内容:** 98 | 99 | **大作业:** **预测PM2.5的值** 100 | 101 | ##### 要求 102 | 103 | 1、要求python3.5+ 104 | 2、只能用(1)numpy(2)scipy(3)pandas 105 | 3、请用梯度下降手写线性回归 106 | 4、最好的公共简单基线 107 | 108 | **我的打卡** 109 | 110 | [代码]() 111 | 112 | ### 第11-13天:机器学习任务四 113 | 114 | **学习视频内容:** 115 | 116 | - 观看李宏毅课程内容:p8 117 | 118 | - 视频连接:[**点我**]() 119 | 120 | - 学习[Datawhale整理笔记](https://datawhalechina.github.io/Leeml-Book/#/chapter8/chapter8) 121 | 122 | **学习打卡内容:** 123 | 124 | - 从基础概率推导贝叶斯公式,朴素贝叶斯公式(1) 125 | - 学习先验概率(2) 126 | - 学习后验概率(3) 127 | - 学习LR和linear regreeesion之间的区别(4) 128 | - 推导sigmoid function公式(5) 129 | 130 | ##### 我的打卡 131 | 132 | [机器学习任务四]() 133 | 134 | ### 第14-16天:机器学习任务五 135 | 136 | **学习视频内容:** 137 | 138 | - 观看李宏毅课程内容:p8 139 | - 视频连接:[**点我**]() 140 | - 学习[Datawhale整理笔记](https://datawhalechina.github.io/Leeml-Book/#/chapter9/chapter9) 141 | 142 | **学习打卡内容:** 143 | 144 | - 推导LR损失函数(1) 145 | - 学习LR梯度下降(2) 146 | - 利用代码描述梯度下降(选做)(3) 147 | - Softmax原理(4) 148 | - softmax损失函数(5) 149 | - softmax梯度下降(6) 150 | 151 | ##### 我的打卡 152 | 153 | [机器学习任务五]() 154 | 155 | ### 第17-19天:逻辑回归代码实现 156 | 157 | ##### 要求 158 | 159 | - 学习LR学习算法的核心代码 160 | - 写出详细的注释说明 161 | 162 | ##### 我的打卡 163 | 164 | [机器学习任务六]() 165 | 166 | ### 第20-22天:决策树 167 | 168 | ##### 学习目标 169 | 170 | - 信息量计算,原理 171 | - 信息熵 172 | - 证明$0⩽H(p)⩽log_2n$ 173 | - 联合概率,边缘概率 174 | - 联合熵,条件熵,条件熵公式推导 175 | - 互信息,互信息公式推导 176 | - 相对熵,交叉熵 177 | - 回顾LR中的交叉熵 178 | - 计算给定数据集中的香农熵 179 | 180 | ##### 我的打卡 181 | 182 | [机器学习任务七]() 183 | 184 | ### 第23-26天:决策树任务二 185 | 186 | **学习打卡内容:** 187 | 188 | - 总结决策树模型结构 189 | - 理解决策树递归思想 190 | - 学习信息增益 191 | - 学习信息增益率 192 | - 学习ID3算法优缺点 193 | - 学习C4.5算法优缺点 194 | - 理解C4.5算法在ID3算法上有什么提升 195 | - 学习C4.5算法在连续值上的处理 196 | - 学习决策树如何生成 197 | - 划分数据集代码 198 | - 选择最好的数据集划分方式代码 199 | - 创建树的函数代码 200 | 201 | ##### 我的打卡 202 | 203 | [机器学习任务八]() 204 | 205 | ### 第27-29天:决策树任务三 206 | 207 | **学习打卡内容:** 208 | 209 | - 阅读《机器学习实战》中42页-48页 210 | 211 | - 在python中使用Matlib注释绘制树图形 212 | 213 | - Matplotlib注释 214 | 215 | - 构造注释树 216 | 217 | ##### 我的打卡 218 | 219 | [机器学习任务九]() 220 | 221 | ### 第30-33天:决策树任务四 222 | 223 | **学习打卡内容:** 224 | 225 | - 阅读《李航统计学习方法》的65-74页 226 | 227 | - 学习Gini指数 228 | 229 | - 学习回归树 230 | 231 | - 剪枝 232 | 233 | ##### 我的打卡 234 | 235 | [机器学习任务十]() 236 | 237 | -------------------------------------------------------------------------------- /notes/lihongyi/day11-13.md: -------------------------------------------------------------------------------- 1 | ## 李宏毅机器学习Day11-13:朴素贝叶斯 2 | 3 | ### 贝叶斯定理 4 | 5 | **贝叶斯定理**是关于随机事件 A 和 B 的条件概率: 6 | 7 | ![img](../../notes/lihongyi/images/4.png) 8 | 9 | 其中P(A|B)是在 B 发生的情况下 A 发生的可能性。 10 | 11 | 在贝叶斯定理中,每个名词都有约定俗成的名称: 12 | 13 | 1. `P(A)是 A 的先验概率,之所以称为“先验”是因为它不考虑任何 B 方面的因素。` 14 | 2. `P(A|B)是已知 B 发生后 A 的条件概率,也由于得自 B 的取值而被称作 A 的后验概率。` 15 | 3. `P(B|A)是已知 A 发生后 B 的条件概率,也由于得自 A 的取值而被称作 B 的后验概率。` 16 | 4. `P(B)是 B 的先验概率,也作标淮化常量(normalizing constant)。` 17 | 18 | 联合概率:表示两个事件共同发生(数学概念上的交集)的概率。A 与 B 的联合概率表示为$P(B∩A)$。 19 | 20 | 根据条件概率的定义,在事件 B 发生的条件下事件 A 发生的概率为: 21 | 22 | $P(A|B)=\frac{P(A\cap B)}{P(B)}​$ 23 | 24 | 同样地,在事件 A 发生的条件下事件 B 发生的概率为: 25 | 26 | $P(B|A)=\frac{P(B\cap A)}{P(A)}​$ 27 | 28 | 结合这两个方程式,我们可以得到: 29 | 30 | $P(A|B)P(B) = P(B|A)P(A) $ 31 | 32 | 上式两边同除以 P(A),若P(A)是非零的,我们可以得到**贝叶斯定理**: 33 | 34 | ![img](../../notes/lihongyi/images/4.png) 35 | 36 | 该定理提供了一种计算的逆条件概率的方法,用已知的数据,来求取无法预知数据发生的概率。 37 | 38 | 这里$P(B)$ 可以根据**全概率公式**求出。 39 | 40 | #### 举例 41 | 42 | 假设两个盒子,各装了5个球,还得知随机抽一个球,抽到的是盒子1的球的概率是 2/3,是盒子2的球的概率是1/3。从盒子中蓝色球和绿色球的分配可以得到: 43 | 44 | - 在盒子1中随机抽一个球,是蓝色的概率为 4/5,绿的的概率为 1/5。 45 | - 在盒子2中随机抽一个球,是蓝色的概率为 2/5,绿的的概率为 3/5。 46 | 47 | 那么问题来了,随机从两个盒子中抽一个球,抽到的是盒子1中蓝色球的概率是多少? 48 | 49 | 由题目,已知: 50 | 51 | $P(Blue∣B1) = 4/5$ 52 | 53 | $P(B1) = 2/3$ 54 | 55 | $P(Blue) = P(Blue∣B1) P(B1) + P(Blue∣B1) P(B2) = 4/5*2/3+2/5*1/3$ = 2/3 56 | 57 | 基于上面公式,得: 58 | 59 | $P(B1∣Blue) = \frac{P(Blue∣B1) P(B1)}{P(Blue)} = 4/5 ​$ 60 | 61 | ### 贝叶斯决策论 62 | 63 | 贝叶斯决策论是概率框架下实施决策的基本方法。它假设决策问题可以用概率的形式来描述,并且假设所有有关的概率结构均已知。 64 | 65 | 假设$λ_{ij}$为真实标记为$c_j$的样本误分类为$c_i$所产生的损失,可以定义将样本$x$分类$c_i$的条件风险(即期望损失)为 66 | 67 | $$R(c_i|x) = \sum_\limits{j=1}^{N} \lambda_{ij}P(c_j|x)​$$ 68 | 69 | 为最小化总体风险,只需要在每个样本上选择那个能使得条件风险$R(c|x)​$最小的类别标记,即 70 | 71 | $h(x)=argminR(c|x)​$ 72 | 73 | 这就是贝叶斯最优分类器,此时的总体风险$R(h)$称为贝叶斯风险。 74 | 75 | 具体来说,若目标是最小化分类错误率,则$λ_{ij}​$ 当i != j时为1,i==j时为0, 此时条件风险为: 76 | 77 | $R(c|x) = 1-P(c|x)$ 78 | 79 | 贝叶斯最优分类器为: 80 | 81 | $h(x)=argmaxP(c|x)​$ 82 | 83 | 不难看出,要得到最小化决策风险,首先要获得后验概率$P(c|x)$。然而,这在现实任务中通常难以获得。 84 | 85 | 从这个角度看,机器学习所要实现得就是基于有限得训练样本集尽可能准备地估计出后验概率$P(c|x)​$。 86 | 87 | 有两种策略,一种是给定$x$,直接建模来预测$c$,这样得到的是**判别式模型**,一种是基于联合概率分布$P(c, x)$ 88 | 89 | 建模,再获得$P(c|x)​$,这样得到的是**生成式模型**。此节我们将要介绍的**贝叶斯分类器**即基于生成式模型。 90 | 91 | 根据贝叶斯定理, 92 | 93 | $P(c∣x) = \frac{P(x∣c) P(c)}{P(x)}​$ 94 | 95 | 求解$P(c|x)​$的问题转化为求解$P(x∣c)​$, $P(c)​$,$P(x)​$,其中$P(x)​$与类标记无关,$P(c)​$是类先验概率,表示样本空间中各类样本所占的比例,$P(x∣c)​$是类条件概率,可以使用**极大似然法**来估计。 96 | 97 | ### 朴素贝叶斯 98 | 99 | 朴素贝叶斯是基于贝叶斯定理与属性条件独立假设的分类方法,对于给定的训练数据集,首先基于属性条件独立假设学习输入/输出的联合概率分布;然后基于此模型,对给定的输入实例x,利用贝叶斯定理求出后验概率最大的输出y。 100 | 101 | 基于该假定,则有: 102 | 103 | $P(c∣x) = \frac{P(x∣c) P(c)}{P(x)} = \frac{P(c)}{P(x)} ∏_\limits{i=0}^{d}P(x_i|c)​$ 104 | 105 | 其中$d$为属性数目,$x_i$为$x$在第i个属性上的值。 106 | 107 | 朴素贝叶斯分类器公式: 108 | 109 | $h(x)=argmaxP(c|x) = argmax\frac{P(c)}{P(x)} ∏_\limits{i=0}^{d}P(x_i|c)​$ 110 | 111 | 其中对所有类别来说,$P(x)$相同。 112 | 113 | 求$P(x_i|c)​$ 时,对于连续属性可考虑概率密度函数。 114 | 115 | ### 先验概率和后验概率 116 | 117 | 先验概率是指根据以往经验和分析得到的概率,而不依赖于其他方面的因素。 118 | 119 | 后验概率是指事件发生的可能原因的概率。 120 | 121 | ### LR和linear regression区别 122 | 123 | 这里的LR意值逻辑回归。 124 | 125 | 逻辑回归和线性回归都属于广义线性回归。 126 | 127 | 区别如下: 128 | 129 | 1. 线性回归的输出是连续值,逻辑回归的输出区间为[0,1],可简单理解为事件发生的概率,基于该概率做分类。 130 | 2. 线性模型的优化目标函数是最小二乘,而逻辑回归则是似然函数。 131 | 3. 逻辑回归是线性回归被sigmoid函数映射后的结果,二者梯度下降公式一样,但实际上完全不是一回事。 132 | 4. 133 | 134 | ### 推导sigmoid function公式 135 | 136 | 根据贝叶斯定理及高斯分布,我们可以推导**s函数**。 137 | 138 | 过程如下: 139 | 140 | -------------------------------------------------------------------------------- /notes/lihongyi/day14-16.md: -------------------------------------------------------------------------------- 1 | ## 李宏毅机器学习Day14-16:逻辑回归 2 | 3 | ### 推导LR损失函数 4 | 5 | 假设我们有一组训练集,类别为c1,c2,数据基于后验概率$f_{w,b}(x) = P_{w,b}(c_1|x) = g(z)​$产生。 6 | 7 | 其中$g\left( z \right)=\frac{1}{1+{{e}^{-z}}}$,$z=\sum_\limits{i=0}^{d}w_ix_i+b$,$d​$表示属性数目。 8 | 9 | ![img](../../notes/lihongyi/images/5.png) 10 | 11 | 基于**最大似然法**,有: 12 | 13 | $L_{(w,b)}=f_{w,b}(x^1)f_{w,b}(x^2)(1−f_{w,b}(x^3))⋯f_{w,b}(x^N)$ 14 | 15 | 对于使得 $L(w,b)​$最大的$w​$和 $b​$,记做$w^∗​$和 $b^∗​$,即: 16 | 17 | $w^∗, b^∗=argmaxL(w,b) ​$ 18 | 19 | 对其取负自然对数后,转化为: 20 | 21 | $w^∗, b^∗=argmaxL(w,b) = argmin(-lnL(w,b))​$, 22 | 23 | 其中,有: 24 | 25 | $-lnL(w,b)=-lnf_{w,b}(x^1)-lnf_{w,b}(x^2)-ln(1−f_{w,b}(x^3))⋯-lnf_{w,b}(x^N)​$ 26 | 27 | $=\sum_\limits{i=0}^{m}-[y^ilnf(x^i)+(1-y^i)ln(1-f(x^i))]​$ 28 | 29 | $m$为样本数,$y^i$代表C1或者C2所对应的数值,这里$f_{w,b}(x)$对应的C1,所以表示C1时,$y^i$=1,表示C2时,$y^i​$=0。 30 | 31 | ### 学习LR梯度下降 32 | 33 | LR梯度下降推导如下: 34 | 35 | ![img](../../notes/lihongyi/images/6.png) 36 | 37 | ![img](../../notes/lihongyi/images/7.png) 38 | 39 | ![img](../../notes/lihongyi/images/8.png) 40 | 41 | 得到梯度下降算法如下: 42 | 43 | **Repeat** { 44 | $w_i :=w_i - η \sum\limits_{n}-(y^n-f_{w,b}(x^n))x_i^n$ 45 | **(simultaneously update all** ) 46 | } 47 | 48 | ### 为什么不用平方误差做损失函数? 49 | 50 | 1. 如果是交叉熵,距离target越远,微分值就越大,就可以做到距离target越远,更新参数越快。而平方误差在距离target很远的时候,微分值非常小,会造成移动的速度非常慢。如图,假设 $y^n=1$ ,如果 $f_{w,b}(x^n)=1$,就是非常接近target,会导致偏微分中第一部分为0,从而偏微分为0;而$f_{w,b}(x^n)0=$,会导致第二部分为0,从而偏微分也是0。 51 | 52 | ![img](../../notes/lihongyi/images/9.png) 53 | 54 | 2. 对于线性回归模型,我们定义的代价函数是所有模型误差的平方和。理论上来说,我们也可以对逻辑回归模型沿用这个定义,但是问题在于,当我们将带入到这样定义了的代价函数中时,我们得到的代价函数将是一个非凸函数。 55 | 56 | ![img](http://www.ai-start.com/ml2014/images/8b94e47b7630ac2b0bcb10d204513810.jpg) 57 | 58 | 这意味着我们的代价函数有许多局部最小值,这将影响梯度下降算法寻找全局最小值。 59 | 60 | ### 代码实现梯度下降 61 | 62 | ```python 63 | import numpy as np 64 | 65 | #定义sigmoid函数 66 | def sigmoid(z): 67 | return(1 / (1 + np.exp(-z))) 68 | 69 | 70 | # 定义损失函数 71 | def costFunction(theta, X, y): 72 | m = y.size 73 | h = sigmoid(X.dot(theta)) 74 | J = -1.0 * (1.0 / m) * (np.log(h).T.dot(y) + np.log(1 - h).T.dot(1 - y)) 75 | if np.isnan(J): 76 | return (np.inf) 77 | return J 78 | 79 | 80 | # 求解梯度 81 | def gradient(theta, X, y): 82 | m = y.size 83 | h = sigmoid(X.dot(theta)) 84 | grad = (1.0 / m) * X.T.dot(h - y) 85 | return (grad) 86 | ``` 87 | 88 | ### Softmax 89 | 90 | softmax就是如果判断输入属于某一个类的概率大于属于其他类的概率,那么这个类对应的值就逼近于1,其他类的值就逼近于0。该算法主要应用就是多分类,而且是互斥的,即只能属于其中的一个类。 91 | 92 | 关于Softmax 函数的定义如下所示: 93 | 94 | $S_i=\frac{e^{V_i}}{\sum_\limits{i}^{C}e^{V_i}}$ 95 | 96 | 其中,$V_i $是分类器前级输出单元的输出。$i$ 表示类别索引,总的类别个数为 $C$。$S_i $表示的是当前元素的指数与所有元素指数和的比值。 97 | 98 | #### softmax损失函数 99 | 100 | 在多分类问题中,我们经常使用**交叉熵**作为损失函数,其形式如下: 101 | 102 | $Loss = - \sum_\limits{i}y_ilna_i​$ 103 | 104 | 其中$y$代表我们的真实值,$a$代表我们softmax求出的值。 105 | 106 | #### softmax梯度下降 107 | 108 | ------ 109 | 110 | 参考: 111 | 112 | [softmax回归推导]() -------------------------------------------------------------------------------- /notes/lihongyi/day20-22.md: -------------------------------------------------------------------------------- 1 | ## 李宏毅机器学习Day20-22:决策树 2 | 3 | ### 信息论 4 | 5 | #### 信息熵(香浓熵) 6 | 7 | 信息熵是度量样本纯度的一种常用指标,代表随机变量的复杂度,其越小则纯度越高。定义如下: 8 | $$ 9 | Ent(D)=−\sum_\limits{k=1}^yp_klog_2p_k 10 | $$ 11 | 12 | 其中满足: 13 | 14 | $0⩽H(p)⩽log_2n$, 这里 $H(p)$ 等同于$Ent(D)$。 15 | 16 | 证明如下: 17 | 18 | ![img](../../notes/lihongyi/images/2.jpg) 19 | 20 | 21 | 22 | #### 相对熵 23 | 24 | 相对熵又称KL散度,如果我们对于同一个随机变量 x 有两个单独的概率分布 P(x) 和 Q(x),我们可以使用 KL 散度来衡量这两个分布的差异。 25 | 26 | 在机器学习中,P往往用来表示样本的真实分布,比如[1,0,0]表示当前样本属于第一类。Q用来表示模型所预测的分布,比如[0.7,0.2,0.1] 。直观的理解就是如果用P来描述样本,那么就非常完美。而用Q来描述样本,虽然可以大致描述,但是不是那么的完美,信息量不足,需要额外的一些“信息增量”才能达到和P一样完美的描述。如果我们的Q通过反复训练,也能完美的描述样本,那么就不再需要额外的“信息增量”,Q等价于P。 27 | 28 | 公式如下: 29 | 30 | $D_{KL}(p||q)=\sum_\limits{i=1}^np(x_i)log(\frac{p(x_i)}{q(x_i)}) $ 31 | 32 | #### 交叉熵 33 | 34 | $$ 35 | \begin{eqnarray} 36 | D_{KL}(p||q) &=& \sum_{i=1}^np(x_i)log(p(x_i))-\sum_{i=1}^np(x_i)log(q(x_i))\\ 37 | &=& -H(p(x))+[-\sum_{i=1}^np(x_i)log(q(x_i))] 38 | \end{eqnarray} 39 | $$ 40 | 41 | 等式的前一部分恰巧就是p的熵,等式的后一部分,就是交叉熵。 42 | 43 | 在机器学习中,我们需要评估label和predicts之间的差距,使用KL散度刚刚好,即$D_{KL}(y||\hat{y})$,由于KL散度中的前一部分不变,故在优化过程中,只需要关注交叉熵就可以了。所以一般在机器学习中直接用用交叉熵做loss,评估模型。 44 | 45 | #### 信息增益 46 | 47 | 条件熵代表在某一个条件下,随机变量的复杂度(不确定度)。 48 | 49 | 信息增益=信息熵-条件熵,代表了在一个条件下,信息复杂度(不确定性)减少的程度。 50 | 51 | #### CART算法 52 | 53 | 使用**基尼指数**划分属性,定义如下: 54 | $$ 55 | Gini{index}= \sum^V_\limits{v=1} \frac{|D^v|}{D} Gini(D^v),而 56 | Gini(D)= 1- \sum^y_{k=1} p_k^2 57 | $$ 58 | $Gini(D)$反映了从数据集$D$中随机抽取两个样本,其类别标记不一致的概率。因此$Gini(D)$越小,则数据集$D​$的纯度越高。 59 | 60 | ### 剪枝 61 | 62 | - 预剪枝:在构造决策树的同时进行剪枝,对每个节点进行划分前的估计,如果不能带来决策树泛化性能的提升则停止划分并将当前节点标记为叶节点。预剪枝有带来欠拟合的风险。 63 | - 后剪枝:决策树构造完成后进行剪枝,自底向上对非叶节点考察,如果该节点的子树替换为子树的叶节点可以提升泛化性能,则替换该子树为其叶节点。后剪纸的欠拟合风险很小,泛化性能通常优于预剪枝,但计算量大,训练时间较长。 64 | 65 | ### 计算香浓熵 66 | 67 | ```python 68 | import numpy as np 69 | import pandas as pd 70 | from collections import Counter 71 | 72 | def calcShannonEnt(data): 73 | """ 计算信息熵 74 | """ 75 | # 获取最后一列的数据 76 | labels = data[data.columns.values[-1]] 77 | # 统计所有类别对应出现的次数 78 | labelCounts = Counter(labels) 79 | # 数据已准备好,计算熵 80 | shannonEnt = 0.0 81 | dataLen = len(data) 82 | for key in labelCounts: 83 | pro = labelCounts[key] / dataLen 84 | shannonEnt -= pro * np.log2(pro) 85 | return shannonEnt 86 | 87 | data = pd.read_csv("watermelon_3a.csv") 88 | res = calcShannonEnt(data) 89 | print("香浓熵为:", res) 90 | ``` 91 | 92 | 输出结果如下: 93 | 94 | ``` 95 | 香浓熵为: 0.9975025463691153 96 | ``` 97 | 98 | ------ 99 | 100 | 相关资料: 101 | 102 | [决策树算法十问]() 103 | 104 | [Datawhale决策树笔记]() 105 | 106 | -------------------------------------------------------------------------------- /notes/lihongyi/day23-26.md: -------------------------------------------------------------------------------- 1 | ## 李宏毅机器学习Day23-26:决策树任务二 2 | 3 | ### 决策树模型结构 4 | 5 | 决策树是一种常见的机器学习方法,它基于二元划分策略(类似于二叉树),如下图所示 6 | 7 | ![img](../../notes/lihongyi/images/10.png) 8 | 9 | 一棵决策树包括一个根节点、若干个内部节点和若干个叶节点。叶节点对应决策的结果,而其他节点对应一个属性测试。决策树学习的目的就是构建一棵泛化能力强的决策树。决策树算法的优点包括: 10 | 11 | - 算法比较简单。 12 | - 理论易于理解。 13 | - 对噪声数据有很好的健壮性。 14 | 15 | 如何选择最优划分属性是决策树学习的关键。 16 | 17 | ### 决策树递归思想 18 | 19 | 从所有可能的决策树模型中选择最优决策树是NP完全问题,通常我们得到的决策树是次最优的,即不一定是全局最优,而是在一个节点处做到最优,决策树的构建属于贪心策略。 20 | 21 | 决策树学习算法通常是递归地选择最优特征,并根据该特征对训练数据集进行分割,使得对各个子数据集有一个最好的分类的过程。 22 | 23 | ### 信息增益 24 | 25 | 条件熵代表在某一个条件下,随机变量的复杂度(不确定度)。 26 | 27 | 信息增益=信息熵-条件熵,代表了在一个条件下,信息复杂度(不确定性)减少的程度。 28 | 29 | 其定义如下: 30 | $$ 31 | Gain(D, a) = Ent(D) - \sum^V_{v=1} \frac{|D^v|}{D} Ent(D^v) 32 | $$ 33 | 34 | $Ent(D)$为信息熵,假定当前样本集合$D$中第$k$类样本所占比例为$p_k(k=1,2,...y)$,则 35 | $$ 36 | Ent(D)=-\sum^y_{k=1}p_klog_2p_k 37 | $$ 38 | $V$表示使用某个属性对$D$根据不同的属性值进行划分产生的分支节点数,$ Ent(D^v)$表示第v个属性值对应的分支下的样本集合$D^v$的信息熵。 39 | 40 | ### 信息增益率 41 | 42 | 信息增益准则对可取值数目较多的属性有所偏好,所以有些算法不直接信用信息增益,而是使用**增益率**,其定义如下: 43 | $$ 44 | Gain_ratio(D, a) = \frac{Gain(D,a)}{IV(a)}, 45 | IV(a) = - \sum^V_\limits{v=1}\frac{|D^v|}{D} log_2\frac{|D^v|}{D} 46 | $$ 47 | 48 | #### ID3算法 49 | 50 | ID3算法的核心是在决策树各个节点上应用 信息增益 准则选择特征,递归的构建决策树。具体方法是:从根结点开始,对结点计算所有可能的特征的信息增益,选择信息增益最大的特征作为结点的特征,由该特征的不同取值建立子结点;再对子结点递归的调用以上方法,构建决策树;直到所有特征的信息增益均很小或没有特征可以选择为止。ID3相当于用极大似然法进行概率模型的选择。 51 | 52 | **缺点**:只能处理离散型属性,并且对倾向于**选择取值较多的属性**。 53 | 54 | **原因**:信息增益反映的给定一个条件以后不确定性减少的程度,必然是分得越细的数据集确定性更高,也就是条件熵越小,信息增益越大。 55 | 56 | #### C4.5算法 57 | 58 | 以信息增益率为准选择决策树的属性。 59 | 60 | C4.5算法是ID3算法的一种改进。 61 | 62 | **缺点**:偏向于选择取值较多的属性。 63 | 64 | ### 对连续值的处理 65 | 66 | 将连续型的属性变量进行离散化处理形成决策树的训练集: 67 | 68 | 1)将需要处理的样本(对应根节点)或样本子集(对应子树)按照连续变量的大小从小到大进行排序。 69 | 70 | 2)假设该属性对应不同的属性值共N个,那么总共有N-1个可能的候选分割值点,每个候选的分割阈值点的值为上述排序后的属性值中两两前后连续元素的中点。 71 | 72 | 3)用信息增益选择最佳划分。 73 | 74 | ### 代码实现 75 | 76 | #### 计算信息熵 77 | 78 | ```python 79 | def calcShannonEnt(dataSet): 80 | """ 计算信息熵 81 | """ 82 | # 获取最后一列的数据 83 | labels = dataSet[:,-1] 84 | # 统计所有类别对应出现的次数 85 | labelCounts = Counter(labels) 86 | # 数据已准备好,计算熵 87 | shannonEnt = 0.0 88 | dataLen = len(dataSet) 89 | for key in labelCounts: 90 | pro = labelCounts[key] / dataLen 91 | shannonEnt -= pro * np.log2(pro) 92 | return shannonEnt 93 | ``` 94 | 95 | #### 选择最优特征 96 | 97 | ```python 98 | def chooseFeature(dataSet): 99 | """ 100 | 选择最优属性 101 | gain = baseEntropy - newEntropy 102 | """ 103 | baseEntropy = calcShannonEnt(dataSet) # 整个数据集的信息熵 104 | bestInfoGain = 0.0 105 | bestFeature = -1 106 | # 遍历所有属性 107 | for i in range(len(dataSet[0]) -1): 108 | splitDict = Counter(dataSet[:, i]) 109 | newEntropy = 0.0 110 | for v in splitDict: 111 | subDataSet = dataSet[dataSet[:, i]==v] 112 | prob = splitDict[v]/float(len(dataSet)) 113 | newEntropy += prob * calcShannonEnt(subDataSet) 114 | gain = baseEntropy - newEntropy 115 | if gain > bestInfoGain: 116 | bestInfoGain = gain 117 | bestFeature = i 118 | return bestFeature 119 | ``` 120 | 121 | #### 生成决策树 122 | 123 | ```python 124 | def createTree(dataSet, feature_labels): 125 | """ 126 | 生成决策树 127 | 返回字典树 128 | dataSet: 数据集 129 | feature_labels: 属性标签 130 | """ 131 | labels = dataSet[:, -1] 132 | # 数据集样本类别相同 133 | if len(set(labels)) == 1: 134 | return labels[0] 135 | # 属性值为空或者唯一属性值相同,返回样本数最多的类别 136 | if len(dataSet[0]) == 1 or (len(dataSet[0]) == 2 and len(set(dataSet[:, 0])) == 1): 137 | resDict = dict(Counter(labels)) 138 | sortedClassCount = sorted(resDict.items(), key=lambda item: item[1], reverse=True) 139 | return sortedClassCount[0][0] 140 | 141 | # 选择最优属性 142 | bestFeat = chooseFeature(dataSet) 143 | bestFeatLabel = feature_labels[bestFeat] 144 | myTree = {bestFeatLabel:{}} 145 | del(feature_labels[bestFeat]) 146 | # 对选择属性进行划分 147 | for v in Counter(dataSet[:, bestFeat]): 148 | # 划分后的子集不应该包含我们选择属性对应的列 149 | subDataSet = np.delete(dataSet[dataSet[:, bestFeat]==v], bestFeat, axis=1) 150 | subLabels = feature_labels[:] 151 | # 生成子树 152 | myTree[bestFeatLabel][v] = createTree(subDataSet,subLabels) 153 | return myTree 154 | ``` 155 | 156 | #### 主程序 157 | 158 | ```python 159 | # 读取数据集,这里忽略 ids 及 连续属性列 160 | dataset = pd.read_csv("watermelon_3a.csv", usecols=['color', 'root', 'knocks', 'texture', 'navel', 'touch', 'label']) 161 | feature_labels = list(dataset.columns) 162 | dataset = dataset.values 163 | res = createTree(dataset, feature_labels) 164 | print(res) 165 | ``` 166 | 167 | #### 结果 168 | 169 | ``` 170 | { 171 | 'texture': { 172 | 'distinct': { 173 | 'root': { 174 | 'curl_up': 1, 175 | 'little_curl_up': { 176 | 'color': { 177 | 'dark_green': 1, 178 | 'black': { 179 | 'touch': {'hard_smooth': 1, 'soft_stick': 0} 180 | } 181 | } 182 | }, 183 | 'stiff': 0 184 | } 185 | }, 186 | 'little_blur': { 187 | 'touch': {'soft_stick': 1, 'hard_smooth': 0} 188 | }, 189 | 'blur': 0} 190 | } 191 | ``` 192 | 193 | -------------------------------------------------------------------------------- /notes/lihongyi/day30-33.md: -------------------------------------------------------------------------------- 1 | ## 李宏毅机器学习Day30-33:CART算法 2 | 3 | ### CART(分类回归树) 4 | 5 | 属于决策树的一种,由特征选择、树的生成以及剪枝组成,既可以用于分类也可以用于回归。CART算法采用的是一种二分递归分割的技术,将当前样本分成两个子样本集,使得生成的非叶子节点都有两个分支。因此CART实际上是一棵**二叉树**。 6 | 7 | CART假设决策树是二叉树,内部结点特征的取值为“是”和“否”,左分支是取值为“是”的分支,右分支是取值为“否”的分支。这样的决策树等价于递归地二分每个特征,将输入空间即特征空间划分为有限个单元,并在这些单元上确定预测的概率分布,也就是在输入给定的条件下输出的条件概率分布。 8 | 9 | **对分类树而言,CART用Gini系数最小化准则来进行特征选择,生成二叉树。当CART作为回归树的时候,使用样本的最小方差作为分裂节点的依据。** 10 | 11 | ### 基尼(Gini)指数 12 | 13 | 定义如下: 14 | $$ 15 | Gini{index}= \sum^V_\limits{v=1} \frac{|D^v|}{D} Gini(D^v),而 16 | Gini(D)= 1- \sum^y_{k=1} p_k^2 17 | $$ 18 | $Gini(D)$反映了从数据集$D$中随机抽取两个样本,其类别标记不一致的概率。因此$Gini(D)$越小,则数据集$D$的纯度越高。 19 | 20 | ### 生成分类树 21 | 22 | **输入:**训练数据集$D​$,停止计算的条件:结点中的样本个数小于预定阈值,或样本集的Gini系数小于预定阈值(样本基本属于同一类),或者没有更多特征。 23 | **输出:**CART决策树。 24 | 25 | 根据训练数据集,从根结点开始,递归地对每个结点进行以下操作,构建二叉决策树: 26 | 27 | 1. 设结点的训练数据集为$D$,计算现有特征对该数据集的Gini系数。此时,对每一个特征$A$,对其可能取的每个值$a$,根据样本点对$A=a$的测试为“是”或 “否”将$D$分割成$D1$和$D2$两部分,计算$A=a$时的Gini系数。 28 | 2. 在所有可能的特征$A$以及它们所有可能的切分点$a$中,选择Gini系数最小的特征及其对应的切分点作为最优特征与最优切分点。依最优特征与最优切分点,从现结点生成两个子结点,将训练数据集依特征分配到两个子结点中去。 29 | 3. 对两个子结点递归地调用步骤1~2,直至满足停止条件。 30 | 4. 生成CART决策树。 31 | 32 | 计算过程类似ID3,只是选择最优特征的依据不同而已。 33 | 34 | ### 生成回归树 35 | 36 | **输入:**训练数据集$D $ 37 | **输出:**回归树$f(x)$ 38 | 39 | 在训练数据集所在的输入空间中,递归得将每一个区域划分为两个子区域并决定每个子区域上的输出值,构建二叉决策树: 40 | 41 | 1. 选择最优切分变量j和切分点s,求解 42 | $$ 43 | min_{j,s}[min_{c_1}\sum_{x_i\in R_1(j,s)}(y_i-c_1)^2+min_{c_2}\sum_{x_i\in R_2(j,s)}(y_i-c_2)^2] 44 | $$ 45 | 46 | 47 | 遍历变量j,对固定的切分变量j扫描切分点s,选择使上式达到误差最小的变量(j,s),其中$R1$和$R2​$表示的是划分之后的空间。 48 | 49 | 2. 用选定的(j,s)划分区域并决定响应的输出值。 50 | $$ 51 | R_1(j,s)=\{x^{(j)}\}\leq s,\quad R_2(j,s)=\{x|x^{(j)}>s\} 52 | $$ 53 | 54 | $$ 55 | c_m=\frac{1}{N_m}\sum_{x_i\in R_m(j,s)}y_i,\quad x\in R_m,m=1,2 56 | $$ 57 | 58 | 3. 继续对两个子区域调用步骤1~2,直到满足停止条件。 59 | 60 | 4. 将输入空间划分为M个区域$R_1,R_2,R_3....R_M$,生成决策树: 61 | $$ 62 | f(x)=\sum_{m=1}^Mc_mI(x\in R_m) 63 | $$ 64 | 65 | 66 | 67 | ------ 68 | 69 | ##### 参考 70 | 71 | [CART算法的原理以及实现]() 72 | 73 | -------------------------------------------------------------------------------- /notes/lihongyi/images/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/lihongyi/images/1.jpg -------------------------------------------------------------------------------- /notes/lihongyi/images/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/lihongyi/images/1.png -------------------------------------------------------------------------------- /notes/lihongyi/images/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/lihongyi/images/10.png -------------------------------------------------------------------------------- /notes/lihongyi/images/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/lihongyi/images/2.jpg -------------------------------------------------------------------------------- /notes/lihongyi/images/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/lihongyi/images/2.png -------------------------------------------------------------------------------- /notes/lihongyi/images/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/lihongyi/images/3.png -------------------------------------------------------------------------------- /notes/lihongyi/images/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/lihongyi/images/4.png -------------------------------------------------------------------------------- /notes/lihongyi/images/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/lihongyi/images/5.png -------------------------------------------------------------------------------- /notes/lihongyi/images/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/lihongyi/images/6.png -------------------------------------------------------------------------------- /notes/lihongyi/images/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/lihongyi/images/7.png -------------------------------------------------------------------------------- /notes/lihongyi/images/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/lihongyi/images/8.png -------------------------------------------------------------------------------- /notes/lihongyi/images/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/lihongyi/images/9.png -------------------------------------------------------------------------------- /notes/lihongyi/相关文章收藏.md: -------------------------------------------------------------------------------- 1 | **[如何理解无偏估计量?]()** 2 | 3 | ###### [为什么样本方差(sample variance)的分母是 n-1?]() 4 | 5 | **[图文并茂的PCA教程]()** 6 | 7 | **[一篇深入剖析PCA的好文](https://www.cnblogs.com/hadoop2015/p/7419087.html)** 8 | 9 | **[详细解释主成分分析]()** 10 | 11 | **[如何让奇异值分解(SVD)变得不“奇异”?](https://redstonewill.com/1529/)** 12 | 13 | **[奇异值的物理意义是什么?](https://www.zhihu.com/question/22237507)** 14 | 15 | **[如何通俗地理解奇异值?](https://www.matongxue.com/madocs/306.html)** 16 | 17 | [ROC,AUC透彻理解]() 18 | 19 | [超强整理,超详细解析,一文彻底搞懂ROC、AUC]() 20 | 21 | -------------------------------------------------------------------------------- /notes/nlp/day4-5.md: -------------------------------------------------------------------------------- 1 | ## NLP理论实践DAY4-5 特征提取 2 | 3 | ### 中文分词概念 4 | 5 | 中文分词是中文信息处理的基本技术,指将一个汉字序列切分成一个个单独的词。 6 | 7 | 分词就是将连续的字序列按照一定的规范重新组合成词序列的过程。 8 | 9 | **基于字典的分词方法**,它是按照一定策略将待分析的汉字串与一个“充分大的”机器词典中的词条进行匹配,若在词典中找到某个字符串,则匹配成功。根据扫描方向的不同,这种分词方法分为正向匹配、逆向匹配和双向匹配,常见的匹配原则有逐词匹配、最大匹配、最小匹配和最佳匹配。 10 | 11 | ![img](../../notes/nlp/images/5.png) 12 | 13 | #### 正向最大匹配法 14 | 15 | 最大匹配是指以词典为依据,取词典中最长单词为第一个次取字数量的扫描串,在词典中进行扫描(为提升扫描效率,还可以跟据字数多少设计多个字典,然后根据字数分别从不同字典中进行扫描)。例如:词典中最长词为“中华人民共和国”共7个汉字,则最大匹配起始字数为7个汉字。然后逐字递减,在对应的词典中进行查找。 16 | 17 | 以“我们在野生动物园玩”为例, 18 | 19 | 正向即从前往后取词,从7->1,每次减一个字,直到词典命中或剩下1个单字。 20 | 21 | 第1轮扫描 22 | 第1次:“我们在野生动物”,扫描7字词典,无 23 | 第2次:“我们在野生动”,扫描6字词典,无 24 | 。。。。 25 | 第6次:“我们”,扫描2字词典,有 26 | 扫描中止,输出第1个词为“我们”,去除第1个词后开始第2轮扫描 27 | 第2轮扫描: 28 | 第1次:“在野生动物园玩”,扫描7字词典,无 29 | 第2次:“在野生动物园”,扫描6字词典,无 30 | 。。。。 31 | 第6次:“在野”,扫描2字词典,有 32 | 扫描中止,输出第2个词为“在野”,去除第2个词后开始第3轮扫描 33 | 第3轮扫描: 34 | 第1次:“生动物园玩”,扫描5字词典,无 35 | 第2次:“生动物园”,扫描4字词典,无 36 | 第3次:“生动物”,扫描3字词典,无 37 | 第4次:“生动”,扫描2字词典,有 38 | 扫描中止,输出第3个词为“生动”,第4轮扫描 39 | 第4轮扫描: 40 | 第1次:“物园玩”,扫描3字词典,无 41 | 第2次:“物园”,扫描2字词典,无 42 | 第3次:“物”,扫描1字词典,无 43 | 扫描中止,输出第4个词为 ‘’物‘’,非字典词数加1,开始第5轮扫描 44 | 第5轮扫描: 45 | 第1次:“园玩”,扫描2字词典,无 46 | 第2次:“园”,扫描1字词典,有 47 | 扫描中止,输出第5个词为“园”,单字字典词数加1,开始第6轮扫描 48 | 第6轮扫描: 49 | 第1次:“玩”,扫描1字字典词,有 50 | 扫描中止,输出第6个词为“玩”,单字字典词数加1,整体扫描结束。 51 | 52 | 正向最大匹配法,最终切分结果为:“我们/在野/生动/物/园/玩”,其中,单字字典词为2,非词典词为1。 53 | 54 | #### 逆向最大匹配法 55 | 56 | 逆向即从后往前取词,从7->1,每次减一个字,直到词典命中或剩下1个单字。即: 57 | 58 | 第1轮扫描:“在野生动物园玩” 59 | 第1次:“在野生动物园玩”,扫描7字词典,无 60 | 第2次:“野生动物园玩”,扫描6字词典,无 61 | 。。。。 62 | 第7次:“玩”,扫描1字词典,有 63 | 扫描中止,输出“玩”,单字字典词加1,开始第2轮扫描 64 | 第2轮扫描:“们在野生动物园” 65 | 第1次:“们在野生动物园”,扫描7字词典,无 66 | 第2次:“在野生动物园”,扫描6字词典,无 67 | 第3次:“野生动物园”,扫描5字词典,有 68 | 扫描中止,输出“野生动物园”,开始第3轮扫描 69 | 第3轮扫描:“我们在” 70 | 第1次:“我们在”,扫描3字词典,无 71 | 第2次:“们在”,扫描2字词典,无 72 | 第3次:“在”,扫描1字词典,有 73 | 扫描中止,输出“在”,单字字典词加1,开始第4轮扫描 74 | 第4轮扫描:“我们” 75 | 第1次:“我们”,扫描2字词典,有 76 | 扫描中止,输出“我们”,整体扫描结束。 77 | 78 | 逆向最大匹配法,最终切分结果为:“我们/在/野生动物园/玩”,其中,单字字典词为2,非词典词为0。 79 | 80 | #### 双向最大匹配法 81 | 82 | 正向最大匹配法和逆向最大匹配法,都有其局限性,我举得例子是正向最大匹配法局限性的例子,逆向也同样存在(如:长春药店,逆向切分为“长/春药店”),因此有人又提出了双向最大匹配法,双向最大匹配法。即,两种算法都切一遍,然后根据大颗粒度词越多越好,非词典词和单字词越少越好的原则,选取其中一种分词结果输出。 83 | 84 | 如:“我们在野生动物园玩” 85 | 86 | 正向最大匹配法,最终切分结果为:“我们/在野/生动/物/园/玩”,其中,两字词3个,单字字典词为2,非词典词为1。 87 | 88 | 逆向最大匹配法,最终切分结果为:“我们/在/野生动物园/玩”,其中,五字词1个,两字词1个,单字字典词为2,非词典词为0。 89 | 90 | 非字典词:正向(1)>逆向(0)(越少越好) 91 | 92 | 单字字典词:正向(2)=逆向(2)(越少越好) 93 | 94 | 总词数:正向(6)>逆向(4)(越少越好) 95 | 96 | 因此最终输出为逆向结果。 97 | 98 | ### 词、字符频率统计 99 | 100 | 使用 collections.Counter 进行统计,jieba进行分词。 101 | 102 | ### unigram、bigram、trigram 103 | 104 | 为了解决自由参数数目过多的问题,引入了马尔科夫假设:随意一个词出现的概率只与它前面出现的有限的n个词有关。基于上述假设的统计语言模型被称为N-gram语言模型。 105 | 106 | 从模型的效果来看,理论上n的取值越大,效果越好。但随着n取值的增加,效果提升的幅度是在下降的。同时还涉及到一个可靠性和可区别性的问题,参数越多,可区别性越好,但同时单个参数的实例变少从而降低了可靠性。 107 | 其中,有关中文分词的一些概念是我们需要掌握的,譬如: 108 | 109 | unigram 一元分词,把句子分成一个一个的汉字,每个词之间没有关联关系; 110 | bigram 二元分词,把句子从头到尾每两个字组成一个词语,当前词只和上一个词有关系; 111 | trigram 三元分词,把句子从头到尾每三个字组成一个词语,当前词只和前两个词有关系。 112 | 比如: 113 | 114 | 大连海事大学: 115 | 116 | unigram 形式为:大/连/海/事/大/学 117 | 118 | bigram形式为: 大连/连海/海事/事大/大学 119 | 120 | trigram形式为:大连海/连海事/海事大事通大学 121 | 122 | ### 文档向量化 123 | 124 | 步骤如下: 125 | 126 | 1. 分词 127 | 2. 去停用词 128 | 3. 每篇文档的向量化 129 | 130 | -------------------------------------------------------------------------------- /notes/nlp/day6-7.md: -------------------------------------------------------------------------------- 1 | ## NLP理论实践DAY6-7 特征选择 2 | 3 | ### TF-IDF 4 | 5 | TF-IDF是Term Frequency - Inverse Document Frequency的缩写,即“词频-逆文本频率”。它由两部分组成,TF和IDF。 6 | 7 | 前面的TF也就是我们前面说到的词频,我们之前做的向量化也就是做了文本中各个词的出现频率统计,并作为文本特征,这个很好理解。关键是后面的这个IDF,即“逆文本频率”如何理解。 8 | 9 | 比如如下几个文本: 10 | 11 | ``` 12 | "I come to China to travel", 13 | "This is a car polupar in China", 14 | "I love tea and Apple ", 15 | "The work is to write some papers in science" 16 | ``` 17 | 18 | 不考虑停用词,处理后得到的词向量如下: 19 | 20 | ``` 21 | [[0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 2 1 0 0] 22 | [0 0 1 1 0 1 1 0 0 1 0 0 0 0 1 0 0 0 0] 23 | [1 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0] 24 | [0 0 0 0 0 1 1 0 1 0 1 1 0 1 0 1 0 1 1]] 25 | ``` 26 | 27 | 如果我们直接将统计词频后的19维特征做为文本分类的输入,会发现有一些问题。比如第一个文本,我们发现"come","China"和“Travel”各出现1次,而“to“出现了两次。似乎看起来这个文本与”to“这个特征更关系紧密。但是实际上”to“是一个非常普遍的词,几乎所有的文本都会用到,因此虽然它的词频为2,但是重要性却比词频为1的"China"和“Travel”要低的多。如果我们的向量化特征仅仅用词频表示就无法反应这一点。因此我们需要进一步的预处理来反应文本的这个特征,而这个预处理就是TF-IDF。我们的IDF就是来帮助我们来反应这个词的重要性的,进而修正仅仅用词频表示的词特征值。 28 | 29 | ### Bag-of-words(词袋) 30 | 31 | ![img](../../notes/nlp/images/6.png) 32 | 33 | Bag-of-words词袋模型最初被用在信息检索领域,对于一篇文档来说,假定不考虑文档内的词的顺序关系和语法,只考虑该文档是否出现过这个单词。假设有5类主题,我们的任务是来了一篇文档,判断它属于哪个主题。在训练集中,我们有若干篇文档,它们的主题类型是已知的。我们从中选出一些文档,每篇文档内有一些词,我们利用这些词来构建词袋。我们的词袋可以是这种形式:{‘watch’,'sports','phone','like','roman',……},然后每篇文档都可以转化为以各个单词作为横坐标,以单词出现的次数为纵坐标的直方图,如下图所示,之后再进行归一化,将每个词出现的频数作为文档的特征。 34 | 35 | 近几年,在图像领域,使用Bag-of-words方法也是取得了较好的结果。如果说文档对应一幅图像的话,那么文档内的词就是一个图像块的特征向量。一篇文档有若干个词构成,同样的,一幅图像由若干个图像块构成,而特征向量是图像块的一种表达方式。我们求得N幅图像中的若干个图像块的特征向量,然后用k-means算法把它们聚成k类,这样我们的词袋里就有k个词,然后来了一幅图像,看它包含哪些词,包含单词A,就把单词A的频数加1。最后归一化,得到这幅图像的BoW表示,假如k=4,每幅图像有8个小块(patch),那么结果可能是这样的:[2,0,4,2],归一化之后为[0.25,0,0.5,0.25]。 36 | 37 | 同样,在语音识别领域,也有Bag-of-words方法也大施了拳脚。假设一段语音信号有2秒长,我们取每帧长40ms,帧移10ms,就可以得到一小段一小段的语音信号,然后提取每一小段上的音频特征,假设这里使用12维MFCC,那么有多少个小段语音信号,就有多少个MFCC特征向量。我们的目标是来一段语音信号,判断它的情感类别。我们的做法是:取一定数量的MFCC特征向量,将它们聚成k个类,那么这里的词袋里的词就是这k个类别。对于一段语音信号,我们对其进行分段之后,将各小段分配到这k个类别上,那么,每个类别上就对应了这一段语音信号里属于该类的段的个数。最后归一化,得到其特征表示。 38 | 39 | ### 点互信息和互信息 40 | 41 | #### 点互信息 42 | 43 | 机器学习相关文献里面,经常会用到点互信息PMI(Pointwise Mutual Information)这个指标来衡量两个事物之间的相关性(比如两个 44 | 45 | 词)。 46 | 47 | 其原理很简单,公式如下: 48 | 49 | ![img](../../notes/nlp/images/1.jpg) 50 | 51 | 在概率论中,我们知道,如果x跟y不相关,则p(x,y)=p(x)p(y)。二者相关性越大,则p(x, y)就相比于p(x)p(y)越大。用后面的式子可能更好理解,在y出现的情况下x出现的条件概率p(x|y)除以x本身出现的概率p(x),自然就表示x跟y的相关程度。 52 | 53 | 举个自然语言处理中的例子来说,我们想衡量like这个词的极性(正向情感还是负向情感)。我们可以预先挑选一些正向情感的词,比如good。然后我们算like跟good的PMI。 54 | 55 | #### 互信息 56 | 57 | 点互信息PMI其实就是从信息论里面的互信息这个概念里面衍生出来的。 58 | 59 | 互信息即: 60 | 61 | ![img](../../notes/nlp/images/2.jpg) 62 | 63 | 其衡量的是两个随机变量之间的相关性,即一个随机变量中包含的关于另一个随机变量的信息量。所谓的随机变量,即随机试验结果的量的表示,可以简单理解为按照一个概率分布进行取值的变量,比如随机抽查的一个人的身高就是一个随机变量。可以看出,互信息其实就是对X和Y的所有可能的取值情况的点互信息PMI的加权和。 64 | 65 | 决策树学习中的信息增益等价于训练数据集中类与特征的互信息。 66 | 67 | ### 特征选择 68 | 69 | #### 过滤(Filter) 70 | 71 | 过滤法只用于检验特征向量和目标(响应变量)的相关度,不需要任何的机器学习的算法,不依赖于任何模型,只是应用统计量做筛选:我们根据统计量的大小,设置合适的阈值,将低于阈值的特征剔除。 72 | 73 | 所以,从某种程度上来说,过滤法更像是一个数学问题,我们只在过滤之后的特征子集上进行建模和训练。 74 | 75 | 过滤法应用于回归问题,还可以采用互信息法(Mutual Information ),应用分类问题则可以使用卡方检验(Chi-Squared Test )。 76 | 77 | #### 包裹(Warpper) 78 | 79 | 与过滤法不同的是,包裹法采用的是特征搜索的办法。它的基本思路是,从初始特征集合中不断的选择子集合,根据学习器的性能来对子集进行评价,直到选择出最佳的子集。在搜索过程中,我们会对每个子集做建模和训练。 80 | 81 | 基于此,包裹法很大程度上变成了一个计算机问题:在特征子集的搜索问题(subset search)。我们有多种思路,最容易想到的办法是穷举(Brute-force search),遍历所有可能的子集,但这样的方法适用于特征数较少的情形,特征一旦增多,就会遇到组合爆炸,在计算上并不可行。(N个特征,则子集会有$2^N-1$种可能) 82 | 83 | 另一个思路是随机化搜索,比如拉斯维加斯算法(Las Vegas algorithm),但这样的算法在特征数大的时候,计算开销仍然很大,而且有给不出任何解的风险。所以,我们常使用的是贪心算法。 84 | 85 | **前向搜索(Forward search)** 86 | 87 | 在开始时,按照特征数来划分子集,每个子集只有一个特征,对每个子集进行评价。然后在最优的子集上逐步增加特征,使模型性能提升最大,直到增加特征并不能使模型性能提升为止。 88 | 89 | **后向搜索(Backward search)** 90 | 91 | 在开始时,将特征集合分别减去一个特征作为子集,每个子集有N—1个特征,对每个子集进行评价。然后在最优的子集上逐步减少特征,使得模型性能提升最大,直到减少特征并不能使模型性能提升为止。 92 | 93 | **双向搜索(Bidirectional search)** 94 | 95 | 将Forward search 和Backward search结合起来。 96 | 97 | **递归剔除(Recursive elimination )** 98 | 99 | 反复的训练模型,并剔除每次的最优或者最差的特征,将剔除完毕的特征集进入下一轮训练,直到所有的特征被剔除,被剔除的顺序度量了特征的重要程度。 100 | 101 | #### 嵌入法(Embedding) 102 | 103 | 如果仔细思考前两种方法,过滤法与学习器没有关系,特征选择只是用统计量做筛选,而包裹法则固定了学习器,特征选择只是在特征空间上进行搜索。而嵌入法最大的突破在于,特征选择会在学习器的训练过程中自动完成。 104 | 105 | 比如在回归问题上,我们可以通过降低权重系数的办法来降低过拟合,那么在线性模型中,降低权重系数就意味着与之相关的特征并不重要,实际上就是对特征做了一定的筛选。正则化的方法就是一种标准的嵌入法。 106 | 107 | 除此之外,决策树也是典型的嵌入法。因为决策树是利用一个特征进行分类,我们在生成决策树的过程就是挑选特征的过程,并且根据特征的不同取值构建子节点,直到特征没有分类能力或者很小,就停止生成节点。 108 | 109 | -------------------------------------------------------------------------------- /notes/nlp/day8.md: -------------------------------------------------------------------------------- 1 | ## NLP理论实践DAY8 朴素贝叶斯 2 | 3 | [用朴素贝叶斯进行文本分类(上)]() 4 | 5 | [用朴素贝叶斯进行文本分类(下)]() 6 | 7 | [朴素贝叶斯实战与进阶]() 8 | 9 | -------------------------------------------------------------------------------- /notes/nlp/images/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/nlp/images/1.jpg -------------------------------------------------------------------------------- /notes/nlp/images/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/nlp/images/1.png -------------------------------------------------------------------------------- /notes/nlp/images/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/nlp/images/2.jpg -------------------------------------------------------------------------------- /notes/nlp/images/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/nlp/images/2.png -------------------------------------------------------------------------------- /notes/nlp/images/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/nlp/images/3.png -------------------------------------------------------------------------------- /notes/nlp/images/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/nlp/images/4.png -------------------------------------------------------------------------------- /notes/nlp/images/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/nlp/images/5.png -------------------------------------------------------------------------------- /notes/nlp/images/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrazyXiao/machine-learning/8e1e8cb9cf6f4e1c403873168f2bacbd84a106bd/notes/nlp/images/6.png -------------------------------------------------------------------------------- /notes/nlp/readme.md: -------------------------------------------------------------------------------- 1 | ## NLP理论实践任务学习笔记 2 | 3 | ### 参考内容 4 | 5 | - [**tensorflow中文教程**]() 6 | - **《Sklearn与Tensorflow机器学习使用指南》** 7 | - [**自然语言处理入门及相关比赛**]() 8 | - [**《python自然语言处理第二版》**]() 9 | - **《自然语言处理综论》第二版** 10 | - [**CS224n 斯坦福深度自然语言处理课(2017)**]() 11 | 12 | ### Task1-数据集探索 13 | 14 | #### 数据集 15 | 16 | 数据集:中、英文数据集各一份 17 | 18 | 中文数据集:THUCNews 19 | 20 | THUCNews数据子集:https://pan.baidu.com/s/1hugrfRu 密码:qfud 21 | 22 | 英文数据集:IMDB数据集 Sentiment Analysis 23 | 24 | #### IMDB数据集下载和探索 25 | 26 | 参考TensorFlow官方教程:影评文本分类 | TensorFlow 27 | 28 | [科赛 - Kesci.com](https://www.kesci.com/home/project/5b6c05409889570010ccce90) 29 | 30 | #### THUCNews数据集下载和探索 31 | 32 | 参考博客中的数据集部分和预处理部分:[CNN字符级中文文本分类-基于TensorFlow实现 - 一蓑烟雨 - CSDN博客](https://blog.csdn.net/u011439796/article/details/77692621) 33 | 34 | 参考代码:[text-classification-cnn-rnn/cnews_loader.py at mas...](https://github.com/gaussic/text-classification-cnn-rnn/blob/master/data/cnews_loader.py) 35 | 36 | #### 学习召回率、准确率、ROC曲线、AUC、PR曲线这些基本概念 37 | 38 | 参考1:[机器学习之类别不平衡问题 (2) —— ROC和PR曲线_慕课手记](https://www.imooc.com/article/48072) 39 | 40 | -------------------------------------------------------------------------------- /notes/questions/1.缺失值处理.md: -------------------------------------------------------------------------------- 1 | ## 1) 缺失值较多 2 | 3 | 缺失值较多.直接将该特征舍弃掉,否则可能反倒会带入较大的噪声,对结果造成不良影响。 4 | 5 | ## 2) 缺失值较少 6 | 7 | 缺失值较少,其余的特征缺失值都在10%以内,我们可以采取很多的方式来处理: 8 | 9 | - 方式1: 把NaN直接作为一个特征,假设用0表示; 10 | 11 | ```python 12 | data_train.fillna(0) 13 | ``` 14 | 15 | - 方式2: 用均值填充; 16 | 17 | > 均值填充可能需要取条件均值,例如某训练集中患癌症和不患癌症的数据中,该值的差距很大,那么就应当填充label相同的数据的均值。 18 | 19 | ```python 20 | data_train.fillna(data_train.mean()) 21 | ``` 22 | 23 | - 方式3:用上下数据进行填充; 24 | 25 | ```python 26 | # 上一个数据填充 27 | data_train.fillna(method='pad') 28 | # 下一个数据填充 29 | data_train.fillna(method='bfill') 30 | ``` 31 | 32 | - 方式4:插值法 33 | 34 | ```python 35 | # 即估计中间点的值 36 | data_train.interpolate() 37 | ``` 38 | 39 | - 方式5:用随机森林等算法拟合 40 | 41 | > 将数据分为有值和缺失值2份,对有值的数据采用随机森林拟合,然后对有缺失值的数据进行预测,用预测的值来填充。 -------------------------------------------------------------------------------- /notes/questions/2.完整机器学习项目流程.md: -------------------------------------------------------------------------------- 1 | ## 1 抽象成数学问题 2 | 3 | 明确问题是进行机器学习的第一步。机器学习的训练过程通常都是一件非常耗时的事情,胡乱尝试时间成本是非常高的。 这里的抽象成数学问题,指的我们明确我们可以获得什么样的数据,目标是一个分类还是回归或者是聚类的问题,如果都不是的话,如果划归为其中的某类问题。 4 | 5 | ## 2 获取数据 6 | 7 | 数据决定了机器学习结果的上限,而算法只是尽可能逼近这个上限。 数据要有代表性,否则必然会过拟合。 而且对于分类问题,数据偏斜不能过于严重,不同类别的数据数量不要有数个数量级的差距。 而且还要对数据的量级有一个评估,多少个样本,多少个特征,可以估算出其对内存的消耗程度,判断训练过程中内存是否能够放得下。如果放不下就得考虑改进算法或者使用一些降维的技巧了。如果数据量实在太大,那就要考虑分布式了。 8 | 9 | ## 3 特征预处理与特征选择 10 | 11 | 良好的数据要能够提取出良好的特征才能真正发挥效力。 特征预处理、数据清洗是很关键的步骤,往往能够使得算法的效果和性能得到显著提高。归一化、离散化、因子化、缺失值处理、去除共线性等,数据挖掘过程中很多时间就花在它们上面。这些工作简单可复制,收益稳定可预期,是机器学习的基础必备步骤。 筛选出显著特征、摒弃非显著特征,需要机器学习工程师反复理解业务。这对很多结果有决定性的影响。特征选择好了,非常简单的算法也能得出良好、稳定的结果。这需要运用特征有效性分析的相关技术,如相关系数、卡方检验、平均互信息、条件熵、后验概率、逻辑回归权重等方法。 12 | 13 | ## 4 训练模型与调优 14 | 15 | 直到这一步才用到我们上面说的算法进行训练。现在很多算法都能够封装成黑盒供人使用。但是真正考验水平的是调整这些算法的(超)参数,使得结果变得更加优良。这需要我们对算法的原理有深入的理解。理解越深入,就越能发现问题的症结,提出良好的调优方案。 16 | 17 | ## 5 模型诊断 18 | 19 | 如何确定模型调优的方向与思路呢?这就需要对模型进行诊断的技术。 过拟合、欠拟合 判断是模型诊断中至关重要的一步。常见的方法如交叉验证,绘制学习曲线等。过拟合的基本调优思路是增加数据量,降低模型复杂度。欠拟合的基本调优思路是提高特征数量和质量,增加模型复杂度。 误差分析 也是机器学习至关重要的步骤。通过观察误差样本,全面分析误差产生误差的原因:是参数的问题还是算法选择的问题,是特征的问题还是数据本身的问题…… 诊断后的模型需要进行调优,调优后的新模型需要重新进行诊断,这是一个反复迭代不断逼近的过程,需要不断地尝试, 进而达到最优状态。 20 | 21 | ## 6 模型融合 22 | 23 | 一般来说,模型融合后都能使得效果有一定提升。而且效果很好。 工程上,主要提升算法准确度的方法是分别在模型的前端(特征清洗和预处理,不同的采样模式)与后端(模型融合)上下功夫。因为他们比较标准可复制,效果比较稳定。而直接调参的工作不会很多,毕竟大量数据训练起来太慢了,而且效果难以保证。 24 | 25 | ## 7 上线运行 26 | 27 | 这一部分内容主要跟工程实现的相关性比较大。工程上是结果导向,模型在线上运行的效果直接决定模型的成败。 不单纯包括其准确程度、误差等情况,还包括其运行的速度(时间复杂度)、资源消耗程度(空间复杂度)、稳定性是否可接受。 这些工作流程主要是工程实践上总结出的一些经验。并不是每个项目都包含完整的一个流程。这里的部分只是一个指导性的说明,只有大家自己多实践,多积累项目经验,才会有自己更深刻的认识。 28 | 29 | -------------------------------------------------------------------------------- /notes/tf-idf.md: -------------------------------------------------------------------------------- 1 | ## TF-IDF 2 | 3 | ### 概述 4 | 5 | TF-IDF是Term Frequency - Inverse Document Frequency的缩写,即“词频-逆文本频率”。它由两部分组成,TF和IDF。 6 | 7 | 前面的TF也就是我们前面说到的词频,我们之前做的向量化也就是做了文本中各个词的出现频率统计,并作为文本特征,这个很好理解。关键是后面的这个IDF,即“逆文本频率”如何理解。 8 | 9 | 比如如下几个文本: 10 | 11 | ``` 12 | "I come to China to travel", 13 | "This is a car polupar in China", 14 | "I love tea and Apple ", 15 | "The work is to write some papers in science" 16 | ``` 17 | 18 | 不考虑停用词,处理后得到的词向量如下: 19 | 20 | ``` 21 | [[0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 2 1 0 0] 22 | [0 0 1 1 0 1 1 0 0 1 0 0 0 0 1 0 0 0 0] 23 | [1 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0] 24 | [0 0 0 0 0 1 1 0 1 0 1 1 0 1 0 1 0 1 1]] 25 | ``` 26 | 27 | 如果我们直接将统计词频后的19维特征做为文本分类的输入,会发现有一些问题。比如第一个文本,我们发现"come","China"和“Travel”各出现1次,而“to“出现了两次。似乎看起来这个文本与”to“这个特征更关系紧密。但是实际上”to“是一个非常普遍的词,几乎所有的文本都会用到,因此虽然它的词频为2,但是重要性却比词频为1的"China"和“Travel”要低的多。如果我们的向量化特征仅仅用词频表示就无法反应这一点。因此我们需要进一步的预处理来反应文本的这个特征,而这个预处理就是TF-IDF。我们的IDF就是来帮助我们来反应这个词的重要性的,进而修正仅仅用词频表示的词特征值。 28 | 29 | 概括来讲, IDF反应了一个词在所有文本中出现的频率,如果一个词在很多的文本中出现,那么它的IDF值应该低,比如上文中的“to”。而反过来如果一个词在比较少的文本中出现,那么它的IDF值应该高。比如一些专业的名词如“Machine Learning”。这样的词IDF值应该高。一个极端的情况,如果一个词在所有的文本中都出现,那么它的IDF值应该为0。 30 | 31 | 上面是从定性上说明的IDF的作用,那么如何对一个词的IDF进行定量分析呢?这里直接给出一个词xx的IDF的基本公式如下: 32 | $$ 33 | IDF(x)=log\frac{N}N_{(x)} 34 | $$ 35 | 36 | 37 | 其中,$N$代表语料库中文本的总数,而$N(x)$代表语料库中包含词x的文本总数。 38 | 39 | 上面的IDF公式已经可以使用了,但是在一些特殊的情况会有一些小问题,比如某一个生僻词在语料库中没有,这样我们的分母为0, IDF没有意义了。所以常用的IDF我们需要做一些平滑,使语料库中没有出现的词也可以得到一个合适的IDF值。平滑的方法有很多种,最常见的IDF平滑后的公式之一为: 40 | $$ 41 | IDF(x)=log\frac{N+1}{N_{(x)}+1}+1 42 | $$ 43 | 有了IDF的定义,我们就可以计算某一个词的TF-IDF值了: 44 | $$ 45 | TF−IDF(x)=TF(x)∗IDF(x) 46 | $$ 47 | 其中$TF(x)=(词x在当前文中出现次数)/(当前文本中所有单词出现次数和)​$。 48 | 49 | ### 实现 50 | 51 | #### 方法一 52 | 53 | ``` 54 | from sklearn.feature_extraction.text import TfidfTransformer 55 | from sklearn.feature_extraction.text import CountVectorizer 56 | 57 | corpus=["I come to China to travel", 58 | "This is a car polupar in China", 59 | "I love tea and Apple ", 60 | "The work is to write some papers in science"] 61 | 62 | vectorizer=CountVectorizer() 63 | 64 | transformer = TfidfTransformer() 65 | tfidf = transformer.fit_transform(vectorizer.fit_transform(corpus)) 66 | print tfidf 67 | ``` 68 | 69 | #### 方法二 70 | 71 | ``` 72 | from sklearn.feature_extraction.text import TfidfVectorizer 73 | tfidf2 = TfidfVectorizer() 74 | re = tfidf2.fit_transform(corpus) 75 | print re 76 | ``` 77 | 78 | -------------------------------------------------------------------------------- /notes/情感分析.md: -------------------------------------------------------------------------------- 1 | ## 情感分析 2 | 3 | ### 引言 4 | 5 | 情感分析在很多点上领域有很多的应用场景: 6 | 7 | - 比如,酒店网站需要提取用户对酒店的评价,然后策略性的进行显示,比如把负面的评价排的稍微往后面一点,总不能上来满屏都是脏乱差吧! 8 | - 比如,一些电商类的网站根据情感分析提取正负面的评价关键词,形成商品的标签。基于这些标签,用户可以快速知道大众对这个商品的看法 9 | - 比如,一些新闻类的网站,根据新闻的评论可以知道这个新闻的热点情况,是积极导向,还是消极导向,从而进行舆论新闻的有效控制。 10 | 11 | ### 方法 12 | 13 | #### 基于情感词典的情感分析 14 | 15 | 这种分析方法简单粗暴,并不需要有太多复杂的知识,但是要求有尽量庞大完备的词库,而且这种词库必须是某一个领域背景下的。至于为什么不能通用稍后再说.... 16 | 17 | 首先需要这样几个词典: 18 | 19 | ##### 停顿词词典 20 | 21 | ``` 22 | 的 和 得 之间 .... 23 | ``` 24 | 25 | ##### 正面评价词 26 | 27 | ``` 28 | 价格便宜 干净 美丽 物美价廉... 29 | ``` 30 | 31 | ##### 负面评价词 32 | 33 | ``` 34 | 埋汰 脏 差 坏 ... 35 | ``` 36 | 37 | ##### 程度词 38 | 39 | ``` 40 | 还行 0.8 41 | 非常好 3.0 42 | 凑合 0.5 43 | 一般 0.5 44 | 特别 2.0 45 | ``` 46 | 47 | ##### 否定词 48 | 49 | ``` 50 | 不 难道 非 ... 51 | ``` 52 | 53 | 这些词典基本每个领域都不一样,比如`声音大`这个词,在音响的领域里面表示正面评价;但是在空调的领域里面就是负面评价了。因此每个领域最好有自己专业的词库,这个词库可以基于爬虫也可以基于人工搜集整理。网上有很多可以下载到的词库,不过都是比较通用的。 54 | 55 | 然后就可以按照下面的步骤计算情感取向了: 56 | 57 | - 获取全部的用户评价内容 58 | - 先进行分词 59 | - 根据每个词计算总体的情感分值,公式如:`-1^(否定词的个数)*程度词的分值*评价词的分值` 60 | - 然后根据正负判断情感走向。 61 | 62 | 比如,`难道非得让我说差么?`中,`难道`和`非`都算否定词,这样分值就是`(-1)^2*1*-1 = -1`,结论是负面评价 63 | 再比如,`难道这样不好吗?`中,`难道`和`不`都是否定词,分值为`(-1)^2*1*1=1`,结论是正面评价 64 | 65 | 虽然说有上面这些规则,在一些特定语境里面情感分析还是会出现误差。而且词语的位置也是一个很重要的因素,在词典这种机制里面,是忽略掉位置的。下面我们再看看基于机器学习的分析方法吧! 66 | 67 | ### 基于机器学习的情感分析方法 68 | 69 | #### 定义问题 70 | 71 | 在情感分析中应用机器学习,首先第一步是定义问题,即先要判断情感分析是一个回归问题还是分类问题,还是聚类问题。由于用户基本上就是正面评价和负面评价,因此我们可以把它定义成二分类的问题。问题定义完,就可以考虑使用什么分类器的方法,比如逻辑回归、支持向量机、神经网络...都可以尝试。 72 | 73 | #### 准备数据 74 | 75 | 有机器学习背景的同学都应该知道,分类的问题属于有监督的学习问题,因此是需要提前准备一些标注数据的(标注的意思就是我们想要知道的结果)。比如现在有这样一波数: 76 | 77 | ``` 78 | 评价语1 正面评价 79 | 评价语2 负面评价 80 | 评价语3 正面评价 81 | 评价语4 正面评价 82 | ``` 83 | 84 | 其中评价属于最后我们想要的结果,即Label;评价语则是原始的数据,需要给变成可以计算的数值(方法有几种:**词袋**、**TF-IDF**、**word2vec**这个以后在详细说明,可以简单的理解为就是把一些评价文字,变成了 01010101的数值作为特征) 85 | 86 | 然后我们就形成了这样的数据: 87 | 88 | ``` 89 | (0 1 1 0 1),1 90 | (1 1 0 0 1),0 91 | (0 1 0 0 0),1 92 | (0 1 1 1 0),1 93 | ``` 94 | 95 | 接下来就需要准备训练集和测试集,训练集用来训练模型;测试集用来测试模型是否正确。训练集在选取时,需要注意正负两个label的比例。试想一下,如果你的训练集里面90%都是负面评价,那么这个模型直接就写死只返回负面评价的结果,那么如果测试集也是同样的数据分布比例,那么正确率也会高达90%。这样显然是不合理的,因此要保证样本中正负评价数据的均衡。关于评测,手段有很多比如RMSE,MSE等等,有兴趣可以多了解下。 96 | 97 | ##### Bag-of-words(词袋) 98 | 99 | Bag-of-words model (BoW model)忽略文本的语法和语序,用一组无序的单词(words)来表达一段文字或一个文档,近年来BoW 模型被广泛应用于计算机视觉中,与应用于文本的BoW 类比,图像的特征(feature)被当作单词(Word)。 100 | 101 | ``` 102 | John likes to watch movies. Mary likes too. 103 | John also likes to watch football games. 104 | ``` 105 | 106 | 107 | 根据上述两句话中出现的单词,构建一个字典(dictionary): 108 | 109 | {"John": 1, "likes": 2, "to": 3, "watch": 4, "movies": 5, "also": 6, "football": 7, "games": 8, "Mary": 9, "too": 10} 110 | 111 | 该字典中包含10个词,每个单词有唯一索引,注意它们的顺序和出现在句子中的顺序没有关联,根据这个词典,我们将上述两句话重新表达为下面的两个向量: 112 | 113 | ``` 114 | [1, 2, 1, 1, 1, 0, 0, 0, 1, 1] 115 | [1, 1, 1, 1, 0, 1, 1, 1, 0, 0] 116 | ``` 117 | 118 | 这两个向量共包含10个元素, 其中第i个元素表示字典中第i个单词在句子中出现的次数. 因此BoW模型可认为是一种统计直方图 (histogram). 在文本检索和处理应用中, 可以通过该模型很方便的计算词频。 119 | 120 | #### 训练模型 121 | 122 | 然后就是利用各种算法训练模型,训练之后对比一下,选一个正确率最高的即可。最后把模型保存下面,之后可以直接使用。 123 | 124 | #### 应用 125 | 126 | 这里就直接应用模型,传入响应评价对应的特征参数即可。 127 | 128 | ------ 129 | 130 | 其他: 131 | 132 | [情感分析实例]() 133 | 134 | -------------------------------------------------------------------------------- /notes/无量纲处理.md: -------------------------------------------------------------------------------- 1 | ### 无量纲处理 2 | 3 | 在进行特征选择之前,一般会先进行数据无量纲化处理,这样,表征不同属性(单位不同)的各特征之间才有可比性,如1cm 与 0.1kg 你怎么比?无量纲处理方法很多,使用不同的方法,对最终的机器学习模型会产生不同的影响。 4 | 5 | #### min-max归一化 6 | 7 | $$ 8 | x_{'} = \frac{x-min}{max-min} 9 | $$ 10 | 11 | 该方法是对原始数据进行线性变换,将其映射到[0,1]之间。 12 | 13 | 上式中,min是样本的最小值,max是样本的最大值。由于最大值与最小值可能是动态变化的,同时也非常容易受噪声(异常点、离群点)影响,因此一般适合小数据的场景。 14 | 15 | ``` 16 | from sklearn.preprocessing import MinMaxScaler 17 | x = np.array([[1,-1,2],[2,0,0],[0,1,-1]]) 18 | x1 = MinMaxScaler().fit_transform(x) 19 | ``` 20 | 21 | 不难发现,x1每列的值都在[0,1]之间,也就是说,该模块是按列计算的。 22 | 23 | #### z-score标准化 24 | 25 | z-score标准化(zero-mena normalization,0-均值标准化)方法的公式如下所示: 26 | $$ 27 | x_{'} = \frac{x-u}{σ} 28 | $$ 29 | 上式中,*x*是原始数据,*u*是样本均值,*σ*是样本标准差。z-score标准化方法试图将原始数据集标准化成均值为0,方差为1且接近于标准正态分布的数据集。然而,一旦原始数据的分布 不 接近于一般正态分布,则标准化的效果会不好。该方法比较适合数据量大的场景。 30 | 31 | ``` 32 | from sklearn.preprocessing import StandardScaler 33 | x = np.array([[1,2,3],[4,5,6],[1,2,1]]) 34 | x1 = StandardScaler().fit_transform(x) 35 | ``` 36 | 37 | 可以发现,x1的每一列加起来都是0,方差是1左右。注意该方法同样按列(即每个属性/特征)进行计算。 38 | 39 | 使用该类的好处在于可以保存训练集中的参数(均值、方差)直接使用其对象转换测试集数据。 40 | 41 | ``` 42 | #可以直接使用训练集对测试集数据进行转换 43 | scaler.transform([[-1., 1., 0.]]) 44 | ``` 45 | 46 | #### Normalization(正则化) 47 | 48 | 这个方法是根据**范数**来进行 Normalization的。 49 | 50 | *L*2范数即为欧式距离,则规则为*L*2的Normalization公式如下所示,易知,其将每行(条)数据转为相应的“单位向量”。 51 | $$ 52 | x_{'} = \frac{x}{\sqrt{\sum_{j}^mx_j^2}} 53 | $$ 54 | 55 | ``` 56 | from sklearn import preprocessing 57 | normalizer = preprocessing.Normalizer().fit(X) 58 | normalizer.transform(X) 59 | ``` 60 | 61 | Normalization的过程是将每个样本缩放到单位范数,即该方法按行(维度)进行计算。 62 | 63 | -------------------------------------------------------------------------------- /notes/机器学习之损失.md: -------------------------------------------------------------------------------- 1 | ### 什么是损失? 2 | 3 | 在机器学习中,损失是对糟糕预测的惩罚。也就是说,损失是一个数值,表示对于单个样本而言模型预测的准确程度。如果模型的预测完全准确,则损失为零,否则损失会较大。训练模型的目标是从所有样本中找到一组平均损失“较小”的权重和偏差。 4 | 5 | ### MSE(均方误差) 6 | 7 | 又称L2损失,常用于线性回归模型的损失函数。 8 | 9 | 公式如下: 10 | 11 | $MSE=\frac1N\sum\limits_{(x,y)∈D}^m(y−prediction(x))^2​$ 12 | 13 | 其中: 14 | 15 | $(x,y)$ 表示样本。 16 | 17 | $prediction(x)$指的是权重和偏差与特征集 x 结合的函数。 18 | 19 | $D $指的是包含多个有标签样本(即 (x,y))的数据集。 20 | 21 | $N ​$指的是 D 中的样本数量。 -------------------------------------------------------------------------------- /notes/机器学习相关算法.md: -------------------------------------------------------------------------------- 1 | ### 回归算法 2 | 3 | #### 线性回归 4 | 5 | 线性回归就是我们前面说过的房价求解问题。如何拟合出一条直线最佳匹配我所有的数据?一般使用“**最小二乘法**”来求解。“最小二乘法”的思想是这样的,假设我们拟合出的直线代表数据的真实值,而观测到的数据代表拥有误差的值。为了尽可能减小误差的影响,需要求解一条直线使所有误差的平方和最小。最小二乘法将最优问题转化为求函数极值问题。函数极值在数学上我们一般会采用求导数为0的方法。但这种做法并不适合计算机,可能求解不出来,也可能计算量太大。 6 | 7 |   计算机科学界专门有一个学科叫“数值计算”,专门用来提升计算机进行各类计算时的准确性和效率问题。例如,著名的“**梯度下降**”以及“**牛顿法**”就是数值计算中的经典算法,也非常适合来处理求解函数极值的问题。梯度下降法是解决回归模型中最简单且有效的方法之一。 8 | 9 | #### 逻辑回归 10 | 11 | 逻辑回归是一种与线性回归非常类似的算法,但是,从本质上讲,线型回归处理的问题类型与逻辑回归不一致。线性回归处理的是数值问题,也就是最后预测出的结果是数字,例如房价。而逻辑回归属于分类算法,也就是说,逻辑回归预测结果是离散的分类,例如判断这封邮件是否是垃圾邮件,以及用户是否会点击此广告等等。 12 | 13 |   实现方面的话,逻辑回归只是对对线性回归的计算结果加上了一个**Sigmoid函数**,将数值结果转化为了0到1之间的概率(Sigmoid函数的图像一般来说并不直观,你只需要理解对数值越大,函数越逼近1,数值越小,函数越逼近0),接着我们根据这个概率可以做预测,例如概率大于0.5,则这封邮件就是垃圾邮件,或者肿瘤是否是恶性的等等。从直观上来说,逻辑回归是画出了一条分类线。 14 | 15 | 逻辑回归算法划出的分类线基本都是线性的(也有划出非线性分类线的逻辑回归,不过那样的模型在处理数据量较大的时候效率会很低),这意味着当两类之间的界线不是线性时,逻辑回归的表达能力就不足。 16 | 17 | 18 | 19 | ### 神经网络 20 | 21 | 神经网络的诞生起源于对大脑工作机理的研究。早期生物界学者们使用神经网络来模拟大脑。机器学习的学者们使用神经网络进行机器学习的实验,发现在视觉与语音的识别上效果都相当好。在**BP算法**(加速神经网络训练过程的数值算法)诞生以后,神经网络的发展进入了一个热潮。 22 | 23 | 在神经网络中,每个处理单元事实上就是一个逻辑回归模型,逻辑回归模型接收上层的输入,把模型的预测结果作为输出传输到下一个层次。通过这样的过程,神经网络可以完成非常复杂的非线性分类。 24 | 25 | 进入90年代,神经网络的发展进入了一个瓶颈期。其主要原因是尽管有BP算法的加速,神经网络的训练过程仍然很困难。因此90年代后期支持向量机(SVM)算法取代了神经网络的地位。 26 | 27 | 28 | 29 | ### SVM(支持向量机) 30 | 31 | 支持向量机算法是诞生于统计学习界,同时在机器学习界大放光彩的经典算法。 32 | 33 | 支持向量机算法从某种意义上来说是逻辑回归算法的强化:通过给予逻辑回归算法更严格的优化条件,支持向量机算法可以获得比逻辑回归更好的分类界线。但是如果没有某类函数技术,则支持向量机算法最多算是一种更好的线性分类技术。 34 | 35 | 但是,通过跟高斯“核”的结合,支持向量机可以表达出非常复杂的分类界线,从而达成很好的的分类效果。“核”事实上就是一种特殊的函数,最典型的特征就是可以将低维的空间映射到高维的空间。 36 | 37 | 38 | 39 | ### 聚类算法 40 | 41 | 前面的算法中的一个显著特征就是我的训练数据中包含了标签,训练出的模型可以对其他未知数据预测标签。在下面的算法中,训练数据都是不含标签的,而算法的目的则是通过训练,推测出这些数据的标签。这类算法有一个统称,即无监督算法(前面有标签的数据的算法则是有监督算法)。无监督算法中最典型的代表就是聚类算法。 42 | 43 | 让我们还是拿一个二维的数据来说,某一个数据包含两个特征。我希望通过聚类算法,给他们中不同的种类打上标签,我该怎么做呢?简单来说,聚类算法就是计算种群中的距离,根据距离的远近将数据划分为多个族群。 44 | 45 | 聚类算法中包括: 46 | 47 | - k-Means 48 | - Hierarchical Clustering 49 | - Expectation Maximisation (EM) 50 | 51 | 52 | 53 | ### 降维算法 54 | 55 | 降维算法也是一种无监督学习算法,其主要特征是将数据从高维降低到低维层次。 56 | 57 | 刚才说的降维过程中减少的维度属于肉眼可视的层次,同时压缩也不会带来信息的损失(因为信息冗余了)。如果肉眼不可视,或者没有冗余的特征,降维算法也能工作,不过这样会带来一些信息的损失。但是,降维算法可以从数学上证明,从高维压缩到的低维中最大程度地保留了数据的信息。因此,使用降维算法仍然有很多的好处。 58 | 59 | 降维算法的主要作用是压缩数据与提升机器学习其他算法的效率。通过降维算法,可以将具有几千个特征的数据压缩至若干个特征。另外,降维算法的另一个好处是数据的可视化,例如将5维的数据压缩至2维,然后可以用二维平面来可视。降维算法的主要代表是**PCA算法**(即主成分分析算法)。 60 | 61 | 62 | 63 | ### 推荐算法 64 | 65 | 推荐算法是目前业界非常火的一种算法,在电商界,如亚马逊,天猫,京东等得到了广泛的运用。推荐算法的主要特征就是可以自动向用户推荐他们最感兴趣的东西,从而增加购买率,提升效益。推荐算法有两个主要的类别: 66 | 67 |   一类是基于物品内容的推荐,是将与用户购买的内容近似的物品推荐给用户,这样的前提是每个物品都得有若干个标签,因此才可以找出与用户购买物品类似的物品,这样推荐的好处是关联程度较大,但是由于每个物品都需要贴标签,因此工作量较大。 68 | 69 |   另一类是基于用户相似度的推荐,则是将与目标用户兴趣相同的其他用户购买的东西推荐给目标用户,例如小A历史上买了物品B和C,经过算法分析,发现另一个与小A近似的用户小D购买了物品E,于是将物品E推荐给小A。 70 | 71 |   两类推荐都有各自的优缺点,在一般的电商应用中,一般是两类混合使用。推荐算法中最有名的算法就是**协同过滤算法**。 72 | 73 | 74 | 75 | ### 决策树 76 | 77 | 决策树(decision tree)是一个树结构。其每个非叶节点表示一个特征属性上的测试,每个分支代表这个特征属性在某个值域上的输出,而每个叶节点存放一个类别。使用决策树进行决策的过程就是从根节点开始,测试待分类项中相应的特征属性,并按照其值选择输出分支,直到到达叶子节点,将叶子节点存放的类别作为决策结果。常见的算法包括: 78 | 79 | - Classification and Regression Tree (CART) 80 | 81 | - Iterative Dichotomiser 3 (ID3) 82 | - C4.5 and C5.0 (different versions of a powerful approach) 83 | 84 | 85 | 86 | ### 模型融合算法 87 | 88 | 严格意义上来说,这不算是一种机器学习算法,而更像是一种优化手段/策略,它通常是结合多个简单的弱机器学习算法,去做更可靠的决策。拿分类问题举个例,直观的理解,就是单个分类器的分类是可能出错,不可靠的,但是如果多个分类器投票,那可靠度就会高很多。常用的模型融合增强方法包括: 89 | 90 | - Random Forest(**随机森林**) 91 | - Boosting 92 | - Bootstrapped Aggregation (Bagging) 93 | - AdaBoost 94 | - Stacked Generalization (blending) 95 | - Gradient Boosting Machines (GBM) 96 | - Gradient Boosted Regression Trees (GBRT) 97 | 98 | 99 | 100 | ### 贝叶斯算法 101 | 102 | 这里说的贝叶斯类算法,指的是在分类和回归问题中,隐含使用了贝叶斯原理的算法。包括: 103 | 104 | - Naive Bayes(**朴素贝叶斯**) 105 | 106 | - Gaussian Naive Bayes 107 | - Multinomial Naive Bayes 108 | - Averaged One-Dependence Estimators (AODE) 109 | - Bayesian Belief Network (BBN) 110 | 111 | - Bayesian Network (BN) 112 | 113 | 114 | 115 | ### 基于实例的算法 116 | 117 | 这里所谓的基于实例的算法,我指的是我们最后建成的模型,对原始数据样本实例依旧有很强的依赖性。这类算法在做预测决策时,一般都是使用某类相似度准则,去比对待预测的样本和原始样本的相近度,再给出相应的预测结果。常见的基于实例的算法有: 118 | 119 | - k-Nearest Neighbour (**KNN**) 120 | 121 | - Learning Vector Quantization (LVQ) 122 | 123 | - Self-Organizing Map (SOM) 124 | 125 | - Locally Weighted Learning (LWL) 126 | 127 | 128 | 129 | ### 人工神经网络类算法 130 | 131 | 偏向于更传统的感知算法,包括: 132 | 133 | - Perceptron(**感知机**) 134 | - Back-Propagation(**BP算法**) 135 | - Radial Basis Function Network (RBFN)(**径向基函数网络**) 136 | 137 | 138 | 139 | ### 半监督学习 140 | 141 | 以上算法都属于监督学习和无监督学习的范畴。而有另一类算法,基于此类的问题给出的训练数据,有一部分有标签,有一部分没有标签。我们想学习出数据组织结构的同时,也能做相应的预测。此类问题相对应的机器学习算法有**自训练**(Self-Training)、**直推学习**(Transductive Learning)、**生成式模型**(Generative Model)等。 142 | 143 | 144 | 145 | ### 无监督学习 146 | 147 | 包括**关联规则**,**聚类**,**降维**等算法。 148 | 149 | 150 | 151 | ### 深度学习 152 | 153 | 近来,机器学习的发展产生了一个新的方向,即“深度学习”。人工智能是机器学习的父类,而深度学习则是机器学习的子类。 154 | 155 | 虽然深度学习这四字听起来颇为高大上,但其理念却非常简单,就是传统的神经网络发展到了多隐藏层的情况。 156 | 157 | 目前业界许多的图像识别技术与语音识别技术的进步都源于深度学习的发展,除了Cortana等语音助手,还包括一些图像识别应用,其中典型的代表就是百度识图功能。常见的深度学习算法包括: 158 | 159 | - Deep Boltzmann Machine (DBM) 160 | - Deep Belief Networks (DBN) 161 | - Convolutional Neural Network (CNN) 162 | - Stacked Auto-Encoders 163 | 164 | 165 | 166 | ### 其他 167 | 168 | 除了以上算法之外,机器学习界还有其他的如**高斯判别**等等算法。但是上面列的六个算法是使用最多,影响最广,种类最全的典型。机器学习界的一个特色就是算法众多,发展百花齐放。 169 | 170 | 除了这些算法以外,有一些算法的名字在机器学习领域中也经常出现。但他们本身并不算是一个机器学习算法,而是为了解决某个子问题而诞生的。你可以理解他们为以上算法的子算法,用于大幅度提高训练过程。其中的代表有:**梯度下降法**,主要运用在线型回归,逻辑回归,神经网络,推荐算法中;**牛顿法**,主要运用在线型回归中;**BP算法**,主要运用在神经网络中;**SMO算法**,主要运用在SVM中。 171 | 172 | 173 | -------------------------------------------------------------------------------- /notes/模型融合.md: -------------------------------------------------------------------------------- 1 | ## 模型融合 2 | 3 | ### 什么是模型融合? 4 | 5 | ![img](../images/e1.png) 6 | 7 | ### Bagging 8 | 9 | ![img](../images/e2.png) 10 | 11 | ### Stacking 12 | 13 | Stacking的思想是一种有层次的融合模型,比如我们将用不同特征训练出来的三个GBDT模型进行融合时,我们会将三个GBDT作为基层模型,在其上在训练一个次学习器(通常为线性模型LR),用于组织利用基学习器的答案,也就是将基层模型的答案作为输入,让次学习器学习组织给基层模型的答案分配权重。 14 | 15 | ![img](../images/e3.png) 16 | 17 | ### Boosting 18 | 19 | Boosting 这其实思想相当的简单,大概是,对一份数据,建立 M 个模型(比如分类),一般这种模型比较简单,称为弱分类器。每次分类都将上一次分错的数据权重提高一点再进行分类,这样最终得到的分类器在测试数据与训练数据上都可以得到比较好的成绩。 20 | ![img](../images/e4.png) 21 | 22 | 我觉得 Boosting 更像是一个人学习的过程, 开始学一样东西的时候, 会去做一些习题,但是常常连一些简单的题目都会弄错,但是越到后面,简单的题目已经难不倒他了,就会去做更复杂的题目,等到他做了很多的题目后,不管是难题还是简单的题都可以解决掉了。 23 | 24 | #### GBDT 25 | 26 | ![img](../images/e5.png) 27 | 28 | ### Bagging vs Boosting 29 | 30 | ![img](../images/e6.png) 31 | 32 | -------------------------------------------------------------------------------- /notes/特征工程.md: -------------------------------------------------------------------------------- 1 | ## 特征工程 2 | 3 | ### 特征工程是什么? 4 | 5 |   有这么一句话在业界广泛流传:数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限而已。那特征工程到底是什么呢?顾名思义,其本质是一项工程活动,目的是最大限度地从原始数据中提取特征以供算法和模型使用。 6 | 7 | 特征处理是特征工程的核心部分,sklearn提供了较为完整的特征处理方法,包括数据预处理,特征选择,降维等。 8 | 9 | ![img](../images/1.jpg) 10 | 11 | ### 数据预处理 12 | 13 |   通过特征提取,我们能得到未经处理的特征,这时的特征可能有以下问题: 14 | 15 | - 不属于同一量纲:即特征的规格不一样,不能够放在一起比较。无量纲化可以解决这一问题。 16 | - 信息冗余:对于某些定量特征,其包含的有效信息为区间划分,例如学习成绩,假若只关心“及格”或不“及格”,那么需要将定量的考分,转换成“1”和“0”表示及格和未及格。二值化可以解决这一问题。 17 | - 定性特征不能直接使用:某些机器学习算法和模型只能接受定量特征的输入,那么需要将定性特征转换为定量特征。最简单的方式是为每一种定性值指定一个定量值,但是这种方式过于灵活,增加了调参的工作。通常使用**哑编码**的方式将定性特征转换为定量特征:假设有N种定性值,则将这一个特征扩展为N种特征,当原始特征值为第i种定性值时,第i个扩展特征赋值为1,其他扩展特征赋值为0。哑编码的方式相比直接指定的方式,不用增加调参的工作,对于线性模型来说,使用哑编码后的特征可达到非线性的效果。 18 | - 存在缺失值:缺失值需要补充。 19 | - 信息利用率低:不同的机器学习算法和模型对数据中信息的利用是不同的,之前提到在线性模型中,使用对定性特征哑编码可以达到非线性的效果。类似地,对定量变量多项式化,或者进行其他的转换,都能达到非线性的效果。 20 | 21 |  我们使用sklearn中的preproccessing库来进行数据预处理,可以覆盖以上问题的解决方案。 22 | 23 | #### [无量纲化]() 24 | 25 | #### 对定量特征二值化 26 | 27 | 定量特征二值化的核心在于设定一个阈值,大于阈值的赋值为1,小于等于阈值的赋值为0,公式表达如下: 28 | 29 | ![img](../images/3.png) 30 | 31 | 使用preproccessing库的Binarizer类对数据进行二值化的代码如下: 32 | 33 | ``` 34 | from sklearn.preprocessing import Binarizer 35 | #二值化,阈值设置为3,返回值为二值化后的数据 36 | Binarizer(threshold=3).fit_transform(iris.data) 37 | ``` 38 | 39 | #### 对定性特征哑编码 40 | 41 | ``` 42 | from sklearn.preprocessing import OneHotEncoder 43 | enc = OneHotEncoder() 44 | enc.fit([[0, 0, 3], 45 | [1, 1, 0], 46 | [0, 2, 1], 47 | [1, 0, 2]]) 48 | ans = enc.transform([[0, 1, 3]]).toarray() # 如果不加 toarray() 的话,输出的是稀疏的存储格式,即索引加值的形式,也可以通过参数指定 sparse = False 来达到同样的效果 49 | print(ans) # 输出 [[ 1. 0. 0. 1. 0. 0. 0. 0. 1.]] 50 | ``` 51 | 52 | 下面解释输出结果的意思。对于输入数组,这依旧是把每一行当作一个样本,每一列当作一个特征, 53 | 54 | - 我们先来看第一个特征,即第一列 [0,1,0,1][0,1,0,1],也就是说它有两个取值 0 或者 1,那么 one-hot 就会使用两位来表示这个特征,[1,0][1,0] 表示 0, [0,1][0,1] 表示 1,在上例输出结果中的前两位 [1,0...][1,0...] 也就是表示该特征为 0 55 | - 第二个特征,第二列 [0,1,2,0][0,1,2,0],它有三种值,那么 one-hot 就会使用三位来表示这个特征,[1,0,0][1,0,0] 表示 0, [0,1,0][0,1,0] 表示 1,[0,0,1][0,0,1] 表示 2,在上例输出结果中的第三位到第六位 [...0,1,0,0...][...0,1,0,0...] 也就是表示该特征为 1 56 | - 第二个特征,第三列 [3,0,1,2][3,0,1,2],它有四种值,那么 one-hot 就会使用四位来表示这个特征,[1,0,0,0][1,0,0,0] 表示 0, [0,1,0,0][0,1,0,0] 表示 1,[0,0,1,0][0,0,1,0] 表示 2,[0,0,0,1][0,0,0,1] 表示 3,在上例输出结果中的最后四位 [...0,0,0,1][...0,0,0,1] 也就是表示该特征为 3 57 | 58 | 好了,到此相信我们已经很明白它的意思了。值得注意的是,虽然训练样本中的数值仅仅代表类别,但是也必须使用数值格式的数据,如果使用字符串格式的数据会报错。 59 | 60 | #### 缺失值计算 61 | 62 | 由于IRIS数据集没有缺失值,故对数据集新增一个样本,4个特征均赋值为NaN,表示数据缺失。使用preproccessing库的Imputer类对数据进行缺失值计算的代码如下: 63 | 64 | ``` 65 | from numpy import vstack, array, nan 66 | from sklearn.preprocessing import Imputer 67 | #缺失值计算,返回值为计算缺失值后的数据 68 | #参数missing_value为缺失值的表示形式,默认为NaN 69 | #参数strategy为缺失值填充方式,默认为mean(均值) 70 | Imputer().fit_transform(vstack((array([nan, nan, nan, nan]), iris.data))) 71 | ``` 72 | 73 | #### 数据变换 74 | 75 | 常见的数据变换有基于多项式的、基于指数函数的、基于对数函数的。 76 | 77 | 使用preproccessing库的PolynomialFeatures类对数据进行多项式转换。 78 | 79 | 基于单变元函数的数据变换可以使用一个统一的方式完成,使用preproccessing库的FunctionTransformer对数据进行对数函数转换。 80 | 81 | ### 特征选择 82 | 83 | 当数据预处理完成后,我们需要选择有意义的特征输入机器学习的算法和模型进行训练。通常来说,从两个方面考虑来选择特征: 84 | 85 | - 特征是否发散:如果一个特征不发散,例如方差接近于0,也就是说样本在这个特征上基本上没有差异,这个特征对于样本的区分并没有什么用。 86 | - 特征与目标的相关性:这点比较显见,与目标相关性高的特征,应当优选选择。除方差法外,本文介绍的其他方法均从相关性考虑。 87 | 88 | 根据特征选择的形式又可以将特征选择方法分为3种: 89 | 90 | - Filter:过滤法,按照发散性或者相关性对各个特征进行评分,设定阈值或者待选择阈值的个数,选择特征。 91 | - Wrapper:包装法,根据目标函数(通常是预测效果评分),每次选择若干特征,或者排除若干特征。 92 | - Embedded:嵌入法,先使用某些机器学习的算法和模型进行训练,得到各个特征的权值系数,根据系数从大到小选择特征。类似于Filter方法,但是是通过训练来确定特征的优劣。 93 | 94 | 我们使用sklearn中的feature_selection库来进行特征选择。 95 | 96 | ### 降维 97 | 98 | 当特征选择完成后,可以直接训练模型了,但是可能由于特征矩阵过大,导致计算量大,训练时间长的问题,因此降低特征矩阵维度也是必不可少的。常见的降维方法除了以上提到的基于L1惩罚项的模型以外,另外还有**主成分分析法**(PCA)和**线性判别分析**(LDA),线性判别分析本身也是一个分类模型。PCA和LDA有很多的相似点,其本质是要将原始的样本映射到维度更低的样本空间中,但是PCA和LDA的映射目标不一样:PCA是为了让映射后的样本具有最大的发散性;而LDA是为了让映射后的样本有最好的分类性能。所以说PCA是一种无监督的降维方法,而LDA是一种有监督的降维方法。 -------------------------------------------------------------------------------- /notes/知识图谱.md: -------------------------------------------------------------------------------- 1 | ## 知识图谱 2 | 3 | ### 什么是知识图谱? 4 | 5 | 知识图谱本质上是一种大规模语义网络。这里关键词就是“语义网络”和“大规模”。 6 | 7 | #### 语义网络 8 | 9 | 语义网络表达了各种各样的实体、概念及其之间的各类语义关联。如下图,可看作一个简单的语义网络。 10 | 11 | ![img](../images/net.png) 12 | 13 | 图中“C罗”是一个实体,“金球奖”也是一个实体,他们俩之间有一个语义关系就是“获得奖项”。“运动员”、“足球运动员”都是概念,后者是前者的子类。 14 | 15 | #### 大规模 16 | 17 | 传统知识库构建主要依靠人工构建、代价高昂、规模有限。举个例子,我国的词林辞海是上万名专家花了10多年编撰而成的,但是它只有十几万词条。而现在任何一个互联网上的知识图谱,比如**DBpedia**,动辄包含上千万实体。人工构建的知识库虽然质量精良,但是规模有限。相比较于那个时代的语义网络,知识图谱规模更大。 18 | 19 | **当下,在更多实际场合下,知识图谱是作为一种技术体系,指代大数据时代知识工程的一系列代表性技术进展的总和。** 20 | 21 | ### 知识图谱的生命周期 22 | 23 | 知识图谱系统的生命周期包含四个重要环节:**知识表示、知识获取、知识管理与知识应用**。 24 | 25 | #### 知识表示 26 | 27 | 在知识表示方面,常用三元组(主语、谓词、宾语)表示知识图谱。如三元组<七里香,歌曲原唱,周杰伦>表示“七里香这首歌曲的原唱是周杰伦”这一知识。需要强调一点,知识图谱只能表达一些简单的关联事实,但很多领域应用的需求已经远远超出了三元组所能表达的简单关联事实,实际应用日益对于利用更加多元的知识表示丰富和增强知识图谱的语义表达能力提出了需求。 28 | 29 | #### 知识获取 30 | 31 | 知识的获取是个系统工程,步骤如下: 32 | 33 | ![img](../images/net.png) 34 | 35 | #### 知识管理 36 | 37 | 知识图谱的主要管理图谱的存储、检索等问题。 38 | 39 | 知识图谱的原始数据类型一般来说有三类(也是互联网上的三类原始数据): 40 | 41 | - 结构化数据(Structed Data),如关系数据库 42 | - 非结构化数据,如图片、音频、视频 43 | - 半结构化数据 如XML、JSON、百科 44 | 45 | 如何存储上面这三类数据类型呢?一般有两种选择,一个是通过RDF(资源描述框架)这样的规范存储格式来进行存储,比较常用的有Jena等。 46 | 47 | 还有一种方法,就是使用图数据库来进行存储,常用的有Neo4j等。 48 | 49 | ### 知识图谱的应用 50 | 51 | ![img](../images/5.png) 52 | 53 | ### 自底向上构建知识图谱 54 | 55 | 构建知识图谱是一个迭代更新的过程,根据知识获取的逻辑,每一轮迭代包含三个阶段: 56 | 57 | - 信息抽取:从各种类型的数据源中提取出实体、属性以及实体间的相互关系,在此基础上形成本体化的知识表达; 58 | - 知识融合:在获得新知识之后,需要对其进行整合,以消除矛盾和歧义,比如某些实体可能有多种表达,某个特定称谓也许对应于多个不同的实体等; 59 | - 知识加工:对于经过融合的新知识,需要经过质量评估之后(部分需要人工参与甄别),才能将合格的部分加入到知识库中,以确保知识库的质量。 60 | 61 | #### 信息抽取 62 | 63 | 信息抽取(infromation extraction)是知识图谱构建的第1步,其中的关键问题是:如何从异构数据源中自动抽取信息得到候选指示单元? 64 | 65 | 信息抽取是一种自动化地从半结构化和无结构数据中抽取实体、关系以及实体属性等结构化信息的技术。涉及的关键技术包括:**实体抽取、关系抽取和属性抽取。** 66 | 67 | **实体抽取**,也称为**命名实体识别**(named entity recognition,NER),是指从文本数据集中自动识别出命名实体。 68 | 69 | 文本语料经过实体抽取之后,得到的是一系列离散的命名实体,为了得到语义信息,还需要从相关语料中提取出实体之间的关联关系,通过关系将实体联系起来,才能够形成网状的知识结构。这就是**关系抽取**需要做的事。 70 | 71 | **属性抽取**的目标是从不同信息源中采集特定实体的属性信息,如针对某个公众人物,可以从网络公开信息中得到其昵称、生日、国籍、教育背景等信息。 72 | 73 | #### 知识融合 74 | 75 | 通过信息抽取,我们就从原始的非结构化和半结构化数据中获取到了实体、关系以及实体的属性信息。 76 | 77 | 如果我们将接下来的过程比喻成拼图的话,那么这些信息就是拼图碎片,散乱无章,甚至还有从其他拼图里跑来的碎片、本身就是用来干扰我们拼图的错误碎片。 78 | 79 | 也就是说: 80 | 81 | - 拼图碎片(信息)之间的关系是扁平化的,缺乏层次性和逻辑性; 82 | - 拼图(知识)中还存在大量冗杂和错误的拼图碎片(信息) 83 | 84 | 那么如何解决这一问题,就是在知识融合这一步里我们需要做的了。 85 | 86 | 知识融合包括2部分内容: 87 | 88 | - 实体链接 89 | - 知识合并 90 | 91 | **实体链接**(entity linking)是指对于从文本中抽取得到的实体对象,将其链接到知识库中对应的正确实体对象的操作。 92 | 93 | 其基本思想是首先根据给定的**实体指称项**,从知识库中选出一组候选实体对象,然后通过**相似度计算**将指称项链接到正确的实体对象。 94 | 95 | 在前面的实体链接中,我们已经将实体链接到知识库中对应的正确实体对象那里去了,但需要注意的是,实体链接链接的是我们从半结构化数据和非结构化数据那里通过信息抽取提取出来的数据。 96 | 97 | 那么除了半结构化数据和非结构化数据以外,我们还有个更方便的数据来源——**结构化数据**,如外部知识库和关系数据库。 98 | 99 | 对于这部分结构化数据的处理,就是我们**知识合并**的内容啦。 100 | 101 | #### 知识加工 102 | 103 | 在前面,我们已经通过**信息抽取**,从原始语料中提取出了实体、关系与属性等知识要素,并且经过**知识融合**,消除实体指称项与实体对象之间的歧义,得到一系列基本的事实表达。 104 | 105 | **然而事实本身并不等于知识。**要想最终获得结构化,网络化的知识体系,还需要经历**知识加工**的过程。 106 | 107 | 知识加工主要包括3方面内容:**本体构建、知识推理和质量评估**。 108 | 109 | ##### 本体构建 110 | 111 | **本体**(ontology)是指工人的概念集合、概念框架,如“人”、“事”、“物”等。 112 | 113 | 自动化本体构建过程包含三个阶段: 114 | 115 | 1. 实体并列关系相似度计算 116 | 2. 实体上下位关系抽取 117 | 3. 本体的生成 118 | 119 | 比如对下面这个例子,当知识图谱刚得到“阿里巴巴”、“腾讯”、“手机”这三个实体的时候,可能会认为它们三个之间并没有什么差别,但当它去计算三个实体之间的相似度后,就会发现,阿里巴巴和腾讯之间可能更相似,和手机差别更大一些。 120 | 121 | 这就是第一步的作用,但这样下来,知识图谱实际上还是没有一个上下层的概念,它还是不知道,阿里巴巴和手机,根本就不隶属于一个类型,无法比较。因此我们在实体上下位关系抽取这一步,就需要去完成这样的工作,从而生成第三步的本体。 122 | 123 | 当三步结束后,这个知识图谱可能就会明白,“阿里巴巴和腾讯,其实都是公司这样一个实体下的细分实体。它们和手机并不是一类。” 124 | 125 | ##### 知识推理 126 | 127 | 在我们完成了本体构建这一步之后,一个知识图谱的雏形便已经搭建好了。但可能在这个时候,知识图谱之间大多数关系都是残缺的,缺失值非常严重,那么这个时候,我们就可以使用知识推理技术,去完成进一步的知识发现。 128 | 129 | 这一块的算法主要可以分为3大类,基于逻辑的推理、基于图的推理和基于深度学习的推理。 130 | 131 | ##### 质量评估 132 | 133 | 质量评估也是知识库构建技术的重要组成部分,这一部分存在的意义在于:可以对知识的可信度进行量化,通过舍弃置信度较低的知识来**保障知识库的质量**。 134 | 135 | #### 知识更新 136 | 137 | ------ 138 | 139 | 其他资料 140 | 141 | [为什么需要知识图谱?什么是知识图谱?——KG的前世今生]() 142 | 143 | -------------------------------------------------------------------------------- /notes/算法应用步骤.md: -------------------------------------------------------------------------------- 1 | ## 机器学习方法 2 | 3 | **一般有以下几个步骤:** 4 | 5 | - 第一步:识别问题 6 | - 第二步:分离数据 7 | - 第三步:构造提取特征 8 | - 第四步:组合数据 9 | - 第五步:分解 10 | - 第六步:选择特征 11 | - 第七步:选择算法进行训练 12 | 13 | 14 | 15 | #### 识别问题 16 | 17 | 在这一步先明确这个问题是分类还是回归。通过问题和数据就可以判断出来,数据由 X 和 label 列构成,label 可以一列也可以多列,可以是二进制也可以是实数,当它为二进制时,问题属于分类,当它为实数时,问题属于回归。 18 | 19 | 用 Training Data 来训练模型,用 Validation Data 来检验这个模型的表现,不然的话,通过各种调节参数,模型可以在训练数据集上面表现的非常出色,但是这可能会是过拟合,过拟合就是太依赖现有的数据了,拟合的效果特别好,但是只适用于训练集,以致于来一个新的数据,就不知道该预测成什么了。所以需要有 Validation 来验证一下,看这个模型是在那里自娱自乐呢,还是真的表现出色。 20 | 21 | 在 scikit learn 包里就有工具可以帮你做到这些: 22 | 分类问题用 **StrtifiedKFold** 23 | 24 | ``` 25 | from sklearn.cross_validation import StratifiedKFold 26 | ``` 27 | 28 | 回归问题用 **KFold** 29 | 30 | ``` 31 | from sklearn.cross_validation import KFold 32 | ``` 33 | 34 | #### 构造特征 35 | 36 | 这个时候,需要将数据转化成模型需要的形式。数据有三种类型:数字,类别,文字。当数据是类别的形式时,需要将它的每一类提取出来作为单独一列,然后用二进制表示每条记录相应的值。 37 | 38 | 这个过程 sklearn 也可以帮你做到: 39 | 40 | ``` 41 | from sklearn.preprocessing import LabelEncoder 42 | ``` 43 | 44 | 或者 45 | 46 | ``` 47 | from sklearn.preprocessing import OneHotEncoder 48 | ``` 49 | 50 | #### 组合数据 51 | 52 | 处理完 Feature 之后,就将它们组合到一起。 53 | 如果数据是稠密的,就可以用 numpy 的 hstack: 54 | 55 | ``` 56 | import numpy as np 57 | X = np.hstack((x1, x2, ...)) 58 | ``` 59 | 60 | 如果是稀疏的,就用 sparse 的 hstack: 61 | 62 | ``` 63 | from scipy import sparse 64 | X = sparse.hstack((x1, x2, ...)) 65 | ``` 66 | 67 | 组合之后,就可以应用以下算法模型: 68 | 69 | - RandomForestClassifier 70 | - RandomForestRegressor 71 | - ExtraTreesClassifier 72 | - ExtraTreesRegressor 73 | - XGBClassifier 74 | - XGBRegressor 75 | 76 | 但是不能应用线性模型,线性模型之前需要对数据进行正则化而不是上述预处理。 77 | 78 | 这一步是为了进一步优化模型,可以用以下方法: 79 | 80 | 81 | 82 | ![img](../images/1.webp) 83 | 84 | 85 | 86 | **PCA:Principal components analysis,主成分分析**,是一种分析、简化数据集的技术。用于减少数据集的维数,同时保持数据集中的对方差贡献最大的特征。 87 | 88 | ``` 89 | from sklearn.decomposition import PCA 90 | ``` 91 | 92 | 对于文字数据,在转化成稀疏矩阵之后,可以用 SVD 93 | 94 | ``` 95 | from sklearn.decomposition import TruncatedSVD 96 | ``` 97 | 98 | **SVD:Singular Value Decomposition,奇异值分解**,是线性代数中一种重要的矩阵分解,它总能找到标准化正交基后方差最大的维度,因此用它进行降维去噪。 99 | 100 | #### 选择特征 101 | 102 | 当特征个数越多时,分析特征、训练模型所需的时间就越长,容易引起“维度灾难”,模型也会越复杂,推广能力也会下降,所以需要剔除不相关或亢余的特征。 103 | 104 | 常用的算法有完全搜索,启发式搜索,和随机算法。 105 | 106 | 例如,Random Forest: 107 | 108 | ``` 109 | from sklearn.ensemble import RandomForestClassifier 110 | ``` 111 | 112 | 或者 xgboost: 113 | 114 | ``` 115 | import xgboost as xgb 116 | ``` 117 | 118 | 对于稀疏的数据,一个比较有名的方法是 chi-2: 119 | 120 | ``` 121 | from sklearn.feature_selection import SelectKBest 122 | from sklearn.feature_selection import chi2 123 | ``` 124 | 125 | #### 选择算法进行训练 126 | 127 | 选择完最相关的参数之后,接下来就可以应用算法,常用的算法有: 128 | 129 | > **Classification**: 130 | > Random Forest 131 | > GBM 132 | > Logistic Regression 133 | > Naive Bayes 134 | > Support Vector Machines 135 | > k-Nearest Neighbors 136 | 137 | > **Regression** 138 | > Random Forest 139 | > GBM 140 | > Linear Regression 141 | > Ridge 142 | > Lasso 143 | > SVR 144 | 145 | 在[scikit-learn](https://link.jianshu.com/?t=http://scikit-learn.org/stable/supervised_learning.html#supervised-learning)里可以看到分类和回归的可用的算法一览,包括它们的原理和例子代码。 146 | 147 | 但是直接应用算法后,一般精度都不是很理想,这个时候需要调节参数,问题来了,**什么模型需要调节什么参数呢?** 148 | 149 | ![img](../images/2.webp) 150 | 151 | 调参之后,也并不就是大功告成,这个时候还是需要去思考,是什么原因造成精度低的,是哪些数据的深意还没有被挖掘到,这个时候需要用**统计和可视化去再一次探索数据**,之后就再走一遍上面的过程。 152 | 153 | -------------------------------------------------------------------------------- /notes/自然语言处理.md: -------------------------------------------------------------------------------- 1 | ## 自然语言处理 2 | 3 | ### 应用 4 | 5 | - 语音识别系统 6 | - 问答系统 7 | - 机器翻译 8 | - 文本摘要 9 | - 情感分析 10 | - 基于模板的聊天机器人 11 | - 文本分类 12 | - 主题分割 13 | 14 | 高级应用: 15 | 16 | - 为某个主题或图像生成文本 17 | - 类人机器人 18 | - 通用机器翻译系统 19 | - 为人类生成个性化文本并忽略手写错误的高级机器人 20 | 21 | ### 关键点 22 | 23 | 词意理解:中国队大胜美国队;中国队大败美国队。“胜”、“败”一对反义词,却表达同样的意思:中国赢了,美国输了。这需要机器能够自动分析出谁胜谁负 24 | 25 | 自动生成语言:自动生成语言基于语言的自动理解,不理解就无法自动生成 26 | 27 | 机器翻译:现在机器翻译已经很多了,但是还很难达到最佳,比如我们把中文翻译成英文,再翻译成中文,再翻译成英文,来回10轮,发现和最初差别还是非常大的。 28 | 29 | 人机对话:这也是我们想做到的最终目标,这里有一个叫做“图灵测试”的方式,也就是在5分钟之内回答提出问题的30%即通过,能通过则认为有智能了。 30 | 31 | ### 实现方法 32 | 33 | 目前业内主要的实现手段有基于规则的、基于实例的、基于统计的以及基于神经网络的。 34 | 35 | 以**机器翻译**为例,我们分别来了解下: 36 | 37 | #### 基于规则的机器翻译 38 | 39 | 基于规则的,也就是完全从语法句法等出发,按照语言的规则来分析和处理,这在上个世纪经历了很多年的试验宣告失败,因为规则太多太多,而且很多语言都不按套路出牌,想象你追赶你的影子,你跑的快他跑的更快,你永远都追不上它。 40 | 41 | 基于规则的机器翻译,是最古老也是见效最快的一种翻译方式。 42 | 43 | 根据翻译的方式可以分为: 44 | 45 | - 直接基于词的翻译 46 | - 结构转换的翻译 47 | - 中间语的翻译 48 | 49 | 从字面上理解,基于词的翻译就是直接把词进行翻译,但是也不是这么简单,会通过一些词性的变换、专业词汇的变换、位置的调整等一些规则,进行修饰。 50 | 51 | ![img](../images/1.png) 52 | 53 | 可以看到翻译的质量很差,但是基于这种词规则的翻译,基本上可以辅助我们做一些翻译的工作;而且这种翻译也带来了机器翻译的0到1的飞跃。 54 | 55 | 那么基于结构转换 其实就是不仅仅考虑单个词,而是考虑到短语的级别。比如根据端与`do chicken`有可能被翻译成`烹饪鸡`,那么整句话就好多了`我们烹饪鸡好吗`。 56 | 57 | 最后一种就是基于中间语的翻译,比如过去在金本位的年代,各国都有自己的货币。中国使用中国的货币,美国使用美国的货币,那么货币之间怎么等价呢?就可以兑换成黄金来衡量价值,这样就可以进行跨币种的买卖了。翻译也是如此,倘若由两种语言无法直译,那么也可以先翻译成中间语,然后通过中间语进行两种语言的翻译。 58 | 59 | #### 基于统计的机器翻译 60 | 61 | 另一派是基于统计的,也就是收集大量的语料数据,通过统计学习的方式来理解语言,这在当代越来越受重视而且已经成为趋势,因为随着硬件技术的发展,大数据存储和计算已经不是问题,无论有什么样的规则,语言都是有统计规律的,当然基于统计也存在缺陷,那就是“小概率事件总是不会发生的”导致总有一些问题解决不了。 62 | 63 | 首先,我们有一段英文想要把它翻译成汉语: 64 | 65 | ``` 66 | we do chicken right 67 | ``` 68 | 69 | 会根据每个词或者短语,罗列它可能出现的翻译结果: 70 | 71 | ``` 72 | 我们/做/鸡/右 73 | 我们/做/鸡/好吗 74 | 我们/干/鸡/怎么样 75 | ... 76 | ``` 77 | 78 | 这样的结果有很多种... 79 | 80 | 然后我们需要一个大量的语料库,即有大量的文章...这些文章会提供 每一种翻译结果出现的概率,概率的计算方式可能是使用隐马尔可夫模型,即自己算相邻词的概率,这个原理在《数学之美》中有介绍,感兴趣的可以去看看。 81 | 82 | 最终挑选概率最高的翻译结果作为最终的输出。 83 | 84 | 总结来说大致的流程是: 85 | 86 | ![img](../images/2.png) 87 | 88 | 因此可以看到,这种翻译方式依赖大量的语料库,因此大多数使用这种方式而且效果比较好的都是那种搜索引擎公司,比如Google和Baidu。 89 | 90 | #### 基于实例的机器翻译 91 | 92 | 这种翻译也比较常见,通俗点说就是抽取句子的模式,当你输入一句话想要翻译的时候,会搜索相类似的语句,然后替换不一样的词汇翻译。举个例子: 93 | 94 | ``` 95 | I gave zhangsan a pen 96 | I gave lisi an apple 97 | ``` 98 | 99 | 就可以抽取他们相似的部分,直接替换不一样的地方的词汇就行。 100 | 101 | #### 基于神经网络的机器翻译 102 | 103 | 在机器翻译中主要使用的是循环神经网络,即上一次的输出可以作为这次的输入继续参与计算。 104 | 105 | 就是在翻译的过程中,虽然是以句子为单位进行翻译的,但是每一句话都会对下一句话的翻译产生影响,这样就做出了上下文的感觉....比如`do chicken`单纯的翻译有很多中翻译的结果。但是如果前面出现过厨师等这类的词句,那么这个单词就可以更倾向翻译成`烹饪鸡`。 106 | 107 | 108 | 109 | ------ 110 | 111 | 其他: 112 | 113 | [人机问答系统原理]() 114 | 115 | -------------------------------------------------------------------------------- /notes/问答系统.md: -------------------------------------------------------------------------------- 1 | ## 问答系统 2 | 3 | ### 基本流程 4 | 5 | - 判断类型的问题,用于锁定问题的精准范围(可以采用一些分类的机器学习算法) 6 | - 信息提取:提取关键词 7 | - 基于关键词的搜索,可以直接基于TF-IDF算法搜索,也可以基于word2vec转变空间向量使用相似词进行搜索 8 | - 结合问题的主题等信息对候选集的答案进行打分 9 | - 返回得分最高的TopN候选答案 10 | 11 | ### 基于知识图谱 12 | 13 | 基于问答库的做法,已经能实现一个基本的问答系统了。但是他其实并不智能,因为所有的答案都需要事先录入好。没有准备的问题,就无法找到对应的答案....试想一下,人类说话的方式多种多样,稍微变一下,就可能得不到想要的答案,这得是多么烂的系统啊。 14 | 15 | 有了知识图谱之后,我们就可以进行一些智能的搜索了。 16 | 17 | 实现方法: 18 | 19 | #### 基于语义解析 20 | 21 | 基于语法树形成特定的查询语言,直接基于知识库进行查询了,比如转化成`SPARQL`进行查询 22 | 23 | #### 基于信息提取 24 | 25 | 相关问题形成语法的依存树,然后根据依存树再生成问题图。基于问题图,我们很容易能到知识图谱里面查询到相关的实体,然后得到基于这个实体的子图。得到子图后,就可以从这个实体出发,把所有的关系对应的实体都做为回答的候选集。当然不仅仅是一层的关系,也可以收集两层的图作为候选集。有了这样的候选集就剩下寻找最优答案的问题了,寻找答案的方法有很多,比如抽取答案的特征与问题的特征两两组合,基于朴素贝叶斯算法选取概率最大的候选答案。 26 | 27 | #### 基于word embedding 28 | 29 | 说完基于特征的信息提取,就要说说这个word embedding,word embedding是一种概念,即区别于普通的One hot编码。 30 | 31 | word embedding,也叫做词嵌入,常用的方法有word2vec。这种方法是基于大量的语料库去分析词语被表达的向量,中间的过程暂且不谈,最终的效果就是父亲-母亲 = 男-女,也就是说在用夹角余弦计算相似度的时候,同种类型的词语往往相似度都比较高。 32 | 33 | 那么在问答系统中,就是对问题进行特征的提取,然后转变成word embedding的表示方法;再对知识库中的答案提取特征,形成word embedding,最终基于计算两者的关系,来寻找最匹配的答案。这种基于word embedding的表达方式寻找最佳的匹配,也被应用到了推荐系统的场景,因此还是值得好好研究一下的。 34 | 35 | #### 基于深度学习 36 | 37 | 由于word embedding其实也是基于特征词的,因此在提取特征词的时候都会忽略掉位置等等的因素。比如,`谢霆锋的爸爸是谁?`和`谢霆锋是谁的爸爸?`就是两个完全不同的问题。但是在深度学习中,如果使用一些循环神经网络,就可以把每个词作为下一个词分析的输入,也就变相的考虑了词语的顺序特征。具体的就不详谈了,能力有限... 38 | 39 | -------------------------------------------------------------------------------- /工具.md: -------------------------------------------------------------------------------- 1 | ## 工具 2 | 3 | ### SciPy 栈 4 | 5 | SciPy 栈由数据科学所使用的一组核心帮助包组成,用于统计分析和数据可视化。 由于其庞大的功能和易用性,scripy栈被认为是大多数数据科学应用的必备条件。该栈主要包含[NumPy](http://www.numpy.org/),[Matplotlib](http://matplotlib.org/),[pandas](http://pandas.pydata.org/)等包。 6 | 7 | ### scikit-learn 8 | 9 | Scikit是一个用于Python的免费开源机器学习库。 它提供了现成的功能来实现诸如线性回归、 分类器、SVM、k-均值和神经网络等多种算法。它还有一些可直接用于训练和测试的样本数据集。由于其速度、鲁棒性和易用性,它是许多机器学习应用程序中使用最广泛的库之一。这里有一个使用scikit-learn进行机器学习的[demo](),关于scikit-learn的更多内容可以在 [官方文档](http://scikit-learn.org/stable/user_guide.html) 中阅读。 10 | 11 | ### tensorflow 12 | 13 | TensorFlow 是一款用于数值计算的强大的开源软件库,特别适用于大规模机器学习的微调。这里有一个使用tf解决手写识别问题的[demo](<../master/code/tf/mnist.py>),关于tensorflow的更多教程可以在[中文社区]()中阅读。 14 | 15 | ### keras 16 | 17 | Keras是一个高层神经网络API,Keras由纯Python编写而成并基Tensorflow、Theano以及CNTK]后端。Keras 为支持快速实验而生,能够把你的idea迅速转换为结果,如果你有如下需求,请选择Keras: 18 | 19 | - 简易和快速的原型设计(keras具有高度模块化,极简,和可扩充特性) 20 | - 支持CNN和RNN,或二者的结合 21 | - 无缝CPU和GPU切换 --------------------------------------------------------------------------------