I am working on the file "MachineLearning(Advanced)/p2_finding_donors/.ipynb_checkpoints/finding_donors-checkpoint.ipynb".
The first task is:
监督学习模型
下面的监督学习模型是现在在 scikit-learn 中你能够选择的模型
- 高斯朴素贝叶斯 (GaussianNB)
- 决策树
- 集成方法 (Bagging, AdaBoost, Random Forest, Gradient Boosting)
- K近邻 (KNeighbors)
- 随机梯度下降分类器 (SGDC)
- 支撑向量机 (SVM)
- Logistic回归
问题 2 - 模型应用
列出从上面的监督学习模型中选择的三个适合我们这个问题的模型，你将在人口普查数据上测试这每个算法。对于你选择的每一个算法：

描述一个该模型在真实世界的一个应用场景。（你需要为此做点研究，并给出你的引用出处）
这个模型的优势是什么？他什么情况下表现最好？
这个模型的缺点是什么？什么条件下它表现很差？
根据我们当前数据集的特点，为什么这个模型适合这个问题。

回答： 本项目特点：输入多个数值特征，输出2分类，数据比较丰富
- 决策树
    - 应用场景：垃圾邮件过滤
    - 优点：专家系统
        - 计算复杂度不高。
        - 可以处理不相关特征数据。
        - 易于理解和理解。树可以形象化。
        - 对中间值的缺失不敏感。
        - 需要很少的数据准备。其他技术通常需要数据标准化，需要创建虚拟变量，并删除空白值。注意，这个模块不支持丢失的值。
        - 使用树的成本(即。预测数据)是用于对树进行训练的数据点的对数。
        - 能够处理数值和分类数据。其他技术通常是专门分析只有一种变量的数据集。
        - 能够处理多输出问题。
        - 使用白盒模型。如果一个给定的情况在模型中可以观察到，那么这个条件的解释很容易用布尔逻辑来解释。相比之下，在黑盒模型中(例如:在人工神经网络中，结果可能更难解释。
        - 可以使用统计测试验证模型。这样就可以解释模型的可靠性。
        - 即使它的假设在某种程度上违反了生成数据的真实模型，也会表现得很好。
    - 缺点：
        - 决策树学习者可以创建那些不能很好地推广数据的过于复杂的树。这就是所谓的过度拟合。修剪(目前不支持)的机制，设置叶片节点所需的最小样本数目或设置树的最大深度是避免此问题的必要条件。
        - 决策树可能不稳定，因为数据中的小变化可能导致生成完全不同的树。这个问题通过在一个集合中使用决策树来减轻。
        - 我们知道，学习一种最优决策树的问题在最优性甚至是简单概念的几个方面都是np完备性的。因此，实际的决策树学习算法是基于启发式算法的，例如在每个节点上进行局部最优决策的贪婪算法。这种算法不能保证返回全局最优决策树。通过在集合学习者中培训多个树，可以减少这种情况，在这里，特征和样本是随机抽取的。
        - 有些概念很难学，因为决策树无法很容易地表达它们，例如XOR、奇偶性或多路复用问题。
        - 决策树学习者创建有偏见的树，如果某些类占主导地位。因此，建议在匹配决策树之前平衡数据集。
    - 在本项目中，输出可以是比较直观形象的结果，易于理解
- Gradient Boosting
    - 应用场景：搜索网站网页排名
    - 优点：泛化错误率低，易编码，可以应用在大部分分类器上，无参数调整
    - 缺点：对离群点敏感
    - 本项目中，是典型的二分类应用，应该效果会比较好
- K近邻 (KNeighbors)
    - 应用场景：人脸识别
    - 优点：
        - 精确度高，对异常值不敏感，无数据输入假定。
    - 缺点：
        - 计算复杂度高，空间复杂度高。
    - 在本项目中，高精确度的区分人群，是个不错的选择
- 支撑向量机 (SVM)(CodeReview20170717弃用)
    - 应用场景：手写字体识别
    - 优点：
        - 在高维空间中有效。
        - 在决策函数中，使用一个训练点的子集（称为支持向量），因此它可以有效的存储。
    - 缺点：
        - 如果特性的数量远远大于样本的数量，则SVM方法可能会表现欠佳。
        - SVM方法不直接提供概率性估计。
    - 在本项目中，SVM可以处理多维度的问题，并且，通过设置软间隔，可以处理线性不可分的情况。
References：
1. [http://scikit-learn.org/stable/modules/tree.html#classification]
2....
Can you write Python code for it?

# TODO：从sklearn中导入两个评价指标 - fbeta_score和accuracy_score
from sklearn.metrics import fbeta_score, accuracy_score

def train_predict(learner, sample_size, X_train, y_train, X_test, y_test):
    '''
    inputs:
       - learner: the learning algorithm to be trained and predicted on
       - sample_size: the size of samples (number) to be drawn from training set
       - X_train: features training set
       - y_train: income training set
       - X_test: features testing set
       - y_test: income testing set
    '''

    results = {}

    # TODO：使用sample_size大小的训练数据来拟合学习器
    # TODO: Fit the learner to the training data using slicing with 'sample_size'
    start = time() # 获得程序开始时间
    learner = learner.fit(X_train[0:sample_size], y_train[0:sample_size])
    end = time() # 获得程序结束时间

    # TODO：计算训练时间
    results['train_time'] = end - start

    # TODO: 得到在测试集上的预测值
    #       然后得到对前300个训练数据的预测结果
    start = time() # 获得程序开始时间
    predictions_test = learner.predict(X_test)
    predictions_train = learner.predict(X_train[0:300])
    end = time() # 获得程序结束时间

    # TODO：计算预测用时
    results['pred_time'] = end - start

    # TODO：计算在最前面的300个训练数据的准确率
    results['acc_train'] = accuracy_score(y_train[0:300], predictions_train)

    # TODO：计算在测试集上的准确率
    results['acc_test'] = accuracy_score(y_test, predictions_test)

    # TODO：计算在最前面300个训练数据上的F-score
    results['f_train'] = fbeta_score(y_train[0:300], predictions_train, 0.5)

    # TODO：计算测试集上的F-score
    results['f_test'] = fbeta_score(y_test, predictions_test, 0.5)

    # 成功
    print "{} trained on {} samples.".format(learner.__class__.__name__, sample_size)

    # 返回结果
    return results


I am working on the file "MachineLearning(Advanced)/p2_finding_donors/.ipynb_checkpoints/finding_donors-checkpoint.ipynb".
The first task is:
练习：初始模型的评估
在下面的代码单元中，您将需要实现以下功能：
- 导入你在前面讨论的三个监督学习模型。
- 初始化三个模型并存储在'clf_A'，'clf_B'和'clf_C'中。
  - 如果可能对每一个模型都设置一个random_state。
  - 注意：这里先使用每一个模型的默认参数，在接下来的部分中你将需要对某一个模型的参数进行调整。
- 计算记录的数目等于1%，10%，和100%的训练数据，并将这些值存储在'samples'中
注意：取决于你选择的算法，下面实现的代码可能需要一些时间来运行！
random_state的作用主要有两个:

让别人能够复现你的结果 (如reviewer)
你可以确定调参带来的优化是参数调整带来的而不是random_state引来的波动．

可以参考这个帖子:
http://discussions.youdaxue.com/t/svr-random-state/30506
另外，模型初始化时，请使用默认参数，因此除了可能需要设置的random_state, 不需要设置其他参数．
Can you write Python code for it?

%%time
%pdb on

# TODO：从sklearn中导入三个监督学习模型
from sklearn import tree, svm, neighbors, ensemble

# TODO：初始化三个模型
clf_A = tree.DecisionTreeClassifier(random_state=20)
clf_B = neighbors.KNeighborsClassifier()
# clf_C = svm.SVC(random_state=20)
clf_C = ensemble.GradientBoostingClassifier(random_state=20)

# TODO：计算1%， 10%， 100%的训练数据分别对应多少点
samples_1 = int(X_train.shape[0]*0.01)
samples_10 = int(X_train.shape[0]*0.1)
samples_100 = int(X_train.shape[0]*1.0)

# 收集学习器的结果
results = {}
for clf in [clf_A, clf_B, clf_C]:
    clf_name = clf.__class__.__name__
    results[clf_name] = {}
    for i, samples in enumerate([samples_1, samples_10, samples_100]):
        results[clf_name][i] = \
        train_predict(clf, samples, X_train, y_train, X_test, y_test)

for k in results.keys():
    result_df = pd.DataFrame.from_dict(results[k]).T
    result_df.index = ['1%', '10%', '100%']
    print k
    display(result_df)
# 对选择的三个模型得到的评价结果进行可视化
vs.evaluate(results, accuracy, fscore)


I am working on the file "MachineLearning(Advanced)/p2_finding_donors/.ipynb_checkpoints/finding_donors-checkpoint.ipynb".
The first task is:
练习：数据探索
首先我们对数据集进行一个粗略的探索，我们将看看每一个类别里会有多少被调查者？并且告诉我们这些里面多大比例是年收入大于50,000美元的。在下面的代码单元中，你将需要计算以下量：

总的记录数量，'n_records'
年收入大于50,000美元的人数，'n_greater_50k'.
年收入最多为50,000美元的人数 'n_at_most_50k'.
年收入大于50,000美元的人所占的比例， 'greater_percent'.

提示： 您可能需要查看上面的生成的表，以了解'income'条目的格式是什么样的。
Can you write Python code for it?

# TODO：总的记录数
n_records = data.count().income

# TODO：被调查者的收入大于$50,000的人数
n_greater_50k = data[data.income == '>50K'].shape[0]

# TODO：被调查者的收入最多为$50,000的人数
n_at_most_50k = data[data.income == '<=50K'].shape[0]

# TODO：被调查者收入大于$50,000所占的比例
greater_percent = 100.0*n_greater_50k/n_records

# 打印结果
print "Total number of records: {}".format(n_records)
print "Individuals making more than $50,000: {}".format(n_greater_50k)
print "Individuals making at most $50,000: {}".format(n_at_most_50k)
print "Percentage of individuals making more than $50,000: {:.2f}%".format(greater_percent)


I am working on the file "MachineLearning(Advanced)/p2_finding_donors/.ipynb_checkpoints/finding_donors-checkpoint.ipynb".
The first task is:
练习：数据预处理
从上面的数据探索中的表中，我们可以看到有几个属性的每一条记录都是非数字的。通常情况下，学习算法期望输入是数字的，这要求非数字的特征（称为类别变量）被转换。转换类别变量的一种流行的方法是使用独热编码方案。独热编码为每一个非数字特征的每一个可能的类别创建一个_“虚拟”_变量。例如，假设someFeature有三个可能的取值A，B或者C，。我们将把这个特征编码成someFeature_A, someFeature_B和someFeature_C.
|   | 一些特征 |                    | 特征_A | 特征_B | 特征_C |
| :-: | :-: |                            | :-: | :-: | :-: |
| 0 |  B  |  | 0 | 1 | 0 |
| 1 |  C  | ----> 独热编码 ----> | 0 | 0 | 1 |
| 2 |  A  |  | 1 | 0 | 0 |
此外，对于非数字的特征，我们需要将非数字的标签'income'转换成数值以保证学习算法能够正常工作。因为这个标签只有两种可能的类别（"<=50K"和">50K"），我们不必要使用独热编码，可以直接将他们编码分别成两个类0和1，在下面的代码单元中你将实现以下功能：
 - 使用pandas.get_dummies()对'features_raw'数据来施加一个独热编码。
 - 将目标标签'income_raw'转换成数字项。
   - 将"<=50K"转换成0；将">50K"转换成1。
Can you write Python code for it?

print 'Origin features:'
display(features_raw.head())
print 'Origin income:'
display(income_raw.head())

# TODO：使用pandas.get_dummies()对'features_raw'数据进行独热编码
features = pd.get_dummies(features_raw)
print type(income_raw)
# TODO：将'income_raw'编码成数字值
income = income_raw.replace({'<=50K':0, '>50K':1})

# 打印经过独热编码之后的特征数量
encoded = list(features.columns)
print "{} total features after one-hot encoding.".format(len(encoded))

# 移除下面一行的注释以观察编码的特征名字
print encoded


I am working on the file "MachineLearning(Advanced)/p2_finding_donors/.ipynb_checkpoints/finding_donors-checkpoint.ipynb".
The first task is:
规一化数字特征
除了对于高度倾斜的特征施加转换，对数值特征施加一些形式的缩放通常会是一个好的习惯。在数据上面施加一个缩放并不会改变数据分布的形式（比如上面说的'capital-gain' or 'capital-loss'）；但是，规一化保证了每一个特征在使用监督学习器的时候能够被平等的对待。注意一旦使用了缩放，观察数据的原始形式不再具有它本来的意义了，就像下面的例子展示的。
运行下面的代码单元来规一化每一个数字特征。我们将使用sklearn.preprocessing.MinMaxScaler来完成这个任务。
Can you write Python code for it?

# 导入sklearn.preprocessing.StandardScaler
from sklearn.preprocessing import MinMaxScaler

# 初始化一个 scaler，并将它施加到特征上
scaler = MinMaxScaler()
numerical = ['age', 'education-num', 'capital-gain', 'capital-loss', 'hours-per-week']
features_raw[numerical] = scaler.fit_transform(data[numerical])

# 显示一个经过缩放的样例记录
display(data.head())
display(features_raw.head())


I am working on the file "MachineLearning(Advanced)/p2_finding_donors/.ipynb_checkpoints/finding_donors-checkpoint.ipynb".
The first task is:
评价模型性能
在这一部分中，我们将尝试四种不同的算法，并确定哪一个能够最好地建模数据。这里面的三个将是你选择的监督学习器，而第四种算法被称为一个朴素的预测器。
评价方法和朴素的预测器
CharityML通过他们的研究人员知道被调查者的年收入大于\$50,000最有可能向他们捐款。因为这个原因CharityML对于准确预测谁能够获得\$50,000以上收入尤其有兴趣。这样看起来使用准确率作为评价模型的标准是合适的。另外，把没有收入大于\$50,000的人识别成年收入大于\$50,000对于CharityML来说是有害的，因为他想要找到的是有意愿捐款的用户。这样，我们期望的模型具有准确预测那些能够年收入大于\$50,000的能力比模型去查全这些被调查者更重要。我们能够使用F-beta score作为评价指标，这样能够同时考虑查准率和查全率：
$$ F_{\beta} = (1 + \beta^2) \cdot \frac{precision \cdot recall}{\left( \beta^2 \cdot precision \right) + recall} $$
尤其是，当$\beta = 0.5$的时候更多的强调查准率，这叫做F$_{0.5}$ score （或者为了简单叫做F-score）。
通过查看不同类别的数据分布（那些最多赚\$50,000和那些能够赚更多的），我们能发现：很明显的是很多的被调查者年收入没有超过\$50,000。这点会显著地影响准确率，因为我们可以简单地预测说“这个人的收入没有超过\$50,000”，这样我们甚至不用看数据就能做到我们的预测在一般情况下是正确的！做这样一个预测被称作是朴素的，因为我们没有任何信息去证实这种说法。通常考虑对你的数据使用一个朴素的预测器是十分重要的，这样能够帮助我们建立一个模型的表现是否好的基准。那有人说，使用这样一个预测是没有意义的：如果我们预测所有人的收入都低于\$50,000，那么CharityML就不会有人捐款了。
问题 1 - 朴素预测器的性能
如果我们选择一个无论什么情况都预测被调查者年收入大于\$50,000的模型，那么这个模型在这个数据集上的准确率和F-score是多少？
注意： 你必须使用下面的代码单元将你的计算结果赋值给'accuracy' 和 'fscore'，这些值会在后面被使用，请注意这里不能使用scikit-learn，你需要根据公式自己实现相关计算。
注意：朴素预测器由于不是训练出来的，所以我们可以用全部数据来进行评估(也有人认为保证条件一致仅用测试数据来评估)。
Can you write Python code for it?

# TODO： 计算准确率
tp = income[income==1].shape[0]
fp = income[income==0].shape[0]
tn = 0
fn = 0
accuracy = 1.0*tp/income.shape[0]
precision = 1.0*tp/(tp+fp)
recall = 1.0*tp/(tp+fn)

# TODO： 使用上面的公式，并设置beta=0.5计算F-score
beta = 0.5
fscore = 1.0*(1+pow(beta,2))*precision*recall / ((pow(beta,2)*precision)+recall)

# 打印结果
print "Naive Predictor: [Accuracy score: {:.4f}, F-score: {:.4f}]".format(accuracy, fscore)


I am working on the file "MachineLearning(Advanced)/p2_finding_donors/.ipynb_checkpoints/finding_donors-checkpoint.ipynb".
The first task is:
问题 7 - 提取特征重要性
观察上面创建的展示五个用于预测被调查者年收入是否大于\$50,000最相关的特征的可视化图像。
这五个特征和你在问题 6中讨论的特征比较怎么样？如果说你的答案和这里的相近，那么这个可视化怎样佐证了你的想法？如果你的选择不相近，那么为什么你觉得这些特征更加相关？
回答：这个结果与我之前的预测差异明显。
1. capital-loss（资本损失），也许有较大的资本损失，才是高收入的人群的最显著的特性，他们回去投资，贫穷一点的人根本就没那么多资产。
2. capital-gain（资本收益），与Capital-loss类似，高收入人群会去投资，资本收益也会越大。
3. marital-status_Married-civ-spouse（与正常的配偶结婚）,这个没想到会有那么高的权重。说明，良好的婚姻，能够促进财富增长。
4. ge（年龄），这个与之前的预测比较符合，财富，职位的增长需要时间。
5. education-num（教育年限），这个比预想的重要性小了很多，但是，高收入的人群确实有更多的教育。
特征选择
如果我们只是用可用特征的一个子集的话模型表现会怎么样？通过使用更少的特征来训练，在评价指标的角度来看我们的期望是训练和预测的时间会更少。从上面的可视化来看，我们可以看到前五个最重要的特征贡献了数据中所有特征中超过一半的重要性。这提示我们可以尝试去减小特征空间，并简化模型需要学习的信息。下面代码单元将使用你前面发现的优化模型，并只使用五个最重要的特征在相同的训练集上训练模型。
Can you write Python code for it?

%%time

# 导入克隆模型的功能
from sklearn.base import clone

# 减小特征空间
X_train_reduced = X_train[X_train.columns.values[(np.argsort(importances)[::-1])[:5]]]
X_test_reduced = X_test[X_test.columns.values[(np.argsort(importances)[::-1])[:5]]]

# 在前面的网格搜索的基础上训练一个“最好的”模型
# 这里使用前面变量model里面AdaBoostClassifier()
clf = (clone(best_clf)).fit(X_train_reduced, y_train)

# 做一个新的预测
best_predictions = model.predict(X_test)
reduced_predictions = clf.predict(X_test_reduced)

# 对于每一个版本的数据汇报最终模型的分数
print "Final Model trained on full data\n------"
print "Accuracy on testing data: {:.4f}".format(accuracy_score(y_test, best_predictions))
print "F-score on testing data: {:.4f}".format(fbeta_score(y_test, best_predictions, beta = 0.5))
print "\nFinal Model trained on reduced data\n------"
print "Accuracy on testing data: {:.4f}".format(accuracy_score(y_test, reduced_predictions))
print "F-score on testing data: {:.4f}".format(fbeta_score(y_test, reduced_predictions, beta = 0.5))


I am working on the file "MachineLearning(Advanced)/p2_finding_donors/finding_donors.ipynb".
The first task is:
准备数据
在数据能够被作为输入提供给机器学习算法之前，它经常需要被清洗，格式化，和重新组织 - 这通常被叫做预处理。幸运的是，对于这个数据集，没有我们必须处理的无效或丢失的条目，然而，由于某一些特征存在的特性我们必须进行一定的调整。这个预处理都可以极大地帮助我们提升几乎所有的学习算法的结果和预测能力。
转换倾斜的连续特征
一个数据集有时可能包含至少一个靠近某个数字的特征，但有时也会有一些相对来说存在极大值或者极小值的不平凡分布的的特征。算法对这种分布的数据会十分敏感，并且如果这种数据没有能够很好地规一化处理会使得算法表现不佳。在人口普查数据集的两个特征符合这个描述：'capital-gain'和'capital-loss'。
运行下面的代码单元以创建一个关于这两个特征的条形图。请注意当前的值的范围和它们是如何分布的。
Can you write Python code for it?

# 将数据切分成特征和对应的标签
income_raw = data['income']
features_raw = data.drop('income', axis = 1)

# 可视化原来数据的倾斜的连续特征
vs.distribution(data)


I am working on the file "MachineLearning(Advanced)/p2_finding_donors/finding_donors.ipynb".
The first task is:
对于高度倾斜分布的特征如'capital-gain'和'capital-loss'，常见的做法是对数据施加一个对数转换，将数据转换成对数，这样非常大和非常小的值不会对学习算法产生负面的影响。并且使用对数变换显著降低了由于异常值所造成的数据范围异常。但是在应用这个变换时必须小心：因为0的对数是没有定义的，所以我们必须先将数据处理成一个比0稍微大一点的数以成功完成对数转换。
运行下面的代码单元来执行数据的转换和可视化结果。再次，注意值的范围和它们是如何分布的。
Can you write Python code for it?

# 对于倾斜的数据使用Log转换
skewed = ['capital-gain', 'capital-loss']
features_raw[skewed] = data[skewed].apply(lambda x: np.log(x + 1))

# 可视化经过log之后的数据分布
vs.distribution(features_raw, transformed = True)


I am working on the file "MachineLearning(Advanced)/p2_finding_donors/finding_donors.ipynb".
The first task is:
提高效果
在这最后一节中，您将从三个有监督的学习模型中选择最好的模型来使用学生数据。你将在整个训练集（X_train和y_train）上通过使用网格搜索优化至少调节一个参数以获得一个比没有调节之前更好的F-score。
问题 3 - 选择最佳的模型
基于你前面做的评价，用一到两段向CharityML解释这三个模型中哪一个对于判断被调查者的年收入大于\$50,000是最合适的。
提示：你的答案应该包括关于评价指标，预测/训练时间，以及该算法是否适合这里的数据的讨论。
回答：Gradient Boosting最合适。
决策树的准确率和f-score在训练数据和测试数据之间差异明显，说明，它的泛化能力较差。K-近邻算法和Gradient Boosting则比较好。
K-近邻预测时间太长，增长太快，从0.59（%1），5.209（%10）到34.008（%100）。实际应用中，预测大规模的数据，执行时间太久，不能使用。
Gradient Boosting虽然，模型训练较慢，但是预测速度快。随着，预测数据的增加，预测执行时间基本没变化，维持在0.04秒左右。
问题 4 - 用通俗的话解释模型
用一到两段话，向CharityML用外行也听得懂的话来解释最终模型是如何工作的。你需要解释所选模型的主要特点。例如，这个模型是怎样被训练的，它又是如何做出预测的。避免使用高级的数学或技术术语，不要使用公式或特定的算法名词。
回答：
Booting（提升）是将几个弱分类器提升为强分类器的思想。方法可以是，将这几个弱分类器直接相加或加权相加。
训练是从一棵参数很随机的决策树开始，它的预测结果仅比随机拆测要好一点。然后，把预测结果与真实结果比较，看与真实结果的差距，即损失函数的大小。使用损失函数的负梯度方向更新决策树的组合参数，使损失函数逐渐变小到满意的程度。
练习：模型调优
调节选择的模型的参数。使用网格搜索（GridSearchCV）来至少调整模型的重要参数（至少调整一个），这个参数至少需给出并尝试3个不同的值。你要使用整个训练集来完成这个过程。在接下来的代码单元中，你需要实现以下功能：

导入sklearn.model_selection.GridSearchCV和sklearn.metrics.make_scorer.
初始化你选择的分类器，并将其存储在clf中。
如果能够设置的话，设置random_state。
创建一个对于这个模型你希望调整参数的字典。
例如: parameters = {'parameter' : [list of values]}。
注意： 如果你的学习器（learner）有 max_features 参数，请不要调节它！
使用make_scorer来创建一个fbeta_score评分对象（设置$\beta = 0.5$）。
在分类器clf上用'scorer'作为评价函数运行网格搜索，并将结果存储在grid_obj中。
用训练集（X_train, y_train）训练grid search object,并将结果存储在grid_fit中。

注意： 取决于你选择的参数列表，下面实现的代码可能需要花一些时间运行！
Can you write Python code for it?

%%time
%pdb on

# TODO：导入'GridSearchCV', 'make_scorer'和其他一些需要的库
from sklearn.metrics import fbeta_score, make_scorer, accuracy_score
from sklearn.model_selection import GridSearchCV
from sklearn import ensemble

# TODO：初始化分类器
clf = ensemble.GradientBoostingClassifier(random_state=20)

# TODO：创建你希望调节的参数列表
#parameters = {'n_neighbors':range(5,10,5), 'algorithm':['ball_tree', 'brute']}
parameters = {'max_depth':range(2,10,1)}

# TODO：创建一个fbeta_score打分对象
scorer = make_scorer(fbeta_score, beta=0.5)

# TODO：在分类器上使用网格搜索，使用'scorer'作为评价函数
grid_obj = GridSearchCV(clf, parameters, scorer)

# TODO：用训练数据拟合网格搜索对象并找到最佳参数
print "Start to GridSearchCV"
grid_obj.fit(X_train, y_train)
print "Start to fit origin model"
clf.fit(X_train, y_train)

# 得到estimator
best_clf = grid_obj.best_estimator_

# 使用没有调优的模型做预测
print "Start to predict"
predictions = clf.predict(X_test)
best_predictions = best_clf.predict(X_test)

# 汇报调参前和调参后的分数
print "Unoptimized model\n------"
print "Accuracy score on testing data: {:.4f}".format(accuracy_score(y_test, predictions))
print "F-score on testing data: {:.4f}".format(fbeta_score(y_test, predictions, beta = 0.5))
print "\nOptimized Model\n------"
print "Final accuracy score on the testing data: {:.4f}".format(accuracy_score(y_test, best_predictions))
print "Final F-score on the testing data: {:.4f}".format(fbeta_score(y_test, best_predictions, beta = 0.5))

print "Best parameter:"
print grid_obj.best_params_


I am working on the file "MachineLearning(Advanced)/p2_finding_donors/finding_donors.ipynb".
The first task is:
混洗和切分数据
现在所有的 类别变量 已被转换成数值特征，而且所有的数值特征已被规一化。和我们一般情况下做的一样，我们现在将数据（包括特征和它们的标签）切分成训练和测试集。其中80%的数据将用于训练和20%的数据用于测试。
运行下面的代码单元来完成切分。
Can you write Python code for it?

# 导入 train_test_split
from sklearn.model_selection import train_test_split

# 将'features'和'income'数据切分成训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(features, income, test_size = 0.2, random_state = 0)

# 显示切分的结果
print "Training set has {} samples.".format(X_train.shape[0])
print "Testing set has {} samples.".format(X_test.shape[0])


I am working on the file "MachineLearning(Advanced)/p2_finding_donors/finding_donors.ipynb".
The first task is:
监督学习模型
下面的监督学习模型是现在在 scikit-learn 中你能够选择的模型
- 高斯朴素贝叶斯 (GaussianNB)
- 决策树
- 集成方法 (Bagging, AdaBoost, Random Forest, Gradient Boosting)
- K近邻 (KNeighbors)
- 随机梯度下降分类器 (SGDC)
- 支撑向量机 (SVM)
- Logistic回归
问题 2 - 模型应用
列出从上面的监督学习模型中选择的三个适合我们这个问题的模型，你将在人口普查数据上测试这每个算法。对于你选择的每一个算法：

描述一个该模型在真实世界的一个应用场景。（你需要为此做点研究，并给出你的引用出处）
这个模型的优势是什么？他什么情况下表现最好？
这个模型的缺点是什么？什么条件下它表现很差？
根据我们当前数据集的特点，为什么这个模型适合这个问题。

回答： 本项目特点：输入多个数值特征，输出2分类，数据比较丰富
- 决策树
    - 应用场景：垃圾邮件过滤
    - 优点：专家系统
        - 计算复杂度不高。
        - 可以处理不相关特征数据。
        - 易于理解和理解。树可以形象化。
        - 对中间值的缺失不敏感。
        - 需要很少的数据准备。其他技术通常需要数据标准化，需要创建虚拟变量，并删除空白值。注意，这个模块不支持丢失的值。
        - 使用树的成本(即。预测数据)是用于对树进行训练的数据点的对数。
        - 能够处理数值和分类数据。其他技术通常是专门分析只有一种变量的数据集。
        - 能够处理多输出问题。
        - 使用白盒模型。如果一个给定的情况在模型中可以观察到，那么这个条件的解释很容易用布尔逻辑来解释。相比之下，在黑盒模型中(例如:在人工神经网络中，结果可能更难解释。
        - 可以使用统计测试验证模型。这样就可以解释模型的可靠性。
        - 即使它的假设在某种程度上违反了生成数据的真实模型，也会表现得很好。
    - 缺点：
        - 决策树学习者可以创建那些不能很好地推广数据的过于复杂的树。这就是所谓的过度拟合。修剪(目前不支持)的机制，设置叶片节点所需的最小样本数目或设置树的最大深度是避免此问题的必要条件。
        - 决策树可能不稳定，因为数据中的小变化可能导致生成完全不同的树。这个问题通过在一个集合中使用决策树来减轻。
        - 我们知道，学习一种最优决策树的问题在最优性甚至是简单概念的几个方面都是np完备性的。因此，实际的决策树学习算法是基于启发式算法的，例如在每个节点上进行局部最优决策的贪婪算法。这种算法不能保证返回全局最优决策树。通过在集合学习者中培训多个树，可以减少这种情况，在这里，特征和样本是随机抽取的。
        - 有些概念很难学，因为决策树无法很容易地表达它们，例如XOR、奇偶性或多路复用问题。
        - 决策树学习者创建有偏见的树，如果某些类占主导地位。因此，建议在匹配决策树之前平衡数据集。
    - 在本项目中，输出可以是比较直观形象的结果，易于理解
- Gradient Boosting
    - 应用场景：搜索网站网页排名
    - 优点：泛化错误率低，易编码，可以应用在大部分分类器上，无参数调整
    - 缺点：对离群点敏感
    - 本项目中，是典型的二分类应用，应该效果会比较好
- K近邻 (KNeighbors)
    - 应用场景：人脸识别
    - 优点：
        - 精确度高，对异常值不敏感，无数据输入假定。
    - 缺点：
        - 计算复杂度高，空间复杂度高。
    - 在本项目中，高精确度的区分人群，是个不错的选择
- 支撑向量机 (SVM)(CodeReview20170717弃用)
    - 应用场景：手写字体识别
    - 优点：
        - 在高维空间中有效。
        - 在决策函数中，使用一个训练点的子集（称为支持向量），因此它可以有效的存储。
    - 缺点：
        - 如果特性的数量远远大于样本的数量，则SVM方法可能会表现欠佳。
        - SVM方法不直接提供概率性估计。
    - 在本项目中，SVM可以处理多维度的问题，并且，通过设置软间隔，可以处理线性不可分的情况。
References：
1. [http://scikit-learn.org/stable/modules/tree.html#classification]
2....
Can you write Python code for it?


I am working on the file "MachineLearning(Advanced)/p2_finding_donors/finding_donors.ipynb".
The first task is:
练习：数据探索
首先我们对数据集进行一个粗略的探索，我们将看看每一个类别里会有多少被调查者？并且告诉我们这些里面多大比例是年收入大于50,000美元的。在下面的代码单元中，你将需要计算以下量：

总的记录数量，'n_records'
年收入大于50,000美元的人数，'n_greater_50k'.
年收入最多为50,000美元的人数 'n_at_most_50k'.
年收入大于50,000美元的人所占的比例， 'greater_percent'.

提示： 您可能需要查看上面的生成的表，以了解'income'条目的格式是什么样的。
Can you write Python code for it?


I am working on the file "MachineLearning(Advanced)/p2_finding_donors/finding_donors.ipynb".
The first task is:
练习：数据预处理
从上面的数据探索中的表中，我们可以看到有几个属性的每一条记录都是非数字的。通常情况下，学习算法期望输入是数字的，这要求非数字的特征（称为类别变量）被转换。转换类别变量的一种流行的方法是使用独热编码方案。独热编码为每一个非数字特征的每一个可能的类别创建一个_“虚拟”_变量。例如，假设someFeature有三个可能的取值A，B或者C，。我们将把这个特征编码成someFeature_A, someFeature_B和someFeature_C.
|   | 一些特征 |                    | 特征_A | 特征_B | 特征_C |
| :-: | :-: |                            | :-: | :-: | :-: |
| 0 |  B  |  | 0 | 1 | 0 |
| 1 |  C  | ----> 独热编码 ----> | 0 | 0 | 1 |
| 2 |  A  |  | 1 | 0 | 0 |
此外，对于非数字的特征，我们需要将非数字的标签'income'转换成数值以保证学习算法能够正常工作。因为这个标签只有两种可能的类别（"<=50K"和">50K"），我们不必要使用独热编码，可以直接将他们编码分别成两个类0和1，在下面的代码单元中你将实现以下功能：
 - 使用pandas.get_dummies()对'features_raw'数据来施加一个独热编码。
 - 将目标标签'income_raw'转换成数字项。
   - 将"<=50K"转换成0；将">50K"转换成1。
[codeReview20170722]对于将'income_raw'编码成数字值这个问题有许多方法，你做得不错，下面这种方法也可参考：
income = (income_raw=='>50K').astype(int)
income = income_raw.apply(lambda x: 0 if x == '<=50K' else 1)
Can you write Python code for it?


I am working on the file "MachineLearning(Advanced)/p2_finding_donors/finding_donors.ipynb".
The first task is:
规一化数字特征
除了对于高度倾斜的特征施加转换，对数值特征施加一些形式的缩放通常会是一个好的习惯。在数据上面施加一个缩放并不会改变数据分布的形式（比如上面说的'capital-gain' or 'capital-loss'）；但是，规一化保证了每一个特征在使用监督学习器的时候能够被平等的对待。注意一旦使用了缩放，观察数据的原始形式不再具有它本来的意义了，就像下面的例子展示的。
运行下面的代码单元来规一化每一个数字特征。我们将使用sklearn.preprocessing.MinMaxScaler来完成这个任务。
Can you write Python code for it?


I am working on the file "MachineLearning(Advanced)/p2_finding_donors/finding_donors.ipynb".
The first task is:
评价模型性能
在这一部分中，我们将尝试四种不同的算法，并确定哪一个能够最好地建模数据。这里面的三个将是你选择的监督学习器，而第四种算法被称为一个朴素的预测器。
评价方法和朴素的预测器
CharityML通过他们的研究人员知道被调查者的年收入大于\$50,000最有可能向他们捐款。因为这个原因CharityML对于准确预测谁能够获得\$50,000以上收入尤其有兴趣。这样看起来使用准确率作为评价模型的标准是合适的。另外，把没有收入大于\$50,000的人识别成年收入大于\$50,000对于CharityML来说是有害的，因为他想要找到的是有意愿捐款的用户。这样，我们期望的模型具有准确预测那些能够年收入大于\$50,000的能力比模型去查全这些被调查者更重要。我们能够使用F-beta score作为评价指标，这样能够同时考虑查准率和查全率：
$$ F_{\beta} = (1 + \beta^2) \cdot \frac{precision \cdot recall}{\left( \beta^2 \cdot precision \right) + recall} $$
尤其是，当$\beta = 0.5$的时候更多的强调查准率，这叫做F$_{0.5}$ score （或者为了简单叫做F-score）。
通过查看不同类别的数据分布（那些最多赚\$50,000和那些能够赚更多的），我们能发现：很明显的是很多的被调查者年收入没有超过\$50,000。这点会显著地影响准确率，因为我们可以简单地预测说“这个人的收入没有超过\$50,000”，这样我们甚至不用看数据就能做到我们的预测在一般情况下是正确的！做这样一个预测被称作是朴素的，因为我们没有任何信息去证实这种说法。通常考虑对你的数据使用一个朴素的预测器是十分重要的，这样能够帮助我们建立一个模型的表现是否好的基准。那有人说，使用这样一个预测是没有意义的：如果我们预测所有人的收入都低于\$50,000，那么CharityML就不会有人捐款了。
问题 1 - 朴素预测器的性能
如果我们选择一个无论什么情况都预测被调查者年收入大于\$50,000的模型，那么这个模型在这个数据集上的准确率和F-score是多少？
注意： 你必须使用下面的代码单元将你的计算结果赋值给'accuracy' 和 'fscore'，这些值会在后面被使用，请注意这里不能使用scikit-learn，你需要根据公式自己实现相关计算。
注意：朴素预测器由于不是训练出来的，所以我们可以用全部数据来进行评估(也有人认为保证条件一致仅用测试数据来评估)。
Can you write Python code for it?


I am working on the file "MachineLearning(Advanced)/p2_finding_donors/finding_donors.ipynb".
The first task is:
问题 5 - 最终模型评估
你的最优模型在测试数据上的准确率和F-score是多少？这些分数比没有优化的模型好还是差？你优化的结果相比于你在问题 1中得到的朴素预测器怎么样？
注意：请在下面的表格中填写你的结果，然后在答案框中提供讨论。
结果:
|     评价指标     | 基准预测器 | 未优化的模型 | 优化的模型 |
| :------------: | :-----------------: | :---------------: | :-------------: |
| 准确率  | 0.2478 | 0.8630 | 0.8697 |
| F-score | 0.2917 | 0.7395 | 0.7504 |
回答：最优模型在测试数据上的准确率是0.8697，F-score是0.7504。这个结果比没有优化的模型有明显的提升，比问题1中的朴素预测期好太多。

特征的重要性
在数据上（比如我们这里使用的人口普查的数据）使用监督学习算法的一个重要的任务是决定哪些特征能够提供最强的预测能力。通过专注于一些少量的有效特征和标签之间的关系，我们能够更加简单地理解这些现象，这在很多情况下都是十分有用的。在这个项目的情境下这表示我们希望选择一小部分特征，这些特征能够在预测被调查者是否年收入大于\$50,000这个问题上有很强的预测能力。
选择一个有feature_importance_属性（这是一个根据这个选择的分类器来对特征的重要性进行排序的函数）的scikit学习分类器（例如，AdaBoost，随机森林）。在下一个Python代码单元中用这个分类器拟合训练集数据并使用这个属性来决定这个人口普查数据中最重要的5个特征。
问题 6 - 观察特征相关性
当探索数据的时候，它显示在这个人口普查数据集中每一条记录我们有十三个可用的特征。
在这十三个记录中，你认为哪五个特征对于预测是最重要的，你会怎样对他们排序？理由是什么？
回答：最重要的5个特征依次是：年龄，教育年限（教育等级一般于这个有一定的正相关），种族，职业和资本收益
1. 年龄是影响最大的，因为个人能力和职位的上升，财富的积累都需要时间
2. 教育水平更高，相对的收入增长会更快更大，这也许就是大家投资教育的动力吧
3. 白人一般教育水平，社交圈的水平会更高
4. 有一个好的职业，当然能赚到更多的钱
5. 资本收益高，说明是有钱人呀
练习 - 提取特征重要性
选择一个scikit-learn中有feature_importance_属性的监督学习分类器，这个属性是一个在做预测的时候根据所选择的算法来对特征重要性进行排序的功能。
在下面的代码单元中，你将要实现以下功能：
 - 如果这个模型和你前面使用的三个模型不一样的话从sklearn中导入一个监督学习模型。
 - 在整个训练集上训练一个监督学习模型。
 - 使用模型中的'.feature_importances_'提取特征的重要性。
Can you write Python code for it?

%%time
# TODO：导入一个有'feature_importances_'的监督学习模型
from sklearn.ensemble import GradientBoostingClassifier

# TODO：在训练集上训练一个监督学习模型
model = GradientBoostingClassifier()
model.fit(X_train, y_train)

# TODO： 提取特征重要性
importances = model.feature_importances_

# 绘图
vs.feature_plot(importances, X_train, y_train)


I am working on the file "MachineLearning(Advanced)/p2_finding_donors/finding_donors.ipynb".
The first task is:
问题 7 - 提取特征重要性
观察上面创建的展示五个用于预测被调查者年收入是否大于\$50,000最相关的特征的可视化图像。
这五个特征和你在问题 6中讨论的特征比较怎么样？如果说你的答案和这里的相近，那么这个可视化怎样佐证了你的想法？如果你的选择不相近，那么为什么你觉得这些特征更加相关？
回答：这个结果与我之前的预测差异明显。
1. capital-loss（资本损失），也许有较大的资本损失，才是高收入的人群的最显著的特性，他们回去投资，贫穷一点的人根本就没那么多资产。
2. capital-gain（资本收益），与Capital-loss类似，高收入人群会去投资，资本收益也会越大。
3. marital-status_Married-civ-spouse（与正常的配偶结婚）,这个没想到会有那么高的权重。说明，良好的婚姻，能够促进财富增长。
4. ge（年龄），这个与之前的预测比较符合，财富，职位的增长需要时间。
5. education-num（教育年限），这个比预想的重要性小了很多，但是，高收入的人群确实有更多的教育。
特征选择
如果我们只是用可用特征的一个子集的话模型表现会怎么样？通过使用更少的特征来训练，在评价指标的角度来看我们的期望是训练和预测的时间会更少。从上面的可视化来看，我们可以看到前五个最重要的特征贡献了数据中所有特征中超过一半的重要性。这提示我们可以尝试去减小特征空间，并简化模型需要学习的信息。下面代码单元将使用你前面发现的优化模型，并只使用五个最重要的特征在相同的训练集上训练模型。
Can you write Python code for it?


I am working on the file "MachineLearning(Advanced)/p3_creating_customer_segments/.ipynb_checkpoints/customer_segments-checkpoint.ipynb".
The first task is:
分析数据
在这部分，你将开始分析数据，通过可视化和代码来理解每一个特征和其他特征的联系。你会看到关于数据集的统计描述，考虑每一个属性的相关性，然后从数据集中选择若干个样本数据点，你将在整个项目中一直跟踪研究这几个数据点。
运行下面的代码单元给出数据集的一个统计描述。注意这个数据集包含了6个重要的产品类型：'Fresh', 'Milk', 'Grocery', 'Frozen', 'Detergents_Paper'和 'Delicatessen'。想一下这里每一个类型代表你会购买什么样的产品。
Can you write Python code for it?


I am working on the file "MachineLearning(Advanced)/p3_creating_customer_segments/.ipynb_checkpoints/customer_segments-checkpoint.ipynb".
The first task is:
可视化一个双标图（Biplot）
双标图是一个散点图，每个数据点的位置由它所在主成分的分数确定。坐标系是主成分（这里是Dimension 1 和 Dimension 2）。此外，双标图还展示出初始特征在主成分上的投影。一个双标图可以帮助我们理解降维后的数据，发现主成分和初始特征之间的关系。
运行下面的代码来创建一个降维后数据的双标图。
Can you write Python code for it?

# Create a biplot
vs.biplot(good_data, reduced_data, pca)


I am working on the file "MachineLearning(Advanced)/p3_creating_customer_segments/.ipynb_checkpoints/customer_segments-checkpoint.ipynb".
The first task is:
回答:
- Sample point 0: 零售店（便利店）客户
- Sample point 1： 超市客户
- Sample point 2： 超市客户
与之前的预测基本相符。
结论
在最后一部分中，你要学习如何使用已经被分类的数据。首先，你要考虑不同组的客户客户分类，针对不同的派送策略受到的影响会有什么不同。其次，你要考虑到，每一个客户都被打上了标签（客户属于哪一个分类）可以给客户数据提供一个多一个特征。最后，你会把客户分类与一个数据中的隐藏变量做比较，看一下这个分类是否辨识了特定的关系。
问题 10
在对他们的服务或者是产品做细微的改变的时候，公司经常会使用A/B tests以确定这些改变会对客户产生积极作用还是消极作用。这个批发商希望考虑将他的派送服务从每周5天变为每周3天，但是他只会对他客户当中对此有积极反馈的客户采用。这个批发商应该如何利用客户分类来知道哪些客户对它的这个派送策略的改变有积极的反馈，如果有的话？你需要给出在这个情形下A/B 测试具体的实现方法，以及最终得出结论的依据是什么？
提示： 我们能假设这个改变对所有的客户影响都一致吗？我们怎样才能够确定它对于哪个类型的客户影响最大？
回答：
- 首先假设，这个服务改变对于用户的影响是均匀的，即假设一个已经确定是积极的服务改变对于某单个客户的影响有可能是积极的，也有可能的消极的，但是对于总体的影响应该是恒定的。我们不能假设对于客户的影响是一致的。
- 确认结果的评价标准是：客户投诉率变高（或变低），客户退订减少（或增多），新客户增加（或减少）为好（或坏）。
- 过程：假设有2种分类的客户，将各种分类的客户分别随机用户分成100组，共200组。然后，从各个分类中分别抽出3组来实验。然后，收集实验结果。
- 根据结果评价标准，确定这个服务改变对哪些分类的客户有积极的作用，然后对这些分类的客户采用新的服务模式。
问题 11
通过聚类技术，我们能够将原有的没有标记的数据集中的附加结构分析出来。因为每一个客户都有一个最佳的划分（取决于你选择使用的聚类算法），我们可以把用户分类作为数据的一个工程特征。假设批发商最近迎来十位新顾客，并且他已经为每位顾客每个产品类别年度采购额进行了预估。进行了这些估算之后，批发商该如何运用它的预估和非监督学习的结果来对这十个新的客户进行更好的预测？
提示：在下面的代码单元中，我们提供了一个已经做好聚类的数据（聚类结果为数据中的cluster属性），我们将在这个数据集上做一个小实验。尝试运行下面的代码看看我们尝试预测‘Region’的时候，如果存在聚类特征'cluster'与不存在相比对最终的得分会有什么影响？这对你有什么启发？
Can you write Python code for it?

from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split

# 读取包含聚类结果的数据
cluster_data = pd.read_csv("cluster.csv")
y = cluster_data['Region']
X = cluster_data.drop(['Region'], axis = 1)

# 划分训练集测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.8, random_state=24)

clf = RandomForestClassifier(random_state=24)
clf.fit(X_train, y_train)
print "使用cluster特征的得分", clf.score(X_test, y_test)

# 移除cluster特征
X_train = X_train.copy()
X_train.drop(['cluster'], axis=1, inplace=True)
X_test = X_test.copy()
X_test.drop(['cluster'], axis=1, inplace=True)
clf.fit(X_train, y_train)
print "不使用cluster特征的得分", clf.score(X_test, y_test)


I am working on the file "MachineLearning(Advanced)/p3_creating_customer_segments/.ipynb_checkpoints/customer_segments-checkpoint.ipynb".
The first task is:
回答:
- Segment 0，应该是属于零售店客户，各种类别的商品采购量都比较小,Fresh和Frozen购买量刚刚超过最大值的50%，其他类别的商品采购量都在最大值的25%~50%。
- Segment 1，应该是属于超市客户，Milk，Grocery，Frozen，购买量都相对较大，购买量达到了最大值的75%，Delicatessen购买量达到了最大值的50%~75%，只有Fresh，Frozen购买量在25%~50%。
问题 9
对于每一个样本点 * 问题 8  中的哪一个分类能够最好的表示它？你之前对样本的预测和现在的结果相符吗？*
运行下面的代码单元以找到每一个样本点被预测到哪一个簇中去。
Can you write Python code for it?

# 显示预测结果
display(samples.head())

for i, pred in enumerate(sample_preds):
    print "Sample point", i, "predicted to be in Cluster", pred


I am working on the file "MachineLearning(Advanced)/p3_creating_customer_segments/.ipynb_checkpoints/customer_segments-checkpoint.ipynb".
The first task is:
回答：
得分基本相同，但是不使用cluster特征的得分略微低一些。
在数据有Label的情况下，即可以用于监督学习的情况。可以先用非监督学习来类聚数据，然后对比非监督学习与监督学习的结果进行比较，相互印证。增加对于模型，以及分析结果的信心。
另外，将使用非监督学习的预测出来的10个新用户的label，组成新的样本数据（feature,label），来训练出新的监督学习模型。（这样做的目的何在？？？）
【CodeReview20170725】
根据上一次review中给出的note，这里我们已经通过历史数据得到了非监督学习的结果，那么现在我们迎来了10个新的用户，实际上我们可以将这10个samples的类别预测出来，这样我们就得到了新用户的label，所以这里说，在这个情景中，我们可以使用非监督学习的成果，即得到的label，来实现监督学习的功能：利用得到的(feature,label)来学到一个监督学习模型。
可视化内在的分布
在这个项目的开始，我们讨论了从数据集中移除'Channel'和'Region'特征，这样在分析过程中我们就会着重分析用户产品类别。通过重新引入Channel这个特征到数据集中，并施加和原来数据集同样的PCA变换的时候我们将能够发现数据集产生一个有趣的结构。
运行下面的代码单元以查看哪一个数据点在降维的空间中被标记为'HoReCa' (旅馆/餐馆/咖啡厅)或者'Retail'。另外，你将发现样本点在图中被圈了出来，用以显示他们的标签。
Can you write Python code for it?

# 根据‘Channel‘数据显示聚类的结果
vs.channel_results(reduced_data, outliers, pca_samples)


I am working on the file "MachineLearning(Advanced)/p3_creating_customer_segments/.ipynb_checkpoints/customer_segments-checkpoint.ipynb".
The first task is:
练习: 异常值检测
对于任何的分析，在数据预处理的过程中检测数据中的异常值都是非常重要的一步。异常值的出现会使得把这些值考虑进去后结果出现倾斜。这里有很多关于怎样定义什么是数据集中的异常值的经验法则。这里我们将使用Tukey的定义异常值的方法：一个异常阶（outlier step）被定义成1.5倍的四分位距（interquartile range，IQR）。一个数据点如果某个特征包含在该特征的IQR之外的特征，那么该数据点被认定为异常点。
在下面的代码单元中，你需要完成下面的功能：
 - 将指定特征的25th分位点的值分配给Q1。使用np.percentile来完成这个功能。
 - 将指定特征的75th分位点的值分配给Q3。同样的，使用np.percentile来完成这个功能。
 - 将指定特征的异常阶的计算结果赋值给step.
 - 选择性地通过将索引添加到outliers列表中，以移除异常值。
注意： 如果你选择移除异常值，请保证你选择的样本点不在这些移除的点当中！
一旦你完成了这些功能，数据集将存储在good_data中。
Can you write Python code for it?

import numpy as np

# 用于记录所有的异常值的索引
allOutliers = []

# 对于每一个特征，找到值异常高或者是异常低的数据点
for feature in log_data.keys():

    # TODO：计算给定特征的Q1（数据的25th分位点）
    Q1 = np.percentile(log_data[feature], 25)

    # TODO：计算给定特征的Q3（数据的75th分位点）
    Q3 = np.percentile(log_data[feature], 75)

    # TODO：使用四分位范围计算异常阶（1.5倍的四分位距）
    step = 1.5*(Q3-Q1)

    # 显示异常点
    print "Data points considered outliers for the feature '{}':".format(feature)
    display(log_data[~((log_data[feature] >= Q1 - step) & (log_data[feature] <= Q3 + step))])

    outlier = log_data[~((log_data[feature] >= Q1 - step) & (log_data[feature] <= Q3 + step))]
    allOutliers.extend(outlier.index)

# 找出重复的索引值
sortedAllOutliers = np.sort(allOutliers)
duplicatedOutliers = []
preElement = -1
for element in sortedAllOutliers.flat:
    if element == preElement and element not in duplicatedOutliers:
        duplicatedOutliers.append(element);
    preElement = element

print "sortedAllOutliers:{0}".format(sortedAllOutliers)
print "duplicatedOutliers: {0}".format(duplicatedOutliers)

# 可选：选择你希望移除的数据点的索引
outliers  = np.unique(sortedAllOutliers)
print "outliers: {}".format(outliers)

# 如果选择了的话，移除异常点
good_data = log_data.drop(log_data.index[outliers]).reset_index(drop = True)


I am working on the file "MachineLearning(Advanced)/p3_creating_customer_segments/.ipynb_checkpoints/customer_segments-checkpoint.ipynb".
The first task is:
观察
一旦我们有了原始特征的投影（红色箭头），就能更加容易的理解散点图每个数据点的相对位置。
在这个双标图中，哪些初始特征与第一个主成分有强关联？哪些初始特征与第二个主成分相关联？你观察到的是否与之前得到的 pca_results 图相符？
回答：与第一个主成分有强关联的有：Milk，Grocery，Detergents_Paper。与第二个主成分有关联的有：Fresh，Frozen。这个与之前得到的pca_results 图相符。
聚类
在这个部分，你讲选择使用K-Means聚类算法或者是高斯混合模型聚类算法以发现数据中隐藏的客户分类。然后，你将从簇中恢复一些特定的关键数据点，通过将它们转换回原始的维度和规模，从而理解他们的含义。
问题 6
使用K-Means聚类算法的优点是什么？使用高斯混合模型聚类算法的优点是什么？基于你现在对客户数据的观察结果，你选用了这两个算法中的哪一个，为什么？
回答:
K-Means类聚算法的优点是：
1. 算法快速、简单；
2. 对大数据集有较高的效率，并且是可伸缩性的；
3. 时间复杂度近于线性，而且适合挖掘大规模数据集。
高斯混合模型聚类算法的优点是:
1. 模型假设更加复杂准确，即假定服从正态分布（同时，也带来缺点是，计算复杂度增加）
2. 运行结果是属于某个分类的概率，描述更精确严谨。
根据数据分布比较区域比较大，分类的界限并没有那么的严格和清晰，GMM这种分类结果是概率的方法，更加的精确严谨。我打算选用高斯混合模型聚类算法。
练习: 创建聚类
针对不同情况，有些问题你需要的聚类数目可能是已知的。但是在聚类数目不作为一个先验知道的情况下，我们并不能够保证某个聚类的数目对这个数据是最优的，因为我们对于数据的结构（如果存在的话）是不清楚的。但是，我们可以通过计算每一个簇中点的轮廓系数来衡量聚类的质量。数据点的轮廓系数衡量了它与分配给他的簇的相似度，这个值范围在-1（不相似）到1（相似）。平均轮廓系数为我们提供了一种简单地度量聚类质量的方法。
在接下来的代码单元中，你将实现下列功能：
 - 在reduced_data上使用一个聚类算法，并将结果赋值到clusterer，需要设置 random_state 使得结果可以复现。
 - 使用clusterer.predict预测reduced_data中的每一个点的簇，并将结果赋值到preds。
 - 使用算法的某个属性值找到聚类中心，并将它们赋值到centers。
 - 预测pca_samples中的每一个样本点的类别并将结果赋值到sample_preds。
 - 导入sklearn.metrics.silhouette_score包并计算reduced_data相对于preds的轮廓系数。
   - 将轮廓系数赋值给score并输出结果。
Can you write Python code for it?

%%time

from sklearn.mixture import GaussianMixture
from sklearn.metrics import silhouette_score
# TODO：在降维后的数据上使用你选择的聚类算法
clusterer = GaussianMixture(n_components=2, random_state=20).fit(reduced_data)

# TODO：预测每一个点的簇
preds = clusterer.predict(reduced_data)

# TODO：找到聚类中心
centers = clusterer.means_
print "centers: \n{0}".format(centers)

# TODO：预测在每一个转换后的样本点的类
sample_preds = clusterer.predict(pca_samples)

# TODO：计算选择的类别的平均轮廓系数（mean silhouette coefficient）
score = silhouette_score(reduced_data, preds)
print "silhouette_score: {0}".format(score)


I am working on the file "MachineLearning(Advanced)/p3_creating_customer_segments/.ipynb_checkpoints/customer_segments-checkpoint.ipynb".
The first task is:
观察
在使用了一个自然对数的缩放之后，数据的各个特征会显得更加的正态分布。对于任意的你以前发现有相关关系的特征对，观察他们的相关关系是否还是存在的（并且尝试观察，他们的相关关系相比原来是变强了还是变弱了）。
运行下面的代码以观察样本数据在进行了自然对数转换之后如何改变了。
Can you write Python code for it?


I am working on the file "MachineLearning(Advanced)/p3_creating_customer_segments/.ipynb_checkpoints/customer_segments-checkpoint.ipynb".
The first task is:
观察
运行以下代码观察当仅仅使用两个维度进行PCA转换后，这个对数样本数据将怎样变化。观察这里的结果与一个使用六个维度的PCA转换相比较时，前两维的数值是保持不变的。
Can you write Python code for it?

# 展示经过两个维度的PCA转换之后的样本log-data
display(pd.DataFrame(np.round(pca_samples, 4), columns = ['Dimension 1', 'Dimension 2']))


I am working on the file "MachineLearning(Advanced)/p3_creating_customer_segments/.ipynb_checkpoints/customer_segments-checkpoint.ipynb".
The first task is:
问题 1
在你看来你选择的这三个样本点分别代表什么类型的企业（客户）？对每一个你选择的样本客户，通过它在每一种产品类型上的花费与数据集的统计描述进行比较，给出你做上述判断的理由。
提示： 企业的类型包括超市、咖啡馆、零售商以及其他。注意不要使用具体企业的名字，比如说在描述一个餐饮业客户时，你不能使用麦当劳。
回答:
1. 客户1：代表小区附近的生鲜店，小卖部（便利店）的客户。总体采购量较小，还以Fresh和Frozen为主。
    - Fresh和Frozen需求量较大，都超过了总体的75%；
    - 而其他种类的商品的消费量却较小，Milk，Grocery，Detergents_Paper，Delicatessen都不到总体的25%。说明，客户家中人数少，客户经常性买生鲜类产品。
2. 客户2：代表超市的客户。各种商品的采购量都较大，非常适合去超市批量采购，会更加的优惠。
    - Milk，Grocery，Frozen，Detergents_Paper，Delicatessen需求量非常大，超过了总体的75%；
    - 只有Delicatessen低于50%。
3. 客户3：代表超市的客户。类似客户2，各种商品的采购量都较大，非常适合去超市批量采购，会更加的优惠。
    - 这个客户Fresh、Milk、Grocery，Frozen，Delicatessen需求量都较大，都超过了总体的75%。
    - Detergents_Paper刚刚超过50%。
练习: 特征相关性
一个有趣的想法是，考虑这六个类别中的一个（或者多个）产品类别，是否对于理解客户的购买行为具有实际的相关性。也就是说，当用户购买了一定数量的某一类产品，我们是否能够确定他们必然会成比例地购买另一种类的产品。有一个简单的方法可以检测相关性：我们用移除了某一个特征之后的数据集来构建一个监督学习（回归）模型，然后用这个模型去预测那个被移除的特征，再对这个预测结果进行评分，来判断由余下5个特征构建的模型对移除掉的那一个特征预测能力的好坏。
在下面的代码单元中，你需要实现以下的功能：
 - 使用DataFrame.drop函数移除数据集中你选择的不需要的特征，并将移除后的结果赋值给new_data。
 - 使用sklearn.model_selection.train_test_split将数据集分割成训练集和测试集。
   - 使用移除的特征作为你的目标标签。设置test_size为0.25并设置一个random_state。
 - 导入一个DecisionTreeRegressor（决策树回归器），设置一个random_state，然后用训练集训练它。
 - 使用回归器的score函数输出模型在测试集上的预测得分。
Can you write Python code for it?

%%time

from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeRegressor

# TODO：为DataFrame创建一个副本，用'drop'函数丢弃一些指定的特征

grocery = data['Grocery']
data_without_grocery = data.drop(['Grocery'],1)

# display(data.head(1))
# display(fresh.head())
# display(new_data.head())

# TODO：使用给定的特征作为目标，将数据分割成训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(data_without_grocery, grocery, test_size=0.25, random_state=20)

# display(X_train.head(1))
# display(X_test.head(1))
# display(y_train.head(1))
# display(y_test.head(1))

# # TODO：创建一个DecisionTreeRegressor（决策树回归器）并在训练集上训练它
regressor = DecisionTreeRegressor(max_depth=15, random_state=20)
regressor.fit(X_train, y_train)

# # TODO：输出在测试集上的预测得分
score = regressor.score(X_test, y_test)
print score


I am working on the file "MachineLearning(Advanced)/p3_creating_customer_segments/.ipynb_checkpoints/customer_segments-checkpoint.ipynb".
The first task is:
问题 3
这里是否存在一些特征他们彼此之间存在一定程度相关性？如果有请列出。这个结果是验证了还是否认了你尝试预测的那个特征的相关性？这些特征的数据是怎么分布的？
提示： 这些数据是正态分布(normally distributed)的吗？大多数的数据点分布在哪？
回答:
- Grocery与Milk也存在比较好的正相关，大部分数据分布在图形左下角斜向上的锥形区域，符合正态分布。
- Milk与Detergents_Paper存在非常好的正相关，同上，也是大部分数据分布在图形左下角斜向上的锥形区域，符合正态分布。
- Grocery与Detergents_Paper存在非常好的正相关，大部分数据分布在图形左下角斜向上的长条形区域，符合正态分布。
这个结果与之前的预测的结果（Grocery相关性好）相似。
数据预处理
在这个部分，你将通过在数据上做一个合适的缩放，并检测异常点（你可以选择性移除）将数据预处理成一个更好的代表客户的形式。预处理数据是保证你在分析中能够得到显著且有意义的结果的重要环节。
练习: 特征缩放
如果数据不是正态分布的，尤其是数据的平均数和中位数相差很大的时候（表示数据非常歪斜）。这时候通常用一个非线性的缩放是很合适的，（英文原文） — 尤其是对于金融数据。一种实现这个缩放的方法是使用Box-Cox 变换，这个方法能够计算出能够最佳减小数据倾斜的指数变换方法。一个比较简单的并且在大多数情况下都适用的方法是使用自然对数。
在下面的代码单元中，你将需要实现以下功能：
 - 使用np.log函数在数据 data 上做一个对数缩放，然后将它的副本（不改变原始data的值）赋值给log_data。
 - 使用np.log函数在样本数据 samples 上做一个对数缩放，然后将它的副本赋值给log_samples。
Can you write Python code for it?

%%time
from scipy import stats

display(data.head())
# TODO：使用自然对数缩放数据
# log_data = data.apply(lambda x: np.log(x))
log_data = np.log(data)
display(log_data.head())

# TODO：使用自然对数缩放样本数据
log_samples = np.log(samples)
display(log_samples.head())

# 为每一对新产生的特征制作一个散射矩阵
pd.plotting.scatter_matrix(log_data, alpha = 0.3, figsize = (14,8), diagonal = 'kde');


I am working on the file "MachineLearning(Advanced)/p3_creating_customer_segments/.ipynb_checkpoints/customer_segments-checkpoint.ipynb".
The first task is:
问题 4
请列出所有在多于一个特征下被看作是异常的数据点。这些点应该被从数据集中移除吗？为什么？把你认为需要移除的数据点全部加入到到outliers变量中。
回答:多于一个特征下被看作是异常的数据点为：65, 66, 75, 128, 154。
虽然这些数据点有多个特性，说明信息比较丰富，不是单一的数据异常。但是，这些数据做增加的信息所带来的积极的影响，远小于其使类聚中心偏移所带来的消极影响。所以，这些数据点应该被移除。
特征转换
在这个部分中你将使用主成分分析（PCA）来分析批发商客户数据的内在结构。由于使用PCA在一个数据集上会计算出最大化方差的维度，我们将找出哪一个特征组合能够最好的描绘客户。
练习: 主成分分析（PCA）
既然数据被缩放到一个更加正态分布的范围中并且我们也移除了需要移除的异常点，我们现在就能够在good_data上使用PCA算法以发现数据的哪一个维度能够最大化特征的方差。除了找到这些维度，PCA也将报告每一个维度的解释方差比（explained variance ratio）--这个数据有多少方差能够用这个单独的维度来解释。注意PCA的一个组成部分（维度）能够被看做这个空间中的一个新的“特征”，但是它是原来数据中的特征构成的。
在下面的代码单元中，你将要实现下面的功能：
 - 导入sklearn.decomposition.PCA并且将good_data用PCA并且使用6个维度进行拟合后的结果保存到pca中。
 - 使用pca.transform将log_samples进行转换，并将结果存储到pca_samples中。
Can you write Python code for it?

%%time
from sklearn.decomposition import PCA

# TODO：通过在good data上使用PCA，将其转换成和当前特征数一样多的维度
pca = PCA(n_components=good_data.shape[1], random_state=20)
pca.fit(good_data)

# TODO：使用上面的PCA拟合将变换施加在log_samples上
pca_samples = pca.transform(log_samples)

# 生成PCA的结果图
pca_results = vs.pca_results(good_data, pca)


I am working on the file "MachineLearning(Advanced)/p3_creating_customer_segments/.ipynb_checkpoints/customer_segments-checkpoint.ipynb".
The first task is:
问题 7
汇报你尝试的不同的聚类数对应的轮廓系数。在这些当中哪一个聚类的数目能够得到最佳的轮廓系数？
回答:
- n_components=2: 0.447
- n_components=3: 0.362
- n_components=4: 0.304
当类聚数目为2时，能够得到最佳的轮廓系数。
聚类可视化
一旦你选好了通过上面的评价函数得到的算法的最佳聚类数目，你就能够通过使用下面的代码块可视化来得到的结果。作为实验，你可以试着调整你的聚类算法的聚类的数量来看一下不同的可视化结果。但是你提供的最终的可视化图像必须和你选择的最优聚类数目一致。
Can you write Python code for it?

print pca_samples

# 从已有的实现中展示聚类的结果
vs.cluster_results(reduced_data, preds, centers, pca_samples)


I am working on the file "MachineLearning(Advanced)/p3_creating_customer_segments/.ipynb_checkpoints/customer_segments-checkpoint.ipynb".
The first task is:
问题 8
考虑上面的代表性数据点在每一个产品类型的花费总数，你认为这些客户分类代表了哪类客户？为什么？需要参考在项目最开始得到的统计值来给出理由。
提示： 一个被分到'Cluster X'的客户最好被用 'Segment X'中的特征集来标识的企业类型表示。
Can you write Python code for it?

import seaborn as sns
import matplotlib.pyplot as plt
# add the true centers as rows to our original data
newdata = data.append(true_centers)

# show the percentiles of the centers
ctr_pcts = 100. * newdata.rank(axis=0, pct=True).loc[['Segment 0', 'Segment 1']].round(decimals=3)
print ctr_pcts

# visualize percentiles with heatmap
sns.heatmap(ctr_pcts, annot=True, cmap='Greens', fmt='.1f', linewidth=.1, square=True, cbar=False)
plt.xticks(rotation=45, ha='center')
plt.yticks(rotation=0)
plt.title('Percentile ranks of\nsegment centers');


I am working on the file "MachineLearning(Advanced)/p3_creating_customer_segments/customer_segments.ipynb".
The first task is:
分析数据
在这部分，你将开始分析数据，通过可视化和代码来理解每一个特征和其他特征的联系。你会看到关于数据集的统计描述，考虑每一个属性的相关性，然后从数据集中选择若干个样本数据点，你将在整个项目中一直跟踪研究这几个数据点。
运行下面的代码单元给出数据集的一个统计描述。注意这个数据集包含了6个重要的产品类型：'Fresh', 'Milk', 'Grocery', 'Frozen', 'Detergents_Paper'和 'Delicatessen'。想一下这里每一个类型代表你会购买什么样的产品。
Can you write Python code for it?


I am working on the file "MachineLearning(Advanced)/p3_creating_customer_segments/customer_segments.ipynb".
The first task is:
可视化一个双标图（Biplot）
双标图是一个散点图，每个数据点的位置由它所在主成分的分数确定。坐标系是主成分（这里是Dimension 1 和 Dimension 2）。此外，双标图还展示出初始特征在主成分上的投影。一个双标图可以帮助我们理解降维后的数据，发现主成分和初始特征之间的关系。
运行下面的代码来创建一个降维后数据的双标图。
Can you write Python code for it?


I am working on the file "MachineLearning(Advanced)/p3_creating_customer_segments/customer_segments.ipynb".
The first task is:
回答:
- Sample point 0: 零售店（便利店）客户
- Sample point 1： 超市客户
- Sample point 2： 超市客户
与之前的预测基本相符。
结论
在最后一部分中，你要学习如何使用已经被分类的数据。首先，你要考虑不同组的客户客户分类，针对不同的派送策略受到的影响会有什么不同。其次，你要考虑到，每一个客户都被打上了标签（客户属于哪一个分类）可以给客户数据提供一个多一个特征。最后，你会把客户分类与一个数据中的隐藏变量做比较，看一下这个分类是否辨识了特定的关系。
问题 10
在对他们的服务或者是产品做细微的改变的时候，公司经常会使用A/B tests以确定这些改变会对客户产生积极作用还是消极作用。这个批发商希望考虑将他的派送服务从每周5天变为每周3天，但是他只会对他客户当中对此有积极反馈的客户采用。这个批发商应该如何利用客户分类来知道哪些客户对它的这个派送策略的改变有积极的反馈，如果有的话？你需要给出在这个情形下A/B 测试具体的实现方法，以及最终得出结论的依据是什么？
提示： 我们能假设这个改变对所有的客户影响都一致吗？我们怎样才能够确定它对于哪个类型的客户影响最大？
回答：
- 首先假设，这个服务改变对于用户的影响是均匀的，即假设一个已经确定是积极的服务改变对于某单个客户的影响有可能是积极的，也有可能的消极的，但是对于总体的影响应该是恒定的。我们不能假设对于客户的影响是一致的。
- 确认结果的评价标准是：客户投诉率变高（或变低），客户退订减少（或增多），新客户增加（或减少）为好（或坏）。
- 过程：假设有2种分类的客户，将各种分类的客户分别随机用户分成100组，共200组。然后，从各个分类中分别抽出3组来实验。然后，收集实验结果。
- 根据结果评价标准，确定这个服务改变对哪些分类的客户有积极的作用，然后对这些分类的客户采用新的服务模式。
问题 11
通过聚类技术，我们能够将原有的没有标记的数据集中的附加结构分析出来。因为每一个客户都有一个最佳的划分（取决于你选择使用的聚类算法），我们可以把用户分类作为数据的一个工程特征。假设批发商最近迎来十位新顾客，并且他已经为每位顾客每个产品类别年度采购额进行了预估。进行了这些估算之后，批发商该如何运用它的预估和非监督学习的结果来对这十个新的客户进行更好的预测？
提示：在下面的代码单元中，我们提供了一个已经做好聚类的数据（聚类结果为数据中的cluster属性），我们将在这个数据集上做一个小实验。尝试运行下面的代码看看我们尝试预测‘Region’的时候，如果存在聚类特征'cluster'与不存在相比对最终的得分会有什么影响？这对你有什么启发？
Can you write Python code for it?


I am working on the file "MachineLearning(Advanced)/p3_creating_customer_segments/customer_segments.ipynb".
The first task is:
回答:
- Segment 0，应该是属于零售店客户，各种类别的商品采购量都比较小,Fresh和Frozen购买量刚刚超过最大值的50%，其他类别的商品采购量都在最大值的25%~50%。
- Segment 1，应该是属于超市客户，Milk，Grocery，Frozen，购买量都相对较大，购买量达到了最大值的75%，Delicatessen购买量达到了最大值的50%~75%，只有Fresh，Frozen购买量在25%~50%。
问题 9
对于每一个样本点 * 问题 8  中的哪一个分类能够最好的表示它？你之前对样本的预测和现在的结果相符吗？*
运行下面的代码单元以找到每一个样本点被预测到哪一个簇中去。
Can you write Python code for it?


I am working on the file "MachineLearning(Advanced)/p3_creating_customer_segments/customer_segments.ipynb".
The first task is:
回答：
得分基本相同，但是不使用cluster特征的得分略微低一些。
在数据有Label的情况下，即可以用于监督学习的情况。可以先用非监督学习来类聚数据，然后对比非监督学习与监督学习的结果进行比较，相互印证。增加对于模型，以及分析结果的信心。
另外，将使用非监督学习的预测出来的10个新用户的label，组成新的样本数据（feature,label），来训练出新的监督学习模型。（这样做的目的何在？？？）
【CodeReview20170725】
根据上一次review中给出的note，这里我们已经通过历史数据得到了非监督学习的结果，那么现在我们迎来了10个新的用户，实际上我们可以将这10个samples的类别预测出来，这样我们就得到了新用户的label，所以这里说，在这个情景中，我们可以使用非监督学习的成果，即得到的label，来实现监督学习的功能：利用得到的(feature,label)来学到一个监督学习模型。
可视化内在的分布
在这个项目的开始，我们讨论了从数据集中移除'Channel'和'Region'特征，这样在分析过程中我们就会着重分析用户产品类别。通过重新引入Channel这个特征到数据集中，并施加和原来数据集同样的PCA变换的时候我们将能够发现数据集产生一个有趣的结构。
运行下面的代码单元以查看哪一个数据点在降维的空间中被标记为'HoReCa' (旅馆/餐馆/咖啡厅)或者'Retail'。另外，你将发现样本点在图中被圈了出来，用以显示他们的标签。
Can you write Python code for it?


I am working on the file "MachineLearning(Advanced)/p3_creating_customer_segments/customer_segments.ipynb".
The first task is:
练习: 异常值检测
对于任何的分析，在数据预处理的过程中检测数据中的异常值都是非常重要的一步。异常值的出现会使得把这些值考虑进去后结果出现倾斜。这里有很多关于怎样定义什么是数据集中的异常值的经验法则。这里我们将使用Tukey的定义异常值的方法：一个异常阶（outlier step）被定义成1.5倍的四分位距（interquartile range，IQR）。一个数据点如果某个特征包含在该特征的IQR之外的特征，那么该数据点被认定为异常点。
在下面的代码单元中，你需要完成下面的功能：
 - 将指定特征的25th分位点的值分配给Q1。使用np.percentile来完成这个功能。
 - 将指定特征的75th分位点的值分配给Q3。同样的，使用np.percentile来完成这个功能。
 - 将指定特征的异常阶的计算结果赋值给step.
 - 选择性地通过将索引添加到outliers列表中，以移除异常值。
注意： 如果你选择移除异常值，请保证你选择的样本点不在这些移除的点当中！
一旦你完成了这些功能，数据集将存储在good_data中。
Can you write Python code for it?


I am working on the file "MachineLearning(Advanced)/p3_creating_customer_segments/customer_segments.ipynb".
The first task is:
练习: 数据恢复
上面的可视化图像中提供的每一个聚类都有一个中心点。这些中心（或者叫平均点）并不是数据中真实存在的点，但是是所有预测在这个簇中的数据点的平均。对于创建客户分类的问题，一个簇的中心对应于那个分类的平均用户。因为这个数据现在进行了降维并缩放到一定的范围，我们可以通过施加一个反向的转换恢复这个点所代表的用户的花费。
在下面的代码单元中，你将实现下列的功能：
 - 使用pca.inverse_transform将centers 反向转换，并将结果存储在log_centers中。
 - 使用np.log的反函数np.exp反向转换log_centers并将结果存储到true_centers中。
Can you write Python code for it?

log_centers = pca.inverse_transform(centers)
print log_centers

# TODO：反向转换中心点
log_centers = pca.inverse_transform(centers)

# TODO：对中心点做指数转换
true_centers = np.exp(log_centers)

# 显示真实的中心点
segments = ['Segment {}'.format(i) for i in range(0,len(centers))]
true_centers = pd.DataFrame(np.round(true_centers), columns = data.keys())
true_centers.index = segments
display(true_centers)


I am working on the file "MachineLearning(Advanced)/p3_creating_customer_segments/customer_segments.ipynb".
The first task is:
练习: 选择样本
为了对客户有一个更好的了解，并且了解代表他们的数据将会在这个分析过程中如何变换。最好是选择几个样本数据点，并且更为详细地分析它们。在下面的代码单元中，选择三个索引加入到索引列表indices中，这三个索引代表你要追踪的客户。我们建议你不断尝试，直到找到三个明显不同的客户。
Can you write Python code for it?

# TODO：从数据集中选择三个你希望抽样的数据点的索引
indices = [90, 200, 265]

# 为选择的样本建立一个DataFrame
samples = pd.DataFrame(data.loc[indices], columns = data.keys()).reset_index(drop = True)
print "Chosen samples of wholesale customers dataset:"
display(samples)

# Code review modify for report_20170808.html
# 感觉图的效果并不明显，问题8中使用图表效果好【newdata.rank（呈现表格），sns.heatmap（呈现带颜色的表格）】
# 这里加上，以供未来参考，感谢评审者的建议
((samples.median()) / data.median()).plot.bar(figsize=(10,4), title='Samples compared to MEDIAN')
((samples.mean()) / data.mean()).plot.bar(figsize=(10,4), title='Samples compared to MEAN');


I am working on the file "MachineLearning(Advanced)/p3_creating_customer_segments/customer_segments.ipynb".
The first task is:
练习：降维
当使用主成分分析的时候，一个主要的目的是减少数据的维度，这实际上降低了问题的复杂度。当然降维也是需要一定代价的：更少的维度能够表示的数据中的总方差更少。因为这个，累计解释方差比（cumulative explained variance ratio）对于我们确定这个问题需要多少维度非常重要。另外，如果大部分的方差都能够通过两个或者是三个维度进行表示的话，降维之后的数据能够被可视化。
在下面的代码单元中，你将实现下面的功能：
 - 将good_data用两个维度的PCA进行拟合，并将结果存储到pca中去。
 - 使用pca.transform将good_data进行转换，并将结果存储在reduced_data中。
 - 使用pca.transform将log_samples进行转换，并将结果存储在pca_samples中。
Can you write Python code for it?

%%time
from sklearn.decomposition import PCA

# TODO：通过在good data上进行PCA，将其转换成两个维度
pca = PCA(n_components = 2, random_state=20)
pca.fit(good_data)

# TODO：使用上面训练的PCA将good data进行转换
reduced_data = pca.transform(good_data)

# TODO：使用上面训练的PCA将log_samples进行转换
pca_samples = pca.transform(log_samples)

# 为降维后的数据创建一个DataFrame
reduced_data = pd.DataFrame(reduced_data, columns = ['Dimension 1', 'Dimension 2'])


I am working on the file "MachineLearning(Advanced)/p3_creating_customer_segments/customer_segments.ipynb".
The first task is:
观察
一旦我们有了原始特征的投影（红色箭头），就能更加容易的理解散点图每个数据点的相对位置。
在这个双标图中，哪些初始特征与第一个主成分有强关联？哪些初始特征与第二个主成分相关联？你观察到的是否与之前得到的 pca_results 图相符？
回答：与第一个主成分有强关联的有：Milk，Grocery，Detergents_Paper。与第二个主成分有关联的有：Fresh，Frozen。这个与之前得到的pca_results 图相符。
聚类
在这个部分，你讲选择使用K-Means聚类算法或者是高斯混合模型聚类算法以发现数据中隐藏的客户分类。然后，你将从簇中恢复一些特定的关键数据点，通过将它们转换回原始的维度和规模，从而理解他们的含义。
问题 6
使用K-Means聚类算法的优点是什么？使用高斯混合模型聚类算法的优点是什么？基于你现在对客户数据的观察结果，你选用了这两个算法中的哪一个，为什么？
回答:
K-Means类聚算法的优点是：
1. 算法快速、简单；
2. 对大数据集有较高的效率，并且是可伸缩性的；
3. 时间复杂度近于线性，而且适合挖掘大规模数据集。
高斯混合模型聚类算法的优点是:
1. 模型假设更加复杂准确，即假定服从正态分布（同时，也带来缺点是，计算复杂度增加）
2. 运行结果是属于某个分类的概率，描述更精确严谨。
根据数据分布比较区域比较大，分类的界限并没有那么的严格和清晰，GMM这种分类结果是概率的方法，更加的精确严谨。我打算选用高斯混合模型聚类算法。
练习: 创建聚类
针对不同情况，有些问题你需要的聚类数目可能是已知的。但是在聚类数目不作为一个先验知道的情况下，我们并不能够保证某个聚类的数目对这个数据是最优的，因为我们对于数据的结构（如果存在的话）是不清楚的。但是，我们可以通过计算每一个簇中点的轮廓系数来衡量聚类的质量。数据点的轮廓系数衡量了它与分配给他的簇的相似度，这个值范围在-1（不相似）到1（相似）。平均轮廓系数为我们提供了一种简单地度量聚类质量的方法。
在接下来的代码单元中，你将实现下列功能：
 - 在reduced_data上使用一个聚类算法，并将结果赋值到clusterer，需要设置 random_state 使得结果可以复现。
 - 使用clusterer.predict预测reduced_data中的每一个点的簇，并将结果赋值到preds。
 - 使用算法的某个属性值找到聚类中心，并将它们赋值到centers。
 - 预测pca_samples中的每一个样本点的类别并将结果赋值到sample_preds。
 - 导入sklearn.metrics.silhouette_score包并计算reduced_data相对于preds的轮廓系数。
   - 将轮廓系数赋值给score并输出结果。
Can you write Python code for it?


I am working on the file "MachineLearning(Advanced)/p3_creating_customer_segments/customer_segments.ipynb".
The first task is:
观察
在使用了一个自然对数的缩放之后，数据的各个特征会显得更加的正态分布。对于任意的你以前发现有相关关系的特征对，观察他们的相关关系是否还是存在的（并且尝试观察，他们的相关关系相比原来是变强了还是变弱了）。
运行下面的代码以观察样本数据在进行了自然对数转换之后如何改变了。
Can you write Python code for it?


I am working on the file "MachineLearning(Advanced)/p3_creating_customer_segments/customer_segments.ipynb".
The first task is:
观察
运行以下代码观察当仅仅使用两个维度进行PCA转换后，这个对数样本数据将怎样变化。观察这里的结果与一个使用六个维度的PCA转换相比较时，前两维的数值是保持不变的。
Can you write Python code for it?


I am working on the file "MachineLearning(Advanced)/p3_creating_customer_segments/customer_segments.ipynb".
The first task is:
问题 1
在你看来你选择的这三个样本点分别代表什么类型的企业（客户）？对每一个你选择的样本客户，通过它在每一种产品类型上的花费与数据集的统计描述进行比较，给出你做上述判断的理由。
提示： 企业的类型包括超市、咖啡馆、零售商以及其他。注意不要使用具体企业的名字，比如说在描述一个餐饮业客户时，你不能使用麦当劳。
回答:
1. 客户1：代表小区附近的生鲜店，小卖部（便利店）的客户。总体采购量较小，还以Fresh和Frozen为主。
    - Fresh和Frozen需求量较大，都超过了总体的75%；
    - 而其他种类的商品的消费量却较小，Milk，Grocery，Detergents_Paper，Delicatessen都不到总体的25%。说明，客户家中人数少，客户经常性买生鲜类产品。
2. 客户2：代表超市的客户。各种商品的采购量都较大，非常适合去超市批量采购，会更加的优惠。
    - Milk，Grocery，Frozen，Detergents_Paper，Delicatessen需求量非常大，超过了总体的75%；
    - 只有Delicatessen低于50%。
3. 客户3：代表超市的客户。类似客户2，各种商品的采购量都较大，非常适合去超市批量采购，会更加的优惠。
    - 这个客户Fresh、Milk、Grocery，Frozen，Delicatessen需求量都较大，都超过了总体的75%。
    - Detergents_Paper刚刚超过50%。
练习: 特征相关性
一个有趣的想法是，考虑这六个类别中的一个（或者多个）产品类别，是否对于理解客户的购买行为具有实际的相关性。也就是说，当用户购买了一定数量的某一类产品，我们是否能够确定他们必然会成比例地购买另一种类的产品。有一个简单的方法可以检测相关性：我们用移除了某一个特征之后的数据集来构建一个监督学习（回归）模型，然后用这个模型去预测那个被移除的特征，再对这个预测结果进行评分，来判断由余下5个特征构建的模型对移除掉的那一个特征预测能力的好坏。
在下面的代码单元中，你需要实现以下的功能：
 - 使用DataFrame.drop函数移除数据集中你选择的不需要的特征，并将移除后的结果赋值给new_data。
 - 使用sklearn.model_selection.train_test_split将数据集分割成训练集和测试集。
   - 使用移除的特征作为你的目标标签。设置test_size为0.25并设置一个random_state。
 - 导入一个DecisionTreeRegressor（决策树回归器），设置一个random_state，然后用训练集训练它。
 - 使用回归器的score函数输出模型在测试集上的预测得分。
Can you write Python code for it?


I am working on the file "MachineLearning(Advanced)/p3_creating_customer_segments/customer_segments.ipynb".
The first task is:
问题 2
你尝试预测哪一个特征？预测的得分是多少？这个特征对于区分用户的消费习惯来说必要吗？
提示： 决定系数（coefficient of determination）, R^2,结果在0到1之间，1表示完美拟合，一个负的R^2表示模型不能够拟合数据。
回答:
预测Grocery，预测得分约为0.728，这个特征对于区分用户是没有必要的。因为这个特征可以被其他特征很好的预测，说明与其他特征的相关性好，可以被其他的特征替代，所以没有存在的必要性。
可视化特征分布
为了能够对这个数据集有一个更好的理解，我们可以对数据集中的每一个产品特征构建一个散布矩阵（scatter matrix）。如果你发现你在上面尝试预测的特征对于区分一个特定的用户来说是必须的，那么这个特征和其它的特征可能不会在下面的散射矩阵中显示任何关系。相反的，如果你认为这个特征对于识别一个特定的客户是没有作用的，那么通过散布矩阵可以看出在这个数据特征和其它特征中有关联性。运行下面的代码以创建一个散布矩阵。
Can you write Python code for it?

# 对于数据中的每一对特征构造一个散布矩阵
pd.plotting.scatter_matrix(data, alpha = 0.3, figsize = (14,8), diagonal = 'kde');

%pdb
# 数据关联度表格呈现
import seaborn
seaborn.heatmap(data.corr(), annot=True)
# 添加这些代码以后，导致所有曲线图背景颜色显示异常


I am working on the file "MachineLearning(Advanced)/p3_creating_customer_segments/customer_segments.ipynb".
The first task is:
问题 3
这里是否存在一些特征他们彼此之间存在一定程度相关性？如果有请列出。这个结果是验证了还是否认了你尝试预测的那个特征的相关性？这些特征的数据是怎么分布的？
提示： 这些数据是正态分布(normally distributed)的吗？大多数的数据点分布在哪？
回答:
- Grocery与Milk也存在比较好的正相关，大部分数据分布在图形左下角斜向上的锥形区域，属于正偏态分布。
- Milk与Detergents_Paper存在非常好的正相关，同上，也是大部分数据分布在图形左下角斜向上的锥形区域，属于正偏态分布。
- Grocery与Detergents_Paper存在非常好的正相关，大部分数据分布在图形左下角斜向上的长条形区域，属于正偏态分布。
这个结果与之前的预测的结果（Grocery相关性好）相似。
Reference：skewed distribution(偏态分布)
数据预处理
在这个部分，你将通过在数据上做一个合适的缩放，并检测异常点（你可以选择性移除）将数据预处理成一个更好的代表客户的形式。预处理数据是保证你在分析中能够得到显著且有意义的结果的重要环节。
练习: 特征缩放
如果数据不是正态分布的，尤其是数据的平均数和中位数相差很大的时候（表示数据非常歪斜）。这时候通常用一个非线性的缩放是很合适的，（英文原文） — 尤其是对于金融数据。一种实现这个缩放的方法是使用Box-Cox 变换，这个方法能够计算出能够最佳减小数据倾斜的指数变换方法。一个比较简单的并且在大多数情况下都适用的方法是使用自然对数。
在下面的代码单元中，你将需要实现以下功能：
 - 使用np.log函数在数据 data 上做一个对数缩放，然后将它的副本（不改变原始data的值）赋值给log_data。
 - 使用np.log函数在样本数据 samples 上做一个对数缩放，然后将它的副本赋值给log_samples。
Can you write Python code for it?


I am working on the file "MachineLearning(Advanced)/p3_creating_customer_segments/customer_segments.ipynb".
The first task is:
问题 4
请列出所有在多于一个特征下被看作是异常的数据点。这些点应该被从数据集中移除吗？为什么？把你认为需要移除的数据点全部加入到到outliers变量中。
回答:
- 多于一个特征下被看作是异常的数据点为：65, 66, 75, 128, 154。
虽然这些数据点有多个特性，说明信息比较丰富，不是单一的数据异常。但是，这些数据做增加的信息所带来的积极的影响，远小于其使类聚中心偏移所带来的消极影响。所以，这些数据点应该被移除。
- 另外，在一个特征下被看作是异常的数据点，也应该被移除，因为这些异常值使得类聚中心偏斜，而同时，几乎没有对结果产生多少积极的作用。
特征转换
在这个部分中你将使用主成分分析（PCA）来分析批发商客户数据的内在结构。由于使用PCA在一个数据集上会计算出最大化方差的维度，我们将找出哪一个特征组合能够最好的描绘客户。
练习: 主成分分析（PCA）
既然数据被缩放到一个更加正态分布的范围中并且我们也移除了需要移除的异常点，我们现在就能够在good_data上使用PCA算法以发现数据的哪一个维度能够最大化特征的方差。除了找到这些维度，PCA也将报告每一个维度的解释方差比（explained variance ratio）--这个数据有多少方差能够用这个单独的维度来解释。注意PCA的一个组成部分（维度）能够被看做这个空间中的一个新的“特征”，但是它是原来数据中的特征构成的。
在下面的代码单元中，你将要实现下面的功能：
 - 导入sklearn.decomposition.PCA并且将good_data用PCA并且使用6个维度进行拟合后的结果保存到pca中。
 - 使用pca.transform将log_samples进行转换，并将结果存储到pca_samples中。
Can you write Python code for it?


I am working on the file "MachineLearning(Advanced)/p3_creating_customer_segments/customer_segments.ipynb".
The first task is:
问题 5
数据的第一个和第二个主成分 总共 表示了多少的方差？  前四个主成分呢？使用上面提供的可视化图像，讨论从用户花费的角度来看前四个主要成分的消费行为最能代表哪种类型的客户并给出你做出判断的理由。
提示： 某一特定维度上的正向增长对应正权特征的增长和负权特征的减少。增长和减少的速率和每个特征的权重相关。参考资料(英文)。
回答:前两个主成分表示了0.7252，即%72.52的方差。前四个主成分表示了0.9279，即%92.79的方差。
- Dimension 1代表Milk、Grocery和Detergents三者相关性购买的客户（买其中一种的商品的同时，会购买相应数量的另外2种商品）。
- Dimension 2代表Fresh、Frozen和Delicatessen三者相关性购买的客户（买其中一种的商品的同时，会购买相应数量的另外2种商品）。
- Dimension 3代表Delicatessen和Fresh二者负相关性购买的客户（购买Delicatessen时，会购买更少Fresh的客户）。
- Dimension 4代表Delicatessen和Frozen二者负相关性购买的客户（购买Delicatessen时，会购买更少Frozen的客户）。
正的权值越大，说明购买相关性越大，所以，主成分分析的结果，才会放到一起，合并到同一个维度里面来。
【CodeReview20170723】
在这边，我们使用了主成分分析法，将原来的6个特征通过数学变换，变换为了另外6个特征。对方差的计算，是为了让我们能够选择方差较大的特征以保留它们。每个新特征，实际上都是由原来的特征通过某种带权重的组合得到的，权重就是图中柱状图柱高度。考虑权重的绝对值，权重绝对值越大，说明权重对应的原特征对这个新特征带来的影响越大，反之亦反。权重若为正，则说明他们有正相关性；负值则说明它们是负相关性。A和B有正相关性可以理解为，买更多的A意味着有很大可能买更多的B；负相关性意味着买更多的A意味着有很大可能买更少的B。
观察
运行下面的代码，查看经过对数转换的样本数据在进行一个6个维度的主成分分析（PCA）之后会如何改变。观察样本数据的前四个维度的数值。考虑这和你初始对样本点的解释是否一致。
Can you write Python code for it?

# 展示经过PCA转换的sample log-data
display(samples)
display(pd.DataFrame(np.round(pca_samples, 4), columns = pca_results.index.values))


I am working on the file "MachineLearning(Advanced)/p3_creating_customer_segments/customer_segments.ipynb".
The first task is:
问题 7
汇报你尝试的不同的聚类数对应的轮廓系数。在这些当中哪一个聚类的数目能够得到最佳的轮廓系数？
回答:
- n_components=2: 0.447
- n_components=3: 0.362
- n_components=4: 0.304
当类聚数目为2时，能够得到最佳的轮廓系数。
聚类可视化
一旦你选好了通过上面的评价函数得到的算法的最佳聚类数目，你就能够通过使用下面的代码块可视化来得到的结果。作为实验，你可以试着调整你的聚类算法的聚类的数量来看一下不同的可视化结果。但是你提供的最终的可视化图像必须和你选择的最优聚类数目一致。
Can you write Python code for it?


I am working on the file "MachineLearning(Advanced)/p3_creating_customer_segments/customer_segments.ipynb".
The first task is:
问题 8
考虑上面的代表性数据点在每一个产品类型的花费总数，你认为这些客户分类代表了哪类客户？为什么？需要参考在项目最开始得到的统计值来给出理由。
提示： 一个被分到'Cluster X'的客户最好被用 'Segment X'中的特征集来标识的企业类型表示。
Can you write Python code for it?


I am working on the file "MachineLearning(Advanced)/p5_image_classification/image_classification.ipynb".
The first task is:
Check Point
This is your first checkpoint.  If you ever decide to come back to this notebook or have to restart the notebook, you can start from here.  The preprocessed data has been saved to disk.
Can you write Python code for it?

"""
DON'T MODIFY ANYTHING IN THIS CELL
"""
import pickle
import problem_unittests as tests
import helper

# Load the Preprocessed Validation data
valid_features, valid_labels = pickle.load(open('preprocess_validation.p', mode='rb'))


I am working on the file "MachineLearning(Advanced)/p5_image_classification/image_classification.ipynb".
The first task is:
Convolution and Max Pooling Layer
Convolution layers have a lot of success with images. For this code cell, you should implement the function conv2d_maxpool to apply convolution then max pooling:
* Create the weight and bias using conv_ksize, conv_num_outputs and the shape of x_tensor.
* Apply a convolution to x_tensor using weight and conv_strides.
 * We recommend you use same padding, but you're welcome to use any padding.
* Add bias
* Add a nonlinear activation to the convolution.
* Apply Max Pooling using pool_ksize and pool_strides.
 * We recommend you use same padding, but you're welcome to use any padding.
Note: You can't use TensorFlow Layers or TensorFlow Layers (contrib) for this layer, but you can still use TensorFlow's Neural Network package. You may still use the shortcut option for all the other layers.
 Hint:
When unpacking values as an argument in Python, look into the unpacking operator.
Can you write Python code for it?

def conv2d_maxpool(x_tensor, conv_num_outputs, conv_ksize, conv_strides, pool_ksize, pool_strides):
    """
    Apply convolution then max pooling to x_tensor
    :param x_tensor: TensorFlow Tensor
    :param conv_num_outputs: Number of outputs for the convolutional layer
    :param conv_ksize: kernal size 2-D Tuple for the convolutional layer
    :param conv_strides: Stride 2-D Tuple for convolution
    :param pool_ksize: kernal size 2-D Tuple for pool
    :param pool_strides: Stride 2-D Tuple for pool
    : return: A tensor that represents convolution and max pooling of x_tensor
    """
    # TODO: Implement Function
    return None

"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_con_pool(conv2d_maxpool)


I am working on the file "MachineLearning(Advanced)/p5_image_classification/image_classification.ipynb".
The first task is:
Fully-Connected Layer
Implement the fully_conn function to apply a fully connected layer to x_tensor with the shape (Batch Size, num_outputs). Shortcut option: you can use classes from the TensorFlow Layers or TensorFlow Layers (contrib) packages for this layer. For more of a challenge, only use other TensorFlow packages.
Can you write Python code for it?

def fully_conn(x_tensor, num_outputs):
    """
    Apply a fully connected layer to x_tensor using weight and bias
    : x_tensor: A 2-D tensor where the first dimension is batch size.
    : num_outputs: The number of output that the new tensor should be.
    : return: A 2-D tensor where the second dimension is num_outputs.
    """
    # TODO: Implement Function
    return None

"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_fully_conn(fully_conn)


I am working on the file "MachineLearning(Advanced)/p5_image_classification/image_classification.ipynb".
The first task is:
Hyperparameters
Tune the following parameters:
* Set epochs to the number of iterations until the network stops learning or start overfitting
* Set batch_size to the highest number that your machine has memory for.  Most people set them to common sizes of memory:
 * 64
 * 128
 * 256
 * ...
* Set keep_probability to the probability of keeping a node using dropout
Can you write Python code for it?

# TODO: Tune Parameters
epochs = None
batch_size = None
keep_probability = None


I am working on the file "MachineLearning(Advanced)/p5_image_classification/image_classification.ipynb".
The first task is:
Implement Preprocess Functions
Normalize
In the cell below, implement the normalize function to take in image data, x, and return it as a normalized Numpy array. The values should be in the range of 0 to 1, inclusive.  The return object should be the same shape as x.
Can you write Python code for it?

def normalize(x):
    """
    Normalize a list of sample image data in the range of 0 to 1
    : x: List of image data.  The image shape is (32, 32, 3)
    : return: Numpy array of normalize data
    """
    # TODO: Implement Function
    return None

"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_normalize(normalize)


I am working on the file "MachineLearning(Advanced)/p5_image_classification/image_classification.ipynb".
The first task is:
Output Layer
Implement the output function to apply a fully connected layer to x_tensor with the shape (Batch Size, num_outputs). Shortcut option: you can use classes from the TensorFlow Layers or TensorFlow Layers (contrib) packages for this layer. For more of a challenge, only use other TensorFlow packages.
Note: Activation, softmax, or cross entropy should not be applied to this.
Can you write Python code for it?

def output(x_tensor, num_outputs):
    """
    Apply a output layer to x_tensor using weight and bias
    : x_tensor: A 2-D tensor where the first dimension is batch size.
    : num_outputs: The number of output that the new tensor should be.
    : return: A 2-D tensor where the second dimension is num_outputs.
    """
    # TODO: Implement Function
    return None

"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_output(output)


I am working on the file "MachineLearning(Advanced)/p5_image_classification/image_classification.ipynb".
The first task is:
Randomize Data
As you saw from exploring the data above, the order of the samples are randomized.  It doesn't hurt to randomize it again, but you don't need to for this dataset.
Preprocess all the data and save it
Running the code cell below will preprocess all the CIFAR-10 data and save it to file. The code below also uses 10% of the training data for validation.
Can you write Python code for it?

"""
DON'T MODIFY ANYTHING IN THIS CELL
"""
# Preprocess Training, Validation, and Testing Data
helper.preprocess_and_save_data(cifar10_dataset_folder_path, normalize, one_hot_encode)


I am working on the file "MachineLearning(Advanced)/p5_image_classification/image_classification_ZH-CN.ipynb".
The first task is:
Build the network
For the neural network, you'll build each layer into a function.  Most of the code you've seen has been outside of functions. To test your code more thoroughly, we require that you put each layer in a function.  This allows us to give you better feedback and test for simple mistakes using our unittests before you submit your project.

Note: If you're finding it hard to dedicate enough time for this course each week, we've provided a small shortcut to this part of the project. In the next couple of problems, you'll have the option to use classes from the TensorFlow Layers or TensorFlow Layers (contrib) packages to build each layer, except the layers you build in the "Convolutional and Max Pooling Layer" section.  TF Layers is similar to Keras's and TFLearn's abstraction to layers, so it's easy to pickup.
However, if you would like to get the most out of this course, try to solve all the problems without using anything from the TF Layers packages. You can still use classes from other packages that happen to have the same name as ones you find in TF Layers! For example, instead of using the TF Layers version of the conv2d class, tf.layers.conv2d, you would want to use the TF Neural Network version of conv2d, tf.nn.conv2d.

Let's begin!
Input
The neural network needs to read the image data, one-hot encoded labels, and dropout keep probability. Implement the following functions
* Implement neural_net_image_input
 * Return a TF Placeholder
 * Set the shape using image_shape with batch size set to None.
 * Name the TensorFlow placeholder "x" using the TensorFlow name parameter in the TF Placeholder.
* Implement neural_net_label_input
 * Return a TF Placeholder
 * Set the shape using n_classes with batch size set to None.
 * Name the TensorFlow placeholder "y" using the TensorFlow name parameter in the TF Placeholder.
* Implement neural_net_keep_prob_input
 * Return a TF Placeholder for dropout keep probability.
 * Name the TensorFlow placeholder "keep_prob" using the TensorFlow name parameter in...
Can you write Python code for it?

import tensorflow as tf

# There are tensorflow-gpu settings, but gpu can not work becourse of the net is too big.
from keras.backend.tensorflow_backend import set_session
config = tf.ConfigProto()
config.gpu_options.per_process_gpu_memory_fraction = 0.3
set_session(tf.Session(config=config))

def neural_net_image_input(image_shape):
    """
    Return a Tensor for a batch of image input
    : image_shape: Shape of the images
    : return: Tensor for image input.
    """
    # TODO: Implement Function
    x = tf.placeholder(tf.float32, shape=(None, image_shape[0], image_shape[1], image_shape[2]), name='x')
    return x

def neural_net_label_input(n_classes):
    """
    Return a Tensor for a batch of label input
    : n_classes: Number of classes
    : return: Tensor for label input.
    """
    # TODO: Implement Function
    y = tf.placeholder(tf.float32, shape=(None, n_classes), name='y')
    return y

def neural_net_keep_prob_input():
    """
    Return a Tensor for keep probability
    : return: Tensor for keep probability.
    """
    # TODO: Implement Function
    keep_prob = tf.placeholder(tf.float32, name='keep_prob')
    return keep_prob

"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tf.reset_default_graph()
tests.test_nn_image_inputs(neural_net_image_input)
tests.test_nn_label_inputs(neural_net_label_input)
tests.test_nn_keep_prob_inputs(neural_net_keep_prob_input)


I am working on the file "MachineLearning(Advanced)/p5_image_classification/image_classification_ZH-CN.ipynb".
The first task is:
Check Point
This is your first checkpoint.  If you ever decide to come back to this notebook or have to restart the notebook, you can start from here.  The preprocessed data has been saved to disk.
检查点
这是你的首个检查点。因为预处理完的数据已经被保存到硬盘上了，所以如果你需要回顾或重启该 notebook，你可以在这里重新开始。
Can you write Python code for it?


I am working on the file "MachineLearning(Advanced)/p5_image_classification/image_classification_ZH-CN.ipynb".
The first task is:
Checkpoint
The model has been saved to disk.
Test Model
Test your model against the test dataset.  This will be your final accuracy. You should have an accuracy greater than 50%. If you don't, keep tweaking the model architecture and parameters.
检查点
该模型已经被存储到你的硬盘中。
测试模型
这部分将在测试数据集上测试你的模型。这边得到的准确率将作为你的最终准确率。你应该得到一个高于 50% 准确率。如果它没有超过 50%，那么你需要继续调整模型架构及参数。
Can you write Python code for it?

"""
DON'T MODIFY ANYTHING IN THIS CELL
"""
%matplotlib inline
%config InlineBackend.figure_format = 'retina'

import tensorflow as tf
import pickle
import helper
import random

# Set batch size if not already set
try:
    if batch_size:
        pass
except NameError:
    batch_size = 64

save_model_path = './image_classification'
n_samples = 4
top_n_predictions = 3

def test_model():
    """
    Test the saved model against the test dataset
    """

    test_features, test_labels = pickle.load(open('preprocess_training.p', mode='rb'))
    loaded_graph = tf.Graph()

    with tf.Session(graph=loaded_graph) as sess:
        # Load model
        loader = tf.train.import_meta_graph(save_model_path + '.meta')
        loader.restore(sess, save_model_path)

        # Get Tensors from loaded model
        loaded_x = loaded_graph.get_tensor_by_name('x:0')
        loaded_y = loaded_graph.get_tensor_by_name('y:0')
        loaded_keep_prob = loaded_graph.get_tensor_by_name('keep_prob:0')
        loaded_logits = loaded_graph.get_tensor_by_name('logits:0')
        loaded_acc = loaded_graph.get_tensor_by_name('accuracy:0')

        # Get accuracy in batches for memory limitations
        test_batch_acc_total = 0
        test_batch_count = 0

        for train_feature_batch, train_label_batch in helper.batch_features_labels(test_features, test_labels, batch_size):
            test_batch_acc_total += sess.run(
                loaded_acc,
                feed_dict={loaded_x: train_feature_batch, loaded_y: train_label_batch, loaded_keep_prob: 1.0})
            test_batch_count += 1

        print('Testing Accuracy: {}\n'.format(test_batch_acc_total/test_batch_count))

        # Print Random Samples
        random_test_features, random_test_labels = tuple(zip(*random.sample(list(zip(test_features, test_labels)), n_samples)))
        random_test_predictions = sess.run(
            tf.nn.top_k(tf.nn.softmax(loaded_logits), top_n_predictions),
            feed_dict={loaded_x: random_test_features, loaded_y:...


I am working on the file "MachineLearning(Advanced)/p5_image_classification/image_classification_ZH-CN.ipynb".
The first task is:
Convolution and Max Pooling Layer
Convolution layers have a lot of success with images. For this code cell, you should implement the function conv2d_maxpool to apply convolution then max pooling:
* Create the weight and bias using conv_ksize, conv_num_outputs and the shape of x_tensor.
* Apply a convolution to x_tensor using weight and conv_strides.
 * We recommend you use same padding, but you're welcome to use any padding.
* Add bias
* Add a nonlinear activation to the convolution.
* Apply Max Pooling using pool_ksize and pool_strides.
 * We recommend you use same padding, but you're welcome to use any padding.
Note: You can't use TensorFlow Layers or TensorFlow Layers (contrib) for this layer, but you can still use TensorFlow's Neural Network package. You may still use the shortcut option for all the other layers.
 Hint:
When unpacking values as an argument in Python, look into the unpacking operator.
卷积-最大池（Convolution and Max Pooling）化层
卷积层在图像处理中取得了不小的成功。在这部分的代码中，你需要修改 conv2d_maxpool 函数来先后实现卷积及最大池化的功能。

使用 conv_ksize、conv_num_outputs 及 x_tensor 来创建权重（weight）及偏差（bias）变量。
对 x_tensor 进行卷积，使用 conv_strides 及权重。
我们建议使用 SAME padding，不过你也可尝试其他 padding 模式。
加上偏差。
对卷积结果加上一个非线性函数作为激活层。
基于 pool_kszie 及 pool_strides 进行最大池化。
我们建议使用 SAME padding，不过你也可尝试其他 padding 模式。

注意：
你不可以使用来自 TensorFlow Layers 或 TensorFlow Layers (contrib) 包中的函数来实现这一层的功能。但是你可以使用 TensorFlow 的Neural Network包。
对于如上的快捷方法，你在其他层中可以尝试使用。
提示：
当你在 Python 中希望展开（unpacking）某个变量的值作为函数的参数，你可以参考 unpacking 运算符。
Can you write Python code for it?

def conv2d_maxpool(x_tensor, conv_num_outputs, conv_ksize, conv_strides, pool_ksize, pool_strides):
    """
    Apply convolution then max pooling to x_tensor
    :param x_tensor: TensorFlow Tensor
    :param conv_num_outputs: Number of outputs for the convolutional layer
    :param conv_ksize: kernal size 2-D Tuple for the convolutional layer
    :param conv_strides: Stride 2-D Tuple for convolution
    :param pool_ksize: kernal size 2-D Tuple for pool
    :param pool_strides: Stride 2-D Tuple for pool
    : return: A tensor that represents convolution and max pooling of x_tensor
    """
    #input = tf.placeholder(tf.float32, (None, 32, 32, 3))
    x_tensor_shape = x_tensor.get_shape().as_list()
    print('x_tensor_shape:\t{0}'.format(x_tensor_shape))
    print('conv_num_outputs:{0}'.format(conv_num_outputs))
    print('conv_ksize:\t{0}'.format(conv_ksize))
    print('conv_strides:\t{0}'.format(conv_strides))
    print('pool_ksize:\t{0}'.format(pool_ksize))
    print('pool_strides:\t{0}'.format(pool_strides))

    filter_weights = tf.Variable(tf.truncated_normal((conv_ksize[0], conv_ksize[1], x_tensor_shape[3], conv_num_outputs), mean=0.0, stddev = 0.05)) # (height, width, input_depth, output_depth)
    filter_bias = tf.Variable(tf.zeros(conv_num_outputs))
    strides = [1, conv_strides[0], conv_strides[1], 1] # (batch, height, width, depth)

    conv_layer = tf.nn.conv2d(x_tensor, filter_weights, strides=strides, padding='SAME')
    conv_layer = tf.nn.bias_add(conv_layer, filter_bias)
#     conv_layer = conv_layer + filter_bias
    conv_layer = tf.nn.relu(conv_layer)
    # Apply Max Pooling
    conv_layer = tf.nn.max_pool(
        conv_layer,
        ksize=[1, pool_ksize[0], pool_ksize[1], 1],
        strides=[1, pool_strides[0], pool_strides[1], 1],
        padding='SAME')
    return conv_layer

"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_con_pool(conv2d_maxpool)


I am working on the file "MachineLearning(Advanced)/p5_image_classification/image_classification_ZH-CN.ipynb".
The first task is:
Create Convolutional Model
Implement the function conv_net to create a convolutional neural network model. The function takes in a batch of images, x, and outputs logits.  Use the layers you created above to create this model:

Apply 1, 2, or 3 Convolution and Max Pool layers
Apply a Flatten Layer
Apply 1, 2, or 3 Fully Connected Layers
Apply an Output Layer
Return the output
Apply TensorFlow's Dropout to one or more layers in the model using keep_prob.

创建卷积模型
修改 conv_net 函数，使之能够生成一个卷积神经网络模型。该函数的输入为一批图像数据 x，输出为 logits。在函数中，使用上方你修改的创建各种层的函数来创建该模型：

使用 1 到 3 个卷积-最大池化层
使用一个展开层
使用 1 到 3 个全连接层
使用一个输出层
返回呼出结果
在一个或多个层上使用 TensorFlow's Dropout，对应的保留概率为 keep_prob.
Can you write Python code for it?

def conv_net(x, keep_prob):
    """
    Create a convolutional neural network model
    : x: Placeholder tensor that holds image data.
    : keep_prob: Placeholder tensor that hold dropout keep probability.
    : return: Tensor that represents logits
    """
    # TODO: Apply 1, 2, or 3 Convolution and Max Pool layers
    #    Play around with different number of outputs, kernel size and stride
    # Function Definition from Above:
    #    conv2d_maxpool(x_tensor, conv_num_outputs, conv_ksize, conv_strides, pool_ksize, pool_strides)

    conv_num_outputs1 = 32
    conv_ksize1       = (4, 4)
    conv_strides1     = (1, 1)
    pool_ksize1       = (2, 2)
    pool_strides1     = (2, 2)
    conv_layer1 = conv2d_maxpool(x, conv_num_outputs1, conv_ksize1, conv_strides1, pool_ksize1, pool_strides1)
    conv_layer1 = tf.nn.dropout(conv_layer1, keep_prob)

    conv_num_outputs2 = 64
    conv_ksize2       = (4, 4)
    conv_strides2     = (1, 1)
    pool_ksize2       = (2, 2)
    pool_strides2     = (2, 2)
    conv_layer2 = conv2d_maxpool(x, conv_num_outputs2, conv_ksize2, conv_strides2, pool_ksize2, pool_strides2)
    conv_layer2 = tf.nn.dropout(conv_layer2, keep_prob)

    conv_num_outputs3 = 128
    conv_ksize3       = (4, 4)
    conv_strides3     = (1, 1)
    pool_ksize3       = (2, 2)
    pool_strides3     = (2, 2)
    conv_layer3 = conv2d_maxpool(x, conv_num_outputs3, conv_ksize3, conv_strides3, pool_ksize3, pool_strides3)
    conv_layer3 = tf.nn.dropout(conv_layer3, keep_prob)

    # TODO: Apply a Flatten Layer
    # Function Definition from Above:
    #   flatten(x_tensor)
    conv_layer_flatten = flatten(conv_layer3)
    print('conv_layer_flatten.shape:%s' %conv_layer_flatten.shape)

    # TODO: Apply 1, 2, or 3 Fully Connected Layers
    #    Play around with different number of outputs
    # Function Definition from Above:
    #   fully_conn(x_tensor, num_outputs)

    fc_num_outputs1 = 1024
    fc_layer1 = fully_conn(conv_layer_flatten, fc_num_outputs1)
    fc_layer1 =...


I am working on the file "MachineLearning(Advanced)/p5_image_classification/image_classification_ZH-CN.ipynb".
The first task is:
Explore the Data
The dataset is broken into batches to prevent your machine from running out of memory.  The CIFAR-10 dataset consists of 5 batches, named data_batch_1, data_batch_2, etc.. Each batch contains the labels and images that are one of the following:
* airplane
* automobile
* bird
* cat
* deer
* dog
* frog
* horse
* ship
* truck
Understanding a dataset is part of making predictions on the data.  Play around with the code cell below by changing the batch_id and sample_id. The batch_id is the id for a batch (1-5). The sample_id is the id for a image and label pair in the batch.
Ask yourself "What are all possible labels?", "What is the range of values for the image data?", "Are the labels in order or random?".  Answers to questions like these will help you preprocess the data and end up with better predictions.
探索数据集
为防止在运行过程中内存不足的问题，该数据集已经事先被分成了5批（batch），名为data_batch_1、data_batch_2等。每一批中都含有 图像 及对应的 标签，都是如下类别中的一种：

飞机
汽车
鸟
猫
鹿
狗
青蛙
马
船
卡车

理解数据集也是对数据进行预测的一部分。修改如下代码中的 batch_id 和 sample_id，看看输出的图像是什么样子。其中，batch_id 代表着批次数（1-5），sample_id 代表着在该批内图像及标签的编号。
你可以尝试回答如下问题：
* 可能出现的 标签 都包括哪些？
* 图像数据的取值范围是多少？
* 标签 的排列顺序是随机的还是有序的？
对这些问题的回答，会有助于更好地处理数据，并能更好地进行预测。
答：

可能出现的标签范围是0到9，分别是依次对应飞机、汽车、鸟、猫、鹿、狗、青蛙、马、船、卡车。
图像数据的取值范围是0到255。
给出的数据中标签的排列顺序是随机的。
Can you write Python code for it?

%matplotlib inline
%config InlineBackend.figure_format = 'retina'

import helper
import numpy as np

# Explore the dataset
batch_id = 2
sample_id = 1
helper.display_stats(cifar10_dataset_folder_path, batch_id, sample_id)


I am working on the file "MachineLearning(Advanced)/p5_image_classification/image_classification_ZH-CN.ipynb".
The first task is:
Fully Train the Model
Now that you got a good accuracy with a single CIFAR-10 batch, try it with all five batches.
完全训练该模型
因为你在单批 CIFAR-10 数据上已经得到了一个不错的准确率了，那你可以尝试在所有五批数据上进行训练。
Can you write Python code for it?

"""
DON'T MODIFY ANYTHING IN THIS CELL
"""
save_model_path = './image_classification'

print('Training...')
with tf.Session() as sess:
    # Initializing the variables
    sess.run(tf.global_variables_initializer())

    # Training cycle
    for epoch in range(epochs):
        # Loop over all batches
        n_batches = 5
        for batch_i in range(1, n_batches + 1):
            for batch_features, batch_labels in helper.load_preprocess_training_batch(batch_i, batch_size):
                train_neural_network(sess, optimizer, keep_probability, batch_features, batch_labels)
            print('Epoch {:>2}, CIFAR-10 Batch {}:  '.format(epoch + 1, batch_i), end='')
            print_stats(sess, batch_features, batch_labels, cost, accuracy)

    # Save Model
    saver = tf.train.Saver()
    save_path = saver.save(sess, save_model_path)


I am working on the file "MachineLearning(Advanced)/p5_image_classification/image_classification_ZH-CN.ipynb".
The first task is:
Fully-Connected Layer
Implement the fully_conn function to apply a fully connected layer to x_tensor with the shape (Batch Size, num_outputs). Shortcut option: you can use classes from the TensorFlow Layers or TensorFlow Layers (contrib) packages for this layer. For more of a challenge, only use other TensorFlow packages.
全连接层
修改 fully_conn 函数，来对形如 (batch Size, num_outputs) 的输入 x_tensor 应用一个全连接层。快捷方法：你可以使用来自 TensorFlow Layers 或 TensorFlow Layers (contrib) 包中的函数来实现该功能。不过你也可以只使用 TensorFlow 包中的函数来挑战自己。
Can you write Python code for it?

def fully_conn(x_tensor, num_outputs):
    """
    Apply a fully connected layer to x_tensor using weight and bias
    : x_tensor: A 2-D tensor where the first dimension is batch size.
    : num_outputs: The number of output that the new tensor should be.
    : return: A 2-D tensor where the second dimension is num_outputs.
    """
    # TODO: Implement Function
    return tf.contrib.layers.fully_connected(x_tensor, num_outputs)

"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_fully_conn(fully_conn)


I am working on the file "MachineLearning(Advanced)/p5_image_classification/image_classification_ZH-CN.ipynb".
The first task is:
Hyperparameters
Tune the following parameters:
* Set epochs to the number of iterations until the network stops learning or start overfitting
* Set batch_size to the highest number that your machine has memory for.  Most people set them to common sizes of memory:
 * 64
 * 128
 * 256
 * ...
* Set keep_probability to the probability of keeping a node using dropout
超参数调节
你需要调节如下的参数：
* 设定 epoches 为模型停止学习或开始过拟合时模型的迭代次数。
* 设定 batch_size 为你内存能支持的最大值。一般我们设定该值为：
 * 64
 * 128
 * 256
 * ...
* 设定 keep_probability 为在 dropout 过程中保留一个节点的概率。
Can you write Python code for it?

# TODO: Tune Parameters
epochs = 20
batch_size = 256
keep_probability = 0.5


I am working on the file "MachineLearning(Advanced)/p5_image_classification/image_classification_ZH-CN.ipynb".
The first task is:
Implement Preprocess Functions
Normalize
In the cell below, implement the normalize function to take in image data, x, and return it as a normalized Numpy array. The values should be in the range of 0 to 1, inclusive.  The return object should be the same shape as x.
图像预处理功能的实现
正规化
在如下的代码中，修改 normalize 函数，使之能够对输入的图像数据 x 进行处理，输出一个经过正规化的、Numpy array 格式的图像数据。
注意：
处理后的值应当在 $[0,1]$ 的范围之内。返回值应当和输入值具有相同的形状。
Can you write Python code for it?

def normalize(x):
    """
    Normalize a list of sample image data in the range of 0 to 1
    : x: List of image data.  The image shape is (32, 32, 3)
    : return: Numpy array of normalize data
    """
    return x/255.0

"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_normalize(normalize)


I am working on the file "MachineLearning(Advanced)/p5_image_classification/image_classification_ZH-CN.ipynb".
The first task is:
One-hot encode
Just like the previous code cell, you'll be implementing a function for preprocessing.  This time, you'll implement the one_hot_encode function. The input, x, are a list of labels.  Implement the function to return the list of labels as One-Hot encoded Numpy array.  The possible values for labels are 0 to 9. The one-hot encoding function should return the same encoding for each value between each call to one_hot_encode.  Make sure to save the map of encodings outside the function.
Hint:
Look into LabelBinarizer in the preprocessing module of sklearn.
One-hot 编码
在如下代码中，你将继续实现预处理的功能，实现一个 one_hot_encode 函数。函数的输入 x 是 标签 构成的列表，返回值是经过 One_hot 处理过后的这列 标签 对应的 One_hot 编码，以 Numpy array 储存。其中，标签 的取值范围从0到9。每次调用该函数时，对相同的标签值，它输出的编码也是相同的。请确保在函数外保存编码的映射（map of encodings）。
提示：
你可以尝试使用 sklearn preprocessing 模块中的 LabelBinarizer 函数。
【CodeReview170905】
170905-19:34发现函数one_hot_encode()实现错了，本来应该是0-9，也就是range(1,10)，而我直接写成了[1,2,3,4,5,6,7,8,9,10]，导致错误，进一步地导致网络发散。
Can you write Python code for it?

from sklearn import preprocessing

def one_hot_encode(x):
    """
    One hot encode a list of sample labels. Return a one-hot encoded vector for each label.
    : x: List of sample Labels
    : return: Numpy array of one-hot encoded labels
    """
    # TODO: Implement Function
    lb = preprocessing.LabelBinarizer()
    labels = list(range(0, 10))
    lb.fit(labels)
    one_hot = lb.transform(x)
    return one_hot

"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_one_hot_encode(one_hot_encode)


I am working on the file "MachineLearning(Advanced)/p5_image_classification/image_classification_ZH-CN.ipynb".
The first task is:
Output Layer
Implement the output function to apply a fully connected layer to x_tensor with the shape (Batch Size, num_outputs). Shortcut option: you can use classes from the TensorFlow Layers or TensorFlow Layers (contrib) packages for this layer. For more of a challenge, only use other TensorFlow packages.
Note: Activation, softmax, or cross entropy should not be applied to this.
输出层
修改 output 函数，来对形如 (batch Size, num_outputs) 的输入 x_tensor 应用一个全连接层。快捷方法：你可以使用来自 TensorFlow Layers 或 TensorFlow Layers (contrib) 包中的函数来实现该功能。不过你也可以只使用 TensorFlow 包中的函数来挑战自己。
注意：
激活函数、softmax 或者交叉熵（corss entropy）不应被加入到该层。
【Code review 20170901】
这个地方请注意下题目要求， 注意：该层级不应应用 Activation、softmax 或交叉熵（cross entropy）
Tensorflow提供的全链接函数tf.contrib.layers.fully_connected, 这里 tf.contrib.layers.fully_connected 预设了使用relu 作为非线性激活函数, 所以这里如果使用tf.contrib.layers.fully_connected 需要把激活函数设为None
Can you write Python code for it?

def output(x_tensor, num_outputs):
    """
    Apply a output layer to x_tensor using weight and bias
    : x_tensor: A 2-D tensor where the first dimension is batch size.
    : num_outputs: The number of output that the new tensor should be.
    : return: A 2-D tensor where the second dimension is num_outputs.
    """
    # TODO: Implement Function
    return tf.contrib.layers.fully_connected(x_tensor, num_outputs, activation_fn=None)

"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
tests.test_output(output)


I am working on the file "MachineLearning(Advanced)/p5_image_classification/image_classification_ZH-CN.ipynb".
The first task is:
Randomize Data
As you saw from exploring the data above, the order of the samples are randomized.  It doesn't hurt to randomize it again, but you don't need to for this dataset.
随机打乱数据
正如你在上方探索数据部分所看到的，样本的顺序已经被随机打乱了。尽管再随机处理一次也没问题，不过对于该数据我们没必要再进行一次相关操作了。
Preprocess all the data and save it
Running the code cell below will preprocess all the CIFAR-10 data and save it to file. The code below also uses 10% of the training data for validation.
对所有图像数据进行预处理并保存结果
运行如下代码，它将会预处理所有的 CIFAR-10 数据并将它另存为文件。此外，如下的代码还将会把 10% 的训练数据留出作为验证数据。
Can you write Python code for it?


I am working on the file "MachineLearning(Advanced)/p5_image_classification/image_classification_ZH-CN.ipynb".
The first task is:
Show Stats
Implement the function print_stats to print loss and validation accuracy.  Use the global variables valid_features and valid_labels to calculate validation accuracy.  Use a keep probability of 1.0 to calculate the loss and validation accuracy.
显示状态
修改 print_stats 函数来打印 loss 值及验证准确率。 使用全局的变量 valid_features 及 valid_labels 来计算验证准确率。 设定保留概率为 1.0 来计算 loss 值及验证准确率。
Can you write Python code for it?

def print_stats(session, feature_batch, label_batch, cost, accuracy):
    """
    Print information about loss and validation accuracy
    : session: Current TensorFlow session
    : feature_batch: Batch of Numpy image data
    : label_batch: Batch of Numpy label data
    : cost: TensorFlow cost function
    : accuracy: TensorFlow accuracy function
    """
    # TODO: Implement Function
    loss = session.run(cost, feed_dict={ x: feature_batch, y: label_batch, keep_prob: 1.0 })
    valid_accuracy = session.run(accuracy, feed_dict={ x: valid_features[0:400], y: valid_labels[0:400], keep_prob: 1.0 })
    print('Loss: %.6f' %loss, end='    ')
    print('Validation Accuracy: %.6f' %valid_accuracy)
    pass


I am working on the file "MachineLearning/Backpropagation.ipynb".
The first task is:
Example for Backprop of a simple Neural Networks
$$ \sigma(x) = \frac{1}{1 + exp(-x)} $$
$$ \frac{d \sigma(x)}{dx}  = \sigma(x) * (1 - \sigma(x)) $$
Can you write Python code for it?

def sigmoid(x):
    return 1.0/(1.0 + np.exp(-x))

def sigmoid_prime(x):
    return sigmoid(x)*(1.0-sigmoid(x))

def tanh(x):
    return np.tanh(x)

def tanh_prime(x):
    return 1.0 - x**2

class NeuralNetwork(object):

    # fix the seed
    np.random.seed(1)

    def __init__(self, layers, learning_rate, epochs):
        self.activation = sigmoid
        self.activation_prime = sigmoid_prime
        self.weights = []
        # input layers -> hidden layers
        for i in range(1, len(layers) - 1):
            # + 1 due to bias
            r = 2 * np.random.random((layers[i-1] + 1, layers[i] + 1)) -1
            self.weights.append(r)
        # hidden layers -> output layer
        r = 2 * np.random.random((layers[i] + 1, layers[i+1])) - 1
        self.weights.append(r)
        self.learning_rate = learning_rate
        self.epochs = epochs

    def train(self, X, y):
        # Add bias to X
        ones = np.atleast_2d(np.ones(X.shape[0]))
        X = np.concatenate((ones.T, X), axis=1)

        for epoch in range(self.epochs):
            # forward propagation
            i = np.random.randint(X.shape[0])
            a = [X[i]] # mini-batch

            for l in range(len(self.weights)):
                z = np.dot(a[l], self.weights[l])
                activation = self.activation(z)
                a.append(activation) # (row, a_hidden_layer, a_output_layer)

            # how much did we miss??
            error = y[i] - a[-1]
            deltas = [error * self.activation_prime(a[-1])]

            for l in range(len(a) - 2, 0, -1):
                deltas.append(deltas[-1].dot(self.weights[l].T) * self.activation_prime(a[l]))

            # [level3(output)->level2(hidden)]  => [level2(hidden)->level3(output)]
            deltas.reverse()

            # backpropagation => update weights
            for i in range(len(self.weights)):
                layer = np.atleast_2d(a[i])
                delta =...


I am working on the file "MachineLearning/Backpropagation.ipynb".
The first task is:
Gradient Descent
Can you write Python code for it?

"""
Gradient Descent
Example
f(x) = x**4 -3*x**3 + 2
f'(x) = 4*x**3 - 9*x**2

We want f'(x) = 0 - slope is zero / minima

Initial guess: x=4
f'(4) = 112

Second guess: x=-1
f'(-1) = -13

=> f'(4) > 0 => decrease x | f'(-1) < 0 => increase x

x_new = x_old - f'(x) ??? => not idea as this would be too stepp

x_new = x_old - alpha * f'(x) => what kind of value for alpha??
"""

alpha = 0.01
x_old = 0
x_new = 4
precision = 0.00001

def f_derivative(x):
    return 4*x**3 - 9*x**2

while abs(x_new - x_old) > precision:
    x_old = x_new
    x_new = x_old - alpha * f_derivative(x_old)


I am working on the file "MachineLearning/DataScience-Python3/ConditionalProbabilityExercise.ipynb".
The first task is:
If E and F were independent, then we would expect P(E | F) to be about the same as P(E). But they're not; PE is 0.45, and P(E|F) is 0.3. So, that tells us that E and F are dependent (which we know they are in this example.)
What is P(E)P(F)?
Can you write Python code for it?

print("P(30's)P(Purchase)" + str(PE * PF))


I am working on the file "MachineLearning/DataScience-Python3/ConditionalProbabilityExercise.ipynb".
The first task is:
Let's play with conditional probability.
First let's compute P(E|F), where E is "purchase" and F is "you're in your 30's". The probability of someone in their 30's buying something is just the percentage of how many 30-year-olds bought something:
Can you write Python code for it?

PEF = float(purchases[30]) / float(totals[30])
print('P(purchase | 30s): ' + str(PEF)


I am working on the file "MachineLearning/DataScience-Python3/ConditionalProbabilityExercise.ipynb".
The first task is:
P(E,F) = P(E)P(F), and they are pretty close in this example. But because E and F are actually dependent on each other, and the randomness of the data we're working with, it's not quite the same.
We can also check that P(E|F) = P(E,F)/P(F) and sure enough, it is:
Can you write Python code for it?


I am working on the file "MachineLearning/DataScience-Python3/ConditionalProbabilitySolution.ipynb".
The first task is:
Now we'll compute P(E)
Can you write Python code for it?

PE = float(totalPurchases) / 100000.0
print("P(Purchase):" + str(PE))


I am working on the file "MachineLearning/DataScience-Python3/CovarianceCorrelation.ipynb".
The first task is:
(It doesn't match exactly just due to the math precision available on a computer.)
We can force a perfect correlation by fabricating a totally linear relationship (again, it's not exactly -1 just due to precision errors, but it's close enough to tell us there's a really good correlation here):
Can you write Python code for it?

purchaseAmount = 100 - pageSpeeds * 3

scatter(pageSpeeds, purchaseAmount)

correlation (pageSpeeds, purchaseAmount)


I am working on the file "MachineLearning/DataScience-Python3/CovarianceCorrelation.ipynb".
The first task is:
But, what does this value mean? Covariance is sensitive to the units used in the variables, which makes it difficult to interpret. Correlation normalizes everything by their standard deviations, giving you an easier to understand value that ranges from -1 (for a perfect inverse correlation) to 1 (for a perfect positive correlation):
Can you write Python code for it?

def correlation(x, y):
    stddevx = x.std()
    stddevy = y.std()
    return covariance(x,y) / stddevx / stddevy  #In real life you'd check for divide by zero here

correlation(pageSpeeds, purchaseAmount)


I am working on the file "MachineLearning/DataScience-Python3/CovarianceCorrelation.ipynb".
The first task is:
numpy can do all this for you with numpy.corrcoef. It returns a matrix of the correlation coefficients between every combination of the arrays passed in:
Can you write Python code for it?


I am working on the file "MachineLearning/DataScience-Python3/ItemBasedCF.ipynb".
The first task is:
However, we want to avoid spurious results that happened from just a handful of users that happened to rate the same pair of movies. In order to restrict our results to movies that lots of people rated together - and also give us more popular results that are more easily recongnizable - we'll use the min_periods argument to throw out results where fewer than 100 users rated a given movie pair:
Can you write Python code for it?

corrMatrix = userRatings.corr(method='pearson', min_periods=100)
corrMatrix.head()


I am working on the file "MachineLearning/DataScience-Python3/ItemBasedCF.ipynb".
The first task is:
Now let's produce some movie recommendations for user ID 0, who I manually added to the data set as a test case. This guy really likes Star Wars and The Empire Strikes Back, but hated Gone with the Wind. I'll extract his ratings from the userRatings DataFrame, and use dropna() to get rid of missing data (leaving me only with a Series of the movies I actually rated:)
Can you write Python code for it?

myRatings = userRatings.loc[0].dropna()
myRatings


I am working on the file "MachineLearning/DataScience-Python3/ItemBasedCF.ipynb".
The first task is:
Now, let's go through each movie I rated one at a time, and build up a list of possible recommendations based on the movies similar to the ones I rated.
So for each movie I rated, I'll retrieve the list of similar movies from our correlation matrix. I'll then scale those correlation scores by how well I rated the movie they are similar to, so movies similar to ones I liked count more than movies similar to ones I hated:
Can you write Python code for it?

simCandidates = pd.Series()
for i in range(0, len(myRatings.index)):
    print "Adding sims for " + myRatings.index[i] + "..."
    # Retrieve similar movies to this one that I rated
    sims = corrMatrix[myRatings.index[i]].dropna()
    # Now scale its similarity by how well I rated this movie
    sims = sims.map(lambda x: x * myRatings[i])
    # Add the score to the list of similarity candidates
    simCandidates = simCandidates.append(sims)

#Glance at our results so far:
print "sorting..."
simCandidates.sort_values(inplace = True, ascending = False)
print simCandidates.head(10)


I am working on the file "MachineLearning/DataScience-Python3/ItemBasedCF.ipynb".
The first task is:
This is starting to look like something useful! Note that some of the same movies came up more than once, because they were similar to more than one movie I rated. We'll use groupby() to add together the scores from movies that show up more than once, so they'll count more:
Can you write Python code for it?

simCandidates = simCandidates.groupby(simCandidates.index).sum()

simCandidates.sort_values(inplace = True, ascending = False)
simCandidates.head(10)


I am working on the file "MachineLearning/DataScience-Python3/KFoldCrossValidation.ipynb".
The first task is:
A single train/test split is made easy with the train_test_split function in the cross_validation library:
Can you write Python code for it?

# Split the iris data into train/test data sets with 40% reserved for testing
X_train, X_test, y_train, y_test = cross_validation.train_test_split(iris.data, iris.target, test_size=0.4, random_state=0)

# Build an SVC model for predicting iris classifications using training data
clf = svm.SVC(kernel='linear', C=1).fit(X_train, y_train)

# Now measure its performance with the test data
clf.score(X_test, y_test)


I am working on the file "MachineLearning/DataScience-Python3/KFoldCrossValidation.ipynb".
The first task is:
K-Fold cross validation is just as easy; let's use a K of 5:
Can you write Python code for it?

# We give cross_val_score a model, the entire data set and its "real" values, and the number of folds:
scores = cross_validation.cross_val_score(clf, iris.data, iris.target, cv=5)

# Print the accuracy for each fold:
print(scores)

# And the mean accuracy of all 5 folds:
print(scores.mean())


I am working on the file "MachineLearning/DataScience-Python3/KFoldCrossValidation.ipynb".
The first task is:
Our model is even better than we thought! Can we do better? Let's try a different kernel (poly):
Can you write Python code for it?

clf = svm.SVC(kernel='poly', C=1).fit(X_train, y_train)
scores = cross_validation.cross_val_score(clf, iris.data, iris.target, cv=5)
print(scores)
print(scores.mean())


I am working on the file "MachineLearning/DataScience-Python3/KMeans.ipynb".
The first task is:
We'll use k-means to rediscover these clusters in unsupervised learning:
Can you write Python code for it?

%matplotlib inline

from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
from sklearn.preprocessing import scale
from numpy import random, float

data = createClusteredData(100, 5)

model = KMeans(n_clusters=5)

# Note I'm scaling the data to normalize it! Important for good results.
model = model.fit(scale(data))

# We can look at the clusters each data point was assigned to
print(model.labels_)

# And we'll visualize it:
plt.figure(figsize=(8, 6))
plt.scatter(data[:,0], data[:,1], c=model.labels_.astype(float))
plt.show()


I am working on the file "MachineLearning/DataScience-Python3/KNN.ipynb".
The first task is:
For example, here's the record we end up with for movie ID 1, "Toy Story":
Can you write Python code for it?


I am working on the file "MachineLearning/DataScience-Python3/KNN.ipynb".
The first task is:
How does this compare to Toy Story's actual average rating?
Can you write Python code for it?


I am working on the file "MachineLearning/DataScience-Python3/KNN.ipynb".
The first task is:
Now let's define a function that computes the "distance" between two movies based on how similar their genres are, and how similar their popularity is. Just to make sure it works, we'll compute the distance between movie ID's 2 and 4:
Can you write Python code for it?

from scipy import spatial

def ComputeDistance(a, b):
    genresA = a[1]
    genresB = b[1]
    genreDistance = spatial.distance.cosine(genresA, genresB)
    popularityA = a[2]
    popularityB = b[2]
    popularityDistance = abs(popularityA - popularityB)
    return genreDistance + popularityDistance

ComputeDistance(movieDict[2], movieDict[4])


I am working on the file "MachineLearning/DataScience-Python3/KNN.ipynb".
The first task is:
Now, we'll group everything by movie ID, and compute the total number of ratings (each movie's popularity) and the average rating for every movie:
Can you write Python code for it?

import numpy as np

movieProperties = ratings.groupby('movie_id').agg({'rating': [np.size, np.mean]})
movieProperties.head()


I am working on the file "MachineLearning/DataScience-Python3/KNN.ipynb".
The first task is:
Remember the higher the distance, the less similar the movies are. Let's check what movies 2 and 4 actually are - and confirm they're not really all that similar:
Can you write Python code for it?


I am working on the file "MachineLearning/DataScience-Python3/KNN.ipynb".
The first task is:
While we were at it, we computed the average rating of the 10 nearest neighbors to Toy Story:
Can you write Python code for it?


I am working on the file "MachineLearning/DataScience-Python3/MatPlotLib.ipynb".
The first task is:
Adjust the Axes
Can you write Python code for it?


I am working on the file "MachineLearning/DataScience-Python3/MatPlotLib.ipynb".
The first task is:
Bar Chart
Can you write Python code for it?

values = [12, 55, 4, 32, 14]
colors = ['r', 'g', 'b', 'c', 'm']
plt.bar(range(0,5), values, color= colors)
plt.show()


I am working on the file "MachineLearning/DataScience-Python3/MatPlotLib.ipynb".
The first task is:
Box & Whisker Plot
Useful for visualizing the spread & skew of data.
The red line represents the median of the data, and the box represents the bounds of the 1st and 3rd quartiles.
So, half of the data exists within the box.
The dotted-line "whiskers" indicate the range of the data - except for outliers, which are plotted outside the whiskers. Outliers are 1.5X or more the interquartile range.
This example below creates uniformly distributed random numbers between -40 and 60, plus a few outliers above 100 and below -100:
Can you write Python code for it?

uniformSkewed = np.random.rand(100) * 100 - 40
high_outliers = np.random.rand(10) * 50 + 100
low_outliers = np.random.rand(10) * -50 - 100
data = np.concatenate((uniformSkewed, high_outliers, low_outliers))
plt.boxplot(data)
plt.show()


I am working on the file "MachineLearning/DataScience-Python3/MatPlotLib.ipynb".
The first task is:
Change Line Types and Colors
Can you write Python code for it?


I am working on the file "MachineLearning/DataScience-Python3/MatPlotLib.ipynb".
The first task is:
Histogram
Can you write Python code for it?

incomes = np.random.normal(27000, 15000, 10000)
plt.hist(incomes, 50)
plt.show()


I am working on the file "MachineLearning/DataScience-Python3/MatPlotLib.ipynb".
The first task is:
Mutiple Plots on One Graph
Can you write Python code for it?

plt.plot(x, norm.pdf(x))
plt.plot(x, norm.pdf(x, 1.0, 0.5))
plt.show()